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 *>;
199 PendingConstDbgValues;
248 void translateDbgValueRecord(
Value *V,
bool HasArgList,
257 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
264 bool translateCopy(
const User &U,
const Value &V,
289 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
291 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
296 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
298 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
320 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
326 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
341 bool translateIntrinsic(
358 bool findUnwindDestinations(
371 bool translateCast(
unsigned Opcode,
const User &U,
382 return translateCompare(U, MIRBuilder);
387 return translateCompare(U, MIRBuilder);
392 void finishPendingPhis();
396 void finishPendingConstDbgValues();
400 bool translateUnaryOp(
unsigned Opcode,
const User &U,
405 bool translateBinaryOp(
unsigned Opcode,
const User &U,
411 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
456 bool lowerJumpTableWorkItem(
465 bool FallthroughUnreachable,
471 bool lowerBitTestWorkItem(
477 bool FallthroughUnreachable);
508 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
511 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
514 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
517 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
520 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
523 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
527 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
530 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
533 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
536 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
539 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
542 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
546 return translatePtrToInt(U, MIRBuilder);
549 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
552 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
555 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
558 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
561 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
564 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
567 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
572 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
576 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
580 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
583 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
586 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
590 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
593 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
596 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
599 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
602 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
638 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
653 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
664 std::unique_ptr<MachineIRBuilder> CurBuilder;
669 std::unique_ptr<MachineIRBuilder> EntryBuilder;
682 std::unique_ptr<OptimizationRemarkEmitter> ORE;
693 bool EnableOpts =
false;
697 bool HasTailCall =
false;
701 bool mayTranslateUserTypes(
const User &U)
const;
708 assert(irt &&
"irt is null!");
711 void addSuccessorWithProb(
714 IRT->addSuccessorWithProb(Src, Dst, Prob);
717 ~GISelSwitchLowering()
override =
default;
723 std::unique_ptr<GISelSwitchLowering> SL;
729 void finalizeFunction();
767 auto Regs = getOrCreateVRegs(Val);
770 assert(Regs.size() == 1 &&
771 "attempt to get single VReg for aggregate or void");
775 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
777 auto &Regs = *VMap.getVRegs(Token);
779 assert(Regs.size() == 1 &&
780 "Expected a single register for convergence tokens.");
784 auto Reg = MRI->createGenericVirtualRegister(
LLT::token());
791 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
795 int getOrCreateFrameIndex(
const AllocaInst &AI);
818 auto RemappedEdge = MachinePreds.find(Edge);
819 if (RemappedEdge != MachinePreds.end())
820 return RemappedEdge->second;
829 void addSuccessorWithProb(
835 : OptLevel(OptLevel) {}
865 "IRTranslator LLVM IR -> MI",
false,
false)
877 MF.getProperties().setFailedISel();
878 bool IsGlobalISelAbortEnabled =
883 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
884 R << (
" (in function: " + MF.getName() +
")").str();
886 if (IsGlobalISelAbortEnabled)
906 DILocationVerifier() =
default;
907 ~DILocationVerifier()
override =
default;
909 const Instruction *getCurrentInst()
const {
return CurrInst; }
910 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
912 void erasingInstr(MachineInstr &
MI)
override {}
913 void changingInstr(MachineInstr &
MI)
override {}
914 void changedInstr(MachineInstr &
MI)
override {}
916 void createdInstr(MachineInstr &
MI)
override {
917 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
922 <<
" was copied to " <<
MI);
928 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
929 (
MI.isDebugInstr())) &&
930 "Line info was not transferred to all instructions");
953IRTranslatorImpl::ValueToVRegInfo::VRegListT &
954IRTranslatorImpl::allocateVRegs(
const Value &Val) {
955 auto VRegsIt = VMap.findVRegs(Val);
956 if (VRegsIt != VMap.vregs_end())
957 return *VRegsIt->second;
958 auto *Regs = VMap.getVRegs(Val);
964 auto *Offsets = VMap.getOffsets(Val);
967 Offsets->empty() ? Offsets :
nullptr);
968 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
974 auto VRegsIt = VMap.findVRegs(Val);
975 if (VRegsIt != VMap.vregs_end())
976 return *VRegsIt->second;
979 return *VMap.getVRegs(Val);
982 auto *VRegs = VMap.getVRegs(Val);
986 "Don't know how to create an empty vreg");
991 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
995 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"GISelFailure",
996 MF->getFunction().getSubprogram(),
997 &MF->getFunction().getEntryBlock());
998 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
1006 auto *
Offsets = VMap.getOffsets(Val);
1008 Offsets->empty() ? Offsets :
nullptr);
1011 for (
auto Ty : SplitTys)
1012 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
1019 while (
auto Elt =
C.getAggregateElement(Idx++)) {
1020 auto EltRegs = getOrCreateVRegs(*Elt);
1027int IRTranslatorImpl::getOrCreateFrameIndex(
const AllocaInst &AI) {
1028 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
1030 return MapEntry->second;
1036 Size = std::max<uint64_t>(
Size, 1u);
1038 int &FI = MapEntry->second;
1039 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
1046 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
1047 MF->getFrameInfo().setStackID(FI, StackID);
1055 return SI->getAlign();
1057 return LI->getAlign();
1063 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"", &
I);
1064 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
1070 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
1071 assert(
MBB &&
"BasicBlock was not encountered before");
1075void IRTranslatorImpl::addMachineCFGPred(CFGEdge
Edge,
1077 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
1078 MachinePreds[
Edge].push_back(NewPred);
1081bool IRTranslatorImpl::translateBinaryOp(
unsigned Opcode,
const User &U,
1083 if (!mayTranslateUserTypes(U))
1090 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1091 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1103bool IRTranslatorImpl::translateUnaryOp(
unsigned Opcode,
const User &U,
1105 if (!mayTranslateUserTypes(U))
1108 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1119bool IRTranslatorImpl::translateFNeg(
const User &U,
1121 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
1124bool IRTranslatorImpl::translateCompare(
const User &U,
1126 if (!mayTranslateUserTypes(U))
1130 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1131 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1136 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1, Flags);
1144 MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1, Flags);
1149bool IRTranslatorImpl::translateRet(
const User &U,
1153 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
1158 VRegs = getOrCreateVRegs(*Ret);
1161 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
1162 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
1163 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
1169 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
1172void IRTranslatorImpl::emitBranchForMergedCondition(
1181 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
1184 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
1187 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
1188 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
1189 CurBuilder->getDebugLoc(), TProb, FProb);
1190 SL->SwitchCases.push_back(CB);
1196 SwitchCG::CaseBlock CB(
1198 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
1199 SL->SwitchCases.push_back(CB);
1204 return I->getParent() == BB;
1208void IRTranslatorImpl::findMergedConditions(
1213 using namespace PatternMatch;
1214 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
1215 "Expected Opc to be AND/OR");
1221 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
1227 const Value *BOpOp0, *BOpOp1;
1241 if (BOpc == Instruction::And)
1242 BOpc = Instruction::Or;
1243 else if (BOpc == Instruction::Or)
1244 BOpc = Instruction::And;
1250 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
1254 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
1261 MachineBasicBlock *TmpBB =
1265 if (
Opc == Instruction::Or) {
1286 auto NewTrueProb = TProb / 2;
1287 auto NewFalseProb = TProb / 2 + FProb;
1289 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1290 NewFalseProb, InvertCond);
1296 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1297 Probs[1], InvertCond);
1299 assert(
Opc == Instruction::And &&
"Unknown merge op!");
1319 auto NewTrueProb = TProb + FProb / 2;
1320 auto NewFalseProb = FProb / 2;
1322 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1323 NewFalseProb, InvertCond);
1329 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1330 Probs[1], InvertCond);
1334bool IRTranslatorImpl::shouldEmitAsBranches(
1335 const std::vector<SwitchCG::CaseBlock> &Cases) {
1337 if (Cases.size() != 2)
1342 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
1343 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
1344 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
1345 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
1351 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
1352 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
1356 Cases[0].TrueBB == Cases[1].ThisBB)
1359 Cases[0].FalseBB == Cases[1].ThisBB)
1366bool IRTranslatorImpl::translateUncondBr(
const User &U,
1369 auto &CurMBB = MIRBuilder.
getMBB();
1374 MIRBuilder.
buildBr(*Succ0MBB);
1377 for (
const BasicBlock *Succ :
successors(&BrInst))
1382bool IRTranslatorImpl::translateCondBr(
const User &U,
1385 auto &CurMBB = MIRBuilder.
getMBB();
1391 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
1410 using namespace PatternMatch;
1412 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
1413 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
1416 const Value *BOp0, *BOp1;
1418 Opcode = Instruction::And;
1420 Opcode = Instruction::Or;
1424 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
1425 getEdgeProbability(&CurMBB, Succ0MBB),
1426 getEdgeProbability(&CurMBB, Succ1MBB),
1428 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
1431 if (shouldEmitAsBranches(SL->SwitchCases)) {
1433 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
1434 SL->SwitchCases.erase(SL->SwitchCases.begin());
1440 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
1441 MF->erase(SL->SwitchCases[
I].ThisBB);
1443 SL->SwitchCases.clear();
1450 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
1451 CurBuilder->getDebugLoc());
1455 emitSwitchCase(CB, &CurMBB, *CurBuilder);
1462 if (!FuncInfo.BPI) {
1463 Src->addSuccessorWithoutProb(Dst);
1467 Prob = getEdgeProbability(Src, Dst);
1468 Src->addSuccessor(Dst, Prob);
1474 const BasicBlock *SrcBB = Src->getBasicBlock();
1475 const BasicBlock *DstBB = Dst->getBasicBlock();
1476 if (!FuncInfo.BPI) {
1479 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
1480 return BranchProbability(1, SuccSize);
1482 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
1486 using namespace SwitchCG;
1489 BranchProbabilityInfo *BPI = FuncInfo.BPI;
1491 Clusters.reserve(
SI.getNumCases());
1492 for (
const auto &
I :
SI.cases()) {
1493 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
1494 assert(Succ &&
"Could not find successor mbb in mapping");
1495 const ConstantInt *CaseVal =
I.getCaseValue();
1496 BranchProbability Prob =
1498 : BranchProbability(1,
SI.getNumCases() + 1);
1499 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
1502 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
1509 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
1512 if (Clusters.empty()) {
1519 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
1520 SL->findBitTestClusters(Clusters, &SI);
1523 dbgs() <<
"Case clusters: ";
1524 for (
const CaseCluster &
C : Clusters) {
1525 if (
C.Kind == CC_JumpTable)
1527 if (
C.Kind == CC_BitTests)
1530 C.Low->getValue().print(
dbgs(),
true);
1531 if (
C.Low !=
C.High) {
1533 C.High->getValue().print(
dbgs(),
true);
1540 assert(!Clusters.empty());
1544 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
1545 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
1547 while (!WorkList.empty()) {
1548 SwitchWorkListItem
W = WorkList.pop_back_val();
1550 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
1552 if (NumClusters > 3 &&
1555 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
1559 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
1569 using namespace SwitchCG;
1570 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
1571 "Clusters not sorted?");
1572 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
1574 auto [LastLeft, FirstRight, LeftProb, RightProb] =
1575 SL->computeSplitWorkItemInfo(W);
1580 assert(PivotCluster >
W.FirstCluster);
1581 assert(PivotCluster <=
W.LastCluster);
1586 const ConstantInt *Pivot = PivotCluster->Low;
1595 MachineBasicBlock *LeftMBB;
1596 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
1597 FirstLeft->Low ==
W.GE &&
1598 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
1599 LeftMBB = FirstLeft->MBB;
1601 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1602 FuncInfo.MF->
insert(BBI, LeftMBB);
1604 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
1610 MachineBasicBlock *RightMBB;
1611 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
1612 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
1613 RightMBB = FirstRight->MBB;
1615 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1616 FuncInfo.MF->
insert(BBI, RightMBB);
1618 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
1626 if (
W.MBB == SwitchMBB)
1627 emitSwitchCase(CB, SwitchMBB, MIB);
1629 SL->SwitchCases.push_back(CB);
1635 assert(JT.
Reg &&
"Should lower JT Header first!");
1650 MachineIRBuilder MIB(*HeaderBB->
getParent());
1657 Register SwitchOpReg = getOrCreateVReg(SValue);
1659 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
1664 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
1678 auto Cst = getOrCreateVReg(
1718 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
1732 "Can only handle SLE ranges");
1743 const LLT CmpTy = MRI->getType(CmpOpReg);
1744 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1770bool IRTranslatorImpl::lowerJumpTableWorkItem(
1776 using namespace SwitchCG;
1779 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1780 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1781 BranchProbability DefaultProb =
W.DefaultProb;
1784 MachineBasicBlock *JumpMBB = JT->
MBB;
1785 CurMF->
insert(BBI, JumpMBB);
1795 auto JumpProb =
I->Prob;
1796 auto FallthroughProb = UnhandledProbs;
1804 if (*SI == DefaultMBB) {
1805 JumpProb += DefaultProb / 2;
1806 FallthroughProb -= DefaultProb / 2;
1811 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1816 if (FallthroughUnreachable)
1817 JTH->FallthroughUnreachable =
true;
1819 if (!JTH->FallthroughUnreachable)
1820 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1821 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1826 JTH->HeaderBB = CurMBB;
1830 if (CurMBB == SwitchMBB) {
1831 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1833 JTH->Emitted =
true;
1837bool IRTranslatorImpl::lowerSwitchRangeWorkItem(
1842 using namespace SwitchCG;
1845 if (
I->Low ==
I->High) {
1861 CaseBlock CB(Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1864 emitSwitchCase(CB, SwitchMBB, MIB);
1870 MachineIRBuilder &MIB = *CurBuilder;
1874 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1876 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1878 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1883 LLT MaskTy = SwitchOpTy;
1889 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1898 Register SubReg = RangeSub.getReg(0);
1899 if (SwitchOpTy != MaskTy)
1905 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1907 if (!
B.FallthroughUnreachable)
1908 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1909 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1913 if (!
B.FallthroughUnreachable) {
1917 RangeSub, RangeCst);
1931 MachineIRBuilder &MIB = *CurBuilder;
1937 if (PopCount == 1) {
1940 auto MaskTrailingZeros =
1945 }
else if (PopCount == BB.
Range) {
1947 auto MaskTrailingOnes =
1955 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1959 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1966 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1968 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1986bool IRTranslatorImpl::lowerBitTestWorkItem(
1992 bool FallthroughUnreachable) {
1993 using namespace SwitchCG;
1996 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
1998 for (BitTestCase &BTC : BTB->Cases)
1999 CurMF->
insert(BBI, BTC.ThisBB);
2002 BTB->Parent = CurMBB;
2003 BTB->Default = Fallthrough;
2005 BTB->DefaultProb = UnhandledProbs;
2009 if (!BTB->ContiguousRange) {
2010 BTB->Prob += DefaultProb / 2;
2011 BTB->DefaultProb -= DefaultProb / 2;
2014 if (FallthroughUnreachable)
2015 BTB->FallthroughUnreachable =
true;
2018 if (CurMBB == SwitchMBB) {
2019 emitBitTestHeader(*BTB, SwitchMBB);
2020 BTB->Emitted =
true;
2030 using namespace SwitchCG;
2032 MachineBasicBlock *NextMBB =
nullptr;
2034 if (++BBI != FuncInfo.MF->end())
2043 [](
const CaseCluster &a,
const CaseCluster &b) {
2044 return a.Prob != b.Prob
2046 : a.Low->getValue().slt(b.Low->getValue());
2051 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
2053 if (
I->Prob >
W.LastCluster->Prob)
2055 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
2063 BranchProbability DefaultProb =
W.DefaultProb;
2064 BranchProbability UnhandledProbs = DefaultProb;
2065 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
2066 UnhandledProbs +=
I->Prob;
2068 MachineBasicBlock *CurMBB =
W.MBB;
2069 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
2070 bool FallthroughUnreachable =
false;
2071 MachineBasicBlock *Fallthrough;
2072 if (
I ==
W.LastCluster) {
2074 Fallthrough = DefaultMBB;
2075 FallthroughUnreachable =
2079 CurMF->
insert(BBI, Fallthrough);
2081 UnhandledProbs -=
I->Prob;
2085 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2086 DefaultProb, UnhandledProbs,
I, Fallthrough,
2087 FallthroughUnreachable)) {
2095 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2096 UnhandledProbs,
I, Fallthrough,
2097 FallthroughUnreachable)) {
2104 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
2105 FallthroughUnreachable, UnhandledProbs,
2106 CurMBB, MIB, SwitchMBB)) {
2113 CurMBB = Fallthrough;
2119bool IRTranslatorImpl::translateIndirectBr(
const User &U,
2127 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
2128 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
2129 for (
const BasicBlock *Succ :
successors(&BrInst)) {
2133 if (!AddedSuccessors.
insert(Succ).second)
2149bool IRTranslatorImpl::translateLoad(
const User &U,
2152 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
2163 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
2165 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
2171 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
2173 if (AA->pointsToConstantMemory(
2180 if (Regs.
size() == 1) {
2181 auto *MMO = MF->getMachineMemOperand(
2183 MRI->getType(Regs[0]), getMemOpAlign(LI),
2184 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
2190 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
2191 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
2193 for (
unsigned i = 0; i < Regs.
size(); ++i) {
2198 Align BaseAlign = getMemOpAlign(LI);
2200 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
2203 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
2209bool IRTranslatorImpl::translateStore(
const User &U,
2212 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
2218 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
2219 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
2221 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
2222 SI.getPointerOperand());
2229 if (Vals.
size() == 1) {
2230 auto *MMO = MF->getMachineMemOperand(
2231 MachinePointerInfo(
SI.getPointerOperand()), Flags,
2232 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
2233 SI.getSyncScopeID(),
SI.getOrdering());
2238 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
2239 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
2241 for (
unsigned i = 0; i < Vals.
size(); ++i) {
2245 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
2246 Align BaseAlign = getMemOpAlign(SI);
2247 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
2250 SI.getSyncScopeID(),
SI.getOrdering());
2257 const Value *Src = U.getOperand(0);
2263 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
2266 for (
auto Idx : EVI->indices())
2267 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2269 for (
auto Idx : IVI->indices())
2270 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2276 DL.getIndexedOffsetInType(Src->getType(), Indices));
2279bool IRTranslatorImpl::translateExtractValue(
const User &U,
2281 const Value *Src =
U.getOperand(0);
2284 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
2286 auto &DstRegs = allocateVRegs(U);
2288 for (
unsigned i = 0; i < DstRegs.size(); ++i)
2289 DstRegs[i] = SrcRegs[Idx++];
2294bool IRTranslatorImpl::translateInsertValue(
const User &U,
2296 const Value *Src =
U.getOperand(0);
2298 auto &DstRegs = allocateVRegs(U);
2299 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
2302 auto *InsertedIt = InsertedRegs.
begin();
2304 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
2305 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
2306 DstRegs[i] = *InsertedIt++;
2308 DstRegs[i] = SrcRegs[i];
2314bool IRTranslatorImpl::translateSelect(
const User &U,
2316 Register Tst = getOrCreateVReg(*
U.getOperand(0));
2325 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
2326 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
2332bool IRTranslatorImpl::translateCopy(
const User &U,
const Value &V,
2334 return translateCopy(U, getOrCreateVReg(V), MIRBuilder);
2337bool IRTranslatorImpl::translateCopy(
const User &U,
Register Src,
2339 auto &Regs = *VMap.getVRegs(U);
2341 Regs.push_back(Src);
2350bool IRTranslatorImpl::translateBitCast(
const User &U,
2352 Type *SrcTy =
U.getOperand(0)->getType();
2353 Type *DstTy =
U.getType();
2360 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
2362 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
2371 "only byte types can be bitcast to or from pointers");
2373 LLT IntTy =
getLLTForType(*DL->getIntPtrType(PtrIRTy), *DL);
2374 Register Src = getOrCreateVReg(*
U.getOperand(0));
2376 if (MRI->getType(Src) != IntTy && MRI->getType(Dst) != IntTy)
2382 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
2385bool IRTranslatorImpl::translateCast(
unsigned Opcode,
const User &U,
2387 if (!mayTranslateUserTypes(U))
2400bool IRTranslatorImpl::translateGetElementPtr(
const User &U,
2402 Value &Op0 = *
U.getOperand(0);
2406 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
2409 uint32_t PtrAddFlags = 0;
2415 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
2425 unsigned VectorWidth = 0;
2429 bool WantSplatVector =
false;
2433 WantSplatVector = VectorWidth > 1;
2437 return translateCopy(U, BaseReg, MIRBuilder);
2441 if (WantSplatVector && !PtrTy.
isVector()) {
2448 OffsetIRTy = DL->getIndexType(PtrIRTy);
2455 const Value *
Idx = GTI.getOperand();
2456 if (StructType *StTy = GTI.getStructTypeOrNull()) {
2458 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
2461 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
2466 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
2467 Offset += ElementSize * *Val;
2476 PtrAddFlagsWithConst(
Offset))
2481 Register IdxReg = getOrCreateVReg(*Idx);
2482 LLT IdxTy = MRI->getType(IdxReg);
2483 if (IdxTy != OffsetTy) {
2484 if (!IdxTy.
isVector() && WantSplatVector) {
2497 if (ElementSize != 1) {
2508 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
2511 GepOffsetReg = IdxReg;
2515 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
2524 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
2525 PtrAddFlagsWithConst(
Offset));
2529 return translateCopy(U, BaseReg, MIRBuilder);
2532bool IRTranslatorImpl::translateMemFunc(
const CallInst &CI,
2542 unsigned MinPtrSize = UINT_MAX;
2543 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
2544 Register SrcReg = getOrCreateVReg(**AI);
2545 LLT SrcTy = MRI->getType(SrcReg);
2547 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
2555 if (MRI->getType(SizeOpReg) != SizeTy)
2567 ConstantInt *CopySize =
nullptr;
2570 DstAlign = MCI->getDestAlign().valueOrOne();
2571 SrcAlign = MCI->getSourceAlign().valueOrOne();
2574 DstAlign = MMI->getDestAlign().valueOrOne();
2575 SrcAlign = MMI->getSourceAlign().valueOrOne();
2579 DstAlign = MSI->getDestAlign().valueOrOne();
2582 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
2583 Opcode != TargetOpcode::G_MEMSET_INLINE) {
2599 if (AA && CopySize &&
2600 AA->pointsToConstantMemory(MemoryLocation(
2610 ICall.addMemOperand(
2611 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
2612 StoreFlags, 1, DstAlign, AAInfo));
2613 if (Opcode != TargetOpcode::G_MEMSET &&
2614 Opcode != TargetOpcode::G_MEMSET_INLINE)
2615 ICall.addMemOperand(MF->getMachineMemOperand(
2616 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
2621bool IRTranslatorImpl::translateTrap(
const CallInst &CI,
2624 StringRef TrapFuncName =
2625 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
2626 if (TrapFuncName.
empty()) {
2627 MachineInstrBuilder MIB;
2628 if (Opcode == TargetOpcode::G_UBSANTRAP) {
2639 CallLowering::CallLoweringInfo
Info;
2640 if (Opcode == TargetOpcode::G_UBSANTRAP)
2648 return CLI->lowerCall(MIRBuilder, Info);
2651bool IRTranslatorImpl::translateVectorInterleave2Intrinsic(
2654 "This function can only be called on the interleave2 intrinsic!");
2658 Register Res = getOrCreateVReg(CI);
2660 LLT OpTy = MRI->getType(Op0);
2667bool IRTranslatorImpl::translateVectorDeinterleave2Intrinsic(
2670 "This function can only be called on the deinterleave2 intrinsic!");
2677 LLT ResTy = MRI->getType(Res[0]);
2694void IRTranslatorImpl::getStackGuard(
Register DstReg,
2697 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
2700 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
2705 const TargetInstrInfo &
TII = *MF->getSubtarget().getInstrInfo();
2706 MRI->setRegClass(DstReg,
2707 TII.getRegClass(
TII.get(TargetOpcode::LOAD_STACK_GUARD), 0));
2709 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
2711 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
2712 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
2714 MachinePointerInfo MPInfo(
Global);
2717 MachineMemOperand *MemRef = MF->getMachineMemOperand(
2718 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
2722bool IRTranslatorImpl::translateOverflowIntrinsic(
2726 Op, {ResRegs[0], ResRegs[1]},
2732bool IRTranslatorImpl::translateFixedPointIntrinsic(
2734 Register Dst = getOrCreateVReg(CI);
2742unsigned IRTranslatorImpl::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
2746 case Intrinsic::acos:
2747 return TargetOpcode::G_FACOS;
2748 case Intrinsic::asin:
2749 return TargetOpcode::G_FASIN;
2750 case Intrinsic::atan:
2751 return TargetOpcode::G_FATAN;
2752 case Intrinsic::atan2:
2753 return TargetOpcode::G_FATAN2;
2754 case Intrinsic::bswap:
2755 return TargetOpcode::G_BSWAP;
2756 case Intrinsic::bitreverse:
2757 return TargetOpcode::G_BITREVERSE;
2758 case Intrinsic::clmul:
2759 return TargetOpcode::G_CLMUL;
2760 case Intrinsic::fshl:
2761 return TargetOpcode::G_FSHL;
2762 case Intrinsic::fshr:
2763 return TargetOpcode::G_FSHR;
2764 case Intrinsic::ceil:
2765 return TargetOpcode::G_FCEIL;
2766 case Intrinsic::cos:
2767 return TargetOpcode::G_FCOS;
2768 case Intrinsic::cosh:
2769 return TargetOpcode::G_FCOSH;
2770 case Intrinsic::ctpop:
2771 return TargetOpcode::G_CTPOP;
2772 case Intrinsic::smulh:
2773 return TargetOpcode::G_SMULH;
2774 case Intrinsic::umulh:
2775 return TargetOpcode::G_UMULH;
2776 case Intrinsic::exp:
2777 return TargetOpcode::G_FEXP;
2778 case Intrinsic::exp2:
2779 return TargetOpcode::G_FEXP2;
2780 case Intrinsic::exp10:
2781 return TargetOpcode::G_FEXP10;
2782 case Intrinsic::fabs:
2783 return TargetOpcode::G_FABS;
2784 case Intrinsic::copysign:
2785 return TargetOpcode::G_FCOPYSIGN;
2786 case Intrinsic::minnum:
2787 return TargetOpcode::G_FMINNUM;
2788 case Intrinsic::maxnum:
2789 return TargetOpcode::G_FMAXNUM;
2790 case Intrinsic::minimum:
2791 return TargetOpcode::G_FMINIMUM;
2792 case Intrinsic::maximum:
2793 return TargetOpcode::G_FMAXIMUM;
2794 case Intrinsic::minimumnum:
2795 return TargetOpcode::G_FMINIMUMNUM;
2796 case Intrinsic::maximumnum:
2797 return TargetOpcode::G_FMAXIMUMNUM;
2798 case Intrinsic::canonicalize:
2799 return TargetOpcode::G_FCANONICALIZE;
2800 case Intrinsic::floor:
2801 return TargetOpcode::G_FFLOOR;
2802 case Intrinsic::fma:
2803 return TargetOpcode::G_FMA;
2804 case Intrinsic::log:
2805 return TargetOpcode::G_FLOG;
2806 case Intrinsic::log2:
2807 return TargetOpcode::G_FLOG2;
2808 case Intrinsic::log10:
2809 return TargetOpcode::G_FLOG10;
2810 case Intrinsic::ldexp:
2811 return TargetOpcode::G_FLDEXP;
2812 case Intrinsic::nearbyint:
2813 return TargetOpcode::G_FNEARBYINT;
2814 case Intrinsic::pow:
2815 return TargetOpcode::G_FPOW;
2816 case Intrinsic::powi:
2817 return TargetOpcode::G_FPOWI;
2818 case Intrinsic::rint:
2819 return TargetOpcode::G_FRINT;
2820 case Intrinsic::round:
2821 return TargetOpcode::G_INTRINSIC_ROUND;
2822 case Intrinsic::roundeven:
2823 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2824 case Intrinsic::sin:
2825 return TargetOpcode::G_FSIN;
2826 case Intrinsic::sinh:
2827 return TargetOpcode::G_FSINH;
2828 case Intrinsic::sqrt:
2829 return TargetOpcode::G_FSQRT;
2830 case Intrinsic::tan:
2831 return TargetOpcode::G_FTAN;
2832 case Intrinsic::tanh:
2833 return TargetOpcode::G_FTANH;
2834 case Intrinsic::trunc:
2835 return TargetOpcode::G_INTRINSIC_TRUNC;
2836 case Intrinsic::readcyclecounter:
2837 return TargetOpcode::G_READCYCLECOUNTER;
2838 case Intrinsic::readsteadycounter:
2839 return TargetOpcode::G_READSTEADYCOUNTER;
2840 case Intrinsic::ptrmask:
2841 return TargetOpcode::G_PTRMASK;
2842 case Intrinsic::lrint:
2843 return TargetOpcode::G_INTRINSIC_LRINT;
2844 case Intrinsic::llrint:
2845 return TargetOpcode::G_INTRINSIC_LLRINT;
2847 case Intrinsic::vector_reduce_fmin:
2848 return TargetOpcode::G_VECREDUCE_FMIN;
2849 case Intrinsic::vector_reduce_fmax:
2850 return TargetOpcode::G_VECREDUCE_FMAX;
2851 case Intrinsic::vector_reduce_fminimum:
2852 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2853 case Intrinsic::vector_reduce_fmaximum:
2854 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2855 case Intrinsic::vector_reduce_fminimumnum:
2856 return TargetOpcode::G_VECREDUCE_FMINIMUMNUM;
2857 case Intrinsic::vector_reduce_fmaximumnum:
2858 return TargetOpcode::G_VECREDUCE_FMAXIMUMNUM;
2859 case Intrinsic::vector_reduce_add:
2860 return TargetOpcode::G_VECREDUCE_ADD;
2861 case Intrinsic::vector_reduce_mul:
2862 return TargetOpcode::G_VECREDUCE_MUL;
2863 case Intrinsic::vector_reduce_and:
2864 return TargetOpcode::G_VECREDUCE_AND;
2865 case Intrinsic::vector_reduce_or:
2866 return TargetOpcode::G_VECREDUCE_OR;
2867 case Intrinsic::vector_reduce_xor:
2868 return TargetOpcode::G_VECREDUCE_XOR;
2869 case Intrinsic::vector_reduce_smax:
2870 return TargetOpcode::G_VECREDUCE_SMAX;
2871 case Intrinsic::vector_reduce_smin:
2872 return TargetOpcode::G_VECREDUCE_SMIN;
2873 case Intrinsic::vector_reduce_umax:
2874 return TargetOpcode::G_VECREDUCE_UMAX;
2875 case Intrinsic::vector_reduce_umin:
2876 return TargetOpcode::G_VECREDUCE_UMIN;
2877 case Intrinsic::experimental_vector_compress:
2878 return TargetOpcode::G_VECTOR_COMPRESS;
2879 case Intrinsic::lround:
2880 return TargetOpcode::G_LROUND;
2881 case Intrinsic::llround:
2882 return TargetOpcode::G_LLROUND;
2883 case Intrinsic::get_fpenv:
2884 return TargetOpcode::G_GET_FPENV;
2885 case Intrinsic::get_fpmode:
2886 return TargetOpcode::G_GET_FPMODE;
2891bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2895 unsigned Op = getSimpleIntrinsicOpcode(ID);
2903 for (
const auto &Arg : CI.
args())
2906 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2914 case Intrinsic::experimental_constrained_fadd:
2915 return TargetOpcode::G_STRICT_FADD;
2916 case Intrinsic::experimental_constrained_fsub:
2917 return TargetOpcode::G_STRICT_FSUB;
2918 case Intrinsic::experimental_constrained_fmul:
2919 return TargetOpcode::G_STRICT_FMUL;
2920 case Intrinsic::experimental_constrained_fdiv:
2921 return TargetOpcode::G_STRICT_FDIV;
2922 case Intrinsic::experimental_constrained_frem:
2923 return TargetOpcode::G_STRICT_FREM;
2924 case Intrinsic::experimental_constrained_fma:
2925 return TargetOpcode::G_STRICT_FMA;
2926 case Intrinsic::experimental_constrained_sqrt:
2927 return TargetOpcode::G_STRICT_FSQRT;
2928 case Intrinsic::experimental_constrained_ldexp:
2929 return TargetOpcode::G_STRICT_FLDEXP;
2930 case Intrinsic::experimental_constrained_fcmp:
2931 return TargetOpcode::G_STRICT_FCMP;
2932 case Intrinsic::experimental_constrained_fcmps:
2933 return TargetOpcode::G_STRICT_FCMPS;
2939bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2951 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2952 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2954 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2955 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2958 .addPredicate(FPCmp->getPredicate())
2972std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2973 auto VRegs = getOrCreateVRegs(Arg);
2974 if (VRegs.
size() != 1)
2975 return std::nullopt;
2978 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2979 if (!VRegDef || !VRegDef->isCopy())
2980 return std::nullopt;
2981 return VRegDef->getOperand(1).getReg().asMCReg();
2984bool IRTranslatorImpl::translateIfEntryValueArgument(
2995 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2997 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2998 <<
": expression is entry_value but "
2999 <<
"couldn't find a physical register\n");
3007 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
3019 case Intrinsic::experimental_convergence_anchor:
3020 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
3021 case Intrinsic::experimental_convergence_entry:
3022 return TargetOpcode::CONVERGENCECTRL_ENTRY;
3023 case Intrinsic::experimental_convergence_loop:
3024 return TargetOpcode::CONVERGENCECTRL_LOOP;
3028bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
3031 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3034 if (ID == Intrinsic::experimental_convergence_loop) {
3036 assert(Bundle &&
"Expected a convergence control token.");
3038 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3045bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3049 if (ORE->enabled()) {
3051 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3059 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3065 case Intrinsic::lifetime_start:
3066 case Intrinsic::lifetime_end: {
3069 MF->getFunction().hasOptNone())
3072 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3073 : TargetOpcode::LIFETIME_END;
3082 case Intrinsic::fake_use: {
3084 for (
const auto &Arg : CI.
args())
3086 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3087 MF->setHasFakeUses(
true);
3090 case Intrinsic::vaend:
3094 case Intrinsic::vastart: {
3096 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3099 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3100 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3102 ListSize, Alignment));
3105 case Intrinsic::uadd_with_overflow:
3106 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3107 case Intrinsic::sadd_with_overflow:
3108 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3109 case Intrinsic::usub_with_overflow:
3110 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3111 case Intrinsic::ssub_with_overflow:
3112 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3113 case Intrinsic::umul_with_overflow:
3114 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3115 case Intrinsic::smul_with_overflow:
3116 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3117 case Intrinsic::uadd_sat:
3118 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3119 case Intrinsic::sadd_sat:
3120 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3121 case Intrinsic::usub_sat:
3122 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3123 case Intrinsic::ssub_sat:
3124 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3125 case Intrinsic::ushl_sat:
3126 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3127 case Intrinsic::sshl_sat:
3128 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3129 case Intrinsic::umin:
3130 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3131 case Intrinsic::umax:
3132 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3133 case Intrinsic::smin:
3134 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3135 case Intrinsic::smax:
3136 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3137 case Intrinsic::abs:
3139 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3140 case Intrinsic::smul_fix:
3141 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3142 case Intrinsic::umul_fix:
3143 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3144 case Intrinsic::smul_fix_sat:
3145 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3146 case Intrinsic::umul_fix_sat:
3147 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3148 case Intrinsic::sdiv_fix:
3149 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3150 case Intrinsic::udiv_fix:
3151 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3152 case Intrinsic::sdiv_fix_sat:
3153 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3154 case Intrinsic::udiv_fix_sat:
3155 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3156 case Intrinsic::fmuladd: {
3157 Register Dst = getOrCreateVReg(CI);
3161 if (TLI->isFMAFasterThanFMulAndFAdd(*MF,
3162 TLI->getValueType(*DL, CI.
getType()))) {
3165 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3176 case Intrinsic::frexp: {
3183 case Intrinsic::modf: {
3185 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3190 case Intrinsic::sincos: {
3197 case Intrinsic::fptosi_sat:
3201 case Intrinsic::fptoui_sat:
3205 case Intrinsic::memcpy_inline:
3206 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3207 case Intrinsic::memcpy:
3208 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3209 case Intrinsic::memmove:
3210 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3211 case Intrinsic::memset:
3212 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3213 case Intrinsic::memset_inline:
3214 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3215 case Intrinsic::eh_typeid_for: {
3218 unsigned TypeID = MF->getTypeIDFor(GV);
3222 case Intrinsic::objectsize:
3225 case Intrinsic::is_constant:
3228 case Intrinsic::stackguard:
3229 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3231 case Intrinsic::stackprotector: {
3234 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3235 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3236 getStackGuard(GuardVal, MIRBuilder);
3241 int FI = getOrCreateFrameIndex(*Slot);
3242 MF->getFrameInfo().setStackProtectorIndex(FI);
3245 GuardVal, getOrCreateVReg(*Slot),
3252 case Intrinsic::stacksave: {
3253 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3256 case Intrinsic::stackrestore: {
3257 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3261 case Intrinsic::cttz:
3262 case Intrinsic::ctlz: {
3264 bool isTrailing =
ID == Intrinsic::cttz;
3265 unsigned Opcode = isTrailing ? Cst->
isZero()
3266 ? TargetOpcode::G_CTTZ
3267 : TargetOpcode::G_CTTZ_ZERO_POISON
3268 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3269 : TargetOpcode::G_CTLZ_ZERO_POISON;
3270 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3274 case Intrinsic::invariant_start: {
3278 case Intrinsic::invariant_end:
3280 case Intrinsic::expect:
3281 case Intrinsic::expect_with_probability:
3282 case Intrinsic::annotation:
3283 case Intrinsic::ptr_annotation:
3284 case Intrinsic::launder_invariant_group:
3285 case Intrinsic::threadlocal_address: {
3287 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3291 case Intrinsic::assume:
3292 case Intrinsic::experimental_noalias_scope_decl:
3293 case Intrinsic::var_annotation:
3294 case Intrinsic::sideeffect:
3297 case Intrinsic::read_volatile_register:
3298 case Intrinsic::read_register: {
3301 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3305 case Intrinsic::write_register: {
3307 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3312 case Intrinsic::localescape: {
3313 MachineBasicBlock &EntryMBB = MF->front();
3318 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3325 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3338 case Intrinsic::vector_reduce_fadd:
3339 case Intrinsic::vector_reduce_fmul: {
3342 Register Dst = getOrCreateVReg(CI);
3348 Opc =
ID == Intrinsic::vector_reduce_fadd
3349 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3350 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3351 if (!MRI->getType(VecSrc).isVector())
3352 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3353 : TargetOpcode::G_FMUL;
3361 if (ID == Intrinsic::vector_reduce_fadd) {
3362 Opc = TargetOpcode::G_VECREDUCE_FADD;
3363 ScalarOpc = TargetOpcode::G_FADD;
3365 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3366 ScalarOpc = TargetOpcode::G_FMUL;
3368 LLT DstTy = MRI->getType(Dst);
3371 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3376 case Intrinsic::trap:
3377 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3378 case Intrinsic::debugtrap:
3379 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3380 case Intrinsic::ubsantrap:
3381 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3382 case Intrinsic::allow_runtime_check:
3383 case Intrinsic::allow_ubsan_check:
3384 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3387 case Intrinsic::amdgcn_cs_chain:
3388 case Intrinsic::amdgcn_call_whole_wave:
3389 return translateCallBase(CI, MIRBuilder);
3390 case Intrinsic::fptrunc_round: {
3395 std::optional<RoundingMode> RoundMode =
3400 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3401 {getOrCreateVReg(CI)},
3403 .addImm((
int)*RoundMode);
3407 case Intrinsic::is_fpclass: {
3412 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3413 {getOrCreateVReg(*FpValue)})
3418 case Intrinsic::set_fpenv: {
3423 case Intrinsic::reset_fpenv:
3426 case Intrinsic::set_fpmode: {
3431 case Intrinsic::reset_fpmode:
3434 case Intrinsic::get_rounding:
3437 case Intrinsic::set_rounding:
3440 case Intrinsic::vscale: {
3444 case Intrinsic::scmp:
3445 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3449 case Intrinsic::ucmp:
3450 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3454 case Intrinsic::vector_extract:
3455 return translateExtractVector(CI, MIRBuilder);
3456 case Intrinsic::vector_insert:
3457 return translateInsertVector(CI, MIRBuilder);
3458 case Intrinsic::stepvector: {
3462 case Intrinsic::prefetch: {
3469 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3472 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3478 case Intrinsic::speculative_load: {
3482 Register Dst = getOrCreateVReg(CI);
3484 Flags |= TLI->getTargetMMOFlags(CI);
3487 if (CI.
hasMetadata(LLVMContext::MD_invariant_load))
3489 auto *MMO = MF->getMachineMemOperand(
3490 MachinePointerInfo(Ptr), Flags, MRI->getType(Dst),
3492 MIRBuilder.
buildLoad(Dst, getOrCreateVReg(*Ptr), *MMO);
3496 case Intrinsic::vector_interleave2:
3497 case Intrinsic::vector_deinterleave2: {
3505 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3507 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3510#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3511 case Intrinsic::INTRINSIC:
3512#include "llvm/IR/ConstrainedOps.def"
3515 case Intrinsic::experimental_convergence_anchor:
3516 case Intrinsic::experimental_convergence_entry:
3517 case Intrinsic::experimental_convergence_loop:
3518 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3519 case Intrinsic::reloc_none: {
3522 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3530bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3532 if (!mayTranslateUserTypes(CB))
3535 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3539 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3544 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3547bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3554 for (
const auto &Arg : CB.
args()) {
3556 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3558 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3559 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3560 &CB, &MIRBuilder.
getMBB(), Arg));
3563 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3566 Args.push_back(getOrCreateVRegs(*Arg));
3570 if (ORE->enabled()) {
3572 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3578 std::optional<CallLowering::PtrAuthInfo> PAI;
3583 const Value *
Key = Bundle->Inputs[0];
3590 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3591 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3593 Register DiscReg = getOrCreateVReg(*Discriminator);
3601 const auto &Token = *Bundle->Inputs[0].get();
3602 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3608 bool Success = CLI->lowerCall(
3609 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3614 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3615 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3622bool IRTranslatorImpl::translateCall(
const User &U,
3624 if (!mayTranslateUserTypes(U))
3632 if (
F && (
F->hasDLLImportStorageClass() ||
3633 (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI() &&
3634 F->hasExternalWeakLinkage())))
3646 return translateInlineAsm(CI, MIRBuilder);
3650 if (translateCallBase(CI, MIRBuilder)) {
3659 if (!MF->getSubtarget().isIntrinsicSupported(ID))
3660 return handleUnsupportedIntrinsic(CI, ID, MIRBuilder);
3662 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3666 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3668 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3671bool IRTranslatorImpl::handleUnsupportedIntrinsic(
3674 F.getContext().diagnose(
3675 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3686bool IRTranslatorImpl::translateIntrinsic(
3689 if (!MF->getSubtarget().isIntrinsicSupported(ID))
3690 return handleUnsupportedIntrinsic(CB, ID, MIRBuilder);
3694 ResultRegs = getOrCreateVRegs(CB);
3698 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3709 assert(CI->getBitWidth() <= 64 &&
3710 "large intrinsic immediates not handled");
3711 MIB.
addImm(CI->getSExtValue());
3716 auto *MD = MDVal->getMetadata();
3720 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3727 if (VRegs.
size() > 1)
3734 for (
const auto &Info : TgtMemIntrinsicInfos) {
3737 LLT MemTy =
Info.memVT.isSimple()
3739 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3743 MachinePointerInfo MPI;
3745 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3746 }
else if (
Info.fallbackAddressSpace) {
3747 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3756 auto *Token = Bundle->Inputs[0].get();
3757 Register TokenReg = getOrCreateVReg(*Token);
3768bool IRTranslatorImpl::findUnwindDestinations(
3780 if (IsWasmCXX || IsWasmD) {
3790 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3796 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3797 UnwindDests.back().first->setIsEHScopeEntry();
3798 UnwindDests.back().first->setIsEHFuncletEntry();
3803 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3804 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3806 if (IsMSVCCXX || IsCoreCLR)
3807 UnwindDests.back().first->setIsEHFuncletEntry();
3809 UnwindDests.back().first->setIsEHScopeEntry();
3811 NewEHPadBB = CatchSwitch->getUnwindDest();
3816 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3817 if (BPI && NewEHPadBB)
3819 EHPadBB = NewEHPadBB;
3824bool IRTranslatorImpl::translateInvoke(
const User &U,
3827 MCContext &
Context = MF->getContext();
3832 const Function *Fn =
I.getCalledFunction();
3839 if (
I.hasDeoptState())
3853 (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI() &&
3857 bool LowerInlineAsm =
I.isInlineAsm();
3858 bool NeedEHLabel =
true;
3864 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3865 BeginSymbol =
Context.createTempSymbol();
3869 if (LowerInlineAsm) {
3870 if (!translateInlineAsm(
I, MIRBuilder))
3872 }
else if (!translateCallBase(
I, MIRBuilder))
3877 EndSymbol =
Context.createTempSymbol();
3882 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3883 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3884 BranchProbability EHPadBBProb =
3888 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3891 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3892 &ReturnMBB = getMBB(*ReturnBB);
3894 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3895 for (
auto &UnwindDest : UnwindDests) {
3896 UnwindDest.first->setIsEHPad();
3897 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3902 assert(BeginSymbol &&
"Expected a begin symbol!");
3903 assert(EndSymbol &&
"Expected an end symbol!");
3904 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3907 MIRBuilder.
buildBr(ReturnMBB);
3913bool IRTranslatorImpl::translateCallBr(
const User &U,
3915 if (!mayTranslateUserTypes(U))
3919 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3922 if (
I.isInlineAsm()) {
3928 if (!translateIntrinsic(
I, IID, MIRBuilder))
3932 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3933 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3942 for (BasicBlock *Dest :
I.getIndirectDests()) {
3943 MachineBasicBlock &
Target = getMBB(*Dest);
3944 Target.setIsInlineAsmBrIndirectTarget();
3945 Target.setLabelMustBeEmitted();
3947 if (Dests.
insert(Dest).second)
3959bool IRTranslatorImpl::translateLandingPad(
const User &U,
3963 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3969 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3970 if (TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel,
3971 PersonalityFn) == 0 &&
3972 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel,
3973 PersonalityFn) == 0)
3988 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3993 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3994 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3995 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
4004 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
4008 TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel, PersonalityFn);
4014 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
4017 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel, PersonalityFn);
4022 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
4023 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
4024 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
4029bool IRTranslatorImpl::translateAlloca(
const User &U,
4037 Register Res = getOrCreateVReg(AI);
4038 int FI = getOrCreateFrameIndex(AI);
4048 if (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI())
4053 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4055 if (MRI->getType(NumElts) !=
IntPtrTy) {
4067 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4072 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4074 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4079 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4088 if (Alignment <= StackAlign)
4092 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4093 assert(MF->getFrameInfo().hasVarSizedObjects());
4097bool IRTranslatorImpl::translateVAArg(
const User &U,
4103 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4104 {getOrCreateVReg(*
U.getOperand(0)),
4105 DL->getABITypeAlign(
U.getType()).value()});
4109bool IRTranslatorImpl::translateUnreachable(
const User &U,
4112 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4113 MF->getTarget().Options.NoTrapAfterNoreturn))
4120bool IRTranslatorImpl::translateInsertElement(
const User &U,
4125 FVT && FVT->getNumElements() == 1)
4126 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4129 Register Val = getOrCreateVReg(*
U.getOperand(0));
4130 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4131 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4134 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4135 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4136 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4137 Idx = getOrCreateVReg(*NewIdxCI);
4141 Idx = getOrCreateVReg(*
U.getOperand(2));
4142 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4143 const LLT VecIdxTy =
4144 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4151bool IRTranslatorImpl::translateInsertVector(
const User &U,
4154 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4155 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4158 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4163 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4168 ResultType && ResultType->getNumElements() == 1) {
4170 InputType && InputType->getNumElements() == 1) {
4174 return translateCopy(U, Vec, MIRBuilder);
4189 auto ScaledIndex = MIRBuilder.
buildMul(
4190 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4200bool IRTranslatorImpl::translateExtractElement(
const User &U,
4204 if (
const FixedVectorType *FVT =
4206 if (FVT->getNumElements() == 1)
4207 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4210 Register Val = getOrCreateVReg(*
U.getOperand(0));
4211 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4216 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4217 Idx = getOrCreateVReg(*NewIdxCI);
4221 Idx = getOrCreateVReg(*
U.getOperand(1));
4222 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4223 const LLT VecIdxTy =
4231bool IRTranslatorImpl::translateExtractVector(
const User &U,
4234 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4236 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4241 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4246 ResultType && ResultType->getNumElements() == 1) {
4248 InputType && InputType->getNumElements() == 1) {
4251 return translateCopy(U, Vec, MIRBuilder);
4266 auto ScaledIndex = MIRBuilder.
buildMul(
4267 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4277bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4283 if (
U.getOperand(0)->getType()->isScalableTy()) {
4284 Register Val = getOrCreateVReg(*
U.getOperand(0));
4286 MRI->getType(Val).getElementType(), Val, 0);
4293 Mask = SVI->getShuffleMask();
4304 unsigned M =
Mask[0];
4306 if (M == 0 || M == 1)
4307 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4313 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4314 }
else if (M < SrcElts * 2) {
4316 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4328 for (
int M : Mask) {
4330 if (M == 0 || M == 1) {
4331 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4333 if (!
Undef.isValid()) {
4334 Undef = MRI->createGenericVirtualRegister(SrcTy);
4344 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4346 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4347 {getOrCreateVReg(*
U.getOperand(0)),
4348 getOrCreateVReg(*
U.getOperand(1))})
4349 .addShuffleMask(MaskAlloc);
4353bool IRTranslatorImpl::translateBitInsert(
const User &U,
4357 Register Val = getOrCreateVReg(*
U.getOperand(1));
4359 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4361 LLT ValTy = MRI.getType(Val);
4364 "bitinsert val wider than base should be rejected by verifier");
4377 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(BaseTy);
4394 MIRBuilder.
buildOr(Res, ClearedBase, ShiftedVal);
4398bool IRTranslatorImpl::translateBitExtract(
const User &U,
4401 Register Src = getOrCreateVReg(*
U.getOperand(0));
4403 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4404 LLT SrcTy = MRI.getType(Src);
4405 LLT ResTy = MRI.getType(Res);
4408 "bitextract result wider than source should be rejected by verifier");
4411 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(SrcTy);
4421 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4423 if (SrcTy == IntResTy)
4434 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4436 if (SrcTy == IntResTy)
4453bool IRTranslatorImpl::translatePHI(
const User &U,
4457 SmallVector<MachineInstr *, 4> Insts;
4458 for (
auto Reg : getOrCreateVRegs(PI)) {
4459 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4463 PendingPHIs.emplace_back(&PI, std::move(Insts));
4467bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4471 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4473 auto Res = getOrCreateVRegs(
I);
4476 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4477 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4478 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4481 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4482 *MF->getMachineMemOperand(
4483 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4484 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4485 I.getSuccessOrdering(),
I.getFailureOrdering()));
4489bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4491 if (!mayTranslateUserTypes(U))
4495 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4498 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4499 Register Val = getOrCreateVReg(*
I.getValOperand());
4501 unsigned Opcode = 0;
4502 switch (
I.getOperation()) {
4506 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4509 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4512 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4515 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4518 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4521 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4524 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4527 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4530 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4533 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4536 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4539 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4542 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4545 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4548 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4551 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4554 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4557 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4560 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4563 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4566 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4569 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4572 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4577 Opcode, Res, Addr, Val,
4578 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4579 Flags, MRI->getType(Val), getMemOpAlign(
I),
4580 I.getAAMetadata(),
I.getSyncScopeID(),
4585bool IRTranslatorImpl::translateFence(
const User &U,
4589 Fence.getSyncScopeID());
4593bool IRTranslatorImpl::translateFreeze(
const User &U,
4599 "Freeze with different source and destination type?");
4601 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4608void IRTranslatorImpl::finishPendingConstDbgValues() {
4609 for (
auto [
MI,
C] : PendingConstDbgValues) {
4610 auto VRegsIt = VMap.findVRegs(*
C);
4611 if (VRegsIt == VMap.vregs_end() || VRegsIt->second->size() != 1)
4615 MachineIRBuilder Builder(*
MI);
4616 Builder.buildDirectDbgValue(VRegsIt->second->front(),
4617 MI->getDebugVariable(),
4618 MI->getDebugExpression());
4619 MI->eraseFromParent();
4621 PendingConstDbgValues.clear();
4624void IRTranslatorImpl::finishPendingPhis() {
4627 GISelObserverWrapper WrapperObserver(&
Verifier);
4628 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4630 for (
auto &Phi : PendingPHIs) {
4631 const PHINode *PI =
Phi.first;
4635 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4641 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4645 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4649 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4650 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4659void IRTranslatorImpl::translateDbgValueRecord(
Value *V,
bool HasArgList,
4665 "Expected inlined-at fields to agree");
4669 if (!V || HasArgList) {
4679 PendingConstDbgValues.emplace_back(
MI, CI);
4689 auto *ExprDerefRemoved =
4695 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
4707void IRTranslatorImpl::translateDbgDeclareRecord(
4712 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4717 "Expected inlined-at fields to agree");
4722 MF->setVariableDbgInfo(Variable, Expression,
4723 getOrCreateFrameIndex(*AI), DL);
4727 if (translateIfEntryValueArgument(
true,
Address, Variable,
4739void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4744 assert(DLR->getLabel() &&
"Missing label");
4745 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4747 "Expected inlined-at fields to agree");
4756 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
4759 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
4764bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4766 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4767 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4769 if (TLI->fallBackToDAGISel(Inst))
4773#define HANDLE_INST(NUM, OPCODE, CLASS) \
4774 case Instruction::OPCODE: \
4775 return translate##OPCODE(Inst, *CurBuilder.get());
4776#include "llvm/IR/Instruction.def"
4785 if (
auto CurrInstDL = CurBuilder->getDL())
4786 EntryBuilder->setDebugLoc(
DebugLoc());
4792 EntryBuilder->buildConstant(
Reg, *CI);
4796 EntryBuilder->buildConstant(
Reg, CB->getValue());
4800 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4801 EntryBuilder->buildFConstant(
Reg, *CF);
4803 EntryBuilder->buildUndef(
Reg);
4805 EntryBuilder->buildConstant(
Reg, 0);
4807 EntryBuilder->buildGlobalValue(
Reg, GV);
4809 Register Addr = getOrCreateVReg(*CPA->getPointer());
4810 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4811 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4813 Constant &Elt = *CAZ->getElementValue(0u);
4815 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4819 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4821 return translateCopy(
C, Elt, *EntryBuilder);
4823 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4826 if (CV->getNumElements() == 1)
4827 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4829 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4830 Constant &Elt = *CV->getElementAsConstant(i);
4831 Ops.push_back(getOrCreateVReg(Elt));
4833 EntryBuilder->buildBuildVector(
Reg,
Ops);
4835 switch(
CE->getOpcode()) {
4836#define HANDLE_INST(NUM, OPCODE, CLASS) \
4837 case Instruction::OPCODE: \
4838 return translate##OPCODE(*CE, *EntryBuilder.get());
4839#include "llvm/IR/Instruction.def"
4844 if (CV->getNumOperands() == 1)
4845 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4847 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4848 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4850 EntryBuilder->buildBuildVector(
Reg,
Ops);
4852 EntryBuilder->buildBlockAddress(
Reg, BA);
4859bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4860 const TargetMachine &TM = TLI->getTargetMachine();
4869 (!
U.getType()->getScalarType()->isBFloatTy() &&
4871 return V->getType()->getScalarType()->isBFloatTy();
4875bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4877 for (
auto &BTB : SL->BitTestCases) {
4880 emitBitTestHeader(BTB, BTB.Parent);
4882 BranchProbability UnhandledProb = BTB.Prob;
4883 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4884 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4886 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4895 MachineBasicBlock *NextMBB;
4896 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4899 NextMBB = BTB.Cases[
j + 1].TargetBB;
4900 }
else if (j + 1 == ej) {
4902 NextMBB = BTB.Default;
4905 NextMBB = BTB.Cases[
j + 1].ThisBB;
4908 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4910 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4914 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4915 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4918 BTB.Cases.pop_back();
4924 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4925 BTB.Default->getBasicBlock()};
4926 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4927 if (!BTB.ContiguousRange) {
4928 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4931 SL->BitTestCases.clear();
4933 for (
auto &JTCase : SL->JTCases) {
4935 if (!JTCase.first.Emitted)
4936 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4938 emitJumpTable(JTCase.second, JTCase.second.MBB);
4940 SL->JTCases.clear();
4942 for (
auto &SwCase : SL->SwitchCases)
4943 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4944 SL->SwitchCases.clear();
4947 if (SPInfo->shouldEmitSDCheck(BB)) {
4948 bool FunctionBasedInstrumentation =
4949 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4950 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4953 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4956 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4957 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4958 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4967 ParentMBB, *MF->getSubtarget().getInstrInfo());
4970 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4974 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4978 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4979 if (FailureMBB->
empty()) {
4980 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4985 SPDescriptor.resetPerBBState();
4992 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4996 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
5002 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
5009 ->buildLoad(PtrMemTy, StackSlotPtr,
5015 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
5027 FunctionType *FnTy = GuardCheckFn->getFunctionType();
5028 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
5029 ISD::ArgFlagsTy
Flags;
5030 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
5032 CallLowering::ArgInfo GuardArgInfo(
5033 {GuardVal, FnTy->getParamType(0), {
Flags}});
5035 CallLowering::CallLoweringInfo
Info;
5036 Info.OrigArgs.push_back(GuardArgInfo);
5037 Info.CallConv = GuardCheckFn->getCallingConv();
5040 if (!CLI->lowerCall(MIRBuilder, Info)) {
5041 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
5051 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
5052 getStackGuard(Guard, *CurBuilder);
5055 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
5057 Register GuardPtr = getOrCreateVReg(*IRGuard);
5060 ->buildLoad(PtrMemTy, GuardPtr,
5066 LLVMContext &Ctx = CurBuilder->getContext();
5067 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
5068 Guard = CurBuilder->buildUndef(PtrMemTy).getReg(0);
5084 const RTLIB::LibcallImpl LibcallImpl =
5085 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
5086 if (LibcallImpl == RTLIB::Unsupported)
5089 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
5091 CallLowering::CallLoweringInfo
Info;
5092 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
5094 StringRef LibcallName =
5099 if (!CLI->lowerCall(*CurBuilder, Info)) {
5100 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
5105 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
5107 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
5112void IRTranslatorImpl::finalizeFunction() {
5115 PendingPHIs.clear();
5116 PendingConstDbgValues.clear();
5118 FrameIndices.clear();
5119 MachinePreds.clear();
5123 EntryBuilder.reset();
5126 SPDescriptor.resetPerFunctionState();
5139 return CI && CI->isMustTailCall();
5151 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
5152 CLI = MF->getSubtarget().getCallLowering();
5153 SPInfo = StackProtectorInfo;
5155 if (CLI->fallBackToDAGISel(*MF)) {
5157 F.getSubprogram(), &
F.getEntryBlock());
5158 R <<
"unable to lower function: "
5159 <<
ore::NV(
"Prototype",
F.getFunctionType());
5176 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5177 CSEInfo = GetCSEInfo();
5178 EntryBuilder->setCSEInfo(CSEInfo);
5179 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5180 CurBuilder->setCSEInfo(CSEInfo);
5182 EntryBuilder = std::make_unique<MachineIRBuilder>();
5183 CurBuilder = std::make_unique<MachineIRBuilder>();
5186 CurBuilder->setMF(*MF);
5187 EntryBuilder->setMF(*MF);
5188 MRI = &MF->getRegInfo();
5189 DL = &
F.getDataLayout();
5193 FuncInfo.ExceptionModel =
F.getParent()->getExceptionModel();
5195 AA = GetAAResults();
5196 FuncInfo.BPI = GetBPI();
5200 FuncInfo.BPI =
nullptr;
5203 LibInfo = LibraryInfo;
5204 Libcalls = LibcallInfo;
5206 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5208 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5209 SL->init(*TLI, TM, *DL);
5211 assert(PendingPHIs.empty() &&
"stale PHIs");
5215 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5218 F.getSubprogram(), &
F.getEntryBlock());
5219 R <<
"unable to translate in big endian mode";
5230 EntryBuilder->setMBB(*EntryBB);
5232 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5233 SwiftError.setFunction(CurMF);
5234 SwiftError.createEntriesInEntryBlock(DbgLoc);
5236 bool IsVarArg =
F.isVarArg();
5237 bool HasMustTailInVarArgFn =
false;
5240 unsigned NumValues =
F.arg_size();
5243 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5245 NumValues += BB.
size();
5248 MBB = MF->CreateMachineBasicBlock(&BB);
5256 if (!BA->hasZeroLiveUses())
5260 if (!HasMustTailInVarArgFn)
5264 VMap.reserveVRegs(NumValues);
5265 MRI->reserveVirtRegs(NumValues);
5267 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5270 EntryBB->addSuccessor(&getMBB(
F.front()));
5275 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5280 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5281 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5282 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5286 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5288 F.getSubprogram(), &
F.getEntryBlock());
5289 R <<
"unable to lower arguments: "
5290 <<
ore::NV(
"Prototype",
F.getFunctionType());
5297 if (EnableCSE && CSEInfo)
5302 DILocationVerifier Verifier;
5310 CurBuilder->setMBB(
MBB);
5311 HasTailCall =
false;
5321 Verifier.setCurrentInst(&Inst);
5325 translateDbgInfo(Inst, *CurBuilder);
5327 if (translate(Inst))
5332 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5334 if (ORE->allowExtraAnalysis(
"gisel-ir-translator")) {
5335 std::string InstStrStorage;
5339 R <<
": '" << InstStrStorage <<
"'";
5346 if (!finalizeBasicBlock(*BB,
MBB)) {
5348 BB->getTerminator()->getDebugLoc(), BB);
5349 R <<
"unable to translate basic block";
5359 finishPendingPhis();
5360 finishPendingConstDbgValues();
5362 SwiftError.propagateVRegs();
5367 assert(EntryBB->succ_size() == 1 &&
5368 "Custom BB used for lowering should have only one successor");
5372 "LLVM-IR entry block has a predecessor!?");
5375 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5384 EntryBB->removeSuccessor(&NewEntryBB);
5385 MF->remove(EntryBB);
5386 MF->deleteMachineBasicBlock(EntryBB);
5388 assert(&MF->front() == &NewEntryBB &&
5389 "New entry wasn't next in the list of basic block!");
5392 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5402 return Impl->runOnMachineFunction(
5421 *
F.getParent(), Subtarget),
5446 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5447 Impl->runOnMachineFunction(
5449 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 const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
The address of a basic block.
static LLVM_ABI BlockAddress * lookup(const BasicBlock *BB)
Lookup an existing BlockAddress constant for the given BasicBlock.
Legacy analysis pass which computes BlockFrequencyInfo.
Analysis pass which computes BranchProbabilityInfo.
Legacy analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
static constexpr BranchProbability getOne()
static constexpr BranchProbability getUnknown()
static constexpr BranchProbability getZero()
static void normalizeProbabilities(ProbabilityIter Begin, ProbabilityIter End)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool isInlineAsm() const
Check if this call is an inline asm statement.
bool cannotMerge() const
Determine if the call cannot be tail merged.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
unsigned countOperandBundlesOfType(StringRef Name) const
Return the number of operand bundles with the tag Name attached to this instruction.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Value * getCalledOperand() const
Value * getArgOperand(unsigned i) const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
bool isConvergent() const
Determine if the invoke is convergent.
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
bool isFPPredicate() const
bool isIntPredicate() const
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This is the common base class for constrained floating point intrinsics.
LLVM_ABI std::optional< fp::ExceptionBehavior > getExceptionBehavior() const
LLVM_ABI unsigned getNonMetadataArgCount() const
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
LLVM_ABI bool startsWithDeref() const
Return whether the first element a DW_OP_deref.
ArrayRef< uint64_t > getElements() const
A parsed version of the target data layout string in and methods for querying it.
DebugLoc getDebugLoc() const
LLVM_ABI Value * getVariableLocationOp(unsigned OpIdx) const
DIExpression * getExpression() const
DILocalVariable * getVariable() const
bool isDbgDeclare() const
static DebugLoc getDropped()
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Class representing an expression and its matching format.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Constant * getPersonalityFn() const
Get the personality function associated with this function.
const Function & getFunction() const
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasOptNone() const
Do not optimize this function (-O0).
The actual analysis pass wrapper.
Simple wrapper that does the following.
Abstract class that contains various methods for clients to notify about changes.
Simple wrapper observer that takes several observers, and calls each one for each event.
void removeObserver(GISelChangeObserver *O)
void addObserver(GISelChangeObserver *O)
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
bool hasExternalWeakLinkage() const
bool hasDLLImportStorageClass() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isTailCall(const MachineInstr &MI) const override
IRTranslatorImpl(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
bool runOnMachineFunction(MachineFunction &MF, function_ref< GISelCSEInfo *()> GetCSEInfo, bool ShouldSkipOpts, function_ref< AAResults *()> GetAAResults, function_ref< BranchProbabilityInfo *()> GetBPI, function_ref< AssumptionCache *()> GetAC, TargetLibraryInfo *LibraryInfo, const LibcallLoweringInfo *LibcallInfo, SSPLayoutInfo *StackProtectorInfo)
IRTranslatorLegacy(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
~IRTranslatorLegacy() override
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI ~IRTranslatorPass()
LLVM_ABI IRTranslatorPass(CodeGenOptLevel OptLevel)
bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB, std::function< ArrayRef< Register >(const Value &Val)> GetOrCreateVRegs) const
Lower the given inline asm call instruction GetOrCreateVRegs is a callback to materialize a register ...
This instruction inserts a struct field of array element value into an aggregate value.
iterator_range< simple_ilist< DbgRecord >::iterator > getDbgRecordRange() const
Return a range over the DbgRecords attached to this instruction.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static bool getUseExtended()
constexpr bool isScalar() const
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isFloat() const
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
static constexpr LLT token()
Get a low-level token; just a scalar with zero bits (or no size).
static LLT integer(unsigned SizeInBits)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Tracks which library functions to use for a particular subtarget or function.
Value * getPointerOperand()
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this load instruction.
static LocationSize precise(uint64_t Value)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned pred_size() const
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void setSuccProbability(succ_iterator I, BranchProbability Prob)
Set successor probability of a given iterator.
succ_iterator succ_begin()
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
LLVM_ABI void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
LLVM_ABI bool isPredecessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a predecessor of this block.
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
int getStackProtectorIndex() const
Return the index for the stack protector object.
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
Helper class to build MachineInstr.
MachineInstrBuilder buildFPTOUI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOUI_SAT Src0.
MachineInstrBuilder buildFMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildFreeze(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_FREEZE Src.
MachineInstrBuilder buildBr(MachineBasicBlock &Dest)
Build and insert G_BR Dest.
MachineInstrBuilder buildModf(const DstOp &Fract, const DstOp &Int, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Int = G_FMODF Src.
LLVMContext & getContext() const
MachineInstrBuilder buildAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_ADD Op0, Op1.
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
MachineInstrBuilder buildResetFPMode()
Build and insert G_RESET_FPMODE.
MachineInstrBuilder buildNot(const DstOp &Dst, const SrcOp &Src0)
Build and insert a bitwise not, NegOne = G_CONSTANT -1 Res = G_OR Op0, NegOne.
MachineInstrBuilder buildFPTOSI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOSI_SAT Src0.
MachineInstrBuilder buildUCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_UCMP Op0, Op1.
MachineInstrBuilder buildJumpTable(const LLT PtrTy, unsigned JTI)
Build and insert Res = G_JUMP_TABLE JTI.
MachineInstrBuilder buildGetRounding(const DstOp &Dst)
Build and insert Dst = G_GET_ROUNDING.
MachineInstrBuilder buildSCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_SCMP Op0, Op1.
MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope)
Build and insert G_FENCE Ordering, Scope.
MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
MachineInstrBuilder buildFMA(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, const SrcOp &Src2, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FMA Op0, Op1, Op2.
MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_MUL Op0, Op1.
MachineInstrBuilder buildInsertSubvector(const DstOp &Res, const SrcOp &Src0, const SrcOp &Src1, unsigned Index)
Build and insert Res = G_INSERT_SUBVECTOR Src0, Src1, Idx.
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildCast(const DstOp &Dst, const SrcOp &Src)
Build and insert an appropriate cast between two registers of equal size.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
MachineInstrBuilder buildLShr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
MachineInstrBuilder buildSExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildAtomicRMW(unsigned Opcode, const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val, MachineMemOperand &MMO)
Build and insert OldValRes<def> = G_ATOMICRMW_<Opcode> Addr, Val, MMO.
MachineInstrBuilder buildSub(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_SUB Op0, Op1.
MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef< Register > Res, bool HasSideEffects, bool isConvergent)
Build and insert a G_INTRINSIC instruction.
MachineInstrBuilder buildVScale(const DstOp &Res, unsigned MinElts)
Build and insert Res = G_VSCALE MinElts.
MachineInstrBuilder buildSplatBuildVector(const DstOp &Res, const SrcOp &Src)
Build and insert Res = G_BUILD_VECTOR with Src replicated to fill the number of elements.
MachineInstrBuilder buildSetFPMode(const SrcOp &Src)
Build and insert G_SET_FPMODE Src.
MachineInstrBuilder buildIntToPtr(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_INTTOPTR instruction.
MachineInstrBuilder buildIndirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in me...
MachineInstrBuilder buildBuildVector(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ...
MachineInstrBuilder buildConstDbgValue(const Constant &C, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instructions specifying that Variable is given by C (suitably modified b...
MachineInstrBuilder buildBrCond(const SrcOp &Tst, MachineBasicBlock &Dest)
Build and insert G_BRCOND Tst, Dest.
std::optional< MachineInstrBuilder > materializeObjectPtrOffset(Register &Res, Register Op0, const LLT ValueTy, uint64_t Value)
Materialize and insert an instruction with appropriate flags for addressing some offset of an object,...
MachineInstrBuilder buildSetRounding(const SrcOp &Src)
Build and insert G_SET_ROUNDING.
MachineInstrBuilder buildExtractVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_PTR_ADD Op0, Op1.
MachineInstrBuilder buildZExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildExtractVectorElementConstant(const DstOp &Res, const SrcOp &Val, const int Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildShl(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineInstrBuilder buildDirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in Re...
MachineInstrBuilder buildDbgLabel(const MDNode *Label)
Build and insert a DBG_LABEL instructions specifying that Label is given.
MachineInstrBuilder buildBrJT(Register TablePtr, unsigned JTI, Register IndexReg)
Build and insert G_BRJT TablePtr, JTI, IndexReg.
MachineInstrBuilder buildDynStackAlloc(const DstOp &Res, const SrcOp &Size, Align Alignment)
Build and insert Res = G_DYN_STACKALLOC Size, Align.
MachineInstrBuilder buildFIDbgValue(int FI, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in th...
MachineInstrBuilder buildResetFPEnv()
Build and insert G_RESET_FPENV.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
void setDebugLoc(const DebugLoc &DL)
Set the debug location to DL for all the next build instructions.
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
MachineInstrBuilder buildInsertVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Elt, const SrcOp &Idx)
Build and insert Res = G_INSERT_VECTOR_ELT Val, Elt, Idx.
MachineInstrBuilder buildAtomicCmpXchgWithSuccess(const DstOp &OldValRes, const DstOp &SuccessRes, const SrcOp &Addr, const SrcOp &CmpVal, const SrcOp &NewVal, MachineMemOperand &MMO)
Build and insert OldValRes<def>, SuccessRes<def> = / G_ATOMIC_CMPXCHG_WITH_SUCCESS Addr,...
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
MachineInstrBuilder buildBitcast(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_BITCAST Src.
const DebugLoc & getDebugLoc()
Get the current instruction's debug location.
MachineInstrBuilder buildTrap(bool Debug=false)
Build and insert G_TRAP or G_DEBUGTRAP.
MachineInstrBuilder buildFFrexp(const DstOp &Fract, const DstOp &Exp, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Exp = G_FFREXP Src.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildOr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_OR Op0, Op1.
MachineInstrBuilder buildFSincos(const DstOp &Sin, const DstOp &Cos, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Sin, Cos = G_FSINCOS Src.
MachineInstrBuilder buildShuffleVector(const DstOp &Res, const SrcOp &Src1, const SrcOp &Src2, ArrayRef< int > Mask)
Build and insert Res = G_SHUFFLE_VECTOR Src1, Src2, Mask.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildPrefetch(const SrcOp &Addr, unsigned RW, unsigned Locality, unsigned CacheType, MachineMemOperand &MMO)
Build and insert G_PREFETCH Addr, RW, Locality, CacheType.
MachineInstrBuilder buildExtractSubvector(const DstOp &Res, const SrcOp &Src, unsigned Index)
Build and insert Res = G_EXTRACT_SUBVECTOR Src, Idx0.
const DataLayout & getDataLayout() const
MachineInstrBuilder buildBrIndirect(Register Tgt)
Build and insert G_BRINDIRECT Tgt.
MachineInstrBuilder buildSplatVector(const DstOp &Res, const SrcOp &Val)
Build and insert Res = G_SPLAT_VECTOR Val.
MachineInstrBuilder buildStepVector(const DstOp &Res, unsigned Step)
Build and insert Res = G_STEP_VECTOR Step.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_FCMP PredOp0, Op1.
MachineInstrBuilder buildFAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FADD Op0, Op1.
MachineInstrBuilder buildSetFPEnv(const SrcOp &Src)
Build and insert G_SET_FPENV Src.
MachineInstrBuilder buildPtrToInt(const DstOp &Dst, const SrcOp &Src)
Build and insert a G_PTRTOINT instruction.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addFPImm(const ConstantFP *Val) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
LLVM_ABI void copyIRFlags(const Instruction &I)
Copy all flags to MachineInst MIFlags.
static LLVM_ABI uint32_t copyFlagsFromInstruction(const Instruction &I)
LLVM_ABI void setDeactivationSymbol(MachineFunction &MF, Value *DS)
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MONonTemporal
The memory access is non-temporal.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
static MachineOperand CreateES(const char *SymName, unsigned TargetFlags=0)
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
A set of analyses that are preserved following a run of a transformation pass.
Class to install both of the above.
Wrapper class representing virtual and physical registers.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Encapsulates all of the information needed to generate a stack protector check, and signals to isel w...
MachineBasicBlock * getSuccessMBB()
MachineBasicBlock * getFailureMBB()
constexpr bool empty() const
Check if the string is empty.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
SwitchLowering(FunctionLoweringInfo &funcinfo)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
const Target & getTarget() const
unsigned NoTrapAfterNoreturn
Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
Target-Independent Code Generator Pass Configuration Options.
virtual std::unique_ptr< CSEConfigBase > getCSEConfig() const
Returns the CSEConfig object to use for the current optimization level.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const CallLowering * getCallLowering() const
virtual const TargetLowering * getTargetLowering() const
bool isSPIRV() const
Tests whether the target is SPIR-V (32/64-bit/Logical).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getZero()
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isByteOrByteVectorTy() const
Return true if this is a byte type or a vector of byte types.
bool isAggregateType() const
Return true if the type is an aggregate type.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isTokenTy() const
Return true if this is 'token'.
bool isVoidTy() const
Return true if this is 'void'.
BasicBlock * getSuccessor(unsigned i=0) const
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
constexpr bool isZero() const
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
A raw_ostream that writes to an std::string.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
LLVM_ABI void sortAndRangeify(CaseClusterVector &Clusters)
Sort Clusters and merge adjacent cases.
std::vector< CaseCluster > CaseClusterVector
@ CC_Range
A cluster of adjacent case labels with the same destination, or just one case.
@ CC_JumpTable
A cluster of cases suitable for jump table lowering.
@ CC_BitTests
A cluster of cases suitable for bit test lowering.
SmallVector< SwitchWorkListItem, 4 > SwitchWorkList
CaseClusterVector::iterator CaseClusterIt
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
ExceptionBehavior
Exception behavior used for floating point operations.
@ ebIgnore
This corresponds to "fpexcept.ignore".
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< PhiNode * > Phi
NodeAddr< CodeNode * > Code
friend class Instruction
Iterator for Instructions in a `BasicBlock.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
LLVM_ABI void diagnoseDontCall(const CallInst &CI)
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool isExceptionPointerAndSelectorType(Type *Ty)
Return true if landingpad result type Ty is a struct of an exception pointer (pointer or integer) and...
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
gep_type_iterator gep_type_end(const User *GEP)
LLVM_ABI MachineBasicBlock::iterator findSplitPointForStackProtector(MachineBasicBlock *BB, const TargetInstrInfo &TII)
Find the split point at which to splice the end of BB into its success stack protector check machine ...
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI llvm::SmallVector< int, 16 > createStrideMask(unsigned Start, unsigned Stride, unsigned VF)
Create a stride shuffle mask.
auto reverse(ContainerTy &&C)
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
auto succ_size(const MachineBasicBlock *BB)
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Global
Append to llvm.global_dtors.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
LLVM_ABI llvm::SmallVector< int, 16 > createInterleaveMask(unsigned VF, unsigned NumVecs)
Create an interleave shuffle mask.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::optional< RoundingMode > convertStrToRoundingMode(StringRef)
Returns a valid RoundingMode enumerator when given a string that is valid as input in constrained int...
gep_type_iterator gep_type_begin(const User *GEP)
LLVM_ABI void computeValueLLTs(const DataLayout &DL, Type &Ty, SmallVectorImpl< LLT > &ValueLLTs, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
computeValueLLTs - Given an LLVM IR type, compute a sequence of LLTs that represent all the individua...
LLVM_ABI GlobalValue * ExtractTypeInfo(Value *V)
ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Pair of physical register and lane mask.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
static StringRef getLibcallImplName(RTLIB::LibcallImpl CallImpl)
Get the libcall routine name for the specified libcall implementation.
bool shouldSkipOptimizationForOptBisect(IRUnitRef IR)
MachineBasicBlock * Parent
This structure is used to communicate between SelectionDAGBuilder and SDISel for the code generation ...
BranchProbability TrueProb
MachineBasicBlock * ThisBB
struct PredInfoPair PredInfo
BranchProbability FalseProb
MachineBasicBlock * TrueBB
MachineBasicBlock * FalseBB
Register Reg
The virtual register containing the index of the jump table entry to jump to.
MachineBasicBlock * Default
The MBB of the default bb, which is a successor of the range check MBB.
unsigned JTI
The JumpTableIndex for this jump table in the function.
MachineBasicBlock * MBB
The MBB into which to emit the code for the indirect jump.