70#include "llvm/IR/IntrinsicsAMDGPU.h"
100#define DEBUG_TYPE "irtranslator"
106 cl::desc(
"Should enable CSE in irtranslator"),
118 class ValueToVRegInfo {
120 ValueToVRegInfo() =
default;
125 using const_vreg_iterator =
127 using const_offset_iterator =
130 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
132 VRegListT *getVRegs(
const Value &V) {
133 auto [It, Inserted] = ValToVRegs.try_emplace(&V);
139 It->second =
new (VRegAlloc.Allocate()) VRegListT();
143 OffsetListT *getOffsets(
const Value &V) {
144 assert(V.getType()->isAggregateType() &&
145 "Offsets are for aggregate values");
146 auto [It, Inserted] = TypeToOffsets.try_emplace(V.getType());
150 It->second =
new (OffsetAlloc.Allocate()) OffsetListT();
154 const_vreg_iterator findVRegs(
const Value &V)
const {
155 return ValToVRegs.find(&V);
158 bool contains(
const Value &V)
const {
return ValToVRegs.contains(&V); }
160 void reserveVRegs(
unsigned NumValues) { ValToVRegs.reserve(NumValues); }
164 TypeToOffsets.clear();
165 VRegAlloc.DestroyAll();
166 OffsetAlloc.DestroyAll();
181 ValueToVRegInfo VMap;
188 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
243 void translateDbgValueRecord(
Value *V,
bool HasArgList,
252 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
259 bool translateCopy(
const User &U,
const Value &V,
284 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
286 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
291 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
293 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
315 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
321 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
336 bool translateIntrinsic(
348 bool findUnwindDestinations(
361 bool translateCast(
unsigned Opcode,
const User &U,
372 return translateCompare(U, MIRBuilder);
377 return translateCompare(U, MIRBuilder);
382 void finishPendingPhis();
386 bool translateUnaryOp(
unsigned Opcode,
const User &U,
391 bool translateBinaryOp(
unsigned Opcode,
const User &U,
397 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
442 bool lowerJumpTableWorkItem(
451 bool FallthroughUnreachable,
457 bool lowerBitTestWorkItem(
463 bool FallthroughUnreachable);
494 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
497 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
500 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
503 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
506 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
509 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
513 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
516 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
519 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
522 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
525 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
528 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
532 return translatePtrToInt(U, MIRBuilder);
535 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
538 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
541 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
544 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
547 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
550 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
553 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
558 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
562 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
566 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
569 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
572 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
576 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
579 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
582 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
585 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
588 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
621 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
636 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
647 std::unique_ptr<MachineIRBuilder> CurBuilder;
652 std::unique_ptr<MachineIRBuilder> EntryBuilder;
665 std::unique_ptr<OptimizationRemarkEmitter> ORE;
676 bool EnableOpts =
false;
680 bool HasTailCall =
false;
684 bool mayTranslateUserTypes(
const User &U)
const;
691 assert(irt &&
"irt is null!");
694 void addSuccessorWithProb(
697 IRT->addSuccessorWithProb(Src, Dst, Prob);
700 ~GISelSwitchLowering()
override =
default;
706 std::unique_ptr<GISelSwitchLowering> SL;
712 void finalizeFunction();
750 auto Regs = getOrCreateVRegs(Val);
753 assert(Regs.size() == 1 &&
754 "attempt to get single VReg for aggregate or void");
758 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
760 auto &Regs = *VMap.getVRegs(Token);
762 assert(Regs.size() == 1 &&
763 "Expected a single register for convergence tokens.");
767 auto Reg = MRI->createGenericVirtualRegister(
LLT::token());
774 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
778 int getOrCreateFrameIndex(
const AllocaInst &AI);
801 auto RemappedEdge = MachinePreds.find(Edge);
802 if (RemappedEdge != MachinePreds.end())
803 return RemappedEdge->second;
812 void addSuccessorWithProb(
818 : OptLevel(OptLevel) {}
848 "IRTranslator LLVM IR -> MI",
false,
false)
860 MF.getProperties().setFailedISel();
861 bool IsGlobalISelAbortEnabled =
866 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
867 R << (
" (in function: " + MF.getName() +
")").str();
869 if (IsGlobalISelAbortEnabled)
889 DILocationVerifier() =
default;
890 ~DILocationVerifier()
override =
default;
892 const Instruction *getCurrentInst()
const {
return CurrInst; }
893 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
895 void erasingInstr(MachineInstr &
MI)
override {}
896 void changingInstr(MachineInstr &
MI)
override {}
897 void changedInstr(MachineInstr &
MI)
override {}
899 void createdInstr(MachineInstr &
MI)
override {
900 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
905 <<
" was copied to " <<
MI);
911 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
912 (
MI.isDebugInstr())) &&
913 "Line info was not transferred to all instructions");
936IRTranslatorImpl::ValueToVRegInfo::VRegListT &
937IRTranslatorImpl::allocateVRegs(
const Value &Val) {
938 auto VRegsIt = VMap.findVRegs(Val);
939 if (VRegsIt != VMap.vregs_end())
940 return *VRegsIt->second;
941 auto *Regs = VMap.getVRegs(Val);
947 auto *Offsets = VMap.getOffsets(Val);
950 Offsets->empty() ? Offsets :
nullptr);
951 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
957 auto VRegsIt = VMap.findVRegs(Val);
958 if (VRegsIt != VMap.vregs_end())
959 return *VRegsIt->second;
962 return *VMap.getVRegs(Val);
965 auto *VRegs = VMap.getVRegs(Val);
969 "Don't know how to create an empty vreg");
974 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
978 OptimizationRemarkMissed
R(
"gisel-irtranslator",
"GISelFailure",
979 MF->getFunction().getSubprogram(),
980 &MF->getFunction().getEntryBlock());
981 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
989 auto *
Offsets = VMap.getOffsets(Val);
991 Offsets->empty() ? Offsets :
nullptr);
994 for (
auto Ty : SplitTys)
995 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
1002 while (
auto Elt =
C.getAggregateElement(Idx++)) {
1003 auto EltRegs = getOrCreateVRegs(*Elt);
1010int IRTranslatorImpl::getOrCreateFrameIndex(
const AllocaInst &AI) {
1011 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
1013 return MapEntry->second;
1019 Size = std::max<uint64_t>(
Size, 1u);
1021 int &FI = MapEntry->second;
1022 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
1029 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
1030 MF->getFrameInfo().setStackID(FI, StackID);
1038 return SI->getAlign();
1040 return LI->getAlign();
1046 OptimizationRemarkMissed
R(
"gisel-irtranslator",
"", &
I);
1047 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
1053 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
1054 assert(
MBB &&
"BasicBlock was not encountered before");
1058void IRTranslatorImpl::addMachineCFGPred(CFGEdge
Edge,
1060 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
1061 MachinePreds[
Edge].push_back(NewPred);
1064bool IRTranslatorImpl::translateBinaryOp(
unsigned Opcode,
const User &U,
1066 if (!mayTranslateUserTypes(U))
1073 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1074 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1086bool IRTranslatorImpl::translateUnaryOp(
unsigned Opcode,
const User &U,
1088 if (!mayTranslateUserTypes(U))
1091 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1102bool IRTranslatorImpl::translateFNeg(
const User &U,
1104 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
1107bool IRTranslatorImpl::translateCompare(
const User &U,
1109 if (!mayTranslateUserTypes(U))
1113 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1114 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1119 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1, Flags);
1127 MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1, Flags);
1132bool IRTranslatorImpl::translateRet(
const User &U,
1136 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
1141 VRegs = getOrCreateVRegs(*Ret);
1144 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
1145 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
1146 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
1152 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
1155void IRTranslatorImpl::emitBranchForMergedCondition(
1164 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
1167 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
1170 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
1171 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
1172 CurBuilder->getDebugLoc(), TProb, FProb);
1173 SL->SwitchCases.push_back(CB);
1179 SwitchCG::CaseBlock CB(
1181 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
1182 SL->SwitchCases.push_back(CB);
1187 return I->getParent() == BB;
1191void IRTranslatorImpl::findMergedConditions(
1196 using namespace PatternMatch;
1197 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
1198 "Expected Opc to be AND/OR");
1204 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
1210 const Value *BOpOp0, *BOpOp1;
1224 if (BOpc == Instruction::And)
1225 BOpc = Instruction::Or;
1226 else if (BOpc == Instruction::Or)
1227 BOpc = Instruction::And;
1233 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
1237 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
1244 MachineBasicBlock *TmpBB =
1248 if (
Opc == Instruction::Or) {
1269 auto NewTrueProb = TProb / 2;
1270 auto NewFalseProb = TProb / 2 + FProb;
1272 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1273 NewFalseProb, InvertCond);
1279 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1280 Probs[1], InvertCond);
1282 assert(
Opc == Instruction::And &&
"Unknown merge op!");
1302 auto NewTrueProb = TProb + FProb / 2;
1303 auto NewFalseProb = FProb / 2;
1305 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1306 NewFalseProb, InvertCond);
1312 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1313 Probs[1], InvertCond);
1317bool IRTranslatorImpl::shouldEmitAsBranches(
1318 const std::vector<SwitchCG::CaseBlock> &Cases) {
1320 if (Cases.size() != 2)
1325 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
1326 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
1327 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
1328 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
1334 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
1335 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
1339 Cases[0].TrueBB == Cases[1].ThisBB)
1342 Cases[0].FalseBB == Cases[1].ThisBB)
1349bool IRTranslatorImpl::translateUncondBr(
const User &U,
1352 auto &CurMBB = MIRBuilder.
getMBB();
1357 MIRBuilder.
buildBr(*Succ0MBB);
1360 for (
const BasicBlock *Succ :
successors(&BrInst))
1365bool IRTranslatorImpl::translateCondBr(
const User &U,
1368 auto &CurMBB = MIRBuilder.
getMBB();
1374 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
1393 using namespace PatternMatch;
1395 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
1396 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
1399 const Value *BOp0, *BOp1;
1401 Opcode = Instruction::And;
1403 Opcode = Instruction::Or;
1407 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
1408 getEdgeProbability(&CurMBB, Succ0MBB),
1409 getEdgeProbability(&CurMBB, Succ1MBB),
1411 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
1414 if (shouldEmitAsBranches(SL->SwitchCases)) {
1416 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
1417 SL->SwitchCases.erase(SL->SwitchCases.begin());
1423 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
1424 MF->erase(SL->SwitchCases[
I].ThisBB);
1426 SL->SwitchCases.clear();
1433 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
1434 CurBuilder->getDebugLoc());
1438 emitSwitchCase(CB, &CurMBB, *CurBuilder);
1445 if (!FuncInfo.BPI) {
1446 Src->addSuccessorWithoutProb(Dst);
1450 Prob = getEdgeProbability(Src, Dst);
1451 Src->addSuccessor(Dst, Prob);
1457 const BasicBlock *SrcBB = Src->getBasicBlock();
1458 const BasicBlock *DstBB = Dst->getBasicBlock();
1459 if (!FuncInfo.BPI) {
1462 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
1463 return BranchProbability(1, SuccSize);
1465 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
1469 using namespace SwitchCG;
1472 BranchProbabilityInfo *BPI = FuncInfo.BPI;
1474 Clusters.reserve(
SI.getNumCases());
1475 for (
const auto &
I :
SI.cases()) {
1476 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
1477 assert(Succ &&
"Could not find successor mbb in mapping");
1478 const ConstantInt *CaseVal =
I.getCaseValue();
1479 BranchProbability Prob =
1481 : BranchProbability(1,
SI.getNumCases() + 1);
1482 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
1485 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
1492 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
1495 if (Clusters.empty()) {
1502 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
1503 SL->findBitTestClusters(Clusters, &SI);
1506 dbgs() <<
"Case clusters: ";
1507 for (
const CaseCluster &
C : Clusters) {
1508 if (
C.Kind == CC_JumpTable)
1510 if (
C.Kind == CC_BitTests)
1513 C.Low->getValue().print(
dbgs(),
true);
1514 if (
C.Low !=
C.High) {
1516 C.High->getValue().print(
dbgs(),
true);
1523 assert(!Clusters.empty());
1527 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
1528 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
1530 while (!WorkList.empty()) {
1531 SwitchWorkListItem
W = WorkList.pop_back_val();
1533 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
1535 if (NumClusters > 3 &&
1538 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
1542 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
1552 using namespace SwitchCG;
1553 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
1554 "Clusters not sorted?");
1555 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
1557 auto [LastLeft, FirstRight, LeftProb, RightProb] =
1558 SL->computeSplitWorkItemInfo(W);
1563 assert(PivotCluster >
W.FirstCluster);
1564 assert(PivotCluster <=
W.LastCluster);
1569 const ConstantInt *Pivot = PivotCluster->Low;
1578 MachineBasicBlock *LeftMBB;
1579 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
1580 FirstLeft->Low ==
W.GE &&
1581 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
1582 LeftMBB = FirstLeft->MBB;
1584 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1585 FuncInfo.MF->
insert(BBI, LeftMBB);
1587 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
1593 MachineBasicBlock *RightMBB;
1594 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
1595 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
1596 RightMBB = FirstRight->MBB;
1598 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1599 FuncInfo.MF->
insert(BBI, RightMBB);
1601 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
1609 if (
W.MBB == SwitchMBB)
1610 emitSwitchCase(CB, SwitchMBB, MIB);
1612 SL->SwitchCases.push_back(CB);
1618 assert(JT.
Reg &&
"Should lower JT Header first!");
1633 MachineIRBuilder MIB(*HeaderBB->
getParent());
1640 Register SwitchOpReg = getOrCreateVReg(SValue);
1642 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
1647 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
1661 auto Cst = getOrCreateVReg(
1701 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
1715 "Can only handle SLE ranges");
1726 const LLT CmpTy = MRI->getType(CmpOpReg);
1727 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1753bool IRTranslatorImpl::lowerJumpTableWorkItem(
1759 using namespace SwitchCG;
1762 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1763 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1764 BranchProbability DefaultProb =
W.DefaultProb;
1767 MachineBasicBlock *JumpMBB = JT->
MBB;
1768 CurMF->
insert(BBI, JumpMBB);
1778 auto JumpProb =
I->Prob;
1779 auto FallthroughProb = UnhandledProbs;
1787 if (*SI == DefaultMBB) {
1788 JumpProb += DefaultProb / 2;
1789 FallthroughProb -= DefaultProb / 2;
1794 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1799 if (FallthroughUnreachable)
1800 JTH->FallthroughUnreachable =
true;
1802 if (!JTH->FallthroughUnreachable)
1803 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1804 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1809 JTH->HeaderBB = CurMBB;
1813 if (CurMBB == SwitchMBB) {
1814 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1816 JTH->Emitted =
true;
1820bool IRTranslatorImpl::lowerSwitchRangeWorkItem(
1825 using namespace SwitchCG;
1828 if (
I->Low ==
I->High) {
1844 CaseBlock CB(Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1847 emitSwitchCase(CB, SwitchMBB, MIB);
1853 MachineIRBuilder &MIB = *CurBuilder;
1857 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1859 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1861 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1866 LLT MaskTy = SwitchOpTy;
1872 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1881 Register SubReg = RangeSub.getReg(0);
1882 if (SwitchOpTy != MaskTy)
1888 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1890 if (!
B.FallthroughUnreachable)
1891 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1892 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1896 if (!
B.FallthroughUnreachable) {
1900 RangeSub, RangeCst);
1914 MachineIRBuilder &MIB = *CurBuilder;
1920 if (PopCount == 1) {
1923 auto MaskTrailingZeros =
1928 }
else if (PopCount == BB.
Range) {
1930 auto MaskTrailingOnes =
1938 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1942 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1949 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1951 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1969bool IRTranslatorImpl::lowerBitTestWorkItem(
1975 bool FallthroughUnreachable) {
1976 using namespace SwitchCG;
1979 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
1981 for (BitTestCase &BTC : BTB->Cases)
1982 CurMF->
insert(BBI, BTC.ThisBB);
1985 BTB->Parent = CurMBB;
1986 BTB->Default = Fallthrough;
1988 BTB->DefaultProb = UnhandledProbs;
1992 if (!BTB->ContiguousRange) {
1993 BTB->Prob += DefaultProb / 2;
1994 BTB->DefaultProb -= DefaultProb / 2;
1997 if (FallthroughUnreachable)
1998 BTB->FallthroughUnreachable =
true;
2001 if (CurMBB == SwitchMBB) {
2002 emitBitTestHeader(*BTB, SwitchMBB);
2003 BTB->Emitted =
true;
2013 using namespace SwitchCG;
2015 MachineBasicBlock *NextMBB =
nullptr;
2017 if (++BBI != FuncInfo.MF->end())
2026 [](
const CaseCluster &a,
const CaseCluster &b) {
2027 return a.Prob != b.Prob
2029 : a.Low->getValue().slt(b.Low->getValue());
2034 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
2036 if (
I->Prob >
W.LastCluster->Prob)
2038 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
2046 BranchProbability DefaultProb =
W.DefaultProb;
2047 BranchProbability UnhandledProbs = DefaultProb;
2048 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
2049 UnhandledProbs +=
I->Prob;
2051 MachineBasicBlock *CurMBB =
W.MBB;
2052 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
2053 bool FallthroughUnreachable =
false;
2054 MachineBasicBlock *Fallthrough;
2055 if (
I ==
W.LastCluster) {
2057 Fallthrough = DefaultMBB;
2062 CurMF->
insert(BBI, Fallthrough);
2064 UnhandledProbs -=
I->Prob;
2068 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2069 DefaultProb, UnhandledProbs,
I, Fallthrough,
2070 FallthroughUnreachable)) {
2078 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2079 UnhandledProbs,
I, Fallthrough,
2080 FallthroughUnreachable)) {
2087 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
2088 FallthroughUnreachable, UnhandledProbs,
2089 CurMBB, MIB, SwitchMBB)) {
2096 CurMBB = Fallthrough;
2102bool IRTranslatorImpl::translateIndirectBr(
const User &U,
2110 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
2111 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
2112 for (
const BasicBlock *Succ :
successors(&BrInst)) {
2116 if (!AddedSuccessors.
insert(Succ).second)
2132bool IRTranslatorImpl::translateLoad(
const User &U,
2135 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
2146 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
2148 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
2154 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
2156 if (AA->pointsToConstantMemory(
2163 if (Regs.
size() == 1) {
2164 auto *MMO = MF->getMachineMemOperand(
2166 MRI->getType(Regs[0]), getMemOpAlign(LI),
2167 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
2173 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
2174 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
2176 for (
unsigned i = 0; i < Regs.
size(); ++i) {
2181 Align BaseAlign = getMemOpAlign(LI);
2183 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
2186 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
2192bool IRTranslatorImpl::translateStore(
const User &U,
2195 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
2201 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
2202 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
2204 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
2205 SI.getPointerOperand());
2212 if (Vals.
size() == 1) {
2213 auto *MMO = MF->getMachineMemOperand(
2214 MachinePointerInfo(
SI.getPointerOperand()), Flags,
2215 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
2216 SI.getSyncScopeID(),
SI.getOrdering());
2221 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
2222 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
2224 for (
unsigned i = 0; i < Vals.
size(); ++i) {
2228 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
2229 Align BaseAlign = getMemOpAlign(SI);
2230 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
2233 SI.getSyncScopeID(),
SI.getOrdering());
2240 const Value *Src = U.getOperand(0);
2246 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
2249 for (
auto Idx : EVI->indices())
2250 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2252 for (
auto Idx : IVI->indices())
2253 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2259 DL.getIndexedOffsetInType(Src->getType(), Indices));
2262bool IRTranslatorImpl::translateExtractValue(
const User &U,
2264 const Value *Src =
U.getOperand(0);
2267 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
2269 auto &DstRegs = allocateVRegs(U);
2271 for (
unsigned i = 0; i < DstRegs.size(); ++i)
2272 DstRegs[i] = SrcRegs[Idx++];
2277bool IRTranslatorImpl::translateInsertValue(
const User &U,
2279 const Value *Src =
U.getOperand(0);
2281 auto &DstRegs = allocateVRegs(U);
2282 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
2285 auto *InsertedIt = InsertedRegs.
begin();
2287 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
2288 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
2289 DstRegs[i] = *InsertedIt++;
2291 DstRegs[i] = SrcRegs[i];
2297bool IRTranslatorImpl::translateSelect(
const User &U,
2299 Register Tst = getOrCreateVReg(*
U.getOperand(0));
2308 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
2309 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
2315bool IRTranslatorImpl::translateCopy(
const User &U,
const Value &V,
2317 return translateCopy(U, getOrCreateVReg(V), MIRBuilder);
2320bool IRTranslatorImpl::translateCopy(
const User &U,
Register Src,
2322 auto &Regs = *VMap.getVRegs(U);
2324 Regs.push_back(Src);
2333bool IRTranslatorImpl::translateBitCast(
const User &U,
2335 Type *SrcTy =
U.getOperand(0)->getType();
2336 Type *DstTy =
U.getType();
2343 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
2345 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
2355 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
2357 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
2359 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
2362bool IRTranslatorImpl::translateCast(
unsigned Opcode,
const User &U,
2364 if (!mayTranslateUserTypes(U))
2377bool IRTranslatorImpl::translateGetElementPtr(
const User &U,
2379 Value &Op0 = *
U.getOperand(0);
2383 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
2386 uint32_t PtrAddFlags = 0;
2392 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
2402 unsigned VectorWidth = 0;
2406 bool WantSplatVector =
false;
2410 WantSplatVector = VectorWidth > 1;
2414 return translateCopy(U, BaseReg, MIRBuilder);
2418 if (WantSplatVector && !PtrTy.
isVector()) {
2425 OffsetIRTy = DL->getIndexType(PtrIRTy);
2432 const Value *Idx = GTI.getOperand();
2433 if (StructType *StTy = GTI.getStructTypeOrNull()) {
2435 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
2438 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
2443 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
2444 Offset += ElementSize * *Val;
2453 PtrAddFlagsWithConst(
Offset))
2458 Register IdxReg = getOrCreateVReg(*Idx);
2459 LLT IdxTy = MRI->getType(IdxReg);
2460 if (IdxTy != OffsetTy) {
2461 if (!IdxTy.
isVector() && WantSplatVector) {
2474 if (ElementSize != 1) {
2485 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
2488 GepOffsetReg = IdxReg;
2492 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
2501 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
2502 PtrAddFlagsWithConst(
Offset));
2506 return translateCopy(U, BaseReg, MIRBuilder);
2509bool IRTranslatorImpl::translateMemFunc(
const CallInst &CI,
2519 unsigned MinPtrSize = UINT_MAX;
2520 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
2521 Register SrcReg = getOrCreateVReg(**AI);
2522 LLT SrcTy = MRI->getType(SrcReg);
2524 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
2532 if (MRI->getType(SizeOpReg) != SizeTy)
2544 ConstantInt *CopySize =
nullptr;
2547 DstAlign = MCI->getDestAlign().valueOrOne();
2548 SrcAlign = MCI->getSourceAlign().valueOrOne();
2551 DstAlign = MMI->getDestAlign().valueOrOne();
2552 SrcAlign = MMI->getSourceAlign().valueOrOne();
2556 DstAlign = MSI->getDestAlign().valueOrOne();
2559 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
2560 Opcode != TargetOpcode::G_MEMSET_INLINE) {
2576 if (AA && CopySize &&
2577 AA->pointsToConstantMemory(MemoryLocation(
2587 ICall.addMemOperand(
2588 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
2589 StoreFlags, 1, DstAlign, AAInfo));
2590 if (Opcode != TargetOpcode::G_MEMSET &&
2591 Opcode != TargetOpcode::G_MEMSET_INLINE)
2592 ICall.addMemOperand(MF->getMachineMemOperand(
2593 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
2598bool IRTranslatorImpl::translateTrap(
const CallInst &CI,
2601 StringRef TrapFuncName =
2602 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
2603 if (TrapFuncName.
empty()) {
2604 if (Opcode == TargetOpcode::G_UBSANTRAP) {
2613 CallLowering::CallLoweringInfo
Info;
2614 if (Opcode == TargetOpcode::G_UBSANTRAP)
2621 return CLI->lowerCall(MIRBuilder, Info);
2624bool IRTranslatorImpl::translateVectorInterleave2Intrinsic(
2627 "This function can only be called on the interleave2 intrinsic!");
2631 Register Res = getOrCreateVReg(CI);
2633 LLT OpTy = MRI->getType(Op0);
2640bool IRTranslatorImpl::translateVectorDeinterleave2Intrinsic(
2643 "This function can only be called on the deinterleave2 intrinsic!");
2650 LLT ResTy = MRI->getType(Res[0]);
2667void IRTranslatorImpl::getStackGuard(
Register DstReg,
2670 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
2673 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
2678 const TargetInstrInfo &
TII = *MF->getSubtarget().getInstrInfo();
2679 MRI->setRegClass(DstReg,
2680 TII.getRegClass(
TII.get(TargetOpcode::LOAD_STACK_GUARD), 0));
2682 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
2684 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
2685 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
2687 MachinePointerInfo MPInfo(
Global);
2690 MachineMemOperand *MemRef = MF->getMachineMemOperand(
2691 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
2692 MIB.setMemRefs({MemRef});
2695bool IRTranslatorImpl::translateOverflowIntrinsic(
2699 Op, {ResRegs[0], ResRegs[1]},
2705bool IRTranslatorImpl::translateFixedPointIntrinsic(
2707 Register Dst = getOrCreateVReg(CI);
2711 MIRBuilder.
buildInstr(
Op, {Dst}, { Src0, Src1, Scale });
2715unsigned IRTranslatorImpl::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
2719 case Intrinsic::acos:
2720 return TargetOpcode::G_FACOS;
2721 case Intrinsic::asin:
2722 return TargetOpcode::G_FASIN;
2723 case Intrinsic::atan:
2724 return TargetOpcode::G_FATAN;
2725 case Intrinsic::atan2:
2726 return TargetOpcode::G_FATAN2;
2727 case Intrinsic::bswap:
2728 return TargetOpcode::G_BSWAP;
2729 case Intrinsic::bitreverse:
2730 return TargetOpcode::G_BITREVERSE;
2731 case Intrinsic::clmul:
2732 return TargetOpcode::G_CLMUL;
2733 case Intrinsic::fshl:
2734 return TargetOpcode::G_FSHL;
2735 case Intrinsic::fshr:
2736 return TargetOpcode::G_FSHR;
2737 case Intrinsic::ceil:
2738 return TargetOpcode::G_FCEIL;
2739 case Intrinsic::cos:
2740 return TargetOpcode::G_FCOS;
2741 case Intrinsic::cosh:
2742 return TargetOpcode::G_FCOSH;
2743 case Intrinsic::ctpop:
2744 return TargetOpcode::G_CTPOP;
2745 case Intrinsic::smulh:
2746 return TargetOpcode::G_SMULH;
2747 case Intrinsic::umulh:
2748 return TargetOpcode::G_UMULH;
2749 case Intrinsic::exp:
2750 return TargetOpcode::G_FEXP;
2751 case Intrinsic::exp2:
2752 return TargetOpcode::G_FEXP2;
2753 case Intrinsic::exp10:
2754 return TargetOpcode::G_FEXP10;
2755 case Intrinsic::fabs:
2756 return TargetOpcode::G_FABS;
2757 case Intrinsic::copysign:
2758 return TargetOpcode::G_FCOPYSIGN;
2759 case Intrinsic::minnum:
2760 return TargetOpcode::G_FMINNUM;
2761 case Intrinsic::maxnum:
2762 return TargetOpcode::G_FMAXNUM;
2763 case Intrinsic::minimum:
2764 return TargetOpcode::G_FMINIMUM;
2765 case Intrinsic::maximum:
2766 return TargetOpcode::G_FMAXIMUM;
2767 case Intrinsic::minimumnum:
2768 return TargetOpcode::G_FMINIMUMNUM;
2769 case Intrinsic::maximumnum:
2770 return TargetOpcode::G_FMAXIMUMNUM;
2771 case Intrinsic::canonicalize:
2772 return TargetOpcode::G_FCANONICALIZE;
2773 case Intrinsic::floor:
2774 return TargetOpcode::G_FFLOOR;
2775 case Intrinsic::fma:
2776 return TargetOpcode::G_FMA;
2777 case Intrinsic::log:
2778 return TargetOpcode::G_FLOG;
2779 case Intrinsic::log2:
2780 return TargetOpcode::G_FLOG2;
2781 case Intrinsic::log10:
2782 return TargetOpcode::G_FLOG10;
2783 case Intrinsic::ldexp:
2784 return TargetOpcode::G_FLDEXP;
2785 case Intrinsic::nearbyint:
2786 return TargetOpcode::G_FNEARBYINT;
2787 case Intrinsic::pow:
2788 return TargetOpcode::G_FPOW;
2789 case Intrinsic::powi:
2790 return TargetOpcode::G_FPOWI;
2791 case Intrinsic::rint:
2792 return TargetOpcode::G_FRINT;
2793 case Intrinsic::round:
2794 return TargetOpcode::G_INTRINSIC_ROUND;
2795 case Intrinsic::roundeven:
2796 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2797 case Intrinsic::sin:
2798 return TargetOpcode::G_FSIN;
2799 case Intrinsic::sinh:
2800 return TargetOpcode::G_FSINH;
2801 case Intrinsic::sqrt:
2802 return TargetOpcode::G_FSQRT;
2803 case Intrinsic::tan:
2804 return TargetOpcode::G_FTAN;
2805 case Intrinsic::tanh:
2806 return TargetOpcode::G_FTANH;
2807 case Intrinsic::trunc:
2808 return TargetOpcode::G_INTRINSIC_TRUNC;
2809 case Intrinsic::readcyclecounter:
2810 return TargetOpcode::G_READCYCLECOUNTER;
2811 case Intrinsic::readsteadycounter:
2812 return TargetOpcode::G_READSTEADYCOUNTER;
2813 case Intrinsic::ptrmask:
2814 return TargetOpcode::G_PTRMASK;
2815 case Intrinsic::lrint:
2816 return TargetOpcode::G_INTRINSIC_LRINT;
2817 case Intrinsic::llrint:
2818 return TargetOpcode::G_INTRINSIC_LLRINT;
2820 case Intrinsic::vector_reduce_fmin:
2821 return TargetOpcode::G_VECREDUCE_FMIN;
2822 case Intrinsic::vector_reduce_fmax:
2823 return TargetOpcode::G_VECREDUCE_FMAX;
2824 case Intrinsic::vector_reduce_fminimum:
2825 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2826 case Intrinsic::vector_reduce_fmaximum:
2827 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2828 case Intrinsic::vector_reduce_fminimumnum:
2829 return TargetOpcode::G_VECREDUCE_FMINIMUMNUM;
2830 case Intrinsic::vector_reduce_fmaximumnum:
2831 return TargetOpcode::G_VECREDUCE_FMAXIMUMNUM;
2832 case Intrinsic::vector_reduce_add:
2833 return TargetOpcode::G_VECREDUCE_ADD;
2834 case Intrinsic::vector_reduce_mul:
2835 return TargetOpcode::G_VECREDUCE_MUL;
2836 case Intrinsic::vector_reduce_and:
2837 return TargetOpcode::G_VECREDUCE_AND;
2838 case Intrinsic::vector_reduce_or:
2839 return TargetOpcode::G_VECREDUCE_OR;
2840 case Intrinsic::vector_reduce_xor:
2841 return TargetOpcode::G_VECREDUCE_XOR;
2842 case Intrinsic::vector_reduce_smax:
2843 return TargetOpcode::G_VECREDUCE_SMAX;
2844 case Intrinsic::vector_reduce_smin:
2845 return TargetOpcode::G_VECREDUCE_SMIN;
2846 case Intrinsic::vector_reduce_umax:
2847 return TargetOpcode::G_VECREDUCE_UMAX;
2848 case Intrinsic::vector_reduce_umin:
2849 return TargetOpcode::G_VECREDUCE_UMIN;
2850 case Intrinsic::experimental_vector_compress:
2851 return TargetOpcode::G_VECTOR_COMPRESS;
2852 case Intrinsic::lround:
2853 return TargetOpcode::G_LROUND;
2854 case Intrinsic::llround:
2855 return TargetOpcode::G_LLROUND;
2856 case Intrinsic::get_fpenv:
2857 return TargetOpcode::G_GET_FPENV;
2858 case Intrinsic::get_fpmode:
2859 return TargetOpcode::G_GET_FPMODE;
2864bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2868 unsigned Op = getSimpleIntrinsicOpcode(ID);
2876 for (
const auto &Arg : CI.
args())
2879 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2887 case Intrinsic::experimental_constrained_fadd:
2888 return TargetOpcode::G_STRICT_FADD;
2889 case Intrinsic::experimental_constrained_fsub:
2890 return TargetOpcode::G_STRICT_FSUB;
2891 case Intrinsic::experimental_constrained_fmul:
2892 return TargetOpcode::G_STRICT_FMUL;
2893 case Intrinsic::experimental_constrained_fdiv:
2894 return TargetOpcode::G_STRICT_FDIV;
2895 case Intrinsic::experimental_constrained_frem:
2896 return TargetOpcode::G_STRICT_FREM;
2897 case Intrinsic::experimental_constrained_fma:
2898 return TargetOpcode::G_STRICT_FMA;
2899 case Intrinsic::experimental_constrained_sqrt:
2900 return TargetOpcode::G_STRICT_FSQRT;
2901 case Intrinsic::experimental_constrained_ldexp:
2902 return TargetOpcode::G_STRICT_FLDEXP;
2903 case Intrinsic::experimental_constrained_fcmp:
2904 return TargetOpcode::G_STRICT_FCMP;
2905 case Intrinsic::experimental_constrained_fcmps:
2906 return TargetOpcode::G_STRICT_FCMPS;
2912bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2924 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2925 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2927 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2928 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2931 .addPredicate(FPCmp->getPredicate())
2945std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2946 auto VRegs = getOrCreateVRegs(Arg);
2947 if (VRegs.
size() != 1)
2948 return std::nullopt;
2951 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2952 if (!VRegDef || !VRegDef->isCopy())
2953 return std::nullopt;
2954 return VRegDef->getOperand(1).getReg().asMCReg();
2957bool IRTranslatorImpl::translateIfEntryValueArgument(
2968 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2970 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2971 <<
": expression is entry_value but "
2972 <<
"couldn't find a physical register\n");
2980 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
2992 case Intrinsic::experimental_convergence_anchor:
2993 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
2994 case Intrinsic::experimental_convergence_entry:
2995 return TargetOpcode::CONVERGENCECTRL_ENTRY;
2996 case Intrinsic::experimental_convergence_loop:
2997 return TargetOpcode::CONVERGENCECTRL_LOOP;
3001bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
3004 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3007 if (ID == Intrinsic::experimental_convergence_loop) {
3009 assert(Bundle &&
"Expected a convergence control token.");
3011 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3018bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3022 if (ORE->enabled()) {
3024 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3032 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3038 case Intrinsic::lifetime_start:
3039 case Intrinsic::lifetime_end: {
3042 MF->getFunction().hasOptNone())
3045 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3046 : TargetOpcode::LIFETIME_END;
3055 case Intrinsic::fake_use: {
3057 for (
const auto &Arg : CI.
args())
3059 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3060 MF->setHasFakeUses(
true);
3063 case Intrinsic::dbg_declare: {
3070 case Intrinsic::dbg_label: {
3076 "Expected inlined-at fields to agree");
3081 case Intrinsic::vaend:
3085 case Intrinsic::vastart: {
3087 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3090 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3091 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3093 ListSize, Alignment));
3096 case Intrinsic::dbg_assign:
3103 case Intrinsic::dbg_value: {
3110 case Intrinsic::uadd_with_overflow:
3111 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3112 case Intrinsic::sadd_with_overflow:
3113 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3114 case Intrinsic::usub_with_overflow:
3115 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3116 case Intrinsic::ssub_with_overflow:
3117 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3118 case Intrinsic::umul_with_overflow:
3119 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3120 case Intrinsic::smul_with_overflow:
3121 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3122 case Intrinsic::uadd_sat:
3123 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3124 case Intrinsic::sadd_sat:
3125 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3126 case Intrinsic::usub_sat:
3127 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3128 case Intrinsic::ssub_sat:
3129 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3130 case Intrinsic::ushl_sat:
3131 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3132 case Intrinsic::sshl_sat:
3133 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3134 case Intrinsic::umin:
3135 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3136 case Intrinsic::umax:
3137 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3138 case Intrinsic::smin:
3139 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3140 case Intrinsic::smax:
3141 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3142 case Intrinsic::abs:
3144 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3145 case Intrinsic::smul_fix:
3146 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3147 case Intrinsic::umul_fix:
3148 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3149 case Intrinsic::smul_fix_sat:
3150 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3151 case Intrinsic::umul_fix_sat:
3152 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3153 case Intrinsic::sdiv_fix:
3154 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3155 case Intrinsic::udiv_fix:
3156 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3157 case Intrinsic::sdiv_fix_sat:
3158 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3159 case Intrinsic::udiv_fix_sat:
3160 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3161 case Intrinsic::fmuladd: {
3162 Register Dst = getOrCreateVReg(CI);
3166 if (TLI->isFMAFasterThanFMulAndFAdd(*MF,
3167 TLI->getValueType(*DL, CI.
getType()))) {
3170 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3181 case Intrinsic::frexp: {
3188 case Intrinsic::modf: {
3190 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3195 case Intrinsic::sincos: {
3202 case Intrinsic::fptosi_sat:
3206 case Intrinsic::fptoui_sat:
3210 case Intrinsic::memcpy_inline:
3211 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3212 case Intrinsic::memcpy:
3213 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3214 case Intrinsic::memmove:
3215 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3216 case Intrinsic::memset:
3217 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3218 case Intrinsic::memset_inline:
3219 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3220 case Intrinsic::eh_typeid_for: {
3223 unsigned TypeID = MF->getTypeIDFor(GV);
3227 case Intrinsic::objectsize:
3230 case Intrinsic::is_constant:
3233 case Intrinsic::stackguard:
3234 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3236 case Intrinsic::stackprotector: {
3239 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3240 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3241 getStackGuard(GuardVal, MIRBuilder);
3246 int FI = getOrCreateFrameIndex(*Slot);
3247 MF->getFrameInfo().setStackProtectorIndex(FI);
3250 GuardVal, getOrCreateVReg(*Slot),
3257 case Intrinsic::stacksave: {
3258 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3261 case Intrinsic::stackrestore: {
3262 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3266 case Intrinsic::cttz:
3267 case Intrinsic::ctlz: {
3269 bool isTrailing =
ID == Intrinsic::cttz;
3270 unsigned Opcode = isTrailing ? Cst->
isZero()
3271 ? TargetOpcode::G_CTTZ
3272 : TargetOpcode::G_CTTZ_ZERO_POISON
3273 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3274 : TargetOpcode::G_CTLZ_ZERO_POISON;
3275 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3279 case Intrinsic::invariant_start: {
3283 case Intrinsic::invariant_end:
3285 case Intrinsic::expect:
3286 case Intrinsic::expect_with_probability:
3287 case Intrinsic::annotation:
3288 case Intrinsic::ptr_annotation:
3289 case Intrinsic::launder_invariant_group:
3290 case Intrinsic::strip_invariant_group:
3291 case Intrinsic::threadlocal_address: {
3293 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3297 case Intrinsic::assume:
3298 case Intrinsic::experimental_noalias_scope_decl:
3299 case Intrinsic::var_annotation:
3300 case Intrinsic::sideeffect:
3303 case Intrinsic::read_volatile_register:
3304 case Intrinsic::read_register: {
3307 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3311 case Intrinsic::write_register: {
3313 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3318 case Intrinsic::localescape: {
3319 MachineBasicBlock &EntryMBB = MF->front();
3324 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3331 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3344 case Intrinsic::vector_reduce_fadd:
3345 case Intrinsic::vector_reduce_fmul: {
3348 Register Dst = getOrCreateVReg(CI);
3354 Opc =
ID == Intrinsic::vector_reduce_fadd
3355 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3356 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3357 if (!MRI->getType(VecSrc).isVector())
3358 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3359 : TargetOpcode::G_FMUL;
3367 if (ID == Intrinsic::vector_reduce_fadd) {
3368 Opc = TargetOpcode::G_VECREDUCE_FADD;
3369 ScalarOpc = TargetOpcode::G_FADD;
3371 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3372 ScalarOpc = TargetOpcode::G_FMUL;
3374 LLT DstTy = MRI->getType(Dst);
3377 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3382 case Intrinsic::trap:
3383 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3384 case Intrinsic::debugtrap:
3385 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3386 case Intrinsic::ubsantrap:
3387 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3388 case Intrinsic::allow_runtime_check:
3389 case Intrinsic::allow_ubsan_check:
3390 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3393 case Intrinsic::amdgcn_cs_chain:
3394 case Intrinsic::amdgcn_call_whole_wave:
3395 return translateCallBase(CI, MIRBuilder);
3396 case Intrinsic::fptrunc_round: {
3401 std::optional<RoundingMode> RoundMode =
3406 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3407 {getOrCreateVReg(CI)},
3409 .addImm((
int)*RoundMode);
3413 case Intrinsic::is_fpclass: {
3418 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3419 {getOrCreateVReg(*FpValue)})
3424 case Intrinsic::set_fpenv: {
3429 case Intrinsic::reset_fpenv:
3432 case Intrinsic::set_fpmode: {
3437 case Intrinsic::reset_fpmode:
3440 case Intrinsic::get_rounding:
3443 case Intrinsic::set_rounding:
3446 case Intrinsic::vscale: {
3450 case Intrinsic::scmp:
3451 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3455 case Intrinsic::ucmp:
3456 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3460 case Intrinsic::vector_extract:
3461 return translateExtractVector(CI, MIRBuilder);
3462 case Intrinsic::vector_insert:
3463 return translateInsertVector(CI, MIRBuilder);
3464 case Intrinsic::stepvector: {
3468 case Intrinsic::prefetch: {
3475 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3478 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3484 case Intrinsic::speculative_load: {
3488 Register Dst = getOrCreateVReg(CI);
3490 Flags |= TLI->getTargetMMOFlags(CI);
3493 if (CI.
hasMetadata(LLVMContext::MD_invariant_load))
3495 auto *MMO = MF->getMachineMemOperand(
3496 MachinePointerInfo(Ptr), Flags, MRI->getType(Dst),
3498 MIRBuilder.
buildLoad(Dst, getOrCreateVReg(*Ptr), *MMO);
3502 case Intrinsic::vector_interleave2:
3503 case Intrinsic::vector_deinterleave2: {
3511 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3513 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3516#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3517 case Intrinsic::INTRINSIC:
3518#include "llvm/IR/ConstrainedOps.def"
3521 case Intrinsic::experimental_convergence_anchor:
3522 case Intrinsic::experimental_convergence_entry:
3523 case Intrinsic::experimental_convergence_loop:
3524 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3525 case Intrinsic::reloc_none: {
3528 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3536bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3538 if (!mayTranslateUserTypes(CB))
3541 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3545 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3550 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3553bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3560 for (
const auto &Arg : CB.
args()) {
3562 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3564 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3565 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3566 &CB, &MIRBuilder.
getMBB(), Arg));
3569 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3572 Args.push_back(getOrCreateVRegs(*Arg));
3576 if (ORE->enabled()) {
3578 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3584 std::optional<CallLowering::PtrAuthInfo> PAI;
3589 const Value *
Key = Bundle->Inputs[0];
3596 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3597 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3599 Register DiscReg = getOrCreateVReg(*Discriminator);
3607 const auto &Token = *Bundle->Inputs[0].get();
3608 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3614 bool Success = CLI->lowerCall(
3615 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3620 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3621 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3628bool IRTranslatorImpl::translateCall(
const User &U,
3630 if (!mayTranslateUserTypes(U))
3638 if (
F && (
F->hasDLLImportStorageClass() ||
3639 (MF->getTarget().getTargetTriple().isOSWindows() &&
3640 F->hasExternalWeakLinkage())))
3652 return translateInlineAsm(CI, MIRBuilder);
3656 if (translateCallBase(CI, MIRBuilder)) {
3665 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3666 const Function &Fn = MF->getFunction();
3668 DiagnosticInfoUnsupportedTargetIntrinsic(Fn, ID, CI.
getDebugLoc()));
3671 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3675 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3677 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3681bool IRTranslatorImpl::translateIntrinsic(
3684 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3686 F.getContext().diagnose(
3687 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3692 ResultRegs = getOrCreateVRegs(CB);
3696 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3707 assert(CI->getBitWidth() <= 64 &&
3708 "large intrinsic immediates not handled");
3709 MIB.
addImm(CI->getSExtValue());
3714 auto *MD = MDVal->getMetadata();
3718 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3725 if (VRegs.
size() > 1)
3732 for (
const auto &Info : TgtMemIntrinsicInfos) {
3735 LLT MemTy =
Info.memVT.isSimple()
3737 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3741 MachinePointerInfo MPI;
3743 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3744 }
else if (
Info.fallbackAddressSpace) {
3745 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3754 auto *Token = Bundle->Inputs[0].get();
3755 Register TokenReg = getOrCreateVReg(*Token);
3766bool IRTranslatorImpl::findUnwindDestinations(
3787 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3793 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3794 UnwindDests.back().first->setIsEHScopeEntry();
3795 UnwindDests.back().first->setIsEHFuncletEntry();
3800 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3801 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3803 if (IsMSVCCXX || IsCoreCLR)
3804 UnwindDests.back().first->setIsEHFuncletEntry();
3806 UnwindDests.back().first->setIsEHScopeEntry();
3808 NewEHPadBB = CatchSwitch->getUnwindDest();
3813 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3814 if (BPI && NewEHPadBB)
3816 EHPadBB = NewEHPadBB;
3821bool IRTranslatorImpl::translateInvoke(
const User &U,
3824 MCContext &
Context = MF->getContext();
3829 const Function *Fn =
I.getCalledFunction();
3836 if (
I.hasDeoptState())
3850 (MF->getTarget().getTargetTriple().isOSWindows() &&
3854 bool LowerInlineAsm =
I.isInlineAsm();
3855 bool NeedEHLabel =
true;
3861 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3862 BeginSymbol =
Context.createTempSymbol();
3866 if (LowerInlineAsm) {
3867 if (!translateInlineAsm(
I, MIRBuilder))
3869 }
else if (!translateCallBase(
I, MIRBuilder))
3874 EndSymbol =
Context.createTempSymbol();
3879 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3880 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3881 BranchProbability EHPadBBProb =
3885 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3888 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3889 &ReturnMBB = getMBB(*ReturnBB);
3891 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3892 for (
auto &UnwindDest : UnwindDests) {
3893 UnwindDest.first->setIsEHPad();
3894 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3899 assert(BeginSymbol &&
"Expected a begin symbol!");
3900 assert(EndSymbol &&
"Expected an end symbol!");
3901 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3904 MIRBuilder.
buildBr(ReturnMBB);
3910bool IRTranslatorImpl::translateCallBr(
const User &U,
3912 if (!mayTranslateUserTypes(U))
3916 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3919 if (
I.isInlineAsm()) {
3925 if (!translateIntrinsic(
I, IID, MIRBuilder))
3929 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3930 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3939 for (BasicBlock *Dest :
I.getIndirectDests()) {
3940 MachineBasicBlock &
Target = getMBB(*Dest);
3941 Target.setIsInlineAsmBrIndirectTarget();
3942 Target.setLabelMustBeEmitted();
3944 if (Dests.
insert(Dest).second)
3956bool IRTranslatorImpl::translateLandingPad(
const User &U,
3960 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3966 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3967 if (TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel,
3968 PersonalityFn) == 0 &&
3969 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel,
3970 PersonalityFn) == 0)
3982 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3987 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3988 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3989 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
3998 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
4002 TLI->getExceptionPointerRegister(FuncInfo.ExceptionModel, PersonalityFn);
4008 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
4011 TLI->getExceptionSelectorRegister(FuncInfo.ExceptionModel, PersonalityFn);
4016 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
4017 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
4018 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
4023bool IRTranslatorImpl::translateAlloca(
const User &U,
4031 Register Res = getOrCreateVReg(AI);
4032 int FI = getOrCreateFrameIndex(AI);
4038 if (MF->getTarget().getTargetTriple().isOSWindows())
4043 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4045 if (MRI->getType(NumElts) !=
IntPtrTy) {
4057 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4062 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4064 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4069 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4078 if (Alignment <= StackAlign)
4082 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4083 assert(MF->getFrameInfo().hasVarSizedObjects());
4087bool IRTranslatorImpl::translateVAArg(
const User &U,
4093 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4094 {getOrCreateVReg(*
U.getOperand(0)),
4095 DL->getABITypeAlign(
U.getType()).value()});
4099bool IRTranslatorImpl::translateUnreachable(
const User &U,
4102 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4103 MF->getTarget().Options.NoTrapAfterNoreturn))
4110bool IRTranslatorImpl::translateInsertElement(
const User &U,
4115 FVT && FVT->getNumElements() == 1)
4116 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4119 Register Val = getOrCreateVReg(*
U.getOperand(0));
4120 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4121 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4124 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4125 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4126 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4127 Idx = getOrCreateVReg(*NewIdxCI);
4131 Idx = getOrCreateVReg(*
U.getOperand(2));
4132 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4133 const LLT VecIdxTy =
4134 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4141bool IRTranslatorImpl::translateInsertVector(
const User &U,
4144 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4145 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4148 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4153 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4158 ResultType && ResultType->getNumElements() == 1) {
4160 InputType && InputType->getNumElements() == 1) {
4164 return translateCopy(U, Vec, MIRBuilder);
4170 Register Idx = getOrCreateVReg(*CI);
4178 Register Idx = getOrCreateVReg(*CI);
4179 auto ScaledIndex = MIRBuilder.
buildMul(
4180 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4190bool IRTranslatorImpl::translateExtractElement(
const User &U,
4194 if (
const FixedVectorType *FVT =
4196 if (FVT->getNumElements() == 1)
4197 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4200 Register Val = getOrCreateVReg(*
U.getOperand(0));
4201 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4206 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4207 Idx = getOrCreateVReg(*NewIdxCI);
4211 Idx = getOrCreateVReg(*
U.getOperand(1));
4212 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4213 const LLT VecIdxTy =
4221bool IRTranslatorImpl::translateExtractVector(
const User &U,
4224 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4226 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4231 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4236 ResultType && ResultType->getNumElements() == 1) {
4238 InputType && InputType->getNumElements() == 1) {
4241 return translateCopy(U, Vec, MIRBuilder);
4247 Register Idx = getOrCreateVReg(*CI);
4255 Register Idx = getOrCreateVReg(*CI);
4256 auto ScaledIndex = MIRBuilder.
buildMul(
4257 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4267bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4273 if (
U.getOperand(0)->getType()->isScalableTy()) {
4274 Register Val = getOrCreateVReg(*
U.getOperand(0));
4276 MRI->getType(Val).getElementType(), Val, 0);
4283 Mask = SVI->getShuffleMask();
4294 unsigned M =
Mask[0];
4296 if (M == 0 || M == 1)
4297 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4303 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4304 }
else if (M < SrcElts * 2) {
4306 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4318 for (
int M : Mask) {
4320 if (M == 0 || M == 1) {
4321 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4323 if (!
Undef.isValid()) {
4324 Undef = MRI->createGenericVirtualRegister(SrcTy);
4334 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4336 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4337 {getOrCreateVReg(*
U.getOperand(0)),
4338 getOrCreateVReg(*
U.getOperand(1))})
4339 .addShuffleMask(MaskAlloc);
4343bool IRTranslatorImpl::translatePHI(
const User &U,
4347 SmallVector<MachineInstr *, 4> Insts;
4348 for (
auto Reg : getOrCreateVRegs(PI)) {
4349 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4353 PendingPHIs.emplace_back(&PI, std::move(Insts));
4357bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4361 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4363 auto Res = getOrCreateVRegs(
I);
4366 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4367 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4368 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4371 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4372 *MF->getMachineMemOperand(
4373 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4374 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4375 I.getSuccessOrdering(),
I.getFailureOrdering()));
4379bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4381 if (!mayTranslateUserTypes(U))
4385 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4388 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4389 Register Val = getOrCreateVReg(*
I.getValOperand());
4391 unsigned Opcode = 0;
4392 switch (
I.getOperation()) {
4396 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4399 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4402 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4405 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4408 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4411 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4414 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4417 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4420 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4423 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4426 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4429 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4432 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4435 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4438 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4441 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4444 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4447 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4450 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4453 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4456 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4459 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4462 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4467 Opcode, Res, Addr, Val,
4468 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4469 Flags, MRI->getType(Val), getMemOpAlign(
I),
4470 I.getAAMetadata(),
I.getSyncScopeID(),
4475bool IRTranslatorImpl::translateFence(
const User &U,
4479 Fence.getSyncScopeID());
4483bool IRTranslatorImpl::translateFreeze(
const User &U,
4489 "Freeze with different source and destination type?");
4491 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4498void IRTranslatorImpl::finishPendingPhis() {
4501 GISelObserverWrapper WrapperObserver(&
Verifier);
4502 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4504 for (
auto &Phi : PendingPHIs) {
4505 const PHINode *PI =
Phi.first;
4509 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4515 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4519 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4523 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4524 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4533void IRTranslatorImpl::translateDbgValueRecord(
Value *V,
bool HasArgList,
4539 "Expected inlined-at fields to agree");
4543 if (!V || HasArgList) {
4561 auto *ExprDerefRemoved =
4567 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
4579void IRTranslatorImpl::translateDbgDeclareRecord(
4584 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4589 "Expected inlined-at fields to agree");
4594 MF->setVariableDbgInfo(Variable, Expression,
4595 getOrCreateFrameIndex(*AI), DL);
4599 if (translateIfEntryValueArgument(
true,
Address, Variable,
4611void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4616 assert(DLR->getLabel() &&
"Missing label");
4617 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4619 "Expected inlined-at fields to agree");
4628 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
4631 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
4636bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4638 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4639 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4641 if (TLI->fallBackToDAGISel(Inst))
4645#define HANDLE_INST(NUM, OPCODE, CLASS) \
4646 case Instruction::OPCODE: \
4647 return translate##OPCODE(Inst, *CurBuilder.get());
4648#include "llvm/IR/Instruction.def"
4657 if (
auto CurrInstDL = CurBuilder->getDL())
4658 EntryBuilder->setDebugLoc(
DebugLoc());
4664 EntryBuilder->buildConstant(
Reg, *CI);
4668 EntryBuilder->buildConstant(
Reg, CB->getValue());
4672 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4673 EntryBuilder->buildFConstant(
Reg, *CF);
4675 EntryBuilder->buildUndef(
Reg);
4677 EntryBuilder->buildConstant(
Reg, 0);
4679 EntryBuilder->buildGlobalValue(
Reg, GV);
4681 Register Addr = getOrCreateVReg(*CPA->getPointer());
4682 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4683 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4685 Constant &Elt = *CAZ->getElementValue(0u);
4687 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4691 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4693 return translateCopy(
C, Elt, *EntryBuilder);
4695 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4698 if (CV->getNumElements() == 1)
4699 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4701 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4702 Constant &Elt = *CV->getElementAsConstant(i);
4703 Ops.push_back(getOrCreateVReg(Elt));
4705 EntryBuilder->buildBuildVector(
Reg,
Ops);
4707 switch(
CE->getOpcode()) {
4708#define HANDLE_INST(NUM, OPCODE, CLASS) \
4709 case Instruction::OPCODE: \
4710 return translate##OPCODE(*CE, *EntryBuilder.get());
4711#include "llvm/IR/Instruction.def"
4716 if (CV->getNumOperands() == 1)
4717 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4719 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4720 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4722 EntryBuilder->buildBuildVector(
Reg,
Ops);
4724 EntryBuilder->buildBlockAddress(
Reg, BA);
4731bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4732 const TargetMachine &TM = TLI->getTargetMachine();
4741 (!
U.getType()->getScalarType()->isBFloatTy() &&
4743 return V->getType()->getScalarType()->isBFloatTy();
4747bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4749 for (
auto &BTB : SL->BitTestCases) {
4752 emitBitTestHeader(BTB, BTB.Parent);
4754 BranchProbability UnhandledProb = BTB.Prob;
4755 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4756 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4758 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4767 MachineBasicBlock *NextMBB;
4768 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4771 NextMBB = BTB.Cases[
j + 1].TargetBB;
4772 }
else if (j + 1 == ej) {
4774 NextMBB = BTB.Default;
4777 NextMBB = BTB.Cases[
j + 1].ThisBB;
4780 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4782 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4786 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4787 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4790 BTB.Cases.pop_back();
4796 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4797 BTB.Default->getBasicBlock()};
4798 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4799 if (!BTB.ContiguousRange) {
4800 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4803 SL->BitTestCases.clear();
4805 for (
auto &JTCase : SL->JTCases) {
4807 if (!JTCase.first.Emitted)
4808 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4810 emitJumpTable(JTCase.second, JTCase.second.MBB);
4812 SL->JTCases.clear();
4814 for (
auto &SwCase : SL->SwitchCases)
4815 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4816 SL->SwitchCases.clear();
4819 if (SPInfo->shouldEmitSDCheck(BB)) {
4820 bool FunctionBasedInstrumentation =
4821 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4822 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4825 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4828 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4829 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4830 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4839 ParentMBB, *MF->getSubtarget().getInstrInfo());
4842 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4846 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4850 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4851 if (FailureMBB->
empty()) {
4852 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4857 SPDescriptor.resetPerBBState();
4864 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4868 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
4874 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
4881 ->buildLoad(PtrMemTy, StackSlotPtr,
4887 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
4899 FunctionType *FnTy = GuardCheckFn->getFunctionType();
4900 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
4901 ISD::ArgFlagsTy
Flags;
4902 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
4904 CallLowering::ArgInfo GuardArgInfo(
4905 {GuardVal, FnTy->getParamType(0), {
Flags}});
4907 CallLowering::CallLoweringInfo
Info;
4908 Info.OrigArgs.push_back(GuardArgInfo);
4909 Info.CallConv = GuardCheckFn->getCallingConv();
4912 if (!CLI->lowerCall(MIRBuilder, Info)) {
4913 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
4923 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
4924 getStackGuard(Guard, *CurBuilder);
4927 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
4928 Register GuardPtr = getOrCreateVReg(*IRGuard);
4931 ->buildLoad(PtrMemTy, GuardPtr,
4950 const RTLIB::LibcallImpl LibcallImpl =
4951 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
4952 if (LibcallImpl == RTLIB::Unsupported)
4955 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
4957 CallLowering::CallLoweringInfo
Info;
4958 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
4960 StringRef LibcallName =
4965 if (!CLI->lowerCall(*CurBuilder, Info)) {
4966 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
4971 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
4973 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
4978void IRTranslatorImpl::finalizeFunction() {
4981 PendingPHIs.clear();
4983 FrameIndices.clear();
4984 MachinePreds.clear();
4988 EntryBuilder.reset();
4991 SPDescriptor.resetPerFunctionState();
5004 return CI && CI->isMustTailCall();
5016 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
5017 CLI = MF->getSubtarget().getCallLowering();
5018 SPInfo = StackProtectorInfo;
5020 if (CLI->fallBackToDAGISel(*MF)) {
5022 F.getSubprogram(), &
F.getEntryBlock());
5023 R <<
"unable to lower function: "
5024 <<
ore::NV(
"Prototype",
F.getFunctionType());
5041 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5042 CSEInfo = GetCSEInfo();
5043 EntryBuilder->setCSEInfo(CSEInfo);
5044 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5045 CurBuilder->setCSEInfo(CSEInfo);
5047 EntryBuilder = std::make_unique<MachineIRBuilder>();
5048 CurBuilder = std::make_unique<MachineIRBuilder>();
5051 CurBuilder->setMF(*MF);
5052 EntryBuilder->setMF(*MF);
5053 MRI = &MF->getRegInfo();
5054 DL = &
F.getDataLayout();
5059 FuncInfo.ExceptionModel =
F.getParent()->getExceptionModel();
5063 AA = GetAAResults();
5064 FuncInfo.BPI = GetBPI();
5068 FuncInfo.BPI =
nullptr;
5071 LibInfo = LibraryInfo;
5072 Libcalls = LibcallInfo;
5074 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5076 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5077 SL->init(*TLI, TM, *DL);
5079 assert(PendingPHIs.empty() &&
"stale PHIs");
5083 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5086 F.getSubprogram(), &
F.getEntryBlock());
5087 R <<
"unable to translate in big endian mode";
5098 EntryBuilder->setMBB(*EntryBB);
5100 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5101 SwiftError.setFunction(CurMF);
5102 SwiftError.createEntriesInEntryBlock(DbgLoc);
5104 bool IsVarArg =
F.isVarArg();
5105 bool HasMustTailInVarArgFn =
false;
5108 unsigned NumValues =
F.arg_size();
5111 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5113 NumValues += BB.
size();
5116 MBB = MF->CreateMachineBasicBlock(&BB);
5124 if (!BA->hasZeroLiveUses())
5128 if (!HasMustTailInVarArgFn)
5132 VMap.reserveVRegs(NumValues);
5133 MRI->reserveVirtRegs(NumValues);
5135 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5138 EntryBB->addSuccessor(&getMBB(
F.front()));
5143 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5148 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5149 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5150 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5154 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5156 F.getSubprogram(), &
F.getEntryBlock());
5157 R <<
"unable to lower arguments: "
5158 <<
ore::NV(
"Prototype",
F.getFunctionType());
5165 if (EnableCSE && CSEInfo)
5170 DILocationVerifier Verifier;
5178 CurBuilder->setMBB(
MBB);
5179 HasTailCall =
false;
5189 Verifier.setCurrentInst(&Inst);
5193 translateDbgInfo(Inst, *CurBuilder);
5195 if (translate(Inst))
5200 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5202 if (ORE->allowExtraAnalysis(
"gisel-irtranslator")) {
5203 std::string InstStrStorage;
5207 R <<
": '" << InstStrStorage <<
"'";
5214 if (!finalizeBasicBlock(*BB,
MBB)) {
5216 BB->getTerminator()->getDebugLoc(), BB);
5217 R <<
"unable to translate basic block";
5227 finishPendingPhis();
5229 SwiftError.propagateVRegs();
5234 assert(EntryBB->succ_size() == 1 &&
5235 "Custom BB used for lowering should have only one successor");
5239 "LLVM-IR entry block has a predecessor!?");
5242 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5251 EntryBB->removeSuccessor(&NewEntryBB);
5252 MF->remove(EntryBB);
5253 MF->deleteMachineBasicBlock(EntryBB);
5255 assert(&MF->front() == &NewEntryBB &&
5256 "New entry wasn't next in the list of basic block!");
5259 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5269 return Impl->runOnMachineFunction(
5288 *
F.getParent(), Subtarget),
5312 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5313 Impl->runOnMachineFunction(
5315 ShouldSkipOpts, [&]() {
return &
FAM.getResult<
AAManager>(
F); },
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
This file describes how to lower LLVM calls to machine code calls.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This contains common code to allow clients to notify changes to machine instr.
const HexagonInstrInfo * TII
static bool checkForMustTailInVarArgFn(bool IsVarArg, const BasicBlock &BB)
Returns true if a BasicBlock BB within a variadic function contains a variadic musttail call.
static unsigned getConvOpcode(Intrinsic::ID ID)
static uint64_t getOffsetFromIndices(const User &U, const DataLayout &DL)
static unsigned getConstrainedOpcode(Intrinsic::ID ID)
IRTranslator LLVM IR static false void reportTranslationError(MachineFunction &MF, OptimizationRemarkEmitter &ORE, OptimizationRemarkMissed &R)
static cl::opt< bool > EnableCSEInIRTranslator("enable-cse-in-irtranslator", cl::desc("Should enable CSE in irtranslator"), cl::Optional, cl::init(false))
static bool isValInBlock(const Value *V, const BasicBlock *BB)
static bool isSwiftError(const Value *V)
This file declares the IRTranslator pass.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This file describes how to lower LLVM inline asm to machine code INLINEASM.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Implement a low-level type suitable for MachineInstr level instruction selection.
Implement a low-level type suitable for MachineInstr level instruction selection.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
OptimizedStructLayoutField Field
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
std::pair< BasicBlock *, BasicBlock * > Edge
verify safepoint Safepoint IR Verifier
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
LLVM_ABI APInt zextOrTrunc(unsigned width) const
Zero extend or truncate to width.
an instruction to allocate memory on the stack
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
LLVM_ABI bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
LLVM_ABI TypeSize getAllocationBaseSize(const DataLayout &DL) const
Get the size of the allocated type.
PointerType * getType() const
Overload to return most specific pointer type.
LLVM_ABI std::optional< TypeSize > getAllocationSize(const DataLayout &DL) const
Get allocation size in bytes.
const Value * getArraySize() const
Get the number of elements allocated.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
This class represents an incoming formal argument to a Function.
LLVM_ABI bool hasSwiftErrorAttr() const
Return true if this argument has the swifterror attribute.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
@ USubCond
Subtract only if no unsigned overflow.
@ FMinimum
*p = minimum(old, v) minimum matches the behavior of llvm.minimum.
@ Min
*p = old <signed v ? old : v
@ USubSat
*p = usub.sat(old, v) usub.sat matches the behavior of llvm.usub.sat.
@ FMaximum
*p = maximum(old, v) maximum matches the behavior of llvm.maximum.
@ UIncWrap
Increment one up to a maximum value.
@ Max
*p = old >signed v ? old : v
@ UMin
*p = old <unsigned v ? old : v
@ FMin
*p = minnum(old, v) minnum matches the behavior of llvm.minnum.
@ UMax
*p = old >unsigned v ? old : v
@ FMaximumNum
*p = maximumnum(old, v) maximumnum matches the behavior of llvm.maximumnum.
@ FMax
*p = maxnum(old, v) maxnum matches the behavior of llvm.maxnum.
@ UDecWrap
Decrement one until a minimum value or zero.
@ FMinimumNum
*p = minimumnum(old, v) minimumnum matches the behavior of llvm.minimumnum.
LLVM Basic Block Representation.
unsigned getNumber() const
const Function * getParent() const
Return the enclosing method, or null if none.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches,...
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
InstListType::const_iterator const_iterator
LLVM_ABI InstListType::const_iterator getFirstNonPHIOrDbg(bool SkipPseudoOp=true) const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic,...
LLVM_ABI const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
The address of a basic block.
static LLVM_ABI BlockAddress * lookup(const BasicBlock *BB)
Lookup an existing BlockAddress constant for the given BasicBlock.
Legacy analysis pass which computes BlockFrequencyInfo.
Analysis pass which computes BranchProbabilityInfo.
Legacy analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
LLVM_ABI BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
static constexpr BranchProbability getOne()
static constexpr BranchProbability getUnknown()
static constexpr BranchProbability getZero()
static void normalizeProbabilities(ProbabilityIter Begin, ProbabilityIter End)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool isInlineAsm() const
Check if this call is an inline asm statement.
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
unsigned countOperandBundlesOfType(StringRef Name) const
Return the number of operand bundles with the tag Name attached to this instruction.
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Value * getCalledOperand() const
Value * getArgOperand(unsigned i) const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
bool isConvergent() const
Determine if the invoke is convergent.
LLVM_ABI Intrinsic::ID getIntrinsicID() const
Returns the intrinsic ID of the intrinsic called or Intrinsic::not_intrinsic if the called function i...
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_ULE
unsigned less or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
bool isFPPredicate() const
bool isIntPredicate() const
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This is the common base class for constrained floating point intrinsics.
LLVM_ABI std::optional< fp::ExceptionBehavior > getExceptionBehavior() const
LLVM_ABI unsigned getNonMetadataArgCount() const
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
LLVM_ABI bool startsWithDeref() const
Return whether the first element a DW_OP_deref.
ArrayRef< uint64_t > getElements() const
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this label.
A parsed version of the target data layout string in and methods for querying it.
Value * getAddress() const
DILabel * getLabel() const
DebugLoc getDebugLoc() const
Value * getValue(unsigned OpIdx=0) const
DILocalVariable * getVariable() const
DIExpression * getExpression() const
LLVM_ABI Value * getVariableLocationOp(unsigned OpIdx) const
DIExpression * getExpression() const
DILocalVariable * getVariable() const
bool isDbgDeclare() const
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Class representing an expression and its matching format.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Constant * getPersonalityFn() const
Get the personality function associated with this function.
const Function & getFunction() const
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
bool hasOptNone() const
Do not optimize this function (-O0).
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
The actual analysis pass wrapper.
Simple wrapper that does the following.
Abstract class that contains various methods for clients to notify about changes.
Simple wrapper observer that takes several observers, and calls each one for each event.
void removeObserver(GISelChangeObserver *O)
void addObserver(GISelChangeObserver *O)
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1',...
bool hasExternalWeakLinkage() const
bool hasDLLImportStorageClass() const
Module * getParent()
Get the module that this global value is contained inside of...
bool isTailCall(const MachineInstr &MI) const override
IRTranslatorImpl(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
bool runOnMachineFunction(MachineFunction &MF, function_ref< GISelCSEInfo *()> GetCSEInfo, bool ShouldSkipOpts, function_ref< AAResults *()> GetAAResults, function_ref< BranchProbabilityInfo *()> GetBPI, function_ref< AssumptionCache *()> GetAC, TargetLibraryInfo *LibraryInfo, const LibcallLoweringInfo *LibcallInfo, SSPLayoutInfo *StackProtectorInfo)
IRTranslatorLegacy(CodeGenOptLevel OptLevel=CodeGenOptLevel::None)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
~IRTranslatorLegacy() override
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LLVM_ABI ~IRTranslatorPass()
LLVM_ABI IRTranslatorPass(CodeGenOptLevel OptLevel)
bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB, std::function< ArrayRef< Register >(const Value &Val)> GetOrCreateVRegs) const
Lower the given inline asm call instruction GetOrCreateVRegs is a callback to materialize a register ...
This instruction inserts a struct field of array element value into an aggregate value.
iterator_range< simple_ilist< DbgRecord >::iterator > getDbgRecordRange() const
Return a range over the DbgRecords attached to this instruction.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool hasAllowReassoc() const LLVM_READONLY
Determine whether the allow-reassociation flag is set.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static bool getUseExtended()
constexpr bool isScalar() const
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isPointer() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
static constexpr LLT token()
Get a low-level token; just a scalar with zero bits (or no size).
static LLT integer(unsigned SizeInBits)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Tracks which library functions to use for a particular subtarget or function.
Value * getPointerOperand()
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this load instruction.
static LocationSize precise(uint64_t Value)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned pred_size() const
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void push_back(MachineInstr *MI)
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void setSuccProbability(succ_iterator I, BranchProbability Prob)
Set successor probability of a given iterator.
succ_iterator succ_begin()
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator
LLVM_ABI void sortUniqueLiveIns()
Sorts and uniques the LiveIns vector.
LLVM_ABI bool isPredecessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a predecessor of this block.
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
int getStackProtectorIndex() const
Return the index for the stack protector object.
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
Helper class to build MachineInstr.
MachineInstrBuilder buildFPTOUI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOUI_SAT Src0.
MachineInstrBuilder buildFMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildFreeze(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_FREEZE Src.
MachineInstrBuilder buildBr(MachineBasicBlock &Dest)
Build and insert G_BR Dest.
MachineInstrBuilder buildModf(const DstOp &Fract, const DstOp &Int, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Int = G_FMODF Src.
LLVMContext & getContext() const
MachineInstrBuilder buildAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_ADD Op0, Op1.
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
MachineInstrBuilder buildResetFPMode()
Build and insert G_RESET_FPMODE.
MachineInstrBuilder buildFPTOSI_SAT(const DstOp &Dst, const SrcOp &Src0)
Build and insert Res = G_FPTOSI_SAT Src0.
MachineInstrBuilder buildUCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_UCMP Op0, Op1.
MachineInstrBuilder buildJumpTable(const LLT PtrTy, unsigned JTI)
Build and insert Res = G_JUMP_TABLE JTI.
MachineInstrBuilder buildGetRounding(const DstOp &Dst)
Build and insert Dst = G_GET_ROUNDING.
MachineInstrBuilder buildSCmp(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_SCMP Op0, Op1.
MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope)
Build and insert G_FENCE Ordering, Scope.
MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
MachineInstrBuilder buildFMA(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, const SrcOp &Src2, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FMA Op0, Op1, Op2.
MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_MUL Op0, Op1.
MachineInstrBuilder buildInsertSubvector(const DstOp &Res, const SrcOp &Src0, const SrcOp &Src1, unsigned Index)
Build and insert Res = G_INSERT_SUBVECTOR Src0, Src1, Idx.
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
MachineInstrBuilder buildCast(const DstOp &Dst, const SrcOp &Src)
Build and insert an appropriate cast between two registers of equal size.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
MachineInstrBuilder buildSExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildAtomicRMW(unsigned Opcode, const DstOp &OldValRes, const SrcOp &Addr, const SrcOp &Val, MachineMemOperand &MMO)
Build and insert OldValRes<def> = G_ATOMICRMW_<Opcode> Addr, Val, MMO.
MachineInstrBuilder buildSub(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_SUB Op0, Op1.
MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, ArrayRef< Register > Res, bool HasSideEffects, bool isConvergent)
Build and insert a G_INTRINSIC instruction.
MachineInstrBuilder buildVScale(const DstOp &Res, unsigned MinElts)
Build and insert Res = G_VSCALE MinElts.
MachineInstrBuilder buildSplatBuildVector(const DstOp &Res, const SrcOp &Src)
Build and insert Res = G_BUILD_VECTOR with Src replicated to fill the number of elements.
MachineInstrBuilder buildSetFPMode(const SrcOp &Src)
Build and insert G_SET_FPMODE Src.
MachineInstrBuilder buildIndirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in me...
MachineInstrBuilder buildBuildVector(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_BUILD_VECTOR Op0, ...
MachineInstrBuilder buildConstDbgValue(const Constant &C, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instructions specifying that Variable is given by C (suitably modified b...
MachineInstrBuilder buildBrCond(const SrcOp &Tst, MachineBasicBlock &Dest)
Build and insert G_BRCOND Tst, Dest.
std::optional< MachineInstrBuilder > materializeObjectPtrOffset(Register &Res, Register Op0, const LLT ValueTy, uint64_t Value)
Materialize and insert an instruction with appropriate flags for addressing some offset of an object,...
MachineInstrBuilder buildSetRounding(const SrcOp &Src)
Build and insert G_SET_ROUNDING.
MachineInstrBuilder buildExtractVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_PTR_ADD Op0, Op1.
MachineInstrBuilder buildZExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MachineInstrBuilder buildExtractVectorElementConstant(const DstOp &Res, const SrcOp &Val, const int Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
MachineInstrBuilder buildShl(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildFrameIndex(const DstOp &Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
MachineInstrBuilder buildDirectDbgValue(Register Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in Re...
MachineInstrBuilder buildDbgLabel(const MDNode *Label)
Build and insert a DBG_LABEL instructions specifying that Label is given.
MachineInstrBuilder buildBrJT(Register TablePtr, unsigned JTI, Register IndexReg)
Build and insert G_BRJT TablePtr, JTI, IndexReg.
MachineInstrBuilder buildDynStackAlloc(const DstOp &Res, const SrcOp &Size, Align Alignment)
Build and insert Res = G_DYN_STACKALLOC Size, Align.
MachineInstrBuilder buildFIDbgValue(int FI, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in th...
MachineInstrBuilder buildResetFPEnv()
Build and insert G_RESET_FPENV.
void setDebugLoc(const DebugLoc &DL)
Set the debug location to DL for all the next build instructions.
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
MachineInstrBuilder buildInsertVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Elt, const SrcOp &Idx)
Build and insert Res = G_INSERT_VECTOR_ELT Val, Elt, Idx.
MachineInstrBuilder buildAtomicCmpXchgWithSuccess(const DstOp &OldValRes, const DstOp &SuccessRes, const SrcOp &Addr, const SrcOp &CmpVal, const SrcOp &NewVal, MachineMemOperand &MMO)
Build and insert OldValRes<def>, SuccessRes<def> = / G_ATOMIC_CMPXCHG_WITH_SUCCESS Addr,...
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
const DebugLoc & getDebugLoc()
Get the current instruction's debug location.
MachineInstrBuilder buildTrap(bool Debug=false)
Build and insert G_TRAP or G_DEBUGTRAP.
MachineInstrBuilder buildFFrexp(const DstOp &Fract, const DstOp &Exp, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Fract, Exp = G_FFREXP Src.
MachineInstrBuilder buildFSincos(const DstOp &Sin, const DstOp &Cos, const SrcOp &Src, std::optional< unsigned > Flags=std::nullopt)
Build and insert Sin, Cos = G_FSINCOS Src.
MachineInstrBuilder buildShuffleVector(const DstOp &Res, const SrcOp &Src1, const SrcOp &Src2, ArrayRef< int > Mask)
Build and insert Res = G_SHUFFLE_VECTOR Src1, Src2, Mask.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
MachineInstrBuilder buildPrefetch(const SrcOp &Addr, unsigned RW, unsigned Locality, unsigned CacheType, MachineMemOperand &MMO)
Build and insert G_PREFETCH Addr, RW, Locality, CacheType.
MachineInstrBuilder buildExtractSubvector(const DstOp &Res, const SrcOp &Src, unsigned Index)
Build and insert Res = G_EXTRACT_SUBVECTOR Src, Idx0.
const DataLayout & getDataLayout() const
MachineInstrBuilder buildBrIndirect(Register Tgt)
Build and insert G_BRINDIRECT Tgt.
MachineInstrBuilder buildSplatVector(const DstOp &Res, const SrcOp &Val)
Build and insert Res = G_SPLAT_VECTOR Val.
MachineInstrBuilder buildStepVector(const DstOp &Res, unsigned Step)
Build and insert Res = G_STEP_VECTOR Step.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_FCMP PredOp0, Op1.
MachineInstrBuilder buildFAdd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_FADD Op0, Op1.
MachineInstrBuilder buildSetFPEnv(const SrcOp &Src)
Build and insert G_SET_FPENV Src.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addFPImm(const ConstantFP *Val) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
LLVM_ABI void copyIRFlags(const Instruction &I)
Copy all flags to MachineInst MIFlags.
static LLVM_ABI uint32_t copyFlagsFromInstruction(const Instruction &I)
LLVM_ABI void setDeactivationSymbol(MachineFunction &MF, Value *DS)
void setDebugLoc(DebugLoc DL)
Replace current source information with new such.
Flags
Flags values. These may be or'd together.
@ MOVolatile
The memory access is volatile.
@ MODereferenceable
The memory access is dereferenceable (i.e., doesn't trap).
@ MOLoad
The memory access reads data.
@ MONonTemporal
The memory access is non-temporal.
@ MOInvariant
The memory access always returns the same value (or traps).
@ MOStore
The memory access writes data.
static MachineOperand CreateES(const char *SymName, unsigned TargetFlags=0)
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
A set of analyses that are preserved following a run of a transformation pass.
Class to install both of the above.
Wrapper class representing virtual and physical registers.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Encapsulates all of the information needed to generate a stack protector check, and signals to isel w...
MachineBasicBlock * getSuccessMBB()
MachineBasicBlock * getFailureMBB()
constexpr bool empty() const
Check if the string is empty.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
SwitchLowering(FunctionLoweringInfo &funcinfo)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
ExceptionHandling getExceptionModel() const
Return the ExceptionHandling to use.
const Triple & getTargetTriple() const
const Target & getTarget() const
unsigned NoTrapAfterNoreturn
Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
Target-Independent Code Generator Pass Configuration Options.
virtual std::unique_ptr< CSEConfigBase > getCSEConfig() const
Returns the CSEConfig object to use for the current optimization level.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const CallLowering * getCallLowering() const
virtual const TargetLowering * getTargetLowering() const
bool isSPIRV() const
Tests whether the target is SPIR-V (32/64-bit/Logical).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static constexpr TypeSize getZero()
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isEmptyTy() const
Return true if this type is empty, that is, it has no elements or all of its elements are empty.
bool isByteTy() const
True if this is an instance of ByteType.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
bool isSized() const
Return true if it makes sense to take the size of this type.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isAggregateType() const
Return true if the type is an aggregate type.
bool isTokenTy() const
Return true if this is 'token'.
bool isVoidTy() const
Return true if this is 'void'.
BasicBlock * getSuccessor(unsigned i=0) const
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
constexpr ScalarTy getFixedValue() const
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
constexpr bool isZero() const
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
A raw_ostream that writes to an std::string.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
TwoOps_match< Val_t, Idx_t, Instruction::ExtractElement > m_ExtractElt(const Val_t &Val, const Idx_t &Idx)
Matches ExtractElementInst.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
LLVM_ABI void sortAndRangeify(CaseClusterVector &Clusters)
Sort Clusters and merge adjacent cases.
std::vector< CaseCluster > CaseClusterVector
@ CC_Range
A cluster of adjacent case labels with the same destination, or just one case.
@ CC_JumpTable
A cluster of cases suitable for jump table lowering.
@ CC_BitTests
A cluster of cases suitable for bit test lowering.
SmallVector< SwitchWorkListItem, 4 > SwitchWorkList
CaseClusterVector::iterator CaseClusterIt
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
ExceptionBehavior
Exception behavior used for floating point operations.
@ ebIgnore
This corresponds to "fpexcept.ignore".
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< PhiNode * > Phi
NodeAddr< CodeNode * > Code
friend class Instruction
Iterator for Instructions in a `BasicBlock.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
LLVM_ABI void diagnoseDontCall(const CallInst &CI)
auto successors(const MachineBasicBlock *BB)
LLVM_ABI MVT getMVTForLLT(LLT Ty)
Get a rough equivalent of an MVT for a given LLT.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
gep_type_iterator gep_type_end(const User *GEP)
LLVM_ABI MachineBasicBlock::iterator findSplitPointForStackProtector(MachineBasicBlock *BB, const TargetInstrInfo &TII)
Find the split point at which to splice the end of BB into its success stack protector check machine ...
LLVM_ABI LLT getLLTForMVT(MVT Ty)
Get a rough equivalent of an LLT for a given MVT.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
Align getKnownAlignment(Value *V, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to infer an alignment for the specified pointer.
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI llvm::SmallVector< int, 16 > createStrideMask(unsigned Start, unsigned Stride, unsigned VF)
Create a stride shuffle mask.
auto reverse(ContainerTy &&C)
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
generic_gep_type_iterator<> gep_type_iterator
auto succ_size(const MachineBasicBlock *BB)
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Global
Append to llvm.global_dtors.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
LLVM_ABI llvm::SmallVector< int, 16 > createInterleaveMask(unsigned VF, unsigned NumVecs)
Create an interleave shuffle mask.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
@ Default
Not specified; resolve to the target's default model.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::optional< RoundingMode > convertStrToRoundingMode(StringRef)
Returns a valid RoundingMode enumerator when given a string that is valid as input in constrained int...
gep_type_iterator gep_type_begin(const User *GEP)
LLVM_ABI void computeValueLLTs(const DataLayout &DL, Type &Ty, SmallVectorImpl< LLT > &ValueLLTs, SmallVectorImpl< TypeSize > *Offsets=nullptr, TypeSize StartingOffset=TypeSize::getZero())
computeValueLLTs - Given an LLVM IR type, compute a sequence of LLTs that represent all the individua...
LLVM_ABI GlobalValue * ExtractTypeInfo(Value *V)
ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
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.
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.