70#include "llvm/IR/IntrinsicsAMDGPU.h"
100#define DEBUG_TYPE "ir-translator"
106 cl::desc(
"Should enable CSE in ir-translator"),
118 class ValueToVRegInfo {
120 ValueToVRegInfo() =
default;
125 using const_vreg_iterator =
127 using const_offset_iterator =
130 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
132 VRegListT *getVRegs(
const Value &V) {
133 auto [It, Inserted] = ValToVRegs.try_emplace(&V);
139 It->second =
new (VRegAlloc.Allocate()) VRegListT();
143 OffsetListT *getOffsets(
const Value &V) {
144 assert(V.getType()->isAggregateType() &&
145 "Offsets are for aggregate values");
146 auto [It, Inserted] = TypeToOffsets.try_emplace(V.getType());
150 It->second =
new (OffsetAlloc.Allocate()) OffsetListT();
154 const_vreg_iterator findVRegs(
const Value &V)
const {
155 return ValToVRegs.find(&V);
158 bool contains(
const Value &V)
const {
return ValToVRegs.contains(&V); }
160 void reserveVRegs(
unsigned NumValues) { ValToVRegs.reserve(NumValues); }
164 TypeToOffsets.clear();
165 VRegAlloc.DestroyAll();
166 OffsetAlloc.DestroyAll();
181 ValueToVRegInfo VMap;
188 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
243 void translateDbgValueRecord(
Value *V,
bool HasArgList,
252 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
259 bool translateCopy(
const User &U,
const Value &V,
284 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
286 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
291 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
293 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
315 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
321 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
336 bool translateIntrinsic(
348 bool findUnwindDestinations(
361 bool translateCast(
unsigned Opcode,
const User &U,
372 return translateCompare(U, MIRBuilder);
377 return translateCompare(U, MIRBuilder);
382 void finishPendingPhis();
386 bool translateUnaryOp(
unsigned Opcode,
const User &U,
391 bool translateBinaryOp(
unsigned Opcode,
const User &U,
397 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
442 bool lowerJumpTableWorkItem(
451 bool FallthroughUnreachable,
457 bool lowerBitTestWorkItem(
463 bool FallthroughUnreachable);
494 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
497 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
500 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
503 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
506 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
509 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
513 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
516 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
519 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
522 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
525 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
528 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
532 return translatePtrToInt(U, MIRBuilder);
535 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
538 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
541 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
544 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
547 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
550 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
553 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
558 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
562 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
566 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
569 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
572 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
576 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
579 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
582 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
585 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
588 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
624 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
639 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
650 std::unique_ptr<MachineIRBuilder> CurBuilder;
655 std::unique_ptr<MachineIRBuilder> EntryBuilder;
668 std::unique_ptr<OptimizationRemarkEmitter> ORE;
679 bool EnableOpts =
false;
683 bool HasTailCall =
false;
687 bool mayTranslateUserTypes(
const User &U)
const;
694 assert(irt &&
"irt is null!");
697 void addSuccessorWithProb(
700 IRT->addSuccessorWithProb(Src, Dst, Prob);
703 ~GISelSwitchLowering()
override =
default;
709 std::unique_ptr<GISelSwitchLowering> SL;
715 void finalizeFunction();
753 auto Regs = getOrCreateVRegs(Val);
756 assert(Regs.size() == 1 &&
757 "attempt to get single VReg for aggregate or void");
761 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
763 auto &Regs = *VMap.getVRegs(Token);
765 assert(Regs.size() == 1 &&
766 "Expected a single register for convergence tokens.");
770 auto Reg = MRI->createGenericVirtualRegister(
LLT::token());
777 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
781 int getOrCreateFrameIndex(
const AllocaInst &AI);
804 auto RemappedEdge = MachinePreds.find(Edge);
805 if (RemappedEdge != MachinePreds.end())
806 return RemappedEdge->second;
815 void addSuccessorWithProb(
821 : OptLevel(OptLevel) {}
851 "IRTranslator LLVM IR -> MI",
false,
false)
863 MF.getProperties().setFailedISel();
864 bool IsGlobalISelAbortEnabled =
869 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
870 R << (
" (in function: " + MF.getName() +
")").str();
872 if (IsGlobalISelAbortEnabled)
892 DILocationVerifier() =
default;
893 ~DILocationVerifier()
override =
default;
895 const Instruction *getCurrentInst()
const {
return CurrInst; }
896 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
898 void erasingInstr(MachineInstr &
MI)
override {}
899 void changingInstr(MachineInstr &
MI)
override {}
900 void changedInstr(MachineInstr &
MI)
override {}
902 void createdInstr(MachineInstr &
MI)
override {
903 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
908 <<
" was copied to " <<
MI);
914 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
915 (
MI.isDebugInstr())) &&
916 "Line info was not transferred to all instructions");
939IRTranslatorImpl::ValueToVRegInfo::VRegListT &
940IRTranslatorImpl::allocateVRegs(
const Value &Val) {
941 auto VRegsIt = VMap.findVRegs(Val);
942 if (VRegsIt != VMap.vregs_end())
943 return *VRegsIt->second;
944 auto *Regs = VMap.getVRegs(Val);
950 auto *Offsets = VMap.getOffsets(Val);
953 Offsets->empty() ? Offsets :
nullptr);
954 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
960 auto VRegsIt = VMap.findVRegs(Val);
961 if (VRegsIt != VMap.vregs_end())
962 return *VRegsIt->second;
965 return *VMap.getVRegs(Val);
968 auto *VRegs = VMap.getVRegs(Val);
972 "Don't know how to create an empty vreg");
977 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
981 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"GISelFailure",
982 MF->getFunction().getSubprogram(),
983 &MF->getFunction().getEntryBlock());
984 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
992 auto *
Offsets = VMap.getOffsets(Val);
994 Offsets->empty() ? Offsets :
nullptr);
997 for (
auto Ty : SplitTys)
998 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
1005 while (
auto Elt =
C.getAggregateElement(Idx++)) {
1006 auto EltRegs = getOrCreateVRegs(*Elt);
1013int IRTranslatorImpl::getOrCreateFrameIndex(
const AllocaInst &AI) {
1014 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
1016 return MapEntry->second;
1022 Size = std::max<uint64_t>(
Size, 1u);
1024 int &FI = MapEntry->second;
1025 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
1032 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
1033 MF->getFrameInfo().setStackID(FI, StackID);
1041 return SI->getAlign();
1043 return LI->getAlign();
1049 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"", &
I);
1050 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
1056 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
1057 assert(
MBB &&
"BasicBlock was not encountered before");
1061void IRTranslatorImpl::addMachineCFGPred(CFGEdge
Edge,
1063 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
1064 MachinePreds[
Edge].push_back(NewPred);
1067bool IRTranslatorImpl::translateBinaryOp(
unsigned Opcode,
const User &U,
1069 if (!mayTranslateUserTypes(U))
1076 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1077 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1089bool IRTranslatorImpl::translateUnaryOp(
unsigned Opcode,
const User &U,
1091 if (!mayTranslateUserTypes(U))
1094 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1105bool IRTranslatorImpl::translateFNeg(
const User &U,
1107 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
1110bool IRTranslatorImpl::translateCompare(
const User &U,
1112 if (!mayTranslateUserTypes(U))
1116 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1117 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1122 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1, Flags);
1130 MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1, Flags);
1135bool IRTranslatorImpl::translateRet(
const User &U,
1139 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
1144 VRegs = getOrCreateVRegs(*Ret);
1147 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
1148 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
1149 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
1155 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
1158void IRTranslatorImpl::emitBranchForMergedCondition(
1167 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
1170 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
1173 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
1174 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
1175 CurBuilder->getDebugLoc(), TProb, FProb);
1176 SL->SwitchCases.push_back(CB);
1182 SwitchCG::CaseBlock CB(
1184 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
1185 SL->SwitchCases.push_back(CB);
1190 return I->getParent() == BB;
1194void IRTranslatorImpl::findMergedConditions(
1199 using namespace PatternMatch;
1200 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
1201 "Expected Opc to be AND/OR");
1207 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
1213 const Value *BOpOp0, *BOpOp1;
1227 if (BOpc == Instruction::And)
1228 BOpc = Instruction::Or;
1229 else if (BOpc == Instruction::Or)
1230 BOpc = Instruction::And;
1236 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
1240 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
1247 MachineBasicBlock *TmpBB =
1251 if (
Opc == Instruction::Or) {
1272 auto NewTrueProb = TProb / 2;
1273 auto NewFalseProb = TProb / 2 + FProb;
1275 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1276 NewFalseProb, InvertCond);
1282 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1283 Probs[1], InvertCond);
1285 assert(
Opc == Instruction::And &&
"Unknown merge op!");
1305 auto NewTrueProb = TProb + FProb / 2;
1306 auto NewFalseProb = FProb / 2;
1308 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1309 NewFalseProb, InvertCond);
1315 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1316 Probs[1], InvertCond);
1320bool IRTranslatorImpl::shouldEmitAsBranches(
1321 const std::vector<SwitchCG::CaseBlock> &Cases) {
1323 if (Cases.size() != 2)
1328 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
1329 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
1330 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
1331 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
1337 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
1338 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
1342 Cases[0].TrueBB == Cases[1].ThisBB)
1345 Cases[0].FalseBB == Cases[1].ThisBB)
1352bool IRTranslatorImpl::translateUncondBr(
const User &U,
1355 auto &CurMBB = MIRBuilder.
getMBB();
1360 MIRBuilder.
buildBr(*Succ0MBB);
1363 for (
const BasicBlock *Succ :
successors(&BrInst))
1368bool IRTranslatorImpl::translateCondBr(
const User &U,
1371 auto &CurMBB = MIRBuilder.
getMBB();
1377 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
1396 using namespace PatternMatch;
1398 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
1399 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
1402 const Value *BOp0, *BOp1;
1404 Opcode = Instruction::And;
1406 Opcode = Instruction::Or;
1410 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
1411 getEdgeProbability(&CurMBB, Succ0MBB),
1412 getEdgeProbability(&CurMBB, Succ1MBB),
1414 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
1417 if (shouldEmitAsBranches(SL->SwitchCases)) {
1419 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
1420 SL->SwitchCases.erase(SL->SwitchCases.begin());
1426 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
1427 MF->erase(SL->SwitchCases[
I].ThisBB);
1429 SL->SwitchCases.clear();
1436 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
1437 CurBuilder->getDebugLoc());
1441 emitSwitchCase(CB, &CurMBB, *CurBuilder);
1448 if (!FuncInfo.BPI) {
1449 Src->addSuccessorWithoutProb(Dst);
1453 Prob = getEdgeProbability(Src, Dst);
1454 Src->addSuccessor(Dst, Prob);
1460 const BasicBlock *SrcBB = Src->getBasicBlock();
1461 const BasicBlock *DstBB = Dst->getBasicBlock();
1462 if (!FuncInfo.BPI) {
1465 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
1466 return BranchProbability(1, SuccSize);
1468 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
1472 using namespace SwitchCG;
1475 BranchProbabilityInfo *BPI = FuncInfo.BPI;
1477 Clusters.reserve(
SI.getNumCases());
1478 for (
const auto &
I :
SI.cases()) {
1479 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
1480 assert(Succ &&
"Could not find successor mbb in mapping");
1481 const ConstantInt *CaseVal =
I.getCaseValue();
1482 BranchProbability Prob =
1484 : BranchProbability(1,
SI.getNumCases() + 1);
1485 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
1488 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
1495 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
1498 if (Clusters.empty()) {
1505 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
1506 SL->findBitTestClusters(Clusters, &SI);
1509 dbgs() <<
"Case clusters: ";
1510 for (
const CaseCluster &
C : Clusters) {
1511 if (
C.Kind == CC_JumpTable)
1513 if (
C.Kind == CC_BitTests)
1516 C.Low->getValue().print(
dbgs(),
true);
1517 if (
C.Low !=
C.High) {
1519 C.High->getValue().print(
dbgs(),
true);
1526 assert(!Clusters.empty());
1530 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
1531 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
1533 while (!WorkList.empty()) {
1534 SwitchWorkListItem
W = WorkList.pop_back_val();
1536 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
1538 if (NumClusters > 3 &&
1541 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
1545 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
1555 using namespace SwitchCG;
1556 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
1557 "Clusters not sorted?");
1558 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
1560 auto [LastLeft, FirstRight, LeftProb, RightProb] =
1561 SL->computeSplitWorkItemInfo(W);
1566 assert(PivotCluster >
W.FirstCluster);
1567 assert(PivotCluster <=
W.LastCluster);
1572 const ConstantInt *Pivot = PivotCluster->Low;
1581 MachineBasicBlock *LeftMBB;
1582 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
1583 FirstLeft->Low ==
W.GE &&
1584 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
1585 LeftMBB = FirstLeft->MBB;
1587 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1588 FuncInfo.MF->
insert(BBI, LeftMBB);
1590 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
1596 MachineBasicBlock *RightMBB;
1597 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
1598 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
1599 RightMBB = FirstRight->MBB;
1601 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1602 FuncInfo.MF->
insert(BBI, RightMBB);
1604 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
1612 if (
W.MBB == SwitchMBB)
1613 emitSwitchCase(CB, SwitchMBB, MIB);
1615 SL->SwitchCases.push_back(CB);
1621 assert(JT.
Reg &&
"Should lower JT Header first!");
1636 MachineIRBuilder MIB(*HeaderBB->
getParent());
1643 Register SwitchOpReg = getOrCreateVReg(SValue);
1645 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
1650 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
1664 auto Cst = getOrCreateVReg(
1704 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
1718 "Can only handle SLE ranges");
1729 const LLT CmpTy = MRI->getType(CmpOpReg);
1730 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1756bool IRTranslatorImpl::lowerJumpTableWorkItem(
1762 using namespace SwitchCG;
1765 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1766 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1767 BranchProbability DefaultProb =
W.DefaultProb;
1770 MachineBasicBlock *JumpMBB = JT->
MBB;
1771 CurMF->
insert(BBI, JumpMBB);
1781 auto JumpProb =
I->Prob;
1782 auto FallthroughProb = UnhandledProbs;
1790 if (*SI == DefaultMBB) {
1791 JumpProb += DefaultProb / 2;
1792 FallthroughProb -= DefaultProb / 2;
1797 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1802 if (FallthroughUnreachable)
1803 JTH->FallthroughUnreachable =
true;
1805 if (!JTH->FallthroughUnreachable)
1806 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1807 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1812 JTH->HeaderBB = CurMBB;
1816 if (CurMBB == SwitchMBB) {
1817 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1819 JTH->Emitted =
true;
1823bool IRTranslatorImpl::lowerSwitchRangeWorkItem(
1828 using namespace SwitchCG;
1831 if (
I->Low ==
I->High) {
1847 CaseBlock CB(Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1850 emitSwitchCase(CB, SwitchMBB, MIB);
1856 MachineIRBuilder &MIB = *CurBuilder;
1860 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1862 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1864 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1869 LLT MaskTy = SwitchOpTy;
1875 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1884 Register SubReg = RangeSub.getReg(0);
1885 if (SwitchOpTy != MaskTy)
1891 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1893 if (!
B.FallthroughUnreachable)
1894 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1895 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1899 if (!
B.FallthroughUnreachable) {
1903 RangeSub, RangeCst);
1917 MachineIRBuilder &MIB = *CurBuilder;
1923 if (PopCount == 1) {
1926 auto MaskTrailingZeros =
1931 }
else if (PopCount == BB.
Range) {
1933 auto MaskTrailingOnes =
1941 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1945 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1952 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1954 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1972bool IRTranslatorImpl::lowerBitTestWorkItem(
1978 bool FallthroughUnreachable) {
1979 using namespace SwitchCG;
1982 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
1984 for (BitTestCase &BTC : BTB->Cases)
1985 CurMF->
insert(BBI, BTC.ThisBB);
1988 BTB->Parent = CurMBB;
1989 BTB->Default = Fallthrough;
1991 BTB->DefaultProb = UnhandledProbs;
1995 if (!BTB->ContiguousRange) {
1996 BTB->Prob += DefaultProb / 2;
1997 BTB->DefaultProb -= DefaultProb / 2;
2000 if (FallthroughUnreachable)
2001 BTB->FallthroughUnreachable =
true;
2004 if (CurMBB == SwitchMBB) {
2005 emitBitTestHeader(*BTB, SwitchMBB);
2006 BTB->Emitted =
true;
2016 using namespace SwitchCG;
2018 MachineBasicBlock *NextMBB =
nullptr;
2020 if (++BBI != FuncInfo.MF->end())
2029 [](
const CaseCluster &a,
const CaseCluster &b) {
2030 return a.Prob != b.Prob
2032 : a.Low->getValue().slt(b.Low->getValue());
2037 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
2039 if (
I->Prob >
W.LastCluster->Prob)
2041 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
2049 BranchProbability DefaultProb =
W.DefaultProb;
2050 BranchProbability UnhandledProbs = DefaultProb;
2051 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
2052 UnhandledProbs +=
I->Prob;
2054 MachineBasicBlock *CurMBB =
W.MBB;
2055 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
2056 bool FallthroughUnreachable =
false;
2057 MachineBasicBlock *Fallthrough;
2058 if (
I ==
W.LastCluster) {
2060 Fallthrough = DefaultMBB;
2065 CurMF->
insert(BBI, Fallthrough);
2067 UnhandledProbs -=
I->Prob;
2071 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2072 DefaultProb, UnhandledProbs,
I, Fallthrough,
2073 FallthroughUnreachable)) {
2081 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2082 UnhandledProbs,
I, Fallthrough,
2083 FallthroughUnreachable)) {
2090 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
2091 FallthroughUnreachable, UnhandledProbs,
2092 CurMBB, MIB, SwitchMBB)) {
2099 CurMBB = Fallthrough;
2105bool IRTranslatorImpl::translateIndirectBr(
const User &U,
2113 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
2114 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
2115 for (
const BasicBlock *Succ :
successors(&BrInst)) {
2119 if (!AddedSuccessors.
insert(Succ).second)
2135bool IRTranslatorImpl::translateLoad(
const User &U,
2138 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
2149 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
2151 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
2157 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
2159 if (AA->pointsToConstantMemory(
2166 if (Regs.
size() == 1) {
2167 auto *MMO = MF->getMachineMemOperand(
2169 MRI->getType(Regs[0]), getMemOpAlign(LI),
2170 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
2176 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
2177 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
2179 for (
unsigned i = 0; i < Regs.
size(); ++i) {
2184 Align BaseAlign = getMemOpAlign(LI);
2186 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
2189 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
2195bool IRTranslatorImpl::translateStore(
const User &U,
2198 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
2204 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
2205 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
2207 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
2208 SI.getPointerOperand());
2215 if (Vals.
size() == 1) {
2216 auto *MMO = MF->getMachineMemOperand(
2217 MachinePointerInfo(
SI.getPointerOperand()), Flags,
2218 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
2219 SI.getSyncScopeID(),
SI.getOrdering());
2224 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
2225 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
2227 for (
unsigned i = 0; i < Vals.
size(); ++i) {
2231 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
2232 Align BaseAlign = getMemOpAlign(SI);
2233 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
2236 SI.getSyncScopeID(),
SI.getOrdering());
2243 const Value *Src = U.getOperand(0);
2249 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
2252 for (
auto Idx : EVI->indices())
2253 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2255 for (
auto Idx : IVI->indices())
2256 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2262 DL.getIndexedOffsetInType(Src->getType(), Indices));
2265bool IRTranslatorImpl::translateExtractValue(
const User &U,
2267 const Value *Src =
U.getOperand(0);
2270 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
2272 auto &DstRegs = allocateVRegs(U);
2274 for (
unsigned i = 0; i < DstRegs.size(); ++i)
2275 DstRegs[i] = SrcRegs[Idx++];
2280bool IRTranslatorImpl::translateInsertValue(
const User &U,
2282 const Value *Src =
U.getOperand(0);
2284 auto &DstRegs = allocateVRegs(U);
2285 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
2288 auto *InsertedIt = InsertedRegs.
begin();
2290 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
2291 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
2292 DstRegs[i] = *InsertedIt++;
2294 DstRegs[i] = SrcRegs[i];
2300bool IRTranslatorImpl::translateSelect(
const User &U,
2302 Register Tst = getOrCreateVReg(*
U.getOperand(0));
2311 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
2312 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
2318bool IRTranslatorImpl::translateCopy(
const User &U,
const Value &V,
2320 return translateCopy(U, getOrCreateVReg(V), MIRBuilder);
2323bool IRTranslatorImpl::translateCopy(
const User &U,
Register Src,
2325 auto &Regs = *VMap.getVRegs(U);
2327 Regs.push_back(Src);
2336bool IRTranslatorImpl::translateBitCast(
const User &U,
2338 Type *SrcTy =
U.getOperand(0)->getType();
2339 Type *DstTy =
U.getType();
2346 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
2348 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
2358 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
2360 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
2362 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
2365bool IRTranslatorImpl::translateCast(
unsigned Opcode,
const User &U,
2367 if (!mayTranslateUserTypes(U))
2380bool IRTranslatorImpl::translateGetElementPtr(
const User &U,
2382 Value &Op0 = *
U.getOperand(0);
2386 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
2389 uint32_t PtrAddFlags = 0;
2395 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
2405 unsigned VectorWidth = 0;
2409 bool WantSplatVector =
false;
2413 WantSplatVector = VectorWidth > 1;
2417 return translateCopy(U, BaseReg, MIRBuilder);
2421 if (WantSplatVector && !PtrTy.
isVector()) {
2428 OffsetIRTy = DL->getIndexType(PtrIRTy);
2435 const Value *Idx = GTI.getOperand();
2436 if (StructType *StTy = GTI.getStructTypeOrNull()) {
2438 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
2441 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
2446 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
2447 Offset += ElementSize * *Val;
2456 PtrAddFlagsWithConst(
Offset))
2461 Register IdxReg = getOrCreateVReg(*Idx);
2462 LLT IdxTy = MRI->getType(IdxReg);
2463 if (IdxTy != OffsetTy) {
2464 if (!IdxTy.
isVector() && WantSplatVector) {
2477 if (ElementSize != 1) {
2488 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
2491 GepOffsetReg = IdxReg;
2495 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
2504 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
2505 PtrAddFlagsWithConst(
Offset));
2509 return translateCopy(U, BaseReg, MIRBuilder);
2512bool IRTranslatorImpl::translateMemFunc(
const CallInst &CI,
2522 unsigned MinPtrSize = UINT_MAX;
2523 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
2524 Register SrcReg = getOrCreateVReg(**AI);
2525 LLT SrcTy = MRI->getType(SrcReg);
2527 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
2535 if (MRI->getType(SizeOpReg) != SizeTy)
2547 ConstantInt *CopySize =
nullptr;
2550 DstAlign = MCI->getDestAlign().valueOrOne();
2551 SrcAlign = MCI->getSourceAlign().valueOrOne();
2554 DstAlign = MMI->getDestAlign().valueOrOne();
2555 SrcAlign = MMI->getSourceAlign().valueOrOne();
2559 DstAlign = MSI->getDestAlign().valueOrOne();
2562 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
2563 Opcode != TargetOpcode::G_MEMSET_INLINE) {
2579 if (AA && CopySize &&
2580 AA->pointsToConstantMemory(MemoryLocation(
2590 ICall.addMemOperand(
2591 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
2592 StoreFlags, 1, DstAlign, AAInfo));
2593 if (Opcode != TargetOpcode::G_MEMSET &&
2594 Opcode != TargetOpcode::G_MEMSET_INLINE)
2595 ICall.addMemOperand(MF->getMachineMemOperand(
2596 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
2601bool IRTranslatorImpl::translateTrap(
const CallInst &CI,
2604 StringRef TrapFuncName =
2605 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
2606 if (TrapFuncName.
empty()) {
2607 if (Opcode == TargetOpcode::G_UBSANTRAP) {
2616 CallLowering::CallLoweringInfo
Info;
2617 if (Opcode == TargetOpcode::G_UBSANTRAP)
2624 return CLI->lowerCall(MIRBuilder, Info);
2627bool IRTranslatorImpl::translateVectorInterleave2Intrinsic(
2630 "This function can only be called on the interleave2 intrinsic!");
2634 Register Res = getOrCreateVReg(CI);
2636 LLT OpTy = MRI->getType(Op0);
2643bool IRTranslatorImpl::translateVectorDeinterleave2Intrinsic(
2646 "This function can only be called on the deinterleave2 intrinsic!");
2653 LLT ResTy = MRI->getType(Res[0]);
2670void IRTranslatorImpl::getStackGuard(
Register DstReg,
2673 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
2676 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
2681 const TargetInstrInfo &
TII = *MF->getSubtarget().getInstrInfo();
2682 MRI->setRegClass(DstReg,
2683 TII.getRegClass(
TII.get(TargetOpcode::LOAD_STACK_GUARD), 0));
2685 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
2687 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
2688 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
2690 MachinePointerInfo MPInfo(
Global);
2693 MachineMemOperand *MemRef = MF->getMachineMemOperand(
2694 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
2695 MIB.setMemRefs({MemRef});
2698bool IRTranslatorImpl::translateOverflowIntrinsic(
2702 Op, {ResRegs[0], ResRegs[1]},
2708bool IRTranslatorImpl::translateFixedPointIntrinsic(
2710 Register Dst = getOrCreateVReg(CI);
2714 MIRBuilder.
buildInstr(
Op, {Dst}, { Src0, Src1, Scale });
2718unsigned IRTranslatorImpl::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
2722 case Intrinsic::acos:
2723 return TargetOpcode::G_FACOS;
2724 case Intrinsic::asin:
2725 return TargetOpcode::G_FASIN;
2726 case Intrinsic::atan:
2727 return TargetOpcode::G_FATAN;
2728 case Intrinsic::atan2:
2729 return TargetOpcode::G_FATAN2;
2730 case Intrinsic::bswap:
2731 return TargetOpcode::G_BSWAP;
2732 case Intrinsic::bitreverse:
2733 return TargetOpcode::G_BITREVERSE;
2734 case Intrinsic::clmul:
2735 return TargetOpcode::G_CLMUL;
2736 case Intrinsic::fshl:
2737 return TargetOpcode::G_FSHL;
2738 case Intrinsic::fshr:
2739 return TargetOpcode::G_FSHR;
2740 case Intrinsic::ceil:
2741 return TargetOpcode::G_FCEIL;
2742 case Intrinsic::cos:
2743 return TargetOpcode::G_FCOS;
2744 case Intrinsic::cosh:
2745 return TargetOpcode::G_FCOSH;
2746 case Intrinsic::ctpop:
2747 return TargetOpcode::G_CTPOP;
2748 case Intrinsic::smulh:
2749 return TargetOpcode::G_SMULH;
2750 case Intrinsic::umulh:
2751 return TargetOpcode::G_UMULH;
2752 case Intrinsic::exp:
2753 return TargetOpcode::G_FEXP;
2754 case Intrinsic::exp2:
2755 return TargetOpcode::G_FEXP2;
2756 case Intrinsic::exp10:
2757 return TargetOpcode::G_FEXP10;
2758 case Intrinsic::fabs:
2759 return TargetOpcode::G_FABS;
2760 case Intrinsic::copysign:
2761 return TargetOpcode::G_FCOPYSIGN;
2762 case Intrinsic::minnum:
2763 return TargetOpcode::G_FMINNUM;
2764 case Intrinsic::maxnum:
2765 return TargetOpcode::G_FMAXNUM;
2766 case Intrinsic::minimum:
2767 return TargetOpcode::G_FMINIMUM;
2768 case Intrinsic::maximum:
2769 return TargetOpcode::G_FMAXIMUM;
2770 case Intrinsic::minimumnum:
2771 return TargetOpcode::G_FMINIMUMNUM;
2772 case Intrinsic::maximumnum:
2773 return TargetOpcode::G_FMAXIMUMNUM;
2774 case Intrinsic::canonicalize:
2775 return TargetOpcode::G_FCANONICALIZE;
2776 case Intrinsic::floor:
2777 return TargetOpcode::G_FFLOOR;
2778 case Intrinsic::fma:
2779 return TargetOpcode::G_FMA;
2780 case Intrinsic::log:
2781 return TargetOpcode::G_FLOG;
2782 case Intrinsic::log2:
2783 return TargetOpcode::G_FLOG2;
2784 case Intrinsic::log10:
2785 return TargetOpcode::G_FLOG10;
2786 case Intrinsic::ldexp:
2787 return TargetOpcode::G_FLDEXP;
2788 case Intrinsic::nearbyint:
2789 return TargetOpcode::G_FNEARBYINT;
2790 case Intrinsic::pow:
2791 return TargetOpcode::G_FPOW;
2792 case Intrinsic::powi:
2793 return TargetOpcode::G_FPOWI;
2794 case Intrinsic::rint:
2795 return TargetOpcode::G_FRINT;
2796 case Intrinsic::round:
2797 return TargetOpcode::G_INTRINSIC_ROUND;
2798 case Intrinsic::roundeven:
2799 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2800 case Intrinsic::sin:
2801 return TargetOpcode::G_FSIN;
2802 case Intrinsic::sinh:
2803 return TargetOpcode::G_FSINH;
2804 case Intrinsic::sqrt:
2805 return TargetOpcode::G_FSQRT;
2806 case Intrinsic::tan:
2807 return TargetOpcode::G_FTAN;
2808 case Intrinsic::tanh:
2809 return TargetOpcode::G_FTANH;
2810 case Intrinsic::trunc:
2811 return TargetOpcode::G_INTRINSIC_TRUNC;
2812 case Intrinsic::readcyclecounter:
2813 return TargetOpcode::G_READCYCLECOUNTER;
2814 case Intrinsic::readsteadycounter:
2815 return TargetOpcode::G_READSTEADYCOUNTER;
2816 case Intrinsic::ptrmask:
2817 return TargetOpcode::G_PTRMASK;
2818 case Intrinsic::lrint:
2819 return TargetOpcode::G_INTRINSIC_LRINT;
2820 case Intrinsic::llrint:
2821 return TargetOpcode::G_INTRINSIC_LLRINT;
2823 case Intrinsic::vector_reduce_fmin:
2824 return TargetOpcode::G_VECREDUCE_FMIN;
2825 case Intrinsic::vector_reduce_fmax:
2826 return TargetOpcode::G_VECREDUCE_FMAX;
2827 case Intrinsic::vector_reduce_fminimum:
2828 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2829 case Intrinsic::vector_reduce_fmaximum:
2830 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2831 case Intrinsic::vector_reduce_fminimumnum:
2832 return TargetOpcode::G_VECREDUCE_FMINIMUMNUM;
2833 case Intrinsic::vector_reduce_fmaximumnum:
2834 return TargetOpcode::G_VECREDUCE_FMAXIMUMNUM;
2835 case Intrinsic::vector_reduce_add:
2836 return TargetOpcode::G_VECREDUCE_ADD;
2837 case Intrinsic::vector_reduce_mul:
2838 return TargetOpcode::G_VECREDUCE_MUL;
2839 case Intrinsic::vector_reduce_and:
2840 return TargetOpcode::G_VECREDUCE_AND;
2841 case Intrinsic::vector_reduce_or:
2842 return TargetOpcode::G_VECREDUCE_OR;
2843 case Intrinsic::vector_reduce_xor:
2844 return TargetOpcode::G_VECREDUCE_XOR;
2845 case Intrinsic::vector_reduce_smax:
2846 return TargetOpcode::G_VECREDUCE_SMAX;
2847 case Intrinsic::vector_reduce_smin:
2848 return TargetOpcode::G_VECREDUCE_SMIN;
2849 case Intrinsic::vector_reduce_umax:
2850 return TargetOpcode::G_VECREDUCE_UMAX;
2851 case Intrinsic::vector_reduce_umin:
2852 return TargetOpcode::G_VECREDUCE_UMIN;
2853 case Intrinsic::experimental_vector_compress:
2854 return TargetOpcode::G_VECTOR_COMPRESS;
2855 case Intrinsic::lround:
2856 return TargetOpcode::G_LROUND;
2857 case Intrinsic::llround:
2858 return TargetOpcode::G_LLROUND;
2859 case Intrinsic::get_fpenv:
2860 return TargetOpcode::G_GET_FPENV;
2861 case Intrinsic::get_fpmode:
2862 return TargetOpcode::G_GET_FPMODE;
2867bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2871 unsigned Op = getSimpleIntrinsicOpcode(ID);
2879 for (
const auto &Arg : CI.
args())
2882 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2890 case Intrinsic::experimental_constrained_fadd:
2891 return TargetOpcode::G_STRICT_FADD;
2892 case Intrinsic::experimental_constrained_fsub:
2893 return TargetOpcode::G_STRICT_FSUB;
2894 case Intrinsic::experimental_constrained_fmul:
2895 return TargetOpcode::G_STRICT_FMUL;
2896 case Intrinsic::experimental_constrained_fdiv:
2897 return TargetOpcode::G_STRICT_FDIV;
2898 case Intrinsic::experimental_constrained_frem:
2899 return TargetOpcode::G_STRICT_FREM;
2900 case Intrinsic::experimental_constrained_fma:
2901 return TargetOpcode::G_STRICT_FMA;
2902 case Intrinsic::experimental_constrained_sqrt:
2903 return TargetOpcode::G_STRICT_FSQRT;
2904 case Intrinsic::experimental_constrained_ldexp:
2905 return TargetOpcode::G_STRICT_FLDEXP;
2906 case Intrinsic::experimental_constrained_fcmp:
2907 return TargetOpcode::G_STRICT_FCMP;
2908 case Intrinsic::experimental_constrained_fcmps:
2909 return TargetOpcode::G_STRICT_FCMPS;
2915bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2927 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2928 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2930 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2931 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2934 .addPredicate(FPCmp->getPredicate())
2948std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2949 auto VRegs = getOrCreateVRegs(Arg);
2950 if (VRegs.
size() != 1)
2951 return std::nullopt;
2954 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2955 if (!VRegDef || !VRegDef->isCopy())
2956 return std::nullopt;
2957 return VRegDef->getOperand(1).getReg().asMCReg();
2960bool IRTranslatorImpl::translateIfEntryValueArgument(
2971 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2973 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2974 <<
": expression is entry_value but "
2975 <<
"couldn't find a physical register\n");
2983 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
2995 case Intrinsic::experimental_convergence_anchor:
2996 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
2997 case Intrinsic::experimental_convergence_entry:
2998 return TargetOpcode::CONVERGENCECTRL_ENTRY;
2999 case Intrinsic::experimental_convergence_loop:
3000 return TargetOpcode::CONVERGENCECTRL_LOOP;
3004bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
3007 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3010 if (ID == Intrinsic::experimental_convergence_loop) {
3012 assert(Bundle &&
"Expected a convergence control token.");
3014 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3021bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3025 if (ORE->enabled()) {
3027 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3035 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3041 case Intrinsic::lifetime_start:
3042 case Intrinsic::lifetime_end: {
3045 MF->getFunction().hasOptNone())
3048 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3049 : TargetOpcode::LIFETIME_END;
3058 case Intrinsic::fake_use: {
3060 for (
const auto &Arg : CI.
args())
3062 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3063 MF->setHasFakeUses(
true);
3066 case Intrinsic::dbg_declare: {
3073 case Intrinsic::dbg_label: {
3079 "Expected inlined-at fields to agree");
3084 case Intrinsic::vaend:
3088 case Intrinsic::vastart: {
3090 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3093 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3094 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3096 ListSize, Alignment));
3099 case Intrinsic::dbg_assign:
3106 case Intrinsic::dbg_value: {
3113 case Intrinsic::uadd_with_overflow:
3114 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3115 case Intrinsic::sadd_with_overflow:
3116 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3117 case Intrinsic::usub_with_overflow:
3118 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3119 case Intrinsic::ssub_with_overflow:
3120 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3121 case Intrinsic::umul_with_overflow:
3122 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3123 case Intrinsic::smul_with_overflow:
3124 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3125 case Intrinsic::uadd_sat:
3126 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3127 case Intrinsic::sadd_sat:
3128 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3129 case Intrinsic::usub_sat:
3130 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3131 case Intrinsic::ssub_sat:
3132 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3133 case Intrinsic::ushl_sat:
3134 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3135 case Intrinsic::sshl_sat:
3136 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3137 case Intrinsic::umin:
3138 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3139 case Intrinsic::umax:
3140 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3141 case Intrinsic::smin:
3142 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3143 case Intrinsic::smax:
3144 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3145 case Intrinsic::abs:
3147 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3148 case Intrinsic::smul_fix:
3149 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3150 case Intrinsic::umul_fix:
3151 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3152 case Intrinsic::smul_fix_sat:
3153 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3154 case Intrinsic::umul_fix_sat:
3155 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3156 case Intrinsic::sdiv_fix:
3157 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3158 case Intrinsic::udiv_fix:
3159 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3160 case Intrinsic::sdiv_fix_sat:
3161 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3162 case Intrinsic::udiv_fix_sat:
3163 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3164 case Intrinsic::fmuladd: {
3165 Register Dst = getOrCreateVReg(CI);
3169 if (TLI->isFMAFasterThanFMulAndFAdd(*MF,
3170 TLI->getValueType(*DL, CI.
getType()))) {
3173 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3184 case Intrinsic::frexp: {
3191 case Intrinsic::modf: {
3193 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3198 case Intrinsic::sincos: {
3205 case Intrinsic::fptosi_sat:
3209 case Intrinsic::fptoui_sat:
3213 case Intrinsic::memcpy_inline:
3214 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3215 case Intrinsic::memcpy:
3216 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3217 case Intrinsic::memmove:
3218 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3219 case Intrinsic::memset:
3220 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3221 case Intrinsic::memset_inline:
3222 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3223 case Intrinsic::eh_typeid_for: {
3226 unsigned TypeID = MF->getTypeIDFor(GV);
3230 case Intrinsic::objectsize:
3233 case Intrinsic::is_constant:
3236 case Intrinsic::stackguard:
3237 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3239 case Intrinsic::stackprotector: {
3242 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3243 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3244 getStackGuard(GuardVal, MIRBuilder);
3249 int FI = getOrCreateFrameIndex(*Slot);
3250 MF->getFrameInfo().setStackProtectorIndex(FI);
3253 GuardVal, getOrCreateVReg(*Slot),
3260 case Intrinsic::stacksave: {
3261 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3264 case Intrinsic::stackrestore: {
3265 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3269 case Intrinsic::cttz:
3270 case Intrinsic::ctlz: {
3272 bool isTrailing =
ID == Intrinsic::cttz;
3273 unsigned Opcode = isTrailing ? Cst->
isZero()
3274 ? TargetOpcode::G_CTTZ
3275 : TargetOpcode::G_CTTZ_ZERO_POISON
3276 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3277 : TargetOpcode::G_CTLZ_ZERO_POISON;
3278 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3282 case Intrinsic::invariant_start: {
3286 case Intrinsic::invariant_end:
3288 case Intrinsic::expect:
3289 case Intrinsic::expect_with_probability:
3290 case Intrinsic::annotation:
3291 case Intrinsic::ptr_annotation:
3292 case Intrinsic::launder_invariant_group:
3293 case Intrinsic::threadlocal_address: {
3295 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3299 case Intrinsic::assume:
3300 case Intrinsic::experimental_noalias_scope_decl:
3301 case Intrinsic::var_annotation:
3302 case Intrinsic::sideeffect:
3305 case Intrinsic::read_volatile_register:
3306 case Intrinsic::read_register: {
3309 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3313 case Intrinsic::write_register: {
3315 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3320 case Intrinsic::localescape: {
3321 MachineBasicBlock &EntryMBB = MF->front();
3326 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3333 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3346 case Intrinsic::vector_reduce_fadd:
3347 case Intrinsic::vector_reduce_fmul: {
3350 Register Dst = getOrCreateVReg(CI);
3356 Opc =
ID == Intrinsic::vector_reduce_fadd
3357 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3358 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3359 if (!MRI->getType(VecSrc).isVector())
3360 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3361 : TargetOpcode::G_FMUL;
3369 if (ID == Intrinsic::vector_reduce_fadd) {
3370 Opc = TargetOpcode::G_VECREDUCE_FADD;
3371 ScalarOpc = TargetOpcode::G_FADD;
3373 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3374 ScalarOpc = TargetOpcode::G_FMUL;
3376 LLT DstTy = MRI->getType(Dst);
3379 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3384 case Intrinsic::trap:
3385 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3386 case Intrinsic::debugtrap:
3387 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3388 case Intrinsic::ubsantrap:
3389 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3390 case Intrinsic::allow_runtime_check:
3391 case Intrinsic::allow_ubsan_check:
3392 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3395 case Intrinsic::amdgcn_cs_chain:
3396 case Intrinsic::amdgcn_call_whole_wave:
3397 return translateCallBase(CI, MIRBuilder);
3398 case Intrinsic::fptrunc_round: {
3403 std::optional<RoundingMode> RoundMode =
3408 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3409 {getOrCreateVReg(CI)},
3411 .addImm((
int)*RoundMode);
3415 case Intrinsic::is_fpclass: {
3420 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3421 {getOrCreateVReg(*FpValue)})
3426 case Intrinsic::set_fpenv: {
3431 case Intrinsic::reset_fpenv:
3434 case Intrinsic::set_fpmode: {
3439 case Intrinsic::reset_fpmode:
3442 case Intrinsic::get_rounding:
3445 case Intrinsic::set_rounding:
3448 case Intrinsic::vscale: {
3452 case Intrinsic::scmp:
3453 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3457 case Intrinsic::ucmp:
3458 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3462 case Intrinsic::vector_extract:
3463 return translateExtractVector(CI, MIRBuilder);
3464 case Intrinsic::vector_insert:
3465 return translateInsertVector(CI, MIRBuilder);
3466 case Intrinsic::stepvector: {
3470 case Intrinsic::prefetch: {
3477 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3480 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3486 case Intrinsic::speculative_load: {
3490 Register Dst = getOrCreateVReg(CI);
3492 Flags |= TLI->getTargetMMOFlags(CI);
3495 if (CI.
hasMetadata(LLVMContext::MD_invariant_load))
3497 auto *MMO = MF->getMachineMemOperand(
3498 MachinePointerInfo(Ptr), Flags, MRI->getType(Dst),
3500 MIRBuilder.
buildLoad(Dst, getOrCreateVReg(*Ptr), *MMO);
3504 case Intrinsic::vector_interleave2:
3505 case Intrinsic::vector_deinterleave2: {
3513 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3515 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3518#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3519 case Intrinsic::INTRINSIC:
3520#include "llvm/IR/ConstrainedOps.def"
3523 case Intrinsic::experimental_convergence_anchor:
3524 case Intrinsic::experimental_convergence_entry:
3525 case Intrinsic::experimental_convergence_loop:
3526 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3527 case Intrinsic::reloc_none: {
3530 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3538bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3540 if (!mayTranslateUserTypes(CB))
3543 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3547 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3552 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3555bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3562 for (
const auto &Arg : CB.
args()) {
3564 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3566 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3567 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3568 &CB, &MIRBuilder.
getMBB(), Arg));
3571 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3574 Args.push_back(getOrCreateVRegs(*Arg));
3578 if (ORE->enabled()) {
3580 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3586 std::optional<CallLowering::PtrAuthInfo> PAI;
3591 const Value *
Key = Bundle->Inputs[0];
3598 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3599 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3601 Register DiscReg = getOrCreateVReg(*Discriminator);
3609 const auto &Token = *Bundle->Inputs[0].get();
3610 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3616 bool Success = CLI->lowerCall(
3617 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3622 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3623 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3630bool IRTranslatorImpl::translateCall(
const User &U,
3632 if (!mayTranslateUserTypes(U))
3640 if (
F && (
F->hasDLLImportStorageClass() ||
3641 (MF->getTarget().getTargetTriple().isOSWindows() &&
3642 F->hasExternalWeakLinkage())))
3654 return translateInlineAsm(CI, MIRBuilder);
3658 if (translateCallBase(CI, MIRBuilder)) {
3667 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3668 const Function &Fn = MF->getFunction();
3670 DiagnosticInfoUnsupportedTargetIntrinsic(Fn, ID, CI.
getDebugLoc()));
3673 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3677 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3679 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3683bool IRTranslatorImpl::translateIntrinsic(
3686 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3688 F.getContext().diagnose(
3689 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3694 ResultRegs = getOrCreateVRegs(CB);
3698 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3709 assert(CI->getBitWidth() <= 64 &&
3710 "large intrinsic immediates not handled");
3711 MIB.
addImm(CI->getSExtValue());
3716 auto *MD = MDVal->getMetadata();
3720 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3727 if (VRegs.
size() > 1)
3734 for (
const auto &Info : TgtMemIntrinsicInfos) {
3737 LLT MemTy =
Info.memVT.isSimple()
3739 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3743 MachinePointerInfo MPI;
3745 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3746 }
else if (
Info.fallbackAddressSpace) {
3747 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3756 auto *Token = Bundle->Inputs[0].get();
3757 Register TokenReg = getOrCreateVReg(*Token);
3768bool IRTranslatorImpl::findUnwindDestinations(
3780 if (IsWasmCXX || IsWasmD) {
3790 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3796 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3797 UnwindDests.back().first->setIsEHScopeEntry();
3798 UnwindDests.back().first->setIsEHFuncletEntry();
3803 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3804 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3806 if (IsMSVCCXX || IsCoreCLR)
3807 UnwindDests.back().first->setIsEHFuncletEntry();
3809 UnwindDests.back().first->setIsEHScopeEntry();
3811 NewEHPadBB = CatchSwitch->getUnwindDest();
3816 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3817 if (BPI && NewEHPadBB)
3819 EHPadBB = NewEHPadBB;
3824bool IRTranslatorImpl::translateInvoke(
const User &U,
3827 MCContext &
Context = MF->getContext();
3832 const Function *Fn =
I.getCalledFunction();
3839 if (
I.hasDeoptState())
3853 (MF->getTarget().getTargetTriple().isOSWindows() &&
3857 bool LowerInlineAsm =
I.isInlineAsm();
3858 bool NeedEHLabel =
true;
3864 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3865 BeginSymbol =
Context.createTempSymbol();
3869 if (LowerInlineAsm) {
3870 if (!translateInlineAsm(
I, MIRBuilder))
3872 }
else if (!translateCallBase(
I, MIRBuilder))
3877 EndSymbol =
Context.createTempSymbol();
3882 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3883 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3884 BranchProbability EHPadBBProb =
3888 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3891 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3892 &ReturnMBB = getMBB(*ReturnBB);
3894 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3895 for (
auto &UnwindDest : UnwindDests) {
3896 UnwindDest.first->setIsEHPad();
3897 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3902 assert(BeginSymbol &&
"Expected a begin symbol!");
3903 assert(EndSymbol &&
"Expected an end symbol!");
3904 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3907 MIRBuilder.
buildBr(ReturnMBB);
3913bool IRTranslatorImpl::translateCallBr(
const User &U,
3915 if (!mayTranslateUserTypes(U))
3919 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3922 if (
I.isInlineAsm()) {
3928 if (!translateIntrinsic(
I, IID, MIRBuilder))
3932 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3933 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3942 for (BasicBlock *Dest :
I.getIndirectDests()) {
3943 MachineBasicBlock &
Target = getMBB(*Dest);
3944 Target.setIsInlineAsmBrIndirectTarget();
3945 Target.setLabelMustBeEmitted();
3947 if (Dests.
insert(Dest).second)
3959bool IRTranslatorImpl::translateLandingPad(
const User &U,
3963 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3969 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3970 if (TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel,
3971 PersonalityFn) == 0 &&
3972 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel,
3973 PersonalityFn) == 0)
3988 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3993 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3994 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3995 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
4004 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
4008 TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel, PersonalityFn);
4014 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
4017 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel, PersonalityFn);
4022 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
4023 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
4024 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
4029bool IRTranslatorImpl::translateAlloca(
const User &U,
4037 Register Res = getOrCreateVReg(AI);
4038 int FI = getOrCreateFrameIndex(AI);
4044 if (MF->getTarget().getTargetTriple().isOSWindows())
4049 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4051 if (MRI->getType(NumElts) !=
IntPtrTy) {
4063 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4068 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4070 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4075 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4084 if (Alignment <= StackAlign)
4088 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4089 assert(MF->getFrameInfo().hasVarSizedObjects());
4093bool IRTranslatorImpl::translateVAArg(
const User &U,
4099 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4100 {getOrCreateVReg(*
U.getOperand(0)),
4101 DL->getABITypeAlign(
U.getType()).value()});
4105bool IRTranslatorImpl::translateUnreachable(
const User &U,
4108 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4109 MF->getTarget().Options.NoTrapAfterNoreturn))
4116bool IRTranslatorImpl::translateInsertElement(
const User &U,
4121 FVT && FVT->getNumElements() == 1)
4122 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4125 Register Val = getOrCreateVReg(*
U.getOperand(0));
4126 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4127 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4130 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4131 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4132 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4133 Idx = getOrCreateVReg(*NewIdxCI);
4137 Idx = getOrCreateVReg(*
U.getOperand(2));
4138 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4139 const LLT VecIdxTy =
4140 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4147bool IRTranslatorImpl::translateInsertVector(
const User &U,
4150 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4151 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4154 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4159 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4164 ResultType && ResultType->getNumElements() == 1) {
4166 InputType && InputType->getNumElements() == 1) {
4170 return translateCopy(U, Vec, MIRBuilder);
4176 Register Idx = getOrCreateVReg(*CI);
4184 Register Idx = getOrCreateVReg(*CI);
4185 auto ScaledIndex = MIRBuilder.
buildMul(
4186 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4196bool IRTranslatorImpl::translateExtractElement(
const User &U,
4200 if (
const FixedVectorType *FVT =
4202 if (FVT->getNumElements() == 1)
4203 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4206 Register Val = getOrCreateVReg(*
U.getOperand(0));
4207 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4212 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4213 Idx = getOrCreateVReg(*NewIdxCI);
4217 Idx = getOrCreateVReg(*
U.getOperand(1));
4218 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4219 const LLT VecIdxTy =
4227bool IRTranslatorImpl::translateExtractVector(
const User &U,
4230 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4232 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4237 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4242 ResultType && ResultType->getNumElements() == 1) {
4244 InputType && InputType->getNumElements() == 1) {
4247 return translateCopy(U, Vec, MIRBuilder);
4253 Register Idx = getOrCreateVReg(*CI);
4261 Register Idx = getOrCreateVReg(*CI);
4262 auto ScaledIndex = MIRBuilder.
buildMul(
4263 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4273bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4279 if (
U.getOperand(0)->getType()->isScalableTy()) {
4280 Register Val = getOrCreateVReg(*
U.getOperand(0));
4282 MRI->getType(Val).getElementType(), Val, 0);
4289 Mask = SVI->getShuffleMask();
4300 unsigned M =
Mask[0];
4302 if (M == 0 || M == 1)
4303 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4309 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4310 }
else if (M < SrcElts * 2) {
4312 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4324 for (
int M : Mask) {
4326 if (M == 0 || M == 1) {
4327 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4329 if (!
Undef.isValid()) {
4330 Undef = MRI->createGenericVirtualRegister(SrcTy);
4340 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4342 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4343 {getOrCreateVReg(*
U.getOperand(0)),
4344 getOrCreateVReg(*
U.getOperand(1))})
4345 .addShuffleMask(MaskAlloc);
4349bool IRTranslatorImpl::translateBitInsert(
const User &U,
4353 Register Val = getOrCreateVReg(*
U.getOperand(1));
4355 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4357 LLT ValTy = MRI.getType(Val);
4360 "bitinsert val wider than base should be rejected by verifier");
4373 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(BaseTy);
4390 MIRBuilder.
buildOr(Res, ClearedBase, ShiftedVal);
4394bool IRTranslatorImpl::translateBitExtract(
const User &U,
4397 Register Src = getOrCreateVReg(*
U.getOperand(0));
4399 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4400 LLT SrcTy = MRI.getType(Src);
4401 LLT ResTy = MRI.getType(Res);
4404 "bitextract result wider than source should be rejected by verifier");
4407 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(SrcTy);
4417 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4419 if (SrcTy == IntResTy)
4430 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4432 if (SrcTy == IntResTy)
4449bool IRTranslatorImpl::translatePHI(
const User &U,
4453 SmallVector<MachineInstr *, 4> Insts;
4454 for (
auto Reg : getOrCreateVRegs(PI)) {
4455 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4459 PendingPHIs.emplace_back(&PI, std::move(Insts));
4463bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4467 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4469 auto Res = getOrCreateVRegs(
I);
4472 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4473 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4474 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4477 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4478 *MF->getMachineMemOperand(
4479 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4480 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4481 I.getSuccessOrdering(),
I.getFailureOrdering()));
4485bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4487 if (!mayTranslateUserTypes(U))
4491 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4494 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4495 Register Val = getOrCreateVReg(*
I.getValOperand());
4497 unsigned Opcode = 0;
4498 switch (
I.getOperation()) {
4502 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4505 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4508 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4511 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4514 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4517 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4520 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4523 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4526 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4529 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4532 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4535 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4538 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4541 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4544 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4547 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4550 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4553 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4556 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4559 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4562 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4565 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4568 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4573 Opcode, Res, Addr, Val,
4574 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4575 Flags, MRI->getType(Val), getMemOpAlign(
I),
4576 I.getAAMetadata(),
I.getSyncScopeID(),
4581bool IRTranslatorImpl::translateFence(
const User &U,
4585 Fence.getSyncScopeID());
4589bool IRTranslatorImpl::translateFreeze(
const User &U,
4595 "Freeze with different source and destination type?");
4597 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4604void IRTranslatorImpl::finishPendingPhis() {
4607 GISelObserverWrapper WrapperObserver(&
Verifier);
4608 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4610 for (
auto &Phi : PendingPHIs) {
4611 const PHINode *PI =
Phi.first;
4615 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4621 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4625 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4629 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4630 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4639void IRTranslatorImpl::translateDbgValueRecord(
Value *V,
bool HasArgList,
4645 "Expected inlined-at fields to agree");
4649 if (!V || HasArgList) {
4667 auto *ExprDerefRemoved =
4673 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
4685void IRTranslatorImpl::translateDbgDeclareRecord(
4690 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4695 "Expected inlined-at fields to agree");
4700 MF->setVariableDbgInfo(Variable, Expression,
4701 getOrCreateFrameIndex(*AI), DL);
4705 if (translateIfEntryValueArgument(
true,
Address, Variable,
4717void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4722 assert(DLR->getLabel() &&
"Missing label");
4723 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4725 "Expected inlined-at fields to agree");
4734 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
4737 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
4742bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4744 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4745 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4747 if (TLI->fallBackToDAGISel(Inst))
4751#define HANDLE_INST(NUM, OPCODE, CLASS) \
4752 case Instruction::OPCODE: \
4753 return translate##OPCODE(Inst, *CurBuilder.get());
4754#include "llvm/IR/Instruction.def"
4763 if (
auto CurrInstDL = CurBuilder->getDL())
4764 EntryBuilder->setDebugLoc(
DebugLoc());
4770 EntryBuilder->buildConstant(
Reg, *CI);
4774 EntryBuilder->buildConstant(
Reg, CB->getValue());
4778 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4779 EntryBuilder->buildFConstant(
Reg, *CF);
4781 EntryBuilder->buildUndef(
Reg);
4783 EntryBuilder->buildConstant(
Reg, 0);
4785 EntryBuilder->buildGlobalValue(
Reg, GV);
4787 Register Addr = getOrCreateVReg(*CPA->getPointer());
4788 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4789 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4791 Constant &Elt = *CAZ->getElementValue(0u);
4793 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4797 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4799 return translateCopy(
C, Elt, *EntryBuilder);
4801 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4804 if (CV->getNumElements() == 1)
4805 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4807 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4808 Constant &Elt = *CV->getElementAsConstant(i);
4809 Ops.push_back(getOrCreateVReg(Elt));
4811 EntryBuilder->buildBuildVector(
Reg,
Ops);
4813 switch(
CE->getOpcode()) {
4814#define HANDLE_INST(NUM, OPCODE, CLASS) \
4815 case Instruction::OPCODE: \
4816 return translate##OPCODE(*CE, *EntryBuilder.get());
4817#include "llvm/IR/Instruction.def"
4822 if (CV->getNumOperands() == 1)
4823 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4825 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4826 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4828 EntryBuilder->buildBuildVector(
Reg,
Ops);
4830 EntryBuilder->buildBlockAddress(
Reg, BA);
4837bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4838 const TargetMachine &TM = TLI->getTargetMachine();
4847 (!
U.getType()->getScalarType()->isBFloatTy() &&
4849 return V->getType()->getScalarType()->isBFloatTy();
4853bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4855 for (
auto &BTB : SL->BitTestCases) {
4858 emitBitTestHeader(BTB, BTB.Parent);
4860 BranchProbability UnhandledProb = BTB.Prob;
4861 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4862 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4864 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4873 MachineBasicBlock *NextMBB;
4874 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4877 NextMBB = BTB.Cases[
j + 1].TargetBB;
4878 }
else if (j + 1 == ej) {
4880 NextMBB = BTB.Default;
4883 NextMBB = BTB.Cases[
j + 1].ThisBB;
4886 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4888 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4892 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4893 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4896 BTB.Cases.pop_back();
4902 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4903 BTB.Default->getBasicBlock()};
4904 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4905 if (!BTB.ContiguousRange) {
4906 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4909 SL->BitTestCases.clear();
4911 for (
auto &JTCase : SL->JTCases) {
4913 if (!JTCase.first.Emitted)
4914 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4916 emitJumpTable(JTCase.second, JTCase.second.MBB);
4918 SL->JTCases.clear();
4920 for (
auto &SwCase : SL->SwitchCases)
4921 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4922 SL->SwitchCases.clear();
4925 if (SPInfo->shouldEmitSDCheck(BB)) {
4926 bool FunctionBasedInstrumentation =
4927 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4928 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4931 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4934 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4935 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4936 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4945 ParentMBB, *MF->getSubtarget().getInstrInfo());
4948 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4952 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4956 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4957 if (FailureMBB->
empty()) {
4958 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4963 SPDescriptor.resetPerBBState();
4970 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4974 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
4980 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
4987 ->buildLoad(PtrMemTy, StackSlotPtr,
4993 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
5005 FunctionType *FnTy = GuardCheckFn->getFunctionType();
5006 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
5007 ISD::ArgFlagsTy
Flags;
5008 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
5010 CallLowering::ArgInfo GuardArgInfo(
5011 {GuardVal, FnTy->getParamType(0), {
Flags}});
5013 CallLowering::CallLoweringInfo
Info;
5014 Info.OrigArgs.push_back(GuardArgInfo);
5015 Info.CallConv = GuardCheckFn->getCallingConv();
5018 if (!CLI->lowerCall(MIRBuilder, Info)) {
5019 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
5029 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
5030 getStackGuard(Guard, *CurBuilder);
5033 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
5034 Register GuardPtr = getOrCreateVReg(*IRGuard);
5037 ->buildLoad(PtrMemTy, GuardPtr,
5056 const RTLIB::LibcallImpl LibcallImpl =
5057 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
5058 if (LibcallImpl == RTLIB::Unsupported)
5061 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
5063 CallLowering::CallLoweringInfo
Info;
5064 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
5066 StringRef LibcallName =
5071 if (!CLI->lowerCall(*CurBuilder, Info)) {
5072 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
5077 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
5079 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
5084void IRTranslatorImpl::finalizeFunction() {
5087 PendingPHIs.clear();
5089 FrameIndices.clear();
5090 MachinePreds.clear();
5094 EntryBuilder.reset();
5097 SPDescriptor.resetPerFunctionState();
5110 return CI && CI->isMustTailCall();
5122 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
5123 CLI = MF->getSubtarget().getCallLowering();
5124 SPInfo = StackProtectorInfo;
5126 if (CLI->fallBackToDAGISel(*MF)) {
5128 F.getSubprogram(), &
F.getEntryBlock());
5129 R <<
"unable to lower function: "
5130 <<
ore::NV(
"Prototype",
F.getFunctionType());
5147 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5148 CSEInfo = GetCSEInfo();
5149 EntryBuilder->setCSEInfo(CSEInfo);
5150 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5151 CurBuilder->setCSEInfo(CSEInfo);
5153 EntryBuilder = std::make_unique<MachineIRBuilder>();
5154 CurBuilder = std::make_unique<MachineIRBuilder>();
5157 CurBuilder->setMF(*MF);
5158 EntryBuilder->setMF(*MF);
5159 MRI = &MF->getRegInfo();
5160 DL = &
F.getDataLayout();
5165 FuncInfo.ExceptionModel =
F.getParent()->getExceptionModel();
5169 AA = GetAAResults();
5170 FuncInfo.BPI = GetBPI();
5174 FuncInfo.BPI =
nullptr;
5177 LibInfo = LibraryInfo;
5178 Libcalls = LibcallInfo;
5180 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5182 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5183 SL->init(*TLI, TM, *DL);
5185 assert(PendingPHIs.empty() &&
"stale PHIs");
5189 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5192 F.getSubprogram(), &
F.getEntryBlock());
5193 R <<
"unable to translate in big endian mode";
5204 EntryBuilder->setMBB(*EntryBB);
5206 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5207 SwiftError.setFunction(CurMF);
5208 SwiftError.createEntriesInEntryBlock(DbgLoc);
5210 bool IsVarArg =
F.isVarArg();
5211 bool HasMustTailInVarArgFn =
false;
5214 unsigned NumValues =
F.arg_size();
5217 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5219 NumValues += BB.
size();
5222 MBB = MF->CreateMachineBasicBlock(&BB);
5230 if (!BA->hasZeroLiveUses())
5234 if (!HasMustTailInVarArgFn)
5238 VMap.reserveVRegs(NumValues);
5239 MRI->reserveVirtRegs(NumValues);
5241 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5244 EntryBB->addSuccessor(&getMBB(
F.front()));
5249 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5254 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5255 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5256 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5260 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5262 F.getSubprogram(), &
F.getEntryBlock());
5263 R <<
"unable to lower arguments: "
5264 <<
ore::NV(
"Prototype",
F.getFunctionType());
5271 if (EnableCSE && CSEInfo)
5276 DILocationVerifier Verifier;
5284 CurBuilder->setMBB(
MBB);
5285 HasTailCall =
false;
5295 Verifier.setCurrentInst(&Inst);
5299 translateDbgInfo(Inst, *CurBuilder);
5301 if (translate(Inst))
5306 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5308 if (ORE->allowExtraAnalysis(
"gisel-ir-translator")) {
5309 std::string InstStrStorage;
5313 R <<
": '" << InstStrStorage <<
"'";
5320 if (!finalizeBasicBlock(*BB,
MBB)) {
5322 BB->getTerminator()->getDebugLoc(), BB);
5323 R <<
"unable to translate basic block";
5333 finishPendingPhis();
5335 SwiftError.propagateVRegs();
5340 assert(EntryBB->succ_size() == 1 &&
5341 "Custom BB used for lowering should have only one successor");
5345 "LLVM-IR entry block has a predecessor!?");
5348 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5357 EntryBB->removeSuccessor(&NewEntryBB);
5358 MF->remove(EntryBB);
5359 MF->deleteMachineBasicBlock(EntryBB);
5361 assert(&MF->front() == &NewEntryBB &&
5362 "New entry wasn't next in the list of basic block!");
5365 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5375 return Impl->runOnMachineFunction(
5394 *
F.getParent(), Subtarget),
5419 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5420 Impl->runOnMachineFunction(
5422 ShouldSkipOpts, [&]() {
return &
FAM.getResult<
AAManager>(
F); },
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
This file describes how to lower LLVM calls to machine code calls.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This contains common code to allow clients to notify changes to machine instr.
const HexagonInstrInfo * TII
static cl::opt< bool > EnableCSEInIRTranslator("enable-cse-in-ir-translator", cl::desc("Should enable CSE in ir-translator"), cl::init(false))
static bool checkForMustTailInVarArgFn(bool IsVarArg, const BasicBlock &BB)
Returns true if a BasicBlock BB within a variadic function contains a variadic musttail call.
static unsigned getConvOpcode(Intrinsic::ID ID)
static uint64_t getOffsetFromIndices(const User &U, const DataLayout &DL)
static unsigned getConstrainedOpcode(Intrinsic::ID ID)
IRTranslator LLVM IR static false void reportTranslationError(MachineFunction &MF, OptimizationRemarkEmitter &ORE, OptimizationRemarkMissed &R)
static bool isValInBlock(const Value *V, const BasicBlock *BB)
static bool isSwiftError(const Value *V)
This file declares the IRTranslator pass.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This file describes how to lower LLVM inline asm to machine code INLINEASM.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Implement a low-level type suitable for MachineInstr level instruction selection.
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
OptimizedStructLayoutField Field
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
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.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
LLVM_ABI TypeSize getAllocationBaseSize(const DataLayout &DL) const
Get the size of the allocated type.
PointerType * getType() const
Overload to return most specific pointer type.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
const Value * getArraySize() const
Get the number of elements allocated.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
This class represents an incoming formal argument to a Function.
LLVM_ABI bool hasSwiftErrorAttr() const
Return true if this argument has the swifterror attribute.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
@ USubCond
Subtract only if no unsigned overflow.
@ FMinimum
*p = minimum(old, v) minimum matches the behavior of llvm.minimum.
@ Min
*p = old <signed v ? old : v
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ FMaximum
*p = maximum(old, v) maximum matches the behavior of llvm.maximum.
@ UIncWrap
Increment one up to a maximum value.
@ Max
*p = old >signed v ? old : v
@ UMin
*p = old <unsigned v ? old : v
@ FMin
*p = minnum(old, v) minnum matches the behavior of llvm.minnum.
@ UMax
*p = old >unsigned v ? old : v
@ FMaximumNum
*p = maximumnum(old, v) maximumnum matches the behavior of llvm.maximumnum.
@ FMax
*p = maxnum(old, v) maxnum matches the behavior of llvm.maxnum.
@ UDecWrap
Decrement one until a minimum value or zero.
@ FMinimumNum
*p = minimumnum(old, v) minimumnum matches the behavior of llvm.minimumnum.
LLVM Basic Block Representation.
unsigned getNumber() const
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
InstListType::const_iterator const_iterator
LLVM_ABI 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.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Value * getCalledOperand() const
Value * getArgOperand(unsigned i) const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
bool isConvergent() const
Determine if the invoke is convergent.
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
bool isFPPredicate() const
bool isIntPredicate() const
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This is the common base class for constrained floating point intrinsics.
LLVM_ABI std::optional< fp::ExceptionBehavior > getExceptionBehavior() const
LLVM_ABI unsigned getNonMetadataArgCount() const
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
LLVM_ABI bool startsWithDeref() const
Return whether the first element a DW_OP_deref.
ArrayRef< uint64_t > getElements() const
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
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI ~IRTranslatorPass()
LLVM_ABI IRTranslatorPass(CodeGenOptLevel OptLevel)
bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB, std::function< ArrayRef< Register >(const Value &Val)> GetOrCreateVRegs) const
Lower the given inline asm call instruction GetOrCreateVRegs is a callback to materialize a register ...
This instruction inserts a struct field of array element value into an aggregate value.
iterator_range< simple_ilist< DbgRecord >::iterator > getDbgRecordRange() const
Return a range over the DbgRecords attached to this instruction.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static bool getUseExtended()
constexpr bool isScalar() const
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isFloat() const
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
static constexpr LLT token()
Get a low-level token; just a scalar with zero bits (or no size).
static LLT integer(unsigned SizeInBits)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Tracks which library functions to use for a particular subtarget or function.
Value * getPointerOperand()
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this load instruction.
static LocationSize precise(uint64_t Value)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned pred_size() const
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void setSuccProbability(succ_iterator I, BranchProbability Prob)
Set successor probability of a given iterator.
succ_iterator succ_begin()
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
LLVM_ABI void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
LLVM_ABI bool isPredecessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a predecessor of this block.
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
int getStackProtectorIndex() const
Return the index for the stack protector object.
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
Helper class to build MachineInstr.
MachineInstrBuilder buildFPTOUI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOUI_SAT Src0.
MachineInstrBuilder buildFMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildFreeze(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_FREEZE Src.
MachineInstrBuilder buildBr(MachineBasicBlock &Dest)
Build and insert G_BR Dest.
MachineInstrBuilder buildModf(const DstOp &Fract, const DstOp &Int, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Int = G_FMODF Src.
LLVMContext & getContext() const
MachineInstrBuilder buildAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_ADD Op0, Op1.
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
MachineInstrBuilder buildResetFPMode()
Build and insert G_RESET_FPMODE.
MachineInstrBuilder buildNot(const DstOp &Dst, const SrcOp &Src0)
Build and insert a bitwise not, NegOne = G_CONSTANT -1 Res = G_OR Op0, NegOne.
MachineInstrBuilder buildFPTOSI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOSI_SAT Src0.
MachineInstrBuilder buildUCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_UCMP Op0, Op1.
MachineInstrBuilder buildJumpTable(const LLT PtrTy, unsigned JTI)
Build and insert Res = G_JUMP_TABLE JTI.
MachineInstrBuilder buildGetRounding(const DstOp &Dst)
Build and insert Dst = G_GET_ROUNDING.
MachineInstrBuilder buildSCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_SCMP Op0, Op1.
MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope)
Build and insert G_FENCE Ordering, Scope.
MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
MachineInstrBuilder buildFMA(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, const SrcOp &Src2, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FMA Op0, Op1, Op2.
MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_MUL Op0, Op1.
MachineInstrBuilder buildInsertSubvector(const DstOp &Res, const SrcOp &Src0, const SrcOp &Src1, unsigned Index)
Build and insert Res = G_INSERT_SUBVECTOR Src0, Src1, Idx.
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildCast(const DstOp &Dst, const SrcOp &Src)
Build and insert an appropriate cast between two registers of equal size.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
MachineInstrBuilder buildLShr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
MachineInstrBuilder buildSExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildAtomicRMW(unsigned Opcode, const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val, MachineMemOperand &MMO)
Build and insert OldValRes<def> = G_ATOMICRMW_<Opcode> Addr, Val, MMO.
MachineInstrBuilder buildSub(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_SUB Op0, Op1.
MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef< Register > Res, bool HasSideEffects, bool isConvergent)
Build and insert a G_INTRINSIC instruction.
MachineInstrBuilder buildVScale(const DstOp &Res, unsigned MinElts)
Build and insert Res = G_VSCALE MinElts.
MachineInstrBuilder buildSplatBuildVector(const DstOp &Res, const SrcOp &Src)
Build and insert Res = G_BUILD_VECTOR with Src replicated to fill the number of elements.
MachineInstrBuilder buildSetFPMode(const SrcOp &Src)
Build and insert G_SET_FPMODE Src.
MachineInstrBuilder buildIntToPtr(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_INTTOPTR instruction.
MachineInstrBuilder buildIndirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in me...
MachineInstrBuilder buildBuildVector(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ...
MachineInstrBuilder buildConstDbgValue(const Constant &C, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instructions specifying that Variable is given by C (suitably modified b...
MachineInstrBuilder buildBrCond(const SrcOp &Tst, MachineBasicBlock &Dest)
Build and insert G_BRCOND Tst, Dest.
std::optional< MachineInstrBuilder > materializeObjectPtrOffset(Register &Res, Register Op0, const LLT ValueTy, uint64_t Value)
Materialize and insert an instruction with appropriate flags for addressing some offset of an object,...
MachineInstrBuilder buildSetRounding(const SrcOp &Src)
Build and insert G_SET_ROUNDING.
MachineInstrBuilder buildExtractVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_PTR_ADD Op0, Op1.
MachineInstrBuilder buildZExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildExtractVectorElementConstant(const DstOp &Res, const SrcOp &Val, const int Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildShl(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineInstrBuilder buildDirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in Re...
MachineInstrBuilder buildDbgLabel(const MDNode *Label)
Build and insert a DBG_LABEL instructions specifying that Label is given.
MachineInstrBuilder buildBrJT(Register TablePtr, unsigned JTI, Register IndexReg)
Build and insert G_BRJT TablePtr, JTI, IndexReg.
MachineInstrBuilder buildDynStackAlloc(const DstOp &Res, const SrcOp &Size, Align Alignment)
Build and insert Res = G_DYN_STACKALLOC Size, Align.
MachineInstrBuilder buildFIDbgValue(int FI, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in th...
MachineInstrBuilder buildResetFPEnv()
Build and insert G_RESET_FPENV.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
void setDebugLoc(const DebugLoc &DL)
Set the debug location to DL for all the next build instructions.
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
MachineInstrBuilder buildInsertVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Elt, const SrcOp &Idx)
Build and insert Res = G_INSERT_VECTOR_ELT Val, Elt, Idx.
MachineInstrBuilder buildAtomicCmpXchgWithSuccess(const DstOp &OldValRes, const DstOp &SuccessRes, const SrcOp &Addr, const SrcOp &CmpVal, const SrcOp &NewVal, MachineMemOperand &MMO)
Build and insert OldValRes<def>, SuccessRes<def> = / G_ATOMIC_CMPXCHG_WITH_SUCCESS Addr,...
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
MachineInstrBuilder buildBitcast(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_BITCAST Src.
const DebugLoc & getDebugLoc()
Get the current instruction's debug location.
MachineInstrBuilder buildTrap(bool Debug=false)
Build and insert G_TRAP or G_DEBUGTRAP.
MachineInstrBuilder buildFFrexp(const DstOp &Fract, const DstOp &Exp, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Exp = G_FFREXP Src.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildOr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_OR Op0, Op1.
MachineInstrBuilder buildFSincos(const DstOp &Sin, const DstOp &Cos, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Sin, Cos = G_FSINCOS Src.
MachineInstrBuilder buildShuffleVector(const DstOp &Res, const SrcOp &Src1, const SrcOp &Src2, ArrayRef< int > Mask)
Build and insert Res = G_SHUFFLE_VECTOR Src1, Src2, Mask.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildPrefetch(const SrcOp &Addr, unsigned RW, unsigned Locality, unsigned CacheType, MachineMemOperand &MMO)
Build and insert G_PREFETCH Addr, RW, Locality, CacheType.
MachineInstrBuilder buildExtractSubvector(const DstOp &Res, const SrcOp &Src, unsigned Index)
Build and insert Res = G_EXTRACT_SUBVECTOR Src, Idx0.
const DataLayout & getDataLayout() const
MachineInstrBuilder buildBrIndirect(Register Tgt)
Build and insert G_BRINDIRECT Tgt.
MachineInstrBuilder buildSplatVector(const DstOp &Res, const SrcOp &Val)
Build and insert Res = G_SPLAT_VECTOR Val.
MachineInstrBuilder buildStepVector(const DstOp &Res, unsigned Step)
Build and insert Res = G_STEP_VECTOR Step.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_FCMP PredOp0, Op1.
MachineInstrBuilder buildFAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FADD Op0, Op1.
MachineInstrBuilder buildSetFPEnv(const SrcOp &Src)
Build and insert G_SET_FPENV Src.
MachineInstrBuilder buildPtrToInt(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_PTRTOINT instruction.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & 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.
@ MONonTemporal
The memory access is non-temporal.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
static MachineOperand CreateES(const char *SymName, unsigned TargetFlags=0)
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
A set of analyses that are preserved following a run of a transformation pass.
Class to install both of the above.
Wrapper class representing virtual and physical registers.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Encapsulates all of the information needed to generate a stack protector check, and signals to isel w...
MachineBasicBlock * getSuccessMBB()
MachineBasicBlock * getFailureMBB()
constexpr bool empty() const
Check if the string is empty.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
SwitchLowering(FunctionLoweringInfo &funcinfo)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
ExceptionHandling getExceptionModel() const
Return the ExceptionHandling to use.
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 bool isExceptionPointerAndSelectorType(Type *Ty)
Return true if landingpad result type Ty is a struct of an exception pointer (pointer or integer) and...
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
gep_type_iterator gep_type_end(const User *GEP)
LLVM_ABI MachineBasicBlock::iterator findSplitPointForStackProtector(MachineBasicBlock *BB, const TargetInstrInfo &TII)
Find the split point at which to splice the end of BB into its success stack protector check machine ...
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI llvm::SmallVector< int, 16 > createStrideMask(unsigned Start, unsigned Stride, unsigned VF)
Create a stride shuffle mask.
auto reverse(ContainerTy &&C)
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
auto succ_size(const MachineBasicBlock *BB)
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Global
Append to llvm.global_dtors.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
LLVM_ABI llvm::SmallVector< int, 16 > createInterleaveMask(unsigned VF, unsigned NumVecs)
Create an interleave shuffle mask.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
@ Default
Not specified; resolve to the target's default model.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::optional< RoundingMode > convertStrToRoundingMode(StringRef)
Returns a valid RoundingMode enumerator when given a string that is valid as input in constrained int...
gep_type_iterator gep_type_begin(const User *GEP)
LLVM_ABI void computeValueLLTs(const DataLayout &DL, Type &Ty, SmallVectorImpl< LLT > &ValueLLTs, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
computeValueLLTs - Given an LLVM IR type, compute a sequence of LLTs that represent all the individua...
LLVM_ABI GlobalValue * ExtractTypeInfo(Value *V)
ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Pair of physical register and lane mask.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
bool shouldSkipOptimizationForOptBisect(IRUnitRef IR)
MachineBasicBlock * Parent
This structure is used to communicate between SelectionDAGBuilder and SDISel for the code generation ...
BranchProbability TrueProb
MachineBasicBlock * ThisBB
struct PredInfoPair PredInfo
BranchProbability FalseProb
MachineBasicBlock * TrueBB
MachineBasicBlock * FalseBB
Register Reg
The virtual register containing the index of the jump table entry to jump to.
MachineBasicBlock * Default
The MBB of the default bb, which is a successor of the range check MBB.
unsigned JTI
The JumpTableIndex for this jump table in the function.
MachineBasicBlock * MBB
The MBB into which to emit the code for the indirect jump.