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";
136 return HST.isTypeForHLX(
F.getReturnType()) ||
138 return HST.isTypeForHLX(A.getType());
144 static const MCPhysReg CalleeSavedRegsV3[] = {
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 static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
153 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3,
154 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
155 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
156 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
162 return HasEHReturn ? HexagonCSR_HLX_EH_SaveList : HexagonCSR_HLX_SaveList;
163 return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3;
168 return HexagonCSR_RegMask;
172 return HexagonCSR_HLX_RegMask;
193 if (!HFI.needsAligna(MF))
199 if (BaseReservedRegs[*R])
204 assert(AP.
isValid() &&
"Couldn't reserve stack align register");
209HexagonRegisterInfo::getBaseReservedRegs(
const MachineFunction &MF)
const {
256 Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, Hexagon::R10,
257 Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, Hexagon::R15,
258 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, Hexagon::R20,
259 Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, Hexagon::R25,
260 Hexagon::R26, Hexagon::R27, Hexagon::R28};
272 int SPAdj,
unsigned FIOp,
274 static unsigned ReuseCount = 0;
277 assert(SPAdj == 0 &&
"Unexpected");
284 auto &HFI = *HST.getFrameLowering();
287 int FI =
MI.getOperand(FIOp).getIndex();
290 int Offset = HFI.getFrameIndexReference(MF, FI, BP).getFixed();
292 int RealOffset =
Offset +
MI.getOperand(FIOp+1).getImm();
294 if (BP == Hexagon::VSP) {
296 Register VSPCopy =
MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
297 BuildMI(MB,
II,
MI.getDebugLoc(), HII.get(Hexagon::A2_tfrcrr), VSPCopy)
302 unsigned Opc =
MI.getOpcode();
304 case Hexagon::PS_fia:
305 MI.setDesc(HII.get(Hexagon::A2_addi));
306 MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
307 MI.removeOperand(FIOp+1);
311 MI.setDesc(HII.get(Hexagon::A2_addi));
315 if (!HII.isValidOffset(
Opc, RealOffset)) {
327 switch (
MI.getOpcode()) {
329 case Hexagon::PS_vloadrw_ai:
330 case Hexagon::PS_vloadrw_nt_ai:
331 case Hexagon::PS_vstorerw_ai:
332 case Hexagon::PS_vstorerw_nt_ai:
335 case Hexagon::PS_vloadrv_ai:
336 case Hexagon::PS_vloadrv_nt_ai:
337 case Hexagon::PS_vstorerv_ai:
338 case Hexagon::PS_vstorerv_nt_ai:
339 case Hexagon::V6_vL32b_ai:
340 case Hexagon::V6_vS32b_ai: {
341 unsigned HwLen = HST.getVectorLength();
342 if (RealOffset % HwLen == 0) {
343 int VecOffset = RealOffset / HwLen;
349 if (!IsPair || (VecOffset + 1) % 16 != 0) {
350 RealOffset = (VecOffset & -16) * HwLen;
351 InstOffset = (VecOffset % 16 - 8) * HwLen;
364 bool PassedCall =
false;
367 for (
auto I = std::next(
II.getReverse()), E = MB.
rend();
I != E; ++
I) {
368 if (SearchCount == SearchRange)
373 PassedCall |= BI.
isCall();
375 if (SeenVRegs.
size() > 1)
377 if (
Op.isReg() &&
Op.getReg().isVirtual())
385 if (!Op2.isImm() || Op2.getImm() != RealOffset)
389 if (R.isPhysical()) {
390 if (Defs.available(R))
392 }
else if (R.isVirtual()) {
397 if (!PassedCall && SeenVRegs.
size() <= 1)
408 ReuseBP =
MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
410 BuildMI(MB,
II,
DL, HII.get(Hexagon::A2_addi), ReuseBP)
415 RealOffset = InstOffset;
418 MI.getOperand(FIOp).ChangeToRegister(BP,
false,
false,
false);
419 MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
434 if (!HST.
useHVXOps() || NewRC->
getID() != Hexagon::HvxWRRegClass.getID())
436 bool SmallSrc = SrcRC->
getID() == Hexagon::HvxVRRegClass.getID();
437 bool SmallDst = DstRC->
getID() == Hexagon::HvxVRRegClass.getID();
438 if (!SmallSrc && !SmallDst)
445 for (
SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex();
446 I != E;
I =
I.getNextIndex()) {
454 if (SmallSrc == SmallDst) {
466 Register SmallReg = SmallSrc ? SrcReg : DstReg;
467 Register LargeReg = SmallSrc ? DstReg : SrcReg;
499 static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi };
500 static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi };
501 static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi };
503 switch (RC.
getID()) {
504 case Hexagon::CtrRegs64RegClassID:
505 case Hexagon::DoubleRegsRegClassID:
506 case Hexagon::CircRegsRegClassID:
508 case Hexagon::HvxWRRegClassID:
509 case Hexagon::HlxLLRRegClassID:
511 case Hexagon::HvxVQRRegClassID:
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 GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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 bool hasHLXSignature(const MachineFunction &MF)
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
MachineRegisterInfo & MRI
This file declares the machine register scavenger class.
Remove Loads Into Fake Uses
This file defines the SmallSet class.
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
This class represents an incoming formal argument to a Function.
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)
Register getVTCMStackRegister() const
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...
bool useFPForScavengingIndex(const MachineFunction &MF) const override
Returns true if the frame pointer is valid.
const uint32_t * getHLXCallPreservedMask() const
Mask for calls that pass or return values in HLX registers.
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
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.