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(
353 bool findUnwindDestinations(
366 bool translateCast(
unsigned Opcode,
const User &U,
377 return translateCompare(U, MIRBuilder);
382 return translateCompare(U, MIRBuilder);
387 void finishPendingPhis();
391 bool translateUnaryOp(
unsigned Opcode,
const User &U,
396 bool translateBinaryOp(
unsigned Opcode,
const User &U,
402 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
447 bool lowerJumpTableWorkItem(
456 bool FallthroughUnreachable,
462 bool lowerBitTestWorkItem(
468 bool FallthroughUnreachable);
499 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
502 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
505 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
508 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
511 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
514 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
518 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
521 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
524 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
527 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
530 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
533 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
537 return translatePtrToInt(U, MIRBuilder);
540 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
543 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
546 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
549 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
552 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
555 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
558 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
563 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
567 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
571 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
574 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
577 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
581 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
584 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
587 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
590 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
593 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
629 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
644 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
655 std::unique_ptr<MachineIRBuilder> CurBuilder;
660 std::unique_ptr<MachineIRBuilder> EntryBuilder;
673 std::unique_ptr<OptimizationRemarkEmitter> ORE;
684 bool EnableOpts =
false;
688 bool HasTailCall =
false;
692 bool mayTranslateUserTypes(
const User &U)
const;
699 assert(irt &&
"irt is null!");
702 void addSuccessorWithProb(
705 IRT->addSuccessorWithProb(Src, Dst, Prob);
708 ~GISelSwitchLowering()
override =
default;
714 std::unique_ptr<GISelSwitchLowering> SL;
720 void finalizeFunction();
758 auto Regs = getOrCreateVRegs(Val);
761 assert(Regs.size() == 1 &&
762 "attempt to get single VReg for aggregate or void");
766 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
768 auto &Regs = *VMap.getVRegs(Token);
770 assert(Regs.size() == 1 &&
771 "Expected a single register for convergence tokens.");
775 auto Reg = MRI->createGenericVirtualRegister(
LLT::token());
782 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
786 int getOrCreateFrameIndex(
const AllocaInst &AI);
809 auto RemappedEdge = MachinePreds.find(Edge);
810 if (RemappedEdge != MachinePreds.end())
811 return RemappedEdge->second;
820 void addSuccessorWithProb(
826 : OptLevel(OptLevel) {}
856 "IRTranslator LLVM IR -> MI",
false,
false)
868 MF.getProperties().setFailedISel();
869 bool IsGlobalISelAbortEnabled =
874 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
875 R << (
" (in function: " + MF.getName() +
")").str();
877 if (IsGlobalISelAbortEnabled)
897 DILocationVerifier() =
default;
898 ~DILocationVerifier()
override =
default;
900 const Instruction *getCurrentInst()
const {
return CurrInst; }
901 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
903 void erasingInstr(MachineInstr &
MI)
override {}
904 void changingInstr(MachineInstr &
MI)
override {}
905 void changedInstr(MachineInstr &
MI)
override {}
907 void createdInstr(MachineInstr &
MI)
override {
908 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
913 <<
" was copied to " <<
MI);
919 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
920 (
MI.isDebugInstr())) &&
921 "Line info was not transferred to all instructions");
944IRTranslatorImpl::ValueToVRegInfo::VRegListT &
945IRTranslatorImpl::allocateVRegs(
const Value &Val) {
946 auto VRegsIt = VMap.findVRegs(Val);
947 if (VRegsIt != VMap.vregs_end())
948 return *VRegsIt->second;
949 auto *Regs = VMap.getVRegs(Val);
955 auto *Offsets = VMap.getOffsets(Val);
958 Offsets->empty() ? Offsets :
nullptr);
959 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
965 auto VRegsIt = VMap.findVRegs(Val);
966 if (VRegsIt != VMap.vregs_end())
967 return *VRegsIt->second;
970 return *VMap.getVRegs(Val);
973 auto *VRegs = VMap.getVRegs(Val);
977 "Don't know how to create an empty vreg");
982 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
986 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"GISelFailure",
987 MF->getFunction().getSubprogram(),
988 &MF->getFunction().getEntryBlock());
989 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
997 auto *
Offsets = VMap.getOffsets(Val);
999 Offsets->empty() ? Offsets :
nullptr);
1002 for (
auto Ty : SplitTys)
1003 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
1010 while (
auto Elt =
C.getAggregateElement(Idx++)) {
1011 auto EltRegs = getOrCreateVRegs(*Elt);
1018int IRTranslatorImpl::getOrCreateFrameIndex(
const AllocaInst &AI) {
1019 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
1021 return MapEntry->second;
1027 Size = std::max<uint64_t>(
Size, 1u);
1029 int &FI = MapEntry->second;
1030 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
1037 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
1038 MF->getFrameInfo().setStackID(FI, StackID);
1046 return SI->getAlign();
1048 return LI->getAlign();
1054 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"", &
I);
1055 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
1061 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
1062 assert(
MBB &&
"BasicBlock was not encountered before");
1066void IRTranslatorImpl::addMachineCFGPred(CFGEdge
Edge,
1068 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
1069 MachinePreds[
Edge].push_back(NewPred);
1072bool IRTranslatorImpl::translateBinaryOp(
unsigned Opcode,
const User &U,
1074 if (!mayTranslateUserTypes(U))
1081 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1082 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1094bool IRTranslatorImpl::translateUnaryOp(
unsigned Opcode,
const User &U,
1096 if (!mayTranslateUserTypes(U))
1099 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1110bool IRTranslatorImpl::translateFNeg(
const User &U,
1112 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
1115bool IRTranslatorImpl::translateCompare(
const User &U,
1117 if (!mayTranslateUserTypes(U))
1121 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1122 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1127 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1, Flags);
1135 MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1, Flags);
1140bool IRTranslatorImpl::translateRet(
const User &U,
1144 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
1149 VRegs = getOrCreateVRegs(*Ret);
1152 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
1153 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
1154 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
1160 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
1163void IRTranslatorImpl::emitBranchForMergedCondition(
1172 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
1175 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
1178 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
1179 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
1180 CurBuilder->getDebugLoc(), TProb, FProb);
1181 SL->SwitchCases.push_back(CB);
1187 SwitchCG::CaseBlock CB(
1189 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
1190 SL->SwitchCases.push_back(CB);
1195 return I->getParent() == BB;
1199void IRTranslatorImpl::findMergedConditions(
1204 using namespace PatternMatch;
1205 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
1206 "Expected Opc to be AND/OR");
1212 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
1218 const Value *BOpOp0, *BOpOp1;
1232 if (BOpc == Instruction::And)
1233 BOpc = Instruction::Or;
1234 else if (BOpc == Instruction::Or)
1235 BOpc = Instruction::And;
1241 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
1245 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
1252 MachineBasicBlock *TmpBB =
1256 if (
Opc == Instruction::Or) {
1277 auto NewTrueProb = TProb / 2;
1278 auto NewFalseProb = TProb / 2 + FProb;
1280 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1281 NewFalseProb, InvertCond);
1287 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1288 Probs[1], InvertCond);
1290 assert(
Opc == Instruction::And &&
"Unknown merge op!");
1310 auto NewTrueProb = TProb + FProb / 2;
1311 auto NewFalseProb = FProb / 2;
1313 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1314 NewFalseProb, InvertCond);
1320 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1321 Probs[1], InvertCond);
1325bool IRTranslatorImpl::shouldEmitAsBranches(
1326 const std::vector<SwitchCG::CaseBlock> &Cases) {
1328 if (Cases.size() != 2)
1333 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
1334 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
1335 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
1336 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
1342 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
1343 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
1347 Cases[0].TrueBB == Cases[1].ThisBB)
1350 Cases[0].FalseBB == Cases[1].ThisBB)
1357bool IRTranslatorImpl::translateUncondBr(
const User &U,
1360 auto &CurMBB = MIRBuilder.
getMBB();
1365 MIRBuilder.
buildBr(*Succ0MBB);
1368 for (
const BasicBlock *Succ :
successors(&BrInst))
1373bool IRTranslatorImpl::translateCondBr(
const User &U,
1376 auto &CurMBB = MIRBuilder.
getMBB();
1382 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
1401 using namespace PatternMatch;
1403 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
1404 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
1407 const Value *BOp0, *BOp1;
1409 Opcode = Instruction::And;
1411 Opcode = Instruction::Or;
1415 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
1416 getEdgeProbability(&CurMBB, Succ0MBB),
1417 getEdgeProbability(&CurMBB, Succ1MBB),
1419 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
1422 if (shouldEmitAsBranches(SL->SwitchCases)) {
1424 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
1425 SL->SwitchCases.erase(SL->SwitchCases.begin());
1431 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
1432 MF->erase(SL->SwitchCases[
I].ThisBB);
1434 SL->SwitchCases.clear();
1441 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
1442 CurBuilder->getDebugLoc());
1446 emitSwitchCase(CB, &CurMBB, *CurBuilder);
1453 if (!FuncInfo.BPI) {
1454 Src->addSuccessorWithoutProb(Dst);
1458 Prob = getEdgeProbability(Src, Dst);
1459 Src->addSuccessor(Dst, Prob);
1465 const BasicBlock *SrcBB = Src->getBasicBlock();
1466 const BasicBlock *DstBB = Dst->getBasicBlock();
1467 if (!FuncInfo.BPI) {
1470 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
1471 return BranchProbability(1, SuccSize);
1473 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
1477 using namespace SwitchCG;
1480 BranchProbabilityInfo *BPI = FuncInfo.BPI;
1482 Clusters.reserve(
SI.getNumCases());
1483 for (
const auto &
I :
SI.cases()) {
1484 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
1485 assert(Succ &&
"Could not find successor mbb in mapping");
1486 const ConstantInt *CaseVal =
I.getCaseValue();
1487 BranchProbability Prob =
1489 : BranchProbability(1,
SI.getNumCases() + 1);
1490 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
1493 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
1500 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
1503 if (Clusters.empty()) {
1510 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
1511 SL->findBitTestClusters(Clusters, &SI);
1514 dbgs() <<
"Case clusters: ";
1515 for (
const CaseCluster &
C : Clusters) {
1516 if (
C.Kind == CC_JumpTable)
1518 if (
C.Kind == CC_BitTests)
1521 C.Low->getValue().print(
dbgs(),
true);
1522 if (
C.Low !=
C.High) {
1524 C.High->getValue().print(
dbgs(),
true);
1531 assert(!Clusters.empty());
1535 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
1536 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
1538 while (!WorkList.empty()) {
1539 SwitchWorkListItem
W = WorkList.pop_back_val();
1541 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
1543 if (NumClusters > 3 &&
1546 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
1550 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
1560 using namespace SwitchCG;
1561 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
1562 "Clusters not sorted?");
1563 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
1565 auto [LastLeft, FirstRight, LeftProb, RightProb] =
1566 SL->computeSplitWorkItemInfo(W);
1571 assert(PivotCluster >
W.FirstCluster);
1572 assert(PivotCluster <=
W.LastCluster);
1577 const ConstantInt *Pivot = PivotCluster->Low;
1586 MachineBasicBlock *LeftMBB;
1587 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
1588 FirstLeft->Low ==
W.GE &&
1589 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
1590 LeftMBB = FirstLeft->MBB;
1592 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1593 FuncInfo.MF->
insert(BBI, LeftMBB);
1595 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
1601 MachineBasicBlock *RightMBB;
1602 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
1603 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
1604 RightMBB = FirstRight->MBB;
1606 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1607 FuncInfo.MF->
insert(BBI, RightMBB);
1609 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
1617 if (
W.MBB == SwitchMBB)
1618 emitSwitchCase(CB, SwitchMBB, MIB);
1620 SL->SwitchCases.push_back(CB);
1626 assert(JT.
Reg &&
"Should lower JT Header first!");
1641 MachineIRBuilder MIB(*HeaderBB->
getParent());
1648 Register SwitchOpReg = getOrCreateVReg(SValue);
1650 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
1655 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
1669 auto Cst = getOrCreateVReg(
1709 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
1723 "Can only handle SLE ranges");
1734 const LLT CmpTy = MRI->getType(CmpOpReg);
1735 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1761bool IRTranslatorImpl::lowerJumpTableWorkItem(
1767 using namespace SwitchCG;
1770 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1771 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1772 BranchProbability DefaultProb =
W.DefaultProb;
1775 MachineBasicBlock *JumpMBB = JT->
MBB;
1776 CurMF->
insert(BBI, JumpMBB);
1786 auto JumpProb =
I->Prob;
1787 auto FallthroughProb = UnhandledProbs;
1795 if (*SI == DefaultMBB) {
1796 JumpProb += DefaultProb / 2;
1797 FallthroughProb -= DefaultProb / 2;
1802 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1807 if (FallthroughUnreachable)
1808 JTH->FallthroughUnreachable =
true;
1810 if (!JTH->FallthroughUnreachable)
1811 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1812 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1817 JTH->HeaderBB = CurMBB;
1821 if (CurMBB == SwitchMBB) {
1822 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1824 JTH->Emitted =
true;
1828bool IRTranslatorImpl::lowerSwitchRangeWorkItem(
1833 using namespace SwitchCG;
1836 if (
I->Low ==
I->High) {
1852 CaseBlock CB(Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1855 emitSwitchCase(CB, SwitchMBB, MIB);
1861 MachineIRBuilder &MIB = *CurBuilder;
1865 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1867 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1869 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1874 LLT MaskTy = SwitchOpTy;
1880 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1889 Register SubReg = RangeSub.getReg(0);
1890 if (SwitchOpTy != MaskTy)
1896 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1898 if (!
B.FallthroughUnreachable)
1899 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1900 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1904 if (!
B.FallthroughUnreachable) {
1908 RangeSub, RangeCst);
1922 MachineIRBuilder &MIB = *CurBuilder;
1928 if (PopCount == 1) {
1931 auto MaskTrailingZeros =
1936 }
else if (PopCount == BB.
Range) {
1938 auto MaskTrailingOnes =
1946 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1950 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1957 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1959 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1977bool IRTranslatorImpl::lowerBitTestWorkItem(
1983 bool FallthroughUnreachable) {
1984 using namespace SwitchCG;
1987 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
1989 for (BitTestCase &BTC : BTB->Cases)
1990 CurMF->
insert(BBI, BTC.ThisBB);
1993 BTB->Parent = CurMBB;
1994 BTB->Default = Fallthrough;
1996 BTB->DefaultProb = UnhandledProbs;
2000 if (!BTB->ContiguousRange) {
2001 BTB->Prob += DefaultProb / 2;
2002 BTB->DefaultProb -= DefaultProb / 2;
2005 if (FallthroughUnreachable)
2006 BTB->FallthroughUnreachable =
true;
2009 if (CurMBB == SwitchMBB) {
2010 emitBitTestHeader(*BTB, SwitchMBB);
2011 BTB->Emitted =
true;
2021 using namespace SwitchCG;
2023 MachineBasicBlock *NextMBB =
nullptr;
2025 if (++BBI != FuncInfo.MF->end())
2034 [](
const CaseCluster &a,
const CaseCluster &b) {
2035 return a.Prob != b.Prob
2037 : a.Low->getValue().slt(b.Low->getValue());
2042 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
2044 if (
I->Prob >
W.LastCluster->Prob)
2046 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
2054 BranchProbability DefaultProb =
W.DefaultProb;
2055 BranchProbability UnhandledProbs = DefaultProb;
2056 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
2057 UnhandledProbs +=
I->Prob;
2059 MachineBasicBlock *CurMBB =
W.MBB;
2060 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
2061 bool FallthroughUnreachable =
false;
2062 MachineBasicBlock *Fallthrough;
2063 if (
I ==
W.LastCluster) {
2065 Fallthrough = DefaultMBB;
2070 CurMF->
insert(BBI, Fallthrough);
2072 UnhandledProbs -=
I->Prob;
2076 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2077 DefaultProb, UnhandledProbs,
I, Fallthrough,
2078 FallthroughUnreachable)) {
2086 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2087 UnhandledProbs,
I, Fallthrough,
2088 FallthroughUnreachable)) {
2095 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
2096 FallthroughUnreachable, UnhandledProbs,
2097 CurMBB, MIB, SwitchMBB)) {
2104 CurMBB = Fallthrough;
2110bool IRTranslatorImpl::translateIndirectBr(
const User &U,
2118 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
2119 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
2120 for (
const BasicBlock *Succ :
successors(&BrInst)) {
2124 if (!AddedSuccessors.
insert(Succ).second)
2140bool IRTranslatorImpl::translateLoad(
const User &U,
2143 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
2154 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
2156 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
2162 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
2164 if (AA->pointsToConstantMemory(
2171 if (Regs.
size() == 1) {
2172 auto *MMO = MF->getMachineMemOperand(
2174 MRI->getType(Regs[0]), getMemOpAlign(LI),
2175 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
2181 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
2182 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
2184 for (
unsigned i = 0; i < Regs.
size(); ++i) {
2189 Align BaseAlign = getMemOpAlign(LI);
2191 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
2194 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
2200bool IRTranslatorImpl::translateStore(
const User &U,
2203 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
2209 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
2210 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
2212 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
2213 SI.getPointerOperand());
2220 if (Vals.
size() == 1) {
2221 auto *MMO = MF->getMachineMemOperand(
2222 MachinePointerInfo(
SI.getPointerOperand()), Flags,
2223 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
2224 SI.getSyncScopeID(),
SI.getOrdering());
2229 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
2230 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
2232 for (
unsigned i = 0; i < Vals.
size(); ++i) {
2236 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
2237 Align BaseAlign = getMemOpAlign(SI);
2238 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
2241 SI.getSyncScopeID(),
SI.getOrdering());
2248 const Value *Src = U.getOperand(0);
2254 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
2257 for (
auto Idx : EVI->indices())
2258 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2260 for (
auto Idx : IVI->indices())
2261 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2267 DL.getIndexedOffsetInType(Src->getType(), Indices));
2270bool IRTranslatorImpl::translateExtractValue(
const User &U,
2272 const Value *Src =
U.getOperand(0);
2275 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
2277 auto &DstRegs = allocateVRegs(U);
2279 for (
unsigned i = 0; i < DstRegs.size(); ++i)
2280 DstRegs[i] = SrcRegs[Idx++];
2285bool IRTranslatorImpl::translateInsertValue(
const User &U,
2287 const Value *Src =
U.getOperand(0);
2289 auto &DstRegs = allocateVRegs(U);
2290 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
2293 auto *InsertedIt = InsertedRegs.
begin();
2295 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
2296 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
2297 DstRegs[i] = *InsertedIt++;
2299 DstRegs[i] = SrcRegs[i];
2305bool IRTranslatorImpl::translateSelect(
const User &U,
2307 Register Tst = getOrCreateVReg(*
U.getOperand(0));
2316 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
2317 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
2323bool IRTranslatorImpl::translateCopy(
const User &U,
const Value &V,
2325 return translateCopy(U, getOrCreateVReg(V), MIRBuilder);
2328bool IRTranslatorImpl::translateCopy(
const User &U,
Register Src,
2330 auto &Regs = *VMap.getVRegs(U);
2332 Regs.push_back(Src);
2341bool IRTranslatorImpl::translateBitCast(
const User &U,
2343 Type *SrcTy =
U.getOperand(0)->getType();
2344 Type *DstTy =
U.getType();
2351 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
2353 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
2362 "only byte types can be bitcast to or from pointers");
2364 LLT IntTy =
getLLTForType(*DL->getIntPtrType(PtrIRTy), *DL);
2365 Register Src = getOrCreateVReg(*
U.getOperand(0));
2367 if (MRI->getType(Src) != IntTy && MRI->getType(Dst) != IntTy)
2373 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
2376bool IRTranslatorImpl::translateCast(
unsigned Opcode,
const User &U,
2378 if (!mayTranslateUserTypes(U))
2391bool IRTranslatorImpl::translateGetElementPtr(
const User &U,
2393 Value &Op0 = *
U.getOperand(0);
2397 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
2400 uint32_t PtrAddFlags = 0;
2406 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
2416 unsigned VectorWidth = 0;
2420 bool WantSplatVector =
false;
2424 WantSplatVector = VectorWidth > 1;
2428 return translateCopy(U, BaseReg, MIRBuilder);
2432 if (WantSplatVector && !PtrTy.
isVector()) {
2439 OffsetIRTy = DL->getIndexType(PtrIRTy);
2446 const Value *
Idx = GTI.getOperand();
2447 if (StructType *StTy = GTI.getStructTypeOrNull()) {
2449 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
2452 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
2457 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
2458 Offset += ElementSize * *Val;
2467 PtrAddFlagsWithConst(
Offset))
2472 Register IdxReg = getOrCreateVReg(*Idx);
2473 LLT IdxTy = MRI->getType(IdxReg);
2474 if (IdxTy != OffsetTy) {
2475 if (!IdxTy.
isVector() && WantSplatVector) {
2488 if (ElementSize != 1) {
2499 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
2502 GepOffsetReg = IdxReg;
2506 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
2515 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
2516 PtrAddFlagsWithConst(
Offset));
2520 return translateCopy(U, BaseReg, MIRBuilder);
2523bool IRTranslatorImpl::translateMemFunc(
const CallInst &CI,
2533 unsigned MinPtrSize = UINT_MAX;
2534 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
2535 Register SrcReg = getOrCreateVReg(**AI);
2536 LLT SrcTy = MRI->getType(SrcReg);
2538 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
2546 if (MRI->getType(SizeOpReg) != SizeTy)
2558 ConstantInt *CopySize =
nullptr;
2561 DstAlign = MCI->getDestAlign().valueOrOne();
2562 SrcAlign = MCI->getSourceAlign().valueOrOne();
2565 DstAlign = MMI->getDestAlign().valueOrOne();
2566 SrcAlign = MMI->getSourceAlign().valueOrOne();
2570 DstAlign = MSI->getDestAlign().valueOrOne();
2573 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
2574 Opcode != TargetOpcode::G_MEMSET_INLINE) {
2590 if (AA && CopySize &&
2591 AA->pointsToConstantMemory(MemoryLocation(
2601 ICall.addMemOperand(
2602 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
2603 StoreFlags, 1, DstAlign, AAInfo));
2604 if (Opcode != TargetOpcode::G_MEMSET &&
2605 Opcode != TargetOpcode::G_MEMSET_INLINE)
2606 ICall.addMemOperand(MF->getMachineMemOperand(
2607 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
2612bool IRTranslatorImpl::translateTrap(
const CallInst &CI,
2615 StringRef TrapFuncName =
2616 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
2617 if (TrapFuncName.
empty()) {
2618 if (Opcode == TargetOpcode::G_UBSANTRAP) {
2627 CallLowering::CallLoweringInfo
Info;
2628 if (Opcode == TargetOpcode::G_UBSANTRAP)
2635 return CLI->lowerCall(MIRBuilder, Info);
2638bool IRTranslatorImpl::translateVectorInterleave2Intrinsic(
2641 "This function can only be called on the interleave2 intrinsic!");
2645 Register Res = getOrCreateVReg(CI);
2647 LLT OpTy = MRI->getType(Op0);
2654bool IRTranslatorImpl::translateVectorDeinterleave2Intrinsic(
2657 "This function can only be called on the deinterleave2 intrinsic!");
2664 LLT ResTy = MRI->getType(Res[0]);
2681void IRTranslatorImpl::getStackGuard(
Register DstReg,
2684 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
2687 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
2692 const TargetInstrInfo &
TII = *MF->getSubtarget().getInstrInfo();
2693 MRI->setRegClass(DstReg,
2694 TII.getRegClass(
TII.get(TargetOpcode::LOAD_STACK_GUARD), 0));
2696 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
2698 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
2699 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
2701 MachinePointerInfo MPInfo(
Global);
2704 MachineMemOperand *MemRef = MF->getMachineMemOperand(
2705 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
2706 MIB.setMemRefs({MemRef});
2709bool IRTranslatorImpl::translateOverflowIntrinsic(
2713 Op, {ResRegs[0], ResRegs[1]},
2719bool IRTranslatorImpl::translateFixedPointIntrinsic(
2721 Register Dst = getOrCreateVReg(CI);
2729unsigned IRTranslatorImpl::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
2733 case Intrinsic::acos:
2734 return TargetOpcode::G_FACOS;
2735 case Intrinsic::asin:
2736 return TargetOpcode::G_FASIN;
2737 case Intrinsic::atan:
2738 return TargetOpcode::G_FATAN;
2739 case Intrinsic::atan2:
2740 return TargetOpcode::G_FATAN2;
2741 case Intrinsic::bswap:
2742 return TargetOpcode::G_BSWAP;
2743 case Intrinsic::bitreverse:
2744 return TargetOpcode::G_BITREVERSE;
2745 case Intrinsic::clmul:
2746 return TargetOpcode::G_CLMUL;
2747 case Intrinsic::fshl:
2748 return TargetOpcode::G_FSHL;
2749 case Intrinsic::fshr:
2750 return TargetOpcode::G_FSHR;
2751 case Intrinsic::ceil:
2752 return TargetOpcode::G_FCEIL;
2753 case Intrinsic::cos:
2754 return TargetOpcode::G_FCOS;
2755 case Intrinsic::cosh:
2756 return TargetOpcode::G_FCOSH;
2757 case Intrinsic::ctpop:
2758 return TargetOpcode::G_CTPOP;
2759 case Intrinsic::smulh:
2760 return TargetOpcode::G_SMULH;
2761 case Intrinsic::umulh:
2762 return TargetOpcode::G_UMULH;
2763 case Intrinsic::exp:
2764 return TargetOpcode::G_FEXP;
2765 case Intrinsic::exp2:
2766 return TargetOpcode::G_FEXP2;
2767 case Intrinsic::exp10:
2768 return TargetOpcode::G_FEXP10;
2769 case Intrinsic::fabs:
2770 return TargetOpcode::G_FABS;
2771 case Intrinsic::copysign:
2772 return TargetOpcode::G_FCOPYSIGN;
2773 case Intrinsic::minnum:
2774 return TargetOpcode::G_FMINNUM;
2775 case Intrinsic::maxnum:
2776 return TargetOpcode::G_FMAXNUM;
2777 case Intrinsic::minimum:
2778 return TargetOpcode::G_FMINIMUM;
2779 case Intrinsic::maximum:
2780 return TargetOpcode::G_FMAXIMUM;
2781 case Intrinsic::minimumnum:
2782 return TargetOpcode::G_FMINIMUMNUM;
2783 case Intrinsic::maximumnum:
2784 return TargetOpcode::G_FMAXIMUMNUM;
2785 case Intrinsic::canonicalize:
2786 return TargetOpcode::G_FCANONICALIZE;
2787 case Intrinsic::floor:
2788 return TargetOpcode::G_FFLOOR;
2789 case Intrinsic::fma:
2790 return TargetOpcode::G_FMA;
2791 case Intrinsic::log:
2792 return TargetOpcode::G_FLOG;
2793 case Intrinsic::log2:
2794 return TargetOpcode::G_FLOG2;
2795 case Intrinsic::log10:
2796 return TargetOpcode::G_FLOG10;
2797 case Intrinsic::ldexp:
2798 return TargetOpcode::G_FLDEXP;
2799 case Intrinsic::nearbyint:
2800 return TargetOpcode::G_FNEARBYINT;
2801 case Intrinsic::pow:
2802 return TargetOpcode::G_FPOW;
2803 case Intrinsic::powi:
2804 return TargetOpcode::G_FPOWI;
2805 case Intrinsic::rint:
2806 return TargetOpcode::G_FRINT;
2807 case Intrinsic::round:
2808 return TargetOpcode::G_INTRINSIC_ROUND;
2809 case Intrinsic::roundeven:
2810 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2811 case Intrinsic::sin:
2812 return TargetOpcode::G_FSIN;
2813 case Intrinsic::sinh:
2814 return TargetOpcode::G_FSINH;
2815 case Intrinsic::sqrt:
2816 return TargetOpcode::G_FSQRT;
2817 case Intrinsic::tan:
2818 return TargetOpcode::G_FTAN;
2819 case Intrinsic::tanh:
2820 return TargetOpcode::G_FTANH;
2821 case Intrinsic::trunc:
2822 return TargetOpcode::G_INTRINSIC_TRUNC;
2823 case Intrinsic::readcyclecounter:
2824 return TargetOpcode::G_READCYCLECOUNTER;
2825 case Intrinsic::readsteadycounter:
2826 return TargetOpcode::G_READSTEADYCOUNTER;
2827 case Intrinsic::ptrmask:
2828 return TargetOpcode::G_PTRMASK;
2829 case Intrinsic::lrint:
2830 return TargetOpcode::G_INTRINSIC_LRINT;
2831 case Intrinsic::llrint:
2832 return TargetOpcode::G_INTRINSIC_LLRINT;
2834 case Intrinsic::vector_reduce_fmin:
2835 return TargetOpcode::G_VECREDUCE_FMIN;
2836 case Intrinsic::vector_reduce_fmax:
2837 return TargetOpcode::G_VECREDUCE_FMAX;
2838 case Intrinsic::vector_reduce_fminimum:
2839 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2840 case Intrinsic::vector_reduce_fmaximum:
2841 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2842 case Intrinsic::vector_reduce_fminimumnum:
2843 return TargetOpcode::G_VECREDUCE_FMINIMUMNUM;
2844 case Intrinsic::vector_reduce_fmaximumnum:
2845 return TargetOpcode::G_VECREDUCE_FMAXIMUMNUM;
2846 case Intrinsic::vector_reduce_add:
2847 return TargetOpcode::G_VECREDUCE_ADD;
2848 case Intrinsic::vector_reduce_mul:
2849 return TargetOpcode::G_VECREDUCE_MUL;
2850 case Intrinsic::vector_reduce_and:
2851 return TargetOpcode::G_VECREDUCE_AND;
2852 case Intrinsic::vector_reduce_or:
2853 return TargetOpcode::G_VECREDUCE_OR;
2854 case Intrinsic::vector_reduce_xor:
2855 return TargetOpcode::G_VECREDUCE_XOR;
2856 case Intrinsic::vector_reduce_smax:
2857 return TargetOpcode::G_VECREDUCE_SMAX;
2858 case Intrinsic::vector_reduce_smin:
2859 return TargetOpcode::G_VECREDUCE_SMIN;
2860 case Intrinsic::vector_reduce_umax:
2861 return TargetOpcode::G_VECREDUCE_UMAX;
2862 case Intrinsic::vector_reduce_umin:
2863 return TargetOpcode::G_VECREDUCE_UMIN;
2864 case Intrinsic::experimental_vector_compress:
2865 return TargetOpcode::G_VECTOR_COMPRESS;
2866 case Intrinsic::lround:
2867 return TargetOpcode::G_LROUND;
2868 case Intrinsic::llround:
2869 return TargetOpcode::G_LLROUND;
2870 case Intrinsic::get_fpenv:
2871 return TargetOpcode::G_GET_FPENV;
2872 case Intrinsic::get_fpmode:
2873 return TargetOpcode::G_GET_FPMODE;
2878bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2882 unsigned Op = getSimpleIntrinsicOpcode(ID);
2890 for (
const auto &Arg : CI.
args())
2893 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2901 case Intrinsic::experimental_constrained_fadd:
2902 return TargetOpcode::G_STRICT_FADD;
2903 case Intrinsic::experimental_constrained_fsub:
2904 return TargetOpcode::G_STRICT_FSUB;
2905 case Intrinsic::experimental_constrained_fmul:
2906 return TargetOpcode::G_STRICT_FMUL;
2907 case Intrinsic::experimental_constrained_fdiv:
2908 return TargetOpcode::G_STRICT_FDIV;
2909 case Intrinsic::experimental_constrained_frem:
2910 return TargetOpcode::G_STRICT_FREM;
2911 case Intrinsic::experimental_constrained_fma:
2912 return TargetOpcode::G_STRICT_FMA;
2913 case Intrinsic::experimental_constrained_sqrt:
2914 return TargetOpcode::G_STRICT_FSQRT;
2915 case Intrinsic::experimental_constrained_ldexp:
2916 return TargetOpcode::G_STRICT_FLDEXP;
2917 case Intrinsic::experimental_constrained_fcmp:
2918 return TargetOpcode::G_STRICT_FCMP;
2919 case Intrinsic::experimental_constrained_fcmps:
2920 return TargetOpcode::G_STRICT_FCMPS;
2926bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2938 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2939 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2941 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2942 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2945 .addPredicate(FPCmp->getPredicate())
2959std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2960 auto VRegs = getOrCreateVRegs(Arg);
2961 if (VRegs.
size() != 1)
2962 return std::nullopt;
2965 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2966 if (!VRegDef || !VRegDef->isCopy())
2967 return std::nullopt;
2968 return VRegDef->getOperand(1).getReg().asMCReg();
2971bool IRTranslatorImpl::translateIfEntryValueArgument(
2982 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2984 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2985 <<
": expression is entry_value but "
2986 <<
"couldn't find a physical register\n");
2994 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
3006 case Intrinsic::experimental_convergence_anchor:
3007 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
3008 case Intrinsic::experimental_convergence_entry:
3009 return TargetOpcode::CONVERGENCECTRL_ENTRY;
3010 case Intrinsic::experimental_convergence_loop:
3011 return TargetOpcode::CONVERGENCECTRL_LOOP;
3015bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
3018 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3021 if (ID == Intrinsic::experimental_convergence_loop) {
3023 assert(Bundle &&
"Expected a convergence control token.");
3025 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3032bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3036 if (ORE->enabled()) {
3038 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3046 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3052 case Intrinsic::lifetime_start:
3053 case Intrinsic::lifetime_end: {
3056 MF->getFunction().hasOptNone())
3059 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3060 : TargetOpcode::LIFETIME_END;
3069 case Intrinsic::fake_use: {
3071 for (
const auto &Arg : CI.
args())
3073 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3074 MF->setHasFakeUses(
true);
3077 case Intrinsic::dbg_declare: {
3084 case Intrinsic::dbg_label: {
3090 "Expected inlined-at fields to agree");
3095 case Intrinsic::vaend:
3099 case Intrinsic::vastart: {
3101 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3104 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3105 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3107 ListSize, Alignment));
3110 case Intrinsic::dbg_assign:
3117 case Intrinsic::dbg_value: {
3124 case Intrinsic::uadd_with_overflow:
3125 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3126 case Intrinsic::sadd_with_overflow:
3127 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3128 case Intrinsic::usub_with_overflow:
3129 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3130 case Intrinsic::ssub_with_overflow:
3131 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3132 case Intrinsic::umul_with_overflow:
3133 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3134 case Intrinsic::smul_with_overflow:
3135 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3136 case Intrinsic::uadd_sat:
3137 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3138 case Intrinsic::sadd_sat:
3139 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3140 case Intrinsic::usub_sat:
3141 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3142 case Intrinsic::ssub_sat:
3143 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3144 case Intrinsic::ushl_sat:
3145 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3146 case Intrinsic::sshl_sat:
3147 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3148 case Intrinsic::umin:
3149 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3150 case Intrinsic::umax:
3151 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3152 case Intrinsic::smin:
3153 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3154 case Intrinsic::smax:
3155 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3156 case Intrinsic::abs:
3158 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3159 case Intrinsic::smul_fix:
3160 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3161 case Intrinsic::umul_fix:
3162 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3163 case Intrinsic::smul_fix_sat:
3164 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3165 case Intrinsic::umul_fix_sat:
3166 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3167 case Intrinsic::sdiv_fix:
3168 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3169 case Intrinsic::udiv_fix:
3170 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3171 case Intrinsic::sdiv_fix_sat:
3172 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3173 case Intrinsic::udiv_fix_sat:
3174 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3175 case Intrinsic::fmuladd: {
3176 Register Dst = getOrCreateVReg(CI);
3180 if (TLI->isFMAFasterThanFMulAndFAdd(*MF,
3181 TLI->getValueType(*DL, CI.
getType()))) {
3184 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3195 case Intrinsic::frexp: {
3202 case Intrinsic::modf: {
3204 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3209 case Intrinsic::sincos: {
3216 case Intrinsic::fptosi_sat:
3220 case Intrinsic::fptoui_sat:
3224 case Intrinsic::memcpy_inline:
3225 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3226 case Intrinsic::memcpy:
3227 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3228 case Intrinsic::memmove:
3229 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3230 case Intrinsic::memset:
3231 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3232 case Intrinsic::memset_inline:
3233 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3234 case Intrinsic::eh_typeid_for: {
3237 unsigned TypeID = MF->getTypeIDFor(GV);
3241 case Intrinsic::objectsize:
3244 case Intrinsic::is_constant:
3247 case Intrinsic::stackguard:
3248 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3250 case Intrinsic::stackprotector: {
3253 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3254 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3255 getStackGuard(GuardVal, MIRBuilder);
3260 int FI = getOrCreateFrameIndex(*Slot);
3261 MF->getFrameInfo().setStackProtectorIndex(FI);
3264 GuardVal, getOrCreateVReg(*Slot),
3271 case Intrinsic::stacksave: {
3272 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3275 case Intrinsic::stackrestore: {
3276 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3280 case Intrinsic::cttz:
3281 case Intrinsic::ctlz: {
3283 bool isTrailing =
ID == Intrinsic::cttz;
3284 unsigned Opcode = isTrailing ? Cst->
isZero()
3285 ? TargetOpcode::G_CTTZ
3286 : TargetOpcode::G_CTTZ_ZERO_POISON
3287 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3288 : TargetOpcode::G_CTLZ_ZERO_POISON;
3289 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3293 case Intrinsic::invariant_start: {
3297 case Intrinsic::invariant_end:
3299 case Intrinsic::expect:
3300 case Intrinsic::expect_with_probability:
3301 case Intrinsic::annotation:
3302 case Intrinsic::ptr_annotation:
3303 case Intrinsic::launder_invariant_group:
3304 case Intrinsic::threadlocal_address: {
3306 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3310 case Intrinsic::assume:
3311 case Intrinsic::experimental_noalias_scope_decl:
3312 case Intrinsic::var_annotation:
3313 case Intrinsic::sideeffect:
3316 case Intrinsic::read_volatile_register:
3317 case Intrinsic::read_register: {
3320 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3324 case Intrinsic::write_register: {
3326 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3331 case Intrinsic::localescape: {
3332 MachineBasicBlock &EntryMBB = MF->front();
3337 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3344 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3357 case Intrinsic::vector_reduce_fadd:
3358 case Intrinsic::vector_reduce_fmul: {
3361 Register Dst = getOrCreateVReg(CI);
3367 Opc =
ID == Intrinsic::vector_reduce_fadd
3368 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3369 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3370 if (!MRI->getType(VecSrc).isVector())
3371 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3372 : TargetOpcode::G_FMUL;
3380 if (ID == Intrinsic::vector_reduce_fadd) {
3381 Opc = TargetOpcode::G_VECREDUCE_FADD;
3382 ScalarOpc = TargetOpcode::G_FADD;
3384 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3385 ScalarOpc = TargetOpcode::G_FMUL;
3387 LLT DstTy = MRI->getType(Dst);
3390 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3395 case Intrinsic::trap:
3396 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3397 case Intrinsic::debugtrap:
3398 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3399 case Intrinsic::ubsantrap:
3400 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3401 case Intrinsic::allow_runtime_check:
3402 case Intrinsic::allow_ubsan_check:
3403 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3406 case Intrinsic::amdgcn_cs_chain:
3407 case Intrinsic::amdgcn_call_whole_wave:
3408 return translateCallBase(CI, MIRBuilder);
3409 case Intrinsic::fptrunc_round: {
3414 std::optional<RoundingMode> RoundMode =
3419 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3420 {getOrCreateVReg(CI)},
3422 .addImm((
int)*RoundMode);
3426 case Intrinsic::is_fpclass: {
3431 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3432 {getOrCreateVReg(*FpValue)})
3437 case Intrinsic::set_fpenv: {
3442 case Intrinsic::reset_fpenv:
3445 case Intrinsic::set_fpmode: {
3450 case Intrinsic::reset_fpmode:
3453 case Intrinsic::get_rounding:
3456 case Intrinsic::set_rounding:
3459 case Intrinsic::vscale: {
3463 case Intrinsic::scmp:
3464 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3468 case Intrinsic::ucmp:
3469 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3473 case Intrinsic::vector_extract:
3474 return translateExtractVector(CI, MIRBuilder);
3475 case Intrinsic::vector_insert:
3476 return translateInsertVector(CI, MIRBuilder);
3477 case Intrinsic::stepvector: {
3481 case Intrinsic::prefetch: {
3488 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3491 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3497 case Intrinsic::speculative_load: {
3501 Register Dst = getOrCreateVReg(CI);
3503 Flags |= TLI->getTargetMMOFlags(CI);
3506 if (CI.
hasMetadata(LLVMContext::MD_invariant_load))
3508 auto *MMO = MF->getMachineMemOperand(
3509 MachinePointerInfo(Ptr), Flags, MRI->getType(Dst),
3511 MIRBuilder.
buildLoad(Dst, getOrCreateVReg(*Ptr), *MMO);
3515 case Intrinsic::vector_interleave2:
3516 case Intrinsic::vector_deinterleave2: {
3524 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3526 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3529#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3530 case Intrinsic::INTRINSIC:
3531#include "llvm/IR/ConstrainedOps.def"
3534 case Intrinsic::experimental_convergence_anchor:
3535 case Intrinsic::experimental_convergence_entry:
3536 case Intrinsic::experimental_convergence_loop:
3537 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3538 case Intrinsic::reloc_none: {
3541 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3549bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3551 if (!mayTranslateUserTypes(CB))
3554 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3558 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3563 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3566bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3573 for (
const auto &Arg : CB.
args()) {
3575 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3577 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3578 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3579 &CB, &MIRBuilder.
getMBB(), Arg));
3582 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3585 Args.push_back(getOrCreateVRegs(*Arg));
3589 if (ORE->enabled()) {
3591 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3597 std::optional<CallLowering::PtrAuthInfo> PAI;
3602 const Value *
Key = Bundle->Inputs[0];
3609 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3610 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3612 Register DiscReg = getOrCreateVReg(*Discriminator);
3620 const auto &Token = *Bundle->Inputs[0].get();
3621 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3627 bool Success = CLI->lowerCall(
3628 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3633 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3634 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3641bool IRTranslatorImpl::translateCall(
const User &U,
3643 if (!mayTranslateUserTypes(U))
3651 if (
F && (
F->hasDLLImportStorageClass() ||
3652 (MF->getTarget().getTargetTriple().isOSWindows() &&
3653 F->hasExternalWeakLinkage())))
3665 return translateInlineAsm(CI, MIRBuilder);
3669 if (translateCallBase(CI, MIRBuilder)) {
3678 if (!MF->getSubtarget().isIntrinsicSupported(ID))
3679 return handleUnsupportedIntrinsic(CI, ID, MIRBuilder);
3681 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3685 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3687 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3690bool IRTranslatorImpl::handleUnsupportedIntrinsic(
3693 F.getContext().diagnose(
3694 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3705bool IRTranslatorImpl::translateIntrinsic(
3708 if (!MF->getSubtarget().isIntrinsicSupported(ID))
3709 return handleUnsupportedIntrinsic(CB, ID, MIRBuilder);
3713 ResultRegs = getOrCreateVRegs(CB);
3717 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3728 assert(CI->getBitWidth() <= 64 &&
3729 "large intrinsic immediates not handled");
3730 MIB.
addImm(CI->getSExtValue());
3735 auto *MD = MDVal->getMetadata();
3739 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3746 if (VRegs.
size() > 1)
3753 for (
const auto &Info : TgtMemIntrinsicInfos) {
3756 LLT MemTy =
Info.memVT.isSimple()
3758 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3762 MachinePointerInfo MPI;
3764 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3765 }
else if (
Info.fallbackAddressSpace) {
3766 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3775 auto *Token = Bundle->Inputs[0].get();
3776 Register TokenReg = getOrCreateVReg(*Token);
3787bool IRTranslatorImpl::findUnwindDestinations(
3799 if (IsWasmCXX || IsWasmD) {
3809 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3815 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3816 UnwindDests.back().first->setIsEHScopeEntry();
3817 UnwindDests.back().first->setIsEHFuncletEntry();
3822 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3823 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3825 if (IsMSVCCXX || IsCoreCLR)
3826 UnwindDests.back().first->setIsEHFuncletEntry();
3828 UnwindDests.back().first->setIsEHScopeEntry();
3830 NewEHPadBB = CatchSwitch->getUnwindDest();
3835 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3836 if (BPI && NewEHPadBB)
3838 EHPadBB = NewEHPadBB;
3843bool IRTranslatorImpl::translateInvoke(
const User &U,
3846 MCContext &
Context = MF->getContext();
3851 const Function *Fn =
I.getCalledFunction();
3858 if (
I.hasDeoptState())
3872 (MF->getTarget().getTargetTriple().isOSWindows() &&
3876 bool LowerInlineAsm =
I.isInlineAsm();
3877 bool NeedEHLabel =
true;
3883 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3884 BeginSymbol =
Context.createTempSymbol();
3888 if (LowerInlineAsm) {
3889 if (!translateInlineAsm(
I, MIRBuilder))
3891 }
else if (!translateCallBase(
I, MIRBuilder))
3896 EndSymbol =
Context.createTempSymbol();
3901 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3902 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3903 BranchProbability EHPadBBProb =
3907 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3910 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3911 &ReturnMBB = getMBB(*ReturnBB);
3913 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3914 for (
auto &UnwindDest : UnwindDests) {
3915 UnwindDest.first->setIsEHPad();
3916 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3921 assert(BeginSymbol &&
"Expected a begin symbol!");
3922 assert(EndSymbol &&
"Expected an end symbol!");
3923 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3926 MIRBuilder.
buildBr(ReturnMBB);
3932bool IRTranslatorImpl::translateCallBr(
const User &U,
3934 if (!mayTranslateUserTypes(U))
3938 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3941 if (
I.isInlineAsm()) {
3947 if (!translateIntrinsic(
I, IID, MIRBuilder))
3951 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3952 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3961 for (BasicBlock *Dest :
I.getIndirectDests()) {
3962 MachineBasicBlock &
Target = getMBB(*Dest);
3963 Target.setIsInlineAsmBrIndirectTarget();
3964 Target.setLabelMustBeEmitted();
3966 if (Dests.
insert(Dest).second)
3978bool IRTranslatorImpl::translateLandingPad(
const User &U,
3982 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3988 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3989 if (TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel,
3990 PersonalityFn) == 0 &&
3991 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel,
3992 PersonalityFn) == 0)
4007 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
4012 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
4013 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
4014 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
4023 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
4027 TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel, PersonalityFn);
4033 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
4036 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel, PersonalityFn);
4041 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
4042 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
4043 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
4048bool IRTranslatorImpl::translateAlloca(
const User &U,
4056 Register Res = getOrCreateVReg(AI);
4057 int FI = getOrCreateFrameIndex(AI);
4063 if (MF->getTarget().getTargetTriple().isOSWindows())
4068 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4070 if (MRI->getType(NumElts) !=
IntPtrTy) {
4082 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4087 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4089 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4094 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4103 if (Alignment <= StackAlign)
4107 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4108 assert(MF->getFrameInfo().hasVarSizedObjects());
4112bool IRTranslatorImpl::translateVAArg(
const User &U,
4118 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4119 {getOrCreateVReg(*
U.getOperand(0)),
4120 DL->getABITypeAlign(
U.getType()).value()});
4124bool IRTranslatorImpl::translateUnreachable(
const User &U,
4127 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4128 MF->getTarget().Options.NoTrapAfterNoreturn))
4135bool IRTranslatorImpl::translateInsertElement(
const User &U,
4140 FVT && FVT->getNumElements() == 1)
4141 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4144 Register Val = getOrCreateVReg(*
U.getOperand(0));
4145 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4146 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4149 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4150 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4151 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4152 Idx = getOrCreateVReg(*NewIdxCI);
4156 Idx = getOrCreateVReg(*
U.getOperand(2));
4157 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4158 const LLT VecIdxTy =
4159 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4166bool IRTranslatorImpl::translateInsertVector(
const User &U,
4169 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4170 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4173 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4178 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4183 ResultType && ResultType->getNumElements() == 1) {
4185 InputType && InputType->getNumElements() == 1) {
4189 return translateCopy(U, Vec, MIRBuilder);
4204 auto ScaledIndex = MIRBuilder.
buildMul(
4205 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4215bool IRTranslatorImpl::translateExtractElement(
const User &U,
4219 if (
const FixedVectorType *FVT =
4221 if (FVT->getNumElements() == 1)
4222 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4225 Register Val = getOrCreateVReg(*
U.getOperand(0));
4226 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4231 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4232 Idx = getOrCreateVReg(*NewIdxCI);
4236 Idx = getOrCreateVReg(*
U.getOperand(1));
4237 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4238 const LLT VecIdxTy =
4246bool IRTranslatorImpl::translateExtractVector(
const User &U,
4249 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4251 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4256 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4261 ResultType && ResultType->getNumElements() == 1) {
4263 InputType && InputType->getNumElements() == 1) {
4266 return translateCopy(U, Vec, MIRBuilder);
4281 auto ScaledIndex = MIRBuilder.
buildMul(
4282 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4292bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4298 if (
U.getOperand(0)->getType()->isScalableTy()) {
4299 Register Val = getOrCreateVReg(*
U.getOperand(0));
4301 MRI->getType(Val).getElementType(), Val, 0);
4308 Mask = SVI->getShuffleMask();
4319 unsigned M =
Mask[0];
4321 if (M == 0 || M == 1)
4322 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4328 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4329 }
else if (M < SrcElts * 2) {
4331 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4343 for (
int M : Mask) {
4345 if (M == 0 || M == 1) {
4346 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4348 if (!
Undef.isValid()) {
4349 Undef = MRI->createGenericVirtualRegister(SrcTy);
4359 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4361 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4362 {getOrCreateVReg(*
U.getOperand(0)),
4363 getOrCreateVReg(*
U.getOperand(1))})
4364 .addShuffleMask(MaskAlloc);
4368bool IRTranslatorImpl::translateBitInsert(
const User &U,
4372 Register Val = getOrCreateVReg(*
U.getOperand(1));
4374 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4376 LLT ValTy = MRI.getType(Val);
4379 "bitinsert val wider than base should be rejected by verifier");
4392 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(BaseTy);
4409 MIRBuilder.
buildOr(Res, ClearedBase, ShiftedVal);
4413bool IRTranslatorImpl::translateBitExtract(
const User &U,
4416 Register Src = getOrCreateVReg(*
U.getOperand(0));
4418 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4419 LLT SrcTy = MRI.getType(Src);
4420 LLT ResTy = MRI.getType(Res);
4423 "bitextract result wider than source should be rejected by verifier");
4426 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(SrcTy);
4436 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4438 if (SrcTy == IntResTy)
4449 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4451 if (SrcTy == IntResTy)
4468bool IRTranslatorImpl::translatePHI(
const User &U,
4472 SmallVector<MachineInstr *, 4> Insts;
4473 for (
auto Reg : getOrCreateVRegs(PI)) {
4474 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4478 PendingPHIs.emplace_back(&PI, std::move(Insts));
4482bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4486 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4488 auto Res = getOrCreateVRegs(
I);
4491 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4492 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4493 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4496 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4497 *MF->getMachineMemOperand(
4498 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4499 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4500 I.getSuccessOrdering(),
I.getFailureOrdering()));
4504bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4506 if (!mayTranslateUserTypes(U))
4510 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4513 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4514 Register Val = getOrCreateVReg(*
I.getValOperand());
4516 unsigned Opcode = 0;
4517 switch (
I.getOperation()) {
4521 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4524 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4527 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4530 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4533 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4536 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4539 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4542 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4545 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4548 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4551 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4554 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4557 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4560 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4563 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4566 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4569 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4572 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4575 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4578 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4581 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4584 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4587 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4592 Opcode, Res, Addr, Val,
4593 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4594 Flags, MRI->getType(Val), getMemOpAlign(
I),
4595 I.getAAMetadata(),
I.getSyncScopeID(),
4600bool IRTranslatorImpl::translateFence(
const User &U,
4604 Fence.getSyncScopeID());
4608bool IRTranslatorImpl::translateFreeze(
const User &U,
4614 "Freeze with different source and destination type?");
4616 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4623void IRTranslatorImpl::finishPendingPhis() {
4626 GISelObserverWrapper WrapperObserver(&
Verifier);
4627 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4629 for (
auto &Phi : PendingPHIs) {
4630 const PHINode *PI =
Phi.first;
4634 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4640 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4644 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4648 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4649 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4658void IRTranslatorImpl::translateDbgValueRecord(
Value *V,
bool HasArgList,
4664 "Expected inlined-at fields to agree");
4668 if (!V || HasArgList) {
4686 auto *ExprDerefRemoved =
4692 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
4704void IRTranslatorImpl::translateDbgDeclareRecord(
4709 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4714 "Expected inlined-at fields to agree");
4719 MF->setVariableDbgInfo(Variable, Expression,
4720 getOrCreateFrameIndex(*AI), DL);
4724 if (translateIfEntryValueArgument(
true,
Address, Variable,
4736void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4741 assert(DLR->getLabel() &&
"Missing label");
4742 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4744 "Expected inlined-at fields to agree");
4753 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
4756 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
4761bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4763 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4764 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4766 if (TLI->fallBackToDAGISel(Inst))
4770#define HANDLE_INST(NUM, OPCODE, CLASS) \
4771 case Instruction::OPCODE: \
4772 return translate##OPCODE(Inst, *CurBuilder.get());
4773#include "llvm/IR/Instruction.def"
4782 if (
auto CurrInstDL = CurBuilder->getDL())
4783 EntryBuilder->setDebugLoc(
DebugLoc());
4789 EntryBuilder->buildConstant(
Reg, *CI);
4793 EntryBuilder->buildConstant(
Reg, CB->getValue());
4797 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4798 EntryBuilder->buildFConstant(
Reg, *CF);
4800 EntryBuilder->buildUndef(
Reg);
4802 EntryBuilder->buildConstant(
Reg, 0);
4804 EntryBuilder->buildGlobalValue(
Reg, GV);
4806 Register Addr = getOrCreateVReg(*CPA->getPointer());
4807 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4808 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4810 Constant &Elt = *CAZ->getElementValue(0u);
4812 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4816 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4818 return translateCopy(
C, Elt, *EntryBuilder);
4820 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4823 if (CV->getNumElements() == 1)
4824 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4826 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4827 Constant &Elt = *CV->getElementAsConstant(i);
4828 Ops.push_back(getOrCreateVReg(Elt));
4830 EntryBuilder->buildBuildVector(
Reg,
Ops);
4832 switch(
CE->getOpcode()) {
4833#define HANDLE_INST(NUM, OPCODE, CLASS) \
4834 case Instruction::OPCODE: \
4835 return translate##OPCODE(*CE, *EntryBuilder.get());
4836#include "llvm/IR/Instruction.def"
4841 if (CV->getNumOperands() == 1)
4842 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4844 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4845 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4847 EntryBuilder->buildBuildVector(
Reg,
Ops);
4849 EntryBuilder->buildBlockAddress(
Reg, BA);
4856bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4857 const TargetMachine &TM = TLI->getTargetMachine();
4866 (!
U.getType()->getScalarType()->isBFloatTy() &&
4868 return V->getType()->getScalarType()->isBFloatTy();
4872bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4874 for (
auto &BTB : SL->BitTestCases) {
4877 emitBitTestHeader(BTB, BTB.Parent);
4879 BranchProbability UnhandledProb = BTB.Prob;
4880 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4881 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4883 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4892 MachineBasicBlock *NextMBB;
4893 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4896 NextMBB = BTB.Cases[
j + 1].TargetBB;
4897 }
else if (j + 1 == ej) {
4899 NextMBB = BTB.Default;
4902 NextMBB = BTB.Cases[
j + 1].ThisBB;
4905 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4907 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4911 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4912 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4915 BTB.Cases.pop_back();
4921 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4922 BTB.Default->getBasicBlock()};
4923 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4924 if (!BTB.ContiguousRange) {
4925 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4928 SL->BitTestCases.clear();
4930 for (
auto &JTCase : SL->JTCases) {
4932 if (!JTCase.first.Emitted)
4933 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4935 emitJumpTable(JTCase.second, JTCase.second.MBB);
4937 SL->JTCases.clear();
4939 for (
auto &SwCase : SL->SwitchCases)
4940 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4941 SL->SwitchCases.clear();
4944 if (SPInfo->shouldEmitSDCheck(BB)) {
4945 bool FunctionBasedInstrumentation =
4946 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4947 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4950 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4953 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4954 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4955 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4964 ParentMBB, *MF->getSubtarget().getInstrInfo());
4967 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4971 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4975 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4976 if (FailureMBB->
empty()) {
4977 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4982 SPDescriptor.resetPerBBState();
4989 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4993 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
4999 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
5006 ->buildLoad(PtrMemTy, StackSlotPtr,
5012 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
5024 FunctionType *FnTy = GuardCheckFn->getFunctionType();
5025 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
5026 ISD::ArgFlagsTy
Flags;
5027 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
5029 CallLowering::ArgInfo GuardArgInfo(
5030 {GuardVal, FnTy->getParamType(0), {
Flags}});
5032 CallLowering::CallLoweringInfo
Info;
5033 Info.OrigArgs.push_back(GuardArgInfo);
5034 Info.CallConv = GuardCheckFn->getCallingConv();
5037 if (!CLI->lowerCall(MIRBuilder, Info)) {
5038 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
5048 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
5049 getStackGuard(Guard, *CurBuilder);
5052 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
5053 Register GuardPtr = getOrCreateVReg(*IRGuard);
5056 ->buildLoad(PtrMemTy, GuardPtr,
5075 const RTLIB::LibcallImpl LibcallImpl =
5076 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
5077 if (LibcallImpl == RTLIB::Unsupported)
5080 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
5082 CallLowering::CallLoweringInfo
Info;
5083 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
5085 StringRef LibcallName =
5090 if (!CLI->lowerCall(*CurBuilder, Info)) {
5091 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
5096 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
5098 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
5103void IRTranslatorImpl::finalizeFunction() {
5106 PendingPHIs.clear();
5108 FrameIndices.clear();
5109 MachinePreds.clear();
5113 EntryBuilder.reset();
5116 SPDescriptor.resetPerFunctionState();
5129 return CI && CI->isMustTailCall();
5141 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
5142 CLI = MF->getSubtarget().getCallLowering();
5143 SPInfo = StackProtectorInfo;
5145 if (CLI->fallBackToDAGISel(*MF)) {
5147 F.getSubprogram(), &
F.getEntryBlock());
5148 R <<
"unable to lower function: "
5149 <<
ore::NV(
"Prototype",
F.getFunctionType());
5166 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5167 CSEInfo = GetCSEInfo();
5168 EntryBuilder->setCSEInfo(CSEInfo);
5169 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5170 CurBuilder->setCSEInfo(CSEInfo);
5172 EntryBuilder = std::make_unique<MachineIRBuilder>();
5173 CurBuilder = std::make_unique<MachineIRBuilder>();
5176 CurBuilder->setMF(*MF);
5177 EntryBuilder->setMF(*MF);
5178 MRI = &MF->getRegInfo();
5179 DL = &
F.getDataLayout();
5184 FuncInfo.ExceptionModel =
F.getParent()->getExceptionModel();
5188 AA = GetAAResults();
5189 FuncInfo.BPI = GetBPI();
5193 FuncInfo.BPI =
nullptr;
5196 LibInfo = LibraryInfo;
5197 Libcalls = LibcallInfo;
5199 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5201 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5202 SL->init(*TLI, TM, *DL);
5204 assert(PendingPHIs.empty() &&
"stale PHIs");
5208 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5211 F.getSubprogram(), &
F.getEntryBlock());
5212 R <<
"unable to translate in big endian mode";
5223 EntryBuilder->setMBB(*EntryBB);
5225 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5226 SwiftError.setFunction(CurMF);
5227 SwiftError.createEntriesInEntryBlock(DbgLoc);
5229 bool IsVarArg =
F.isVarArg();
5230 bool HasMustTailInVarArgFn =
false;
5233 unsigned NumValues =
F.arg_size();
5236 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5238 NumValues += BB.
size();
5241 MBB = MF->CreateMachineBasicBlock(&BB);
5249 if (!BA->hasZeroLiveUses())
5253 if (!HasMustTailInVarArgFn)
5257 VMap.reserveVRegs(NumValues);
5258 MRI->reserveVirtRegs(NumValues);
5260 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5263 EntryBB->addSuccessor(&getMBB(
F.front()));
5268 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5273 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5274 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5275 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5279 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5281 F.getSubprogram(), &
F.getEntryBlock());
5282 R <<
"unable to lower arguments: "
5283 <<
ore::NV(
"Prototype",
F.getFunctionType());
5290 if (EnableCSE && CSEInfo)
5295 DILocationVerifier Verifier;
5303 CurBuilder->setMBB(
MBB);
5304 HasTailCall =
false;
5314 Verifier.setCurrentInst(&Inst);
5318 translateDbgInfo(Inst, *CurBuilder);
5320 if (translate(Inst))
5325 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5327 if (ORE->allowExtraAnalysis(
"gisel-ir-translator")) {
5328 std::string InstStrStorage;
5332 R <<
": '" << InstStrStorage <<
"'";
5339 if (!finalizeBasicBlock(*BB,
MBB)) {
5341 BB->getTerminator()->getDebugLoc(), BB);
5342 R <<
"unable to translate basic block";
5352 finishPendingPhis();
5354 SwiftError.propagateVRegs();
5359 assert(EntryBB->succ_size() == 1 &&
5360 "Custom BB used for lowering should have only one successor");
5364 "LLVM-IR entry block has a predecessor!?");
5367 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5376 EntryBB->removeSuccessor(&NewEntryBB);
5377 MF->remove(EntryBB);
5378 MF->deleteMachineBasicBlock(EntryBB);
5380 assert(&MF->front() == &NewEntryBB &&
5381 "New entry wasn't next in the list of basic block!");
5384 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5394 return Impl->runOnMachineFunction(
5413 *
F.getParent(), Subtarget),
5438 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5439 Impl->runOnMachineFunction(
5441 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).
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.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isByteOrByteVectorTy() const
Return true if this is a byte type or a vector of byte types.
bool isAggregateType() const
Return true if the type is an aggregate type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isTokenTy() const
Return true if this is 'token'.
bool isVoidTy() const
Return true if this is 'void'.
BasicBlock * getSuccessor(unsigned i=0) const
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
constexpr bool isZero() const
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
A raw_ostream that writes to an std::string.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
LLVM_ABI void sortAndRangeify(CaseClusterVector &Clusters)
Sort Clusters and merge adjacent cases.
std::vector< CaseCluster > CaseClusterVector
@ CC_Range
A cluster of adjacent case labels with the same destination, or just one case.
@ CC_JumpTable
A cluster of cases suitable for jump table lowering.
@ CC_BitTests
A cluster of cases suitable for bit test lowering.
SmallVector< SwitchWorkListItem, 4 > SwitchWorkList
CaseClusterVector::iterator CaseClusterIt
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
ExceptionBehavior
Exception behavior used for floating point operations.
@ ebIgnore
This corresponds to "fpexcept.ignore".
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< PhiNode * > Phi
NodeAddr< CodeNode * > Code
friend class Instruction
Iterator for Instructions in a `BasicBlock.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
LLVM_ABI void diagnoseDontCall(const CallInst &CI)
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isExceptionPointerAndSelectorType(Type *Ty)
Return true if landingpad result type Ty is a struct of an exception pointer (pointer or integer) and...
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
gep_type_iterator gep_type_end(const User *GEP)
LLVM_ABI MachineBasicBlock::iterator findSplitPointForStackProtector(MachineBasicBlock *BB, const TargetInstrInfo &TII)
Find the split point at which to splice the end of BB into its success stack protector check machine ...
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI llvm::SmallVector< int, 16 > createStrideMask(unsigned Start, unsigned Stride, unsigned VF)
Create a stride shuffle mask.
auto reverse(ContainerTy &&C)
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
auto succ_size(const MachineBasicBlock *BB)
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Global
Append to llvm.global_dtors.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
LLVM_ABI llvm::SmallVector< int, 16 > createInterleaveMask(unsigned VF, unsigned NumVecs)
Create an interleave shuffle mask.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
@ 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.