70#include "llvm/IR/IntrinsicsAMDGPU.h"
100#define DEBUG_TYPE "ir-translator"
106 cl::desc(
"Should enable CSE in ir-translator"),
118 class ValueToVRegInfo {
120 ValueToVRegInfo() =
default;
125 using const_vreg_iterator =
128 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
130 VRegListT *getVRegs(
const Value &V) {
131 auto [It, Inserted] = ValToVRegs.try_emplace(&V);
137 It->second =
new (VRegAlloc.Allocate()) VRegListT();
141 OffsetListT *getOffsets(
const Value &V) {
142 assert(V.getType()->isAggregateType() &&
143 "Offsets are for aggregate values");
144 auto [It, Inserted] = TypeToOffsets.try_emplace(V.getType());
148 It->second =
new (OffsetAlloc.Allocate()) OffsetListT();
152 const_vreg_iterator findVRegs(
const Value &V)
const {
153 return ValToVRegs.find(&V);
156 bool contains(
const Value &V)
const {
return ValToVRegs.contains(&V); }
158 void reserveVRegs(
unsigned NumValues) { ValToVRegs.reserve(NumValues); }
162 TypeToOffsets.clear();
163 VRegAlloc.DestroyAll();
164 OffsetAlloc.DestroyAll();
179 ValueToVRegInfo VMap;
186 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
197 PendingConstDbgValues;
246 void translateDbgValueRecord(
Value *V,
bool HasArgList,
255 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
262 bool translateCopy(
const User &U,
const Value &V,
287 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
289 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
294 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
296 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
318 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
324 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
339 bool translateIntrinsic(
356 bool findUnwindDestinations(
369 bool translateCast(
unsigned Opcode,
const User &U,
380 return translateCompare(U, MIRBuilder);
385 return translateCompare(U, MIRBuilder);
390 void finishPendingPhis();
394 void finishPendingConstDbgValues();
398 bool translateUnaryOp(
unsigned Opcode,
const User &U,
403 bool translateBinaryOp(
unsigned Opcode,
const User &U,
409 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
454 bool lowerJumpTableWorkItem(
463 bool FallthroughUnreachable,
469 bool lowerBitTestWorkItem(
475 bool FallthroughUnreachable);
506 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
509 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
512 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
515 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
518 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
521 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
525 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
528 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
531 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
534 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
537 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
540 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
544 return translatePtrToInt(U, MIRBuilder);
547 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
550 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
553 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
556 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
559 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
562 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
565 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
570 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
574 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
578 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
581 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
584 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
588 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
591 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
594 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
597 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
600 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
636 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
651 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
662 std::unique_ptr<MachineIRBuilder> CurBuilder;
667 std::unique_ptr<MachineIRBuilder> EntryBuilder;
680 std::unique_ptr<OptimizationRemarkEmitter> ORE;
691 bool EnableOpts =
false;
695 bool HasTailCall =
false;
699 bool mayTranslateUserTypes(
const User &U)
const;
706 assert(irt &&
"irt is null!");
709 void addSuccessorWithProb(
712 IRT->addSuccessorWithProb(Src, Dst, Prob);
715 ~GISelSwitchLowering()
override =
default;
721 std::unique_ptr<GISelSwitchLowering> SL;
727 void finalizeFunction();
765 auto Regs = getOrCreateVRegs(Val);
768 assert(Regs.size() == 1 &&
769 "attempt to get single VReg for aggregate or void");
773 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
775 auto &Regs = *VMap.getVRegs(Token);
777 assert(Regs.size() == 1 &&
778 "Expected a single register for convergence tokens.");
782 auto Reg = MRI->createGenericVirtualRegister(
LLT::token());
789 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
793 int getOrCreateFrameIndex(
const AllocaInst &AI);
816 auto RemappedEdge = MachinePreds.find(Edge);
817 if (RemappedEdge != MachinePreds.end())
818 return RemappedEdge->second;
827 void addSuccessorWithProb(
833 : OptLevel(OptLevel) {}
863 "IRTranslator LLVM IR -> MI",
false,
false)
875 MF.getProperties().setFailedISel();
876 bool IsGlobalISelAbortEnabled =
881 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
882 R << (
" (in function: " + MF.getName() +
")").str();
884 if (IsGlobalISelAbortEnabled)
904 DILocationVerifier() =
default;
905 ~DILocationVerifier()
override =
default;
907 const Instruction *getCurrentInst()
const {
return CurrInst; }
908 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
910 void erasingInstr(MachineInstr &
MI)
override {}
911 void changingInstr(MachineInstr &
MI)
override {}
912 void changedInstr(MachineInstr &
MI)
override {}
914 void createdInstr(MachineInstr &
MI)
override {
915 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
920 <<
" was copied to " <<
MI);
926 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
927 (
MI.isDebugInstr())) &&
928 "Line info was not transferred to all instructions");
951IRTranslatorImpl::ValueToVRegInfo::VRegListT &
952IRTranslatorImpl::allocateVRegs(
const Value &Val) {
953 auto VRegsIt = VMap.findVRegs(Val);
954 if (VRegsIt != VMap.vregs_end())
955 return *VRegsIt->second;
956 auto *Regs = VMap.getVRegs(Val);
962 auto *Offsets = VMap.getOffsets(Val);
965 Offsets->empty() ? Offsets :
nullptr);
966 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
972 auto VRegsIt = VMap.findVRegs(Val);
973 if (VRegsIt != VMap.vregs_end())
974 return *VRegsIt->second;
977 return *VMap.getVRegs(Val);
980 auto *VRegs = VMap.getVRegs(Val);
984 "Don't know how to create an empty vreg");
989 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
993 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"GISelFailure",
994 MF->getFunction().getSubprogram(),
995 &MF->getFunction().getEntryBlock());
996 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
1004 auto *
Offsets = VMap.getOffsets(Val);
1006 Offsets->empty() ? Offsets :
nullptr);
1009 for (
auto Ty : SplitTys)
1010 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
1017 while (
auto Elt =
C.getAggregateElement(Idx++)) {
1018 auto EltRegs = getOrCreateVRegs(*Elt);
1025int IRTranslatorImpl::getOrCreateFrameIndex(
const AllocaInst &AI) {
1026 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
1028 return MapEntry->second;
1034 Size = std::max<uint64_t>(
Size, 1u);
1036 int &FI = MapEntry->second;
1037 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
1044 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
1045 MF->getFrameInfo().setStackID(FI, StackID);
1053 return SI->getAlign();
1055 return LI->getAlign();
1061 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"", &
I);
1062 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
1068 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
1069 assert(
MBB &&
"BasicBlock was not encountered before");
1073void IRTranslatorImpl::addMachineCFGPred(CFGEdge
Edge,
1075 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
1076 MachinePreds[
Edge].push_back(NewPred);
1079bool IRTranslatorImpl::translateBinaryOp(
unsigned Opcode,
const User &U,
1081 if (!mayTranslateUserTypes(U))
1088 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1089 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1101bool IRTranslatorImpl::translateUnaryOp(
unsigned Opcode,
const User &U,
1103 if (!mayTranslateUserTypes(U))
1106 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1117bool IRTranslatorImpl::translateFNeg(
const User &U,
1119 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
1122bool IRTranslatorImpl::translateCompare(
const User &U,
1124 if (!mayTranslateUserTypes(U))
1128 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1129 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1134 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1, Flags);
1142 MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1, Flags);
1147bool IRTranslatorImpl::translateRet(
const User &U,
1151 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
1156 VRegs = getOrCreateVRegs(*Ret);
1159 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
1160 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
1161 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
1167 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
1170void IRTranslatorImpl::emitBranchForMergedCondition(
1179 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
1182 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
1185 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
1186 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
1187 CurBuilder->getDebugLoc(), TProb, FProb);
1188 SL->SwitchCases.push_back(CB);
1194 SwitchCG::CaseBlock CB(
1196 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
1197 SL->SwitchCases.push_back(CB);
1202 return I->getParent() == BB;
1206void IRTranslatorImpl::findMergedConditions(
1211 using namespace PatternMatch;
1212 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
1213 "Expected Opc to be AND/OR");
1219 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
1225 const Value *BOpOp0, *BOpOp1;
1239 if (BOpc == Instruction::And)
1240 BOpc = Instruction::Or;
1241 else if (BOpc == Instruction::Or)
1242 BOpc = Instruction::And;
1248 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
1252 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
1259 MachineBasicBlock *TmpBB =
1263 if (
Opc == Instruction::Or) {
1284 auto NewTrueProb = TProb / 2;
1285 auto NewFalseProb = TProb / 2 + FProb;
1287 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1288 NewFalseProb, InvertCond);
1294 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1295 Probs[1], InvertCond);
1297 assert(
Opc == Instruction::And &&
"Unknown merge op!");
1317 auto NewTrueProb = TProb + FProb / 2;
1318 auto NewFalseProb = FProb / 2;
1320 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1321 NewFalseProb, InvertCond);
1327 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1328 Probs[1], InvertCond);
1332bool IRTranslatorImpl::shouldEmitAsBranches(
1333 const std::vector<SwitchCG::CaseBlock> &Cases) {
1335 if (Cases.size() != 2)
1340 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
1341 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
1342 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
1343 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
1349 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
1350 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
1354 Cases[0].TrueBB == Cases[1].ThisBB)
1357 Cases[0].FalseBB == Cases[1].ThisBB)
1364bool IRTranslatorImpl::translateUncondBr(
const User &U,
1367 auto &CurMBB = MIRBuilder.
getMBB();
1372 MIRBuilder.
buildBr(*Succ0MBB);
1375 for (
const BasicBlock *Succ :
successors(&BrInst))
1380bool IRTranslatorImpl::translateCondBr(
const User &U,
1383 auto &CurMBB = MIRBuilder.
getMBB();
1389 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
1408 using namespace PatternMatch;
1410 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
1411 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
1414 const Value *BOp0, *BOp1;
1416 Opcode = Instruction::And;
1418 Opcode = Instruction::Or;
1422 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
1423 getEdgeProbability(&CurMBB, Succ0MBB),
1424 getEdgeProbability(&CurMBB, Succ1MBB),
1426 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
1429 if (shouldEmitAsBranches(SL->SwitchCases)) {
1431 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
1432 SL->SwitchCases.erase(SL->SwitchCases.begin());
1438 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
1439 MF->erase(SL->SwitchCases[
I].ThisBB);
1441 SL->SwitchCases.clear();
1448 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
1449 CurBuilder->getDebugLoc());
1453 emitSwitchCase(CB, &CurMBB, *CurBuilder);
1460 if (!FuncInfo.BPI) {
1461 Src->addSuccessorWithoutProb(Dst);
1465 Prob = getEdgeProbability(Src, Dst);
1466 Src->addSuccessor(Dst, Prob);
1472 const BasicBlock *SrcBB = Src->getBasicBlock();
1473 const BasicBlock *DstBB = Dst->getBasicBlock();
1474 if (!FuncInfo.BPI) {
1477 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
1478 return BranchProbability(1, SuccSize);
1480 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
1484 using namespace SwitchCG;
1487 BranchProbabilityInfo *BPI = FuncInfo.BPI;
1489 Clusters.reserve(
SI.getNumCases());
1490 for (
const auto &
I :
SI.cases()) {
1491 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
1492 assert(Succ &&
"Could not find successor mbb in mapping");
1493 const ConstantInt *CaseVal =
I.getCaseValue();
1494 BranchProbability Prob =
1496 : BranchProbability(1,
SI.getNumCases() + 1);
1497 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
1500 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
1507 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
1510 if (Clusters.empty()) {
1517 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
1518 SL->findBitTestClusters(Clusters, &SI);
1521 dbgs() <<
"Case clusters: ";
1522 for (
const CaseCluster &
C : Clusters) {
1523 if (
C.Kind == CC_JumpTable)
1525 if (
C.Kind == CC_BitTests)
1528 C.Low->getValue().print(
dbgs(),
true);
1529 if (
C.Low !=
C.High) {
1531 C.High->getValue().print(
dbgs(),
true);
1538 assert(!Clusters.empty());
1542 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
1543 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
1545 while (!WorkList.empty()) {
1546 SwitchWorkListItem
W = WorkList.pop_back_val();
1548 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
1550 if (NumClusters > 3 &&
1553 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
1557 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
1567 using namespace SwitchCG;
1568 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
1569 "Clusters not sorted?");
1570 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
1572 auto [LastLeft, FirstRight, LeftProb, RightProb] =
1573 SL->computeSplitWorkItemInfo(W);
1578 assert(PivotCluster >
W.FirstCluster);
1579 assert(PivotCluster <=
W.LastCluster);
1584 const ConstantInt *Pivot = PivotCluster->Low;
1593 MachineBasicBlock *LeftMBB;
1594 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
1595 FirstLeft->Low ==
W.GE &&
1596 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
1597 LeftMBB = FirstLeft->MBB;
1599 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1600 FuncInfo.MF->
insert(BBI, LeftMBB);
1602 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
1608 MachineBasicBlock *RightMBB;
1609 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
1610 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
1611 RightMBB = FirstRight->MBB;
1613 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1614 FuncInfo.MF->
insert(BBI, RightMBB);
1616 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
1624 if (
W.MBB == SwitchMBB)
1625 emitSwitchCase(CB, SwitchMBB, MIB);
1627 SL->SwitchCases.push_back(CB);
1633 assert(JT.
Reg &&
"Should lower JT Header first!");
1648 MachineIRBuilder MIB(*HeaderBB->
getParent());
1655 Register SwitchOpReg = getOrCreateVReg(SValue);
1657 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
1662 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
1676 auto Cst = getOrCreateVReg(
1716 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
1730 "Can only handle SLE ranges");
1741 const LLT CmpTy = MRI->getType(CmpOpReg);
1742 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1768bool IRTranslatorImpl::lowerJumpTableWorkItem(
1774 using namespace SwitchCG;
1777 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1778 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1779 BranchProbability DefaultProb =
W.DefaultProb;
1782 MachineBasicBlock *JumpMBB = JT->
MBB;
1783 CurMF->
insert(BBI, JumpMBB);
1793 auto JumpProb =
I->Prob;
1794 auto FallthroughProb = UnhandledProbs;
1802 if (*SI == DefaultMBB) {
1803 JumpProb += DefaultProb / 2;
1804 FallthroughProb -= DefaultProb / 2;
1809 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1814 if (FallthroughUnreachable)
1815 JTH->FallthroughUnreachable =
true;
1817 if (!JTH->FallthroughUnreachable)
1818 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1819 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1824 JTH->HeaderBB = CurMBB;
1828 if (CurMBB == SwitchMBB) {
1829 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1831 JTH->Emitted =
true;
1835bool IRTranslatorImpl::lowerSwitchRangeWorkItem(
1840 using namespace SwitchCG;
1843 if (
I->Low ==
I->High) {
1859 CaseBlock CB(Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1862 emitSwitchCase(CB, SwitchMBB, MIB);
1868 MachineIRBuilder &MIB = *CurBuilder;
1872 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1874 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1876 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1881 LLT MaskTy = SwitchOpTy;
1887 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1896 Register SubReg = RangeSub.getReg(0);
1897 if (SwitchOpTy != MaskTy)
1903 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1905 if (!
B.FallthroughUnreachable)
1906 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1907 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1911 if (!
B.FallthroughUnreachable) {
1915 RangeSub, RangeCst);
1929 MachineIRBuilder &MIB = *CurBuilder;
1935 if (PopCount == 1) {
1938 auto MaskTrailingZeros =
1943 }
else if (PopCount == BB.
Range) {
1945 auto MaskTrailingOnes =
1953 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1957 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1964 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1966 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1984bool IRTranslatorImpl::lowerBitTestWorkItem(
1990 bool FallthroughUnreachable) {
1991 using namespace SwitchCG;
1994 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
1996 for (BitTestCase &BTC : BTB->Cases)
1997 CurMF->
insert(BBI, BTC.ThisBB);
2000 BTB->Parent = CurMBB;
2001 BTB->Default = Fallthrough;
2003 BTB->DefaultProb = UnhandledProbs;
2007 if (!BTB->ContiguousRange) {
2008 BTB->Prob += DefaultProb / 2;
2009 BTB->DefaultProb -= DefaultProb / 2;
2012 if (FallthroughUnreachable)
2013 BTB->FallthroughUnreachable =
true;
2016 if (CurMBB == SwitchMBB) {
2017 emitBitTestHeader(*BTB, SwitchMBB);
2018 BTB->Emitted =
true;
2028 using namespace SwitchCG;
2030 MachineBasicBlock *NextMBB =
nullptr;
2032 if (++BBI != FuncInfo.MF->end())
2041 [](
const CaseCluster &a,
const CaseCluster &b) {
2042 return a.Prob != b.Prob
2044 : a.Low->getValue().slt(b.Low->getValue());
2049 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
2051 if (
I->Prob >
W.LastCluster->Prob)
2053 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
2061 BranchProbability DefaultProb =
W.DefaultProb;
2062 BranchProbability UnhandledProbs = DefaultProb;
2063 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
2064 UnhandledProbs +=
I->Prob;
2066 MachineBasicBlock *CurMBB =
W.MBB;
2067 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
2068 bool FallthroughUnreachable =
false;
2069 MachineBasicBlock *Fallthrough;
2070 if (
I ==
W.LastCluster) {
2072 Fallthrough = DefaultMBB;
2073 FallthroughUnreachable =
2077 CurMF->
insert(BBI, Fallthrough);
2079 UnhandledProbs -=
I->Prob;
2083 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2084 DefaultProb, UnhandledProbs,
I, Fallthrough,
2085 FallthroughUnreachable)) {
2093 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2094 UnhandledProbs,
I, Fallthrough,
2095 FallthroughUnreachable)) {
2102 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
2103 FallthroughUnreachable, UnhandledProbs,
2104 CurMBB, MIB, SwitchMBB)) {
2111 CurMBB = Fallthrough;
2117bool IRTranslatorImpl::translateIndirectBr(
const User &U,
2125 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
2126 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
2127 for (
const BasicBlock *Succ :
successors(&BrInst)) {
2131 if (!AddedSuccessors.
insert(Succ).second)
2147bool IRTranslatorImpl::translateLoad(
const User &U,
2150 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
2161 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
2163 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
2169 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
2171 if (AA->pointsToConstantMemory(
2178 if (Regs.
size() == 1) {
2179 auto *MMO = MF->getMachineMemOperand(
2181 MRI->getType(Regs[0]), getMemOpAlign(LI),
2182 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
2188 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
2189 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
2191 for (
unsigned i = 0; i < Regs.
size(); ++i) {
2196 Align BaseAlign = getMemOpAlign(LI);
2198 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
2201 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
2207bool IRTranslatorImpl::translateStore(
const User &U,
2210 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
2216 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
2217 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
2219 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
2220 SI.getPointerOperand());
2227 if (Vals.
size() == 1) {
2228 auto *MMO = MF->getMachineMemOperand(
2229 MachinePointerInfo(
SI.getPointerOperand()), Flags,
2230 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
2231 SI.getSyncScopeID(),
SI.getOrdering());
2236 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
2237 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
2239 for (
unsigned i = 0; i < Vals.
size(); ++i) {
2243 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
2244 Align BaseAlign = getMemOpAlign(SI);
2245 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
2248 SI.getSyncScopeID(),
SI.getOrdering());
2255 const Value *Src = U.getOperand(0);
2261 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
2264 for (
auto Idx : EVI->indices())
2265 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2267 for (
auto Idx : IVI->indices())
2268 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2274 DL.getIndexedOffsetInType(Src->getType(), Indices));
2277bool IRTranslatorImpl::translateExtractValue(
const User &U,
2279 const Value *Src =
U.getOperand(0);
2282 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
2284 auto &DstRegs = allocateVRegs(U);
2286 for (
unsigned i = 0; i < DstRegs.size(); ++i)
2287 DstRegs[i] = SrcRegs[Idx++];
2292bool IRTranslatorImpl::translateInsertValue(
const User &U,
2294 const Value *Src =
U.getOperand(0);
2296 auto &DstRegs = allocateVRegs(U);
2297 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
2300 auto *InsertedIt = InsertedRegs.
begin();
2302 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
2303 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
2304 DstRegs[i] = *InsertedIt++;
2306 DstRegs[i] = SrcRegs[i];
2312bool IRTranslatorImpl::translateSelect(
const User &U,
2314 Register Tst = getOrCreateVReg(*
U.getOperand(0));
2323 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
2324 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
2330bool IRTranslatorImpl::translateCopy(
const User &U,
const Value &V,
2332 return translateCopy(U, getOrCreateVReg(V), MIRBuilder);
2335bool IRTranslatorImpl::translateCopy(
const User &U,
Register Src,
2337 auto &Regs = *VMap.getVRegs(U);
2339 Regs.push_back(Src);
2348bool IRTranslatorImpl::translateBitCast(
const User &U,
2350 Type *SrcTy =
U.getOperand(0)->getType();
2351 Type *DstTy =
U.getType();
2358 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
2360 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
2369 "only byte types can be bitcast to or from pointers");
2371 LLT IntTy =
getLLTForType(*DL->getIntPtrType(PtrIRTy), *DL);
2372 Register Src = getOrCreateVReg(*
U.getOperand(0));
2374 if (MRI->getType(Src) != IntTy && MRI->getType(Dst) != IntTy)
2380 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
2383bool IRTranslatorImpl::translateCast(
unsigned Opcode,
const User &U,
2385 if (!mayTranslateUserTypes(U))
2398bool IRTranslatorImpl::translateGetElementPtr(
const User &U,
2400 Value &Op0 = *
U.getOperand(0);
2404 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
2407 uint32_t PtrAddFlags = 0;
2413 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
2423 unsigned VectorWidth = 0;
2427 bool WantSplatVector =
false;
2431 WantSplatVector = VectorWidth > 1;
2435 return translateCopy(U, BaseReg, MIRBuilder);
2439 if (WantSplatVector && !PtrTy.
isVector()) {
2446 OffsetIRTy = DL->getIndexType(PtrIRTy);
2453 const Value *
Idx = GTI.getOperand();
2454 if (StructType *StTy = GTI.getStructTypeOrNull()) {
2456 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
2459 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
2464 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
2465 Offset += ElementSize * *Val;
2474 PtrAddFlagsWithConst(
Offset))
2479 Register IdxReg = getOrCreateVReg(*Idx);
2480 LLT IdxTy = MRI->getType(IdxReg);
2481 if (IdxTy != OffsetTy) {
2482 if (!IdxTy.
isVector() && WantSplatVector) {
2495 if (ElementSize != 1) {
2506 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
2509 GepOffsetReg = IdxReg;
2513 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
2522 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
2523 PtrAddFlagsWithConst(
Offset));
2527 return translateCopy(U, BaseReg, MIRBuilder);
2530bool IRTranslatorImpl::translateMemFunc(
const CallInst &CI,
2540 unsigned MinPtrSize = UINT_MAX;
2541 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
2542 Register SrcReg = getOrCreateVReg(**AI);
2543 LLT SrcTy = MRI->getType(SrcReg);
2545 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
2553 if (MRI->getType(SizeOpReg) != SizeTy)
2565 ConstantInt *CopySize =
nullptr;
2568 DstAlign = MCI->getDestAlign().valueOrOne();
2569 SrcAlign = MCI->getSourceAlign().valueOrOne();
2572 DstAlign = MMI->getDestAlign().valueOrOne();
2573 SrcAlign = MMI->getSourceAlign().valueOrOne();
2577 DstAlign = MSI->getDestAlign().valueOrOne();
2580 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
2581 Opcode != TargetOpcode::G_MEMSET_INLINE) {
2597 if (AA && CopySize &&
2598 AA->pointsToConstantMemory(MemoryLocation(
2608 ICall.addMemOperand(
2609 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
2610 StoreFlags, 1, DstAlign, AAInfo));
2611 if (Opcode != TargetOpcode::G_MEMSET &&
2612 Opcode != TargetOpcode::G_MEMSET_INLINE)
2613 ICall.addMemOperand(MF->getMachineMemOperand(
2614 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
2619bool IRTranslatorImpl::translateTrap(
const CallInst &CI,
2622 StringRef TrapFuncName =
2623 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
2624 if (TrapFuncName.
empty()) {
2625 MachineInstrBuilder MIB;
2626 if (Opcode == TargetOpcode::G_UBSANTRAP) {
2637 CallLowering::CallLoweringInfo
Info;
2638 if (Opcode == TargetOpcode::G_UBSANTRAP)
2646 return CLI->lowerCall(MIRBuilder, Info);
2649bool IRTranslatorImpl::translateVectorInterleave2Intrinsic(
2652 "This function can only be called on the interleave2 intrinsic!");
2656 Register Res = getOrCreateVReg(CI);
2658 LLT OpTy = MRI->getType(Op0);
2665bool IRTranslatorImpl::translateVectorDeinterleave2Intrinsic(
2668 "This function can only be called on the deinterleave2 intrinsic!");
2675 LLT ResTy = MRI->getType(Res[0]);
2692void IRTranslatorImpl::getStackGuard(
Register DstReg,
2695 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
2698 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
2703 const TargetInstrInfo &
TII = *MF->getSubtarget().getInstrInfo();
2704 MRI->setRegClass(DstReg,
2705 TII.getRegClass(
TII.get(TargetOpcode::LOAD_STACK_GUARD), 0));
2707 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
2709 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
2710 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
2712 MachinePointerInfo MPInfo(
Global);
2715 MachineMemOperand *MemRef = MF->getMachineMemOperand(
2716 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
2720bool IRTranslatorImpl::translateOverflowIntrinsic(
2724 Op, {ResRegs[0], ResRegs[1]},
2730bool IRTranslatorImpl::translateFixedPointIntrinsic(
2732 Register Dst = getOrCreateVReg(CI);
2740unsigned IRTranslatorImpl::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
2744 case Intrinsic::acos:
2745 return TargetOpcode::G_FACOS;
2746 case Intrinsic::asin:
2747 return TargetOpcode::G_FASIN;
2748 case Intrinsic::atan:
2749 return TargetOpcode::G_FATAN;
2750 case Intrinsic::atan2:
2751 return TargetOpcode::G_FATAN2;
2752 case Intrinsic::bswap:
2753 return TargetOpcode::G_BSWAP;
2754 case Intrinsic::bitreverse:
2755 return TargetOpcode::G_BITREVERSE;
2756 case Intrinsic::clmul:
2757 return TargetOpcode::G_CLMUL;
2758 case Intrinsic::fshl:
2759 return TargetOpcode::G_FSHL;
2760 case Intrinsic::fshr:
2761 return TargetOpcode::G_FSHR;
2762 case Intrinsic::ceil:
2763 return TargetOpcode::G_FCEIL;
2764 case Intrinsic::cos:
2765 return TargetOpcode::G_FCOS;
2766 case Intrinsic::cosh:
2767 return TargetOpcode::G_FCOSH;
2768 case Intrinsic::ctpop:
2769 return TargetOpcode::G_CTPOP;
2770 case Intrinsic::smulh:
2771 return TargetOpcode::G_SMULH;
2772 case Intrinsic::umulh:
2773 return TargetOpcode::G_UMULH;
2774 case Intrinsic::exp:
2775 return TargetOpcode::G_FEXP;
2776 case Intrinsic::exp2:
2777 return TargetOpcode::G_FEXP2;
2778 case Intrinsic::exp10:
2779 return TargetOpcode::G_FEXP10;
2780 case Intrinsic::fabs:
2781 return TargetOpcode::G_FABS;
2782 case Intrinsic::copysign:
2783 return TargetOpcode::G_FCOPYSIGN;
2784 case Intrinsic::minnum:
2785 return TargetOpcode::G_FMINNUM;
2786 case Intrinsic::maxnum:
2787 return TargetOpcode::G_FMAXNUM;
2788 case Intrinsic::minimum:
2789 return TargetOpcode::G_FMINIMUM;
2790 case Intrinsic::maximum:
2791 return TargetOpcode::G_FMAXIMUM;
2792 case Intrinsic::minimumnum:
2793 return TargetOpcode::G_FMINIMUMNUM;
2794 case Intrinsic::maximumnum:
2795 return TargetOpcode::G_FMAXIMUMNUM;
2796 case Intrinsic::canonicalize:
2797 return TargetOpcode::G_FCANONICALIZE;
2798 case Intrinsic::floor:
2799 return TargetOpcode::G_FFLOOR;
2800 case Intrinsic::fma:
2801 return TargetOpcode::G_FMA;
2802 case Intrinsic::log:
2803 return TargetOpcode::G_FLOG;
2804 case Intrinsic::log2:
2805 return TargetOpcode::G_FLOG2;
2806 case Intrinsic::log10:
2807 return TargetOpcode::G_FLOG10;
2808 case Intrinsic::ldexp:
2809 return TargetOpcode::G_FLDEXP;
2810 case Intrinsic::nearbyint:
2811 return TargetOpcode::G_FNEARBYINT;
2812 case Intrinsic::pow:
2813 return TargetOpcode::G_FPOW;
2814 case Intrinsic::powi:
2815 return TargetOpcode::G_FPOWI;
2816 case Intrinsic::rint:
2817 return TargetOpcode::G_FRINT;
2818 case Intrinsic::round:
2819 return TargetOpcode::G_INTRINSIC_ROUND;
2820 case Intrinsic::roundeven:
2821 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2822 case Intrinsic::sin:
2823 return TargetOpcode::G_FSIN;
2824 case Intrinsic::sinh:
2825 return TargetOpcode::G_FSINH;
2826 case Intrinsic::sqrt:
2827 return TargetOpcode::G_FSQRT;
2828 case Intrinsic::tan:
2829 return TargetOpcode::G_FTAN;
2830 case Intrinsic::tanh:
2831 return TargetOpcode::G_FTANH;
2832 case Intrinsic::trunc:
2833 return TargetOpcode::G_INTRINSIC_TRUNC;
2834 case Intrinsic::readcyclecounter:
2835 return TargetOpcode::G_READCYCLECOUNTER;
2836 case Intrinsic::readsteadycounter:
2837 return TargetOpcode::G_READSTEADYCOUNTER;
2838 case Intrinsic::ptrmask:
2839 return TargetOpcode::G_PTRMASK;
2840 case Intrinsic::lrint:
2841 return TargetOpcode::G_INTRINSIC_LRINT;
2842 case Intrinsic::llrint:
2843 return TargetOpcode::G_INTRINSIC_LLRINT;
2845 case Intrinsic::vector_reduce_fmin:
2846 return TargetOpcode::G_VECREDUCE_FMIN;
2847 case Intrinsic::vector_reduce_fmax:
2848 return TargetOpcode::G_VECREDUCE_FMAX;
2849 case Intrinsic::vector_reduce_fminimum:
2850 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2851 case Intrinsic::vector_reduce_fmaximum:
2852 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2853 case Intrinsic::vector_reduce_fminimumnum:
2854 return TargetOpcode::G_VECREDUCE_FMINIMUMNUM;
2855 case Intrinsic::vector_reduce_fmaximumnum:
2856 return TargetOpcode::G_VECREDUCE_FMAXIMUMNUM;
2857 case Intrinsic::vector_reduce_add:
2858 return TargetOpcode::G_VECREDUCE_ADD;
2859 case Intrinsic::vector_reduce_mul:
2860 return TargetOpcode::G_VECREDUCE_MUL;
2861 case Intrinsic::vector_reduce_and:
2862 return TargetOpcode::G_VECREDUCE_AND;
2863 case Intrinsic::vector_reduce_or:
2864 return TargetOpcode::G_VECREDUCE_OR;
2865 case Intrinsic::vector_reduce_xor:
2866 return TargetOpcode::G_VECREDUCE_XOR;
2867 case Intrinsic::vector_reduce_smax:
2868 return TargetOpcode::G_VECREDUCE_SMAX;
2869 case Intrinsic::vector_reduce_smin:
2870 return TargetOpcode::G_VECREDUCE_SMIN;
2871 case Intrinsic::vector_reduce_umax:
2872 return TargetOpcode::G_VECREDUCE_UMAX;
2873 case Intrinsic::vector_reduce_umin:
2874 return TargetOpcode::G_VECREDUCE_UMIN;
2875 case Intrinsic::experimental_vector_compress:
2876 return TargetOpcode::G_VECTOR_COMPRESS;
2877 case Intrinsic::lround:
2878 return TargetOpcode::G_LROUND;
2879 case Intrinsic::llround:
2880 return TargetOpcode::G_LLROUND;
2881 case Intrinsic::get_fpenv:
2882 return TargetOpcode::G_GET_FPENV;
2883 case Intrinsic::get_fpmode:
2884 return TargetOpcode::G_GET_FPMODE;
2889bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2893 unsigned Op = getSimpleIntrinsicOpcode(ID);
2901 for (
const auto &Arg : CI.
args())
2904 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2912 case Intrinsic::experimental_constrained_fadd:
2913 return TargetOpcode::G_STRICT_FADD;
2914 case Intrinsic::experimental_constrained_fsub:
2915 return TargetOpcode::G_STRICT_FSUB;
2916 case Intrinsic::experimental_constrained_fmul:
2917 return TargetOpcode::G_STRICT_FMUL;
2918 case Intrinsic::experimental_constrained_fdiv:
2919 return TargetOpcode::G_STRICT_FDIV;
2920 case Intrinsic::experimental_constrained_frem:
2921 return TargetOpcode::G_STRICT_FREM;
2922 case Intrinsic::experimental_constrained_fma:
2923 return TargetOpcode::G_STRICT_FMA;
2924 case Intrinsic::experimental_constrained_sqrt:
2925 return TargetOpcode::G_STRICT_FSQRT;
2926 case Intrinsic::experimental_constrained_ldexp:
2927 return TargetOpcode::G_STRICT_FLDEXP;
2928 case Intrinsic::experimental_constrained_fcmp:
2929 return TargetOpcode::G_STRICT_FCMP;
2930 case Intrinsic::experimental_constrained_fcmps:
2931 return TargetOpcode::G_STRICT_FCMPS;
2937bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2949 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2950 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2952 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2953 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2956 .addPredicate(FPCmp->getPredicate())
2970std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2971 auto VRegs = getOrCreateVRegs(Arg);
2972 if (VRegs.
size() != 1)
2973 return std::nullopt;
2976 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2977 if (!VRegDef || !VRegDef->isCopy())
2978 return std::nullopt;
2979 return VRegDef->getOperand(1).getReg().asMCReg();
2982bool IRTranslatorImpl::translateIfEntryValueArgument(
2993 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2995 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2996 <<
": expression is entry_value but "
2997 <<
"couldn't find a physical register\n");
3005 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
3017 case Intrinsic::experimental_convergence_anchor:
3018 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
3019 case Intrinsic::experimental_convergence_entry:
3020 return TargetOpcode::CONVERGENCECTRL_ENTRY;
3021 case Intrinsic::experimental_convergence_loop:
3022 return TargetOpcode::CONVERGENCECTRL_LOOP;
3026bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
3029 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3032 if (ID == Intrinsic::experimental_convergence_loop) {
3034 assert(Bundle &&
"Expected a convergence control token.");
3036 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3043bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3047 if (ORE->enabled()) {
3049 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3057 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3063 case Intrinsic::lifetime_start:
3064 case Intrinsic::lifetime_end: {
3067 MF->getFunction().hasOptNone())
3070 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3071 : TargetOpcode::LIFETIME_END;
3080 case Intrinsic::fake_use: {
3082 for (
const auto &Arg : CI.
args())
3084 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3085 MF->setHasFakeUses(
true);
3088 case Intrinsic::vaend:
3092 case Intrinsic::vastart: {
3094 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3097 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3098 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3100 ListSize, Alignment));
3103 case Intrinsic::uadd_with_overflow:
3104 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3105 case Intrinsic::sadd_with_overflow:
3106 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3107 case Intrinsic::usub_with_overflow:
3108 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3109 case Intrinsic::ssub_with_overflow:
3110 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3111 case Intrinsic::umul_with_overflow:
3112 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3113 case Intrinsic::smul_with_overflow:
3114 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3115 case Intrinsic::uadd_sat:
3116 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3117 case Intrinsic::sadd_sat:
3118 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3119 case Intrinsic::usub_sat:
3120 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3121 case Intrinsic::ssub_sat:
3122 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3123 case Intrinsic::ushl_sat:
3124 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3125 case Intrinsic::sshl_sat:
3126 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3127 case Intrinsic::umin:
3128 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3129 case Intrinsic::umax:
3130 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3131 case Intrinsic::smin:
3132 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3133 case Intrinsic::smax:
3134 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3135 case Intrinsic::abs:
3137 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3138 case Intrinsic::smul_fix:
3139 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3140 case Intrinsic::umul_fix:
3141 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3142 case Intrinsic::smul_fix_sat:
3143 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3144 case Intrinsic::umul_fix_sat:
3145 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3146 case Intrinsic::sdiv_fix:
3147 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3148 case Intrinsic::udiv_fix:
3149 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3150 case Intrinsic::sdiv_fix_sat:
3151 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3152 case Intrinsic::udiv_fix_sat:
3153 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3154 case Intrinsic::fmuladd: {
3155 Register Dst = getOrCreateVReg(CI);
3159 if (TLI->isFMAFasterThanFMulAndFAdd(*MF,
3160 TLI->getValueType(*DL, CI.
getType()))) {
3163 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3174 case Intrinsic::frexp: {
3181 case Intrinsic::modf: {
3183 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3188 case Intrinsic::sincos: {
3195 case Intrinsic::fptosi_sat:
3199 case Intrinsic::fptoui_sat:
3203 case Intrinsic::memcpy_inline:
3204 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3205 case Intrinsic::memcpy:
3206 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3207 case Intrinsic::memmove:
3208 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3209 case Intrinsic::memset:
3210 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3211 case Intrinsic::memset_inline:
3212 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3213 case Intrinsic::eh_typeid_for: {
3216 unsigned TypeID = MF->getTypeIDFor(GV);
3220 case Intrinsic::objectsize:
3223 case Intrinsic::is_constant:
3226 case Intrinsic::stackguard:
3227 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3229 case Intrinsic::stackprotector: {
3232 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3233 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3234 getStackGuard(GuardVal, MIRBuilder);
3239 int FI = getOrCreateFrameIndex(*Slot);
3240 MF->getFrameInfo().setStackProtectorIndex(FI);
3243 GuardVal, getOrCreateVReg(*Slot),
3250 case Intrinsic::stacksave: {
3251 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3254 case Intrinsic::stackrestore: {
3255 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3259 case Intrinsic::cttz:
3260 case Intrinsic::ctlz: {
3262 bool isTrailing =
ID == Intrinsic::cttz;
3263 unsigned Opcode = isTrailing ? Cst->
isZero()
3264 ? TargetOpcode::G_CTTZ
3265 : TargetOpcode::G_CTTZ_ZERO_POISON
3266 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3267 : TargetOpcode::G_CTLZ_ZERO_POISON;
3268 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3272 case Intrinsic::invariant_start: {
3276 case Intrinsic::invariant_end:
3278 case Intrinsic::expect:
3279 case Intrinsic::expect_with_probability:
3280 case Intrinsic::annotation:
3281 case Intrinsic::ptr_annotation:
3282 case Intrinsic::launder_invariant_group:
3283 case Intrinsic::threadlocal_address: {
3285 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3289 case Intrinsic::assume:
3290 case Intrinsic::experimental_noalias_scope_decl:
3291 case Intrinsic::var_annotation:
3292 case Intrinsic::sideeffect:
3295 case Intrinsic::read_volatile_register:
3296 case Intrinsic::read_register: {
3299 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3303 case Intrinsic::write_register: {
3305 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3310 case Intrinsic::localescape: {
3311 MachineBasicBlock &EntryMBB = MF->front();
3316 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3323 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3336 case Intrinsic::vector_reduce_fadd:
3337 case Intrinsic::vector_reduce_fmul: {
3340 Register Dst = getOrCreateVReg(CI);
3346 Opc =
ID == Intrinsic::vector_reduce_fadd
3347 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3348 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3349 if (!MRI->getType(VecSrc).isVector())
3350 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3351 : TargetOpcode::G_FMUL;
3359 if (ID == Intrinsic::vector_reduce_fadd) {
3360 Opc = TargetOpcode::G_VECREDUCE_FADD;
3361 ScalarOpc = TargetOpcode::G_FADD;
3363 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3364 ScalarOpc = TargetOpcode::G_FMUL;
3366 LLT DstTy = MRI->getType(Dst);
3369 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3374 case Intrinsic::trap:
3375 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3376 case Intrinsic::debugtrap:
3377 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3378 case Intrinsic::ubsantrap:
3379 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3380 case Intrinsic::allow_runtime_check:
3381 case Intrinsic::allow_ubsan_check:
3382 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3385 case Intrinsic::amdgcn_cs_chain:
3386 case Intrinsic::amdgcn_call_whole_wave:
3387 return translateCallBase(CI, MIRBuilder);
3388 case Intrinsic::fptrunc_round: {
3393 std::optional<RoundingMode> RoundMode =
3398 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3399 {getOrCreateVReg(CI)},
3401 .addImm((
int)*RoundMode);
3405 case Intrinsic::is_fpclass: {
3410 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3411 {getOrCreateVReg(*FpValue)})
3416 case Intrinsic::set_fpenv: {
3421 case Intrinsic::reset_fpenv:
3424 case Intrinsic::set_fpmode: {
3429 case Intrinsic::reset_fpmode:
3432 case Intrinsic::get_rounding:
3435 case Intrinsic::set_rounding:
3438 case Intrinsic::vscale: {
3442 case Intrinsic::scmp:
3443 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3447 case Intrinsic::ucmp:
3448 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3452 case Intrinsic::vector_extract:
3453 return translateExtractVector(CI, MIRBuilder);
3454 case Intrinsic::vector_insert:
3455 return translateInsertVector(CI, MIRBuilder);
3456 case Intrinsic::stepvector: {
3460 case Intrinsic::prefetch: {
3467 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3470 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3476 case Intrinsic::speculative_load: {
3480 Register Dst = getOrCreateVReg(CI);
3482 Flags |= TLI->getTargetMMOFlags(CI);
3485 if (CI.
hasMetadata(LLVMContext::MD_invariant_load))
3487 auto *MMO = MF->getMachineMemOperand(
3488 MachinePointerInfo(Ptr), Flags, MRI->getType(Dst),
3490 MIRBuilder.
buildLoad(Dst, getOrCreateVReg(*Ptr), *MMO);
3494 case Intrinsic::vector_interleave2:
3495 case Intrinsic::vector_deinterleave2: {
3503 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3505 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3508#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3509 case Intrinsic::INTRINSIC:
3510#include "llvm/IR/ConstrainedOps.def"
3513 case Intrinsic::experimental_convergence_anchor:
3514 case Intrinsic::experimental_convergence_entry:
3515 case Intrinsic::experimental_convergence_loop:
3516 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3517 case Intrinsic::reloc_none: {
3520 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3528bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3530 if (!mayTranslateUserTypes(CB))
3533 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3537 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3542 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3545bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3552 for (
const auto &Arg : CB.
args()) {
3554 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3556 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3557 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3558 &CB, &MIRBuilder.
getMBB(), Arg));
3561 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3564 Args.push_back(getOrCreateVRegs(*Arg));
3568 if (ORE->enabled()) {
3570 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3576 std::optional<CallLowering::PtrAuthInfo> PAI;
3581 const Value *
Key = Bundle->Inputs[0];
3588 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3589 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3591 Register DiscReg = getOrCreateVReg(*Discriminator);
3599 const auto &Token = *Bundle->Inputs[0].get();
3600 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3606 bool Success = CLI->lowerCall(
3607 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3612 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3613 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3620bool IRTranslatorImpl::translateCall(
const User &U,
3622 if (!mayTranslateUserTypes(U))
3630 if (
F && (
F->hasDLLImportStorageClass() ||
3631 (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI() &&
3632 F->hasExternalWeakLinkage())))
3644 return translateInlineAsm(CI, MIRBuilder);
3648 if (translateCallBase(CI, MIRBuilder)) {
3657 if (!MF->getSubtarget().isIntrinsicSupported(ID))
3658 return handleUnsupportedIntrinsic(CI, ID, MIRBuilder);
3660 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3664 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3666 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3669bool IRTranslatorImpl::handleUnsupportedIntrinsic(
3672 F.getContext().diagnose(
3673 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3684bool IRTranslatorImpl::translateIntrinsic(
3687 if (!MF->getSubtarget().isIntrinsicSupported(ID))
3688 return handleUnsupportedIntrinsic(CB, ID, MIRBuilder);
3692 ResultRegs = getOrCreateVRegs(CB);
3696 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3707 assert(CI->getBitWidth() <= 64 &&
3708 "large intrinsic immediates not handled");
3709 MIB.
addImm(CI->getSExtValue());
3714 auto *MD = MDVal->getMetadata();
3718 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3725 if (VRegs.
size() > 1)
3732 for (
const auto &Info : TgtMemIntrinsicInfos) {
3735 LLT MemTy =
Info.memVT.isSimple()
3737 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3741 MachinePointerInfo MPI;
3743 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3744 }
else if (
Info.fallbackAddressSpace) {
3745 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3754 auto *Token = Bundle->Inputs[0].get();
3755 Register TokenReg = getOrCreateVReg(*Token);
3766bool IRTranslatorImpl::findUnwindDestinations(
3778 if (IsWasmCXX || IsWasmD) {
3788 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3794 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3795 UnwindDests.back().first->setIsEHScopeEntry();
3796 UnwindDests.back().first->setIsEHFuncletEntry();
3801 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3802 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3804 if (IsMSVCCXX || IsCoreCLR)
3805 UnwindDests.back().first->setIsEHFuncletEntry();
3807 UnwindDests.back().first->setIsEHScopeEntry();
3809 NewEHPadBB = CatchSwitch->getUnwindDest();
3814 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3815 if (BPI && NewEHPadBB)
3817 EHPadBB = NewEHPadBB;
3822bool IRTranslatorImpl::translateInvoke(
const User &U,
3825 MCContext &
Context = MF->getContext();
3830 const Function *Fn =
I.getCalledFunction();
3837 if (
I.hasDeoptState())
3851 (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI() &&
3855 bool LowerInlineAsm =
I.isInlineAsm();
3856 bool NeedEHLabel =
true;
3862 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3863 BeginSymbol =
Context.createTempSymbol();
3867 if (LowerInlineAsm) {
3868 if (!translateInlineAsm(
I, MIRBuilder))
3870 }
else if (!translateCallBase(
I, MIRBuilder))
3875 EndSymbol =
Context.createTempSymbol();
3880 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3881 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3882 BranchProbability EHPadBBProb =
3886 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3889 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3890 &ReturnMBB = getMBB(*ReturnBB);
3892 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3893 for (
auto &UnwindDest : UnwindDests) {
3894 UnwindDest.first->setIsEHPad();
3895 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3900 assert(BeginSymbol &&
"Expected a begin symbol!");
3901 assert(EndSymbol &&
"Expected an end symbol!");
3902 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3905 MIRBuilder.
buildBr(ReturnMBB);
3911bool IRTranslatorImpl::translateCallBr(
const User &U,
3913 if (!mayTranslateUserTypes(U))
3917 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3920 if (
I.isInlineAsm()) {
3926 if (!translateIntrinsic(
I, IID, MIRBuilder))
3930 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3931 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3940 for (BasicBlock *Dest :
I.getIndirectDests()) {
3941 MachineBasicBlock &
Target = getMBB(*Dest);
3942 Target.setIsInlineAsmBrIndirectTarget();
3943 Target.setLabelMustBeEmitted();
3945 if (Dests.
insert(Dest).second)
3957bool IRTranslatorImpl::translateLandingPad(
const User &U,
3961 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3967 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3968 if (TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel,
3969 PersonalityFn) == 0 &&
3970 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel,
3971 PersonalityFn) == 0)
3986 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3991 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3992 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3993 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
4002 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
4006 TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel, PersonalityFn);
4012 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
4015 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel, PersonalityFn);
4020 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
4021 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
4022 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
4027bool IRTranslatorImpl::translateAlloca(
const User &U,
4035 Register Res = getOrCreateVReg(AI);
4036 int FI = getOrCreateFrameIndex(AI);
4046 if (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI())
4051 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4053 if (MRI->getType(NumElts) !=
IntPtrTy) {
4065 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4070 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4072 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4077 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4086 if (Alignment <= StackAlign)
4090 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4091 assert(MF->getFrameInfo().hasVarSizedObjects());
4095bool IRTranslatorImpl::translateVAArg(
const User &U,
4101 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4102 {getOrCreateVReg(*
U.getOperand(0)),
4103 DL->getABITypeAlign(
U.getType()).value()});
4107bool IRTranslatorImpl::translateUnreachable(
const User &U,
4110 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4111 MF->getTarget().Options.NoTrapAfterNoreturn))
4118bool IRTranslatorImpl::translateInsertElement(
const User &U,
4123 FVT && FVT->getNumElements() == 1)
4124 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4127 Register Val = getOrCreateVReg(*
U.getOperand(0));
4128 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4129 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4132 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4133 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4134 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4135 Idx = getOrCreateVReg(*NewIdxCI);
4139 Idx = getOrCreateVReg(*
U.getOperand(2));
4140 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4141 const LLT VecIdxTy =
4142 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4149bool IRTranslatorImpl::translateInsertVector(
const User &U,
4152 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4153 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4156 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4161 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4166 ResultType && ResultType->getNumElements() == 1) {
4168 InputType && InputType->getNumElements() == 1) {
4172 return translateCopy(U, Vec, MIRBuilder);
4187 auto ScaledIndex = MIRBuilder.
buildMul(
4188 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4198bool IRTranslatorImpl::translateExtractElement(
const User &U,
4202 if (
const FixedVectorType *FVT =
4204 if (FVT->getNumElements() == 1)
4205 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4208 Register Val = getOrCreateVReg(*
U.getOperand(0));
4209 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4214 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4215 Idx = getOrCreateVReg(*NewIdxCI);
4219 Idx = getOrCreateVReg(*
U.getOperand(1));
4220 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4221 const LLT VecIdxTy =
4229bool IRTranslatorImpl::translateExtractVector(
const User &U,
4232 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4234 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4239 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4244 ResultType && ResultType->getNumElements() == 1) {
4246 InputType && InputType->getNumElements() == 1) {
4249 return translateCopy(U, Vec, MIRBuilder);
4264 auto ScaledIndex = MIRBuilder.
buildMul(
4265 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4275bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4281 if (
U.getOperand(0)->getType()->isScalableTy()) {
4282 Register Val = getOrCreateVReg(*
U.getOperand(0));
4284 MRI->getType(Val).getElementType(), Val, 0);
4291 Mask = SVI->getShuffleMask();
4302 unsigned M =
Mask[0];
4304 if (M == 0 || M == 1)
4305 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4311 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4312 }
else if (M < SrcElts * 2) {
4314 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4326 for (
int M : Mask) {
4328 if (M == 0 || M == 1) {
4329 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4331 if (!
Undef.isValid()) {
4332 Undef = MRI->createGenericVirtualRegister(SrcTy);
4342 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4344 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4345 {getOrCreateVReg(*
U.getOperand(0)),
4346 getOrCreateVReg(*
U.getOperand(1))})
4347 .addShuffleMask(MaskAlloc);
4351bool IRTranslatorImpl::translateBitInsert(
const User &U,
4355 Register Val = getOrCreateVReg(*
U.getOperand(1));
4357 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4359 LLT ValTy = MRI.getType(Val);
4362 "bitinsert val wider than base should be rejected by verifier");
4375 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(BaseTy);
4392 MIRBuilder.
buildOr(Res, ClearedBase, ShiftedVal);
4396bool IRTranslatorImpl::translateBitExtract(
const User &U,
4399 Register Src = getOrCreateVReg(*
U.getOperand(0));
4401 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4402 LLT SrcTy = MRI.getType(Src);
4403 LLT ResTy = MRI.getType(Res);
4406 "bitextract result wider than source should be rejected by verifier");
4409 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(SrcTy);
4419 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4421 if (SrcTy == IntResTy)
4432 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4434 if (SrcTy == IntResTy)
4451bool IRTranslatorImpl::translatePHI(
const User &U,
4455 SmallVector<MachineInstr *, 4> Insts;
4456 for (
auto Reg : getOrCreateVRegs(PI)) {
4457 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4461 PendingPHIs.emplace_back(&PI, std::move(Insts));
4465bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4469 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4471 auto Res = getOrCreateVRegs(
I);
4474 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4475 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4476 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4479 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4480 *MF->getMachineMemOperand(
4481 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4482 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4483 I.getSuccessOrdering(),
I.getFailureOrdering()));
4487bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4489 if (!mayTranslateUserTypes(U))
4493 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4496 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4497 Register Val = getOrCreateVReg(*
I.getValOperand());
4499 unsigned Opcode = 0;
4500 switch (
I.getOperation()) {
4504 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4507 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4510 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4513 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4516 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4519 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4522 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4525 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4528 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4531 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4534 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4537 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4540 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4543 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4546 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4549 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4552 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4555 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4558 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4561 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4564 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4567 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4570 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4575 Opcode, Res, Addr, Val,
4576 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4577 Flags, MRI->getType(Val), getMemOpAlign(
I),
4578 I.getAAMetadata(),
I.getSyncScopeID(),
4583bool IRTranslatorImpl::translateFence(
const User &U,
4587 Fence.getSyncScopeID());
4591bool IRTranslatorImpl::translateFreeze(
const User &U,
4597 "Freeze with different source and destination type?");
4599 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4606void IRTranslatorImpl::finishPendingConstDbgValues() {
4607 for (
auto [
MI,
C] : PendingConstDbgValues) {
4608 auto VRegsIt = VMap.findVRegs(*
C);
4609 if (VRegsIt == VMap.vregs_end() || VRegsIt->second->size() != 1)
4613 MachineIRBuilder Builder(*
MI);
4614 Builder.buildDirectDbgValue(VRegsIt->second->front(),
4615 MI->getDebugVariable(),
4616 MI->getDebugExpression());
4617 MI->eraseFromParent();
4619 PendingConstDbgValues.clear();
4622void IRTranslatorImpl::finishPendingPhis() {
4625 GISelObserverWrapper WrapperObserver(&
Verifier);
4626 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4628 for (
auto &Phi : PendingPHIs) {
4629 const PHINode *PI =
Phi.first;
4633 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4639 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4643 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4647 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4648 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4657void IRTranslatorImpl::translateDbgValueRecord(
Value *V,
bool HasArgList,
4663 "Expected inlined-at fields to agree");
4667 if (!V || HasArgList) {
4677 PendingConstDbgValues.emplace_back(
MI, CI);
4687 auto *ExprDerefRemoved =
4693 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
4705void IRTranslatorImpl::translateDbgDeclareRecord(
4710 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4715 "Expected inlined-at fields to agree");
4720 MF->setVariableDbgInfo(Variable, Expression,
4721 getOrCreateFrameIndex(*AI), DL);
4725 if (translateIfEntryValueArgument(
true,
Address, Variable,
4737void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4742 assert(DLR->getLabel() &&
"Missing label");
4743 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4745 "Expected inlined-at fields to agree");
4754 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
4757 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
4762bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4764 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4765 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4767 if (TLI->fallBackToDAGISel(Inst))
4771#define HANDLE_INST(NUM, OPCODE, CLASS) \
4772 case Instruction::OPCODE: \
4773 return translate##OPCODE(Inst, *CurBuilder.get());
4774#include "llvm/IR/Instruction.def"
4783 if (
auto CurrInstDL = CurBuilder->getDL())
4784 EntryBuilder->setDebugLoc(
DebugLoc());
4790 EntryBuilder->buildConstant(
Reg, *CI);
4794 EntryBuilder->buildConstant(
Reg, CB->getValue());
4798 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4799 EntryBuilder->buildFConstant(
Reg, *CF);
4801 EntryBuilder->buildUndef(
Reg);
4803 EntryBuilder->buildConstant(
Reg, 0);
4805 EntryBuilder->buildGlobalValue(
Reg, GV);
4807 Register Addr = getOrCreateVReg(*CPA->getPointer());
4808 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4809 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4811 Constant &Elt = *CAZ->getElementValue(0u);
4813 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4817 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4819 return translateCopy(
C, Elt, *EntryBuilder);
4821 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4824 if (CV->getNumElements() == 1)
4825 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4827 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4828 Constant &Elt = *CV->getElementAsConstant(i);
4829 Ops.push_back(getOrCreateVReg(Elt));
4831 EntryBuilder->buildBuildVector(
Reg,
Ops);
4833 switch(
CE->getOpcode()) {
4834#define HANDLE_INST(NUM, OPCODE, CLASS) \
4835 case Instruction::OPCODE: \
4836 return translate##OPCODE(*CE, *EntryBuilder.get());
4837#include "llvm/IR/Instruction.def"
4842 if (CV->getNumOperands() == 1)
4843 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4845 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4846 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4848 EntryBuilder->buildBuildVector(
Reg,
Ops);
4850 EntryBuilder->buildBlockAddress(
Reg, BA);
4857bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4858 const TargetMachine &TM = TLI->getTargetMachine();
4867 (!
U.getType()->getScalarType()->isBFloatTy() &&
4869 return V->getType()->getScalarType()->isBFloatTy();
4873bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4875 for (
auto &BTB : SL->BitTestCases) {
4878 emitBitTestHeader(BTB, BTB.Parent);
4880 BranchProbability UnhandledProb = BTB.Prob;
4881 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4882 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4884 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4893 MachineBasicBlock *NextMBB;
4894 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4897 NextMBB = BTB.Cases[
j + 1].TargetBB;
4898 }
else if (j + 1 == ej) {
4900 NextMBB = BTB.Default;
4903 NextMBB = BTB.Cases[
j + 1].ThisBB;
4906 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4908 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4912 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4913 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4916 BTB.Cases.pop_back();
4922 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4923 BTB.Default->getBasicBlock()};
4924 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4925 if (!BTB.ContiguousRange) {
4926 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4929 SL->BitTestCases.clear();
4931 for (
auto &JTCase : SL->JTCases) {
4933 if (!JTCase.first.Emitted)
4934 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4936 emitJumpTable(JTCase.second, JTCase.second.MBB);
4938 SL->JTCases.clear();
4940 for (
auto &SwCase : SL->SwitchCases)
4941 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4942 SL->SwitchCases.clear();
4945 if (SPInfo->shouldEmitSDCheck(BB)) {
4946 bool FunctionBasedInstrumentation =
4947 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4948 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4951 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4954 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4955 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4956 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4965 ParentMBB, *MF->getSubtarget().getInstrInfo());
4968 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4972 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4976 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4977 if (FailureMBB->
empty()) {
4978 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4983 SPDescriptor.resetPerBBState();
4990 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4994 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
5000 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
5007 ->buildLoad(PtrMemTy, StackSlotPtr,
5013 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
5025 FunctionType *FnTy = GuardCheckFn->getFunctionType();
5026 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
5027 ISD::ArgFlagsTy
Flags;
5028 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
5030 CallLowering::ArgInfo GuardArgInfo(
5031 {GuardVal, FnTy->getParamType(0), {
Flags}});
5033 CallLowering::CallLoweringInfo
Info;
5034 Info.OrigArgs.push_back(GuardArgInfo);
5035 Info.CallConv = GuardCheckFn->getCallingConv();
5038 if (!CLI->lowerCall(MIRBuilder, Info)) {
5039 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
5049 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
5050 getStackGuard(Guard, *CurBuilder);
5053 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
5055 Register GuardPtr = getOrCreateVReg(*IRGuard);
5058 ->buildLoad(PtrMemTy, GuardPtr,
5064 LLVMContext &Ctx = CurBuilder->getContext();
5065 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
5066 Guard = CurBuilder->buildUndef(PtrMemTy).getReg(0);
5082 const RTLIB::LibcallImpl LibcallImpl =
5083 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
5084 if (LibcallImpl == RTLIB::Unsupported)
5087 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
5089 CallLowering::CallLoweringInfo
Info;
5090 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
5092 StringRef LibcallName =
5097 if (!CLI->lowerCall(*CurBuilder, Info)) {
5098 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
5103 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
5105 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
5110void IRTranslatorImpl::finalizeFunction() {
5113 PendingPHIs.clear();
5114 PendingConstDbgValues.clear();
5116 FrameIndices.clear();
5117 MachinePreds.clear();
5121 EntryBuilder.reset();
5124 SPDescriptor.resetPerFunctionState();
5137 return CI && CI->isMustTailCall();
5149 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
5150 CLI = MF->getSubtarget().getCallLowering();
5151 SPInfo = StackProtectorInfo;
5153 if (CLI->fallBackToDAGISel(*MF)) {
5155 F.getSubprogram(), &
F.getEntryBlock());
5156 R <<
"unable to lower function: "
5157 <<
ore::NV(
"Prototype",
F.getFunctionType());
5174 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5175 CSEInfo = GetCSEInfo();
5176 EntryBuilder->setCSEInfo(CSEInfo);
5177 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5178 CurBuilder->setCSEInfo(CSEInfo);
5180 EntryBuilder = std::make_unique<MachineIRBuilder>();
5181 CurBuilder = std::make_unique<MachineIRBuilder>();
5184 CurBuilder->setMF(*MF);
5185 EntryBuilder->setMF(*MF);
5186 MRI = &MF->getRegInfo();
5187 DL = &
F.getDataLayout();
5191 FuncInfo.ExceptionModel =
F.getParent()->getExceptionModel();
5193 AA = GetAAResults();
5194 FuncInfo.BPI = GetBPI();
5198 FuncInfo.BPI =
nullptr;
5201 LibInfo = LibraryInfo;
5202 Libcalls = LibcallInfo;
5204 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5206 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5207 SL->init(*TLI, TM, *DL);
5209 assert(PendingPHIs.empty() &&
"stale PHIs");
5213 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5216 F.getSubprogram(), &
F.getEntryBlock());
5217 R <<
"unable to translate in big endian mode";
5228 EntryBuilder->setMBB(*EntryBB);
5230 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5231 SwiftError.setFunction(CurMF);
5232 SwiftError.createEntriesInEntryBlock(DbgLoc);
5234 bool IsVarArg =
F.isVarArg();
5235 bool HasMustTailInVarArgFn =
false;
5238 unsigned NumValues =
F.arg_size();
5241 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5243 NumValues += BB.
size();
5246 MBB = MF->CreateMachineBasicBlock(&BB);
5254 if (!BA->hasZeroLiveUses())
5258 if (!HasMustTailInVarArgFn)
5262 VMap.reserveVRegs(NumValues);
5263 MRI->reserveVirtRegs(NumValues);
5265 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5268 EntryBB->addSuccessor(&getMBB(
F.front()));
5273 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5278 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5279 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5280 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5284 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5286 F.getSubprogram(), &
F.getEntryBlock());
5287 R <<
"unable to lower arguments: "
5288 <<
ore::NV(
"Prototype",
F.getFunctionType());
5295 if (EnableCSE && CSEInfo)
5300 DILocationVerifier Verifier;
5308 CurBuilder->setMBB(
MBB);
5309 HasTailCall =
false;
5319 Verifier.setCurrentInst(&Inst);
5323 translateDbgInfo(Inst, *CurBuilder);
5325 if (translate(Inst))
5330 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5332 if (ORE->allowExtraAnalysis(
"gisel-ir-translator")) {
5333 std::string InstStrStorage;
5337 R <<
": '" << InstStrStorage <<
"'";
5344 if (!finalizeBasicBlock(*BB,
MBB)) {
5346 BB->getTerminator()->getDebugLoc(), BB);
5347 R <<
"unable to translate basic block";
5357 finishPendingPhis();
5358 finishPendingConstDbgValues();
5360 SwiftError.propagateVRegs();
5365 assert(EntryBB->succ_size() == 1 &&
5366 "Custom BB used for lowering should have only one successor");
5370 "LLVM-IR entry block has a predecessor!?");
5373 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5382 EntryBB->removeSuccessor(&NewEntryBB);
5383 MF->remove(EntryBB);
5384 MF->deleteMachineBasicBlock(EntryBB);
5386 assert(&MF->front() == &NewEntryBB &&
5387 "New entry wasn't next in the list of basic block!");
5390 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5400 return Impl->runOnMachineFunction(
5419 *
F.getParent(), Subtarget),
5444 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5445 Impl->runOnMachineFunction(
5447 ShouldSkipOpts, [&]() {
return &
FAM.getResult<
AAManager>(
F); },
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
This file describes how to lower LLVM calls to machine code calls.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This contains common code to allow clients to notify changes to machine instr.
const HexagonInstrInfo * TII
static cl::opt< bool > EnableCSEInIRTranslator("enable-cse-in-ir-translator", cl::desc("Should enable CSE in ir-translator"), cl::init(false))
static bool checkForMustTailInVarArgFn(bool IsVarArg, const BasicBlock &BB)
Returns true if a BasicBlock BB within a variadic function contains a variadic musttail call.
static unsigned getConvOpcode(Intrinsic::ID ID)
static uint64_t getOffsetFromIndices(const User &U, const DataLayout &DL)
static unsigned getConstrainedOpcode(Intrinsic::ID ID)
IRTranslator LLVM IR static false void reportTranslationError(MachineFunction &MF, OptimizationRemarkEmitter &ORE, OptimizationRemarkMissed &R)
static bool isValInBlock(const Value *V, const BasicBlock *BB)
static bool isSwiftError(const Value *V)
This file declares the IRTranslator pass.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This file describes how to lower LLVM inline asm to machine code INLINEASM.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Implement a low-level type suitable for MachineInstr level instruction selection.
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
OptimizedStructLayoutField Field
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
SmallVector< MachineOperand, 4 > Cond
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
std::pair< BasicBlock *, BasicBlock * > Edge
verify safepoint Safepoint IR Verifier
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
LLVM_ABI TypeSize getAllocationBaseSize(const DataLayout &DL) const
Get the size of the allocated type.
PointerType * getType() const
Overload to return most specific pointer type.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
const Value * getArraySize() const
Get the number of elements allocated.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
This class represents an incoming formal argument to a Function.
LLVM_ABI bool hasSwiftErrorAttr() const
Return true if this argument has the swifterror attribute.
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.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
@ USubCond
Subtract only if no unsigned overflow.
@ FMinimum
*p = minimum(old, v) minimum matches the behavior of llvm.minimum.
@ Min
*p = old <signed v ? old : v
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ FMaximum
*p = maximum(old, v) maximum matches the behavior of llvm.maximum.
@ UIncWrap
Increment one up to a maximum value.
@ Max
*p = old >signed v ? old : v
@ UMin
*p = old <unsigned v ? old : v
@ FMin
*p = minnum(old, v) minnum matches the behavior of llvm.minnum.
@ UMax
*p = old >unsigned v ? old : v
@ FMaximumNum
*p = maximumnum(old, v) maximumnum matches the behavior of llvm.maximumnum.
@ FMax
*p = maxnum(old, v) maxnum matches the behavior of llvm.maxnum.
@ UDecWrap
Decrement one until a minimum value or zero.
@ FMinimumNum
*p = minimumnum(old, v) minimumnum matches the behavior of llvm.minimumnum.
LLVM Basic Block Representation.
unsigned getNumber() const
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
InstListType::const_iterator const_iterator
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
The address of a basic block.
static LLVM_ABI BlockAddress * lookup(const BasicBlock *BB)
Lookup an existing BlockAddress constant for the given BasicBlock.
Legacy analysis pass which computes BlockFrequencyInfo.
Analysis pass which computes BranchProbabilityInfo.
Legacy analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
static constexpr BranchProbability getOne()
static constexpr BranchProbability getUnknown()
static constexpr BranchProbability getZero()
static void normalizeProbabilities(ProbabilityIter Begin, ProbabilityIter End)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool isInlineAsm() const
Check if this call is an inline asm statement.
bool cannotMerge() const
Determine if the call cannot be tail merged.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
unsigned countOperandBundlesOfType(StringRef Name) const
Return the number of operand bundles with the tag Name attached to this instruction.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Value * getCalledOperand() const
Value * getArgOperand(unsigned i) const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
bool isConvergent() const
Determine if the invoke is convergent.
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
bool isFPPredicate() const
bool isIntPredicate() const
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This is the common base class for constrained floating point intrinsics.
LLVM_ABI std::optional< fp::ExceptionBehavior > getExceptionBehavior() const
LLVM_ABI unsigned getNonMetadataArgCount() const
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
LLVM_ABI bool startsWithDeref() const
Return whether the first element a DW_OP_deref.
ArrayRef< uint64_t > getElements() const
A parsed version of the target data layout string in and methods for querying it.
DebugLoc getDebugLoc() const
LLVM_ABI Value * getVariableLocationOp(unsigned OpIdx) const
DIExpression * getExpression() const
DILocalVariable * getVariable() const
bool isDbgDeclare() const
static DebugLoc getDropped()
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Class representing an expression and its matching format.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Constant * getPersonalityFn() const
Get the personality function associated with this function.
const Function & getFunction() const
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasOptNone() const
Do not optimize this function (-O0).
The actual analysis pass wrapper.
Simple wrapper that does the following.
Abstract class that contains various methods for clients to notify about changes.
Simple wrapper observer that takes several observers, and calls each one for each event.
void removeObserver(GISelChangeObserver *O)
void addObserver(GISelChangeObserver *O)
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
bool hasExternalWeakLinkage() const
bool hasDLLImportStorageClass() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isTailCall(const MachineInstr &MI) const override
IRTranslatorImpl(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
bool runOnMachineFunction(MachineFunction &MF, function_ref< GISelCSEInfo *()> GetCSEInfo, bool ShouldSkipOpts, function_ref< AAResults *()> GetAAResults, function_ref< BranchProbabilityInfo *()> GetBPI, function_ref< AssumptionCache *()> GetAC, TargetLibraryInfo *LibraryInfo, const LibcallLoweringInfo *LibcallInfo, SSPLayoutInfo *StackProtectorInfo)
IRTranslatorLegacy(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
~IRTranslatorLegacy() override
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI ~IRTranslatorPass()
LLVM_ABI IRTranslatorPass(CodeGenOptLevel OptLevel)
bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB, std::function< ArrayRef< Register >(const Value &Val)> GetOrCreateVRegs) const
Lower the given inline asm call instruction GetOrCreateVRegs is a callback to materialize a register ...
This instruction inserts a struct field of array element value into an aggregate value.
iterator_range< simple_ilist< DbgRecord >::iterator > getDbgRecordRange() const
Return a range over the DbgRecords attached to this instruction.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static bool getUseExtended()
constexpr bool isScalar() const
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isFloat() const
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
static constexpr LLT token()
Get a low-level token; just a scalar with zero bits (or no size).
static LLT integer(unsigned SizeInBits)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Tracks which library functions to use for a particular subtarget or function.
Value * getPointerOperand()
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this load instruction.
static LocationSize precise(uint64_t Value)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned pred_size() const
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void setSuccProbability(succ_iterator I, BranchProbability Prob)
Set successor probability of a given iterator.
succ_iterator succ_begin()
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
LLVM_ABI void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
LLVM_ABI bool isPredecessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a predecessor of this block.
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
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.
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
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
int getStackProtectorIndex() const
Return the index for the stack protector object.
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
Helper class to build MachineInstr.
MachineInstrBuilder buildFPTOUI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOUI_SAT Src0.
MachineInstrBuilder buildFMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildFreeze(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_FREEZE Src.
MachineInstrBuilder buildBr(MachineBasicBlock &Dest)
Build and insert G_BR Dest.
MachineInstrBuilder buildModf(const DstOp &Fract, const DstOp &Int, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Int = G_FMODF Src.
LLVMContext & getContext() const
MachineInstrBuilder buildAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_ADD Op0, Op1.
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
MachineInstrBuilder buildResetFPMode()
Build and insert G_RESET_FPMODE.
MachineInstrBuilder buildNot(const DstOp &Dst, const SrcOp &Src0)
Build and insert a bitwise not, NegOne = G_CONSTANT -1 Res = G_OR Op0, NegOne.
MachineInstrBuilder buildFPTOSI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOSI_SAT Src0.
MachineInstrBuilder buildUCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_UCMP Op0, Op1.
MachineInstrBuilder buildJumpTable(const LLT PtrTy, unsigned JTI)
Build and insert Res = G_JUMP_TABLE JTI.
MachineInstrBuilder buildGetRounding(const DstOp &Dst)
Build and insert Dst = G_GET_ROUNDING.
MachineInstrBuilder buildSCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_SCMP Op0, Op1.
MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope)
Build and insert G_FENCE Ordering, Scope.
MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
MachineInstrBuilder buildFMA(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, const SrcOp &Src2, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FMA Op0, Op1, Op2.
MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_MUL Op0, Op1.
MachineInstrBuilder buildInsertSubvector(const DstOp &Res, const SrcOp &Src0, const SrcOp &Src1, unsigned Index)
Build and insert Res = G_INSERT_SUBVECTOR Src0, Src1, Idx.
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildCast(const DstOp &Dst, const SrcOp &Src)
Build and insert an appropriate cast between two registers of equal size.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
MachineInstrBuilder buildLShr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
MachineInstrBuilder buildSExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildAtomicRMW(unsigned Opcode, const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val, MachineMemOperand &MMO)
Build and insert OldValRes<def> = G_ATOMICRMW_<Opcode> Addr, Val, MMO.
MachineInstrBuilder buildSub(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_SUB Op0, Op1.
MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef< Register > Res, bool HasSideEffects, bool isConvergent)
Build and insert a G_INTRINSIC instruction.
MachineInstrBuilder buildVScale(const DstOp &Res, unsigned MinElts)
Build and insert Res = G_VSCALE MinElts.
MachineInstrBuilder buildSplatBuildVector(const DstOp &Res, const SrcOp &Src)
Build and insert Res = G_BUILD_VECTOR with Src replicated to fill the number of elements.
MachineInstrBuilder buildSetFPMode(const SrcOp &Src)
Build and insert G_SET_FPMODE Src.
MachineInstrBuilder buildIntToPtr(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_INTTOPTR instruction.
MachineInstrBuilder buildIndirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in me...
MachineInstrBuilder buildBuildVector(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ...
MachineInstrBuilder buildConstDbgValue(const Constant &C, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instructions specifying that Variable is given by C (suitably modified b...
MachineInstrBuilder buildBrCond(const SrcOp &Tst, MachineBasicBlock &Dest)
Build and insert G_BRCOND Tst, Dest.
std::optional< MachineInstrBuilder > materializeObjectPtrOffset(Register &Res, Register Op0, const LLT ValueTy, uint64_t Value)
Materialize and insert an instruction with appropriate flags for addressing some offset of an object,...
MachineInstrBuilder buildSetRounding(const SrcOp &Src)
Build and insert G_SET_ROUNDING.
MachineInstrBuilder buildExtractVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_PTR_ADD Op0, Op1.
MachineInstrBuilder buildZExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildExtractVectorElementConstant(const DstOp &Res, const SrcOp &Val, const int Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildShl(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineInstrBuilder buildDirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in Re...
MachineInstrBuilder buildDbgLabel(const MDNode *Label)
Build and insert a DBG_LABEL instructions specifying that Label is given.
MachineInstrBuilder buildBrJT(Register TablePtr, unsigned JTI, Register IndexReg)
Build and insert G_BRJT TablePtr, JTI, IndexReg.
MachineInstrBuilder buildDynStackAlloc(const DstOp &Res, const SrcOp &Size, Align Alignment)
Build and insert Res = G_DYN_STACKALLOC Size, Align.
MachineInstrBuilder buildFIDbgValue(int FI, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in th...
MachineInstrBuilder buildResetFPEnv()
Build and insert G_RESET_FPENV.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
void setDebugLoc(const DebugLoc &DL)
Set the debug location to DL for all the next build instructions.
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
MachineInstrBuilder buildInsertVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Elt, const SrcOp &Idx)
Build and insert Res = G_INSERT_VECTOR_ELT Val, Elt, Idx.
MachineInstrBuilder buildAtomicCmpXchgWithSuccess(const DstOp &OldValRes, const DstOp &SuccessRes, const SrcOp &Addr, const SrcOp &CmpVal, const SrcOp &NewVal, MachineMemOperand &MMO)
Build and insert OldValRes<def>, SuccessRes<def> = / G_ATOMIC_CMPXCHG_WITH_SUCCESS Addr,...
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
MachineInstrBuilder buildBitcast(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_BITCAST Src.
const DebugLoc & getDebugLoc()
Get the current instruction's debug location.
MachineInstrBuilder buildTrap(bool Debug=false)
Build and insert G_TRAP or G_DEBUGTRAP.
MachineInstrBuilder buildFFrexp(const DstOp &Fract, const DstOp &Exp, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Exp = G_FFREXP Src.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildOr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_OR Op0, Op1.
MachineInstrBuilder buildFSincos(const DstOp &Sin, const DstOp &Cos, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Sin, Cos = G_FSINCOS Src.
MachineInstrBuilder buildShuffleVector(const DstOp &Res, const SrcOp &Src1, const SrcOp &Src2, ArrayRef< int > Mask)
Build and insert Res = G_SHUFFLE_VECTOR Src1, Src2, Mask.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildPrefetch(const SrcOp &Addr, unsigned RW, unsigned Locality, unsigned CacheType, MachineMemOperand &MMO)
Build and insert G_PREFETCH Addr, RW, Locality, CacheType.
MachineInstrBuilder buildExtractSubvector(const DstOp &Res, const SrcOp &Src, unsigned Index)
Build and insert Res = G_EXTRACT_SUBVECTOR Src, Idx0.
const DataLayout & getDataLayout() const
MachineInstrBuilder buildBrIndirect(Register Tgt)
Build and insert G_BRINDIRECT Tgt.
MachineInstrBuilder buildSplatVector(const DstOp &Res, const SrcOp &Val)
Build and insert Res = G_SPLAT_VECTOR Val.
MachineInstrBuilder buildStepVector(const DstOp &Res, unsigned Step)
Build and insert Res = G_STEP_VECTOR Step.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_FCMP PredOp0, Op1.
MachineInstrBuilder buildFAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FADD Op0, Op1.
MachineInstrBuilder buildSetFPEnv(const SrcOp &Src)
Build and insert G_SET_FPENV Src.
MachineInstrBuilder buildPtrToInt(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_PTRTOINT instruction.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addFPImm(const ConstantFP *Val) 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 & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
LLVM_ABI void copyIRFlags(const Instruction &I)
Copy all flags to MachineInst MIFlags.
static LLVM_ABI uint32_t copyFlagsFromInstruction(const Instruction &I)
LLVM_ABI void setDeactivationSymbol(MachineFunction &MF, Value *DS)
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MONonTemporal
The memory access is non-temporal.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
static MachineOperand CreateES(const char *SymName, unsigned TargetFlags=0)
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
A set of analyses that are preserved following a run of a transformation pass.
Class to install both of the above.
Wrapper class representing virtual and physical registers.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
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.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Encapsulates all of the information needed to generate a stack protector check, and signals to isel w...
MachineBasicBlock * getSuccessMBB()
MachineBasicBlock * getFailureMBB()
constexpr bool empty() const
Check if the string is empty.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
SwitchLowering(FunctionLoweringInfo &funcinfo)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
const Target & getTarget() const
unsigned NoTrapAfterNoreturn
Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
Target-Independent Code Generator Pass Configuration Options.
virtual std::unique_ptr< CSEConfigBase > getCSEConfig() const
Returns the CSEConfig object to use for the current optimization level.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const CallLowering * getCallLowering() const
virtual const TargetLowering * getTargetLowering() const
bool isSPIRV() const
Tests whether the target is SPIR-V (32/64-bit/Logical).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getZero()
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isByteOrByteVectorTy() const
Return true if this is a byte type or a vector of byte types.
bool isAggregateType() const
Return true if the type is an aggregate type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isTokenTy() const
Return true if this is 'token'.
bool isVoidTy() const
Return true if this is 'void'.
BasicBlock * getSuccessor(unsigned i=0) const
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
constexpr bool isZero() const
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
A raw_ostream that writes to an std::string.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
LLVM_ABI void sortAndRangeify(CaseClusterVector &Clusters)
Sort Clusters and merge adjacent cases.
std::vector< CaseCluster > CaseClusterVector
@ CC_Range
A cluster of adjacent case labels with the same destination, or just one case.
@ CC_JumpTable
A cluster of cases suitable for jump table lowering.
@ CC_BitTests
A cluster of cases suitable for bit test lowering.
SmallVector< SwitchWorkListItem, 4 > SwitchWorkList
CaseClusterVector::iterator CaseClusterIt
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
ExceptionBehavior
Exception behavior used for floating point operations.
@ ebIgnore
This corresponds to "fpexcept.ignore".
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< PhiNode * > Phi
NodeAddr< CodeNode * > Code
friend class Instruction
Iterator for Instructions in a `BasicBlock.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
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.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
LLVM_ABI void diagnoseDontCall(const CallInst &CI)
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isExceptionPointerAndSelectorType(Type *Ty)
Return true if landingpad result type Ty is a struct of an exception pointer (pointer or integer) and...
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
gep_type_iterator gep_type_end(const User *GEP)
LLVM_ABI MachineBasicBlock::iterator findSplitPointForStackProtector(MachineBasicBlock *BB, const TargetInstrInfo &TII)
Find the split point at which to splice the end of BB into its success stack protector check machine ...
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
constexpr bool has_single_bit(T Value) noexcept
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 llvm::SmallVector< int, 16 > createStrideMask(unsigned Start, unsigned Stride, unsigned VF)
Create a stride shuffle mask.
auto reverse(ContainerTy &&C)
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
auto succ_size(const MachineBasicBlock *BB)
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Global
Append to llvm.global_dtors.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
LLVM_ABI llvm::SmallVector< int, 16 > createInterleaveMask(unsigned VF, unsigned NumVecs)
Create an interleave shuffle mask.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::optional< RoundingMode > convertStrToRoundingMode(StringRef)
Returns a valid RoundingMode enumerator when given a string that is valid as input in constrained int...
gep_type_iterator gep_type_begin(const User *GEP)
LLVM_ABI void computeValueLLTs(const DataLayout &DL, Type &Ty, SmallVectorImpl< LLT > &ValueLLTs, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
computeValueLLTs - Given an LLVM IR type, compute a sequence of LLTs that represent all the individua...
LLVM_ABI GlobalValue * ExtractTypeInfo(Value *V)
ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
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.
Pair of physical register and lane mask.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
bool shouldSkipOptimizationForOptBisect(IRUnitRef IR)
MachineBasicBlock * Parent
This structure is used to communicate between SelectionDAGBuilder and SDISel for the code generation ...
BranchProbability TrueProb
MachineBasicBlock * ThisBB
struct PredInfoPair PredInfo
BranchProbability FalseProb
MachineBasicBlock * TrueBB
MachineBasicBlock * FalseBB
Register Reg
The virtual register containing the index of the jump table entry to jump to.
MachineBasicBlock * Default
The MBB of the default bb, which is a successor of the range check MBB.
unsigned JTI
The JumpTableIndex for this jump table in the function.
MachineBasicBlock * MBB
The MBB into which to emit the code for the indirect jump.