42#define GET_REGINFO_TARGET_DESC
43#include "HexagonGenRegisterInfo.inc"
49 cl::desc(
"Limit on instruction search range in frame index elimination"));
53 cl::desc(
"Limit on the number of reused registers in frame index "
62 return R == Hexagon::R0 || R == Hexagon::R1 || R == Hexagon::R2 ||
63 R == Hexagon::R3 || R == Hexagon::D0 || R == Hexagon::D1;
69 using namespace Hexagon;
72 R0, R1,
R2, R3,
R4, R5,
R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, 0
75 D0, D1, D2, D3, D4, D5, D6, D7, 0
81 V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13,
82 V14, V15, V16, V17, V18, V19, V20, V21, V22, V23, V24, V25, V26, V27,
86 W0, W1, W2, W3, W4, W5, W6, W7, W8, W9, W10, W11, W12, W13, W14, W15, 0
92 switch (RC->
getID()) {
93 case IntRegsRegClassID:
95 case DoubleRegsRegClassID:
97 case PredRegsRegClassID:
101 case HvxWRRegClassID:
103 case HvxQRRegClassID:
111 dbgs() <<
"Register class: " << getRegClassName(RC) <<
"\n";
120 static const MCPhysReg CalleeSavedRegsV3[] = {
121 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
122 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
123 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
128 static const MCPhysReg CalleeSavedRegsV3EHReturn[] = {
129 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3,
130 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
131 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
132 Hexagon::R24, Hexagon::R25, Hexagon::R26, Hexagon::R27, 0
137 return HasEHReturn ? CalleeSavedRegsV3EHReturn : CalleeSavedRegsV3;
143 return HexagonCSR_RegMask;
209 int SPAdj,
unsigned FIOp,
211 static unsigned ReuseCount = 0;
214 assert(SPAdj == 0 &&
"Unexpected");
221 auto &HFI = *HST.getFrameLowering();
224 int FI =
MI.getOperand(FIOp).getIndex();
227 int Offset = HFI.getFrameIndexReference(MF, FI, BP).getFixed();
229 int RealOffset =
Offset +
MI.getOperand(FIOp+1).getImm();
231 unsigned Opc =
MI.getOpcode();
233 case Hexagon::PS_fia:
234 MI.setDesc(HII.get(Hexagon::A2_addi));
235 MI.getOperand(FIOp).ChangeToImmediate(RealOffset);
236 MI.removeOperand(FIOp+1);
240 MI.setDesc(HII.get(Hexagon::A2_addi));
244 if (!HII.isValidOffset(Opc, RealOffset,
this)) {
256 switch (
MI.getOpcode()) {
258 case Hexagon::PS_vloadrw_ai:
259 case Hexagon::PS_vloadrw_nt_ai:
260 case Hexagon::PS_vstorerw_ai:
261 case Hexagon::PS_vstorerw_nt_ai:
264 case Hexagon::PS_vloadrv_ai:
265 case Hexagon::PS_vloadrv_nt_ai:
266 case Hexagon::PS_vstorerv_ai:
267 case Hexagon::PS_vstorerv_nt_ai:
268 case Hexagon::V6_vL32b_ai:
269 case Hexagon::V6_vS32b_ai: {
270 unsigned HwLen = HST.getVectorLength();
271 if (RealOffset % HwLen == 0) {
272 int VecOffset = RealOffset / HwLen;
278 if (!IsPair || (VecOffset + 1) % 16 != 0) {
279 RealOffset = (VecOffset & -16) * HwLen;
280 InstOffset = (VecOffset % 16 - 8) * HwLen;
293 bool PassedCall =
false;
296 for (
auto I = std::next(
II.getReverse()), E = MB.
rend();
I != E; ++
I) {
297 if (SearchCount == SearchRange)
302 PassedCall |= BI.
isCall();
304 if (SeenVRegs.
size() > 1)
306 if (
Op.isReg() &&
Op.getReg().isVirtual())
314 if (!Op2.isImm() || Op2.getImm() != RealOffset)
318 if (R.isPhysical()) {
319 if (Defs.available(R))
321 }
else if (R.isVirtual()) {
326 if (!PassedCall && SeenVRegs.
size() <= 1)
337 ReuseBP =
MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
339 BuildMI(MB,
II,
DL, HII.get(Hexagon::A2_addi), ReuseBP)
344 RealOffset = InstOffset;
347 MI.getOperand(FIOp).ChangeToRegister(BP,
false,
false,
false);
348 MI.getOperand(FIOp+1).ChangeToImmediate(RealOffset);
363 if (!HST.
useHVXOps() || NewRC->
getID() != Hexagon::HvxWRRegClass.getID())
365 bool SmallSrc = SrcRC->
getID() == Hexagon::HvxVRRegClass.getID();
366 bool SmallDst = DstRC->
getID() == Hexagon::HvxVRRegClass.getID();
367 if (!SmallSrc && !SmallDst)
374 for (
SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex();
375 I != E;
I =
I.getNextIndex()) {
383 if (SmallSrc == SmallDst) {
395 Register SmallReg = SmallSrc ? SrcReg : DstReg;
396 Register LargeReg = SmallSrc ? DstReg : SrcReg;
425 static const unsigned ISub[] = { Hexagon::isub_lo, Hexagon::isub_hi };
426 static const unsigned VSub[] = { Hexagon::vsub_lo, Hexagon::vsub_hi };
427 static const unsigned WSub[] = { Hexagon::wsub_lo, Hexagon::wsub_hi };
429 switch (RC.
getID()) {
430 case Hexagon::CtrRegs64RegClassID:
431 case Hexagon::DoubleRegsRegClassID:
433 case Hexagon::HvxWRRegClassID:
435 case Hexagon::HvxVQRRegClassID:
452 unsigned Kind)
const {
453 return &Hexagon::IntRegsRegClass;
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
Rewrite Partial Register Uses
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallSet class.
This class represents an Operation in the Expression.
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
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.
unsigned getID() const
Return the register class ID number.
sc_iterator getSuperClasses() const
Returns a NULL-terminated 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.