70#include "llvm/IR/IntrinsicsAMDGPU.h"
100#define DEBUG_TYPE "ir-translator"
106 cl::desc(
"Should enable CSE in ir-translator"),
118 class ValueToVRegInfo {
120 ValueToVRegInfo() =
default;
125 using const_vreg_iterator =
128 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
130 VRegListT *getVRegs(
const Value &V) {
131 auto [It, Inserted] = ValToVRegs.try_emplace(&V);
137 It->second =
new (VRegAlloc.Allocate()) VRegListT();
141 OffsetListT *getOffsets(
const Value &V) {
142 assert(V.getType()->isAggregateType() &&
143 "Offsets are for aggregate values");
144 auto [It, Inserted] = TypeToOffsets.try_emplace(V.getType());
148 It->second =
new (OffsetAlloc.Allocate()) OffsetListT();
152 const_vreg_iterator findVRegs(
const Value &V)
const {
153 return ValToVRegs.find(&V);
156 bool contains(
const Value &V)
const {
return ValToVRegs.contains(&V); }
158 void reserveVRegs(
unsigned NumValues) { ValToVRegs.reserve(NumValues); }
162 TypeToOffsets.clear();
163 VRegAlloc.DestroyAll();
164 OffsetAlloc.DestroyAll();
179 ValueToVRegInfo VMap;
186 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
197 PendingConstDbgValues;
253 void translateDbgValueListRecord(
261 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
268 bool translateCopy(
const User &U,
const Value &V,
293 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
295 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
300 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
302 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
324 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
330 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
345 bool translateIntrinsic(
362 bool findUnwindDestinations(
375 bool translateCast(
unsigned Opcode,
const User &U,
386 return translateCompare(U, MIRBuilder);
391 return translateCompare(U, MIRBuilder);
396 void finishPendingPhis();
400 void finishPendingConstDbgValues();
404 bool translateUnaryOp(
unsigned Opcode,
const User &U,
409 bool translateBinaryOp(
unsigned Opcode,
const User &U,
415 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
460 bool lowerJumpTableWorkItem(
469 bool FallthroughUnreachable,
475 bool lowerBitTestWorkItem(
481 bool FallthroughUnreachable);
512 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
515 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
518 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
521 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
524 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
527 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
531 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
534 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
537 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
540 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
543 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
546 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
550 return translatePtrToInt(U, MIRBuilder);
553 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
556 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
559 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
562 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
565 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
568 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
571 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
576 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
580 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
584 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
587 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
590 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
594 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
597 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
600 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
603 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
606 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
642 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
657 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
668 std::unique_ptr<MachineIRBuilder> CurBuilder;
673 std::unique_ptr<MachineIRBuilder> EntryBuilder;
686 std::unique_ptr<OptimizationRemarkEmitter> ORE;
697 bool EnableOpts =
false;
701 bool HasTailCall =
false;
705 bool mayTranslateUserTypes(
const User &U)
const;
712 assert(irt &&
"irt is null!");
715 void addSuccessorWithProb(
718 IRT->addSuccessorWithProb(Src, Dst, Prob);
721 ~GISelSwitchLowering()
override =
default;
727 std::unique_ptr<GISelSwitchLowering> SL;
733 void finalizeFunction();
771 auto Regs = getOrCreateVRegs(Val);
774 assert(Regs.size() == 1 &&
775 "attempt to get single VReg for aggregate or void");
779 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
781 auto &Regs = *VMap.getVRegs(Token);
783 assert(Regs.size() == 1 &&
784 "Expected a single register for convergence tokens.");
788 auto Reg = MRI->createGenericVirtualRegister(
LLT::token());
795 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
799 int getOrCreateFrameIndex(
const AllocaInst &AI);
822 auto RemappedEdge = MachinePreds.find(Edge);
823 if (RemappedEdge != MachinePreds.end())
824 return RemappedEdge->second;
833 void addSuccessorWithProb(
839 : OptLevel(OptLevel) {}
869 "IRTranslator LLVM IR -> MI",
false,
false)
881 MF.getProperties().setFailedISel();
882 bool IsGlobalISelAbortEnabled =
887 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
888 R << (
" (in function: " + MF.getName() +
")").str();
890 if (IsGlobalISelAbortEnabled)
910 DILocationVerifier() =
default;
911 ~DILocationVerifier()
override =
default;
913 const Instruction *getCurrentInst()
const {
return CurrInst; }
914 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
916 void erasingInstr(MachineInstr &
MI)
override {}
917 void changingInstr(MachineInstr &
MI)
override {}
918 void changedInstr(MachineInstr &
MI)
override {}
920 void createdInstr(MachineInstr &
MI)
override {
921 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
926 <<
" was copied to " <<
MI);
932 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
933 (
MI.isDebugInstr())) &&
934 "Line info was not transferred to all instructions");
957IRTranslatorImpl::ValueToVRegInfo::VRegListT &
958IRTranslatorImpl::allocateVRegs(
const Value &Val) {
959 auto VRegsIt = VMap.findVRegs(Val);
960 if (VRegsIt != VMap.vregs_end())
961 return *VRegsIt->second;
962 auto *Regs = VMap.getVRegs(Val);
968 auto *Offsets = VMap.getOffsets(Val);
971 Offsets->empty() ? Offsets :
nullptr);
972 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
978 auto VRegsIt = VMap.findVRegs(Val);
979 if (VRegsIt != VMap.vregs_end())
980 return *VRegsIt->second;
983 return *VMap.getVRegs(Val);
986 auto *VRegs = VMap.getVRegs(Val);
990 "Don't know how to create an empty vreg");
995 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
999 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"GISelFailure",
1000 MF->getFunction().getSubprogram(),
1001 &MF->getFunction().getEntryBlock());
1002 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
1010 auto *
Offsets = VMap.getOffsets(Val);
1012 Offsets->empty() ? Offsets :
nullptr);
1015 for (
auto Ty : SplitTys)
1016 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
1023 while (
auto Elt =
C.getAggregateElement(Idx++)) {
1024 auto EltRegs = getOrCreateVRegs(*Elt);
1031int IRTranslatorImpl::getOrCreateFrameIndex(
const AllocaInst &AI) {
1032 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
1034 return MapEntry->second;
1040 Size = std::max<uint64_t>(
Size, 1u);
1042 int &FI = MapEntry->second;
1043 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
1050 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
1051 MF->getFrameInfo().setStackID(FI, StackID);
1059 return SI->getAlign();
1061 return LI->getAlign();
1067 OptimizationRemarkMissed
R(
"gisel-ir-translator",
"", &
I);
1068 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
1074 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
1075 assert(
MBB &&
"BasicBlock was not encountered before");
1079void IRTranslatorImpl::addMachineCFGPred(CFGEdge
Edge,
1081 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
1082 MachinePreds[
Edge].push_back(NewPred);
1085bool IRTranslatorImpl::translateBinaryOp(
unsigned Opcode,
const User &U,
1087 if (!mayTranslateUserTypes(U))
1094 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1095 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1107bool IRTranslatorImpl::translateUnaryOp(
unsigned Opcode,
const User &U,
1109 if (!mayTranslateUserTypes(U))
1112 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1123bool IRTranslatorImpl::translateFNeg(
const User &U,
1125 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
1128bool IRTranslatorImpl::translateCompare(
const User &U,
1130 if (!mayTranslateUserTypes(U))
1134 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1135 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1153bool IRTranslatorImpl::translateRet(
const User &U,
1157 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
1162 VRegs = getOrCreateVRegs(*Ret);
1165 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
1166 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
1167 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
1173 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
1176void IRTranslatorImpl::emitBranchForMergedCondition(
1185 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
1188 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
1191 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
1192 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
1193 CurBuilder->getDebugLoc(), TProb, FProb);
1194 SL->SwitchCases.push_back(CB);
1200 SwitchCG::CaseBlock CB(
1202 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
1203 SL->SwitchCases.push_back(CB);
1208 return I->getParent() == BB;
1212void IRTranslatorImpl::findMergedConditions(
1217 using namespace PatternMatch;
1218 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
1219 "Expected Opc to be AND/OR");
1225 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
1231 const Value *BOpOp0, *BOpOp1;
1245 if (BOpc == Instruction::And)
1246 BOpc = Instruction::Or;
1247 else if (BOpc == Instruction::Or)
1248 BOpc = Instruction::And;
1254 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
1258 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
1265 MachineBasicBlock *TmpBB =
1269 if (
Opc == Instruction::Or) {
1290 auto NewTrueProb = TProb / 2;
1291 auto NewFalseProb = TProb / 2 + FProb;
1293 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1294 NewFalseProb, InvertCond);
1300 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1301 Probs[1], InvertCond);
1303 assert(
Opc == Instruction::And &&
"Unknown merge op!");
1323 auto NewTrueProb = TProb + FProb / 2;
1324 auto NewFalseProb = FProb / 2;
1326 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1327 NewFalseProb, InvertCond);
1333 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1334 Probs[1], InvertCond);
1338bool IRTranslatorImpl::shouldEmitAsBranches(
1339 const std::vector<SwitchCG::CaseBlock> &Cases) {
1341 if (Cases.size() != 2)
1346 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
1347 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
1348 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
1349 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
1355 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
1356 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
1360 Cases[0].TrueBB == Cases[1].ThisBB)
1363 Cases[0].FalseBB == Cases[1].ThisBB)
1370bool IRTranslatorImpl::translateUncondBr(
const User &U,
1373 auto &CurMBB = MIRBuilder.
getMBB();
1378 MIRBuilder.
buildBr(*Succ0MBB);
1381 for (
const BasicBlock *Succ :
successors(&BrInst))
1386bool IRTranslatorImpl::translateCondBr(
const User &U,
1389 auto &CurMBB = MIRBuilder.
getMBB();
1395 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
1414 using namespace PatternMatch;
1416 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
1417 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
1420 const Value *BOp0, *BOp1;
1422 Opcode = Instruction::And;
1424 Opcode = Instruction::Or;
1428 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
1429 getEdgeProbability(&CurMBB, Succ0MBB),
1430 getEdgeProbability(&CurMBB, Succ1MBB),
1432 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
1435 if (shouldEmitAsBranches(SL->SwitchCases)) {
1437 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
1438 SL->SwitchCases.erase(SL->SwitchCases.begin());
1444 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
1445 MF->erase(SL->SwitchCases[
I].ThisBB);
1447 SL->SwitchCases.clear();
1454 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
1455 CurBuilder->getDebugLoc());
1459 emitSwitchCase(CB, &CurMBB, *CurBuilder);
1466 if (!FuncInfo.BPI) {
1467 Src->addSuccessorWithoutProb(Dst);
1471 Prob = getEdgeProbability(Src, Dst);
1472 Src->addSuccessor(Dst, Prob);
1478 const BasicBlock *SrcBB = Src->getBasicBlock();
1479 const BasicBlock *DstBB = Dst->getBasicBlock();
1480 if (!FuncInfo.BPI) {
1483 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
1484 return BranchProbability(1, SuccSize);
1486 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
1490 using namespace SwitchCG;
1493 BranchProbabilityInfo *BPI = FuncInfo.BPI;
1495 Clusters.reserve(
SI.getNumCases());
1496 for (
const auto &
I :
SI.cases()) {
1497 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
1498 assert(Succ &&
"Could not find successor mbb in mapping");
1499 const ConstantInt *CaseVal =
I.getCaseValue();
1500 BranchProbability Prob =
1502 : BranchProbability(1,
SI.getNumCases() + 1);
1503 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
1506 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
1513 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
1516 if (Clusters.empty()) {
1523 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
1524 SL->findBitTestClusters(Clusters, &SI);
1527 dbgs() <<
"Case clusters: ";
1528 for (
const CaseCluster &
C : Clusters) {
1529 if (
C.Kind == CC_JumpTable)
1531 if (
C.Kind == CC_BitTests)
1534 C.Low->getValue().print(
dbgs(),
true);
1535 if (
C.Low !=
C.High) {
1537 C.High->getValue().print(
dbgs(),
true);
1544 assert(!Clusters.empty());
1548 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
1549 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
1551 while (!WorkList.empty()) {
1552 SwitchWorkListItem
W = WorkList.pop_back_val();
1554 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
1556 if (NumClusters > 3 &&
1559 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
1563 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
1573 using namespace SwitchCG;
1574 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
1575 "Clusters not sorted?");
1576 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
1578 auto [LastLeft, FirstRight, LeftProb, RightProb] =
1579 SL->computeSplitWorkItemInfo(W);
1584 assert(PivotCluster >
W.FirstCluster);
1585 assert(PivotCluster <=
W.LastCluster);
1590 const ConstantInt *Pivot = PivotCluster->Low;
1599 MachineBasicBlock *LeftMBB;
1600 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
1601 FirstLeft->Low ==
W.GE &&
1602 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
1603 LeftMBB = FirstLeft->MBB;
1605 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1606 FuncInfo.MF->
insert(BBI, LeftMBB);
1608 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
1614 MachineBasicBlock *RightMBB;
1615 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
1616 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
1617 RightMBB = FirstRight->MBB;
1619 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1620 FuncInfo.MF->
insert(BBI, RightMBB);
1622 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
1630 if (
W.MBB == SwitchMBB)
1631 emitSwitchCase(CB, SwitchMBB, MIB);
1633 SL->SwitchCases.push_back(CB);
1639 assert(JT.
Reg &&
"Should lower JT Header first!");
1654 MachineIRBuilder MIB(*HeaderBB->
getParent());
1661 Register SwitchOpReg = getOrCreateVReg(SValue);
1663 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
1668 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
1682 auto Cst = getOrCreateVReg(
1722 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
1736 "Can only handle SLE ranges");
1747 const LLT CmpTy = MRI->getType(CmpOpReg);
1748 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1774bool IRTranslatorImpl::lowerJumpTableWorkItem(
1780 using namespace SwitchCG;
1783 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1784 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1785 BranchProbability DefaultProb =
W.DefaultProb;
1788 MachineBasicBlock *JumpMBB = JT->
MBB;
1789 CurMF->
insert(BBI, JumpMBB);
1799 auto JumpProb =
I->Prob;
1800 auto FallthroughProb = UnhandledProbs;
1808 if (*SI == DefaultMBB) {
1809 JumpProb += DefaultProb / 2;
1810 FallthroughProb -= DefaultProb / 2;
1815 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1820 if (FallthroughUnreachable)
1821 JTH->FallthroughUnreachable =
true;
1823 if (!JTH->FallthroughUnreachable)
1824 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1825 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1830 JTH->HeaderBB = CurMBB;
1834 if (CurMBB == SwitchMBB) {
1835 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1837 JTH->Emitted =
true;
1841bool IRTranslatorImpl::lowerSwitchRangeWorkItem(
1846 using namespace SwitchCG;
1849 if (
I->Low ==
I->High) {
1865 CaseBlock CB(
Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1868 emitSwitchCase(CB, SwitchMBB, MIB);
1874 MachineIRBuilder &MIB = *CurBuilder;
1878 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1880 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1882 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1887 LLT MaskTy = SwitchOpTy;
1893 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1902 Register SubReg = RangeSub.getReg(0);
1903 if (SwitchOpTy != MaskTy)
1909 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1911 if (!
B.FallthroughUnreachable)
1912 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1913 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1917 if (!
B.FallthroughUnreachable) {
1921 RangeSub, RangeCst);
1935 MachineIRBuilder &MIB = *CurBuilder;
1941 if (PopCount == 1) {
1944 auto MaskTrailingZeros =
1949 }
else if (PopCount == BB.
Range) {
1951 auto MaskTrailingOnes =
1959 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1963 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1970 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1972 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1990bool IRTranslatorImpl::lowerBitTestWorkItem(
1996 bool FallthroughUnreachable) {
1997 using namespace SwitchCG;
2000 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
2002 for (BitTestCase &BTC : BTB->Cases)
2003 CurMF->
insert(BBI, BTC.ThisBB);
2006 BTB->Parent = CurMBB;
2007 BTB->Default = Fallthrough;
2009 BTB->DefaultProb = UnhandledProbs;
2013 if (!BTB->ContiguousRange) {
2014 BTB->Prob += DefaultProb / 2;
2015 BTB->DefaultProb -= DefaultProb / 2;
2018 if (FallthroughUnreachable)
2019 BTB->FallthroughUnreachable =
true;
2022 if (CurMBB == SwitchMBB) {
2023 emitBitTestHeader(*BTB, SwitchMBB);
2024 BTB->Emitted =
true;
2034 using namespace SwitchCG;
2036 MachineBasicBlock *NextMBB =
nullptr;
2038 if (++BBI != FuncInfo.MF->end())
2047 [](
const CaseCluster &a,
const CaseCluster &b) {
2048 return a.Prob != b.Prob
2050 : a.Low->getValue().slt(b.Low->getValue());
2055 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
2057 if (
I->Prob >
W.LastCluster->Prob)
2059 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
2067 BranchProbability DefaultProb =
W.DefaultProb;
2068 BranchProbability UnhandledProbs = DefaultProb;
2069 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
2070 UnhandledProbs +=
I->Prob;
2072 MachineBasicBlock *CurMBB =
W.MBB;
2073 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
2074 bool FallthroughUnreachable =
false;
2075 MachineBasicBlock *Fallthrough;
2076 if (
I ==
W.LastCluster) {
2078 Fallthrough = DefaultMBB;
2079 FallthroughUnreachable =
2083 CurMF->
insert(BBI, Fallthrough);
2085 UnhandledProbs -=
I->Prob;
2089 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2090 DefaultProb, UnhandledProbs,
I, Fallthrough,
2091 FallthroughUnreachable)) {
2099 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2100 UnhandledProbs,
I, Fallthrough,
2101 FallthroughUnreachable)) {
2108 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
2109 FallthroughUnreachable, UnhandledProbs,
2110 CurMBB, MIB, SwitchMBB)) {
2117 CurMBB = Fallthrough;
2123bool IRTranslatorImpl::translateIndirectBr(
const User &U,
2131 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
2132 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
2133 for (
const BasicBlock *Succ :
successors(&BrInst)) {
2137 if (!AddedSuccessors.
insert(Succ).second)
2153bool IRTranslatorImpl::translateLoad(
const User &U,
2156 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
2167 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
2169 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
2175 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
2177 if (AA->pointsToConstantMemory(
2184 if (Regs.
size() == 1) {
2185 auto *MMO = MF->getMachineMemOperand(
2187 MRI->getType(Regs[0]), getMemOpAlign(LI),
2188 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
2194 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
2195 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
2197 for (
unsigned i = 0; i < Regs.
size(); ++i) {
2202 Align BaseAlign = getMemOpAlign(LI);
2204 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
2207 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
2213bool IRTranslatorImpl::translateStore(
const User &U,
2216 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
2222 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
2223 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
2225 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
2226 SI.getPointerOperand());
2233 if (Vals.
size() == 1) {
2234 auto *MMO = MF->getMachineMemOperand(
2235 MachinePointerInfo(
SI.getPointerOperand()), Flags,
2236 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
2237 SI.getSyncScopeID(),
SI.getOrdering());
2242 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
2243 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
2245 for (
unsigned i = 0; i < Vals.
size(); ++i) {
2249 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
2250 Align BaseAlign = getMemOpAlign(SI);
2251 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
2254 SI.getSyncScopeID(),
SI.getOrdering());
2261 const Value *Src = U.getOperand(0);
2267 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
2270 for (
auto Idx : EVI->indices())
2271 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2273 for (
auto Idx : IVI->indices())
2274 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2280 DL.getIndexedOffsetInType(Src->getType(), Indices));
2283bool IRTranslatorImpl::translateExtractValue(
const User &U,
2285 const Value *Src =
U.getOperand(0);
2288 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
2290 auto &DstRegs = allocateVRegs(U);
2292 for (
unsigned i = 0; i < DstRegs.size(); ++i)
2293 DstRegs[i] = SrcRegs[Idx++];
2298bool IRTranslatorImpl::translateInsertValue(
const User &U,
2300 const Value *Src =
U.getOperand(0);
2302 auto &DstRegs = allocateVRegs(U);
2303 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
2306 auto *InsertedIt = InsertedRegs.
begin();
2308 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
2309 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
2310 DstRegs[i] = *InsertedIt++;
2312 DstRegs[i] = SrcRegs[i];
2318bool IRTranslatorImpl::translateSelect(
const User &U,
2320 Register Tst = getOrCreateVReg(*
U.getOperand(0));
2329 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
2330 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
2336bool IRTranslatorImpl::translateCopy(
const User &U,
const Value &
V,
2338 return translateCopy(U, getOrCreateVReg(
V), MIRBuilder);
2341bool IRTranslatorImpl::translateCopy(
const User &U,
Register Src,
2343 auto &Regs = *VMap.getVRegs(U);
2345 Regs.push_back(Src);
2354bool IRTranslatorImpl::translateBitCast(
const User &U,
2356 Type *SrcTy =
U.getOperand(0)->getType();
2357 Type *DstTy =
U.getType();
2364 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
2366 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
2375 "only byte types can be bitcast to or from pointers");
2377 LLT IntTy =
getLLTForType(*DL->getIntPtrType(PtrIRTy), *DL);
2378 Register Src = getOrCreateVReg(*
U.getOperand(0));
2380 if (MRI->getType(Src) != IntTy && MRI->getType(Dst) != IntTy)
2386 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
2389bool IRTranslatorImpl::translateCast(
unsigned Opcode,
const User &U,
2391 if (!mayTranslateUserTypes(U))
2404bool IRTranslatorImpl::translateGetElementPtr(
const User &U,
2406 Value &Op0 = *
U.getOperand(0);
2410 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
2413 uint32_t PtrAddFlags = 0;
2419 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
2429 unsigned VectorWidth = 0;
2433 bool WantSplatVector =
false;
2437 WantSplatVector = VectorWidth > 1;
2441 return translateCopy(U, BaseReg, MIRBuilder);
2445 if (WantSplatVector && !PtrTy.
isVector()) {
2452 OffsetIRTy = DL->getIndexType(PtrIRTy);
2459 const Value *
Idx = GTI.getOperand();
2460 if (StructType *StTy = GTI.getStructTypeOrNull()) {
2462 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
2465 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
2470 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
2471 Offset += ElementSize * *Val;
2480 PtrAddFlagsWithConst(
Offset))
2485 Register IdxReg = getOrCreateVReg(*Idx);
2486 LLT IdxTy = MRI->getType(IdxReg);
2487 if (IdxTy != OffsetTy) {
2488 if (!IdxTy.
isVector() && WantSplatVector) {
2501 if (ElementSize != 1) {
2512 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
2515 GepOffsetReg = IdxReg;
2519 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
2528 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
2529 PtrAddFlagsWithConst(
Offset));
2533 return translateCopy(U, BaseReg, MIRBuilder);
2536bool IRTranslatorImpl::translateMemFunc(
const CallInst &CI,
2546 unsigned MinPtrSize = UINT_MAX;
2547 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
2548 Register SrcReg = getOrCreateVReg(**AI);
2549 LLT SrcTy = MRI->getType(SrcReg);
2551 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
2559 if (MRI->getType(SizeOpReg) != SizeTy)
2571 ConstantInt *CopySize =
nullptr;
2574 DstAlign = MCI->getDestAlign().valueOrOne();
2575 SrcAlign = MCI->getSourceAlign().valueOrOne();
2578 DstAlign = MMI->getDestAlign().valueOrOne();
2579 SrcAlign = MMI->getSourceAlign().valueOrOne();
2583 DstAlign = MSI->getDestAlign().valueOrOne();
2586 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
2587 Opcode != TargetOpcode::G_MEMSET_INLINE) {
2603 if (AA && CopySize &&
2604 AA->pointsToConstantMemory(MemoryLocation(
2614 ICall.addMemOperand(
2615 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
2616 StoreFlags, 1, DstAlign, AAInfo));
2617 if (Opcode != TargetOpcode::G_MEMSET &&
2618 Opcode != TargetOpcode::G_MEMSET_INLINE)
2619 ICall.addMemOperand(MF->getMachineMemOperand(
2620 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
2625bool IRTranslatorImpl::translateTrap(
const CallInst &CI,
2628 StringRef TrapFuncName =
2629 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
2630 if (TrapFuncName.
empty()) {
2631 MachineInstrBuilder MIB;
2632 if (Opcode == TargetOpcode::G_UBSANTRAP) {
2643 CallLowering::CallLoweringInfo
Info;
2644 if (Opcode == TargetOpcode::G_UBSANTRAP)
2652 return CLI->lowerCall(MIRBuilder, Info);
2655bool IRTranslatorImpl::translateVectorInterleave2Intrinsic(
2658 "This function can only be called on the interleave2 intrinsic!");
2662 Register Res = getOrCreateVReg(CI);
2664 LLT OpTy = MRI->getType(Op0);
2671bool IRTranslatorImpl::translateVectorDeinterleave2Intrinsic(
2674 "This function can only be called on the deinterleave2 intrinsic!");
2681 LLT ResTy = MRI->getType(Res[0]);
2698void IRTranslatorImpl::getStackGuard(
Register DstReg,
2701 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
2704 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
2709 const TargetInstrInfo &
TII = *MF->getSubtarget().getInstrInfo();
2710 MRI->setRegClass(DstReg,
2711 TII.getRegClass(
TII.get(TargetOpcode::LOAD_STACK_GUARD), 0));
2713 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
2715 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
2716 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
2718 MachinePointerInfo MPInfo(
Global);
2721 MachineMemOperand *MemRef = MF->getMachineMemOperand(
2722 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
2726bool IRTranslatorImpl::translateOverflowIntrinsic(
2730 Op, {ResRegs[0], ResRegs[1]},
2736bool IRTranslatorImpl::translateFixedPointIntrinsic(
2738 Register Dst = getOrCreateVReg(CI);
2746unsigned IRTranslatorImpl::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
2750 case Intrinsic::acos:
2751 return TargetOpcode::G_FACOS;
2752 case Intrinsic::asin:
2753 return TargetOpcode::G_FASIN;
2754 case Intrinsic::atan:
2755 return TargetOpcode::G_FATAN;
2756 case Intrinsic::atan2:
2757 return TargetOpcode::G_FATAN2;
2758 case Intrinsic::bswap:
2759 return TargetOpcode::G_BSWAP;
2760 case Intrinsic::bitreverse:
2761 return TargetOpcode::G_BITREVERSE;
2762 case Intrinsic::clmul:
2763 return TargetOpcode::G_CLMUL;
2764 case Intrinsic::fshl:
2765 return TargetOpcode::G_FSHL;
2766 case Intrinsic::fshr:
2767 return TargetOpcode::G_FSHR;
2768 case Intrinsic::ceil:
2769 return TargetOpcode::G_FCEIL;
2770 case Intrinsic::cos:
2771 return TargetOpcode::G_FCOS;
2772 case Intrinsic::cosh:
2773 return TargetOpcode::G_FCOSH;
2774 case Intrinsic::ctpop:
2775 return TargetOpcode::G_CTPOP;
2776 case Intrinsic::smulh:
2777 return TargetOpcode::G_SMULH;
2778 case Intrinsic::umulh:
2779 return TargetOpcode::G_UMULH;
2780 case Intrinsic::exp:
2781 return TargetOpcode::G_FEXP;
2782 case Intrinsic::exp2:
2783 return TargetOpcode::G_FEXP2;
2784 case Intrinsic::exp10:
2785 return TargetOpcode::G_FEXP10;
2786 case Intrinsic::fabs:
2787 return TargetOpcode::G_FABS;
2788 case Intrinsic::copysign:
2789 return TargetOpcode::G_FCOPYSIGN;
2790 case Intrinsic::minnum:
2791 return TargetOpcode::G_FMINNUM;
2792 case Intrinsic::maxnum:
2793 return TargetOpcode::G_FMAXNUM;
2794 case Intrinsic::minimum:
2795 return TargetOpcode::G_FMINIMUM;
2796 case Intrinsic::maximum:
2797 return TargetOpcode::G_FMAXIMUM;
2798 case Intrinsic::minimumnum:
2799 return TargetOpcode::G_FMINIMUMNUM;
2800 case Intrinsic::maximumnum:
2801 return TargetOpcode::G_FMAXIMUMNUM;
2802 case Intrinsic::canonicalize:
2803 return TargetOpcode::G_FCANONICALIZE;
2804 case Intrinsic::floor:
2805 return TargetOpcode::G_FFLOOR;
2806 case Intrinsic::fma:
2807 return TargetOpcode::G_FMA;
2808 case Intrinsic::log:
2809 return TargetOpcode::G_FLOG;
2810 case Intrinsic::log2:
2811 return TargetOpcode::G_FLOG2;
2812 case Intrinsic::log10:
2813 return TargetOpcode::G_FLOG10;
2814 case Intrinsic::ldexp:
2815 return TargetOpcode::G_FLDEXP;
2816 case Intrinsic::nearbyint:
2817 return TargetOpcode::G_FNEARBYINT;
2818 case Intrinsic::pow:
2819 return TargetOpcode::G_FPOW;
2820 case Intrinsic::powi:
2821 return TargetOpcode::G_FPOWI;
2822 case Intrinsic::rint:
2823 return TargetOpcode::G_FRINT;
2824 case Intrinsic::round:
2825 return TargetOpcode::G_INTRINSIC_ROUND;
2826 case Intrinsic::roundeven:
2827 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2828 case Intrinsic::sin:
2829 return TargetOpcode::G_FSIN;
2830 case Intrinsic::sinh:
2831 return TargetOpcode::G_FSINH;
2832 case Intrinsic::sqrt:
2833 return TargetOpcode::G_FSQRT;
2834 case Intrinsic::tan:
2835 return TargetOpcode::G_FTAN;
2836 case Intrinsic::tanh:
2837 return TargetOpcode::G_FTANH;
2838 case Intrinsic::trunc:
2839 return TargetOpcode::G_INTRINSIC_TRUNC;
2840 case Intrinsic::readcyclecounter:
2841 return TargetOpcode::G_READCYCLECOUNTER;
2842 case Intrinsic::readsteadycounter:
2843 return TargetOpcode::G_READSTEADYCOUNTER;
2844 case Intrinsic::ptrmask:
2845 return TargetOpcode::G_PTRMASK;
2846 case Intrinsic::lrint:
2847 return TargetOpcode::G_INTRINSIC_LRINT;
2848 case Intrinsic::llrint:
2849 return TargetOpcode::G_INTRINSIC_LLRINT;
2851 case Intrinsic::vector_reduce_fmin:
2852 return TargetOpcode::G_VECREDUCE_FMIN;
2853 case Intrinsic::vector_reduce_fmax:
2854 return TargetOpcode::G_VECREDUCE_FMAX;
2855 case Intrinsic::vector_reduce_fminimum:
2856 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2857 case Intrinsic::vector_reduce_fmaximum:
2858 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2859 case Intrinsic::vector_reduce_fminimumnum:
2860 return TargetOpcode::G_VECREDUCE_FMINIMUMNUM;
2861 case Intrinsic::vector_reduce_fmaximumnum:
2862 return TargetOpcode::G_VECREDUCE_FMAXIMUMNUM;
2863 case Intrinsic::vector_reduce_add:
2864 return TargetOpcode::G_VECREDUCE_ADD;
2865 case Intrinsic::vector_reduce_mul:
2866 return TargetOpcode::G_VECREDUCE_MUL;
2867 case Intrinsic::vector_reduce_and:
2868 return TargetOpcode::G_VECREDUCE_AND;
2869 case Intrinsic::vector_reduce_or:
2870 return TargetOpcode::G_VECREDUCE_OR;
2871 case Intrinsic::vector_reduce_xor:
2872 return TargetOpcode::G_VECREDUCE_XOR;
2873 case Intrinsic::vector_reduce_smax:
2874 return TargetOpcode::G_VECREDUCE_SMAX;
2875 case Intrinsic::vector_reduce_smin:
2876 return TargetOpcode::G_VECREDUCE_SMIN;
2877 case Intrinsic::vector_reduce_umax:
2878 return TargetOpcode::G_VECREDUCE_UMAX;
2879 case Intrinsic::vector_reduce_umin:
2880 return TargetOpcode::G_VECREDUCE_UMIN;
2881 case Intrinsic::experimental_vector_compress:
2882 return TargetOpcode::G_VECTOR_COMPRESS;
2883 case Intrinsic::lround:
2884 return TargetOpcode::G_LROUND;
2885 case Intrinsic::llround:
2886 return TargetOpcode::G_LLROUND;
2887 case Intrinsic::get_fpenv:
2888 return TargetOpcode::G_GET_FPENV;
2889 case Intrinsic::get_fpmode:
2890 return TargetOpcode::G_GET_FPMODE;
2895bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2899 unsigned Op = getSimpleIntrinsicOpcode(ID);
2907 for (
const auto &Arg : CI.
args())
2910 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2918 case Intrinsic::experimental_constrained_fadd:
2919 return TargetOpcode::G_STRICT_FADD;
2920 case Intrinsic::experimental_constrained_fsub:
2921 return TargetOpcode::G_STRICT_FSUB;
2922 case Intrinsic::experimental_constrained_fmul:
2923 return TargetOpcode::G_STRICT_FMUL;
2924 case Intrinsic::experimental_constrained_fdiv:
2925 return TargetOpcode::G_STRICT_FDIV;
2926 case Intrinsic::experimental_constrained_frem:
2927 return TargetOpcode::G_STRICT_FREM;
2928 case Intrinsic::experimental_constrained_fma:
2929 return TargetOpcode::G_STRICT_FMA;
2930 case Intrinsic::experimental_constrained_sqrt:
2931 return TargetOpcode::G_STRICT_FSQRT;
2932 case Intrinsic::experimental_constrained_ldexp:
2933 return TargetOpcode::G_STRICT_FLDEXP;
2934 case Intrinsic::experimental_constrained_fcmp:
2935 return TargetOpcode::G_STRICT_FCMP;
2936 case Intrinsic::experimental_constrained_fcmps:
2937 return TargetOpcode::G_STRICT_FCMPS;
2943bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2955 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2956 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2958 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2959 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2962 .addPredicate(FPCmp->getPredicate())
2976std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2977 auto VRegs = getOrCreateVRegs(Arg);
2978 if (VRegs.
size() != 1)
2979 return std::nullopt;
2982 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2983 if (!VRegDef || !VRegDef->isCopy())
2984 return std::nullopt;
2985 return VRegDef->getOperand(1).getReg().asMCReg();
2988bool IRTranslatorImpl::translateIfEntryValueArgument(
2999 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
3001 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
3002 <<
": expression is entry_value but "
3003 <<
"couldn't find a physical register\n");
3011 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
3023 case Intrinsic::experimental_convergence_anchor:
3024 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
3025 case Intrinsic::experimental_convergence_entry:
3026 return TargetOpcode::CONVERGENCECTRL_ENTRY;
3027 case Intrinsic::experimental_convergence_loop:
3028 return TargetOpcode::CONVERGENCECTRL_LOOP;
3032bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
3035 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3038 if (ID == Intrinsic::experimental_convergence_loop) {
3040 assert(Bundle &&
"Expected a convergence control token.");
3042 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3049bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3053 if (ORE->enabled()) {
3055 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3063 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3069 case Intrinsic::lifetime_start:
3070 case Intrinsic::lifetime_end: {
3073 MF->getFunction().hasOptNone())
3076 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3077 : TargetOpcode::LIFETIME_END;
3086 case Intrinsic::fake_use: {
3088 for (
const auto &Arg : CI.
args())
3090 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3091 MF->setHasFakeUses(
true);
3094 case Intrinsic::vaend:
3098 case Intrinsic::vastart: {
3100 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3103 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3104 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3106 ListSize, Alignment));
3109 case Intrinsic::uadd_with_overflow:
3110 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3111 case Intrinsic::sadd_with_overflow:
3112 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3113 case Intrinsic::usub_with_overflow:
3114 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3115 case Intrinsic::ssub_with_overflow:
3116 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3117 case Intrinsic::umul_with_overflow:
3118 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3119 case Intrinsic::smul_with_overflow:
3120 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3121 case Intrinsic::uadd_sat:
3122 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3123 case Intrinsic::sadd_sat:
3124 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3125 case Intrinsic::usub_sat:
3126 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3127 case Intrinsic::ssub_sat:
3128 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3129 case Intrinsic::ushl_sat:
3130 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3131 case Intrinsic::sshl_sat:
3132 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3133 case Intrinsic::umin:
3134 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3135 case Intrinsic::umax:
3136 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3137 case Intrinsic::smin:
3138 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3139 case Intrinsic::smax:
3140 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3141 case Intrinsic::abs:
3143 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3144 case Intrinsic::smul_fix:
3145 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3146 case Intrinsic::umul_fix:
3147 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3148 case Intrinsic::smul_fix_sat:
3149 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3150 case Intrinsic::umul_fix_sat:
3151 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3152 case Intrinsic::sdiv_fix:
3153 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3154 case Intrinsic::udiv_fix:
3155 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3156 case Intrinsic::sdiv_fix_sat:
3157 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3158 case Intrinsic::udiv_fix_sat:
3159 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3160 case Intrinsic::fmuladd: {
3161 Register Dst = getOrCreateVReg(CI);
3165 if (TLI->isFMAFasterThanFMulAndFAdd(*MF,
3166 TLI->getValueType(*DL, CI.
getType()))) {
3169 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3180 case Intrinsic::frexp: {
3187 case Intrinsic::modf: {
3189 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3194 case Intrinsic::sincos: {
3201 case Intrinsic::fptosi_sat:
3205 case Intrinsic::fptoui_sat:
3209 case Intrinsic::memcpy_inline:
3210 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3211 case Intrinsic::memcpy:
3212 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3213 case Intrinsic::memmove:
3214 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3215 case Intrinsic::memset:
3216 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3217 case Intrinsic::memset_inline:
3218 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3219 case Intrinsic::eh_typeid_for: {
3222 unsigned TypeID = MF->getTypeIDFor(GV);
3226 case Intrinsic::objectsize:
3229 case Intrinsic::is_constant:
3232 case Intrinsic::stackguard:
3233 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3235 case Intrinsic::stackprotector: {
3238 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3239 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3240 getStackGuard(GuardVal, MIRBuilder);
3245 int FI = getOrCreateFrameIndex(*Slot);
3246 MF->getFrameInfo().setStackProtectorIndex(FI);
3249 GuardVal, getOrCreateVReg(*Slot),
3256 case Intrinsic::stacksave: {
3257 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3260 case Intrinsic::stackrestore: {
3261 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3265 case Intrinsic::cttz:
3266 case Intrinsic::ctlz: {
3268 bool isTrailing =
ID == Intrinsic::cttz;
3269 unsigned Opcode = isTrailing ? Cst->
isZero()
3270 ? TargetOpcode::G_CTTZ
3271 : TargetOpcode::G_CTTZ_ZERO_POISON
3272 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3273 : TargetOpcode::G_CTLZ_ZERO_POISON;
3274 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3278 case Intrinsic::invariant_start: {
3282 case Intrinsic::invariant_end:
3284 case Intrinsic::expect:
3285 case Intrinsic::expect_with_probability:
3286 case Intrinsic::annotation:
3287 case Intrinsic::ptr_annotation:
3288 case Intrinsic::launder_invariant_group:
3289 case Intrinsic::threadlocal_address: {
3291 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3295 case Intrinsic::assume:
3296 case Intrinsic::experimental_noalias_scope_decl:
3297 case Intrinsic::var_annotation:
3298 case Intrinsic::sideeffect:
3301 case Intrinsic::read_volatile_register:
3302 case Intrinsic::read_register: {
3305 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3309 case Intrinsic::write_register: {
3311 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3316 case Intrinsic::localescape: {
3317 MachineBasicBlock &EntryMBB = MF->front();
3322 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3329 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3342 case Intrinsic::vector_reduce_fadd:
3343 case Intrinsic::vector_reduce_fmul: {
3346 Register Dst = getOrCreateVReg(CI);
3352 Opc =
ID == Intrinsic::vector_reduce_fadd
3353 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3354 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3355 if (!MRI->getType(VecSrc).isVector())
3356 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3357 : TargetOpcode::G_FMUL;
3365 if (ID == Intrinsic::vector_reduce_fadd) {
3366 Opc = TargetOpcode::G_VECREDUCE_FADD;
3367 ScalarOpc = TargetOpcode::G_FADD;
3369 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3370 ScalarOpc = TargetOpcode::G_FMUL;
3372 LLT DstTy = MRI->getType(Dst);
3375 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3380 case Intrinsic::trap:
3381 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3382 case Intrinsic::debugtrap:
3383 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3384 case Intrinsic::ubsantrap:
3385 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3386 case Intrinsic::allow_runtime_check:
3387 case Intrinsic::allow_ubsan_check:
3388 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3391 case Intrinsic::amdgcn_cs_chain:
3392 case Intrinsic::amdgcn_call_whole_wave:
3393 return translateCallBase(CI, MIRBuilder);
3394 case Intrinsic::fptrunc_round: {
3399 std::optional<RoundingMode> RoundMode =
3404 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3405 {getOrCreateVReg(CI)},
3407 .addImm((
int)*RoundMode);
3411 case Intrinsic::is_fpclass: {
3416 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3417 {getOrCreateVReg(*FpValue)})
3422 case Intrinsic::set_fpenv: {
3427 case Intrinsic::reset_fpenv:
3430 case Intrinsic::set_fpmode: {
3435 case Intrinsic::reset_fpmode:
3438 case Intrinsic::get_rounding:
3441 case Intrinsic::set_rounding:
3444 case Intrinsic::vscale: {
3448 case Intrinsic::scmp:
3449 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3453 case Intrinsic::ucmp:
3454 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3458 case Intrinsic::vector_extract:
3459 return translateExtractVector(CI, MIRBuilder);
3460 case Intrinsic::vector_insert:
3461 return translateInsertVector(CI, MIRBuilder);
3462 case Intrinsic::stepvector: {
3466 case Intrinsic::prefetch: {
3473 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3476 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3482 case Intrinsic::speculative_load: {
3486 Register Dst = getOrCreateVReg(CI);
3488 Flags |= TLI->getTargetMMOFlags(CI);
3491 if (CI.
hasMetadata(LLVMContext::MD_invariant_load))
3493 auto *MMO = MF->getMachineMemOperand(
3494 MachinePointerInfo(Ptr), Flags, MRI->getType(Dst),
3496 MIRBuilder.
buildLoad(Dst, getOrCreateVReg(*Ptr), *MMO);
3500 case Intrinsic::vector_interleave2:
3501 case Intrinsic::vector_deinterleave2: {
3509 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3511 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3514#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3515 case Intrinsic::INTRINSIC:
3516#include "llvm/IR/ConstrainedOps.def"
3519 case Intrinsic::experimental_convergence_anchor:
3520 case Intrinsic::experimental_convergence_entry:
3521 case Intrinsic::experimental_convergence_loop:
3522 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3523 case Intrinsic::reloc_none: {
3526 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3534bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3536 if (!mayTranslateUserTypes(CB))
3539 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3543 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3548 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3551bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3558 for (
const auto &Arg : CB.
args()) {
3560 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3562 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3563 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3564 &CB, &MIRBuilder.
getMBB(), Arg));
3567 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3570 Args.push_back(getOrCreateVRegs(*Arg));
3574 if (ORE->enabled()) {
3576 MemoryOpRemark
R(*ORE,
"gisel-ir-translator-memsize", *DL, *LibInfo);
3582 std::optional<CallLowering::PtrAuthInfo> PAI;
3587 const Value *
Key = Bundle->Inputs[0];
3594 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3595 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3597 Register DiscReg = getOrCreateVReg(*Discriminator);
3605 const auto &Token = *Bundle->Inputs[0].get();
3606 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3612 bool Success = CLI->lowerCall(
3613 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3618 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3619 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3626bool IRTranslatorImpl::translateCall(
const User &U,
3628 if (!mayTranslateUserTypes(U))
3636 if (
F && (
F->hasDLLImportStorageClass() ||
3637 (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI() &&
3638 F->hasExternalWeakLinkage())))
3650 return translateInlineAsm(CI, MIRBuilder);
3654 if (translateCallBase(CI, MIRBuilder)) {
3663 if (!MF->getSubtarget().isIntrinsicSupported(ID))
3664 return handleUnsupportedIntrinsic(CI, ID, MIRBuilder);
3666 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3670 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3672 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3675bool IRTranslatorImpl::handleUnsupportedIntrinsic(
3678 F.getContext().diagnose(
3679 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3690bool IRTranslatorImpl::translateIntrinsic(
3693 if (!MF->getSubtarget().isIntrinsicSupported(ID))
3694 return handleUnsupportedIntrinsic(CB, ID, MIRBuilder);
3698 ResultRegs = getOrCreateVRegs(CB);
3702 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3713 assert(CI->getBitWidth() <= 64 &&
3714 "large intrinsic immediates not handled");
3715 MIB.
addImm(CI->getSExtValue());
3720 auto *MD = MDVal->getMetadata();
3724 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3731 if (VRegs.
size() > 1)
3738 for (
const auto &Info : TgtMemIntrinsicInfos) {
3741 LLT MemTy =
Info.memVT.isSimple()
3743 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3747 MachinePointerInfo MPI;
3749 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3750 }
else if (
Info.fallbackAddressSpace) {
3751 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3760 auto *Token = Bundle->Inputs[0].get();
3761 Register TokenReg = getOrCreateVReg(*Token);
3772bool IRTranslatorImpl::findUnwindDestinations(
3784 if (IsWasmCXX || IsWasmD) {
3794 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3800 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3801 UnwindDests.back().first->setIsEHScopeEntry();
3802 UnwindDests.back().first->setIsEHFuncletEntry();
3807 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3808 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3810 if (IsMSVCCXX || IsCoreCLR)
3811 UnwindDests.back().first->setIsEHFuncletEntry();
3813 UnwindDests.back().first->setIsEHScopeEntry();
3815 NewEHPadBB = CatchSwitch->getUnwindDest();
3820 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3821 if (BPI && NewEHPadBB)
3823 EHPadBB = NewEHPadBB;
3828bool IRTranslatorImpl::translateInvoke(
const User &U,
3831 MCContext &
Context = MF->getContext();
3836 const Function *Fn =
I.getCalledFunction();
3843 if (
I.hasDeoptState())
3857 (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI() &&
3861 bool LowerInlineAsm =
I.isInlineAsm();
3862 bool NeedEHLabel =
true;
3868 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3869 BeginSymbol =
Context.createTempSymbol();
3873 if (LowerInlineAsm) {
3874 if (!translateInlineAsm(
I, MIRBuilder))
3876 }
else if (!translateCallBase(
I, MIRBuilder))
3881 EndSymbol =
Context.createTempSymbol();
3886 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3887 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3888 BranchProbability EHPadBBProb =
3892 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3895 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3896 &ReturnMBB = getMBB(*ReturnBB);
3898 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3899 for (
auto &UnwindDest : UnwindDests) {
3900 UnwindDest.first->setIsEHPad();
3901 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3906 assert(BeginSymbol &&
"Expected a begin symbol!");
3907 assert(EndSymbol &&
"Expected an end symbol!");
3908 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3911 MIRBuilder.
buildBr(ReturnMBB);
3917bool IRTranslatorImpl::translateCallBr(
const User &U,
3919 if (!mayTranslateUserTypes(U))
3923 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3926 if (
I.isInlineAsm()) {
3932 if (!translateIntrinsic(
I, IID, MIRBuilder))
3936 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3937 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3946 for (BasicBlock *Dest :
I.getIndirectDests()) {
3947 MachineBasicBlock &
Target = getMBB(*Dest);
3948 Target.setIsInlineAsmBrIndirectTarget();
3949 Target.setLabelMustBeEmitted();
3951 if (Dests.
insert(Dest).second)
3963bool IRTranslatorImpl::translateLandingPad(
const User &U,
3967 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3973 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3974 if (TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel,
3975 PersonalityFn) == 0 &&
3976 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel,
3977 PersonalityFn) == 0)
3992 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3997 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3998 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3999 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
4008 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
4012 TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel, PersonalityFn);
4018 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
4021 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel, PersonalityFn);
4026 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
4027 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
4028 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
4033bool IRTranslatorImpl::translateAlloca(
const User &U,
4041 Register Res = getOrCreateVReg(AI);
4042 int FI = getOrCreateFrameIndex(AI);
4052 if (MF->getTarget().getTargetTriple().isOSWindowsOrUEFI())
4057 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4059 if (MRI->getType(NumElts) !=
IntPtrTy) {
4071 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4076 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4078 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4083 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4092 if (Alignment <= StackAlign)
4096 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4097 assert(MF->getFrameInfo().hasVarSizedObjects());
4101bool IRTranslatorImpl::translateVAArg(
const User &U,
4107 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4108 {getOrCreateVReg(*
U.getOperand(0)),
4109 DL->getABITypeAlign(
U.getType()).value()});
4113bool IRTranslatorImpl::translateUnreachable(
const User &U,
4116 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4117 MF->getTarget().Options.NoTrapAfterNoreturn))
4124bool IRTranslatorImpl::translateInsertElement(
const User &U,
4129 FVT && FVT->getNumElements() == 1)
4130 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4133 Register Val = getOrCreateVReg(*
U.getOperand(0));
4134 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4135 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4138 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4139 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4140 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4141 Idx = getOrCreateVReg(*NewIdxCI);
4145 Idx = getOrCreateVReg(*
U.getOperand(2));
4146 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4147 const LLT VecIdxTy =
4148 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4155bool IRTranslatorImpl::translateInsertVector(
const User &U,
4158 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4159 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4162 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4167 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4172 ResultType && ResultType->getNumElements() == 1) {
4174 InputType && InputType->getNumElements() == 1) {
4179 return translateCopy(U, Elt, MIRBuilder);
4194 auto ScaledIndex = MIRBuilder.
buildMul(
4195 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4205bool IRTranslatorImpl::translateExtractElement(
const User &U,
4209 if (
const FixedVectorType *FVT =
4211 if (FVT->getNumElements() == 1)
4212 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4215 Register Val = getOrCreateVReg(*
U.getOperand(0));
4216 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4221 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4222 Idx = getOrCreateVReg(*NewIdxCI);
4226 Idx = getOrCreateVReg(*
U.getOperand(1));
4227 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4228 const LLT VecIdxTy =
4236bool IRTranslatorImpl::translateExtractVector(
const User &U,
4239 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4241 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4246 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4251 ResultType && ResultType->getNumElements() == 1) {
4253 InputType && InputType->getNumElements() == 1) {
4256 return translateCopy(U, Vec, MIRBuilder);
4271 auto ScaledIndex = MIRBuilder.
buildMul(
4272 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4282bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4288 if (
U.getOperand(0)->getType()->isScalableTy()) {
4289 Register Val = getOrCreateVReg(*
U.getOperand(0));
4291 MRI->getType(Val).getElementType(), Val, 0);
4298 Mask = SVI->getShuffleMask();
4309 unsigned M =
Mask[0];
4311 if (M == 0 || M == 1)
4312 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4318 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4319 }
else if (M < SrcElts * 2) {
4321 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4333 for (
int M : Mask) {
4335 if (M == 0 || M == 1) {
4336 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4338 if (!
Undef.isValid()) {
4339 Undef = MRI->createGenericVirtualRegister(SrcTy);
4349 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4351 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4352 {getOrCreateVReg(*
U.getOperand(0)),
4353 getOrCreateVReg(*
U.getOperand(1))})
4354 .addShuffleMask(MaskAlloc);
4358bool IRTranslatorImpl::translateBitInsert(
const User &U,
4362 Register Val = getOrCreateVReg(*
U.getOperand(1));
4364 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4366 LLT ValTy = MRI.getType(Val);
4369 "bitinsert val wider than base should be rejected by verifier");
4382 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(BaseTy);
4399 MIRBuilder.
buildOr(Res, ClearedBase, ShiftedVal);
4403bool IRTranslatorImpl::translateBitExtract(
const User &U,
4406 Register Src = getOrCreateVReg(*
U.getOperand(0));
4408 MachineRegisterInfo &MRI = *MIRBuilder.
getMRI();
4409 LLT SrcTy = MRI.getType(Src);
4410 LLT ResTy = MRI.getType(Res);
4413 "bitextract result wider than source should be rejected by verifier");
4416 LLT ShiftAmtTy = TLI->getPreferredShiftAmountTy(SrcTy);
4426 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4428 if (SrcTy == IntResTy)
4440 Register IntRes = MRI.createGenericVirtualRegister(IntResTy);
4442 if (SrcTy == IntResTy)
4459bool IRTranslatorImpl::translatePHI(
const User &U,
4463 SmallVector<MachineInstr *, 4> Insts;
4464 for (
auto Reg : getOrCreateVRegs(PI)) {
4465 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4469 PendingPHIs.emplace_back(&PI, std::move(Insts));
4473bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4477 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4479 auto Res = getOrCreateVRegs(
I);
4482 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4483 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4484 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4487 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4488 *MF->getMachineMemOperand(
4489 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4490 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4491 I.getSuccessOrdering(),
I.getFailureOrdering()));
4495bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4497 if (!mayTranslateUserTypes(U))
4501 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4504 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4505 Register Val = getOrCreateVReg(*
I.getValOperand());
4507 unsigned Opcode = 0;
4508 switch (
I.getOperation()) {
4512 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4515 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4518 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4521 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4524 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4527 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4530 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4533 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4536 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4539 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4542 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4545 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4548 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4551 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4554 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4557 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4560 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4563 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4566 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4569 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4572 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4575 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4578 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4583 Opcode, Res, Addr, Val,
4584 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4585 Flags, MRI->getType(Val), getMemOpAlign(
I),
4586 I.getAAMetadata(),
I.getSyncScopeID(),
4591bool IRTranslatorImpl::translateFence(
const User &U,
4595 Fence.getSyncScopeID());
4599bool IRTranslatorImpl::translateFreeze(
const User &U,
4605 "Freeze with different source and destination type?");
4607 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4614void IRTranslatorImpl::finishPendingConstDbgValues() {
4615 for (
auto [
MI,
C] : PendingConstDbgValues) {
4616 auto VRegsIt = VMap.findVRegs(*
C);
4617 if (VRegsIt == VMap.vregs_end() || VRegsIt->second->size() != 1)
4621 MachineIRBuilder Builder(*
MI);
4622 Builder.buildDirectDbgValue(VRegsIt->second->front(),
4623 MI->getDebugVariable(),
4624 MI->getDebugExpression());
4625 MI->eraseFromParent();
4627 PendingConstDbgValues.clear();
4630void IRTranslatorImpl::finishPendingPhis() {
4633 GISelObserverWrapper WrapperObserver(&
Verifier);
4634 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4636 for (
auto &Phi : PendingPHIs) {
4637 const PHINode *PI =
Phi.first;
4641 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4647 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4651 for (
auto *
Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4655 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4656 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4665void IRTranslatorImpl::translateDbgValueRecord(
Value *
V,
4671 "Expected inlined-at fields to agree");
4685 PendingConstDbgValues.emplace_back(
MI, CI);
4695 auto *ExprDerefRemoved =
4701 if (translateIfEntryValueArgument(
false,
V, Variable, Expression, DL,
4713void IRTranslatorImpl::translateDbgValueListRecord(
4718 "Expected inlined-at fields to agree");
4721 auto GetLocationOperand = [&](
Value *
V) -> std::optional<MachineOperand> {
4723 return std::nullopt;
4735 return std::nullopt;
4737 if (Regs.
size() != 1)
4738 return std::nullopt;
4746 SmallVector<MachineOperand, 4> MOs;
4748 std::optional<MachineOperand> MO = GetLocationOperand(
V);
4760 MIRBuilder.
getTII().
get(TargetOpcode::DBG_VALUE_LIST),
4761 false, MOs, Variable, Expression));
4764void IRTranslatorImpl::translateDbgDeclareRecord(
4769 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4774 "Expected inlined-at fields to agree");
4779 MF->setVariableDbgInfo(Variable, Expression,
4780 getOrCreateFrameIndex(*AI), DL);
4784 if (translateIfEntryValueArgument(
true,
Address, Variable,
4796void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4801 assert(DLR->getLabel() &&
"Missing label");
4802 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4804 "Expected inlined-at fields to agree");
4813 translateDbgDeclareRecord(
V, DVR.
hasArgList(), Variable, Expression,
4816 translateDbgValueListRecord(DVR.
location_ops(), Variable, Expression,
4819 translateDbgValueRecord(
V, Variable, Expression, DVR.
getDebugLoc(),
4824bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4826 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4827 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4829 if (TLI->fallBackToDAGISel(Inst))
4833#define HANDLE_INST(NUM, OPCODE, CLASS) \
4834 case Instruction::OPCODE: \
4835 return translate##OPCODE(Inst, *CurBuilder.get());
4836#include "llvm/IR/Instruction.def"
4845 if (
auto CurrInstDL = CurBuilder->getDL())
4846 EntryBuilder->setDebugLoc(
DebugLoc());
4852 EntryBuilder->buildConstant(
Reg, *CI);
4856 EntryBuilder->buildConstant(
Reg, CB->getValue());
4860 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4861 EntryBuilder->buildFConstant(
Reg, *CF);
4863 EntryBuilder->buildUndef(
Reg);
4865 EntryBuilder->buildConstant(
Reg, 0);
4867 EntryBuilder->buildGlobalValue(
Reg, GV);
4869 Register Addr = getOrCreateVReg(*CPA->getPointer());
4870 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4871 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4873 Constant &Elt = *CAZ->getElementValue(0u);
4875 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4879 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4881 return translateCopy(
C, Elt, *EntryBuilder);
4883 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4886 if (CV->getNumElements() == 1)
4887 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4889 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4890 Constant &Elt = *CV->getElementAsConstant(i);
4891 Ops.push_back(getOrCreateVReg(Elt));
4893 EntryBuilder->buildBuildVector(
Reg,
Ops);
4895 switch(
CE->getOpcode()) {
4896#define HANDLE_INST(NUM, OPCODE, CLASS) \
4897 case Instruction::OPCODE: \
4898 return translate##OPCODE(*CE, *EntryBuilder.get());
4899#include "llvm/IR/Instruction.def"
4904 if (CV->getNumOperands() == 1)
4905 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4907 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4908 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4910 EntryBuilder->buildBuildVector(
Reg,
Ops);
4912 EntryBuilder->buildBlockAddress(
Reg, BA);
4919bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4920 const TargetMachine &TM = TLI->getTargetMachine();
4929 (!
U.getType()->getScalarType()->isBFloatTy() &&
4931 return V->getType()->getScalarType()->isBFloatTy();
4935bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4937 for (
auto &BTB : SL->BitTestCases) {
4940 emitBitTestHeader(BTB, BTB.Parent);
4942 BranchProbability UnhandledProb = BTB.Prob;
4943 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4944 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4946 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4955 MachineBasicBlock *NextMBB;
4956 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4959 NextMBB = BTB.Cases[
j + 1].TargetBB;
4960 }
else if (j + 1 == ej) {
4962 NextMBB = BTB.Default;
4965 NextMBB = BTB.Cases[
j + 1].ThisBB;
4968 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4970 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4974 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4975 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4978 BTB.Cases.pop_back();
4984 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4985 BTB.Default->getBasicBlock()};
4986 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4987 if (!BTB.ContiguousRange) {
4988 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4991 SL->BitTestCases.clear();
4993 for (
auto &JTCase : SL->JTCases) {
4995 if (!JTCase.first.Emitted)
4996 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4998 emitJumpTable(JTCase.second, JTCase.second.MBB);
5000 SL->JTCases.clear();
5002 for (
auto &SwCase : SL->SwitchCases)
5003 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
5004 SL->SwitchCases.clear();
5007 if (SPInfo->shouldEmitSDCheck(BB)) {
5008 bool FunctionBasedInstrumentation =
5009 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
5010 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
5013 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
5016 }
else if (SPDescriptor.shouldEmitStackProtector()) {
5017 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
5018 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
5027 ParentMBB, *MF->getSubtarget().getInstrInfo());
5030 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
5034 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
5038 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
5039 if (FailureMBB->
empty()) {
5040 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
5045 SPDescriptor.resetPerBBState();
5052 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
5056 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
5062 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
5069 ->buildLoad(PtrMemTy, StackSlotPtr,
5075 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
5087 FunctionType *FnTy = GuardCheckFn->getFunctionType();
5088 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
5089 ISD::ArgFlagsTy
Flags;
5090 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
5092 CallLowering::ArgInfo GuardArgInfo(
5093 {GuardVal, FnTy->getParamType(0), {
Flags}});
5095 CallLowering::CallLoweringInfo
Info;
5096 Info.OrigArgs.push_back(GuardArgInfo);
5097 Info.CallConv = GuardCheckFn->getCallingConv();
5100 if (!CLI->lowerCall(MIRBuilder, Info)) {
5101 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
5111 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
5112 getStackGuard(Guard, *CurBuilder);
5115 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
5117 Register GuardPtr = getOrCreateVReg(*IRGuard);
5120 ->buildLoad(PtrMemTy, GuardPtr,
5126 LLVMContext &Ctx = CurBuilder->getContext();
5127 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
5128 Guard = CurBuilder->buildUndef(PtrMemTy).getReg(0);
5144 const RTLIB::LibcallImpl LibcallImpl =
5145 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
5146 if (LibcallImpl == RTLIB::Unsupported)
5149 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
5151 CallLowering::CallLoweringInfo
Info;
5152 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
5154 StringRef LibcallName =
5159 if (!CLI->lowerCall(*CurBuilder, Info)) {
5160 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
5165 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
5167 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
5172void IRTranslatorImpl::finalizeFunction() {
5175 PendingPHIs.clear();
5176 PendingConstDbgValues.clear();
5178 FrameIndices.clear();
5179 MachinePreds.clear();
5183 EntryBuilder.reset();
5186 SPDescriptor.resetPerFunctionState();
5199 return CI && CI->isMustTailCall();
5211 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
5212 CLI = MF->getSubtarget().getCallLowering();
5213 SPInfo = StackProtectorInfo;
5215 if (CLI->fallBackToDAGISel(*MF)) {
5217 F.getSubprogram(), &
F.getEntryBlock());
5218 R <<
"unable to lower function: "
5219 <<
ore::NV(
"Prototype",
F.getFunctionType());
5236 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5237 CSEInfo = GetCSEInfo();
5238 EntryBuilder->setCSEInfo(CSEInfo);
5239 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5240 CurBuilder->setCSEInfo(CSEInfo);
5242 EntryBuilder = std::make_unique<MachineIRBuilder>();
5243 CurBuilder = std::make_unique<MachineIRBuilder>();
5246 CurBuilder->setMF(*MF);
5247 EntryBuilder->setMF(*MF);
5248 MRI = &MF->getRegInfo();
5249 DL = &
F.getDataLayout();
5253 FuncInfo.ExceptionModel =
F.getParent()->getExceptionModel();
5255 AA = GetAAResults();
5256 FuncInfo.BPI = GetBPI();
5260 FuncInfo.BPI =
nullptr;
5263 LibInfo = LibraryInfo;
5264 Libcalls = LibcallInfo;
5266 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5268 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5269 SL->init(*TLI, TM, *DL);
5271 assert(PendingPHIs.empty() &&
"stale PHIs");
5275 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5278 F.getSubprogram(), &
F.getEntryBlock());
5279 R <<
"unable to translate in big endian mode";
5290 EntryBuilder->setMBB(*EntryBB);
5292 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5293 SwiftError.setFunction(CurMF);
5294 SwiftError.createEntriesInEntryBlock(DbgLoc);
5296 bool IsVarArg =
F.isVarArg();
5297 bool HasMustTailInVarArgFn =
false;
5300 unsigned NumValues =
F.arg_size();
5303 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5305 NumValues += BB.
size();
5308 MBB = MF->CreateMachineBasicBlock(&BB);
5316 if (!BA->hasZeroLiveUses())
5320 if (!HasMustTailInVarArgFn)
5324 VMap.reserveVRegs(NumValues);
5325 MRI->reserveVirtRegs(NumValues);
5327 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5330 EntryBB->addSuccessor(&getMBB(
F.front()));
5335 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5340 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5341 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5342 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5346 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5348 F.getSubprogram(), &
F.getEntryBlock());
5349 R <<
"unable to lower arguments: "
5350 <<
ore::NV(
"Prototype",
F.getFunctionType());
5357 if (EnableCSE && CSEInfo)
5362 DILocationVerifier Verifier;
5370 CurBuilder->setMBB(
MBB);
5371 HasTailCall =
false;
5381 Verifier.setCurrentInst(&Inst);
5385 translateDbgInfo(Inst, *CurBuilder);
5387 if (translate(Inst))
5392 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5394 if (ORE->allowExtraAnalysis(
"gisel-ir-translator")) {
5395 std::string InstStrStorage;
5399 R <<
": '" << InstStrStorage <<
"'";
5406 if (!finalizeBasicBlock(*BB,
MBB)) {
5408 BB->getTerminator()->getDebugLoc(), BB);
5409 R <<
"unable to translate basic block";
5419 finishPendingPhis();
5420 finishPendingConstDbgValues();
5422 SwiftError.propagateVRegs();
5427 assert(EntryBB->succ_size() == 1 &&
5428 "Custom BB used for lowering should have only one successor");
5432 "LLVM-IR entry block has a predecessor!?");
5435 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5444 EntryBB->removeSuccessor(&NewEntryBB);
5445 MF->remove(EntryBB);
5446 MF->deleteMachineBasicBlock(EntryBB);
5448 assert(&MF->front() == &NewEntryBB &&
5449 "New entry wasn't next in the list of basic block!");
5452 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5462 return Impl->runOnMachineFunction(
5506 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5507 Impl->runOnMachineFunction(
5509 ShouldSkipOpts, [&]() {
return &
FAM.getResult<
AAManager>(
F); },
const AArch64Subtarget & Subtarget
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
This file describes how to lower LLVM calls to machine code calls.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This contains common code to allow clients to notify changes to machine instr.
const HexagonInstrInfo * TII
static cl::opt< bool > EnableCSEInIRTranslator("enable-cse-in-ir-translator", cl::desc("Should enable CSE in ir-translator"), cl::init(false))
static bool checkForMustTailInVarArgFn(bool IsVarArg, const BasicBlock &BB)
Returns true if a BasicBlock BB within a variadic function contains a variadic musttail call.
static unsigned getConvOpcode(Intrinsic::ID ID)
static uint64_t getOffsetFromIndices(const User &U, const DataLayout &DL)
static unsigned getConstrainedOpcode(Intrinsic::ID ID)
IRTranslator LLVM IR static false void reportTranslationError(MachineFunction &MF, OptimizationRemarkEmitter &ORE, OptimizationRemarkMissed &R)
static bool isValInBlock(const Value *V, const BasicBlock *BB)
static bool isSwiftError(const Value *V)
This file declares the IRTranslator pass.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This file describes how to lower LLVM inline asm to machine code INLINEASM.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Implement a low-level type suitable for MachineInstr level instruction selection.
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
OptimizedStructLayoutField Field
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
SmallVector< MachineOperand, 4 > Cond
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
std::pair< BasicBlock *, BasicBlock * > Edge
verify safepoint Safepoint IR Verifier
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
LLVM_ABI TypeSize getAllocationBaseSize(const DataLayout &DL) const
Get the size of the allocated type.
PointerType * getType() const
Overload to return most specific pointer type.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
const Value * getArraySize() const
Get the number of elements allocated.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
This class represents an incoming formal argument to a Function.
LLVM_ABI bool hasSwiftErrorAttr() const
Return true if this argument has the swifterror attribute.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
Get the first element.
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.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
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
LLVM_ABI iterator_range< location_op_iterator > location_ops() const
Get the locations corresponding to the variable referenced by the debug info intrinsic.
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.
constexpr unsigned getScalarSizeInBits() const
constexpr bool isFloatOrFloatVector() const
static bool getUseExtended()
constexpr bool isScalar() const
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
LLT changeToInteger() const
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 isPointerOrPointerVector() const
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)
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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 insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
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.
const TargetInstrInfo & getTII()
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...
MachineFunction & getMF()
Getter for the function we currently build.
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 CreateFPImm(const ConstantFP *CFP)
static MachineOperand CreateCImm(const ConstantInt *CI)
static MachineOperand CreateImm(int64_t Val)
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
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.
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 range adaptor for a pair of iterators.
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.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RelativeUniformCounterPtr Values
@ 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.