37#define GET_REGINFO_TARGET_DESC
38#include "HexagonGenRegisterInfo.inc"
44 cl::desc(
"Limit on instruction search range in frame index elimination"));
48 cl::desc(
"Limit on the number of reused registers in frame index "
67 if (Reg >= Hexagon::VF0 && Reg <= Hexagon::VF31)
70 if (Reg >= Hexagon::VFR0 && Reg <= Hexagon::VFR31)
76 return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
77 R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
86 R0, R1,
R2, R3,
R4, R5,
R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0
89 D0, D1, D2, D3, D4, D5, D6, D7, 0
95 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13,
96 V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27,
100 W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
106 switch (RC->
getID()) {
107 case IntRegsRegClassID:
109 case DoubleRegsRegClassID:
111 case PredRegsRegClassID:
113 case HvxVRRegClassID:
115 case HvxWRRegClassID:
117 case HvxQRRegClassID:
125 dbgs() <<
"Register class: " << getRegClassName(RC) <<
"\n";
134 static const MCPhysReg CalleeSavedRegsV3[] = {
135 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
136 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
137 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
142 static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
143 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3,
144 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
145 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
146 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
151 return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3;
157 return HexagonCSR_RegMask;
223 int SPAdj,
unsigned FIOp,
225 static unsigned ReuseCount = 0;
228 assert(SPAdj == 0 &&
"Unexpected");
235 auto &HFI = *HST.getFrameLowering();
238 int FI =
MI.getOperand(FIOp).getIndex();
241 int Offset = HFI.getFrameIndexReference(MF, FI, BP).getFixed();
243 int RealOffset =
Offset +
MI.getOperand(FIOp+1).getImm();
245 unsigned Opc =
MI.getOpcode();
247 case Hexagon::PS_fia:
248 MI.setDesc(HII.get(Hexagon::A2_addi));
249 MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
250 MI.removeOperand(FIOp+1);
254 MI.setDesc(HII.get(Hexagon::A2_addi));
258 if (!HII.isValidOffset(
Opc, RealOffset,
this)) {
270 switch (
MI.getOpcode()) {
272 case Hexagon::PS_vloadrw_ai:
273 case Hexagon::PS_vloadrw_nt_ai:
274 case Hexagon::PS_vstorerw_ai:
275 case Hexagon::PS_vstorerw_nt_ai:
278 case Hexagon::PS_vloadrv_ai:
279 case Hexagon::PS_vloadrv_nt_ai:
280 case Hexagon::PS_vstorerv_ai:
281 case Hexagon::PS_vstorerv_nt_ai:
282 case Hexagon::V6_vL32b_ai:
283 case Hexagon::V6_vS32b_ai: {
284 unsigned HwLen = HST.getVectorLength();
285 if (RealOffset % HwLen == 0) {
286 int VecOffset = RealOffset / HwLen;
292 if (!IsPair || (VecOffset + 1) % 16 != 0) {
293 RealOffset = (VecOffset & -16) * HwLen;
294 InstOffset = (VecOffset % 16 - 8) * HwLen;
307 bool PassedCall =
false;
310 for (
auto I = std::next(
II.getReverse()), E = MB.
rend();
I != E; ++
I) {
311 if (SearchCount == SearchRange)
316 PassedCall |= BI.
isCall();
318 if (SeenVRegs.
size() > 1)
320 if (
Op.isReg() &&
Op.getReg().isVirtual())
328 if (!Op2.isImm() || Op2.getImm() != RealOffset)
332 if (R.isPhysical()) {
333 if (Defs.available(R))
335 }
else if (R.isVirtual()) {
340 if (!PassedCall && SeenVRegs.
size() <= 1)
351 ReuseBP =
MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
353 BuildMI(MB,
II,
DL, HII.get(Hexagon::A2_addi), ReuseBP)
358 RealOffset = InstOffset;
361 MI.getOperand(FIOp).ChangeToRegister(BP,
false,
false,
false);
362 MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
377 if (!HST.
useHVXOps() || NewRC->
getID() != Hexagon::HvxWRRegClass.getID())
379 bool SmallSrc = SrcRC->
getID() == Hexagon::HvxVRRegClass.getID();
380 bool SmallDst = DstRC->
getID() == Hexagon::HvxVRRegClass.getID();
381 if (!SmallSrc && !SmallDst)
388 for (
SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex();
389 I != E;
I =
I.getNextIndex()) {
397 if (SmallSrc == SmallDst) {
409 Register SmallReg = SmallSrc ? SrcReg : DstReg;
410 Register LargeReg = SmallSrc ? DstReg : SrcReg;
439 static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi };
440 static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi };
441 static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi };
443 switch (RC.
getID()) {
444 case Hexagon::CtrRegs64RegClassID:
445 case Hexagon::DoubleRegsRegClassID:
447 case Hexagon::HvxWRRegClassID:
449 case Hexagon::HvxVQRRegClassID:
467 return &Hexagon::IntRegsRegClass;
unsigned const MachineRegisterInfo * MRI
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"))
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
empty - 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
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.
bool hasReservedR19() const
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...
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.
unsigned getID() const
Return the register class ID number.
ArrayRef< unsigned > superclasses() const
Returns a list of super-classes.
#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
This represents a simple continuous liveness interval for a value.