67#define DEBUG_TYPE "hexagon-pei"
162 if (!HST.getFrameLowering()->hasFP(MF))
173 Register SCSPReg = HST.getSCSPReg();
174 const auto &HRI = *HST.getRegisterInfo();
175 if (!HST.isRegisterReservedByUser(SCSPReg))
180 " to use shadow call stack on Hexagon");
182 const auto &HII = *HST.getInstrInfo();
196 MBB.addLiveIn(SCSPReg);
203 unsigned DwarfSCSReg = HRI.getDwarfRegNum(SCSPReg,
true);
206 assert(DwarfSCSReg < 32 &&
"SCS register should be < 32");
207 const char CFIInst[] = {
208 (
char)dwarf::DW_CFA_val_expression,
211 (
char)(
unsigned)(dwarf::DW_OP_breg0 + DwarfSCSReg),
231 Register SCSPReg = HST.getSCSPReg();
232 const auto &HII = *HST.getInstrInfo();
235 BuildMI(
MBB,
MI,
DL, HII.get(Hexagon::L2_loadri_io), Hexagon::R31)
254 cl::desc(
"Set the number of scavenger slots"),
259 cl::desc(
"Specify O2(not Os) spill func threshold"),
264 cl::desc(
"Specify Os spill func threshold"),
273 cl::desc(
"Enable stack frame shrink wrapping"));
278 cl::desc(
"Max count of stack frame shrink-wraps"));
282 cl::desc(
"Enable long calls for save-restore stubs."),
293 cl::init(std::numeric_limits<unsigned>::max()));
312 char HexagonCallFrameInformation::ID = 0;
316bool HexagonCallFrameInformation::runOnMachineFunction(
MachineFunction &MF) {
317 auto &HFI = *MF.
getSubtarget<HexagonSubtarget>().getFrameLowering();
322 HFI.insertCFIInstructions(MF);
327 "Hexagon call frame information",
false,
false)
330 return new HexagonCallFrameInformation();
347 if (!RegNo || SubReg < RegNo)
357 static_assert(Hexagon::R1 > 0,
358 "Assume physical registers are encoded as positive integers");
363 for (
unsigned I = 1,
E = CSI.
size();
I <
E; ++
I) {
384 unsigned Opc =
MI.getOpcode();
386 case Hexagon::PS_alloca:
409 for (
MCPhysReg S : HRI.subregs_inclusive(R))
414 if (MO.isRegMask()) {
419 const uint32_t *BM = MO.getRegMask();
423 if (!(BM[R / 32] & (1u << (R % 32))))
438 unsigned RetOpc =
I->getOpcode();
439 return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
461 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
462 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
463 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT:
464 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC:
465 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT:
466 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC:
467 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4:
468 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC:
481 return F.hasOptSize() && !
F.hasMinSize();
493 MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB)
const {
494 static unsigned ShrinkCounter = 0;
496 if (MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() &&
505 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
507 MachineDominatorTree MDT;
509 MachinePostDominatorTree MPT;
512 using UnsignedMap = DenseMap<unsigned, unsigned>;
513 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
519 RPO[
I->getNumber()] = RPON++;
525 unsigned BN = RPO[
I.getNumber()];
526 for (MachineBasicBlock *Succ :
I.successors())
528 if (RPO[Succ->getNumber()] <= BN)
535 BitVector CSR(Hexagon::NUM_TARGET_REGS);
536 for (
const MCPhysReg *
P = HRI.getCalleeSavedRegs(&MF); *
P; ++
P)
545 dbgs() <<
"Blocks needing SF: {";
546 for (
auto &
B : SFBlocks)
551 if (SFBlocks.
empty())
555 MachineBasicBlock *DomB = SFBlocks[0];
556 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
561 MachineBasicBlock *PDomB = SFBlocks[0];
562 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
568 dbgs() <<
"Computed dom block: ";
573 dbgs() <<
", computed pdom block: ";
589 LLVM_DEBUG(
dbgs() <<
"PDom block does not post-dominate dom block\n");
612 findShrunkPrologEpilog(MF, PrologB, EpilogB);
614 bool PrologueStubs =
false;
616 insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
622 insertAlignaInBlock(*PrologB, AfterCSR);
623 insertPrologueInBlock(*PrologB, PrologueStubs);
631 while (AfterProlog != PrologB->
end() &&
637 updateEntryPaths(MF, *PrologB);
640 insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
641 insertEpilogueInBlock(*EpilogB);
644 if (
B.isReturnBlock())
645 insertCSRRestoresInBlock(
B, CSI, HRI);
648 if (
B.isReturnBlock())
649 insertEpilogueInBlock(
B);
667 BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1);
668 updateExitPaths(*EpilogB, *EpilogB, DoneT, DoneF, Path);
677 assert(
F.hasFnAttribute(Attribute::NoReturn) &&
678 F.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
679 !
F.getFunction().hasFnAttribute(Attribute::UWTable));
695 assert(!MFI.hasVarSizedObjects() &&
696 !HST.getRegisterInfo()->hasStackRealignment(MF));
697 return F.hasFnAttribute(Attribute::NoReturn) &&
698 F.hasFnAttribute(Attribute::NoUnwind) &&
699 !
F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() &&
700 MFI.getStackSize() == 0;
703void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &
MBB,
704 bool PrologueStubs)
const {
720 FrameSize = MaxCFA +
alignTo(FrameSize, MaxAlign);
731 SmallVector<MachineInstr *, 4> AdjustRegs;
734 if (
MI.getOpcode() == Hexagon::PS_alloca)
737 for (
auto *
MI : AdjustRegs) {
738 assert((
MI->getOpcode() == Hexagon::PS_alloca) &&
"Expected alloca");
739 expandAlloca(
MI, MF, HII, SP, MaxCF);
740 MI->eraseFromParent();
745 if (MF.getFunction().isVarArg() &&
746 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
748 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
749 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0)
751 : NumVarArgRegs * 4 + 4;
752 if (RegisterSavedAreaSizePlusPadding > 0) {
755 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
757 .
addImm(-RegisterSavedAreaSizePlusPadding)
762 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
763 for (
int i = HMFI.getFirstNamedArgFrameIndex(),
764 e = HMFI.getLastNamedArgFrameIndex(); i >= e; --i) {
769 unsigned LDOpc, STOpc;
773 if (ObjAlign > ObjSize) {
776 else if (ObjSize <= 2)
778 else if (ObjSize <= 4)
780 else if (ObjSize > 4)
784 switch (OpcodeChecker) {
786 LDOpc = Hexagon::L2_loadrb_io;
787 STOpc = Hexagon::S2_storerb_io;
790 LDOpc = Hexagon::L2_loadrh_io;
791 STOpc = Hexagon::S2_storerh_io;
794 LDOpc = Hexagon::L2_loadri_io;
795 STOpc = Hexagon::S2_storeri_io;
799 LDOpc = Hexagon::L2_loadrd_io;
800 STOpc = Hexagon::S2_storerd_io;
804 Register RegUsed = LDOpc == Hexagon::L2_loadrd_io ? Hexagon::D3
806 int LoadStoreCount = ObjSize / OpcodeChecker;
808 if (ObjSize % OpcodeChecker)
816 NumBytes =
alignTo(NumBytes, ObjAlign);
819 while (
Count < LoadStoreCount) {
821 BuildMI(
MBB, InsertPt, dl, HII.get(LDOpc), RegUsed)
823 .
addImm(RegisterSavedAreaSizePlusPadding +
840 NumBytes =
alignTo(NumBytes, 8);
845 NumBytes = (NumVarArgRegs % 2 == 0) ? NumBytes : NumBytes + 4;
847 for (
int j = FirstVarArgSavedReg, i = 0;
j < 6; ++
j, ++i) {
848 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_storeri_io))
858 insertAllocframe(
MBB, InsertPt, NumBytes);
860 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP)
868 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_call_stk))
870 }
else if (NumBytes > 0) {
872 auto *TLI = HST.getTargetLowering();
873 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
874 unsigned ProbeSize = 0;
877 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
879 if (NeedsProbing && NumBytes > ProbeSize) {
881 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
886 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
890 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
898void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &
MBB)
const {
912 MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
914 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
915 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
916 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
917 NumBytes += RegisterSavedAreaSizePlusPadding;
920 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
928 unsigned RetOpc = RetI ? RetI->
getOpcode() : 0;
931 if (RetOpc == Hexagon::EH_RETURN_JMPR) {
934 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
937 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_add), SP)
948 if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
949 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC ||
950 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT ||
951 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC) {
968 bool NeedsDeallocframe =
true;
969 unsigned PrevOpc = 0;
972 PrevOpc = PrevIt->getOpcode();
973 if (PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
974 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC ||
975 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
976 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
977 PrevOpc == Hexagon::PS_call_nr || PrevOpc == Hexagon::PS_callr_nr)
978 NeedsDeallocframe =
false;
981 if (!MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() ||
983 if (!NeedsDeallocframe) {
988 if (NeedsSCS && PrevOpc != Hexagon::PS_call_nr &&
989 PrevOpc != Hexagon::PS_callr_nr)
991 "useRestoreFunction() should have prevented this");
998 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1007 unsigned NewOpc = Hexagon::L4_return;
1008 MachineInstr *NewI =
BuildMI(
MBB, RetI, dl, HII.get(NewOpc))
1017 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
1018 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
1019 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
1024 bool HasRestoreStub =
1026 (
I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
1028 Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
1029 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
1030 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC);
1031 if (!HasRestoreStub)
1032 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1035 if (RegisterSavedAreaSizePlusPadding != 0)
1036 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1038 .
addImm(RegisterSavedAreaSizePlusPadding);
1042 if (NeedsSCS && !HasRestoreStub)
1047void HexagonFrameLowering::insertAllocframe(MachineBasicBlock &
MBB,
1056 const unsigned int ALLOCFRAME_MAX = 16384;
1066 auto *TLI = HST.getTargetLowering();
1067 bool NeedsProbing = TLI->hasInlineStackProbe(MF) && NumBytes > 0;
1068 unsigned ProbeSize = 0;
1071 ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1074 if (NeedsProbing && NumBytes > ProbeSize) {
1076 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1084 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
1090 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
1093 }
else if (NumBytes >= ALLOCFRAME_MAX) {
1095 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1104 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1109 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1124 if (
MI.getOpcode() == Hexagon::PS_probed_stackalloc)
1129 auto *TLI = HST.getTargetLowering();
1131 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
1137 Register TargetReg =
MI->getOperand(0).getReg();
1144 MF.
insert(InsertPt, LoopMBB);
1147 MF.
insert(InsertPt, ExitMBB);
1168 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi),
1174 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
1180 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
1186 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
1192 BuildMI(*ExitMBB, ExitMBB->
begin(),
DL, HII.get(Hexagon::A2_tfr),
1198 MBB->addSuccessor(LoopMBB);
1203 MI->eraseFromParent();
1210void HexagonFrameLowering::insertAlignaInBlock(
1218 assert(needsAligna(MF) &&
"Unexpected stack align base register");
1223 BuildMI(
MBB, InsertPt,
DL, HII.get(Hexagon::PS_aligna), AP)
1237 for (
unsigned i = 0; i < Worklist.
size(); ++i) {
1238 unsigned BN = Worklist[i];
1241 if (!
MBB.isLiveIn(R.getReg()))
1242 MBB.addLiveIn(R.getReg());
1244 for (
auto &SB :
MBB.successors())
1245 Worklist.
insert(SB->getNumber());
1249bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &
MBB,
1250 MachineBasicBlock &RestoreB, BitVector &DoneT, BitVector &DoneF,
1251 BitVector &Path)
const {
1254 if (Path[BN] || DoneF[BN])
1262 bool ReachedExit =
false;
1264 ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path);
1270 MachineInstr &RetI =
MBB.
back();
1280 if (ReachedExit && &
MBB != &RestoreB) {
1293static std::optional<MachineBasicBlock::iterator>
1300 auto End =
B.instr_end();
1304 if (!
I.isBundle()) {
1305 if (
I.getOpcode() == Hexagon::S2_allocframe)
1306 return std::next(It);
1310 bool HasCall =
false, HasAllocFrame =
false;
1312 while (++
T != End &&
T->isBundled()) {
1313 if (
T->getOpcode() == Hexagon::S2_allocframe)
1314 HasAllocFrame =
true;
1315 else if (
T->isCall())
1319 return HasCall ? It : std::next(It);
1321 return std::nullopt;
1327 insertCFIInstructionsAt(
B, *At);
1342 const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION);
1345 bool HasFP = hasFP(MF);
1348 unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(),
true);
1349 unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(),
true);
1376 Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
1377 Hexagon::R17, Hexagon::R16, Hexagon::R19, Hexagon::R18,
1378 Hexagon::R21, Hexagon::R20, Hexagon::R23, Hexagon::R22,
1379 Hexagon::R25, Hexagon::R24, Hexagon::R27, Hexagon::R26,
1380 Hexagon::D0, Hexagon::D1, Hexagon::D8, Hexagon::D9,
1381 Hexagon::D10, Hexagon::D11, Hexagon::D12, Hexagon::D13
1387 auto IfR = [
Reg] (
const CalleeSavedInfo &
C) ->
bool {
1388 return C.getReg() ==
Reg;
1407 getFrameIndexReference(MF,
F->getFrameIdx(), FrameReg).getFixed();
1413 unsigned DwarfReg = HRI.getDwarfRegNum(
Reg,
true);
1425 Register HiReg = HRI.getSubReg(
Reg, Hexagon::isub_hi);
1426 Register LoReg = HRI.getSubReg(
Reg, Hexagon::isub_lo);
1427 unsigned HiDwarfReg = HRI.getDwarfRegNum(HiReg,
true);
1428 unsigned LoDwarfReg = HRI.getDwarfRegNum(LoReg,
true);
1444 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1460 if (HasAlloca || HasExtraAlign)
1489 bool Stkchk =
false) {
1490 const char * V4SpillToMemoryFunctions[] = {
1491 "__save_r16_through_r17",
1492 "__save_r16_through_r19",
1493 "__save_r16_through_r21",
1494 "__save_r16_through_r23",
1495 "__save_r16_through_r25",
1496 "__save_r16_through_r27" };
1498 const char * V4SpillToMemoryStkchkFunctions[] = {
1499 "__save_r16_through_r17_stkchk",
1500 "__save_r16_through_r19_stkchk",
1501 "__save_r16_through_r21_stkchk",
1502 "__save_r16_through_r23_stkchk",
1503 "__save_r16_through_r25_stkchk",
1504 "__save_r16_through_r27_stkchk" };
1506 const char * V4SpillFromMemoryFunctions[] = {
1507 "__restore_r16_through_r17_and_deallocframe",
1508 "__restore_r16_through_r19_and_deallocframe",
1509 "__restore_r16_through_r21_and_deallocframe",
1510 "__restore_r16_through_r23_and_deallocframe",
1511 "__restore_r16_through_r25_and_deallocframe",
1512 "__restore_r16_through_r27_and_deallocframe" };
1514 const char * V4SpillFromMemoryTailcallFunctions[] = {
1515 "__restore_r16_through_r17_and_deallocframe_before_tailcall",
1516 "__restore_r16_through_r19_and_deallocframe_before_tailcall",
1517 "__restore_r16_through_r21_and_deallocframe_before_tailcall",
1518 "__restore_r16_through_r23_and_deallocframe_before_tailcall",
1519 "__restore_r16_through_r25_and_deallocframe_before_tailcall",
1520 "__restore_r16_through_r27_and_deallocframe_before_tailcall"
1523 const char **SpillFunc =
nullptr;
1527 SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
1528 : V4SpillToMemoryFunctions;
1531 SpillFunc = V4SpillFromMemoryFunctions;
1534 SpillFunc = V4SpillFromMemoryTailcallFunctions;
1537 assert(SpillFunc &&
"Unknown spill kind");
1542 return SpillFunc[0];
1544 return SpillFunc[1];
1546 return SpillFunc[2];
1548 return SpillFunc[3];
1550 return SpillFunc[4];
1552 return SpillFunc[5];
1567 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1572 Register SP = HRI.getStackRegister();
1574 Register AP = HMFI.getStackAlignBaseReg();
1589 bool UseFP =
false, UseAP =
false;
1594 if (NoOpt && !HasExtraAlign)
1599 UseFP |= (HasAlloca || HasExtraAlign);
1610 bool HasFP =
hasFP(MF);
1611 assert((HasFP || !UseFP) &&
"This function must have frame pointer");
1637 if (
Offset > 0 && !HasFP)
1652 if (!UseFP && !UseAP)
1653 RealOffset = FrameSize+
Offset;
1659 bool &PrologueStubs)
const {
1664 PrologueStubs =
false;
1669 if (useSpillFunction(MF, CSI)) {
1670 PrologueStubs =
true;
1682 if (StkOvrFlowEnabled) {
1684 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
1685 : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
1687 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
1688 : Hexagon::SAVE_REGISTERS_CALL_V4STK;
1691 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
1692 : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
1694 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
1695 : Hexagon::SAVE_REGISTERS_CALL_V4;
1698 MachineInstr *SaveRegsCall =
1703 addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI,
false,
true);
1705 for (
const CalleeSavedInfo &
I : CSI)
1708 for (
const CalleeSavedInfo &
I : CSI) {
1709 MCRegister
Reg =
I.getReg();
1714 int FI =
I.getFrameIdx();
1725bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &
MBB,
1726 const CSIVect &CSI,
const HexagonRegisterInfo &HRI)
const {
1735 if (useRestoreFunction(MF, CSI)) {
1740 auto &HTM =
static_cast<const HexagonTargetMachine&
>(MF.
getTarget());
1741 bool IsPIC = HTM.isPositionIndependent();
1747 MachineInstr *DeallocCall =
nullptr;
1752 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
1753 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
1755 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
1756 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
1765 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
1766 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
1768 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
1769 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
1775 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI,
true,
false);
1779 for (
const CalleeSavedInfo &
I : CSI) {
1780 MCRegister
Reg =
I.getReg();
1782 int FI =
I.getFrameIdx();
1793 unsigned Opc =
MI.getOpcode();
1795 assert((
Opc == Hexagon::ADJCALLSTACKDOWN ||
Opc == Hexagon::ADJCALLSTACKUP) &&
1796 "Cannot handle this call frame pseudo instruction");
1797 return MBB.erase(
I);
1805 auto IsUsed = [&HRI,&MRI] (
Register Reg) ->
bool {
1837 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1864 "AP must be assigned before register allocation");
1869 bool HasResSub =
false;
1895 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1901 for (
int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
1939 int64_t MinOffset = 0;
1941 for (
const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
1946 MinOffset = std::min(MinOffset, S->Offset);
1948 SRegs[S->Reg] =
false;
1957 unsigned Size =
TRI->getSpillSize(*RC);
1958 int64_t Off = MinOffset -
Size;
1960 Off &= -Alignment.value();
1962 MinOffset = std::min(MinOffset, Off);
1968 dbgs() <<
"CS information: {";
1970 int FI =
I.getFrameIdx();
1982 bool MissedReg =
false;
2002 if (!Hexagon::ModRegsRegClass.
contains(DstR) ||
2003 !Hexagon::ModRegsRegClass.
contains(SrcR))
2007 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), TmpR).
add(
MI->getOperand(1));
2008 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), DstR)
2020 if (!
MI->getOperand(0).isFI())
2024 unsigned Opc =
MI->getOpcode();
2026 bool IsKill =
MI->getOperand(2).isKill();
2027 int FI =
MI->getOperand(0).getIndex();
2032 unsigned TfrOpc = (
Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
2038 BuildMI(
B, It,
DL, HII.get(Hexagon::S2_storeri_io))
2049bool HexagonFrameLowering::expandLoadInt(MachineBasicBlock &
B,
2051 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2052 MachineInstr *
MI = &*It;
2053 if (!
MI->getOperand(1).isFI())
2057 unsigned Opc =
MI->getOpcode();
2059 int FI =
MI->getOperand(1).getIndex();
2063 BuildMI(
B, It,
DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2070 unsigned TfrOpc = (
Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
2071 : Hexagon::A2_tfrrcr;
2073 .
addReg(TmpR, RegState::Kill);
2080bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &
B,
2082 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2083 MachineInstr *
MI = &*It;
2084 if (!
MI->getOperand(0).isFI())
2089 bool IsKill =
MI->getOperand(2).isKill();
2090 int FI =
MI->getOperand(0).getIndex();
2091 auto *RC = &Hexagon::HvxVRRegClass;
2100 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2103 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
2105 .
addReg(TmpR0, RegState::Kill);
2108 expandStoreVec(
B, std::prev(It), MRI, HII, NewRegs);
2116bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &
B,
2118 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2119 MachineInstr *
MI = &*It;
2120 if (!
MI->getOperand(1).isFI())
2125 int FI =
MI->getOperand(1).getIndex();
2126 auto *RC = &Hexagon::HvxVRRegClass;
2134 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2137 expandLoadVec(
B, std::prev(It), MRI, HII, NewRegs);
2139 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandvrt), DstR)
2140 .
addReg(TmpR1, RegState::Kill)
2141 .
addReg(TmpR0, RegState::Kill);
2149bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &
B,
2151 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2154 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2155 MachineInstr *
MI = &*It;
2156 if (!
MI->getOperand(0).isFI())
2163 LivePhysRegs LPR(HRI);
2166 for (
auto R =
B.begin(); R != It; ++R) {
2168 LPR.stepForward(*R, Clobbers);
2173 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
2174 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
2175 bool IsKill =
MI->getOperand(2).isKill();
2176 int FI =
MI->getOperand(0).getIndex();
2178 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2179 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2184 if (LPR.contains(SrcLo)) {
2185 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2186 : Hexagon::V6_vS32Ub_ai;
2195 if (LPR.contains(SrcHi)) {
2196 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2197 : Hexagon::V6_vS32Ub_ai;
2209bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &
B,
2211 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2214 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2215 MachineInstr *
MI = &*It;
2216 if (!
MI->getOperand(1).isFI())
2221 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
2222 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
2223 int FI =
MI->getOperand(1).getIndex();
2225 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2226 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2231 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2232 : Hexagon::V6_vL32Ub_ai;
2239 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2240 : Hexagon::V6_vL32Ub_ai;
2250bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &
B,
2252 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2255 MachineInstr *
MI = &*It;
2256 if (!
MI->getOperand(0).isFI())
2259 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2262 bool IsKill =
MI->getOperand(2).isKill();
2263 int FI =
MI->getOperand(0).getIndex();
2265 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2267 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2268 : Hexagon::V6_vS32Ub_ai;
2279bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &
B,
2281 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2284 MachineInstr *
MI = &*It;
2285 if (!
MI->getOperand(1).isFI())
2288 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2291 int FI =
MI->getOperand(1).getIndex();
2293 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2295 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2296 : Hexagon::V6_vL32Ub_ai;
2307 SmallVectorImpl<Register> &NewRegs)
const {
2308 auto &HII = *MF.
getSubtarget<HexagonSubtarget>().getInstrInfo();
2312 for (
auto &
B : MF) {
2315 for (
auto I =
B.begin(),
E =
B.end();
I !=
E;
I = NextI) {
2316 MachineInstr *
MI = &*
I;
2317 NextI = std::next(
I);
2318 unsigned Opc =
MI->getOpcode();
2321 case TargetOpcode::COPY:
2322 Changed |= expandCopy(
B,
I, MRI, HII, NewRegs);
2324 case Hexagon::STriw_pred:
2325 case Hexagon::STriw_ctr:
2326 Changed |= expandStoreInt(
B,
I, MRI, HII, NewRegs);
2328 case Hexagon::LDriw_pred:
2329 case Hexagon::LDriw_ctr:
2330 Changed |= expandLoadInt(
B,
I, MRI, HII, NewRegs);
2332 case Hexagon::PS_vstorerq_ai:
2333 Changed |= expandStoreVecPred(
B,
I, MRI, HII, NewRegs);
2335 case Hexagon::PS_vloadrq_ai:
2336 Changed |= expandLoadVecPred(
B,
I, MRI, HII, NewRegs);
2338 case Hexagon::PS_vloadrw_ai:
2339 Changed |= expandLoadVec2(
B,
I, MRI, HII, NewRegs);
2341 case Hexagon::PS_vstorerw_ai:
2342 Changed |= expandStoreVec2(
B,
I, MRI, HII, NewRegs);
2356 SavedRegs.
resize(HRI.getNumRegs());
2370 assert(AP.
isValid() &&
"AP must be assigned before register allocation");
2376 expandSpillMacros(MF, NewRegs);
2378 optimizeSpillSlots(MF, NewRegs);
2382 if (!NewRegs.
empty() || mayOverflowFrameOffset(MF)) {
2388 SpillRCs.
insert(&Hexagon::IntRegsRegClass);
2393 for (
const auto *RC : SpillRCs) {
2397 switch (RC->
getID()) {
2398 case Hexagon::IntRegsRegClassID:
2401 case Hexagon::HvxQRRegClassID:
2405 unsigned S = HRI.getSpillSize(*RC);
2406 Align A = HRI.getSpillAlign(*RC);
2407 for (
unsigned i = 0; i < Num; i++) {
2409 RS->addScavengingFrameIndex(NewFI);
2426 auto F = DeadMap.find({Reg,0});
2427 if (
F == DeadMap.end())
2429 for (
auto &DR :
F->second)
2430 if (DR.contains(FIR))
2435 for (
Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
2450 SmallVectorImpl<Register> &VRegs)
const {
2452 auto &HII = *HST.getInstrInfo();
2453 auto &HRI = *HST.getRegisterInfo();
2455 HexagonBlockRanges HBR(MF);
2457 using BlockIndexMap =
2458 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2459 using BlockRangeMap =
2460 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2461 using IndexType = HexagonBlockRanges::IndexType;
2468 SlotInfo() =
default;
2471 BlockIndexMap BlockIndexes;
2472 SmallSet<int,4> BadFIs;
2473 std::map<int,SlotInfo> FIRangeMap;
2482 if (HaveRC ==
nullptr || HaveRC == NewRC)
2487 if (NewRC->hasSubClassEq(HaveRC))
2494 for (
auto &
B : MF) {
2495 std::map<int,IndexType> LastStore, LastLoad;
2496 auto P = BlockIndexes.emplace(&
B, HexagonBlockRanges::InstrIndexMap(
B));
2497 auto &IndexMap =
P.first->second;
2499 << IndexMap <<
'\n');
2501 for (
auto &In :
B) {
2505 if (
In.isDebugInstr())
2508 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2509 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2523 int TFI =
Load ? LFI : SFI;
2524 unsigned AM = HII.getAddrMode(In);
2525 SlotInfo &
SI = FIRangeMap[TFI];
2529 unsigned OpNum =
Load ? 0 : 2;
2530 auto *RC = HII.getRegClass(
In.getDesc(), OpNum);
2531 RC = getCommonRC(
SI.RC, RC);
2539 unsigned S = HII.getMemAccessSize(In);
2540 if (
SI.Size != 0 &&
SI.Size != S)
2546 for (
auto *Mo :
In.memoperands()) {
2547 if (!Mo->isVolatile() && !Mo->isAtomic())
2558 for (
unsigned i = 0, n =
In.getNumOperands(); i < n; ++i) {
2559 const MachineOperand &
Op =
In.getOperand(i);
2562 int FI =
Op.getIndex();
2565 if (i+1 >= n || !
In.getOperand(i+1).isImm() ||
2566 In.getOperand(i+1).getImm() != 0)
2568 if (BadFIs.
count(FI))
2572 auto &
LS = LastStore[FI];
2573 auto &LL = LastLoad[FI];
2575 if (LS == IndexType::None)
2576 LS = IndexType::Entry;
2579 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2580 if (LS != IndexType::None)
2581 RL.
add(LS, LL,
false,
false);
2582 else if (LL != IndexType::None)
2583 RL.
add(IndexType::Entry, LL,
false,
false);
2584 LL = IndexType::None;
2592 for (
auto &
I : LastLoad) {
2593 IndexType LL =
I.second;
2594 if (LL == IndexType::None)
2596 auto &RL = FIRangeMap[
I.first].Map[&
B];
2597 IndexType &
LS = LastStore[
I.first];
2598 if (LS != IndexType::None)
2599 RL.
add(LS, LL,
false,
false);
2601 RL.
add(IndexType::Entry, LL,
false,
false);
2602 LS = IndexType::None;
2604 for (
auto &
I : LastStore) {
2605 IndexType
LS =
I.second;
2606 if (LS == IndexType::None)
2608 auto &RL = FIRangeMap[
I.first].Map[&
B];
2609 RL.
add(LS, IndexType::None,
false,
false);
2614 for (
auto &
P : FIRangeMap) {
2615 dbgs() <<
"fi#" <<
P.first;
2616 if (BadFIs.
count(
P.first))
2619 if (
P.second.RC !=
nullptr)
2620 dbgs() << HRI.getRegClassName(
P.second.RC) <<
'\n';
2622 dbgs() <<
"<null>\n";
2623 for (
auto &R :
P.second.Map)
2632 SmallSet<int,4> LoxFIs;
2634 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2636 for (
auto &
P : FIRangeMap) {
2638 if (BadFIs.
count(
P.first))
2640 for (
auto &
B : MF) {
2641 auto F =
P.second.Map.find(&
B);
2643 if (
F ==
P.second.Map.end() ||
F->second.empty())
2645 HexagonBlockRanges::IndexRange &
IR =
F->second.front();
2646 if (
IR.start() == IndexType::Entry)
2647 LoxFIs.insert(
P.first);
2648 BlockFIMap[&
B].push_back(
P.first);
2653 dbgs() <<
"Block-to-FI map (* -- live-on-exit):\n";
2654 for (
auto &
P : BlockFIMap) {
2655 auto &FIs =
P.second;
2659 for (
auto I : FIs) {
2660 dbgs() <<
" fi#" <<
I;
2661 if (LoxFIs.count(
I))
2673 for (
auto &
B : MF) {
2674 auto F = BlockIndexes.find(&
B);
2675 assert(
F != BlockIndexes.end());
2676 HexagonBlockRanges::InstrIndexMap &IM =
F->second;
2680 << HexagonBlockRanges::PrintRangeMap(
DM, HRI));
2682 for (
auto FI : BlockFIMap[&
B]) {
2683 if (BadFIs.
count(FI))
2686 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2687 for (
auto &
Range : RL) {
2689 if (!IndexType::isInstr(
Range.start()) ||
2690 !IndexType::isInstr(
Range.end()))
2694 assert(
SI.mayStore() &&
"Unexpected start instruction");
2696 MachineOperand &SrcOp =
SI.getOperand(2);
2698 HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.
getReg(),
2700 auto *RC = HII.getRegClass(
SI.getDesc(), 2);
2717 MachineInstr *CopyIn =
nullptr;
2718 if (SrcRR.
Reg != FoundR || SrcRR.
Sub != 0) {
2720 CopyIn =
BuildMI(
B, StartIt,
DL, HII.get(TargetOpcode::COPY), FoundR)
2726 if (LoxFIs.count(FI) && (&
Range == &RL.back())) {
2729 SrcOp.
setReg(HRI.getSubReg(FoundR, SR));
2741 for (
auto It = StartIt; It != EndIt; It = NextIt) {
2742 MachineInstr &
MI = *It;
2743 NextIt = std::next(It);
2745 if (!HII.isLoadFromStackSlot(
MI, TFI) || TFI != FI)
2748 assert(
MI.getOperand(0).getSubReg() == 0);
2749 MachineInstr *CopyOut =
nullptr;
2750 if (DstR != FoundR) {
2752 unsigned MemSize = HII.getMemAccessSize(
MI);
2754 unsigned CopyOpc = TargetOpcode::COPY;
2755 if (HII.isSignExtendingLoad(
MI))
2756 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2757 else if (HII.isZeroExtendingLoad(
MI))
2758 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2759 CopyOut =
BuildMI(
B, It,
DL, HII.get(CopyOpc), DstR)
2767 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2775void HexagonFrameLowering::expandAlloca(MachineInstr *AI,
MachineFunction &MF,
2776 const HexagonInstrInfo &HII,
2778 MachineBasicBlock &MB = *AI->
getParent();
2788 bool NeedsProbing = TLI->hasInlineStackProbe(MF);
2790 if (!NeedsProbing) {
2814 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2818 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), SP)
2856 unsigned ProbeSize = TLI->getStackProbeSize(MF, StackAlign);
2861 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_sub), Rd)
2867 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
2876 MF.
insert(InsertPt, LoopMBB);
2878 MF.
insert(InsertPt, ExitMBB);
2889 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi), Hexagon::R29)
2894 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
2900 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
2906 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
2915 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_tfr), Hexagon::R29)
2919 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_addi), Rd)
2947void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(
MachineInstr *
MI,
2948 const CSIVect &CSI,
bool IsDef,
bool IsKill)
const {
2959 const CSIVect &CSI)
const {
2972 BitVector Regs(Hexagon::NUM_TARGET_REGS);
2975 if (!Hexagon::DoubleRegsRegClass.
contains(R))
2979 int F = Regs.find_first();
2980 if (
F != Hexagon::D8)
2983 int N = Regs.find_next(
F);
2984 if (
N >= 0 &&
N !=
F+1)
2993 const CSIVect &CSI)
const {
2994 if (shouldInlineCSR(MF, CSI))
2996 unsigned NumCSI = CSI.size();
3015 if (HST.getSCSPReg().id() <= MaxReg.id())
3021 return Threshold < NumCSI;
3024bool HexagonFrameLowering::useRestoreFunction(
const MachineFunction &MF,
3025 const CSIVect &CSI)
const {
3026 if (shouldInlineCSR(MF, CSI))
3039 unsigned NumCSI = CSI.size();
3045 return Threshold < NumCSI;
3048bool HexagonFrameLowering::mayOverflowFrameOffset(
MachineFunction &MF)
const {
3053 if (HST.useHVXOps() && StackSize > 256)
3060 bool HasImmStack =
false;
3061 unsigned MinLS = ~0
u;
3063 for (
const MachineBasicBlock &
B : MF) {
3064 for (
const MachineInstr &
MI :
B) {
3066 switch (
MI.getOpcode()) {
3067 case Hexagon::S4_storeirit_io:
3068 case Hexagon::S4_storeirif_io:
3069 case Hexagon::S4_storeiri_io:
3072 case Hexagon::S4_storeirht_io:
3073 case Hexagon::S4_storeirhf_io:
3074 case Hexagon::S4_storeirh_io:
3077 case Hexagon::S4_storeirbt_io:
3078 case Hexagon::S4_storeirbf_io:
3079 case Hexagon::S4_storeirb_io:
3080 if (
MI.getOperand(0).isFI())
3082 MinLS = std::min(MinLS, LS);
3096struct HexagonFrameSortingObject {
3097 bool IsValid =
false;
3103struct HexagonFrameSortingComparator {
3104 inline bool operator()(
const HexagonFrameSortingObject &
A,
3105 const HexagonFrameSortingObject &
B)
const {
3106 return std::make_tuple(!
A.IsValid,
A.ObjectAlignment,
A.Size) <
3107 std::make_tuple(!
B.IsValid,
B.ObjectAlignment,
B.Size);
3117 if (ObjectsToAllocate.
empty())
3121 int NObjects = ObjectsToAllocate.
size();
3129 if (i != ObjectsToAllocate[j])
3140 SortingObjects[i].IsValid =
true;
3141 SortingObjects[i].Index = i;
3151 for (
auto &Obj : SortingObjects) {
3154 ObjectsToAllocate[--i] = Obj.Index;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static RegisterPass< DebugifyModulePass > DM("debugify", "Attach debug info to everything")
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
static MachineInstr * getReturn(MachineBasicBlock &MBB)
Returns the "return" instruction from this block, or nullptr if there isn't any.
static cl::opt< unsigned > ShrinkLimit("shrink-frame-limit", cl::init(std::numeric_limits< unsigned >::max()), cl::Hidden, cl::desc("Max count of stack frame shrink-wraps"))
static bool isOptNone(const MachineFunction &MF)
static cl::opt< int > SpillFuncThreshold("spill-func-threshold", cl::Hidden, cl::desc("Specify O2(not Os) spill func threshold"), cl::init(6))
static std::optional< MachineBasicBlock::iterator > findCFILocation(MachineBasicBlock &B)
static cl::opt< bool > EliminateFramePointer("hexagon-fp-elim", cl::init(true), cl::Hidden, cl::desc("Refrain from using FP whenever possible"))
static bool enableAllocFrameElim(const MachineFunction &MF)
static const char * getSpillFunctionFor(Register MaxReg, SpillKind SpillType, bool Stkchk=false)
static bool hasReturn(const MachineBasicBlock &MBB)
Returns true if MBB contains an instruction that returns.
static cl::opt< bool > EnableSaveRestoreLong("enable-save-restore-long", cl::Hidden, cl::desc("Enable long calls for save-restore stubs."), cl::init(false))
static bool needToReserveScavengingSpillSlots(MachineFunction &MF, const HexagonRegisterInfo &HRI, const TargetRegisterClass *RC)
Returns true if there are no caller-saved registers available in class RC.
static bool isOptSize(const MachineFunction &MF)
static Register getMax32BitSubRegister(Register Reg, const TargetRegisterInfo &TRI, bool hireg=true)
Map a register pair Reg to the subregister that has the greater "number", i.e.
static cl::opt< int > SpillFuncThresholdOs("spill-func-threshold-Os", cl::Hidden, cl::desc("Specify Os spill func threshold"), cl::init(1))
static bool needsStackFrame(const MachineBasicBlock &MBB, const BitVector &CSR, const HexagonRegisterInfo &HRI)
Checks if the basic block contains any instruction that needs a stack frame to be already in place.
static cl::opt< bool > DisableDeallocRet("disable-hexagon-dealloc-ret", cl::Hidden, cl::desc("Disable Dealloc Return for Hexagon target"))
static cl::opt< bool > EnableShrinkWrapping("hexagon-shrink-frame", cl::init(true), cl::Hidden, cl::desc("Enable stack frame shrink wrapping"))
static bool hasTailCall(const MachineBasicBlock &MBB)
Returns true if MBB has a machine instructions that indicates a tail call in the block.
static cl::opt< unsigned > NumberScavengerSlots("number-scavenger-slots", cl::Hidden, cl::desc("Set the number of scavenger slots"), cl::init(2))
static Register getMaxCalleeSavedReg(ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo &TRI)
Returns the callee saved register with the largest id in the vector.
static bool isMinSize(const MachineFunction &MF)
static cl::opt< unsigned > SpillOptMax("spill-opt-max", cl::Hidden, cl::init(std::numeric_limits< unsigned >::max()))
static unsigned SpillOptCount
static void dump_registers(BitVector &Regs, const TargetRegisterInfo &TRI)
static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static bool isRestoreCall(unsigned Opc)
static cl::opt< bool > OptimizeSpillSlots("hexagon-opt-spill", cl::Hidden, cl::init(true), cl::desc("Optimize spill slots"))
static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static cl::opt< bool > EnableStackOVFSanitizer("enable-stackovf-sanitizer", cl::Hidden, cl::desc("Enable runtime checks for stack overflow."), cl::init(false))
Legalize the Machine IR a function s Machine IR
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file declares the machine register scavenger class.
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
BitVector & set()
Set all bits in the bitvector.
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
Helper class for creating CFI instructions and inserting them into MIR.
void buildEscape(StringRef Bytes, StringRef Comment="") const
void buildRestore(MCRegister Reg) const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
bool hasOptNone() const
Do not optimize this function (-O0).
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI)
IndexType getIndex(MachineInstr *MI) const
MachineInstr * getInstr(IndexType Idx) const
void add(IndexType Start, IndexType End, bool Fixed, bool TiedEnd)
void insertCFIInstructions(MachineFunction &MF) const
bool hasFPImpl(const MachineFunction &MF) const override
bool enableCalleeSaveSkip(const MachineFunction &MF) const override
Returns true if the target can safely skip saving callee-saved registers for noreturn nounwind functi...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Perform most of the PEI work here:
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void orderFrameObjects(const MachineFunction &MF, SmallVectorImpl< int > &ObjectsToAllocate) const override
Order the symbols in the local stack frame.
void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologueMBB) const override
Replace a StackProbe stub (if any) with the actual probe code inline.
const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override
getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...
bool needsAligna(const MachineFunction &MF) const
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
const HexagonRegisterInfo & getRegisterInfo() const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
Hexagon target-specific information for each MachineFunction.
Register getStackAlignBaseReg() const
bool isEHReturnCalleeSaveReg(Register Reg) const
const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override
Code Generation virtual methods...
const MCPhysReg * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
const HexagonInstrInfo * getInstrInfo() const override
const HexagonFrameLowering * getFrameLowering() const override
bool isEnvironmentMusl() const
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Describe properties that are true of each instruction in the target description file.
MCRegAliasIterator enumerates all registers aliasing Reg.
unsigned getID() const
getID() - Return the register class ID number.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
Wrapper class representing physical registers. Should be passed by value.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< succ_iterator > successors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
bool dominates(const MachineInstr *A, const MachineInstr *B) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setMaxCallFrameSize(uint64_t S)
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool hasCalls() const
Return true if the current function has any function calls.
Align getMaxAlign() const
Return alignment of this function's frame.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
LLVM_ABI int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
MachineBasicBlock * getBlockNumbered(unsigned N) const
getBlockNumbered - MachineBasicBlocks are automatically numbered when they are inserted into the mach...
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
BasicBlockListType::iterator iterator
LLVM_ABI bool disableFramePointerElim() const
Returns true if frame pointer elimination should be disabled for this function.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
instr_iterator getInstrIterator() const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isReturn(QueryType Type=AnyInBundle) const
const MachineBasicBlock * getParent() const
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
LLVM_ABI void copyImplicitOps(MachineFunction &MF, const MachineInstr &MI)
Copy implicit register operands from specified instruction to this instruction.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
LLVM_ABI MachineBasicBlock * findNearestCommonDominator(ArrayRef< MachineBasicBlock * > Blocks) const
Returns the nearest common dominator of the given blocks.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI bool isPhysRegUsed(MCRegister PhysReg, bool SkipRegMaskTest=false) const
Return true if the specified register is modified or read in this function.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
int64_t getFixed() const
Returns the fixed component of the stack.
Represent a constant reference to a string, i.e.
LLVM_ABI std::string lower() const
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const TargetRegisterInfo & getRegisterInfo() const
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
bool isPositionIndependent() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
constexpr RegState getKillRegState(bool B)
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createHexagonCallFrameInformation()
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
DWARFExpression::Operation Op
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
MaybeAlign getStackAlign(const Function &F, unsigned Index)
void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)
Convenience function for recomputing live-in's for a set of MBBs until the computation converges.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
static RegisterSet expandToSubRegs(RegisterRef R, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
std::map< RegisterRef, RangeList > RegToRangeMap
static LLVM_ABI MachinePointerInfo getStack(MachineFunction &MF, int64_t Offset, uint8_t ID=0)
Stack pointer relative access.