31#define DEBUG_TYPE "riscv-frame"
65 RISCV::X18, RISCV::X19, RISCV::X20,
66 RISCV::X21, RISCV::X22, RISCV::X23,
67 RISCV::X24, RISCV::X25, RISCV::X26,
116 STI.hasStdExtZimop();
117 bool HasSWShadowStack =
119 if (!HasHWShadowStack && !HasSWShadowStack)
132 if (HasHWShadowStack) {
133 if (STI.hasStdExtZcmop()) {
134 static_assert(
RAReg == RISCV::X1,
"C.SSPUSH only accepts X1");
144 bool IsRV64 = STI.is64Bit();
145 int64_t SlotSize = STI.getXLen() / 8;
165 char DwarfSCSReg =
TRI->getDwarfRegNum(SCSPReg,
true);
166 assert(DwarfSCSReg < 32 &&
"SCS Register should be < 32 (X3).");
168 char Offset =
static_cast<char>(-SlotSize) & 0x7f;
169 const char CFIInst[] = {
170 dwarf::DW_CFA_val_expression,
173 static_cast<char>(
unsigned(dwarf::DW_OP_breg0 + DwarfSCSReg)),
186 STI.hasStdExtZimop();
187 bool HasSWShadowStack =
189 if (!HasHWShadowStack && !HasSWShadowStack)
199 if (HasHWShadowStack) {
206 bool IsRV64 = STI.is64Bit();
207 int64_t SlotSize = STI.getXLen() / 8;
233 if (!RVFI->isSiFiveStackSwapInterrupt(MF))
239 assert(STI.hasVendorXSfmclic() &&
"Stack Swapping Requires XSfmclic");
243 .
addImm(RISCVSysReg::sf_mscratchcsw)
264 for (
int I = 0;
I < 2; ++
I) {
277 if (!RVFI->isSiFivePreemptibleInterrupt(MF))
292 TII->storeRegToStackSlot(
MBB,
MBBI, RISCV::X8,
true,
293 RVFI->getInterruptCSRFrameIndex(0),
296 TII->storeRegToStackSlot(
MBB,
MBBI, RISCV::X9,
true,
297 RVFI->getInterruptCSRFrameIndex(1),
306 .
addImm(RISCVSysReg::mcause)
311 .
addImm(RISCVSysReg::mepc)
318 .
addImm(RISCVSysReg::mstatus)
329 if (!RVFI->isSiFivePreemptibleInterrupt(MF))
340 .
addImm(RISCVSysReg::mstatus)
349 .
addImm(RISCVSysReg::mepc)
354 .
addImm(RISCVSysReg::mcause)
360 TII->loadRegFromStackSlot(
361 MBB,
MBBI, RISCV::X9, RVFI->getInterruptCSRFrameIndex(1),
363 TII->loadRegFromStackSlot(
364 MBB,
MBBI, RISCV::X8, RVFI->getInterruptCSRFrameIndex(0),
373 const std::vector<CalleeSavedInfo> &CSI) {
376 if (CSI.empty() || !RVFI->useSaveRestoreLibCalls(MF))
383 if (CS.getFrameIdx() < 0)
384 MaxReg = std::max(MaxReg.
id(), CS.getReg().id());
389 switch (MaxReg.
id()) {
393 case RISCV::X27:
return 12;
394 case RISCV::X26:
return 11;
395 case RISCV::X25:
return 10;
396 case RISCV::X24:
return 9;
397 case RISCV::X23:
return 8;
398 case RISCV::X22:
return 7;
399 case RISCV::X21:
return 6;
400 case RISCV::X20:
return 5;
401 case RISCV::X19:
return 4;
402 case RISCV::X18:
return 3;
403 case RISCV::X9:
return 2;
404 case FPReg:
return 1;
405 case RAReg:
return 0;
414 const std::vector<CalleeSavedInfo> &CSI) {
415 static const char *
const SpillLibCalls[] = {
434 return SpillLibCalls[LibCallID];
441 const std::vector<CalleeSavedInfo> &CSI) {
442 static const char *
const RestoreLibCalls[] = {
453 "__riscv_restore_10",
454 "__riscv_restore_11",
461 return RestoreLibCalls[LibCallID];
466 unsigned NumPushPopRegs = 0;
467 for (
auto &CS : CSI) {
471 unsigned RegNum = std::distance(std::begin(
FixedCSRFIMap), FII);
472 NumPushPopRegs = std::max(NumPushPopRegs, RegNum + 1);
475 assert(NumPushPopRegs != 12 &&
"x26 requires x27 to also be pushed");
476 return NumPushPopRegs;
503 TRI->hasStackRealignment(MF);
507void RISCVFrameLowering::determineFrameLayout(
MachineFunction &MF)
const {
515 if (RVFI->useQCIInterrupt(MF))
522 FrameSize =
alignTo(FrameSize, StackAlign);
532 if (RVFI->getRVVStackSize() && (!
hasFP(MF) ||
TRI->hasStackRealignment(MF))) {
533 int ScalarLocalVarSize = FrameSize - RVFI->getCalleeSavedStackSize() -
534 RVFI->getVarArgsSaveSize();
535 if (
auto RVVPadding =
537 RVFI->setRVVPadding(RVVPadding);
552 const std::vector<CalleeSavedInfo> &CSI) {
556 for (
auto &CS : CSI) {
557 int FI = CS.getFrameIdx();
562 return NonLibcallCSI;
567 const std::vector<CalleeSavedInfo> &CSI) {
571 for (
auto &CS : CSI) {
572 int FI = CS.getFrameIdx();
582 const std::vector<CalleeSavedInfo> &CSI) {
586 if (!RVFI->useSaveRestoreLibCalls(MF) && !RVFI->isPushable(MF))
587 return PushOrLibCallsCSI;
589 for (
const auto &CS : CSI) {
590 if (RVFI->useQCIInterrupt(MF)) {
601 PushOrLibCallsCSI.push_back(CS);
604 return PushOrLibCallsCSI;
609 const std::vector<CalleeSavedInfo> &CSI) {
613 if (!RVFI->useQCIInterrupt(MF))
614 return QCIInterruptCSI;
616 for (
const auto &CS : CSI) {
619 QCIInterruptCSI.push_back(CS);
622 return QCIInterruptCSI;
625void RISCVFrameLowering::allocateAndProbeStackForRVV(
629 assert(Amount != 0 &&
"Did not need to adjust stack pointer for RVV.");
634 const RISCVInstrInfo *
TII =
STI.getInstrInfo();
639 TII->mulImm(MF,
MBB,
MBBI,
DL, TargetReg, NumOfVReg, Flag);
644 CFIBuilder.buildDefCFA(TargetReg, -Amount);
653 CFIBuilder.buildDefCFARegister(
SPReg);
676 int64_t FixedOffset =
Offset.getFixed();
677 int64_t ScalableOffset =
Offset.getScalable();
678 unsigned DwarfVLenB =
TRI.getDwarfRegNum(RISCV::VLENB,
true);
683 Comment << (FixedOffset < 0 ?
" - " :
" + ") << std::abs(FixedOffset);
696 Comment << (ScalableOffset < 0 ?
" - " :
" + ") << std::abs(ScalableOffset)
703 assert(
Offset.getScalable() != 0 &&
"Did not need to adjust CFA for RVV");
705 std::string CommentBuffer;
708 unsigned DwarfReg =
TRI.getDwarfRegNum(
Reg,
true);
719 DefCfaExpr.
push_back(dwarf::DW_CFA_def_cfa_expression);
729 assert(
Offset.getScalable() != 0 &&
"Did not need to adjust CFA for RVV");
731 std::string CommentBuffer;
739 unsigned DwarfReg =
TRI.getDwarfRegNum(
Reg,
true);
740 DefCfaExpr.
push_back(dwarf::DW_CFA_expression);
753 uint64_t RealStackSize,
bool EmitCFI,
760 bool IsRV64 =
STI.is64Bit();
764 if (!NeedProbe ||
Offset <= ProbeSize) {
771 if (NeedProbe && DynAllocation) {
784 if (
Offset < ProbeSize * 5) {
788 while (CurrentOffset + ProbeSize <=
Offset) {
798 CurrentOffset += ProbeSize;
865 case RISCV::QC_CM_PUSH:
866 case RISCV::QC_CM_PUSHFP:
878 case RISCV::QC_CM_POP:
889 return RISCV::CM_PUSH;
891 return UpdateFP ? RISCV::QC_CM_PUSHFP : RISCV::QC_CM_PUSH;
902 return RISCV::CM_POP;
904 return RISCV::QC_CM_POP;
937 auto PossiblePush =
MBBI;
944 determineFrameLayout(MF);
978 unsigned LibCallFrameSize =
980 RVFI->setLibCallStackSize(LibCallFrameSize);
993 uint64_t StackSize = RealStackSize - RVFI->getReservedSpillsSize();
994 uint64_t RVVStackSize = RVFI->getRVVStackSize();
997 if (RealStackSize == 0 && !MFI.
adjustsStack() && RVVStackSize == 0)
1002 if (
STI.isRegisterReservedByUser(
SPReg))
1004 MF.
getFunction(),
"Stack pointer required, but has been reserved."});
1008 if (FirstSPAdjustAmount) {
1009 StackSize = FirstSPAdjustAmount;
1010 RealStackSize = FirstSPAdjustAmount;
1013 if (RVFI->useQCIInterrupt(MF)) {
1018 if (NeedsDwarfCFI) {
1031 if (RVFI->isPushable(MF) && PossiblePush !=
MBB.end() &&
1032 isPush(PossiblePush->getOpcode())) {
1039 PossiblePush->getOperand(1).setImm(StackAdj);
1040 StackSize -= StackAdj;
1042 if (NeedsDwarfCFI) {
1055 bool DynAllocation =
1059 NeedProbe, ProbeSize, DynAllocation,
1083 if (
STI.isRegisterReservedByUser(
FPReg))
1085 MF.
getFunction(),
"Frame pointer required, but has been reserved."});
1091 if (!RVFI->hasImplicitFPUpdates(MF)) {
1104 if (FirstSPAdjustAmount) {
1106 assert(SecondSPAdjustAmount > 0 &&
1107 "SecondSPAdjustAmount should be greater than zero");
1111 NeedProbe, ProbeSize, DynAllocation,
1117 allocateAndProbeStackForRVV(MF,
MBB,
MBBI,
DL, RVVStackSize,
1119 NeedsDwarfCFI && !
hasFP(MF), DynAllocation);
1128 if (NeedsDwarfCFI && !
hasFP(MF)) {
1143 if (RI->hasStackRealignment(MF)) {
1147 if (
isInt<12>(-(
int)MaxAlignment.value())) {
1150 .
addImm(-(
int)MaxAlignment.value())
1153 unsigned ShiftAmount =
Log2(MaxAlignment);
1165 if (NeedProbe && RVVStackSize == 0) {
1168 if (SecondSPAdjustAmount < ProbeSize &&
1169 SecondSPAdjustAmount + MaxAlignment.value() >= ProbeSize) {
1170 bool IsRV64 =
STI.is64Bit();
1197 int64_t CFAOffset)
const {
1225 MBBI =
MBB.getLastNonDebugInstr();
1227 DL =
MBBI->getDebugLoc();
1229 MBBI =
MBB.getFirstTerminator();
1242 auto FirstScalarCSRRestoreInsn =
1249 uint64_t RealStackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
1251 uint64_t StackSize = FirstSPAdjustAmount ? FirstSPAdjustAmount
1253 RVFI->getReservedSpillsSize();
1254 uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize();
1255 uint64_t RVVStackSize = RVFI->getRVVStackSize();
1257 bool RestoreSPFromFP = RI->hasStackRealignment(MF) ||
1262 if (!RestoreSPFromFP)
1267 if (NeedsDwarfCFI) {
1270 emitCalleeSavedRVVEpilogCFI(
MBB, FirstScalarCSRRestoreInsn);
1274 if (FirstSPAdjustAmount) {
1277 assert(SecondSPAdjustAmount > 0 &&
1278 "SecondSPAdjustAmount should be greater than zero");
1282 if (!RestoreSPFromFP)
1287 if (NeedsDwarfCFI && !
hasFP(MF))
1301 if (RestoreSPFromFP) {
1302 assert(
hasFP(MF) &&
"frame pointer should not have been eliminated");
1308 if (NeedsDwarfCFI &&
hasFP(MF))
1322 deallocateStack(MF,
MBB,
MBBI,
DL, StackSize,
1323 RVFI->getLibCallStackSize());
1335 if (RVFI->isPushable(MF) &&
MBBI !=
MBB.end() &&
isPop(
MBBI->getOpcode())) {
1342 MBBI->getOperand(1).setImm(StackAdj);
1343 StackSize -= StackAdj;
1346 deallocateStack(MF,
MBB,
MBBI,
DL, StackSize,
1347 RealStackSize - StackSize);
1350 if (NextI ==
MBB.end() || NextI->getOpcode() != RISCV::PseudoRET) {
1352 if (NeedsDwarfCFI) {
1372 deallocateStack(MF,
MBB,
MBBI,
DL, StackSize,
1373 RVFI->getQCIInterruptStackSize());
1400 "Unexpected stack ID for the frame object.");
1412 MinCSFI = CSI[0].getFrameIdx();
1413 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
1416 if (FI >= MinCSFI && FI <= MaxCSFI) {
1419 if (FirstSPAdjustAmount)
1470 if (FrameReg ==
FPReg) {
1489 "Can't index across variable sized realign");
1494 "Inconsistent stack layout");
1537 "Can't index across variable sized realign");
1539 RVFI->getRVVStackSize());
1547 RVFI->getCalleeSavedStackSize() -
1548 RVFI->getVarArgsSaveSize() + RVFI->getRVVPadding();
1559 if (!BaseReg.isValid())
1579 for (
unsigned i = 0; CSRegs[i]; ++i) {
1580 unsigned CSReg = CSRegs[i];
1585 SavedRegs.
reset(CSReg);
1587 auto SubRegs =
TRI.subregs(CSReg);
1589 if (!
MRI.def_empty(CSReg) ||
MRI.getUsedPhysRegsMask().test(CSReg)) {
1590 SavedRegs.
set(CSReg);
1591 for (
unsigned Reg : SubRegs)
1596 if (!SubRegs.empty() &&
llvm::all_of(SubRegs, [&](
unsigned Reg) {
1597 return SavedRegs.test(Reg);
1599 SavedRegs.
set(CSReg);
1614 if (RVFI->isPushable(MF) && SavedRegs.
test(RISCV::X26))
1615 SavedRegs.
set(RISCV::X27);
1621std::pair<int64_t, Align>
1622RISCVFrameLowering::assignRVVStackObjectOffsets(
MachineFunction &MF)
const {
1626 auto pushRVVObjects = [&](
int FIBegin,
int FIEnd) {
1627 for (
int I = FIBegin, E = FIEnd;
I != E; ++
I) {
1640 if (!RVVCSI.empty())
1641 pushRVVObjects(RVVCSI[0].getFrameIdx(),
1642 RVVCSI[RVVCSI.size() - 1].getFrameIdx() + 1);
1646 Align RVVStackAlign(16);
1649 if (!
ST.hasVInstructions()) {
1651 "Can't allocate scalable-vector objects without V instructions");
1652 return std::make_pair(0, RVVStackAlign);
1657 for (
int FI : ObjectsToAllocate) {
1669 RVVStackAlign = std::max(RVVStackAlign, ObjectAlign);
1672 uint64_t StackSize =
Offset;
1682 if (
auto RVVStackAlignVScale = RVVStackAlign.value() / VScale) {
1683 if (
auto AlignmentPadding =
1685 StackSize += AlignmentPadding;
1686 for (
int FI : ObjectsToAllocate)
1691 return std::make_pair(StackSize, RVVStackAlign);
1697 static constexpr unsigned ScavSlotsNumRVVSpillScalableObject = 2;
1701 static constexpr unsigned ScavSlotsNumRVVSpillNonScalableObject = 1;
1705 static constexpr unsigned ScavSlotsADDIScalableObject = 1;
1707 static constexpr unsigned MaxScavSlotsNumKnown =
1708 std::max({ScavSlotsADDIScalableObject, ScavSlotsNumRVVSpillScalableObject,
1709 ScavSlotsNumRVVSpillNonScalableObject});
1711 unsigned MaxScavSlotsNum = 0;
1717 for (
auto &MO :
MI.operands()) {
1723 MaxScavSlotsNum = std::max(
1724 MaxScavSlotsNum, IsScalableVectorID
1725 ? ScavSlotsNumRVVSpillScalableObject
1726 : ScavSlotsNumRVVSpillNonScalableObject);
1727 }
else if (
MI.getOpcode() == RISCV::ADDI && IsScalableVectorID) {
1729 std::max(MaxScavSlotsNum, ScavSlotsADDIScalableObject);
1732 if (MaxScavSlotsNum == MaxScavSlotsNumKnown)
1733 return MaxScavSlotsNumKnown;
1735 return MaxScavSlotsNum;
1759 unsigned FnSize = 0;
1760 for (
auto &
MBB : MF) {
1761 for (
auto &
MI :
MBB) {
1779 if (
MI.isConditionalBranch())
1780 FnSize +=
TII.getInstSizeInBytes(
MI);
1781 if (
MI.isConditionalBranch() ||
MI.isUnconditionalBranch()) {
1783 FnSize += 2 + 8 + 2 + 2;
1785 FnSize += 4 + 8 + 4 + 4;
1789 FnSize +=
TII.getInstSizeInBytes(
MI);
1804 int64_t RVVStackSize;
1805 Align RVVStackAlign;
1806 std::tie(RVVStackSize, RVVStackAlign) = assignRVVStackObjectOffsets(MF);
1808 RVFI->setRVVStackSize(RVVStackSize);
1809 RVFI->setRVVStackAlign(RVVStackAlign);
1818 unsigned ScavSlotsNum = 0;
1828 if (IsLargeFunction)
1829 ScavSlotsNum = std::max(ScavSlotsNum, 1u);
1836 for (
unsigned I = 0;
I < ScavSlotsNum;
I++) {
1838 RegInfo->getSpillAlign(*RC));
1839 RS->addScavengingFrameIndex(FI);
1841 if (IsLargeFunction && RVFI->getBranchRelaxationScratchFrameIndex() == -1)
1842 RVFI->setBranchRelaxationScratchFrameIndex(FI);
1845 unsigned Size = RVFI->getReservedSpillsSize();
1847 int FrameIdx = Info.getFrameIdx();
1853 RVFI->setCalleeSavedStackSize(
Size);
1877 int64_t Amount =
MI->getOperand(0).getImm();
1883 if (
MI->getOpcode() == RISCV::ADJCALLSTACKDOWN)
1893 bool DynAllocation =
1897 true, ProbeSize, DynAllocation,
1907 return MBB.erase(
MI);
1925 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
1931 if (RVFI->getReservedSpillsSize())
1936 if (!
isInt<12>(StackSize) && (CSI.size() > 0)) {
1949 if (
STI.hasStdExtZca()) {
1966 auto CanCompress = [&](
uint64_t CompressLen) ->
bool {
1967 if (StackSize <= 2047 + CompressLen ||
1968 (StackSize > 2048 * 2 - StackAlign &&
1969 StackSize <= 2047 * 2 + CompressLen) ||
1970 StackSize > 2048 * 3 - StackAlign)
1978 const uint64_t ADDI16SPCompressLen = 496;
1979 if (
STI.is64Bit() && CanCompress(ADDI16SPCompressLen))
1980 return ADDI16SPCompressLen;
1981 if (CanCompress(RVCompressLen))
1982 return RVCompressLen;
1984 return 2048 - StackAlign;
1991 std::vector<CalleeSavedInfo> &CSI)
const {
1998 if (RVFI->isSiFivePreemptibleInterrupt(MF)) {
1999 for (
int I = 0;
I < 2; ++
I) {
2000 int FI = RVFI->getInterruptCSRFrameIndex(
I);
2001 MFI.setIsCalleeSavedObjectIndex(FI,
true);
2009 if (RVFI->useQCIInterrupt(MF)) {
2013 if (RVFI->isPushable(MF)) {
2020 unsigned OnlyPushIfMoreThan = RVFI->useQCIInterrupt(MF) ? 2 : 0;
2021 if (PushedRegNum > OnlyPushIfMoreThan) {
2022 RVFI->setRVPushRegs(PushedRegNum);
2023 RVFI->setRVPushStackSize(
alignTo((
STI.getXLen() / 8) * PushedRegNum, 16));
2027 for (
auto &CS : CSI) {
2030 unsigned Size = RegInfo->getSpillSize(*RC);
2032 if (RVFI->useQCIInterrupt(MF)) {
2034 return P.first == CS.getReg();
2037 int64_t
Offset = FFI->second * (int64_t)
Size;
2039 int FrameIdx = MFI.CreateFixedSpillStackObject(
Size,
Offset);
2041 CS.setFrameIdx(FrameIdx);
2046 if (RVFI->useSaveRestoreLibCalls(MF) || RVFI->isPushable(MF)) {
2049 unsigned RegNum = std::distance(std::begin(
FixedCSRFIMap), FII);
2053 if (RVFI->getPushPopKind(MF) ==
2055 Offset = -int64_t(RVFI->getRVPushRegs() - RegNum) *
Size;
2059 if (RVFI->useQCIInterrupt(MF))
2062 int FrameIdx = MFI.CreateFixedSpillStackObject(
Size,
Offset);
2064 CS.setFrameIdx(FrameIdx);
2070 Align Alignment = RegInfo->getSpillAlign(*RC);
2075 int FrameIdx = MFI.CreateStackObject(
Size, Alignment,
true);
2076 MFI.setIsCalleeSavedObjectIndex(FrameIdx,
true);
2077 CS.setFrameIdx(FrameIdx);
2082 if (RVFI->useQCIInterrupt(MF)) {
2085 MFI.CreateFixedSpillStackObject(
2089 if (RVFI->isPushable(MF)) {
2092 if (int64_t PushSize = RVFI->getRVPushStackSize())
2093 MFI.CreateFixedSpillStackObject(PushSize, -PushSize - QCIOffset);
2094 }
else if (
int LibCallRegs =
getLibCallID(MF, CSI) + 1) {
2095 int64_t LibCallFrameSize =
2097 MFI.CreateFixedSpillStackObject(LibCallFrameSize, -LibCallFrameSize);
2112 if (
MI !=
MBB.end() && !
MI->isDebugInstr())
2113 DL =
MI->getDebugLoc();
2122 ? RISCV::QC_C_MIENTER_NEST
2123 : RISCV::QC_C_MIENTER))
2133 if (PushedRegNum > 0) {
2141 PushBuilder.
addImm(RegEnc);
2144 for (
unsigned i = 0; i < PushedRegNum; i++)
2154 for (
auto &CS : CSI)
2155 MBB.addLiveIn(CS.getReg());
2162 auto storeRegsToStackSlots = [&](
decltype(UnmanagedCSI) CSInfo) {
2163 for (
auto &CS : CSInfo) {
2167 TII.storeRegToStackSlot(
MBB,
MI, Reg, !
MBB.isLiveIn(Reg),
2172 storeRegsToStackSlots(UnmanagedCSI);
2173 storeRegsToStackSlots(RVVCSI);
2179 return RISCV::VRRegClass.contains(BaseReg) ? 1
2180 : RISCV::VRM2RegClass.contains(BaseReg) ? 2
2181 : RISCV::VRM4RegClass.contains(BaseReg) ? 4
2185void RISCVFrameLowering::emitCalleeSavedRVVPrologCFI(
2189 RISCVMachineFunctionInfo *RVFI = MF->
getInfo<RISCVMachineFunctionInfo>();
2190 const RISCVRegisterInfo &
TRI = *
STI.getRegisterInfo();
2198 uint64_t ScalarLocalVarSize =
2201 FixedSize -= ScalarLocalVarSize;
2205 for (
auto &CS : RVVCSI) {
2207 int FI = CS.getFrameIdx();
2210 for (
unsigned i = 0; i < NumRegs; ++i) {
2218void RISCVFrameLowering::emitCalleeSavedRVVEpilogCFI(
2222 const RISCVRegisterInfo &
TRI = *
STI.getRegisterInfo();
2226 for (
auto &CS : RVVCSI) {
2229 for (
unsigned i = 0; i < NumRegs; ++i)
2230 CFIHelper.buildRestore(BaseReg + i);
2243 if (
MI !=
MBB.end() && !
MI->isDebugInstr())
2244 DL =
MI->getDebugLoc();
2255 auto loadRegFromStackSlot = [&](
decltype(UnmanagedCSI) CSInfo) {
2256 for (
auto &CS : CSInfo) {
2262 "loadRegFromStackSlot didn't insert any code!");
2265 loadRegFromStackSlot(RVVCSI);
2266 loadRegFromStackSlot(UnmanagedCSI);
2272 assert(
MI->getOpcode() == RISCV::QC_C_MILEAVERET &&
2273 "Unexpected QCI Interrupt Return Instruction");
2278 if (PushedRegNum > 0) {
2285 PopBuilder.
addImm(RegEnc);
2293 if (RestoreLibCall) {
2302 if (
MI !=
MBB.end() &&
MI->getOpcode() == RISCV::PseudoRET) {
2303 NewMI->copyImplicitOps(*MF, *
MI);
2304 MI->eraseFromParent();
2331 if (
STI.preferVsetvliOverReadVLENB() &&
2332 (
MBB.isLiveIn(RISCV::VTYPE) ||
MBB.isLiveIn(RISCV::VL)))
2343 RS.enterBasicBlock(*TmpMBB);
2344 return !RS.isRegUsed(RISCV::X5);
2355 return MBB.succ_empty();
2364 if (
MBB.succ_size() > 1)
2402 assert(TargetReg != RISCV::X2 &&
"New top of stack cannot already be in SP");
2409 bool IsRV64 = Subtarget.is64Bit();
2410 Align StackAlign = Subtarget.getFrameLowering()->getStackAlign();
2417 MF.
insert(MBBInsertPoint, LoopTestMBB);
2419 MF.
insert(MBBInsertPoint, ExitMBB);
2424 TII->movImm(
MBB,
MBBI,
DL, ScratchReg, ProbeSize, Flags);
2435 TII->get(IsRV64 ? RISCV::SD : RISCV::SW))
2470 MBB.addSuccessor(LoopTestMBB);
2480 SmallVector<MachineInstr *, 4> ToReplace;
2481 for (MachineInstr &
MI :
MBB) {
2482 unsigned Opc =
MI.getOpcode();
2483 if (
Opc == RISCV::PROBED_STACKALLOC ||
2484 Opc == RISCV::PROBED_STACKALLOC_RVV) {
2489 for (MachineInstr *
MI : ToReplace) {
2490 if (
MI->getOpcode() == RISCV::PROBED_STACKALLOC ||
2491 MI->getOpcode() == RISCV::PROBED_STACKALLOC_RVV) {
2494 Register TargetReg =
MI->getOperand(0).getReg();
2496 (
MI->getOpcode() == RISCV::PROBED_STACKALLOC_RVV));
unsigned const MachineRegisterInfo * MRI
static MCCFIInstruction createDefCFAExpression(const TargetRegisterInfo &TRI, unsigned Reg, const StackOffset &Offset)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file contains constants used for implementing Dwarf debug support.
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
static uint64_t estimateFunctionSizeInBytes(const LoongArchInstrInfo *TII, const MachineFunction &MF)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static constexpr uint64_t QCIInterruptPushAmount
static unsigned getPushOpcode(RISCVMachineFunctionInfo::PushPopKind Kind, bool UpdateFP)
static void emitSiFiveCLICPreemptibleSaves(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL)
static MCRegister getRVVBaseRegister(const RISCVRegisterInfo &TRI, const Register &Reg)
static void createSiFivePreemptibleInterruptFrameEntries(MachineFunction &MF, RISCVMachineFunctionInfo &RVFI)
static constexpr MCPhysReg FPReg
static const char * getRestoreLibCallName(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static bool needsDwarfCFI(const MachineFunction &MF)
Returns true if DWARF CFI instructions ("frame moves") should be emitted.
static constexpr MCPhysReg SPReg
static const char * getSpillLibCallName(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static bool hasRVVFrameObject(const MachineFunction &MF)
static void appendScalableVectorExpression(const TargetRegisterInfo &TRI, SmallVectorImpl< char > &Expr, StackOffset Offset, llvm::raw_string_ostream &Comment)
static SmallVector< CalleeSavedInfo, 8 > getQCISavedInfo(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static void emitSiFiveCLICPreemptibleRestores(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL)
static SmallVector< CalleeSavedInfo, 8 > getRVVCalleeSavedInfo(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static bool isPop(unsigned Opcode)
static unsigned getCalleeSavedRVVNumRegs(const Register &BaseReg)
static MCCFIInstruction createDefCFAOffset(const TargetRegisterInfo &TRI, Register Reg, StackOffset Offset)
static void emitStackProbeInline(MachineBasicBlock::iterator MBBI, DebugLoc DL, Register TargetReg, bool IsRVV)
static Align getABIStackAlignment(RISCVABI::ABI ABI)
static unsigned getPopOpcode(RISCVMachineFunctionInfo::PushPopKind Kind)
static SmallVector< CalleeSavedInfo, 8 > getPushOrLibCallsSavedInfo(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static int getLibCallID(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static const std::pair< MCPhysReg, int8_t > FixedCSRFIQCIInterruptMap[]
static bool isPush(unsigned Opcode)
static constexpr MCPhysReg RAReg
static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static const MCPhysReg FixedCSRFIMap[]
static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL)
static SmallVector< CalleeSavedInfo, 8 > getUnmanagedCSI(const MachineFunction &MF, const std::vector< CalleeSavedInfo > &CSI)
static void emitSiFiveCLICStackSwap(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL)
static unsigned getNumPushPopRegs(const std::vector< CalleeSavedInfo > &CSI)
static unsigned getScavSlotsNumForRVV(MachineFunction &MF)
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
bool test(unsigned Idx) const
Helper class for creating CFI instructions and inserting them into MIR.
void buildEscape(StringRef Bytes, StringRef Comment="") const
void buildDefCFAOffset(int64_t Offset, MCSymbol *Label=nullptr) const
void buildRestore(MCRegister Reg) const
void buildDefCFARegister(MCRegister Reg) const
void buildOffset(MCRegister Reg, int64_t Offset) const
void insertCFIInst(const MCCFIInstruction &CFIInst) const
void buildDefCFA(MCRegister Reg, int64_t Offset) const
void setInsertPoint(MachineBasicBlock::iterator IP)
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
MCRegister getReg() const
Diagnostic information for unsupported feature in backend.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasOptNone() const
Do not optimize this function (-O0).
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals, SMLoc Loc={}, StringRef Comment="")
.cfi_escape Allows the user to add arbitrary bytes to the unwind info.
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
LLVM_ABI MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
bool isReturnBlock() const
Convenience function that returns true if the block ends in a return instruction.
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.
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
LLVM_ABI void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getOffsetAdjustment() const
Return the correction for frame offsets.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
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.
bool isMaxCallFrameSizeComputed() const
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.
uint8_t getStackID(int ObjectIdx) const
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.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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 & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved 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...
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override
assignCalleeSavedSpillSlots - Allows target to override spill slot assignment logic.
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
uint64_t getFirstSPAdjustAmount(const MachineFunction &MF) const
bool enableShrinkWrapping(const MachineFunction &MF) const override
Returns true if the target will correctly handle shrink wrapping.
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
bool hasBP(const MachineFunction &MF) const
void allocateStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineFunction &MF, uint64_t Offset, uint64_t RealStackSize, bool EmitCFI, bool NeedProbe, uint64_t ProbeSize, bool DynAllocation, MachineInstr::MIFlag Flag) const
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a epilogue for the target.
bool hasFPImpl(const MachineFunction &MF) const override
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
Register getInitialCFARegister(const MachineFunction &MF) const override
Return initial CFA register value i.e.
const RISCVSubtarget & STI
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...
bool isSupportedStackID(TargetStackID::Value ID) const override
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
TargetStackID::Value getStackIDForScalableVectors() const override
Returns the StackID that scalable vectors should be associated with.
int getInitialCFAOffset(const MachineFunction &MF) const override
Return initial CFA offset value i.e.
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
bool canUseAsPrologue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a prologue for the target.
RISCVFrameLowering(const RISCVSubtarget &STI)
uint64_t getStackSizeWithRVVPadding(const MachineFunction &MF) const
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
bool isPushable(const MachineFunction &MF) const
InterruptStackKind getInterruptStackKind(const MachineFunction &MF) const
bool isSiFivePreemptibleInterrupt(const MachineFunction &MF) const
void pushInterruptCSRFrameIndex(int FI)
PushPopKind getPushPopKind(const MachineFunction &MF) const
uint64_t getRVVPadding() const
unsigned getRVPushRegs() const
bool useSaveRestoreLibCalls(const MachineFunction &MF) const
unsigned getVarArgsSaveSize() const
bool useQCIInterrupt(const MachineFunction &MF) const
unsigned getCalleeSavedStackSize() const
bool hasVInstructions() const
const RISCVRegisterInfo * getRegisterInfo() const override
bool hasInlineStackProbe(const MachineFunction &MF) const override
True if stack clash protection is enabled for this functions.
unsigned getStackProbeSize(const MachineFunction &MF, Align StackAlign) const
Wrapper class representing virtual and physical registers.
Represents a location in source code.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void append(StringRef RHS)
Append from a StringRef.
StringRef str() const
Explicit conversion to StringRef.
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.
StackOffset holds a fixed and a scalable offset in bytes.
int64_t getFixed() const
Returns the fixed component of the stack.
int64_t getScalable() const
Returns the scalable component of the stack.
static StackOffset get(int64_t Fixed, int64_t Scalable)
static StackOffset getScalable(int64_t Scalable)
static StackOffset getFixed(int64_t Fixed)
StringRef - Represent a constant reference to a string, i.e.
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...
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl=Align(1), bool StackReal=true)
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
int alignSPAdjust(int SPAdj) const
alignSPAdjust - This method aligns the stack adjustment to the correct alignment.
TargetInstrInfo - Interface to description of machine instruction set.
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ GHC
Used by the Glasgow Haskell Compiler (GHC).
static unsigned encodeRegListNumRegs(unsigned NumRegs)
static constexpr unsigned RVVBitsPerBlock
bool isRVVSpill(const MachineInstr &MI)
static constexpr unsigned RVVBytesPerBlock
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
@ ScalablePredicateVector
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
IterT next_nodbg(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It, then continue incrementing it while it points to a debug instruction.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
constexpr T alignDown(U Value, V Align, W Skew=0)
Returns the largest unsigned integer less than or equal to Value and is Skew mod Align.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void appendLEB128(SmallVectorImpl< U > &Buffer, T Value)
unsigned Log2(Align A)
Returns the log2 of the alignment.
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.
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 bool isRVVRegClass(const TargetRegisterClass *RC)
void adjustReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, Register SrcReg, StackOffset Offset, MachineInstr::MIFlag Flag, MaybeAlign RequiredAlign) const