68#define DEBUG_TYPE "hexagon-pei"
78 return containsHLXObject(HST, EltTy);
176 if (!HST.getFrameLowering()->hasFP(MF))
187 Register SCSPReg = HST.getSCSPReg();
188 const auto &HRI = *HST.getRegisterInfo();
189 if (!HST.isRegisterReservedByUser(SCSPReg))
194 " to use shadow call stack on Hexagon");
196 const auto &HII = *HST.getInstrInfo();
210 MBB.addLiveIn(SCSPReg);
217 unsigned DwarfSCSReg = HRI.getDwarfRegNum(SCSPReg,
true);
220 assert(DwarfSCSReg < 32 &&
"SCS register should be < 32");
221 const char CFIInst[] = {
222 (
char)dwarf::DW_CFA_val_expression,
225 (
char)(
unsigned)(dwarf::DW_OP_breg0 + DwarfSCSReg),
245 Register SCSPReg = HST.getSCSPReg();
246 const auto &HII = *HST.getInstrInfo();
249 BuildMI(
MBB,
MI,
DL, HII.get(Hexagon::L2_loadri_io), Hexagon::R31)
268 cl::desc(
"Set the number of scavenger slots"),
273 cl::desc(
"Specify O2(not Os) spill func threshold"),
278 cl::desc(
"Specify Os spill func threshold"),
287 cl::desc(
"Enable stack frame shrink wrapping"));
292 cl::desc(
"Max count of stack frame shrink-wraps"));
296 cl::desc(
"Enable long calls for save-restore stubs."),
307 cl::init(std::numeric_limits<unsigned>::max()));
326 char HexagonCallFrameInformation::ID = 0;
330bool HexagonCallFrameInformation::runOnMachineFunction(
MachineFunction &MF) {
331 auto &HFI = *MF.
getSubtarget<HexagonSubtarget>().getFrameLowering();
336 HFI.insertCFIInstructions(MF);
341 "Hexagon call frame information",
false,
false)
344 return new HexagonCallFrameInformation();
361 if (!RegNo || SubReg < RegNo)
371 static_assert(Hexagon::R1 > 0,
372 "Assume physical registers are encoded as positive integers");
377 for (
unsigned I = 1,
E = CSI.
size();
I <
E; ++
I) {
398 unsigned Opc =
MI.getOpcode();
400 case Hexagon::PS_alloca:
423 for (
MCPhysReg S : HRI.subregs_inclusive(R))
428 if (MO.isRegMask()) {
433 const uint32_t *BM = MO.getRegMask();
437 if (!(BM[R / 32] & (1u << (R % 32))))
452 unsigned RetOpc =
I->getOpcode();
453 return RetOpc == Hexagon::PS_tailcall_i || RetOpc == Hexagon::PS_tailcall_r;
475 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
476 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
477 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT:
478 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC:
479 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT:
480 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC:
481 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4:
482 case Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC:
495 return F.hasOptSize() && !
F.hasMinSize();
507 MachineBasicBlock *&PrologB, MachineBasicBlock *&EpilogB)
const {
508 static unsigned ShrinkCounter = 0;
510 if (MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() &&
519 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
521 MachineDominatorTree MDT;
523 MachinePostDominatorTree MPT;
526 using UnsignedMap = DenseMap<unsigned, unsigned>;
527 using RPOTType = ReversePostOrderTraversal<const MachineFunction *>;
533 RPO[
I->getNumber()] = RPON++;
539 unsigned BN = RPO[
I.getNumber()];
540 for (MachineBasicBlock *Succ :
I.successors())
542 if (RPO[Succ->getNumber()] <= BN)
549 BitVector CSR(Hexagon::NUM_TARGET_REGS);
550 for (
const MCPhysReg *
P = HRI.getCalleeSavedRegs(&MF); *
P; ++
P)
559 dbgs() <<
"Blocks needing SF: {";
560 for (
auto &
B : SFBlocks)
565 if (SFBlocks.
empty())
569 MachineBasicBlock *DomB = SFBlocks[0];
570 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
575 MachineBasicBlock *PDomB = SFBlocks[0];
576 for (
unsigned i = 1, n = SFBlocks.
size(); i < n; ++i) {
582 dbgs() <<
"Computed dom block: ";
587 dbgs() <<
", computed pdom block: ";
603 LLVM_DEBUG(
dbgs() <<
"PDom block does not post-dominate dom block\n");
626 findShrunkPrologEpilog(MF, PrologB, EpilogB);
628 bool PrologueStubs =
false;
630 insertCSRSpillsInBlock(*PrologB, CSI, HRI, PrologueStubs);
636 insertAlignaInBlock(*PrologB, AfterCSR);
637 insertPrologueInBlock(*PrologB, PrologueStubs);
645 while (AfterProlog != PrologB->
end() &&
651 updateEntryPaths(MF, *PrologB);
654 insertCSRRestoresInBlock(*EpilogB, CSI, HRI);
655 insertEpilogueInBlock(*EpilogB);
658 if (
B.isReturnBlock())
659 insertCSRRestoresInBlock(
B, CSI, HRI);
662 if (
B.isReturnBlock())
663 insertEpilogueInBlock(
B);
681 BitVector DoneT(MaxBN+1), DoneF(MaxBN+1), Path(MaxBN+1);
682 updateExitPaths(*EpilogB, *EpilogB, DoneT, DoneF, Path);
691 assert(
F.hasFnAttribute(Attribute::NoReturn) &&
692 F.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
693 !
F.getFunction().hasFnAttribute(Attribute::UWTable));
709 assert(!MFI.hasVarSizedObjects() &&
710 !HST.getRegisterInfo()->hasStackRealignment(MF));
711 return F.hasFnAttribute(Attribute::NoReturn) &&
712 F.hasFnAttribute(Attribute::NoUnwind) &&
713 !
F.hasFnAttribute(Attribute::UWTable) && HST.noreturnStackElim() &&
714 MFI.getStackSize() == 0;
717void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &
MBB,
718 bool PrologueStubs)
const {
724 auto &HMFI = *MF.
getInfo<HexagonMachineFunctionInfo>();
727 uint64_t VTCMFrameSize = HMFI.getVTCMFrameInfo().getStackSize();
736 FrameSize = MaxCFA +
alignTo(FrameSize, MaxAlign);
747 SmallVector<MachineInstr *, 4> AdjustRegs;
750 if (
MI.getOpcode() == Hexagon::PS_alloca)
753 for (
auto *
MI : AdjustRegs) {
754 assert((
MI->getOpcode() == Hexagon::PS_alloca) &&
"Expected alloca");
755 expandAlloca(
MI, MF, HII, SP, MaxCF);
756 MI->eraseFromParent();
761 if (MF.getFunction().isVarArg() &&
762 MF.getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
764 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
765 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0)
767 : NumVarArgRegs * 4 + 4;
768 if (RegisterSavedAreaSizePlusPadding > 0) {
771 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
773 .
addImm(-RegisterSavedAreaSizePlusPadding)
778 auto &HMFI = *MF.getInfo<HexagonMachineFunctionInfo>();
779 for (
int i = HMFI.getFirstNamedArgFrameIndex(),
780 e = HMFI.getLastNamedArgFrameIndex(); i >= e; --i) {
785 unsigned LDOpc, STOpc;
789 if (ObjAlign > ObjSize) {
792 else if (ObjSize <= 2)
794 else if (ObjSize <= 4)
796 else if (ObjSize > 4)
800 switch (OpcodeChecker) {
802 LDOpc = Hexagon::L2_loadrb_io;
803 STOpc = Hexagon::S2_storerb_io;
806 LDOpc = Hexagon::L2_loadrh_io;
807 STOpc = Hexagon::S2_storerh_io;
810 LDOpc = Hexagon::L2_loadri_io;
811 STOpc = Hexagon::S2_storeri_io;
815 LDOpc = Hexagon::L2_loadrd_io;
816 STOpc = Hexagon::S2_storerd_io;
820 Register RegUsed = LDOpc == Hexagon::L2_loadrd_io ? Hexagon::D3
822 int LoadStoreCount = ObjSize / OpcodeChecker;
824 if (ObjSize % OpcodeChecker)
832 NumBytes =
alignTo(NumBytes, ObjAlign);
835 while (
Count < LoadStoreCount) {
837 BuildMI(
MBB, InsertPt, dl, HII.get(LDOpc), RegUsed)
839 .
addImm(RegisterSavedAreaSizePlusPadding +
856 NumBytes =
alignTo(NumBytes, 8);
861 NumBytes = (NumVarArgRegs % 2 == 0) ? NumBytes : NumBytes + 4;
863 for (
int j = FirstVarArgSavedReg, i = 0;
j < 6; ++
j, ++i) {
864 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_storeri_io))
874 insertAllocframe(
MBB, InsertPt, NumBytes);
876 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_andir), SP)
878 .
addImm(-int64_t(MaxAlign.value()));
884 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_call_stk))
886 }
else if (NumBytes > 0) {
888 auto *
TLI = HST.getTargetLowering();
890 unsigned ProbeSize = 0;
893 ProbeSize =
TLI->getStackProbeSize(MF, StackAlign);
895 if (NeedsProbing && NumBytes > ProbeSize) {
897 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
902 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
906 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
913 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::V2_vallocframe_imm))
914 .
addImm(VTCMFrameSize / 2048)
918void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &
MBB)
const {
928 const auto &HMFI = *MF.
getInfo<HexagonMachineFunctionInfo>();
929 uint64_t VTCMFrameSize = HMFI.getVTCMFrameInfo().getStackSize();
931 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::V2_vdeallocframe_imm))
932 .
addImm(VTCMFrameSize / 2048);
938 MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl()) {
940 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
941 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
942 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
943 NumBytes += RegisterSavedAreaSizePlusPadding;
946 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
954 unsigned RetOpc = RetI ? RetI->
getOpcode() : 0;
957 if (RetOpc == Hexagon::EH_RETURN_JMPR) {
960 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
963 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_add), SP)
974 if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
975 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC ||
976 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT ||
977 RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC) {
994 bool NeedsDeallocframe =
true;
995 unsigned PrevOpc = 0;
998 PrevOpc = PrevIt->getOpcode();
999 if (PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
1000 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC ||
1001 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
1002 PrevOpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
1003 PrevOpc == Hexagon::PS_call_nr || PrevOpc == Hexagon::PS_callr_nr)
1004 NeedsDeallocframe =
false;
1007 if (!MF.
getSubtarget<HexagonSubtarget>().isEnvironmentMusl() ||
1009 if (!NeedsDeallocframe) {
1014 if (NeedsSCS && PrevOpc != Hexagon::PS_call_nr &&
1015 PrevOpc != Hexagon::PS_callr_nr)
1017 "useRestoreFunction() should have prevented this");
1024 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1033 unsigned NewOpc = Hexagon::L4_return;
1034 MachineInstrBuilder NewI =
BuildMI(
MBB, RetI, dl, HII.get(NewOpc))
1044 int NumVarArgRegs = 6 - FirstVarArgSavedReg;
1045 int RegisterSavedAreaSizePlusPadding = (NumVarArgRegs % 2 == 0) ?
1046 (NumVarArgRegs * 4) : (NumVarArgRegs * 4 + 4);
1051 bool HasRestoreStub =
1053 (
I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT ||
1055 Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC ||
1056 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
1057 I->getOpcode() == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC);
1058 if (!HasRestoreStub)
1059 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::L2_deallocframe))
1062 if (RegisterSavedAreaSizePlusPadding != 0)
1063 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1065 .
addImm(RegisterSavedAreaSizePlusPadding);
1069 if (NeedsSCS && !HasRestoreStub)
1074void HexagonFrameLowering::insertAllocframe(MachineBasicBlock &
MBB,
1083 const unsigned int ALLOCFRAME_MAX = 16384;
1093 auto *
TLI = HST.getTargetLowering();
1095 unsigned ProbeSize = 0;
1098 ProbeSize =
TLI->getStackProbeSize(MF, StackAlign);
1101 if (NeedsProbing && NumBytes > ProbeSize) {
1103 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1111 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), Hexagon::R28)
1117 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::PS_probed_stackalloc))
1120 }
else if (NumBytes >= ALLOCFRAME_MAX) {
1122 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1131 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::A2_addi), SP)
1136 BuildMI(
MBB, InsertPt, dl, HII.get(Hexagon::S2_allocframe))
1151 if (
MI.getOpcode() == Hexagon::PS_probed_stackalloc)
1156 auto *
TLI = HST.getTargetLowering();
1158 unsigned ProbeSize =
TLI->getStackProbeSize(MF, StackAlign);
1164 Register TargetReg =
MI->getOperand(0).getReg();
1171 MF.
insert(InsertPt, LoopMBB);
1174 MF.
insert(InsertPt, ExitMBB);
1195 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi),
1201 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
1207 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
1213 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
1219 BuildMI(*ExitMBB, ExitMBB->
begin(),
DL, HII.get(Hexagon::A2_tfr),
1225 MBB->addSuccessor(LoopMBB);
1230 MI->eraseFromParent();
1237void HexagonFrameLowering::insertAlignaInBlock(
1245 assert(needsAligna(MF) &&
"Unexpected stack align base register");
1250 BuildMI(
MBB, InsertPt,
DL, HII.get(Hexagon::PS_aligna), AP)
1264 for (
unsigned i = 0; i < Worklist.
size(); ++i) {
1265 unsigned BN = Worklist[i];
1268 if (!
MBB.isLiveIn(R.getReg()))
1269 MBB.addLiveIn(R.getReg());
1271 for (
auto &SB :
MBB.successors())
1272 Worklist.
insert(SB->getNumber());
1276bool HexagonFrameLowering::updateExitPaths(MachineBasicBlock &
MBB,
1277 MachineBasicBlock &RestoreB, BitVector &DoneT, BitVector &DoneF,
1278 BitVector &Path)
const {
1281 if (Path[BN] || DoneF[BN])
1289 bool ReachedExit =
false;
1291 ReachedExit |= updateExitPaths(*SB, RestoreB, DoneT, DoneF, Path);
1297 MachineInstr &RetI =
MBB.
back();
1307 if (ReachedExit && &
MBB != &RestoreB) {
1320static std::optional<MachineBasicBlock::iterator>
1327 auto End =
B.instr_end();
1331 if (!
I.isBundle()) {
1332 if (
I.getOpcode() == Hexagon::S2_allocframe)
1333 return std::next(It);
1337 bool HasCall =
false, HasAllocFrame =
false;
1339 while (++
T !=
End &&
T->isBundled()) {
1340 if (
T->getOpcode() == Hexagon::S2_allocframe)
1341 HasAllocFrame =
true;
1342 else if (
T->isCall())
1346 return HasCall ? It : std::next(It);
1348 return std::nullopt;
1354 insertCFIInstructionsAt(
B, *At);
1369 const MCInstrDesc &CFID = HII.get(TargetOpcode::CFI_INSTRUCTION);
1372 bool HasFP = hasFP(MF);
1375 unsigned DwFPReg = HRI.getDwarfRegNum(HRI.getFrameRegister(),
true);
1376 unsigned DwRAReg = HRI.getDwarfRegNum(HRI.getRARegister(),
true);
1403 Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
1404 Hexagon::R17, Hexagon::R16, Hexagon::R19, Hexagon::R18,
1405 Hexagon::R21, Hexagon::R20, Hexagon::R23, Hexagon::R22,
1406 Hexagon::R25, Hexagon::R24, Hexagon::R27, Hexagon::R26,
1407 Hexagon::D0, Hexagon::D1, Hexagon::D8, Hexagon::D9,
1408 Hexagon::D10, Hexagon::D11, Hexagon::D12, Hexagon::D13
1414 auto IfR = [
Reg] (
const CalleeSavedInfo &
C) ->
bool {
1415 return C.getReg() ==
Reg;
1434 getFrameIndexReference(MF,
F->getFrameIdx(), FrameReg).getFixed();
1440 unsigned DwarfReg = HRI.getDwarfRegNum(
Reg,
true);
1452 Register HiReg = HRI.getSubReg(
Reg, Hexagon::isub_hi);
1453 Register LoReg = HRI.getSubReg(
Reg, Hexagon::isub_lo);
1454 unsigned HiDwarfReg = HRI.getDwarfRegNum(HiReg,
true);
1455 unsigned LoDwarfReg = HRI.getDwarfRegNum(LoReg,
true);
1471 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1487 if (HasAlloca || HasExtraAlign)
1503 if (HMFI.getVTCMFrameInfo().getStackSize())
1518 bool Stkchk =
false) {
1519 const char * V4SpillToMemoryFunctions[] = {
1520 "__save_r16_through_r17",
1521 "__save_r16_through_r19",
1522 "__save_r16_through_r21",
1523 "__save_r16_through_r23",
1524 "__save_r16_through_r25",
1525 "__save_r16_through_r27" };
1527 const char * V4SpillToMemoryStkchkFunctions[] = {
1528 "__save_r16_through_r17_stkchk",
1529 "__save_r16_through_r19_stkchk",
1530 "__save_r16_through_r21_stkchk",
1531 "__save_r16_through_r23_stkchk",
1532 "__save_r16_through_r25_stkchk",
1533 "__save_r16_through_r27_stkchk" };
1535 const char * V4SpillFromMemoryFunctions[] = {
1536 "__restore_r16_through_r17_and_deallocframe",
1537 "__restore_r16_through_r19_and_deallocframe",
1538 "__restore_r16_through_r21_and_deallocframe",
1539 "__restore_r16_through_r23_and_deallocframe",
1540 "__restore_r16_through_r25_and_deallocframe",
1541 "__restore_r16_through_r27_and_deallocframe" };
1543 const char * V4SpillFromMemoryTailcallFunctions[] = {
1544 "__restore_r16_through_r17_and_deallocframe_before_tailcall",
1545 "__restore_r16_through_r19_and_deallocframe_before_tailcall",
1546 "__restore_r16_through_r21_and_deallocframe_before_tailcall",
1547 "__restore_r16_through_r23_and_deallocframe_before_tailcall",
1548 "__restore_r16_through_r25_and_deallocframe_before_tailcall",
1549 "__restore_r16_through_r27_and_deallocframe_before_tailcall"
1552 const char **SpillFunc =
nullptr;
1556 SpillFunc = Stkchk ? V4SpillToMemoryStkchkFunctions
1557 : V4SpillToMemoryFunctions;
1560 SpillFunc = V4SpillFromMemoryFunctions;
1563 SpillFunc = V4SpillFromMemoryTailcallFunctions;
1566 assert(SpillFunc &&
"Unknown spill kind");
1571 return SpillFunc[0];
1573 return SpillFunc[1];
1575 return SpillFunc[2];
1577 return SpillFunc[3];
1579 return SpillFunc[4];
1581 return SpillFunc[5];
1595 if (HMFI.isVTCMStackIndex(FI)) {
1597 FrameReg = HRI.getVTCMStackRegister();
1599 HMFI.getMappedVTCMObjectOffset(FI));
1604 bool HasExtraAlign = HRI.hasStackRealignment(MF);
1608 Register SP = HRI.getStackRegister();
1610 Register AP = HMFI.getStackAlignBaseReg();
1625 bool UseFP =
false, UseAP =
false;
1630 if (NoOpt && !HasExtraAlign)
1635 UseFP |= (HasAlloca || HasExtraAlign);
1646 bool HasFP =
hasFP(MF);
1647 assert((HasFP || !UseFP) &&
"This function must have frame pointer");
1673 if (
Offset > 0 && !HasFP)
1688 if (!UseFP && !UseAP)
1689 RealOffset = FrameSize+
Offset;
1695 bool &PrologueStubs)
const {
1700 PrologueStubs =
false;
1705 if (useSpillFunction(MF, CSI)) {
1706 PrologueStubs =
true;
1718 if (StkOvrFlowEnabled) {
1720 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT_PIC
1721 : Hexagon::SAVE_REGISTERS_CALL_V4STK_EXT;
1723 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4STK_PIC
1724 : Hexagon::SAVE_REGISTERS_CALL_V4STK;
1727 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC
1728 : Hexagon::SAVE_REGISTERS_CALL_V4_EXT;
1730 SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
1731 : Hexagon::SAVE_REGISTERS_CALL_V4;
1734 MachineInstr *SaveRegsCall =
1739 addCalleeSaveRegistersAsImpOperand(SaveRegsCall, CSI,
false,
true);
1741 for (
const CalleeSavedInfo &
I : CSI)
1744 for (
const CalleeSavedInfo &
I : CSI) {
1745 MCRegister
Reg =
I.getReg();
1750 int FI =
I.getFrameIdx();
1761bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &
MBB,
1762 const CSIVect &CSI,
const HexagonRegisterInfo &HRI)
const {
1771 if (useRestoreFunction(MF, CSI)) {
1776 auto &HTM =
static_cast<const HexagonTargetMachine&
>(MF.
getTarget());
1777 bool IsPIC = HTM.isPositionIndependent();
1783 MachineInstr *DeallocCall =
nullptr;
1788 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT_PIC
1789 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_EXT;
1791 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
1792 : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
1801 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT_PIC
1802 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4_EXT;
1804 RetOpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
1805 : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
1806 MachineInstrBuilder MIB =
1810 for (
const MachineOperand &MO :
drop_begin(It->implicit_operands()))
1814 addCalleeSaveRegistersAsImpOperand(DeallocCall, CSI,
true,
false);
1818 for (
const CalleeSavedInfo &
I : CSI) {
1819 MCRegister
Reg =
I.getReg();
1821 int FI =
I.getFrameIdx();
1832 unsigned Opc =
MI.getOpcode();
1834 assert((
Opc == Hexagon::ADJCALLSTACKDOWN ||
Opc == Hexagon::ADJCALLSTACKUP) &&
1835 "Cannot handle this call frame pseudo instruction");
1836 return MBB.erase(
I);
1839void HexagonFrameLowering::computeVTCMStackOffsets(
MachineFunction &MF)
const {
1842 const auto &HRI = *HST.getRegisterInfo();
1845 const int64_t HlxLRSize = HRI.getSpillSize(Hexagon::HlxLRRegClass);
1856 if (!IsHlxLRSpill &&
1863 IsHlxLRSpill ? VTCMFrameInfo.CreateSpillStackObject(
Size, Alignment)
1864 : VTCMFrameInfo.CreateStackObject(
1867 VTCMFrameInfo.setObjectOffset(VTCMIndex, -
Offset);
1868 HMFI.moveToVTCMStack(
I, VTCMIndex);
1871 VTCMFrameInfo.setStackSize(
Offset);
1877 if (HST.hasV85OpsOnly() && HST.useHLXOps())
1878 computeVTCMStackOffsets(MF);
1884 if (!HST.hasV85OpsOnly() || !HST.useHLXOps())
1904 if (
MRI.isPhysRegUsed(*AI))
1934 BitVector SRegs(Hexagon::NUM_TARGET_REGS);
1961 "AP must be assigned before register allocation");
1966 bool HasResSub =
false;
1993 BitVector TmpSup(Hexagon::NUM_TARGET_REGS);
1996 if (Hexagon::HlxLRRegClass.
contains(R))
2001 for (
int x = TmpSup.find_first(); x >= 0; x = TmpSup.find_next(x)) {
2039 int64_t MinOffset = 0;
2041 for (
const SpillSlot *S = FixedSlots; S != FixedSlots+NumFixed; ++S) {
2046 MinOffset = std::min(MinOffset, S->Offset);
2048 SRegs[S->Reg] =
false;
2057 unsigned Size =
TRI->getSpillSize(*RC);
2059 if (Hexagon::HlxLRRegClass.
contains(R)) {
2065 int64_t
Off = MinOffset -
Size;
2067 Off &= -Alignment.value();
2069 MinOffset = std::min(MinOffset,
Off);
2075 dbgs() <<
"CS information: {";
2077 int FI =
I.getFrameIdx();
2089 bool MissedReg =
false;
2109 if (!Hexagon::ModRegsRegClass.
contains(DstR) ||
2110 !Hexagon::ModRegsRegClass.
contains(SrcR))
2113 Register TmpR =
MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2114 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), TmpR).
add(
MI->getOperand(1));
2115 BuildMI(
B, It,
DL, HII.get(TargetOpcode::COPY), DstR)
2127 if (!
MI->getOperand(0).isFI())
2131 unsigned Opc =
MI->getOpcode();
2133 bool IsKill =
MI->getOperand(2).isKill();
2134 int FI =
MI->getOperand(0).getIndex();
2138 Register TmpR =
MRI.createVirtualRegister(&Hexagon::IntRegsRegClass);
2139 unsigned TfrOpc = (
Opc == Hexagon::STriw_pred) ? Hexagon::C2_tfrpr
2145 BuildMI(
B, It,
DL, HII.get(Hexagon::S2_storeri_io))
2156bool HexagonFrameLowering::expandStoreCirc(
2158 MachineRegisterInfo &
MRI,
const HexagonInstrInfo &HII,
2159 SmallVectorImpl<Register> &NewRegs)
const {
2161 const auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2162 MachineInstr *
MI = &*It;
2163 if (!
MI->getOperand(0).isFI())
2168 bool IsKill =
MI->getOperand(1).isKill();
2169 int FI =
MI->getOperand(0).getIndex();
2172 for (
auto SubReg : {Hexagon::isub_lo, Hexagon::isub_hi}) {
2173 Register SrcSubReg = HRI.getSubReg(SrcR, SubReg);
2177 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrcrr), TmpR)
2182 BuildMI(
B, It,
DL, HII.get(Hexagon::S2_storeri_io))
2185 .
addReg(TmpR, RegState::Kill)
2188 Offset += HRI.getSpillSize(Hexagon::IntRegsRegClass);
2195bool HexagonFrameLowering::expandLoadCirc(
2197 MachineRegisterInfo &
MRI,
const HexagonInstrInfo &HII,
2198 SmallVectorImpl<Register> &NewRegs)
const {
2200 const auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2201 MachineInstr *
MI = &*It;
2202 if (!
MI->getOperand(1).isFI())
2207 int FI =
MI->getOperand(1).getIndex();
2210 for (
auto SubReg : {Hexagon::isub_lo, Hexagon::isub_hi}) {
2211 Register DstSubReg = HRI.getSubReg(DstR, SubReg);
2215 BuildMI(
B, It,
DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2221 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrrcr), DstSubReg)
2222 .
addReg(TmpR, RegState::Kill)
2226 Offset += HRI.getSpillSize(Hexagon::IntRegsRegClass);
2233bool HexagonFrameLowering::expandLoadInt(
2235 MachineRegisterInfo &
MRI,
const HexagonInstrInfo &HII,
2236 SmallVectorImpl<Register> &NewRegs)
const {
2237 MachineInstr *
MI = &*It;
2238 if (!
MI->getOperand(1).isFI())
2242 unsigned Opc =
MI->getOpcode();
2244 int FI =
MI->getOperand(1).getIndex();
2248 BuildMI(
B, It,
DL, HII.get(Hexagon::L2_loadri_io), TmpR)
2255 unsigned TfrOpc = (
Opc == Hexagon::LDriw_pred) ? Hexagon::C2_tfrrp
2256 : Hexagon::A2_tfrrcr;
2258 .
addReg(TmpR, RegState::Kill);
2265bool HexagonFrameLowering::expandStoreVecPred(MachineBasicBlock &
B,
2267 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2268 MachineInstr *
MI = &*It;
2269 if (!
MI->getOperand(0).isFI())
2274 bool IsKill =
MI->getOperand(2).isKill();
2275 int FI =
MI->getOperand(0).getIndex();
2276 auto *RC = &Hexagon::HvxVRRegClass;
2285 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2288 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandqrt), TmpR1)
2290 .
addReg(TmpR0, RegState::Kill);
2293 expandStoreVec(
B, std::prev(It),
MRI, HII, NewRegs);
2301bool HexagonFrameLowering::expandLoadVecPred(MachineBasicBlock &
B,
2303 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2304 MachineInstr *
MI = &*It;
2305 if (!
MI->getOperand(1).isFI())
2310 int FI =
MI->getOperand(1).getIndex();
2311 auto *RC = &Hexagon::HvxVRRegClass;
2319 BuildMI(
B, It,
DL, HII.get(Hexagon::A2_tfrsi), TmpR0)
2322 expandLoadVec(
B, std::prev(It),
MRI, HII, NewRegs);
2324 BuildMI(
B, It,
DL, HII.get(Hexagon::V6_vandvrt), DstR)
2325 .
addReg(TmpR1, RegState::Kill)
2326 .
addReg(TmpR0, RegState::Kill);
2334bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &
B,
2336 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2339 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2340 MachineInstr *
MI = &*It;
2341 if (!
MI->getOperand(0).isFI())
2348 LivePhysRegs LPR(HRI);
2351 for (
auto R =
B.begin(); R != It; ++R) {
2353 LPR.stepForward(*R, Clobbers);
2358 Register SrcLo = HRI.getSubReg(SrcR, Hexagon::vsub_lo);
2359 Register SrcHi = HRI.getSubReg(SrcR, Hexagon::vsub_hi);
2360 bool IsKill =
MI->getOperand(2).isKill();
2361 int FI =
MI->getOperand(0).getIndex();
2363 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2364 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2369 if (LPR.contains(SrcLo)) {
2370 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2371 : Hexagon::V6_vS32Ub_ai;
2380 if (LPR.contains(SrcHi)) {
2381 StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2382 : Hexagon::V6_vS32Ub_ai;
2394bool HexagonFrameLowering::expandLoadVec2(MachineBasicBlock &
B,
2396 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2399 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2400 MachineInstr *
MI = &*It;
2401 if (!
MI->getOperand(1).isFI())
2406 Register DstHi = HRI.getSubReg(DstR, Hexagon::vsub_hi);
2407 Register DstLo = HRI.getSubReg(DstR, Hexagon::vsub_lo);
2408 int FI =
MI->getOperand(1).getIndex();
2410 unsigned Size = HRI.getSpillSize(Hexagon::HvxVRRegClass);
2411 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2416 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2417 : Hexagon::V6_vL32Ub_ai;
2424 LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2425 : Hexagon::V6_vL32Ub_ai;
2435bool HexagonFrameLowering::expandStoreVec(MachineBasicBlock &
B,
2437 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2440 MachineInstr *
MI = &*It;
2441 if (!
MI->getOperand(0).isFI())
2444 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2447 bool IsKill =
MI->getOperand(2).isKill();
2448 int FI =
MI->getOperand(0).getIndex();
2450 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2452 unsigned StoreOpc = NeedAlign <= HasAlign ? Hexagon::V6_vS32b_ai
2453 : Hexagon::V6_vS32Ub_ai;
2464bool HexagonFrameLowering::expandLoadVec(MachineBasicBlock &
B,
2466 const HexagonInstrInfo &HII, SmallVectorImpl<Register> &NewRegs)
const {
2469 MachineInstr *
MI = &*It;
2470 if (!
MI->getOperand(1).isFI())
2473 auto &HRI = *MF.
getSubtarget<HexagonSubtarget>().getRegisterInfo();
2476 int FI =
MI->getOperand(1).getIndex();
2478 Align NeedAlign = HRI.getSpillAlign(Hexagon::HvxVRRegClass);
2480 unsigned LoadOpc = NeedAlign <= HasAlign ? Hexagon::V6_vL32b_ai
2481 : Hexagon::V6_vL32Ub_ai;
2492 SmallVectorImpl<Register> &NewRegs)
const {
2493 auto &HII = *MF.
getSubtarget<HexagonSubtarget>().getInstrInfo();
2497 for (
auto &
B : MF) {
2500 for (
auto I =
B.begin(),
E =
B.end();
I !=
E;
I = NextI) {
2501 MachineInstr *
MI = &*
I;
2502 NextI = std::next(
I);
2503 unsigned Opc =
MI->getOpcode();
2506 case TargetOpcode::COPY:
2509 case Hexagon::STriw_pred:
2510 case Hexagon::STriw_ctr:
2513 case Hexagon::STriw_circ:
2516 case Hexagon::LDriw_pred:
2517 case Hexagon::LDriw_ctr:
2520 case Hexagon::LDriw_circ:
2523 case Hexagon::PS_vstorerq_ai:
2524 Changed |= expandStoreVecPred(
B,
I,
MRI, HII, NewRegs);
2526 case Hexagon::PS_vloadrq_ai:
2529 case Hexagon::PS_vloadrw_ai:
2532 case Hexagon::PS_vstorerw_ai:
2547 SavedRegs.
resize(HRI.getNumRegs());
2552 for (
const MCPhysReg *R = HRI.getCalleeSavedRegs(&MF); *R; ++R)
2561 assert(AP.
isValid() &&
"AP must be assigned before register allocation");
2567 expandSpillMacros(MF, NewRegs);
2569 optimizeSpillSlots(MF, NewRegs);
2573 if (!NewRegs.
empty() || mayOverflowFrameOffset(MF)) {
2579 SpillRCs.
insert(&Hexagon::IntRegsRegClass);
2584 for (
const auto *RC : SpillRCs) {
2588 switch (RC->
getID()) {
2589 case Hexagon::IntRegsRegClassID:
2592 case Hexagon::HvxQRRegClassID:
2596 unsigned S = HRI.getSpillSize(*RC);
2597 Align A = HRI.getSpillAlign(*RC);
2598 for (
unsigned i = 0; i < Num; i++) {
2600 RS->addScavengingFrameIndex(NewFI);
2617 auto F = DeadMap.find({Reg,0});
2618 if (
F == DeadMap.end())
2620 for (
auto &DR :
F->second)
2621 if (DR.contains(FIR))
2626 for (
Register Reg : HRI.getRawAllocationOrder(*RC, MF)) {
2641 SmallVectorImpl<Register> &VRegs)
const {
2643 auto &HII = *HST.getInstrInfo();
2646 HexagonBlockRanges HBR(MF);
2648 using BlockIndexMap =
2649 std::map<MachineBasicBlock *, HexagonBlockRanges::InstrIndexMap>;
2650 using BlockRangeMap =
2651 std::map<MachineBasicBlock *, HexagonBlockRanges::RangeList>;
2652 using IndexType = HexagonBlockRanges::IndexType;
2659 SlotInfo() =
default;
2662 BlockIndexMap BlockIndexes;
2663 SmallSet<int,4> BadFIs;
2664 std::map<int,SlotInfo> FIRangeMap;
2673 if (HaveRC ==
nullptr || HaveRC == NewRC)
2678 if (NewRC->hasSubClassEq(HaveRC))
2685 for (
auto &
B : MF) {
2686 std::map<int,IndexType> LastStore, LastLoad;
2687 auto P = BlockIndexes.emplace(&
B, HexagonBlockRanges::InstrIndexMap(
B));
2688 auto &IndexMap =
P.first->second;
2690 << IndexMap <<
'\n');
2692 for (
auto &In :
B) {
2696 if (
In.isDebugInstr())
2699 bool Load = HII.isLoadFromStackSlot(In, LFI) && !HII.isPredicated(In);
2700 bool Store = HII.isStoreToStackSlot(In, SFI) && !HII.isPredicated(In);
2714 int TFI =
Load ? LFI : SFI;
2715 unsigned AM = HII.getAddrMode(In);
2716 SlotInfo &
SI = FIRangeMap[TFI];
2720 unsigned OpNum =
Load ? 0 : 2;
2721 auto *RC = HII.getRegClass(
In.getDesc(), OpNum);
2722 RC = getCommonRC(
SI.RC, RC);
2730 unsigned S = HII.getMemAccessSize(In);
2731 if (
SI.Size != 0 &&
SI.Size != S)
2737 for (
auto *Mo :
In.memoperands()) {
2738 if (!Mo->isVolatile() && !Mo->isAtomic())
2749 for (
unsigned i = 0, n =
In.getNumOperands(); i < n; ++i) {
2750 const MachineOperand &
Op =
In.getOperand(i);
2753 int FI =
Op.getIndex();
2756 if (i+1 >= n || !
In.getOperand(i+1).isImm() ||
2757 In.getOperand(i+1).getImm() != 0)
2759 if (BadFIs.
count(FI))
2763 auto &
LS = LastStore[FI];
2764 auto &LL = LastLoad[FI];
2766 if (LS == IndexType::None)
2767 LS = IndexType::Entry;
2770 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2771 if (LS != IndexType::None)
2772 RL.
add(LS, LL,
false,
false);
2773 else if (LL != IndexType::None)
2774 RL.
add(IndexType::Entry, LL,
false,
false);
2775 LL = IndexType::None;
2783 for (
auto &
I : LastLoad) {
2784 IndexType LL =
I.second;
2785 if (LL == IndexType::None)
2787 auto &RL = FIRangeMap[
I.first].Map[&
B];
2788 IndexType &
LS = LastStore[
I.first];
2789 if (LS != IndexType::None)
2790 RL.
add(LS, LL,
false,
false);
2792 RL.
add(IndexType::Entry, LL,
false,
false);
2793 LS = IndexType::None;
2795 for (
auto &
I : LastStore) {
2796 IndexType
LS =
I.second;
2797 if (LS == IndexType::None)
2799 auto &RL = FIRangeMap[
I.first].Map[&
B];
2800 RL.
add(LS, IndexType::None,
false,
false);
2805 for (
auto &
P : FIRangeMap) {
2806 dbgs() <<
"fi#" <<
P.first;
2807 if (BadFIs.
count(
P.first))
2810 if (
P.second.RC !=
nullptr)
2811 dbgs() << HRI.getRegClassName(
P.second.RC) <<
'\n';
2813 dbgs() <<
"<null>\n";
2814 for (
auto &R :
P.second.Map)
2823 SmallSet<int,4> LoxFIs;
2825 std::map<MachineBasicBlock*,std::vector<int>> BlockFIMap;
2827 for (
auto &
P : FIRangeMap) {
2829 if (BadFIs.
count(
P.first))
2831 for (
auto &
B : MF) {
2832 auto F =
P.second.Map.find(&
B);
2834 if (
F ==
P.second.Map.end() ||
F->second.empty())
2836 HexagonBlockRanges::IndexRange &
IR =
F->second.front();
2837 if (
IR.start() == IndexType::Entry)
2838 LoxFIs.insert(
P.first);
2839 BlockFIMap[&
B].push_back(
P.first);
2844 dbgs() <<
"Block-to-FI map (* -- live-on-exit):\n";
2845 for (
auto &
P : BlockFIMap) {
2846 auto &FIs =
P.second;
2850 for (
auto I : FIs) {
2851 dbgs() <<
" fi#" <<
I;
2852 if (LoxFIs.count(
I))
2864 for (
auto &
B : MF) {
2865 auto F = BlockIndexes.find(&
B);
2866 assert(
F != BlockIndexes.end());
2867 HexagonBlockRanges::InstrIndexMap &IM =
F->second;
2871 << HexagonBlockRanges::PrintRangeMap(
DM, HRI));
2873 for (
auto FI : BlockFIMap[&
B]) {
2874 if (BadFIs.
count(FI))
2877 HexagonBlockRanges::RangeList &RL = FIRangeMap[FI].Map[&
B];
2878 for (
auto &
Range : RL) {
2880 if (!IndexType::isInstr(
Range.start()) ||
2881 !IndexType::isInstr(
Range.end()))
2885 assert(
SI.mayStore() &&
"Unexpected start instruction");
2887 MachineOperand &SrcOp =
SI.getOperand(2);
2889 HexagonBlockRanges::RegisterRef SrcRR = { SrcOp.
getReg(),
2891 auto *RC = HII.getRegClass(
SI.getDesc(), 2);
2908 MachineInstr *CopyIn =
nullptr;
2909 if (SrcRR.
Reg != FoundR || SrcRR.
Sub != 0) {
2911 CopyIn =
BuildMI(
B, StartIt,
DL, HII.get(TargetOpcode::COPY), FoundR)
2917 if (LoxFIs.count(FI) && (&
Range == &RL.back())) {
2920 SrcOp.
setReg(HRI.getSubReg(FoundR, SR));
2932 for (
auto It = StartIt; It != EndIt; It = NextIt) {
2933 MachineInstr &
MI = *It;
2934 NextIt = std::next(It);
2936 if (!HII.isLoadFromStackSlot(
MI, TFI) || TFI != FI)
2939 assert(
MI.getOperand(0).getSubReg() == 0);
2940 MachineInstr *CopyOut =
nullptr;
2941 if (DstR != FoundR) {
2943 unsigned MemSize = HII.getMemAccessSize(
MI);
2945 unsigned CopyOpc = TargetOpcode::COPY;
2946 if (HII.isSignExtendingLoad(
MI))
2947 CopyOpc = (MemSize == 1) ? Hexagon::A2_sxtb : Hexagon::A2_sxth;
2948 else if (HII.isZeroExtendingLoad(
MI))
2949 CopyOpc = (MemSize == 1) ? Hexagon::A2_zxtb : Hexagon::A2_zxth;
2950 CopyOut =
BuildMI(
B, It,
DL, HII.get(CopyOpc), DstR)
2958 HexagonBlockRanges::RegisterRef FoundRR = { FoundR, 0 };
2966void HexagonFrameLowering::expandAlloca(MachineInstr *AI,
MachineFunction &MF,
2967 const HexagonInstrInfo &HII,
2969 MachineBasicBlock &MB = *AI->
getParent();
2978 auto *
TLI = HST.getTargetLowering();
2981 if (!NeedsProbing) {
3005 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
3009 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), SP)
3047 unsigned ProbeSize =
TLI->getStackProbeSize(MF, StackAlign);
3052 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_sub), Rd)
3058 BuildMI(MB, AI,
DL, HII.get(Hexagon::A2_andir), Rd)
3067 MF.
insert(InsertPt, LoopMBB);
3069 MF.
insert(InsertPt, ExitMBB);
3080 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::A2_addi), Hexagon::R29)
3085 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::S4_storeiri_io))
3091 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::C2_cmpgtu),
3097 BuildMI(*LoopMBB, LoopMBB->
end(),
DL, HII.get(Hexagon::J2_jumpt))
3106 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_tfr), Hexagon::R29)
3110 BuildMI(*ExitMBB, ExitIt,
DL, HII.get(Hexagon::A2_addi), Rd)
3138void HexagonFrameLowering::addCalleeSaveRegistersAsImpOperand(
MachineInstr *
MI,
3139 const CSIVect &CSI,
bool IsDef,
bool IsKill)
const {
3150 const CSIVect &CSI)
const {
3163 BitVector Regs(Hexagon::NUM_TARGET_REGS);
3166 if (!Hexagon::DoubleRegsRegClass.
contains(R))
3170 int F = Regs.find_first();
3171 if (
F != Hexagon::D8)
3174 int N = Regs.find_next(
F);
3175 if (
N >= 0 &&
N !=
F+1)
3184 const CSIVect &CSI)
const {
3185 if (shouldInlineCSR(MF, CSI))
3187 unsigned NumCSI = CSI.size();
3206 if (HST.getSCSPReg().id() <= MaxReg.id())
3212 return Threshold < NumCSI;
3215bool HexagonFrameLowering::useRestoreFunction(
const MachineFunction &MF,
3216 const CSIVect &CSI)
const {
3217 if (shouldInlineCSR(MF, CSI))
3230 unsigned NumCSI = CSI.size();
3236 return Threshold < NumCSI;
3239bool HexagonFrameLowering::mayOverflowFrameOffset(
MachineFunction &MF)
const {
3244 if (HST.useHVXOps() && StackSize > 256)
3251 bool HasImmStack =
false;
3252 unsigned MinLS = ~0
u;
3254 for (
const MachineBasicBlock &
B : MF) {
3255 for (
const MachineInstr &
MI :
B) {
3257 switch (
MI.getOpcode()) {
3258 case Hexagon::S4_storeirit_io:
3259 case Hexagon::S4_storeirif_io:
3260 case Hexagon::S4_storeiri_io:
3263 case Hexagon::S4_storeirht_io:
3264 case Hexagon::S4_storeirhf_io:
3265 case Hexagon::S4_storeirh_io:
3268 case Hexagon::S4_storeirbt_io:
3269 case Hexagon::S4_storeirbf_io:
3270 case Hexagon::S4_storeirb_io:
3271 if (
MI.getOperand(0).isFI())
3273 MinLS = std::min(MinLS, LS);
3287struct HexagonFrameSortingObject {
3288 bool IsValid =
false;
3294struct HexagonFrameSortingComparator {
3295 inline bool operator()(
const HexagonFrameSortingObject &
A,
3296 const HexagonFrameSortingObject &
B)
const {
3297 return std::make_tuple(!
A.IsValid,
A.ObjectAlignment,
A.Size) <
3298 std::make_tuple(!
B.IsValid,
B.ObjectAlignment,
B.Size);
3308 if (ObjectsToAllocate.
empty())
3312 int NObjects = ObjectsToAllocate.
size();
3320 if (i != ObjectsToAllocate[j])
3331 SortingObjects[i].IsValid =
true;
3332 SortingObjects[i].Index = i;
3342 for (
auto &Obj : SortingObjects) {
3345 ObjectsToAllocate[--i] = Obj.Index;
const TargetLowering & TLI
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 bool containsHLXObject(const llvm::HexagonSubtarget &HST, llvm::Type *Ty)
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.
MachineRegisterInfo & MRI
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.
an instruction to allocate memory on the stack
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
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 processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
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 * getCallerSavedRegs(const MachineFunction *MF, const TargetRegisterClass *RC) const
bool isTypeForHLX(Type *VecTy) const
const HexagonInstrInfo * getInstrInfo() const override
const HexagonFrameLowering * getFrameLowering() const override
const HexagonRegisterInfo * getRegisterInfo() 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.
const AllocaInst * getObjectAllocation(int ObjectIdx) const
Return the underlying Alloca of the specified stack object if it exists.
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.
bool isSpillSlotObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a spill slot.
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.
void RemoveStackObject(int ObjectIdx)
Remove or mark dead a statically sized stack object.
bool isVariableSizedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a variable sized object.
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.
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead 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
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.
mop_range implicit_operands()
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,...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
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
virtual bool hasInlineStackProbe(const MachineFunction &MF) 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
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
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.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
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)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
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.
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)
@ End
Run the machine verifier once, at the end of the pipeline.
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.