70#include "llvm/IR/IntrinsicsAMDGPU.h"
99#define DEBUG_TYPE "irtranslator"
105 cl::desc(
"Should enable CSE in irtranslator"),
117 class ValueToVRegInfo {
119 ValueToVRegInfo() =
default;
124 using const_vreg_iterator =
126 using const_offset_iterator =
129 inline const_vreg_iterator vregs_end()
const {
return ValToVRegs.end(); }
131 VRegListT *getVRegs(
const Value &V) {
132 auto It = ValToVRegs.find(&V);
133 if (It != ValToVRegs.end())
136 return insertVRegs(V);
139 OffsetListT *getOffsets(
const Value &V) {
140 auto It = TypeToOffsets.find(V.getType());
141 if (It != TypeToOffsets.end())
144 return insertOffsets(V);
147 const_vreg_iterator findVRegs(
const Value &V)
const {
148 return ValToVRegs.find(&V);
151 bool contains(
const Value &V)
const {
return ValToVRegs.contains(&V); }
155 TypeToOffsets.clear();
156 VRegAlloc.DestroyAll();
157 OffsetAlloc.DestroyAll();
161 VRegListT *insertVRegs(
const Value &V) {
162 assert(!ValToVRegs.contains(&V) &&
"Value already exists");
166 auto *VRegList =
new (VRegAlloc.Allocate()) VRegListT();
167 ValToVRegs[&V] = VRegList;
171 OffsetListT *insertOffsets(
const Value &V) {
172 assert(!TypeToOffsets.contains(V.getType()) &&
"Type already exists");
174 auto *OffsetList =
new (OffsetAlloc.Allocate()) OffsetListT();
175 TypeToOffsets[V.getType()] = OffsetList;
189 ValueToVRegInfo VMap;
196 using CFGEdge = std::pair<const BasicBlock *, const BasicBlock *>;
251 void translateDbgValueRecord(
Value *V,
bool HasArgList,
260 void translateDbgDeclareRecord(
Value *
Address,
bool HasArgList,
267 bool translateCopy(
const User &U,
const Value &V,
292 bool translateVectorInterleave2Intrinsic(
const CallInst &CI,
294 bool translateVectorDeinterleave2Intrinsic(
const CallInst &CI,
299 bool translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
301 bool translateFixedPointIntrinsic(
unsigned Op,
const CallInst &CI,
323 std::optional<MCRegister> getArgPhysReg(
Argument &Arg);
329 bool translateIfEntryValueArgument(
bool isDeclare,
Value *Arg,
344 bool translateIntrinsic(
356 bool findUnwindDestinations(
369 bool translateCast(
unsigned Opcode,
const User &U,
380 return translateCompare(U, MIRBuilder);
385 return translateCompare(U, MIRBuilder);
390 void finishPendingPhis();
394 bool translateUnaryOp(
unsigned Opcode,
const User &U,
399 bool translateBinaryOp(
unsigned Opcode,
const User &U,
405 bool shouldEmitAsBranches(
const std::vector<SwitchCG::CaseBlock> &Cases);
450 bool lowerJumpTableWorkItem(
459 bool FallthroughUnreachable,
465 bool lowerBitTestWorkItem(
471 bool FallthroughUnreachable);
502 return translateBinaryOp(TargetOpcode::G_ADD, U, MIRBuilder);
505 return translateBinaryOp(TargetOpcode::G_SUB, U, MIRBuilder);
508 return translateBinaryOp(TargetOpcode::G_AND, U, MIRBuilder);
511 return translateBinaryOp(TargetOpcode::G_MUL, U, MIRBuilder);
514 return translateBinaryOp(TargetOpcode::G_OR, U, MIRBuilder);
517 return translateBinaryOp(TargetOpcode::G_XOR, U, MIRBuilder);
521 return translateBinaryOp(TargetOpcode::G_UDIV, U, MIRBuilder);
524 return translateBinaryOp(TargetOpcode::G_SDIV, U, MIRBuilder);
527 return translateBinaryOp(TargetOpcode::G_UREM, U, MIRBuilder);
530 return translateBinaryOp(TargetOpcode::G_SREM, U, MIRBuilder);
533 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
536 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
540 return translatePtrToInt(U, MIRBuilder);
543 return translateCast(TargetOpcode::G_TRUNC, U, MIRBuilder);
546 return translateCast(TargetOpcode::G_FPTRUNC, U, MIRBuilder);
549 return translateCast(TargetOpcode::G_FPEXT, U, MIRBuilder);
552 return translateCast(TargetOpcode::G_FPTOUI, U, MIRBuilder);
555 return translateCast(TargetOpcode::G_FPTOSI, U, MIRBuilder);
558 return translateCast(TargetOpcode::G_UITOFP, U, MIRBuilder);
561 return translateCast(TargetOpcode::G_SITOFP, U, MIRBuilder);
566 return translateCast(TargetOpcode::G_SEXT, U, MIRBuilder);
570 return translateCast(TargetOpcode::G_ZEXT, U, MIRBuilder);
574 return translateBinaryOp(TargetOpcode::G_SHL, U, MIRBuilder);
577 return translateBinaryOp(TargetOpcode::G_LSHR, U, MIRBuilder);
580 return translateBinaryOp(TargetOpcode::G_ASHR, U, MIRBuilder);
584 return translateBinaryOp(TargetOpcode::G_FADD, U, MIRBuilder);
587 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
590 return translateBinaryOp(TargetOpcode::G_FMUL, U, MIRBuilder);
593 return translateBinaryOp(TargetOpcode::G_FDIV, U, MIRBuilder);
596 return translateBinaryOp(TargetOpcode::G_FREM, U, MIRBuilder);
629 return translateCast(TargetOpcode::G_ADDRSPACE_CAST, U, MIRBuilder);
644 bool translateConvergenceControlIntrinsic(
const CallInst &CI,
655 std::unique_ptr<MachineIRBuilder> CurBuilder;
660 std::unique_ptr<MachineIRBuilder> EntryBuilder;
673 std::unique_ptr<OptimizationRemarkEmitter> ORE;
684 bool EnableOpts =
false;
688 bool HasTailCall =
false;
692 bool mayTranslateUserTypes(
const User &U)
const;
699 assert(irt &&
"irt is null!");
702 void addSuccessorWithProb(
705 IRT->addSuccessorWithProb(Src, Dst, Prob);
708 ~GISelSwitchLowering()
override =
default;
714 std::unique_ptr<GISelSwitchLowering> SL;
720 void finalizeFunction();
758 auto Regs = getOrCreateVRegs(Val);
761 assert(Regs.size() == 1 &&
762 "attempt to get single VReg for aggregate or void");
766 Register getOrCreateConvergenceTokenVReg(
const Value &Token) {
768 auto &Regs = *VMap.getVRegs(Token);
770 assert(Regs.size() == 1 &&
771 "Expected a single register for convergence tokens.");
775 auto Reg = MRI->createGenericVirtualRegister(
LLT::token());
777 auto &Offsets = *VMap.getOffsets(Token);
779 Offsets.push_back(0);
785 ValueToVRegInfo::VRegListT &allocateVRegs(
const Value &Val);
789 int getOrCreateFrameIndex(
const AllocaInst &AI);
812 auto RemappedEdge = MachinePreds.find(Edge);
813 if (RemappedEdge != MachinePreds.end())
814 return RemappedEdge->second;
823 void addSuccessorWithProb(
829 : OptLevel(OptLevel) {}
859 "IRTranslator LLVM IR -> MI",
false,
false)
871 MF.getProperties().setFailedISel();
872 bool IsGlobalISelAbortEnabled =
877 if (!R.getLocation().isValid() || IsGlobalISelAbortEnabled)
878 R << (
" (in function: " + MF.getName() +
")").str();
880 if (IsGlobalISelAbortEnabled)
900 DILocationVerifier() =
default;
901 ~DILocationVerifier()
override =
default;
903 const Instruction *getCurrentInst()
const {
return CurrInst; }
904 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
906 void erasingInstr(MachineInstr &
MI)
override {}
907 void changingInstr(MachineInstr &
MI)
override {}
908 void changedInstr(MachineInstr &
MI)
override {}
910 void createdInstr(MachineInstr &
MI)
override {
911 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
916 <<
" was copied to " <<
MI);
922 (
MI.getParent()->isEntryBlock() && !
MI.getDebugLoc()) ||
923 (
MI.isDebugInstr())) &&
924 "Line info was not transferred to all instructions");
947IRTranslatorImpl::ValueToVRegInfo::VRegListT &
948IRTranslatorImpl::allocateVRegs(
const Value &Val) {
949 auto VRegsIt = VMap.findVRegs(Val);
950 if (VRegsIt != VMap.vregs_end())
951 return *VRegsIt->second;
952 auto *Regs = VMap.getVRegs(Val);
953 auto *Offsets = VMap.getOffsets(Val);
956 Offsets->empty() ? Offsets :
nullptr);
957 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
963 auto VRegsIt = VMap.findVRegs(Val);
964 if (VRegsIt != VMap.vregs_end())
965 return *VRegsIt->second;
968 return *VMap.getVRegs(Val);
971 auto *VRegs = VMap.getVRegs(Val);
972 auto *Offsets = VMap.getOffsets(Val);
976 "Don't know how to create an empty vreg");
981 if (Offsets->empty())
982 Offsets->push_back(0);
990 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
999 Offsets->empty() ? Offsets :
nullptr);
1002 for (
auto Ty : SplitTys)
1003 VRegs->push_back(MRI->createGenericVirtualRegister(Ty));
1010 while (
auto Elt =
C.getAggregateElement(Idx++)) {
1011 auto EltRegs = getOrCreateVRegs(*Elt);
1018int IRTranslatorImpl::getOrCreateFrameIndex(
const AllocaInst &AI) {
1019 auto [MapEntry,
Inserted] = FrameIndices.try_emplace(&AI);
1021 return MapEntry->second;
1027 Size = std::max<uint64_t>(
Size, 1u);
1029 int &FI = MapEntry->second;
1030 FI = MF->getFrameInfo().CreateStackObject(
Size, AI.
getAlign(),
false, &AI);
1037 MF->getSubtarget().getFrameLowering()->getStackIDForScalableVectors();
1038 MF->getFrameInfo().setStackID(FI, StackID);
1046 return SI->getAlign();
1048 return LI->getAlign();
1054 OptimizationRemarkMissed
R(
"gisel-irtranslator",
"", &
I);
1055 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &
I);
1061 MachineBasicBlock *
MBB = FuncInfo.getMBB(&BB);
1062 assert(
MBB &&
"BasicBlock was not encountered before");
1066void IRTranslatorImpl::addMachineCFGPred(CFGEdge
Edge,
1068 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
1069 MachinePreds[
Edge].push_back(NewPred);
1072bool IRTranslatorImpl::translateBinaryOp(
unsigned Opcode,
const User &U,
1074 if (!mayTranslateUserTypes(U))
1081 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1082 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1094bool IRTranslatorImpl::translateUnaryOp(
unsigned Opcode,
const User &U,
1096 if (!mayTranslateUserTypes(U))
1099 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1110bool IRTranslatorImpl::translateFNeg(
const User &U,
1112 return translateUnaryOp(TargetOpcode::G_FNEG, U, MIRBuilder);
1115bool IRTranslatorImpl::translateCompare(
const User &U,
1117 if (!mayTranslateUserTypes(U))
1121 Register Op0 = getOrCreateVReg(*
U.getOperand(0));
1122 Register Op1 = getOrCreateVReg(*
U.getOperand(1));
1127 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1, Flags);
1135 MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1, Flags);
1140bool IRTranslatorImpl::translateRet(
const User &U,
1144 if (Ret && DL->getTypeStoreSize(Ret->
getType()).isZero())
1149 VRegs = getOrCreateVRegs(*Ret);
1152 if (CLI->supportSwiftError() && SwiftError.getFunctionArg()) {
1153 SwiftErrorVReg = SwiftError.getOrCreateVRegUseAt(
1154 &RI, &MIRBuilder.
getMBB(), SwiftError.getFunctionArg());
1160 return CLI->lowerReturn(MIRBuilder, Ret, VRegs, FuncInfo, SwiftErrorVReg);
1163void IRTranslatorImpl::emitBranchForMergedCondition(
1172 Condition = InvertCond ? IC->getInversePredicate() : IC->getPredicate();
1175 Condition = InvertCond ?
FC->getInversePredicate() :
FC->getPredicate();
1178 SwitchCG::CaseBlock CB(Condition,
false, BOp->getOperand(0),
1179 BOp->getOperand(1),
nullptr,
TBB, FBB, CurBB,
1180 CurBuilder->getDebugLoc(), TProb, FProb);
1181 SL->SwitchCases.push_back(CB);
1187 SwitchCG::CaseBlock CB(
1189 nullptr,
TBB, FBB, CurBB, CurBuilder->getDebugLoc(), TProb, FProb);
1190 SL->SwitchCases.push_back(CB);
1195 return I->getParent() == BB;
1199void IRTranslatorImpl::findMergedConditions(
1204 using namespace PatternMatch;
1205 assert((
Opc == Instruction::And ||
Opc == Instruction::Or) &&
1206 "Expected Opc to be AND/OR");
1212 findMergedConditions(NotCond,
TBB, FBB, CurBB, SwitchBB,
Opc, TProb, FProb,
1218 const Value *BOpOp0, *BOpOp1;
1232 if (BOpc == Instruction::And)
1233 BOpc = Instruction::Or;
1234 else if (BOpc == Instruction::Or)
1235 BOpc = Instruction::And;
1241 bool BOpIsInOrAndTree = BOpc && BOpc ==
Opc && BOp->
hasOneUse();
1245 emitBranchForMergedCondition(
Cond,
TBB, FBB, CurBB, SwitchBB, TProb, FProb,
1252 MachineBasicBlock *TmpBB =
1256 if (
Opc == Instruction::Or) {
1277 auto NewTrueProb = TProb / 2;
1278 auto NewFalseProb = TProb / 2 + FProb;
1280 findMergedConditions(BOpOp0,
TBB, TmpBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1281 NewFalseProb, InvertCond);
1287 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1288 Probs[1], InvertCond);
1290 assert(
Opc == Instruction::And &&
"Unknown merge op!");
1310 auto NewTrueProb = TProb + FProb / 2;
1311 auto NewFalseProb = FProb / 2;
1313 findMergedConditions(BOpOp0, TmpBB, FBB, CurBB, SwitchBB,
Opc, NewTrueProb,
1314 NewFalseProb, InvertCond);
1320 findMergedConditions(BOpOp1,
TBB, FBB, TmpBB, SwitchBB,
Opc, Probs[0],
1321 Probs[1], InvertCond);
1325bool IRTranslatorImpl::shouldEmitAsBranches(
1326 const std::vector<SwitchCG::CaseBlock> &Cases) {
1328 if (Cases.size() != 2)
1333 if ((Cases[0].CmpLHS == Cases[1].CmpLHS &&
1334 Cases[0].CmpRHS == Cases[1].CmpRHS) ||
1335 (Cases[0].CmpRHS == Cases[1].CmpLHS &&
1336 Cases[0].CmpLHS == Cases[1].CmpRHS)) {
1342 if (Cases[0].CmpRHS == Cases[1].CmpRHS &&
1343 Cases[0].PredInfo.Pred == Cases[1].PredInfo.Pred &&
1347 Cases[0].TrueBB == Cases[1].ThisBB)
1350 Cases[0].FalseBB == Cases[1].ThisBB)
1357bool IRTranslatorImpl::translateUncondBr(
const User &U,
1360 auto &CurMBB = MIRBuilder.
getMBB();
1365 MIRBuilder.
buildBr(*Succ0MBB);
1368 for (
const BasicBlock *Succ :
successors(&BrInst))
1373bool IRTranslatorImpl::translateCondBr(
const User &U,
1376 auto &CurMBB = MIRBuilder.
getMBB();
1382 MachineBasicBlock *Succ1MBB = &getMBB(*BrInst.
getSuccessor(1));
1401 using namespace PatternMatch;
1403 if (!TLI->isJumpExpensive() && CondI && CondI->
hasOneUse() &&
1404 !BrInst.
hasMetadata(LLVMContext::MD_unpredictable)) {
1407 const Value *BOp0, *BOp1;
1409 Opcode = Instruction::And;
1411 Opcode = Instruction::Or;
1415 findMergedConditions(CondI, Succ0MBB, Succ1MBB, &CurMBB, &CurMBB, Opcode,
1416 getEdgeProbability(&CurMBB, Succ0MBB),
1417 getEdgeProbability(&CurMBB, Succ1MBB),
1419 assert(SL->SwitchCases[0].ThisBB == &CurMBB &&
"Unexpected lowering!");
1422 if (shouldEmitAsBranches(SL->SwitchCases)) {
1424 emitSwitchCase(SL->SwitchCases[0], &CurMBB, *CurBuilder);
1425 SL->SwitchCases.erase(SL->SwitchCases.begin());
1431 for (
unsigned I = 1,
E = SL->SwitchCases.size();
I !=
E; ++
I)
1432 MF->erase(SL->SwitchCases[
I].ThisBB);
1434 SL->SwitchCases.clear();
1441 nullptr, Succ0MBB, Succ1MBB, &CurMBB,
1442 CurBuilder->getDebugLoc());
1446 emitSwitchCase(CB, &CurMBB, *CurBuilder);
1453 if (!FuncInfo.BPI) {
1454 Src->addSuccessorWithoutProb(Dst);
1458 Prob = getEdgeProbability(Src, Dst);
1459 Src->addSuccessor(Dst, Prob);
1465 const BasicBlock *SrcBB = Src->getBasicBlock();
1466 const BasicBlock *DstBB = Dst->getBasicBlock();
1467 if (!FuncInfo.BPI) {
1470 auto SuccSize = std::max<uint32_t>(
succ_size(SrcBB), 1);
1471 return BranchProbability(1, SuccSize);
1473 return FuncInfo.BPI->getEdgeProbability(SrcBB, DstBB);
1477 using namespace SwitchCG;
1480 BranchProbabilityInfo *BPI = FuncInfo.BPI;
1482 Clusters.reserve(
SI.getNumCases());
1483 for (
const auto &
I :
SI.cases()) {
1484 MachineBasicBlock *Succ = &getMBB(*
I.getCaseSuccessor());
1485 assert(Succ &&
"Could not find successor mbb in mapping");
1486 const ConstantInt *CaseVal =
I.getCaseValue();
1487 BranchProbability Prob =
1489 : BranchProbability(1,
SI.getNumCases() + 1);
1490 Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Prob));
1493 MachineBasicBlock *DefaultMBB = &getMBB(*
SI.getDefaultDest());
1500 MachineBasicBlock *SwitchMBB = &getMBB(*
SI.getParent());
1503 if (Clusters.empty()) {
1510 SL->findJumpTables(Clusters, &SI, std::nullopt, DefaultMBB,
nullptr,
nullptr);
1511 SL->findBitTestClusters(Clusters, &SI);
1514 dbgs() <<
"Case clusters: ";
1515 for (
const CaseCluster &
C : Clusters) {
1516 if (
C.Kind == CC_JumpTable)
1518 if (
C.Kind == CC_BitTests)
1521 C.Low->getValue().print(
dbgs(),
true);
1522 if (
C.Low !=
C.High) {
1524 C.High->getValue().print(
dbgs(),
true);
1531 assert(!Clusters.empty());
1535 auto DefaultProb = getEdgeProbability(SwitchMBB, DefaultMBB);
1536 WorkList.push_back({SwitchMBB,
First,
Last,
nullptr,
nullptr, DefaultProb});
1538 while (!WorkList.empty()) {
1539 SwitchWorkListItem
W = WorkList.pop_back_val();
1541 unsigned NumClusters =
W.LastCluster -
W.FirstCluster + 1;
1543 if (NumClusters > 3 &&
1546 splitWorkItem(WorkList, W,
SI.getCondition(), SwitchMBB, MIB);
1550 if (!lowerSwitchWorkItem(W,
SI.getCondition(), SwitchMBB, DefaultMBB, MIB))
1560 using namespace SwitchCG;
1561 assert(
W.FirstCluster->Low->getValue().slt(
W.LastCluster->Low->getValue()) &&
1562 "Clusters not sorted?");
1563 assert(
W.LastCluster -
W.FirstCluster + 1 >= 2 &&
"Too small to split!");
1565 auto [LastLeft, FirstRight, LeftProb, RightProb] =
1566 SL->computeSplitWorkItemInfo(W);
1571 assert(PivotCluster >
W.FirstCluster);
1572 assert(PivotCluster <=
W.LastCluster);
1577 const ConstantInt *Pivot = PivotCluster->Low;
1586 MachineBasicBlock *LeftMBB;
1587 if (FirstLeft == LastLeft && FirstLeft->Kind == CC_Range &&
1588 FirstLeft->Low ==
W.GE &&
1589 (FirstLeft->High->getValue() + 1LL) == Pivot->
getValue()) {
1590 LeftMBB = FirstLeft->MBB;
1592 LeftMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1593 FuncInfo.MF->
insert(BBI, LeftMBB);
1595 {LeftMBB, FirstLeft, LastLeft,
W.GE, Pivot,
W.DefaultProb / 2});
1601 MachineBasicBlock *RightMBB;
1602 if (FirstRight == LastRight && FirstRight->Kind == CC_Range &&
W.LT &&
1603 (FirstRight->High->getValue() + 1ULL) ==
W.LT->getValue()) {
1604 RightMBB = FirstRight->MBB;
1606 RightMBB = FuncInfo.MF->CreateMachineBasicBlock(
W.MBB->getBasicBlock());
1607 FuncInfo.MF->
insert(BBI, RightMBB);
1609 {RightMBB, FirstRight, LastRight, Pivot,
W.LT,
W.DefaultProb / 2});
1617 if (
W.MBB == SwitchMBB)
1618 emitSwitchCase(CB, SwitchMBB, MIB);
1620 SL->SwitchCases.push_back(CB);
1626 assert(JT.
Reg &&
"Should lower JT Header first!");
1641 MachineIRBuilder MIB(*HeaderBB->
getParent());
1648 Register SwitchOpReg = getOrCreateVReg(SValue);
1650 auto Sub = MIB.
buildSub({SwitchTy}, SwitchOpReg, FirstCst);
1655 const LLT PtrScalarTy =
LLT::integer(DL->getTypeSizeInBits(PtrIRTy));
1669 auto Cst = getOrCreateVReg(
1709 if (MRI->getType(CondLHS).getSizeInBits() == 1 && CI && CI->isOne() &&
1723 "Can only handle SLE ranges");
1734 const LLT CmpTy = MRI->getType(CmpOpReg);
1735 auto Sub = MIB.
buildSub({CmpTy}, CmpOpReg, CondLHS);
1761bool IRTranslatorImpl::lowerJumpTableWorkItem(
1767 using namespace SwitchCG;
1770 JumpTableHeader *JTH = &SL->JTCases[
I->JTCasesIndex].first;
1771 SwitchCG::JumpTable *JT = &SL->JTCases[
I->JTCasesIndex].second;
1772 BranchProbability DefaultProb =
W.DefaultProb;
1775 MachineBasicBlock *JumpMBB = JT->
MBB;
1776 CurMF->
insert(BBI, JumpMBB);
1786 auto JumpProb =
I->Prob;
1787 auto FallthroughProb = UnhandledProbs;
1795 if (*SI == DefaultMBB) {
1796 JumpProb += DefaultProb / 2;
1797 FallthroughProb -= DefaultProb / 2;
1802 addMachineCFGPred({SwitchMBB->
getBasicBlock(), (*SI)->getBasicBlock()},
1807 if (FallthroughUnreachable)
1808 JTH->FallthroughUnreachable =
true;
1810 if (!JTH->FallthroughUnreachable)
1811 addSuccessorWithProb(CurMBB, Fallthrough, FallthroughProb);
1812 addSuccessorWithProb(CurMBB, JumpMBB, JumpProb);
1817 JTH->HeaderBB = CurMBB;
1821 if (CurMBB == SwitchMBB) {
1822 if (!emitJumpTableHeader(*JT, *JTH, CurMBB))
1824 JTH->Emitted =
true;
1828bool IRTranslatorImpl::lowerSwitchRangeWorkItem(
1833 using namespace SwitchCG;
1836 if (
I->Low ==
I->High) {
1852 CaseBlock CB(Pred, FallthroughUnreachable,
LHS,
RHS, MHS,
I->MBB, Fallthrough,
1855 emitSwitchCase(CB, SwitchMBB, MIB);
1861 MachineIRBuilder &MIB = *CurBuilder;
1865 Register SwitchOpReg = getOrCreateVReg(*
B.SValue);
1867 LLT SwitchOpTy = MRI->getType(SwitchOpReg);
1869 auto RangeSub = MIB.
buildSub(SwitchOpTy, SwitchOpReg, MinValReg);
1874 LLT MaskTy = SwitchOpTy;
1880 for (
const SwitchCG::BitTestCase &Case :
B.Cases) {
1889 Register SubReg = RangeSub.getReg(0);
1890 if (SwitchOpTy != MaskTy)
1896 MachineBasicBlock *
MBB =
B.Cases[0].ThisBB;
1898 if (!
B.FallthroughUnreachable)
1899 addSuccessorWithProb(SwitchBB,
B.Default,
B.DefaultProb);
1900 addSuccessorWithProb(SwitchBB,
MBB,
B.Prob);
1904 if (!
B.FallthroughUnreachable) {
1908 RangeSub, RangeCst);
1922 MachineIRBuilder &MIB = *CurBuilder;
1928 if (PopCount == 1) {
1931 auto MaskTrailingZeros =
1936 }
else if (PopCount == BB.
Range) {
1938 auto MaskTrailingOnes =
1946 auto SwitchVal = MIB.
buildShl(SwitchTy, CstOne,
Reg);
1950 auto AndOp = MIB.
buildAnd(SwitchTy, SwitchVal, CstMask);
1957 addSuccessorWithProb(SwitchBB,
B.TargetBB,
B.ExtraProb);
1959 addSuccessorWithProb(SwitchBB, NextMBB, BranchProbToNext);
1977bool IRTranslatorImpl::lowerBitTestWorkItem(
1983 bool FallthroughUnreachable) {
1984 using namespace SwitchCG;
1987 BitTestBlock *BTB = &SL->BitTestCases[
I->BTCasesIndex];
1989 for (BitTestCase &BTC : BTB->Cases)
1990 CurMF->
insert(BBI, BTC.ThisBB);
1993 BTB->Parent = CurMBB;
1994 BTB->Default = Fallthrough;
1996 BTB->DefaultProb = UnhandledProbs;
2000 if (!BTB->ContiguousRange) {
2001 BTB->Prob += DefaultProb / 2;
2002 BTB->DefaultProb -= DefaultProb / 2;
2005 if (FallthroughUnreachable)
2006 BTB->FallthroughUnreachable =
true;
2009 if (CurMBB == SwitchMBB) {
2010 emitBitTestHeader(*BTB, SwitchMBB);
2011 BTB->Emitted =
true;
2021 using namespace SwitchCG;
2023 MachineBasicBlock *NextMBB =
nullptr;
2025 if (++BBI != FuncInfo.MF->end())
2034 [](
const CaseCluster &a,
const CaseCluster &b) {
2035 return a.Prob != b.Prob
2037 : a.Low->getValue().slt(b.Low->getValue());
2042 for (CaseClusterIt
I =
W.LastCluster;
I >
W.FirstCluster;) {
2044 if (
I->Prob >
W.LastCluster->Prob)
2046 if (
I->Kind == CC_Range &&
I->MBB == NextMBB) {
2054 BranchProbability DefaultProb =
W.DefaultProb;
2055 BranchProbability UnhandledProbs = DefaultProb;
2056 for (CaseClusterIt
I =
W.FirstCluster;
I <=
W.LastCluster; ++
I)
2057 UnhandledProbs +=
I->Prob;
2059 MachineBasicBlock *CurMBB =
W.MBB;
2060 for (CaseClusterIt
I =
W.FirstCluster,
E =
W.LastCluster;
I <=
E; ++
I) {
2061 bool FallthroughUnreachable =
false;
2062 MachineBasicBlock *Fallthrough;
2063 if (
I ==
W.LastCluster) {
2065 Fallthrough = DefaultMBB;
2070 CurMF->
insert(BBI, Fallthrough);
2072 UnhandledProbs -=
I->Prob;
2076 if (!lowerBitTestWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2077 DefaultProb, UnhandledProbs,
I, Fallthrough,
2078 FallthroughUnreachable)) {
2086 if (!lowerJumpTableWorkItem(W, SwitchMBB, CurMBB, DefaultMBB, MIB, BBI,
2087 UnhandledProbs,
I, Fallthrough,
2088 FallthroughUnreachable)) {
2095 if (!lowerSwitchRangeWorkItem(
I,
Cond, Fallthrough,
2096 FallthroughUnreachable, UnhandledProbs,
2097 CurMBB, MIB, SwitchMBB)) {
2104 CurMBB = Fallthrough;
2110bool IRTranslatorImpl::translateIndirectBr(
const User &U,
2118 SmallPtrSet<const BasicBlock *, 32> AddedSuccessors;
2119 MachineBasicBlock &CurBB = MIRBuilder.
getMBB();
2120 for (
const BasicBlock *Succ :
successors(&BrInst)) {
2124 if (!AddedSuccessors.
insert(Succ).second)
2140bool IRTranslatorImpl::translateLoad(
const User &U,
2143 TypeSize StoreSize = DL->getTypeStoreSize(LI.
getType());
2154 assert(Regs.
size() == 1 &&
"swifterror should be single pointer");
2156 SwiftError.getOrCreateVRegUseAt(&LI, &MIRBuilder.
getMBB(), Ptr);
2162 TLI->getLoadMemOperandFlags(LI, *DL, AC, LibInfo, OptLevel);
2164 if (AA->pointsToConstantMemory(
2171 if (Regs.
size() == 1) {
2172 auto *MMO = MF->getMachineMemOperand(
2174 MRI->getType(Regs[0]), getMemOpAlign(LI),
2175 MMOMetadata(AAInfo, LI.
getMetadata(LLVMContext::MD_range)),
2181 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(LI);
2182 Type *OffsetIRTy = DL->getIndexType(Ptr->
getType());
2184 for (
unsigned i = 0; i < Regs.
size(); ++i) {
2189 Align BaseAlign = getMemOpAlign(LI);
2191 MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Regs[i]),
2194 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
2200bool IRTranslatorImpl::translateStore(
const User &U,
2203 if (DL->getTypeStoreSize(
SI.getValueOperand()->getType()).isZero())
2209 if (CLI->supportSwiftError() &&
isSwiftError(
SI.getPointerOperand())) {
2210 assert(Vals.
size() == 1 &&
"swifterror should be single pointer");
2212 Register VReg = SwiftError.getOrCreateVRegDefAt(&SI, &MIRBuilder.
getMBB(),
2213 SI.getPointerOperand());
2220 if (Vals.
size() == 1) {
2221 auto *MMO = MF->getMachineMemOperand(
2222 MachinePointerInfo(
SI.getPointerOperand()), Flags,
2223 MRI->getType(Vals[0]), getMemOpAlign(SI),
SI.getAAMetadata(),
2224 SI.getSyncScopeID(),
SI.getOrdering());
2229 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*
SI.getValueOperand());
2230 Type *OffsetIRTy = DL->getIndexType(
SI.getPointerOperandType());
2232 for (
unsigned i = 0; i < Vals.
size(); ++i) {
2236 MachinePointerInfo Ptr(
SI.getPointerOperand(), Offsets[i]);
2237 Align BaseAlign = getMemOpAlign(SI);
2238 auto *MMO = MF->getMachineMemOperand(Ptr, Flags, MRI->getType(Vals[i]),
2241 SI.getSyncScopeID(),
SI.getOrdering());
2248 const Value *Src = U.getOperand(0);
2254 Indices.
push_back(ConstantInt::get(Int32Ty, 0));
2257 for (
auto Idx : EVI->indices())
2258 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2260 for (
auto Idx : IVI->indices())
2261 Indices.
push_back(ConstantInt::get(Int32Ty, Idx));
2267 DL.getIndexedOffsetInType(Src->getType(), Indices));
2270bool IRTranslatorImpl::translateExtractValue(
const User &U,
2272 const Value *Src =
U.getOperand(0);
2275 ArrayRef<uint64_t>
Offsets = *VMap.getOffsets(*Src);
2277 auto &DstRegs = allocateVRegs(U);
2279 for (
unsigned i = 0; i < DstRegs.size(); ++i)
2280 DstRegs[i] = SrcRegs[Idx++];
2285bool IRTranslatorImpl::translateInsertValue(
const User &U,
2287 const Value *Src =
U.getOperand(0);
2289 auto &DstRegs = allocateVRegs(U);
2290 ArrayRef<uint64_t> DstOffsets = *VMap.getOffsets(U);
2293 auto *InsertedIt = InsertedRegs.
begin();
2295 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
2296 if (DstOffsets[i] >=
Offset && InsertedIt != InsertedRegs.
end())
2297 DstRegs[i] = *InsertedIt++;
2299 DstRegs[i] = SrcRegs[i];
2305bool IRTranslatorImpl::translateSelect(
const User &U,
2307 Register Tst = getOrCreateVReg(*
U.getOperand(0));
2316 for (
unsigned i = 0; i < ResRegs.
size(); ++i) {
2317 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i], Flags);
2323bool IRTranslatorImpl::translateCopy(
const User &U,
const Value &V,
2325 return translateCopy(U, getOrCreateVReg(V), MIRBuilder);
2328bool IRTranslatorImpl::translateCopy(
const User &U,
Register Src,
2330 auto &Regs = *VMap.getVRegs(U);
2332 Regs.push_back(Src);
2333 VMap.getOffsets(U)->push_back(0);
2342bool IRTranslatorImpl::translateBitCast(
const User &U,
2344 Type *SrcTy =
U.getOperand(0)->getType();
2345 Type *DstTy =
U.getType();
2352 return translateCast(TargetOpcode::G_CONSTANT_FOLD_BARRIER, U,
2354 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
2364 return translateCast(TargetOpcode::G_INTTOPTR, U, MIRBuilder);
2366 return translateCast(TargetOpcode::G_PTRTOINT, U, MIRBuilder);
2368 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
2371bool IRTranslatorImpl::translateCast(
unsigned Opcode,
const User &U,
2373 if (!mayTranslateUserTypes(U))
2386bool IRTranslatorImpl::translateGetElementPtr(
const User &U,
2388 Value &Op0 = *
U.getOperand(0);
2392 Type *OffsetIRTy = DL->getIndexType(PtrIRTy);
2395 uint32_t PtrAddFlags = 0;
2401 auto PtrAddFlagsWithConst = [&](int64_t
Offset) {
2411 unsigned VectorWidth = 0;
2415 bool WantSplatVector =
false;
2419 WantSplatVector = VectorWidth > 1;
2423 return translateCopy(U, BaseReg, MIRBuilder);
2427 if (WantSplatVector && !PtrTy.
isVector()) {
2434 OffsetIRTy = DL->getIndexType(PtrIRTy);
2441 const Value *Idx = GTI.getOperand();
2442 if (StructType *StTy = GTI.getStructTypeOrNull()) {
2444 Offset += DL->getStructLayout(StTy)->getElementOffset(
Field);
2447 uint64_t ElementSize = GTI.getSequentialElementStride(*DL);
2452 if (std::optional<int64_t> Val = CI->getValue().trySExtValue()) {
2453 Offset += ElementSize * *Val;
2462 PtrAddFlagsWithConst(
Offset))
2467 Register IdxReg = getOrCreateVReg(*Idx);
2468 LLT IdxTy = MRI->getType(IdxReg);
2469 if (IdxTy != OffsetTy) {
2470 if (!IdxTy.
isVector() && WantSplatVector) {
2483 if (ElementSize != 1) {
2494 MIRBuilder.
buildMul(OffsetTy, IdxReg, ElementSizeMIB, ScaleFlags)
2497 GepOffsetReg = IdxReg;
2501 MIRBuilder.
buildPtrAdd(PtrTy, BaseReg, GepOffsetReg, PtrAddFlags)
2510 MIRBuilder.
buildPtrAdd(getOrCreateVReg(U), BaseReg, OffsetMIB.getReg(0),
2511 PtrAddFlagsWithConst(
Offset));
2515 return translateCopy(U, BaseReg, MIRBuilder);
2518bool IRTranslatorImpl::translateMemFunc(
const CallInst &CI,
2528 unsigned MinPtrSize = UINT_MAX;
2529 for (
auto AI = CI.
arg_begin(), AE = CI.
arg_end(); std::next(AI) != AE; ++AI) {
2530 Register SrcReg = getOrCreateVReg(**AI);
2531 LLT SrcTy = MRI->getType(SrcReg);
2533 MinPtrSize = std::min<unsigned>(SrcTy.
getSizeInBits(), MinPtrSize);
2541 if (MRI->getType(SizeOpReg) != SizeTy)
2553 ConstantInt *CopySize =
nullptr;
2556 DstAlign = MCI->getDestAlign().valueOrOne();
2557 SrcAlign = MCI->getSourceAlign().valueOrOne();
2560 DstAlign = MMI->getDestAlign().valueOrOne();
2561 SrcAlign = MMI->getSourceAlign().valueOrOne();
2565 DstAlign = MSI->getDestAlign().valueOrOne();
2568 if (Opcode != TargetOpcode::G_MEMCPY_INLINE &&
2569 Opcode != TargetOpcode::G_MEMSET_INLINE) {
2585 if (AA && CopySize &&
2586 AA->pointsToConstantMemory(MemoryLocation(
2596 ICall.addMemOperand(
2597 MF->getMachineMemOperand(MachinePointerInfo(CI.
getArgOperand(0)),
2598 StoreFlags, 1, DstAlign, AAInfo));
2599 if (Opcode != TargetOpcode::G_MEMSET &&
2600 Opcode != TargetOpcode::G_MEMSET_INLINE)
2601 ICall.addMemOperand(MF->getMachineMemOperand(
2602 MachinePointerInfo(SrcPtr), LoadFlags, 1, SrcAlign, AAInfo));
2607bool IRTranslatorImpl::translateTrap(
const CallInst &CI,
2610 StringRef TrapFuncName =
2611 CI.
getAttributes().getFnAttr(
"trap-func-name").getValueAsString();
2612 if (TrapFuncName.
empty()) {
2613 if (Opcode == TargetOpcode::G_UBSANTRAP) {
2622 CallLowering::CallLoweringInfo
Info;
2623 if (Opcode == TargetOpcode::G_UBSANTRAP)
2630 return CLI->lowerCall(MIRBuilder, Info);
2633bool IRTranslatorImpl::translateVectorInterleave2Intrinsic(
2636 "This function can only be called on the interleave2 intrinsic!");
2640 Register Res = getOrCreateVReg(CI);
2642 LLT OpTy = MRI->getType(Op0);
2649bool IRTranslatorImpl::translateVectorDeinterleave2Intrinsic(
2652 "This function can only be called on the deinterleave2 intrinsic!");
2659 LLT ResTy = MRI->getType(Res[0]);
2676void IRTranslatorImpl::getStackGuard(
Register DstReg,
2679 TLI->getSDagStackGuard(*MF->getFunction().getParent(), *Libcalls);
2682 Ctx.
diagnose(DiagnosticInfoGeneric(
"unable to lower stackguard"));
2687 const TargetRegisterInfo *
TRI = MF->getSubtarget().getRegisterInfo();
2688 MRI->setRegClass(DstReg,
TRI->getPointerRegClass());
2690 MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD, {DstReg}, {});
2692 unsigned AddrSpace =
Global->getType()->getPointerAddressSpace();
2693 LLT PtrTy =
LLT::pointer(AddrSpace, DL->getPointerSizeInBits(AddrSpace));
2695 MachinePointerInfo MPInfo(
Global);
2698 MachineMemOperand *MemRef = MF->getMachineMemOperand(
2699 MPInfo, Flags, PtrTy, DL->getPointerABIAlignment(AddrSpace));
2700 MIB.setMemRefs({MemRef});
2703bool IRTranslatorImpl::translateOverflowIntrinsic(
2707 Op, {ResRegs[0], ResRegs[1]},
2713bool IRTranslatorImpl::translateFixedPointIntrinsic(
2715 Register Dst = getOrCreateVReg(CI);
2719 MIRBuilder.
buildInstr(
Op, {Dst}, { Src0, Src1, Scale });
2723unsigned IRTranslatorImpl::getSimpleIntrinsicOpcode(
Intrinsic::ID ID) {
2727 case Intrinsic::acos:
2728 return TargetOpcode::G_FACOS;
2729 case Intrinsic::asin:
2730 return TargetOpcode::G_FASIN;
2731 case Intrinsic::atan:
2732 return TargetOpcode::G_FATAN;
2733 case Intrinsic::atan2:
2734 return TargetOpcode::G_FATAN2;
2735 case Intrinsic::bswap:
2736 return TargetOpcode::G_BSWAP;
2737 case Intrinsic::bitreverse:
2738 return TargetOpcode::G_BITREVERSE;
2739 case Intrinsic::fshl:
2740 return TargetOpcode::G_FSHL;
2741 case Intrinsic::fshr:
2742 return TargetOpcode::G_FSHR;
2743 case Intrinsic::ceil:
2744 return TargetOpcode::G_FCEIL;
2745 case Intrinsic::cos:
2746 return TargetOpcode::G_FCOS;
2747 case Intrinsic::cosh:
2748 return TargetOpcode::G_FCOSH;
2749 case Intrinsic::ctpop:
2750 return TargetOpcode::G_CTPOP;
2751 case Intrinsic::exp:
2752 return TargetOpcode::G_FEXP;
2753 case Intrinsic::exp2:
2754 return TargetOpcode::G_FEXP2;
2755 case Intrinsic::exp10:
2756 return TargetOpcode::G_FEXP10;
2757 case Intrinsic::fabs:
2758 return TargetOpcode::G_FABS;
2759 case Intrinsic::copysign:
2760 return TargetOpcode::G_FCOPYSIGN;
2761 case Intrinsic::minnum:
2762 return TargetOpcode::G_FMINNUM;
2763 case Intrinsic::maxnum:
2764 return TargetOpcode::G_FMAXNUM;
2765 case Intrinsic::minimum:
2766 return TargetOpcode::G_FMINIMUM;
2767 case Intrinsic::maximum:
2768 return TargetOpcode::G_FMAXIMUM;
2769 case Intrinsic::minimumnum:
2770 return TargetOpcode::G_FMINIMUMNUM;
2771 case Intrinsic::maximumnum:
2772 return TargetOpcode::G_FMAXIMUMNUM;
2773 case Intrinsic::canonicalize:
2774 return TargetOpcode::G_FCANONICALIZE;
2775 case Intrinsic::floor:
2776 return TargetOpcode::G_FFLOOR;
2777 case Intrinsic::fma:
2778 return TargetOpcode::G_FMA;
2779 case Intrinsic::log:
2780 return TargetOpcode::G_FLOG;
2781 case Intrinsic::log2:
2782 return TargetOpcode::G_FLOG2;
2783 case Intrinsic::log10:
2784 return TargetOpcode::G_FLOG10;
2785 case Intrinsic::ldexp:
2786 return TargetOpcode::G_FLDEXP;
2787 case Intrinsic::nearbyint:
2788 return TargetOpcode::G_FNEARBYINT;
2789 case Intrinsic::pow:
2790 return TargetOpcode::G_FPOW;
2791 case Intrinsic::powi:
2792 return TargetOpcode::G_FPOWI;
2793 case Intrinsic::rint:
2794 return TargetOpcode::G_FRINT;
2795 case Intrinsic::round:
2796 return TargetOpcode::G_INTRINSIC_ROUND;
2797 case Intrinsic::roundeven:
2798 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2799 case Intrinsic::sin:
2800 return TargetOpcode::G_FSIN;
2801 case Intrinsic::sinh:
2802 return TargetOpcode::G_FSINH;
2803 case Intrinsic::sqrt:
2804 return TargetOpcode::G_FSQRT;
2805 case Intrinsic::tan:
2806 return TargetOpcode::G_FTAN;
2807 case Intrinsic::tanh:
2808 return TargetOpcode::G_FTANH;
2809 case Intrinsic::trunc:
2810 return TargetOpcode::G_INTRINSIC_TRUNC;
2811 case Intrinsic::readcyclecounter:
2812 return TargetOpcode::G_READCYCLECOUNTER;
2813 case Intrinsic::readsteadycounter:
2814 return TargetOpcode::G_READSTEADYCOUNTER;
2815 case Intrinsic::ptrmask:
2816 return TargetOpcode::G_PTRMASK;
2817 case Intrinsic::lrint:
2818 return TargetOpcode::G_INTRINSIC_LRINT;
2819 case Intrinsic::llrint:
2820 return TargetOpcode::G_INTRINSIC_LLRINT;
2822 case Intrinsic::vector_reduce_fmin:
2823 return TargetOpcode::G_VECREDUCE_FMIN;
2824 case Intrinsic::vector_reduce_fmax:
2825 return TargetOpcode::G_VECREDUCE_FMAX;
2826 case Intrinsic::vector_reduce_fminimum:
2827 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2828 case Intrinsic::vector_reduce_fmaximum:
2829 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2830 case Intrinsic::vector_reduce_fminimumnum:
2831 return TargetOpcode::G_VECREDUCE_FMINIMUMNUM;
2832 case Intrinsic::vector_reduce_fmaximumnum:
2833 return TargetOpcode::G_VECREDUCE_FMAXIMUMNUM;
2834 case Intrinsic::vector_reduce_add:
2835 return TargetOpcode::G_VECREDUCE_ADD;
2836 case Intrinsic::vector_reduce_mul:
2837 return TargetOpcode::G_VECREDUCE_MUL;
2838 case Intrinsic::vector_reduce_and:
2839 return TargetOpcode::G_VECREDUCE_AND;
2840 case Intrinsic::vector_reduce_or:
2841 return TargetOpcode::G_VECREDUCE_OR;
2842 case Intrinsic::vector_reduce_xor:
2843 return TargetOpcode::G_VECREDUCE_XOR;
2844 case Intrinsic::vector_reduce_smax:
2845 return TargetOpcode::G_VECREDUCE_SMAX;
2846 case Intrinsic::vector_reduce_smin:
2847 return TargetOpcode::G_VECREDUCE_SMIN;
2848 case Intrinsic::vector_reduce_umax:
2849 return TargetOpcode::G_VECREDUCE_UMAX;
2850 case Intrinsic::vector_reduce_umin:
2851 return TargetOpcode::G_VECREDUCE_UMIN;
2852 case Intrinsic::experimental_vector_compress:
2853 return TargetOpcode::G_VECTOR_COMPRESS;
2854 case Intrinsic::lround:
2855 return TargetOpcode::G_LROUND;
2856 case Intrinsic::llround:
2857 return TargetOpcode::G_LLROUND;
2858 case Intrinsic::get_fpenv:
2859 return TargetOpcode::G_GET_FPENV;
2860 case Intrinsic::get_fpmode:
2861 return TargetOpcode::G_GET_FPMODE;
2866bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2870 unsigned Op = getSimpleIntrinsicOpcode(ID);
2878 for (
const auto &Arg : CI.
args())
2881 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2889 case Intrinsic::experimental_constrained_fadd:
2890 return TargetOpcode::G_STRICT_FADD;
2891 case Intrinsic::experimental_constrained_fsub:
2892 return TargetOpcode::G_STRICT_FSUB;
2893 case Intrinsic::experimental_constrained_fmul:
2894 return TargetOpcode::G_STRICT_FMUL;
2895 case Intrinsic::experimental_constrained_fdiv:
2896 return TargetOpcode::G_STRICT_FDIV;
2897 case Intrinsic::experimental_constrained_frem:
2898 return TargetOpcode::G_STRICT_FREM;
2899 case Intrinsic::experimental_constrained_fma:
2900 return TargetOpcode::G_STRICT_FMA;
2901 case Intrinsic::experimental_constrained_sqrt:
2902 return TargetOpcode::G_STRICT_FSQRT;
2903 case Intrinsic::experimental_constrained_ldexp:
2904 return TargetOpcode::G_STRICT_FLDEXP;
2905 case Intrinsic::experimental_constrained_fcmp:
2906 return TargetOpcode::G_STRICT_FCMP;
2907 case Intrinsic::experimental_constrained_fcmps:
2908 return TargetOpcode::G_STRICT_FCMPS;
2914bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2926 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2927 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2929 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2930 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2933 .addPredicate(FPCmp->getPredicate())
2947std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2948 auto VRegs = getOrCreateVRegs(Arg);
2949 if (VRegs.
size() != 1)
2950 return std::nullopt;
2953 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2954 if (!VRegDef || !VRegDef->isCopy())
2955 return std::nullopt;
2956 return VRegDef->getOperand(1).getReg().asMCReg();
2959bool IRTranslatorImpl::translateIfEntryValueArgument(
2970 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2972 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2973 <<
": expression is entry_value but "
2974 <<
"couldn't find a physical register\n");
2982 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
2994 case Intrinsic::experimental_convergence_anchor:
2995 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
2996 case Intrinsic::experimental_convergence_entry:
2997 return TargetOpcode::CONVERGENCECTRL_ENTRY;
2998 case Intrinsic::experimental_convergence_loop:
2999 return TargetOpcode::CONVERGENCECTRL_LOOP;
3003bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
3006 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3009 if (ID == Intrinsic::experimental_convergence_loop) {
3011 assert(Bundle &&
"Expected a convergence control token.");
3013 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3020bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3024 if (ORE->enabled()) {
3026 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3034 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3040 case Intrinsic::lifetime_start:
3041 case Intrinsic::lifetime_end: {
3044 MF->getFunction().hasOptNone())
3047 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3048 : TargetOpcode::LIFETIME_END;
3057 case Intrinsic::fake_use: {
3059 for (
const auto &Arg : CI.
args())
3061 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3062 MF->setHasFakeUses(
true);
3065 case Intrinsic::dbg_declare: {
3072 case Intrinsic::dbg_label: {
3078 "Expected inlined-at fields to agree");
3083 case Intrinsic::vaend:
3087 case Intrinsic::vastart: {
3089 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3092 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3093 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3095 ListSize, Alignment));
3098 case Intrinsic::dbg_assign:
3105 case Intrinsic::dbg_value: {
3112 case Intrinsic::uadd_with_overflow:
3113 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3114 case Intrinsic::sadd_with_overflow:
3115 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3116 case Intrinsic::usub_with_overflow:
3117 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3118 case Intrinsic::ssub_with_overflow:
3119 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3120 case Intrinsic::umul_with_overflow:
3121 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3122 case Intrinsic::smul_with_overflow:
3123 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3124 case Intrinsic::uadd_sat:
3125 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3126 case Intrinsic::sadd_sat:
3127 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3128 case Intrinsic::usub_sat:
3129 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3130 case Intrinsic::ssub_sat:
3131 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3132 case Intrinsic::ushl_sat:
3133 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3134 case Intrinsic::sshl_sat:
3135 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3136 case Intrinsic::umin:
3137 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3138 case Intrinsic::umax:
3139 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3140 case Intrinsic::smin:
3141 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3142 case Intrinsic::smax:
3143 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3144 case Intrinsic::abs:
3146 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3147 case Intrinsic::smul_fix:
3148 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3149 case Intrinsic::umul_fix:
3150 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3151 case Intrinsic::smul_fix_sat:
3152 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3153 case Intrinsic::umul_fix_sat:
3154 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3155 case Intrinsic::sdiv_fix:
3156 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3157 case Intrinsic::udiv_fix:
3158 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3159 case Intrinsic::sdiv_fix_sat:
3160 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3161 case Intrinsic::udiv_fix_sat:
3162 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3163 case Intrinsic::fmuladd: {
3164 const TargetMachine &TM = MF->getTarget();
3165 Register Dst = getOrCreateVReg(CI);
3170 TLI->isFMAFasterThanFMulAndFAdd(*MF,
3171 TLI->getValueType(*DL, CI.
getType()))) {
3174 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3185 case Intrinsic::frexp: {
3192 case Intrinsic::modf: {
3194 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3199 case Intrinsic::sincos: {
3206 case Intrinsic::fptosi_sat:
3210 case Intrinsic::fptoui_sat:
3214 case Intrinsic::memcpy_inline:
3215 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3216 case Intrinsic::memcpy:
3217 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3218 case Intrinsic::memmove:
3219 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3220 case Intrinsic::memset:
3221 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3222 case Intrinsic::memset_inline:
3223 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3224 case Intrinsic::eh_typeid_for: {
3227 unsigned TypeID = MF->getTypeIDFor(GV);
3231 case Intrinsic::objectsize:
3234 case Intrinsic::is_constant:
3237 case Intrinsic::stackguard:
3238 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3240 case Intrinsic::stackprotector: {
3243 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3244 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3245 getStackGuard(GuardVal, MIRBuilder);
3250 int FI = getOrCreateFrameIndex(*Slot);
3251 MF->getFrameInfo().setStackProtectorIndex(FI);
3254 GuardVal, getOrCreateVReg(*Slot),
3261 case Intrinsic::stacksave: {
3262 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3265 case Intrinsic::stackrestore: {
3266 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3270 case Intrinsic::cttz:
3271 case Intrinsic::ctlz: {
3273 bool isTrailing =
ID == Intrinsic::cttz;
3274 unsigned Opcode = isTrailing ? Cst->
isZero()
3275 ? TargetOpcode::G_CTTZ
3276 : TargetOpcode::G_CTTZ_ZERO_POISON
3277 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3278 : TargetOpcode::G_CTLZ_ZERO_POISON;
3279 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3283 case Intrinsic::invariant_start: {
3287 case Intrinsic::invariant_end:
3289 case Intrinsic::expect:
3290 case Intrinsic::expect_with_probability:
3291 case Intrinsic::annotation:
3292 case Intrinsic::ptr_annotation:
3293 case Intrinsic::launder_invariant_group:
3294 case Intrinsic::strip_invariant_group:
3295 case Intrinsic::threadlocal_address: {
3297 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3301 case Intrinsic::assume:
3302 case Intrinsic::experimental_noalias_scope_decl:
3303 case Intrinsic::var_annotation:
3304 case Intrinsic::sideeffect:
3307 case Intrinsic::read_volatile_register:
3308 case Intrinsic::read_register: {
3311 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3315 case Intrinsic::write_register: {
3317 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3322 case Intrinsic::localescape: {
3323 MachineBasicBlock &EntryMBB = MF->front();
3328 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3335 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3348 case Intrinsic::vector_reduce_fadd:
3349 case Intrinsic::vector_reduce_fmul: {
3352 Register Dst = getOrCreateVReg(CI);
3358 Opc =
ID == Intrinsic::vector_reduce_fadd
3359 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3360 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3361 if (!MRI->getType(VecSrc).isVector())
3362 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3363 : TargetOpcode::G_FMUL;
3371 if (ID == Intrinsic::vector_reduce_fadd) {
3372 Opc = TargetOpcode::G_VECREDUCE_FADD;
3373 ScalarOpc = TargetOpcode::G_FADD;
3375 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3376 ScalarOpc = TargetOpcode::G_FMUL;
3378 LLT DstTy = MRI->getType(Dst);
3381 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3386 case Intrinsic::trap:
3387 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3388 case Intrinsic::debugtrap:
3389 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3390 case Intrinsic::ubsantrap:
3391 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3392 case Intrinsic::allow_runtime_check:
3393 case Intrinsic::allow_ubsan_check:
3394 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3397 case Intrinsic::amdgcn_cs_chain:
3398 case Intrinsic::amdgcn_call_whole_wave:
3399 return translateCallBase(CI, MIRBuilder);
3400 case Intrinsic::fptrunc_round: {
3405 std::optional<RoundingMode> RoundMode =
3410 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3411 {getOrCreateVReg(CI)},
3413 .addImm((
int)*RoundMode);
3417 case Intrinsic::is_fpclass: {
3422 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3423 {getOrCreateVReg(*FpValue)})
3428 case Intrinsic::set_fpenv: {
3433 case Intrinsic::reset_fpenv:
3436 case Intrinsic::set_fpmode: {
3441 case Intrinsic::reset_fpmode:
3444 case Intrinsic::get_rounding:
3447 case Intrinsic::set_rounding:
3450 case Intrinsic::vscale: {
3454 case Intrinsic::scmp:
3455 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3459 case Intrinsic::ucmp:
3460 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3464 case Intrinsic::vector_extract:
3465 return translateExtractVector(CI, MIRBuilder);
3466 case Intrinsic::vector_insert:
3467 return translateInsertVector(CI, MIRBuilder);
3468 case Intrinsic::stepvector: {
3472 case Intrinsic::prefetch: {
3479 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3482 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3488 case Intrinsic::vector_interleave2:
3489 case Intrinsic::vector_deinterleave2: {
3497 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3499 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3502#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3503 case Intrinsic::INTRINSIC:
3504#include "llvm/IR/ConstrainedOps.def"
3507 case Intrinsic::experimental_convergence_anchor:
3508 case Intrinsic::experimental_convergence_entry:
3509 case Intrinsic::experimental_convergence_loop:
3510 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3511 case Intrinsic::reloc_none: {
3514 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3522bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3524 if (!mayTranslateUserTypes(CB))
3527 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3531 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3536 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3539bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3546 for (
const auto &Arg : CB.
args()) {
3548 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3550 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3551 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3552 &CB, &MIRBuilder.
getMBB(), Arg));
3555 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3558 Args.push_back(getOrCreateVRegs(*Arg));
3562 if (ORE->enabled()) {
3564 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3570 std::optional<CallLowering::PtrAuthInfo> PAI;
3575 const Value *
Key = Bundle->Inputs[0];
3582 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3583 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3585 Register DiscReg = getOrCreateVReg(*Discriminator);
3593 const auto &Token = *Bundle->Inputs[0].get();
3594 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3600 bool Success = CLI->lowerCall(
3601 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3606 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3607 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3614bool IRTranslatorImpl::translateCall(
const User &U,
3616 if (!mayTranslateUserTypes(U))
3624 if (
F && (
F->hasDLLImportStorageClass() ||
3625 (MF->getTarget().getTargetTriple().isOSWindows() &&
3626 F->hasExternalWeakLinkage())))
3638 return translateInlineAsm(CI, MIRBuilder);
3642 if (translateCallBase(CI, MIRBuilder)) {
3651 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3652 const Function &Fn = MF->getFunction();
3654 DiagnosticInfoUnsupportedTargetIntrinsic(Fn, ID, CI.
getDebugLoc()));
3657 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3661 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3663 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3667bool IRTranslatorImpl::translateIntrinsic(
3670 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3672 F.getContext().diagnose(
3673 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3678 ResultRegs = getOrCreateVRegs(CB);
3682 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3693 assert(CI->getBitWidth() <= 64 &&
3694 "large intrinsic immediates not handled");
3695 MIB.
addImm(CI->getSExtValue());
3700 auto *MD = MDVal->getMetadata();
3704 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3711 if (VRegs.
size() > 1)
3718 for (
const auto &Info : TgtMemIntrinsicInfos) {
3721 LLT MemTy =
Info.memVT.isSimple()
3723 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3727 MachinePointerInfo MPI;
3729 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3730 }
else if (
Info.fallbackAddressSpace) {
3731 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3740 auto *Token = Bundle->Inputs[0].get();
3741 Register TokenReg = getOrCreateVReg(*Token);
3752bool IRTranslatorImpl::findUnwindDestinations(
3773 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3779 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3780 UnwindDests.back().first->setIsEHScopeEntry();
3781 UnwindDests.back().first->setIsEHFuncletEntry();
3786 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3787 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3789 if (IsMSVCCXX || IsCoreCLR)
3790 UnwindDests.back().first->setIsEHFuncletEntry();
3792 UnwindDests.back().first->setIsEHScopeEntry();
3794 NewEHPadBB = CatchSwitch->getUnwindDest();
3799 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3800 if (BPI && NewEHPadBB)
3802 EHPadBB = NewEHPadBB;
3807bool IRTranslatorImpl::translateInvoke(
const User &U,
3810 MCContext &
Context = MF->getContext();
3815 const Function *Fn =
I.getCalledFunction();
3822 if (
I.hasDeoptState())
3836 (MF->getTarget().getTargetTriple().isOSWindows() &&
3840 bool LowerInlineAsm =
I.isInlineAsm();
3841 bool NeedEHLabel =
true;
3847 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3848 BeginSymbol =
Context.createTempSymbol();
3852 if (LowerInlineAsm) {
3853 if (!translateInlineAsm(
I, MIRBuilder))
3855 }
else if (!translateCallBase(
I, MIRBuilder))
3860 EndSymbol =
Context.createTempSymbol();
3865 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3866 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3867 BranchProbability EHPadBBProb =
3871 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3874 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3875 &ReturnMBB = getMBB(*ReturnBB);
3877 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3878 for (
auto &UnwindDest : UnwindDests) {
3879 UnwindDest.first->setIsEHPad();
3880 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3885 assert(BeginSymbol &&
"Expected a begin symbol!");
3886 assert(EndSymbol &&
"Expected an end symbol!");
3887 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3890 MIRBuilder.
buildBr(ReturnMBB);
3896bool IRTranslatorImpl::translateCallBr(
const User &U,
3898 if (!mayTranslateUserTypes(U))
3902 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3905 if (
I.isInlineAsm()) {
3911 if (!translateIntrinsic(
I, IID, MIRBuilder))
3915 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3916 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3925 for (BasicBlock *Dest :
I.getIndirectDests()) {
3926 MachineBasicBlock &
Target = getMBB(*Dest);
3927 Target.setIsInlineAsmBrIndirectTarget();
3928 Target.setLabelMustBeEmitted();
3930 if (Dests.
insert(Dest).second)
3942bool IRTranslatorImpl::translateLandingPad(
const User &U,
3946 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3952 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3953 if (TLI->getExceptionPointerRegister(
3954 TLI->getTargetMachine().getExceptionModel(), PersonalityFn) == 0 &&
3955 TLI->getExceptionSelectorRegister(
3956 TLI->getTargetMachine().getExceptionModel(), PersonalityFn) == 0)
3968 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3973 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3974 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3975 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
3984 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
3987 Register ExceptionReg = TLI->getExceptionPointerRegister(
3988 TLI->getTargetMachine().getExceptionModel(), PersonalityFn);
3994 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
3996 Register SelectorReg = TLI->getExceptionSelectorRegister(
3997 TLI->getTargetMachine().getExceptionModel(), PersonalityFn);
4002 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
4003 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
4004 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
4009bool IRTranslatorImpl::translateAlloca(
const User &U,
4017 Register Res = getOrCreateVReg(AI);
4018 int FI = getOrCreateFrameIndex(AI);
4024 if (MF->getTarget().getTargetTriple().isOSWindows())
4029 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4031 if (MRI->getType(NumElts) !=
IntPtrTy) {
4043 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4048 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4050 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4055 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4064 if (Alignment <= StackAlign)
4068 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4069 assert(MF->getFrameInfo().hasVarSizedObjects());
4073bool IRTranslatorImpl::translateVAArg(
const User &U,
4079 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4080 {getOrCreateVReg(*
U.getOperand(0)),
4081 DL->getABITypeAlign(
U.getType()).value()});
4085bool IRTranslatorImpl::translateUnreachable(
const User &U,
4088 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4089 MF->getTarget().Options.NoTrapAfterNoreturn))
4096bool IRTranslatorImpl::translateInsertElement(
const User &U,
4101 FVT && FVT->getNumElements() == 1)
4102 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4105 Register Val = getOrCreateVReg(*
U.getOperand(0));
4106 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4107 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4110 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4111 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4112 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4113 Idx = getOrCreateVReg(*NewIdxCI);
4117 Idx = getOrCreateVReg(*
U.getOperand(2));
4118 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4119 const LLT VecIdxTy =
4120 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4127bool IRTranslatorImpl::translateInsertVector(
const User &U,
4130 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4131 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4134 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4139 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4144 ResultType && ResultType->getNumElements() == 1) {
4146 InputType && InputType->getNumElements() == 1) {
4150 return translateCopy(U, Vec, MIRBuilder);
4156 Register Idx = getOrCreateVReg(*CI);
4164 Register Idx = getOrCreateVReg(*CI);
4165 auto ScaledIndex = MIRBuilder.
buildMul(
4166 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4176bool IRTranslatorImpl::translateExtractElement(
const User &U,
4180 if (
const FixedVectorType *FVT =
4182 if (FVT->getNumElements() == 1)
4183 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4186 Register Val = getOrCreateVReg(*
U.getOperand(0));
4187 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4192 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4193 Idx = getOrCreateVReg(*NewIdxCI);
4197 Idx = getOrCreateVReg(*
U.getOperand(1));
4198 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4199 const LLT VecIdxTy =
4207bool IRTranslatorImpl::translateExtractVector(
const User &U,
4210 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4212 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4217 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4222 ResultType && ResultType->getNumElements() == 1) {
4224 InputType && InputType->getNumElements() == 1) {
4227 return translateCopy(U, Vec, MIRBuilder);
4233 Register Idx = getOrCreateVReg(*CI);
4241 Register Idx = getOrCreateVReg(*CI);
4242 auto ScaledIndex = MIRBuilder.
buildMul(
4243 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4253bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4259 if (
U.getOperand(0)->getType()->isScalableTy()) {
4260 Register Val = getOrCreateVReg(*
U.getOperand(0));
4262 MRI->getType(Val).getElementType(), Val, 0);
4269 Mask = SVI->getShuffleMask();
4280 unsigned M =
Mask[0];
4282 if (M == 0 || M == 1)
4283 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4289 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4290 }
else if (M < SrcElts * 2) {
4292 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4304 for (
int M : Mask) {
4306 if (M == 0 || M == 1) {
4307 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4309 if (!
Undef.isValid()) {
4310 Undef = MRI->createGenericVirtualRegister(SrcTy);
4320 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4322 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4323 {getOrCreateVReg(*
U.getOperand(0)),
4324 getOrCreateVReg(*
U.getOperand(1))})
4325 .addShuffleMask(MaskAlloc);
4329bool IRTranslatorImpl::translatePHI(
const User &U,
4333 SmallVector<MachineInstr *, 4> Insts;
4334 for (
auto Reg : getOrCreateVRegs(PI)) {
4335 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4339 PendingPHIs.emplace_back(&PI, std::move(Insts));
4343bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4347 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4349 auto Res = getOrCreateVRegs(
I);
4352 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4353 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4354 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4357 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4358 *MF->getMachineMemOperand(
4359 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4360 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4361 I.getSuccessOrdering(),
I.getFailureOrdering()));
4365bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4367 if (!mayTranslateUserTypes(U))
4371 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4374 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4375 Register Val = getOrCreateVReg(*
I.getValOperand());
4377 unsigned Opcode = 0;
4378 switch (
I.getOperation()) {
4382 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4385 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4388 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4391 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4394 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4397 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4400 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4403 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4406 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4409 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4412 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4415 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4418 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4421 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4424 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4427 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4430 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4433 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4436 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4439 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4442 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4445 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4448 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4453 Opcode, Res, Addr, Val,
4454 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4455 Flags, MRI->getType(Val), getMemOpAlign(
I),
4456 I.getAAMetadata(),
I.getSyncScopeID(),
4461bool IRTranslatorImpl::translateFence(
const User &U,
4465 Fence.getSyncScopeID());
4469bool IRTranslatorImpl::translateFreeze(
const User &U,
4475 "Freeze with different source and destination type?");
4477 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4484void IRTranslatorImpl::finishPendingPhis() {
4487 GISelObserverWrapper WrapperObserver(&
Verifier);
4488 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4490 for (
auto &Phi : PendingPHIs) {
4491 const PHINode *PI =
Phi.first;
4495 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4501 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4505 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4509 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4510 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4519void IRTranslatorImpl::translateDbgValueRecord(
Value *V,
bool HasArgList,
4525 "Expected inlined-at fields to agree");
4529 if (!V || HasArgList) {
4547 auto *ExprDerefRemoved =
4553 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
4565void IRTranslatorImpl::translateDbgDeclareRecord(
4570 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4575 "Expected inlined-at fields to agree");
4580 MF->setVariableDbgInfo(Variable, Expression,
4581 getOrCreateFrameIndex(*AI), DL);
4585 if (translateIfEntryValueArgument(
true,
Address, Variable,
4597void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4602 assert(DLR->getLabel() &&
"Missing label");
4603 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4605 "Expected inlined-at fields to agree");
4614 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
4617 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
4622bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4624 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4625 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4627 if (TLI->fallBackToDAGISel(Inst))
4631#define HANDLE_INST(NUM, OPCODE, CLASS) \
4632 case Instruction::OPCODE: \
4633 return translate##OPCODE(Inst, *CurBuilder.get());
4634#include "llvm/IR/Instruction.def"
4643 if (
auto CurrInstDL = CurBuilder->getDL())
4644 EntryBuilder->setDebugLoc(
DebugLoc());
4650 EntryBuilder->buildConstant(
Reg, *CI);
4654 EntryBuilder->buildConstant(
Reg, CB->getValue());
4658 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4659 EntryBuilder->buildFConstant(
Reg, *CF);
4661 EntryBuilder->buildUndef(
Reg);
4663 EntryBuilder->buildConstant(
Reg, 0);
4665 EntryBuilder->buildGlobalValue(
Reg, GV);
4667 Register Addr = getOrCreateVReg(*CPA->getPointer());
4668 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4669 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4671 Constant &Elt = *CAZ->getElementValue(0u);
4673 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4677 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4679 return translateCopy(
C, Elt, *EntryBuilder);
4681 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4684 if (CV->getNumElements() == 1)
4685 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4687 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4688 Constant &Elt = *CV->getElementAsConstant(i);
4689 Ops.push_back(getOrCreateVReg(Elt));
4691 EntryBuilder->buildBuildVector(
Reg,
Ops);
4693 switch(
CE->getOpcode()) {
4694#define HANDLE_INST(NUM, OPCODE, CLASS) \
4695 case Instruction::OPCODE: \
4696 return translate##OPCODE(*CE, *EntryBuilder.get());
4697#include "llvm/IR/Instruction.def"
4702 if (CV->getNumOperands() == 1)
4703 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4705 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4706 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4708 EntryBuilder->buildBuildVector(
Reg,
Ops);
4710 EntryBuilder->buildBlockAddress(
Reg, BA);
4717bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4718 const TargetMachine &TM = TLI->getTargetMachine();
4727 (!
U.getType()->getScalarType()->isBFloatTy() &&
4729 return V->getType()->getScalarType()->isBFloatTy();
4733bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4735 for (
auto &BTB : SL->BitTestCases) {
4738 emitBitTestHeader(BTB, BTB.Parent);
4740 BranchProbability UnhandledProb = BTB.Prob;
4741 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4742 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4744 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4753 MachineBasicBlock *NextMBB;
4754 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4757 NextMBB = BTB.Cases[
j + 1].TargetBB;
4758 }
else if (j + 1 == ej) {
4760 NextMBB = BTB.Default;
4763 NextMBB = BTB.Cases[
j + 1].ThisBB;
4766 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4768 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4772 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4773 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4776 BTB.Cases.pop_back();
4782 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4783 BTB.Default->getBasicBlock()};
4784 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4785 if (!BTB.ContiguousRange) {
4786 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4789 SL->BitTestCases.clear();
4791 for (
auto &JTCase : SL->JTCases) {
4793 if (!JTCase.first.Emitted)
4794 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4796 emitJumpTable(JTCase.second, JTCase.second.MBB);
4798 SL->JTCases.clear();
4800 for (
auto &SwCase : SL->SwitchCases)
4801 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4802 SL->SwitchCases.clear();
4805 if (SPInfo->shouldEmitSDCheck(BB)) {
4806 bool FunctionBasedInstrumentation =
4807 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4808 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4811 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4814 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4815 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4816 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4825 ParentMBB, *MF->getSubtarget().getInstrInfo());
4828 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4832 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4836 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4837 if (FailureMBB->
empty()) {
4838 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4843 SPDescriptor.resetPerBBState();
4850 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4854 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
4860 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
4867 ->buildLoad(PtrMemTy, StackSlotPtr,
4873 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
4885 FunctionType *FnTy = GuardCheckFn->getFunctionType();
4886 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
4887 ISD::ArgFlagsTy
Flags;
4888 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
4890 CallLowering::ArgInfo GuardArgInfo(
4891 {GuardVal, FnTy->getParamType(0), {
Flags}});
4893 CallLowering::CallLoweringInfo
Info;
4894 Info.OrigArgs.push_back(GuardArgInfo);
4895 Info.CallConv = GuardCheckFn->getCallingConv();
4898 if (!CLI->lowerCall(MIRBuilder, Info)) {
4899 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
4909 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
4910 getStackGuard(Guard, *CurBuilder);
4913 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
4914 Register GuardPtr = getOrCreateVReg(*IRGuard);
4917 ->buildLoad(PtrMemTy, GuardPtr,
4936 const RTLIB::LibcallImpl LibcallImpl =
4937 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
4938 if (LibcallImpl == RTLIB::Unsupported)
4941 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
4943 CallLowering::CallLoweringInfo
Info;
4944 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
4946 StringRef LibcallName =
4951 if (!CLI->lowerCall(*CurBuilder, Info)) {
4952 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
4957 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
4959 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
4964void IRTranslatorImpl::finalizeFunction() {
4967 PendingPHIs.clear();
4969 FrameIndices.clear();
4970 MachinePreds.clear();
4974 EntryBuilder.reset();
4977 SPDescriptor.resetPerFunctionState();
4990 return CI && CI->isMustTailCall();
5002 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
5003 CLI = MF->getSubtarget().getCallLowering();
5004 SPInfo = StackProtectorInfo;
5006 if (CLI->fallBackToDAGISel(*MF)) {
5008 F.getSubprogram(), &
F.getEntryBlock());
5009 R <<
"unable to lower function: "
5010 <<
ore::NV(
"Prototype",
F.getFunctionType());
5027 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5028 CSEInfo = GetCSEInfo();
5029 EntryBuilder->setCSEInfo(CSEInfo);
5030 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5031 CurBuilder->setCSEInfo(CSEInfo);
5033 EntryBuilder = std::make_unique<MachineIRBuilder>();
5034 CurBuilder = std::make_unique<MachineIRBuilder>();
5037 CurBuilder->setMF(*MF);
5038 EntryBuilder->setMF(*MF);
5039 MRI = &MF->getRegInfo();
5040 DL = &
F.getDataLayout();
5045 AA = GetAAResults();
5046 FuncInfo.BPI = GetBPI();
5050 FuncInfo.BPI =
nullptr;
5053 LibInfo = LibraryInfo;
5054 Libcalls = LibcallInfo;
5056 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5058 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5059 SL->init(*TLI, TM, *DL);
5061 assert(PendingPHIs.empty() &&
"stale PHIs");
5065 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5068 F.getSubprogram(), &
F.getEntryBlock());
5069 R <<
"unable to translate in big endian mode";
5080 EntryBuilder->setMBB(*EntryBB);
5082 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5083 SwiftError.setFunction(CurMF);
5084 SwiftError.createEntriesInEntryBlock(DbgLoc);
5086 bool IsVarArg =
F.isVarArg();
5087 bool HasMustTailInVarArgFn =
false;
5090 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5094 MBB = MF->CreateMachineBasicBlock(&BB);
5102 if (!BA->hasZeroLiveUses())
5106 if (!HasMustTailInVarArgFn)
5110 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5113 EntryBB->addSuccessor(&getMBB(
F.front()));
5118 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5123 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5124 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5125 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5129 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5131 F.getSubprogram(), &
F.getEntryBlock());
5132 R <<
"unable to lower arguments: "
5133 <<
ore::NV(
"Prototype",
F.getFunctionType());
5140 if (EnableCSE && CSEInfo)
5145 DILocationVerifier Verifier;
5153 CurBuilder->setMBB(
MBB);
5154 HasTailCall =
false;
5164 Verifier.setCurrentInst(&Inst);
5168 translateDbgInfo(Inst, *CurBuilder);
5170 if (translate(Inst))
5175 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5177 if (ORE->allowExtraAnalysis(
"gisel-irtranslator")) {
5178 std::string InstStrStorage;
5182 R <<
": '" << InstStrStorage <<
"'";
5189 if (!finalizeBasicBlock(*BB,
MBB)) {
5191 BB->getTerminator()->getDebugLoc(), BB);
5192 R <<
"unable to translate basic block";
5202 finishPendingPhis();
5204 SwiftError.propagateVRegs();
5209 assert(EntryBB->succ_size() == 1 &&
5210 "Custom BB used for lowering should have only one successor");
5214 "LLVM-IR entry block has a predecessor!?");
5217 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5226 EntryBB->removeSuccessor(&NewEntryBB);
5227 MF->remove(EntryBB);
5228 MF->deleteMachineBasicBlock(EntryBB);
5230 assert(&MF->front() == &NewEntryBB &&
5231 "New entry wasn't next in the list of basic block!");
5234 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5244 return Impl->runOnMachineFunction(
5263 *
F.getParent(), Subtarget),
5287 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5288 Impl->runOnMachineFunction(
5290 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...
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.
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.
const BasicBlock & getEntryBlock() const
DISubprogram * getSubprogram() const
Get the attached subprogram.
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
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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.
@ 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,...
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
A set of analyses that are preserved following a run of a transformation pass.
Class to install both of the above.
Wrapper class representing virtual and physical registers.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
Encapsulates all of the information needed to generate a stack protector check, and signals to isel w...
MachineBasicBlock * getSuccessMBB()
MachineBasicBlock * getFailureMBB()
constexpr bool empty() const
Check if the string is empty.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
SwitchLowering(FunctionLoweringInfo &funcinfo)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
const Target & getTarget() const
unsigned NoTrapAfterNoreturn
Do not emit a trap instruction for 'unreachable' IR instructions behind noreturn calls,...
unsigned TrapUnreachable
Emit target-specific trap instruction for 'unreachable' IR instructions.
FPOpFusion::FPOpFusionMode AllowFPOpFusion
AllowFPOpFusion - This flag is set by the -fp-contract=xxx option.
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.
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
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.
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.
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.