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 "
57 return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
58 R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
64 using namespace Hexagon;
67 R0, R1,
R2, R3,
R4, R5,
R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0
70 D0, D1, D2, D3, D4, D5, D6, D7, 0
76 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13,
77 V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27,
81 W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
87 switch (RC->
getID()) {
88 case IntRegsRegClassID:
90 case DoubleRegsRegClassID:
92 case PredRegsRegClassID:
106 dbgs() <<
"Register class: " << getRegClassName(RC) <<
"\n";
115 static const MCPhysReg CalleeSavedRegsV3[] = {
116 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
117 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
118 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
123 static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
124 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3,
125 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
126 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
127 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
132 return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3;
138 return HexagonCSR_RegMask;
204 int SPAdj,
unsigned FIOp,
206 static unsigned ReuseCount = 0;
209 assert(SPAdj == 0 &&
"Unexpected");
216 auto &HFI = *HST.getFrameLowering();
219 int FI =
MI.getOperand(FIOp).getIndex();
222 int Offset = HFI.getFrameIndexReference(MF, FI, BP).getFixed();
224 int RealOffset =
Offset +
MI.getOperand(FIOp+1).getImm();
226 unsigned Opc =
MI.getOpcode();
228 case Hexagon::PS_fia:
229 MI.setDesc(HII.get(Hexagon::A2_addi));
230 MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
231 MI.removeOperand(FIOp+1);
235 MI.setDesc(HII.get(Hexagon::A2_addi));
239 if (!HII.isValidOffset(Opc, RealOffset,
this)) {
251 switch (
MI.getOpcode()) {
253 case Hexagon::PS_vloadrw_ai:
254 case Hexagon::PS_vloadrw_nt_ai:
255 case Hexagon::PS_vstorerw_ai:
256 case Hexagon::PS_vstorerw_nt_ai:
259 case Hexagon::PS_vloadrv_ai:
260 case Hexagon::PS_vloadrv_nt_ai:
261 case Hexagon::PS_vstorerv_ai:
262 case Hexagon::PS_vstorerv_nt_ai:
263 case Hexagon::V6_vL32b_ai:
264 case Hexagon::V6_vS32b_ai: {
265 unsigned HwLen = HST.getVectorLength();
266 if (RealOffset % HwLen == 0) {
267 int VecOffset = RealOffset / HwLen;
273 if (!IsPair || (VecOffset + 1) % 16 != 0) {
274 RealOffset = (VecOffset & -16) * HwLen;
275 InstOffset = (VecOffset % 16 - 8) * HwLen;
288 bool PassedCall =
false;
291 for (
auto I = std::next(
II.getReverse()), E = MB.
rend();
I != E; ++
I) {
292 if (SearchCount == SearchRange)
297 PassedCall |= BI.
isCall();
299 if (SeenVRegs.
size() > 1)
301 if (
Op.isReg() &&
Op.getReg().isVirtual())
309 if (!Op2.isImm() || Op2.getImm() != RealOffset)
313 if (R.isPhysical()) {
314 if (Defs.available(R))
316 }
else if (R.isVirtual()) {
321 if (!PassedCall && SeenVRegs.
size() <= 1)
332 ReuseBP =
MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
334 BuildMI(MB,
II,
DL, HII.get(Hexagon::A2_addi), ReuseBP)
339 RealOffset = InstOffset;
342 MI.getOperand(FIOp).ChangeToRegister(BP,
false,
false,
false);
343 MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
358 if (!HST.
useHVXOps() || NewRC->
getID() != Hexagon::HvxWRRegClass.getID())
360 bool SmallSrc = SrcRC->
getID() == Hexagon::HvxVRRegClass.getID();
361 bool SmallDst = DstRC->
getID() == Hexagon::HvxVRRegClass.getID();
362 if (!SmallSrc && !SmallDst)
369 for (
SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex();
370 I != E;
I =
I.getNextIndex()) {
378 if (SmallSrc == SmallDst) {
390 Register SmallReg = SmallSrc ? SrcReg : DstReg;
391 Register LargeReg = SmallSrc ? DstReg : SrcReg;
420 static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi };
421 static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi };
422 static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi };
424 switch (RC.
getID()) {
425 case Hexagon::CtrRegs64RegClassID:
426 case Hexagon::DoubleRegsRegClassID:
428 case Hexagon::HvxWRRegClassID:
430 case Hexagon::HvxVQRRegClassID:
448 unsigned Kind)
const {
449 return &Hexagon::IntRegsRegClass;
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
bool empty() const
empty - Check if the array is empty.
This class represents an Operation in the Expression.
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
const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const override
HexagonRegisterInfo(unsigned HwMode)
BitVector getReservedRegs(const MachineFunction &MF) const override
Register getStackRegister() const
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
const MCPhysReg * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
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.
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 & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isCall(QueryType Type=AnyInBundle) const
iterator_range< mop_iterator > operands()
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.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
This represents a simple continuous liveness interval for a value.