38#define GET_REGINFO_TARGET_DESC
39#include "HexagonGenRegisterInfo.inc"
45 cl::desc(
"Limit on instruction search range in frame index elimination"));
49 cl::desc(
"Limit on the number of reused registers in frame index "
68 if (Reg >= Hexagon::VF0 && Reg <= Hexagon::VF31)
71 if (Reg >= Hexagon::VFR0 && Reg <= Hexagon::VFR31)
77 return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
78 R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
87 R0, R1,
R2, R3,
R4, R5,
R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0
90 D0, D1, D2, D3, D4, D5, D6, D7, 0
96 V0,
V1, V2,
V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13,
97 V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27,
101 W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
107 switch (RC->
getID()) {
108 case IntRegsRegClassID:
110 case DoubleRegsRegClassID:
112 case PredRegsRegClassID:
114 case HvxVRRegClassID:
116 case HvxWRRegClassID:
118 case HvxQRRegClassID:
126 dbgs() <<
"Register class: " << getRegClassName(RC) <<
"\n";
135 static const MCPhysReg CalleeSavedRegsV3[] = {
136 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
137 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
138 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
143 static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
144 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3,
145 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
146 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
147 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
152 return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3;
158 return HexagonCSR_RegMask;
179 if (!HFI.needsAligna(MF))
185 if (BaseReservedRegs[*R])
190 assert(AP.
isValid() &&
"Couldn't reserve stack align register");
195HexagonRegisterInfo::getBaseReservedRegs(
const MachineFunction &MF)
const {
242 Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, Hexagon::R10,
243 Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, Hexagon::R15,
244 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, Hexagon::R20,
245 Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, Hexagon::R25,
246 Hexagon::R26, Hexagon::R27, Hexagon::R28};
258 int SPAdj,
unsigned FIOp,
260 static unsigned ReuseCount = 0;
263 assert(SPAdj == 0 &&
"Unexpected");
270 auto &HFI = *HST.getFrameLowering();
273 int FI =
MI.getOperand(FIOp).getIndex();
276 int Offset = HFI.getFrameIndexReference(MF, FI, BP).getFixed();
278 int RealOffset =
Offset +
MI.getOperand(FIOp+1).getImm();
280 unsigned Opc =
MI.getOpcode();
282 case Hexagon::PS_fia:
283 MI.setDesc(HII.get(Hexagon::A2_addi));
284 MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
285 MI.removeOperand(FIOp+1);
289 MI.setDesc(HII.get(Hexagon::A2_addi));
293 if (!HII.isValidOffset(
Opc, RealOffset,
this)) {
305 switch (
MI.getOpcode()) {
307 case Hexagon::PS_vloadrw_ai:
308 case Hexagon::PS_vloadrw_nt_ai:
309 case Hexagon::PS_vstorerw_ai:
310 case Hexagon::PS_vstorerw_nt_ai:
313 case Hexagon::PS_vloadrv_ai:
314 case Hexagon::PS_vloadrv_nt_ai:
315 case Hexagon::PS_vstorerv_ai:
316 case Hexagon::PS_vstorerv_nt_ai:
317 case Hexagon::V6_vL32b_ai:
318 case Hexagon::V6_vS32b_ai: {
319 unsigned HwLen = HST.getVectorLength();
320 if (RealOffset % HwLen == 0) {
321 int VecOffset = RealOffset / HwLen;
327 if (!IsPair || (VecOffset + 1) % 16 != 0) {
328 RealOffset = (VecOffset & -16) * HwLen;
329 InstOffset = (VecOffset % 16 - 8) * HwLen;
342 bool PassedCall =
false;
345 for (
auto I = std::next(
II.getReverse()), E = MB.
rend();
I != E; ++
I) {
346 if (SearchCount == SearchRange)
351 PassedCall |= BI.
isCall();
353 if (SeenVRegs.
size() > 1)
355 if (
Op.isReg() &&
Op.getReg().isVirtual())
363 if (!Op2.isImm() || Op2.getImm() != RealOffset)
367 if (R.isPhysical()) {
368 if (Defs.available(R))
370 }
else if (R.isVirtual()) {
375 if (!PassedCall && SeenVRegs.
size() <= 1)
386 ReuseBP = MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
388 BuildMI(MB,
II,
DL, HII.get(Hexagon::A2_addi), ReuseBP)
393 RealOffset = InstOffset;
396 MI.getOperand(FIOp).ChangeToRegister(BP,
false,
false,
false);
397 MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
412 if (!HST.
useHVXOps() || NewRC->
getID() != Hexagon::HvxWRRegClass.getID())
414 bool SmallSrc = SrcRC->
getID() == Hexagon::HvxVRRegClass.getID();
415 bool SmallDst = DstRC->
getID() == Hexagon::HvxVRRegClass.getID();
416 if (!SmallSrc && !SmallDst)
423 for (
SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex();
424 I != E;
I =
I.getNextIndex()) {
432 if (SmallSrc == SmallDst) {
444 Register SmallReg = SmallSrc ? SrcReg : DstReg;
445 Register LargeReg = SmallSrc ? DstReg : SrcReg;
474 static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi };
475 static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi };
476 static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi };
478 switch (RC.
getID()) {
479 case Hexagon::CtrRegs64RegClassID:
480 case Hexagon::DoubleRegsRegClassID:
482 case Hexagon::HvxWRRegClassID:
484 case Hexagon::HvxVQRRegClassID:
502 return &Hexagon::IntRegsRegClass;
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
static cl::opt< unsigned > FrameIndexReuseLimit("hexagon-frame-index-reuse-limit", cl::init(~0), cl::Hidden, cl::desc("Limit on the number of reused registers in frame index " "elimination"))
static cl::opt< unsigned > FrameIndexSearchRange("hexagon-frame-index-search-range", cl::init(32), cl::Hidden, cl::desc("Limit on instruction search range in frame index elimination"))
Promote Memory to Register
uint64_t IntrinsicInst * II
This file declares the machine register scavenger class.
Remove Loads Into Fake Uses
This file defines the SmallSet class.
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
bool empty() const
Check if the array is empty.
Hexagon target-specific information for each MachineFunction.
Register getFrameRegister() const
bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS=nullptr) const override
bool isEHReturnCalleeSaveReg(Register Reg) const
HexagonRegisterInfo(unsigned HwMode)
BitVector getReservedRegs(const MachineFunction &MF) const override
Register getStackRegister() const
Register computeStackAlignBaseRegister(const MachineFunction &MF) const
Compute the first available callee-saved register to use as the aligned-stack base register when this...
const TargetRegisterClass * getPointerRegClass(unsigned Kind=0) const override
bool useFPForScavengingIndex(const MachineFunction &MF) const override
Returns true if the frame pointer is valid.
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
unsigned getHexagonSubRegIndex(const TargetRegisterClass &RC, unsigned GenIdx) const
bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const override
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
bool isFakeReg(MCPhysReg Reg) const
Returns true if the given reserved physical register Reg is live across function calls/returns.
const MCPhysReg * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
bool isGlobalReg(MCPhysReg Reg) const
Returns true if the given reserved physical register is live across function calls/returns.
const HexagonInstrInfo * getInstrInfo() const override
SlotIndexes * getSlotIndexes() const
LiveInterval & getInterval(Register Reg)
A set of register units used to track register liveness.
static void accumulateUsedDefed(const MachineInstr &MI, LiveRegUnits &ModifiedRegUnits, LiveRegUnits &UsedRegUnits, const TargetRegisterInfo *TRI)
For a machine instruction MI, adds all register units used in UsedRegUnits and defined or clobbered i...
ArrayRef< unsigned > superclasses() const
Returns a list of super-classes.
unsigned getID() const
getID() - Return the register class ID number.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isCall(QueryType Type=AnyInBundle) const
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
SlotIndex - An opaque wrapper around machine indexes.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual bool isRegisterReservedByUser(Register R) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
llvm::ArrayRef< MCPhysReg > GetVectRegRev()
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
MCRegisterClass TargetRegisterClass
This represents a simple continuous liveness interval for a value.