70#include "llvm/IR/IntrinsicsAMDGPU.h"
99#define DEBUG_TYPE "irtranslator"
105 cl::desc(
"Should enable CSE in irtranslator"),
117 class ValueToVRegInfo {
119 ValueToVRegInfo() =
default;
124 using const_vreg_iterator =
126 using const_offset_iterator =
129 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
131 VRegListT *getVRegs(
const Value &V) {
132 auto [It, Inserted] = ValToVRegs.try_emplace(&V);
138 It->second =
new (VRegAlloc.Allocate()) VRegListT();
142 OffsetListT *getOffsets(
const Value &V) {
143 assert(V.getType()->isAggregateType() &&
144 "Offsets are for aggregate values");
145 auto [It, Inserted] = TypeToOffsets.try_emplace(V.getType());
149 It->second =
new (OffsetAlloc.Allocate()) OffsetListT();
153 const_vreg_iterator findVRegs(
const Value &V)
const {
154 return ValToVRegs.find(&V);
157 bool contains(
const Value &V)
const {
return ValToVRegs.contains(&V); }
159 void reserveVRegs(
unsigned NumValues) { ValToVRegs.reserve(NumValues); }
163 TypeToOffsets.clear();
164 VRegAlloc.DestroyAll();
165 OffsetAlloc.DestroyAll();
180 ValueToVRegInfo VMap;
187 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
242 void translateDbgValueRecord(
Value *V,
bool HasArgList,
251 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
258 bool translateCopy(
const User &U,
const Value &V,
283 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
285 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
290 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
292 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
314 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
320 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
335 bool translateIntrinsic(
347 bool findUnwindDestinations(
360 bool translateCast(
unsigned Opcode,
const User &U,
371 return translateCompare(U, MIRBuilder);
376 return translateCompare(U, MIRBuilder);
381 void finishPendingPhis();
385 bool translateUnaryOp(
unsigned Opcode,
const User &U,
390 bool translateBinaryOp(
unsigned Opcode,
const User &U,
396 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
441 bool lowerJumpTableWorkItem(
450 bool FallthroughUnreachable,
456 bool lowerBitTestWorkItem(
462 bool FallthroughUnreachable);
493 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
496 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
499 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
502 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
505 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
508 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
512 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
515 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
518 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
521 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
524 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
527 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
531 return translatePtrToInt(U, MIRBuilder);
534 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
537 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
540 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
543 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
546 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
549 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
552 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
557 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
561 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
565 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
568 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
571 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
575 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
578 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
581 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
584 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
587 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
620 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
635 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
646 std::unique_ptr<MachineIRBuilder> CurBuilder;
651 std::unique_ptr<MachineIRBuilder> EntryBuilder;
664 std::unique_ptr<OptimizationRemarkEmitter> ORE;
675 bool EnableOpts =
false;
679 bool HasTailCall =
false;
683 bool mayTranslateUserTypes(
const User &U)
const;
690 assert(irt &&
"irt is null!");
693 void addSuccessorWithProb(
696 IRT->addSuccessorWithProb(Src, Dst, Prob);
699 ~GISelSwitchLowering()
override =
default;
705 std::unique_ptr<GISelSwitchLowering> SL;
711 void finalizeFunction();
749 auto Regs = getOrCreateVRegs(Val);
752 assert(Regs.size() == 1 &&
753 "attempt to get single VReg for aggregate or void");
757 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
759 auto &Regs = *VMap.getVRegs(Token);
761 assert(Regs.size() == 1 &&
762 "Expected a single register for convergence tokens.");
766 auto Reg = MRI->createGenericVirtualRegister(
LLT::token());
773 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
777 int getOrCreateFrameIndex(
const AllocaInst &AI);
800 auto RemappedEdge = MachinePreds.find(Edge);
801 if (RemappedEdge != MachinePreds.end())
802 return RemappedEdge->second;
811 void addSuccessorWithProb(
817 : OptLevel(OptLevel) {}
847 "IRTranslator LLVM IR -> MI",
false,
false)
859 MF.getProperties().setFailedISel();
860 bool IsGlobalISelAbortEnabled =
865 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
866 R << (
" (in function: " + MF.getName() +
")").str();
868 if (IsGlobalISelAbortEnabled)
888 DILocationVerifier() =
default;
889 ~DILocationVerifier()
override =
default;
891 const Instruction *getCurrentInst()
const {
return CurrInst; }
892 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
894 void erasingInstr(MachineInstr &
MI)
override {}
895 void changingInstr(MachineInstr &
MI)
override {}
896 void changedInstr(MachineInstr &
MI)
override {}
898 void createdInstr(MachineInstr &
MI)
override {
899 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
904 <<
" was copied to " <<
MI);
910 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
911 (
MI.isDebugInstr())) &&
912 "Line info was not transferred to all instructions");
935IRTranslatorImpl::ValueToVRegInfo::VRegListT &
936IRTranslatorImpl::allocateVRegs(
const Value &Val) {
937 auto VRegsIt = VMap.findVRegs(Val);
938 if (VRegsIt != VMap.vregs_end())
939 return *VRegsIt->second;
940 auto *Regs = VMap.getVRegs(Val);
946 auto *Offsets = VMap.getOffsets(Val);
949 Offsets->empty() ? Offsets :
nullptr);
950 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
956 auto VRegsIt = VMap.findVRegs(Val);
957 if (VRegsIt != VMap.vregs_end())
958 return *VRegsIt->second;
961 return *VMap.getVRegs(Val);
964 auto *VRegs = VMap.getVRegs(Val);
968 "Don't know how to create an empty vreg");
973 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
977 OptimizationRemarkMissed
R(
"gisel-irtranslator",
"GISelFailure",
978 MF->getFunction().getSubprogram(),
979 &MF->getFunction().getEntryBlock());
980 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
988 auto *
Offsets = VMap.getOffsets(Val);
990 Offsets->empty() ? Offsets :
nullptr);
993 for (
auto Ty : SplitTys)
994 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
1001 while (
auto Elt =
C.getAggregateElement(Idx++)) {
1002 auto EltRegs = getOrCreateVRegs(*Elt);
1009int IRTranslatorImpl::getOrCreateFrameIndex(
const AllocaInst &AI) {
1010 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
1012 return MapEntry->second;
1018 Size = std::max<uint64_t>(
Size, 1u);
1020 int &FI = MapEntry->second;
1021 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
1028 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
1029 MF->getFrameInfo().setStackID(FI, StackID);
1037 return SI->getAlign();
1039 return LI->getAlign();
1045 OptimizationRemarkMissed
R(
"gisel-irtranslator",
"", &
I);
1046 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
1052 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
1053 assert(
MBB &&
"BasicBlock was not encountered before");
1057void IRTranslatorImpl::addMachineCFGPred(CFGEdge
Edge,
1059 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
1060 MachinePreds[
Edge].push_back(NewPred);
1063bool IRTranslatorImpl::translateBinaryOp(
unsigned Opcode,
const User &U,
1065 if (!mayTranslateUserTypes(U))
1072 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1073 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1085bool IRTranslatorImpl::translateUnaryOp(
unsigned Opcode,
const User &U,
1087 if (!mayTranslateUserTypes(U))
1090 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1101bool IRTranslatorImpl::translateFNeg(
const User &U,
1103 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
1106bool IRTranslatorImpl::translateCompare(
const User &U,
1108 if (!mayTranslateUserTypes(U))
1112 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1113 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1118 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1, Flags);
1126 MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1, Flags);
1131bool IRTranslatorImpl::translateRet(
const User &U,
1135 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
1140 VRegs = getOrCreateVRegs(*Ret);
1143 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
1144 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
1145 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
1151 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
1154void IRTranslatorImpl::emitBranchForMergedCondition(
1163 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
1166 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
1169 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
1170 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
1171 CurBuilder->getDebugLoc(), TProb, FProb);
1172 SL->SwitchCases.push_back(CB);
1178 SwitchCG::CaseBlock CB(
1180 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
1181 SL->SwitchCases.push_back(CB);
1186 return I->getParent() == BB;
1190void IRTranslatorImpl::findMergedConditions(
1195 using namespace PatternMatch;
1196 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
1197 "Expected Opc to be AND/OR");
1203 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
1209 const Value *BOpOp0, *BOpOp1;
1223 if (BOpc == Instruction::And)
1224 BOpc = Instruction::Or;
1225 else if (BOpc == Instruction::Or)
1226 BOpc = Instruction::And;
1232 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
1236 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
1243 MachineBasicBlock *TmpBB =
1247 if (
Opc == Instruction::Or) {
1268 auto NewTrueProb = TProb / 2;
1269 auto NewFalseProb = TProb / 2 + FProb;
1271 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1272 NewFalseProb, InvertCond);
1278 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1279 Probs[1], InvertCond);
1281 assert(
Opc == Instruction::And &&
"Unknown merge op!");
1301 auto NewTrueProb = TProb + FProb / 2;
1302 auto NewFalseProb = FProb / 2;
1304 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1305 NewFalseProb, InvertCond);
1311 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1312 Probs[1], InvertCond);
1316bool IRTranslatorImpl::shouldEmitAsBranches(
1317 const std::vector<SwitchCG::CaseBlock> &Cases) {
1319 if (Cases.size() != 2)
1324 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
1325 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
1326 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
1327 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
1333 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
1334 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
1338 Cases[0].TrueBB == Cases[1].ThisBB)
1341 Cases[0].FalseBB == Cases[1].ThisBB)
1348bool IRTranslatorImpl::translateUncondBr(
const User &U,
1351 auto &CurMBB = MIRBuilder.
getMBB();
1356 MIRBuilder.
buildBr(*Succ0MBB);
1359 for (
const BasicBlock *Succ :
successors(&BrInst))
1364bool IRTranslatorImpl::translateCondBr(
const User &U,
1367 auto &CurMBB = MIRBuilder.
getMBB();
1373 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
1392 using namespace PatternMatch;
1394 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
1395 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
1398 const Value *BOp0, *BOp1;
1400 Opcode = Instruction::And;
1402 Opcode = Instruction::Or;
1406 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
1407 getEdgeProbability(&CurMBB, Succ0MBB),
1408 getEdgeProbability(&CurMBB, Succ1MBB),
1410 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
1413 if (shouldEmitAsBranches(SL->SwitchCases)) {
1415 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
1416 SL->SwitchCases.erase(SL->SwitchCases.begin());
1422 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
1423 MF->erase(SL->SwitchCases[
I].ThisBB);
1425 SL->SwitchCases.clear();
1432 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
1433 CurBuilder->getDebugLoc());
1437 emitSwitchCase(CB, &CurMBB, *CurBuilder);
1444 if (!FuncInfo.BPI) {
1445 Src->addSuccessorWithoutProb(Dst);
1449 Prob = getEdgeProbability(Src, Dst);
1450 Src->addSuccessor(Dst, Prob);
1456 const BasicBlock *SrcBB = Src->getBasicBlock();
1457 const BasicBlock *DstBB = Dst->getBasicBlock();
1458 if (!FuncInfo.BPI) {
1461 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
1462 return BranchProbability(1, SuccSize);
1464 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
1468 using namespace SwitchCG;
1471 BranchProbabilityInfo *BPI = FuncInfo.BPI;
1473 Clusters.reserve(
SI.getNumCases());
1474 for (
const auto &
I :
SI.cases()) {
1475 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
1476 assert(Succ &&
"Could not find successor mbb in mapping");
1477 const ConstantInt *CaseVal =
I.getCaseValue();
1478 BranchProbability Prob =
1480 : BranchProbability(1,
SI.getNumCases() + 1);
1481 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
1484 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
1491 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
1494 if (Clusters.empty()) {
1501 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
1502 SL->findBitTestClusters(Clusters, &SI);
1505 dbgs() <<
"Case clusters: ";
1506 for (
const CaseCluster &
C : Clusters) {
1507 if (
C.Kind == CC_JumpTable)
1509 if (
C.Kind == CC_BitTests)
1512 C.Low->getValue().print(
dbgs(),
true);
1513 if (
C.Low !=
C.High) {
1515 C.High->getValue().print(
dbgs(),
true);
1522 assert(!Clusters.empty());
1526 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
1527 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
1529 while (!WorkList.empty()) {
1530 SwitchWorkListItem
W = WorkList.pop_back_val();
1532 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
1534 if (NumClusters > 3 &&
1537 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
1541 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
1551 using namespace SwitchCG;
1552 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
1553 "Clusters not sorted?");
1554 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
1556 auto [LastLeft, FirstRight, LeftProb, RightProb] =
1557 SL->computeSplitWorkItemInfo(W);
1562 assert(PivotCluster >
W.FirstCluster);
1563 assert(PivotCluster <=
W.LastCluster);
1568 const ConstantInt *Pivot = PivotCluster->Low;
1577 MachineBasicBlock *LeftMBB;
1578 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
1579 FirstLeft->Low ==
W.GE &&
1580 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
1581 LeftMBB = FirstLeft->MBB;
1583 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1584 FuncInfo.MF->
insert(BBI, LeftMBB);
1586 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
1592 MachineBasicBlock *RightMBB;
1593 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
1594 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
1595 RightMBB = FirstRight->MBB;
1597 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1598 FuncInfo.MF->
insert(BBI, RightMBB);
1600 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
1608 if (
W.MBB == SwitchMBB)
1609 emitSwitchCase(CB, SwitchMBB, MIB);
1611 SL->SwitchCases.push_back(CB);
1617 assert(JT.
Reg &&
"Should lower JT Header first!");
1632 MachineIRBuilder MIB(*HeaderBB->
getParent());
1639 Register SwitchOpReg = getOrCreateVReg(SValue);
1641 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
1646 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
1660 auto Cst = getOrCreateVReg(
1700 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
1714 "Can only handle SLE ranges");
1725 const LLT CmpTy = MRI->getType(CmpOpReg);
1726 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1752bool IRTranslatorImpl::lowerJumpTableWorkItem(
1758 using namespace SwitchCG;
1761 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1762 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1763 BranchProbability DefaultProb =
W.DefaultProb;
1766 MachineBasicBlock *JumpMBB = JT->
MBB;
1767 CurMF->
insert(BBI, JumpMBB);
1777 auto JumpProb =
I->Prob;
1778 auto FallthroughProb = UnhandledProbs;
1786 if (*SI == DefaultMBB) {
1787 JumpProb += DefaultProb / 2;
1788 FallthroughProb -= DefaultProb / 2;
1793 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1798 if (FallthroughUnreachable)
1799 JTH->FallthroughUnreachable =
true;
1801 if (!JTH->FallthroughUnreachable)
1802 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1803 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1808 JTH->HeaderBB = CurMBB;
1812 if (CurMBB == SwitchMBB) {
1813 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1815 JTH->Emitted =
true;
1819bool IRTranslatorImpl::lowerSwitchRangeWorkItem(
1824 using namespace SwitchCG;
1827 if (
I->Low ==
I->High) {
1843 CaseBlock CB(Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1846 emitSwitchCase(CB, SwitchMBB, MIB);
1852 MachineIRBuilder &MIB = *CurBuilder;
1856 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1858 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1860 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1865 LLT MaskTy = SwitchOpTy;
1871 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1880 Register SubReg = RangeSub.getReg(0);
1881 if (SwitchOpTy != MaskTy)
1887 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1889 if (!
B.FallthroughUnreachable)
1890 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1891 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1895 if (!
B.FallthroughUnreachable) {
1899 RangeSub, RangeCst);
1913 MachineIRBuilder &MIB = *CurBuilder;
1919 if (PopCount == 1) {
1922 auto MaskTrailingZeros =
1927 }
else if (PopCount == BB.
Range) {
1929 auto MaskTrailingOnes =
1937 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1941 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1948 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1950 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1968bool IRTranslatorImpl::lowerBitTestWorkItem(
1974 bool FallthroughUnreachable) {
1975 using namespace SwitchCG;
1978 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
1980 for (BitTestCase &BTC : BTB->Cases)
1981 CurMF->
insert(BBI, BTC.ThisBB);
1984 BTB->Parent = CurMBB;
1985 BTB->Default = Fallthrough;
1987 BTB->DefaultProb = UnhandledProbs;
1991 if (!BTB->ContiguousRange) {
1992 BTB->Prob += DefaultProb / 2;
1993 BTB->DefaultProb -= DefaultProb / 2;
1996 if (FallthroughUnreachable)
1997 BTB->FallthroughUnreachable =
true;
2000 if (CurMBB == SwitchMBB) {
2001 emitBitTestHeader(*BTB, SwitchMBB);
2002 BTB->Emitted =
true;
2012 using namespace SwitchCG;
2014 MachineBasicBlock *NextMBB =
nullptr;
2016 if (++BBI != FuncInfo.MF->end())
2025 [](
const CaseCluster &a,
const CaseCluster &b) {
2026 return a.Prob != b.Prob
2028 : a.Low->getValue().slt(b.Low->getValue());
2033 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
2035 if (
I->Prob >
W.LastCluster->Prob)
2037 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
2045 BranchProbability DefaultProb =
W.DefaultProb;
2046 BranchProbability UnhandledProbs = DefaultProb;
2047 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
2048 UnhandledProbs +=
I->Prob;
2050 MachineBasicBlock *CurMBB =
W.MBB;
2051 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
2052 bool FallthroughUnreachable =
false;
2053 MachineBasicBlock *Fallthrough;
2054 if (
I ==
W.LastCluster) {
2056 Fallthrough = DefaultMBB;
2061 CurMF->
insert(BBI, Fallthrough);
2063 UnhandledProbs -=
I->Prob;
2067 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2068 DefaultProb, UnhandledProbs,
I, Fallthrough,
2069 FallthroughUnreachable)) {
2077 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2078 UnhandledProbs,
I, Fallthrough,
2079 FallthroughUnreachable)) {
2086 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
2087 FallthroughUnreachable, UnhandledProbs,
2088 CurMBB, MIB, SwitchMBB)) {
2095 CurMBB = Fallthrough;
2101bool IRTranslatorImpl::translateIndirectBr(
const User &U,
2109 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
2110 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
2111 for (
const BasicBlock *Succ :
successors(&BrInst)) {
2115 if (!AddedSuccessors.
insert(Succ).second)
2131bool IRTranslatorImpl::translateLoad(
const User &U,
2134 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
2145 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
2147 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
2153 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
2155 if (AA->pointsToConstantMemory(
2162 if (Regs.
size() == 1) {
2163 auto *MMO = MF->getMachineMemOperand(
2165 MRI->getType(Regs[0]), getMemOpAlign(LI),
2166 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
2172 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
2173 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
2175 for (
unsigned i = 0; i < Regs.
size(); ++i) {
2180 Align BaseAlign = getMemOpAlign(LI);
2182 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
2185 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
2191bool IRTranslatorImpl::translateStore(
const User &U,
2194 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
2200 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
2201 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
2203 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
2204 SI.getPointerOperand());
2211 if (Vals.
size() == 1) {
2212 auto *MMO = MF->getMachineMemOperand(
2213 MachinePointerInfo(
SI.getPointerOperand()), Flags,
2214 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
2215 SI.getSyncScopeID(),
SI.getOrdering());
2220 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
2221 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
2223 for (
unsigned i = 0; i < Vals.
size(); ++i) {
2227 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
2228 Align BaseAlign = getMemOpAlign(SI);
2229 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
2232 SI.getSyncScopeID(),
SI.getOrdering());
2239 const Value *Src = U.getOperand(0);
2245 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
2248 for (
auto Idx : EVI->indices())
2249 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2251 for (
auto Idx : IVI->indices())
2252 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2258 DL.getIndexedOffsetInType(Src->getType(), Indices));
2261bool IRTranslatorImpl::translateExtractValue(
const User &U,
2263 const Value *Src =
U.getOperand(0);
2266 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
2268 auto &DstRegs = allocateVRegs(U);
2270 for (
unsigned i = 0; i < DstRegs.size(); ++i)
2271 DstRegs[i] = SrcRegs[Idx++];
2276bool IRTranslatorImpl::translateInsertValue(
const User &U,
2278 const Value *Src =
U.getOperand(0);
2280 auto &DstRegs = allocateVRegs(U);
2281 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
2284 auto *InsertedIt = InsertedRegs.
begin();
2286 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
2287 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
2288 DstRegs[i] = *InsertedIt++;
2290 DstRegs[i] = SrcRegs[i];
2296bool IRTranslatorImpl::translateSelect(
const User &U,
2298 Register Tst = getOrCreateVReg(*
U.getOperand(0));
2307 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
2308 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
2314bool IRTranslatorImpl::translateCopy(
const User &U,
const Value &V,
2316 return translateCopy(U, getOrCreateVReg(V), MIRBuilder);
2319bool IRTranslatorImpl::translateCopy(
const User &U,
Register Src,
2321 auto &Regs = *VMap.getVRegs(U);
2323 Regs.push_back(Src);
2332bool IRTranslatorImpl::translateBitCast(
const User &U,
2334 Type *SrcTy =
U.getOperand(0)->getType();
2335 Type *DstTy =
U.getType();
2342 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
2344 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
2354 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
2356 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
2358 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
2361bool IRTranslatorImpl::translateCast(
unsigned Opcode,
const User &U,
2363 if (!mayTranslateUserTypes(U))
2376bool IRTranslatorImpl::translateGetElementPtr(
const User &U,
2378 Value &Op0 = *
U.getOperand(0);
2382 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
2385 uint32_t PtrAddFlags = 0;
2391 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
2401 unsigned VectorWidth = 0;
2405 bool WantSplatVector =
false;
2409 WantSplatVector = VectorWidth > 1;
2413 return translateCopy(U, BaseReg, MIRBuilder);
2417 if (WantSplatVector && !PtrTy.
isVector()) {
2424 OffsetIRTy = DL->getIndexType(PtrIRTy);
2431 const Value *Idx = GTI.getOperand();
2432 if (StructType *StTy = GTI.getStructTypeOrNull()) {
2434 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
2437 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
2442 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
2443 Offset += ElementSize * *Val;
2452 PtrAddFlagsWithConst(
Offset))
2457 Register IdxReg = getOrCreateVReg(*Idx);
2458 LLT IdxTy = MRI->getType(IdxReg);
2459 if (IdxTy != OffsetTy) {
2460 if (!IdxTy.
isVector() && WantSplatVector) {
2473 if (ElementSize != 1) {
2484 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
2487 GepOffsetReg = IdxReg;
2491 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
2500 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
2501 PtrAddFlagsWithConst(
Offset));
2505 return translateCopy(U, BaseReg, MIRBuilder);
2508bool IRTranslatorImpl::translateMemFunc(
const CallInst &CI,
2518 unsigned MinPtrSize = UINT_MAX;
2519 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
2520 Register SrcReg = getOrCreateVReg(**AI);
2521 LLT SrcTy = MRI->getType(SrcReg);
2523 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
2531 if (MRI->getType(SizeOpReg) != SizeTy)
2543 ConstantInt *CopySize =
nullptr;
2546 DstAlign = MCI->getDestAlign().valueOrOne();
2547 SrcAlign = MCI->getSourceAlign().valueOrOne();
2550 DstAlign = MMI->getDestAlign().valueOrOne();
2551 SrcAlign = MMI->getSourceAlign().valueOrOne();
2555 DstAlign = MSI->getDestAlign().valueOrOne();
2558 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
2559 Opcode != TargetOpcode::G_MEMSET_INLINE) {
2575 if (AA && CopySize &&
2576 AA->pointsToConstantMemory(MemoryLocation(
2586 ICall.addMemOperand(
2587 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
2588 StoreFlags, 1, DstAlign, AAInfo));
2589 if (Opcode != TargetOpcode::G_MEMSET &&
2590 Opcode != TargetOpcode::G_MEMSET_INLINE)
2591 ICall.addMemOperand(MF->getMachineMemOperand(
2592 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
2597bool IRTranslatorImpl::translateTrap(
const CallInst &CI,
2600 StringRef TrapFuncName =
2601 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
2602 if (TrapFuncName.
empty()) {
2603 if (Opcode == TargetOpcode::G_UBSANTRAP) {
2612 CallLowering::CallLoweringInfo
Info;
2613 if (Opcode == TargetOpcode::G_UBSANTRAP)
2620 return CLI->lowerCall(MIRBuilder, Info);
2623bool IRTranslatorImpl::translateVectorInterleave2Intrinsic(
2626 "This function can only be called on the interleave2 intrinsic!");
2630 Register Res = getOrCreateVReg(CI);
2632 LLT OpTy = MRI->getType(Op0);
2639bool IRTranslatorImpl::translateVectorDeinterleave2Intrinsic(
2642 "This function can only be called on the deinterleave2 intrinsic!");
2649 LLT ResTy = MRI->getType(Res[0]);
2666void IRTranslatorImpl::getStackGuard(
Register DstReg,
2669 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
2672 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
2677 const TargetRegisterInfo *
TRI = MF->getSubtarget().getRegisterInfo();
2678 MRI->setRegClass(DstReg,
TRI->getPointerRegClass());
2680 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
2682 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
2683 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
2685 MachinePointerInfo MPInfo(
Global);
2688 MachineMemOperand *MemRef = MF->getMachineMemOperand(
2689 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
2690 MIB.setMemRefs({MemRef});
2693bool IRTranslatorImpl::translateOverflowIntrinsic(
2697 Op, {ResRegs[0], ResRegs[1]},
2703bool IRTranslatorImpl::translateFixedPointIntrinsic(
2705 Register Dst = getOrCreateVReg(CI);
2709 MIRBuilder.
buildInstr(
Op, {Dst}, { Src0, Src1, Scale });
2713unsigned IRTranslatorImpl::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
2717 case Intrinsic::acos:
2718 return TargetOpcode::G_FACOS;
2719 case Intrinsic::asin:
2720 return TargetOpcode::G_FASIN;
2721 case Intrinsic::atan:
2722 return TargetOpcode::G_FATAN;
2723 case Intrinsic::atan2:
2724 return TargetOpcode::G_FATAN2;
2725 case Intrinsic::bswap:
2726 return TargetOpcode::G_BSWAP;
2727 case Intrinsic::bitreverse:
2728 return TargetOpcode::G_BITREVERSE;
2729 case Intrinsic::clmul:
2730 return TargetOpcode::G_CLMUL;
2731 case Intrinsic::fshl:
2732 return TargetOpcode::G_FSHL;
2733 case Intrinsic::fshr:
2734 return TargetOpcode::G_FSHR;
2735 case Intrinsic::ceil:
2736 return TargetOpcode::G_FCEIL;
2737 case Intrinsic::cos:
2738 return TargetOpcode::G_FCOS;
2739 case Intrinsic::cosh:
2740 return TargetOpcode::G_FCOSH;
2741 case Intrinsic::ctpop:
2742 return TargetOpcode::G_CTPOP;
2743 case Intrinsic::exp:
2744 return TargetOpcode::G_FEXP;
2745 case Intrinsic::exp2:
2746 return TargetOpcode::G_FEXP2;
2747 case Intrinsic::exp10:
2748 return TargetOpcode::G_FEXP10;
2749 case Intrinsic::fabs:
2750 return TargetOpcode::G_FABS;
2751 case Intrinsic::copysign:
2752 return TargetOpcode::G_FCOPYSIGN;
2753 case Intrinsic::minnum:
2754 return TargetOpcode::G_FMINNUM;
2755 case Intrinsic::maxnum:
2756 return TargetOpcode::G_FMAXNUM;
2757 case Intrinsic::minimum:
2758 return TargetOpcode::G_FMINIMUM;
2759 case Intrinsic::maximum:
2760 return TargetOpcode::G_FMAXIMUM;
2761 case Intrinsic::minimumnum:
2762 return TargetOpcode::G_FMINIMUMNUM;
2763 case Intrinsic::maximumnum:
2764 return TargetOpcode::G_FMAXIMUMNUM;
2765 case Intrinsic::canonicalize:
2766 return TargetOpcode::G_FCANONICALIZE;
2767 case Intrinsic::floor:
2768 return TargetOpcode::G_FFLOOR;
2769 case Intrinsic::fma:
2770 return TargetOpcode::G_FMA;
2771 case Intrinsic::log:
2772 return TargetOpcode::G_FLOG;
2773 case Intrinsic::log2:
2774 return TargetOpcode::G_FLOG2;
2775 case Intrinsic::log10:
2776 return TargetOpcode::G_FLOG10;
2777 case Intrinsic::ldexp:
2778 return TargetOpcode::G_FLDEXP;
2779 case Intrinsic::nearbyint:
2780 return TargetOpcode::G_FNEARBYINT;
2781 case Intrinsic::pow:
2782 return TargetOpcode::G_FPOW;
2783 case Intrinsic::powi:
2784 return TargetOpcode::G_FPOWI;
2785 case Intrinsic::rint:
2786 return TargetOpcode::G_FRINT;
2787 case Intrinsic::round:
2788 return TargetOpcode::G_INTRINSIC_ROUND;
2789 case Intrinsic::roundeven:
2790 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2791 case Intrinsic::sin:
2792 return TargetOpcode::G_FSIN;
2793 case Intrinsic::sinh:
2794 return TargetOpcode::G_FSINH;
2795 case Intrinsic::sqrt:
2796 return TargetOpcode::G_FSQRT;
2797 case Intrinsic::tan:
2798 return TargetOpcode::G_FTAN;
2799 case Intrinsic::tanh:
2800 return TargetOpcode::G_FTANH;
2801 case Intrinsic::trunc:
2802 return TargetOpcode::G_INTRINSIC_TRUNC;
2803 case Intrinsic::readcyclecounter:
2804 return TargetOpcode::G_READCYCLECOUNTER;
2805 case Intrinsic::readsteadycounter:
2806 return TargetOpcode::G_READSTEADYCOUNTER;
2807 case Intrinsic::ptrmask:
2808 return TargetOpcode::G_PTRMASK;
2809 case Intrinsic::lrint:
2810 return TargetOpcode::G_INTRINSIC_LRINT;
2811 case Intrinsic::llrint:
2812 return TargetOpcode::G_INTRINSIC_LLRINT;
2814 case Intrinsic::vector_reduce_fmin:
2815 return TargetOpcode::G_VECREDUCE_FMIN;
2816 case Intrinsic::vector_reduce_fmax:
2817 return TargetOpcode::G_VECREDUCE_FMAX;
2818 case Intrinsic::vector_reduce_fminimum:
2819 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2820 case Intrinsic::vector_reduce_fmaximum:
2821 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2822 case Intrinsic::vector_reduce_fminimumnum:
2823 return TargetOpcode::G_VECREDUCE_FMINIMUMNUM;
2824 case Intrinsic::vector_reduce_fmaximumnum:
2825 return TargetOpcode::G_VECREDUCE_FMAXIMUMNUM;
2826 case Intrinsic::vector_reduce_add:
2827 return TargetOpcode::G_VECREDUCE_ADD;
2828 case Intrinsic::vector_reduce_mul:
2829 return TargetOpcode::G_VECREDUCE_MUL;
2830 case Intrinsic::vector_reduce_and:
2831 return TargetOpcode::G_VECREDUCE_AND;
2832 case Intrinsic::vector_reduce_or:
2833 return TargetOpcode::G_VECREDUCE_OR;
2834 case Intrinsic::vector_reduce_xor:
2835 return TargetOpcode::G_VECREDUCE_XOR;
2836 case Intrinsic::vector_reduce_smax:
2837 return TargetOpcode::G_VECREDUCE_SMAX;
2838 case Intrinsic::vector_reduce_smin:
2839 return TargetOpcode::G_VECREDUCE_SMIN;
2840 case Intrinsic::vector_reduce_umax:
2841 return TargetOpcode::G_VECREDUCE_UMAX;
2842 case Intrinsic::vector_reduce_umin:
2843 return TargetOpcode::G_VECREDUCE_UMIN;
2844 case Intrinsic::experimental_vector_compress:
2845 return TargetOpcode::G_VECTOR_COMPRESS;
2846 case Intrinsic::lround:
2847 return TargetOpcode::G_LROUND;
2848 case Intrinsic::llround:
2849 return TargetOpcode::G_LLROUND;
2850 case Intrinsic::get_fpenv:
2851 return TargetOpcode::G_GET_FPENV;
2852 case Intrinsic::get_fpmode:
2853 return TargetOpcode::G_GET_FPMODE;
2858bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2862 unsigned Op = getSimpleIntrinsicOpcode(ID);
2870 for (
const auto &Arg : CI.
args())
2873 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2881 case Intrinsic::experimental_constrained_fadd:
2882 return TargetOpcode::G_STRICT_FADD;
2883 case Intrinsic::experimental_constrained_fsub:
2884 return TargetOpcode::G_STRICT_FSUB;
2885 case Intrinsic::experimental_constrained_fmul:
2886 return TargetOpcode::G_STRICT_FMUL;
2887 case Intrinsic::experimental_constrained_fdiv:
2888 return TargetOpcode::G_STRICT_FDIV;
2889 case Intrinsic::experimental_constrained_frem:
2890 return TargetOpcode::G_STRICT_FREM;
2891 case Intrinsic::experimental_constrained_fma:
2892 return TargetOpcode::G_STRICT_FMA;
2893 case Intrinsic::experimental_constrained_sqrt:
2894 return TargetOpcode::G_STRICT_FSQRT;
2895 case Intrinsic::experimental_constrained_ldexp:
2896 return TargetOpcode::G_STRICT_FLDEXP;
2897 case Intrinsic::experimental_constrained_fcmp:
2898 return TargetOpcode::G_STRICT_FCMP;
2899 case Intrinsic::experimental_constrained_fcmps:
2900 return TargetOpcode::G_STRICT_FCMPS;
2906bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2918 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2919 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2921 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2922 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2925 .addPredicate(FPCmp->getPredicate())
2939std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2940 auto VRegs = getOrCreateVRegs(Arg);
2941 if (VRegs.
size() != 1)
2942 return std::nullopt;
2945 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2946 if (!VRegDef || !VRegDef->isCopy())
2947 return std::nullopt;
2948 return VRegDef->getOperand(1).getReg().asMCReg();
2951bool IRTranslatorImpl::translateIfEntryValueArgument(
2962 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2964 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2965 <<
": expression is entry_value but "
2966 <<
"couldn't find a physical register\n");
2974 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
2986 case Intrinsic::experimental_convergence_anchor:
2987 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
2988 case Intrinsic::experimental_convergence_entry:
2989 return TargetOpcode::CONVERGENCECTRL_ENTRY;
2990 case Intrinsic::experimental_convergence_loop:
2991 return TargetOpcode::CONVERGENCECTRL_LOOP;
2995bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
2998 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3001 if (ID == Intrinsic::experimental_convergence_loop) {
3003 assert(Bundle &&
"Expected a convergence control token.");
3005 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3012bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3016 if (ORE->enabled()) {
3018 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3026 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3032 case Intrinsic::lifetime_start:
3033 case Intrinsic::lifetime_end: {
3036 MF->getFunction().hasOptNone())
3039 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3040 : TargetOpcode::LIFETIME_END;
3049 case Intrinsic::fake_use: {
3051 for (
const auto &Arg : CI.
args())
3053 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3054 MF->setHasFakeUses(
true);
3057 case Intrinsic::dbg_declare: {
3064 case Intrinsic::dbg_label: {
3070 "Expected inlined-at fields to agree");
3075 case Intrinsic::vaend:
3079 case Intrinsic::vastart: {
3081 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3084 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3085 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3087 ListSize, Alignment));
3090 case Intrinsic::dbg_assign:
3097 case Intrinsic::dbg_value: {
3104 case Intrinsic::uadd_with_overflow:
3105 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3106 case Intrinsic::sadd_with_overflow:
3107 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3108 case Intrinsic::usub_with_overflow:
3109 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3110 case Intrinsic::ssub_with_overflow:
3111 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3112 case Intrinsic::umul_with_overflow:
3113 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3114 case Intrinsic::smul_with_overflow:
3115 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3116 case Intrinsic::uadd_sat:
3117 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3118 case Intrinsic::sadd_sat:
3119 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3120 case Intrinsic::usub_sat:
3121 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3122 case Intrinsic::ssub_sat:
3123 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3124 case Intrinsic::ushl_sat:
3125 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3126 case Intrinsic::sshl_sat:
3127 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3128 case Intrinsic::umin:
3129 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3130 case Intrinsic::umax:
3131 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3132 case Intrinsic::smin:
3133 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3134 case Intrinsic::smax:
3135 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3136 case Intrinsic::abs:
3138 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3139 case Intrinsic::smul_fix:
3140 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3141 case Intrinsic::umul_fix:
3142 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3143 case Intrinsic::smul_fix_sat:
3144 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3145 case Intrinsic::umul_fix_sat:
3146 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3147 case Intrinsic::sdiv_fix:
3148 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3149 case Intrinsic::udiv_fix:
3150 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3151 case Intrinsic::sdiv_fix_sat:
3152 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3153 case Intrinsic::udiv_fix_sat:
3154 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3155 case Intrinsic::fmuladd: {
3156 Register Dst = getOrCreateVReg(CI);
3160 if (TLI->isFMAFasterThanFMulAndFAdd(*MF,
3161 TLI->getValueType(*DL, CI.
getType()))) {
3164 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3175 case Intrinsic::frexp: {
3182 case Intrinsic::modf: {
3184 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3189 case Intrinsic::sincos: {
3196 case Intrinsic::fptosi_sat:
3200 case Intrinsic::fptoui_sat:
3204 case Intrinsic::memcpy_inline:
3205 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3206 case Intrinsic::memcpy:
3207 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3208 case Intrinsic::memmove:
3209 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3210 case Intrinsic::memset:
3211 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3212 case Intrinsic::memset_inline:
3213 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3214 case Intrinsic::eh_typeid_for: {
3217 unsigned TypeID = MF->getTypeIDFor(GV);
3221 case Intrinsic::objectsize:
3224 case Intrinsic::is_constant:
3227 case Intrinsic::stackguard:
3228 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3230 case Intrinsic::stackprotector: {
3233 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3234 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3235 getStackGuard(GuardVal, MIRBuilder);
3240 int FI = getOrCreateFrameIndex(*Slot);
3241 MF->getFrameInfo().setStackProtectorIndex(FI);
3244 GuardVal, getOrCreateVReg(*Slot),
3251 case Intrinsic::stacksave: {
3252 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3255 case Intrinsic::stackrestore: {
3256 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3260 case Intrinsic::cttz:
3261 case Intrinsic::ctlz: {
3263 bool isTrailing =
ID == Intrinsic::cttz;
3264 unsigned Opcode = isTrailing ? Cst->
isZero()
3265 ? TargetOpcode::G_CTTZ
3266 : TargetOpcode::G_CTTZ_ZERO_POISON
3267 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3268 : TargetOpcode::G_CTLZ_ZERO_POISON;
3269 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3273 case Intrinsic::invariant_start: {
3277 case Intrinsic::invariant_end:
3279 case Intrinsic::expect:
3280 case Intrinsic::expect_with_probability:
3281 case Intrinsic::annotation:
3282 case Intrinsic::ptr_annotation:
3283 case Intrinsic::launder_invariant_group:
3284 case Intrinsic::strip_invariant_group:
3285 case Intrinsic::threadlocal_address: {
3287 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3291 case Intrinsic::assume:
3292 case Intrinsic::experimental_noalias_scope_decl:
3293 case Intrinsic::var_annotation:
3294 case Intrinsic::sideeffect:
3297 case Intrinsic::read_volatile_register:
3298 case Intrinsic::read_register: {
3301 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3305 case Intrinsic::write_register: {
3307 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3312 case Intrinsic::localescape: {
3313 MachineBasicBlock &EntryMBB = MF->front();
3318 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3325 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3338 case Intrinsic::vector_reduce_fadd:
3339 case Intrinsic::vector_reduce_fmul: {
3342 Register Dst = getOrCreateVReg(CI);
3348 Opc =
ID == Intrinsic::vector_reduce_fadd
3349 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3350 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3351 if (!MRI->getType(VecSrc).isVector())
3352 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3353 : TargetOpcode::G_FMUL;
3361 if (ID == Intrinsic::vector_reduce_fadd) {
3362 Opc = TargetOpcode::G_VECREDUCE_FADD;
3363 ScalarOpc = TargetOpcode::G_FADD;
3365 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3366 ScalarOpc = TargetOpcode::G_FMUL;
3368 LLT DstTy = MRI->getType(Dst);
3371 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3376 case Intrinsic::trap:
3377 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3378 case Intrinsic::debugtrap:
3379 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3380 case Intrinsic::ubsantrap:
3381 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3382 case Intrinsic::allow_runtime_check:
3383 case Intrinsic::allow_ubsan_check:
3384 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3387 case Intrinsic::amdgcn_cs_chain:
3388 case Intrinsic::amdgcn_call_whole_wave:
3389 return translateCallBase(CI, MIRBuilder);
3390 case Intrinsic::fptrunc_round: {
3395 std::optional<RoundingMode> RoundMode =
3400 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3401 {getOrCreateVReg(CI)},
3403 .addImm((
int)*RoundMode);
3407 case Intrinsic::is_fpclass: {
3412 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3413 {getOrCreateVReg(*FpValue)})
3418 case Intrinsic::set_fpenv: {
3423 case Intrinsic::reset_fpenv:
3426 case Intrinsic::set_fpmode: {
3431 case Intrinsic::reset_fpmode:
3434 case Intrinsic::get_rounding:
3437 case Intrinsic::set_rounding:
3440 case Intrinsic::vscale: {
3444 case Intrinsic::scmp:
3445 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3449 case Intrinsic::ucmp:
3450 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3454 case Intrinsic::vector_extract:
3455 return translateExtractVector(CI, MIRBuilder);
3456 case Intrinsic::vector_insert:
3457 return translateInsertVector(CI, MIRBuilder);
3458 case Intrinsic::stepvector: {
3462 case Intrinsic::prefetch: {
3469 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3472 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3478 case Intrinsic::vector_interleave2:
3479 case Intrinsic::vector_deinterleave2: {
3487 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3489 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3492#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3493 case Intrinsic::INTRINSIC:
3494#include "llvm/IR/ConstrainedOps.def"
3497 case Intrinsic::experimental_convergence_anchor:
3498 case Intrinsic::experimental_convergence_entry:
3499 case Intrinsic::experimental_convergence_loop:
3500 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3501 case Intrinsic::reloc_none: {
3504 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3512bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3514 if (!mayTranslateUserTypes(CB))
3517 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3521 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3526 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3529bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3536 for (
const auto &Arg : CB.
args()) {
3538 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3540 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3541 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3542 &CB, &MIRBuilder.
getMBB(), Arg));
3545 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3548 Args.push_back(getOrCreateVRegs(*Arg));
3552 if (ORE->enabled()) {
3554 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3560 std::optional<CallLowering::PtrAuthInfo> PAI;
3565 const Value *
Key = Bundle->Inputs[0];
3572 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3573 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3575 Register DiscReg = getOrCreateVReg(*Discriminator);
3583 const auto &Token = *Bundle->Inputs[0].get();
3584 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3590 bool Success = CLI->lowerCall(
3591 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3596 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3597 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3604bool IRTranslatorImpl::translateCall(
const User &U,
3606 if (!mayTranslateUserTypes(U))
3614 if (
F && (
F->hasDLLImportStorageClass() ||
3615 (MF->getTarget().getTargetTriple().isOSWindows() &&
3616 F->hasExternalWeakLinkage())))
3628 return translateInlineAsm(CI, MIRBuilder);
3632 if (translateCallBase(CI, MIRBuilder)) {
3641 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3642 const Function &Fn = MF->getFunction();
3644 DiagnosticInfoUnsupportedTargetIntrinsic(Fn, ID, CI.
getDebugLoc()));
3647 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3651 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3653 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3657bool IRTranslatorImpl::translateIntrinsic(
3660 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3662 F.getContext().diagnose(
3663 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3668 ResultRegs = getOrCreateVRegs(CB);
3672 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3683 assert(CI->getBitWidth() <= 64 &&
3684 "large intrinsic immediates not handled");
3685 MIB.
addImm(CI->getSExtValue());
3690 auto *MD = MDVal->getMetadata();
3694 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3701 if (VRegs.
size() > 1)
3708 for (
const auto &Info : TgtMemIntrinsicInfos) {
3711 LLT MemTy =
Info.memVT.isSimple()
3713 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3717 MachinePointerInfo MPI;
3719 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3720 }
else if (
Info.fallbackAddressSpace) {
3721 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3730 auto *Token = Bundle->Inputs[0].get();
3731 Register TokenReg = getOrCreateVReg(*Token);
3742bool IRTranslatorImpl::findUnwindDestinations(
3763 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3769 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3770 UnwindDests.back().first->setIsEHScopeEntry();
3771 UnwindDests.back().first->setIsEHFuncletEntry();
3776 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3777 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3779 if (IsMSVCCXX || IsCoreCLR)
3780 UnwindDests.back().first->setIsEHFuncletEntry();
3782 UnwindDests.back().first->setIsEHScopeEntry();
3784 NewEHPadBB = CatchSwitch->getUnwindDest();
3789 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3790 if (BPI && NewEHPadBB)
3792 EHPadBB = NewEHPadBB;
3797bool IRTranslatorImpl::translateInvoke(
const User &U,
3800 MCContext &
Context = MF->getContext();
3805 const Function *Fn =
I.getCalledFunction();
3812 if (
I.hasDeoptState())
3826 (MF->getTarget().getTargetTriple().isOSWindows() &&
3830 bool LowerInlineAsm =
I.isInlineAsm();
3831 bool NeedEHLabel =
true;
3837 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3838 BeginSymbol =
Context.createTempSymbol();
3842 if (LowerInlineAsm) {
3843 if (!translateInlineAsm(
I, MIRBuilder))
3845 }
else if (!translateCallBase(
I, MIRBuilder))
3850 EndSymbol =
Context.createTempSymbol();
3855 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3856 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3857 BranchProbability EHPadBBProb =
3861 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3864 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3865 &ReturnMBB = getMBB(*ReturnBB);
3867 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3868 for (
auto &UnwindDest : UnwindDests) {
3869 UnwindDest.first->setIsEHPad();
3870 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3875 assert(BeginSymbol &&
"Expected a begin symbol!");
3876 assert(EndSymbol &&
"Expected an end symbol!");
3877 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3880 MIRBuilder.
buildBr(ReturnMBB);
3886bool IRTranslatorImpl::translateCallBr(
const User &U,
3888 if (!mayTranslateUserTypes(U))
3892 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3895 if (
I.isInlineAsm()) {
3901 if (!translateIntrinsic(
I, IID, MIRBuilder))
3905 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3906 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3915 for (BasicBlock *Dest :
I.getIndirectDests()) {
3916 MachineBasicBlock &
Target = getMBB(*Dest);
3917 Target.setIsInlineAsmBrIndirectTarget();
3918 Target.setLabelMustBeEmitted();
3920 if (Dests.
insert(Dest).second)
3932bool IRTranslatorImpl::translateLandingPad(
const User &U,
3936 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3942 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3943 if (TLI->getExceptionPointerRegister(
3944 TLI->getTargetMachine().getExceptionModel(), PersonalityFn) == 0 &&
3945 TLI->getExceptionSelectorRegister(
3946 TLI->getTargetMachine().getExceptionModel(), PersonalityFn) == 0)
3958 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3963 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3964 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3965 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
3974 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
3977 Register ExceptionReg = TLI->getExceptionPointerRegister(
3978 TLI->getTargetMachine().getExceptionModel(), PersonalityFn);
3984 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
3986 Register SelectorReg = TLI->getExceptionSelectorRegister(
3987 TLI->getTargetMachine().getExceptionModel(), PersonalityFn);
3992 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
3993 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
3994 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
3999bool IRTranslatorImpl::translateAlloca(
const User &U,
4007 Register Res = getOrCreateVReg(AI);
4008 int FI = getOrCreateFrameIndex(AI);
4014 if (MF->getTarget().getTargetTriple().isOSWindows())
4019 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4021 if (MRI->getType(NumElts) !=
IntPtrTy) {
4033 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4038 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4040 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4045 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4054 if (Alignment <= StackAlign)
4058 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4059 assert(MF->getFrameInfo().hasVarSizedObjects());
4063bool IRTranslatorImpl::translateVAArg(
const User &U,
4069 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4070 {getOrCreateVReg(*
U.getOperand(0)),
4071 DL->getABITypeAlign(
U.getType()).value()});
4075bool IRTranslatorImpl::translateUnreachable(
const User &U,
4078 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4079 MF->getTarget().Options.NoTrapAfterNoreturn))
4086bool IRTranslatorImpl::translateInsertElement(
const User &U,
4091 FVT && FVT->getNumElements() == 1)
4092 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4095 Register Val = getOrCreateVReg(*
U.getOperand(0));
4096 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4097 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4100 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4101 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4102 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4103 Idx = getOrCreateVReg(*NewIdxCI);
4107 Idx = getOrCreateVReg(*
U.getOperand(2));
4108 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4109 const LLT VecIdxTy =
4110 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4117bool IRTranslatorImpl::translateInsertVector(
const User &U,
4120 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4121 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4124 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4129 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4134 ResultType && ResultType->getNumElements() == 1) {
4136 InputType && InputType->getNumElements() == 1) {
4140 return translateCopy(U, Vec, MIRBuilder);
4146 Register Idx = getOrCreateVReg(*CI);
4154 Register Idx = getOrCreateVReg(*CI);
4155 auto ScaledIndex = MIRBuilder.
buildMul(
4156 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4166bool IRTranslatorImpl::translateExtractElement(
const User &U,
4170 if (
const FixedVectorType *FVT =
4172 if (FVT->getNumElements() == 1)
4173 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4176 Register Val = getOrCreateVReg(*
U.getOperand(0));
4177 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4182 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4183 Idx = getOrCreateVReg(*NewIdxCI);
4187 Idx = getOrCreateVReg(*
U.getOperand(1));
4188 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4189 const LLT VecIdxTy =
4197bool IRTranslatorImpl::translateExtractVector(
const User &U,
4200 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4202 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4207 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4212 ResultType && ResultType->getNumElements() == 1) {
4214 InputType && InputType->getNumElements() == 1) {
4217 return translateCopy(U, Vec, MIRBuilder);
4223 Register Idx = getOrCreateVReg(*CI);
4231 Register Idx = getOrCreateVReg(*CI);
4232 auto ScaledIndex = MIRBuilder.
buildMul(
4233 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4243bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4249 if (
U.getOperand(0)->getType()->isScalableTy()) {
4250 Register Val = getOrCreateVReg(*
U.getOperand(0));
4252 MRI->getType(Val).getElementType(), Val, 0);
4259 Mask = SVI->getShuffleMask();
4270 unsigned M =
Mask[0];
4272 if (M == 0 || M == 1)
4273 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4279 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4280 }
else if (M < SrcElts * 2) {
4282 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4294 for (
int M : Mask) {
4296 if (M == 0 || M == 1) {
4297 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4299 if (!
Undef.isValid()) {
4300 Undef = MRI->createGenericVirtualRegister(SrcTy);
4310 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4312 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4313 {getOrCreateVReg(*
U.getOperand(0)),
4314 getOrCreateVReg(*
U.getOperand(1))})
4315 .addShuffleMask(MaskAlloc);
4319bool IRTranslatorImpl::translatePHI(
const User &U,
4323 SmallVector<MachineInstr *, 4> Insts;
4324 for (
auto Reg : getOrCreateVRegs(PI)) {
4325 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4329 PendingPHIs.emplace_back(&PI, std::move(Insts));
4333bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4337 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4339 auto Res = getOrCreateVRegs(
I);
4342 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4343 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4344 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4347 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4348 *MF->getMachineMemOperand(
4349 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4350 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4351 I.getSuccessOrdering(),
I.getFailureOrdering()));
4355bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4357 if (!mayTranslateUserTypes(U))
4361 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4364 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4365 Register Val = getOrCreateVReg(*
I.getValOperand());
4367 unsigned Opcode = 0;
4368 switch (
I.getOperation()) {
4372 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4375 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4378 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4381 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4384 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4387 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4390 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4393 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4396 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4399 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4402 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4405 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4408 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4411 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4414 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4417 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4420 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4423 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4426 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4429 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4432 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4435 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4438 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4443 Opcode, Res, Addr, Val,
4444 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4445 Flags, MRI->getType(Val), getMemOpAlign(
I),
4446 I.getAAMetadata(),
I.getSyncScopeID(),
4451bool IRTranslatorImpl::translateFence(
const User &U,
4455 Fence.getSyncScopeID());
4459bool IRTranslatorImpl::translateFreeze(
const User &U,
4465 "Freeze with different source and destination type?");
4467 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4474void IRTranslatorImpl::finishPendingPhis() {
4477 GISelObserverWrapper WrapperObserver(&
Verifier);
4478 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4480 for (
auto &Phi : PendingPHIs) {
4481 const PHINode *PI =
Phi.first;
4485 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4491 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4495 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4499 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4500 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4509void IRTranslatorImpl::translateDbgValueRecord(
Value *V,
bool HasArgList,
4515 "Expected inlined-at fields to agree");
4519 if (!V || HasArgList) {
4537 auto *ExprDerefRemoved =
4543 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
4555void IRTranslatorImpl::translateDbgDeclareRecord(
4560 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4565 "Expected inlined-at fields to agree");
4570 MF->setVariableDbgInfo(Variable, Expression,
4571 getOrCreateFrameIndex(*AI), DL);
4575 if (translateIfEntryValueArgument(
true,
Address, Variable,
4587void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4592 assert(DLR->getLabel() &&
"Missing label");
4593 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4595 "Expected inlined-at fields to agree");
4604 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
4607 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
4612bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4614 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4615 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4617 if (TLI->fallBackToDAGISel(Inst))
4621#define HANDLE_INST(NUM, OPCODE, CLASS) \
4622 case Instruction::OPCODE: \
4623 return translate##OPCODE(Inst, *CurBuilder.get());
4624#include "llvm/IR/Instruction.def"
4633 if (
auto CurrInstDL = CurBuilder->getDL())
4634 EntryBuilder->setDebugLoc(
DebugLoc());
4640 EntryBuilder->buildConstant(
Reg, *CI);
4644 EntryBuilder->buildConstant(
Reg, CB->getValue());
4648 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4649 EntryBuilder->buildFConstant(
Reg, *CF);
4651 EntryBuilder->buildUndef(
Reg);
4653 EntryBuilder->buildConstant(
Reg, 0);
4655 EntryBuilder->buildGlobalValue(
Reg, GV);
4657 Register Addr = getOrCreateVReg(*CPA->getPointer());
4658 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4659 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4661 Constant &Elt = *CAZ->getElementValue(0u);
4663 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4667 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4669 return translateCopy(
C, Elt, *EntryBuilder);
4671 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4674 if (CV->getNumElements() == 1)
4675 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4677 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4678 Constant &Elt = *CV->getElementAsConstant(i);
4679 Ops.push_back(getOrCreateVReg(Elt));
4681 EntryBuilder->buildBuildVector(
Reg,
Ops);
4683 switch(
CE->getOpcode()) {
4684#define HANDLE_INST(NUM, OPCODE, CLASS) \
4685 case Instruction::OPCODE: \
4686 return translate##OPCODE(*CE, *EntryBuilder.get());
4687#include "llvm/IR/Instruction.def"
4692 if (CV->getNumOperands() == 1)
4693 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4695 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4696 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4698 EntryBuilder->buildBuildVector(
Reg,
Ops);
4700 EntryBuilder->buildBlockAddress(
Reg, BA);
4707bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4708 const TargetMachine &TM = TLI->getTargetMachine();
4717 (!
U.getType()->getScalarType()->isBFloatTy() &&
4719 return V->getType()->getScalarType()->isBFloatTy();
4723bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4725 for (
auto &BTB : SL->BitTestCases) {
4728 emitBitTestHeader(BTB, BTB.Parent);
4730 BranchProbability UnhandledProb = BTB.Prob;
4731 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4732 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4734 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4743 MachineBasicBlock *NextMBB;
4744 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4747 NextMBB = BTB.Cases[
j + 1].TargetBB;
4748 }
else if (j + 1 == ej) {
4750 NextMBB = BTB.Default;
4753 NextMBB = BTB.Cases[
j + 1].ThisBB;
4756 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4758 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4762 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4763 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4766 BTB.Cases.pop_back();
4772 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4773 BTB.Default->getBasicBlock()};
4774 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4775 if (!BTB.ContiguousRange) {
4776 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4779 SL->BitTestCases.clear();
4781 for (
auto &JTCase : SL->JTCases) {
4783 if (!JTCase.first.Emitted)
4784 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4786 emitJumpTable(JTCase.second, JTCase.second.MBB);
4788 SL->JTCases.clear();
4790 for (
auto &SwCase : SL->SwitchCases)
4791 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4792 SL->SwitchCases.clear();
4795 if (SPInfo->shouldEmitSDCheck(BB)) {
4796 bool FunctionBasedInstrumentation =
4797 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4798 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4801 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4804 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4805 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4806 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4815 ParentMBB, *MF->getSubtarget().getInstrInfo());
4818 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4822 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4826 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4827 if (FailureMBB->
empty()) {
4828 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4833 SPDescriptor.resetPerBBState();
4840 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4844 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
4850 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
4857 ->buildLoad(PtrMemTy, StackSlotPtr,
4863 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
4875 FunctionType *FnTy = GuardCheckFn->getFunctionType();
4876 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
4877 ISD::ArgFlagsTy
Flags;
4878 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
4880 CallLowering::ArgInfo GuardArgInfo(
4881 {GuardVal, FnTy->getParamType(0), {
Flags}});
4883 CallLowering::CallLoweringInfo
Info;
4884 Info.OrigArgs.push_back(GuardArgInfo);
4885 Info.CallConv = GuardCheckFn->getCallingConv();
4888 if (!CLI->lowerCall(MIRBuilder, Info)) {
4889 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
4899 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
4900 getStackGuard(Guard, *CurBuilder);
4903 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
4904 Register GuardPtr = getOrCreateVReg(*IRGuard);
4907 ->buildLoad(PtrMemTy, GuardPtr,
4926 const RTLIB::LibcallImpl LibcallImpl =
4927 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
4928 if (LibcallImpl == RTLIB::Unsupported)
4931 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
4933 CallLowering::CallLoweringInfo
Info;
4934 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
4936 StringRef LibcallName =
4941 if (!CLI->lowerCall(*CurBuilder, Info)) {
4942 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
4947 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
4949 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
4954void IRTranslatorImpl::finalizeFunction() {
4957 PendingPHIs.clear();
4959 FrameIndices.clear();
4960 MachinePreds.clear();
4964 EntryBuilder.reset();
4967 SPDescriptor.resetPerFunctionState();
4980 return CI && CI->isMustTailCall();
4992 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
4993 CLI = MF->getSubtarget().getCallLowering();
4994 SPInfo = StackProtectorInfo;
4996 if (CLI->fallBackToDAGISel(*MF)) {
4998 F.getSubprogram(), &
F.getEntryBlock());
4999 R <<
"unable to lower function: "
5000 <<
ore::NV(
"Prototype",
F.getFunctionType());
5017 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5018 CSEInfo = GetCSEInfo();
5019 EntryBuilder->setCSEInfo(CSEInfo);
5020 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5021 CurBuilder->setCSEInfo(CSEInfo);
5023 EntryBuilder = std::make_unique<MachineIRBuilder>();
5024 CurBuilder = std::make_unique<MachineIRBuilder>();
5027 CurBuilder->setMF(*MF);
5028 EntryBuilder->setMF(*MF);
5029 MRI = &MF->getRegInfo();
5030 DL = &
F.getDataLayout();
5035 AA = GetAAResults();
5036 FuncInfo.BPI = GetBPI();
5040 FuncInfo.BPI =
nullptr;
5043 LibInfo = LibraryInfo;
5044 Libcalls = LibcallInfo;
5046 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5048 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5049 SL->init(*TLI, TM, *DL);
5051 assert(PendingPHIs.empty() &&
"stale PHIs");
5055 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5058 F.getSubprogram(), &
F.getEntryBlock());
5059 R <<
"unable to translate in big endian mode";
5070 EntryBuilder->setMBB(*EntryBB);
5072 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5073 SwiftError.setFunction(CurMF);
5074 SwiftError.createEntriesInEntryBlock(DbgLoc);
5076 bool IsVarArg =
F.isVarArg();
5077 bool HasMustTailInVarArgFn =
false;
5080 unsigned NumValues =
F.arg_size();
5083 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5085 NumValues += BB.
size();
5088 MBB = MF->CreateMachineBasicBlock(&BB);
5096 if (!BA->hasZeroLiveUses())
5100 if (!HasMustTailInVarArgFn)
5104 VMap.reserveVRegs(NumValues);
5105 MRI->reserveVirtRegs(NumValues);
5107 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5110 EntryBB->addSuccessor(&getMBB(
F.front()));
5115 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5120 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5121 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5122 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5126 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5128 F.getSubprogram(), &
F.getEntryBlock());
5129 R <<
"unable to lower arguments: "
5130 <<
ore::NV(
"Prototype",
F.getFunctionType());
5137 if (EnableCSE && CSEInfo)
5142 DILocationVerifier Verifier;
5150 CurBuilder->setMBB(
MBB);
5151 HasTailCall =
false;
5161 Verifier.setCurrentInst(&Inst);
5165 translateDbgInfo(Inst, *CurBuilder);
5167 if (translate(Inst))
5172 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5174 if (ORE->allowExtraAnalysis(
"gisel-irtranslator")) {
5175 std::string InstStrStorage;
5179 R <<
": '" << InstStrStorage <<
"'";
5186 if (!finalizeBasicBlock(*BB,
MBB)) {
5188 BB->getTerminator()->getDebugLoc(), BB);
5189 R <<
"unable to translate basic block";
5199 finishPendingPhis();
5201 SwiftError.propagateVRegs();
5206 assert(EntryBB->succ_size() == 1 &&
5207 "Custom BB used for lowering should have only one successor");
5211 "LLVM-IR entry block has a predecessor!?");
5214 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5223 EntryBB->removeSuccessor(&NewEntryBB);
5224 MF->remove(EntryBB);
5225 MF->deleteMachineBasicBlock(EntryBB);
5227 assert(&MF->front() == &NewEntryBB &&
5228 "New entry wasn't next in the list of basic block!");
5231 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5241 return Impl->runOnMachineFunction(
5260 *
F.getParent(), Subtarget),
5284 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5285 Impl->runOnMachineFunction(
5287 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 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 cl::opt< bool > EnableCSEInIRTranslator("enable-cse-in-irtranslator", cl::desc("Should enable CSE in irtranslator"), cl::Optional, cl::init(false))
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...
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.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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.
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 InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
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.
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.
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
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this label.
A parsed version of the target data layout string in and methods for querying it.
Value * getAddress() const
DILabel * getLabel() const
DebugLoc getDebugLoc() const
Value * getValue(unsigned OpIdx=0) const
DILocalVariable * getVariable() const
DIExpression * getExpression() const
LLVM_ABI Value * getVariableLocationOp(unsigned OpIdx) const
DIExpression * getExpression() const
DILocalVariable * getVariable() const
bool isDbgDeclare() const
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).
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
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
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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.
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
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 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.
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 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.
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.
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.
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.
Register getReg(unsigned Idx) const
Get the register for the operand index.
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 & 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.
@ 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,...
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.
bool isByteTy() const
True if this is an instance of ByteType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isAggregateType() const
Return true if the type is an aggregate type.
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 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.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
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.
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.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
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.