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::clmul:
2740 return TargetOpcode::G_CLMUL;
2741 case Intrinsic::fshl:
2742 return TargetOpcode::G_FSHL;
2743 case Intrinsic::fshr:
2744 return TargetOpcode::G_FSHR;
2745 case Intrinsic::ceil:
2746 return TargetOpcode::G_FCEIL;
2747 case Intrinsic::cos:
2748 return TargetOpcode::G_FCOS;
2749 case Intrinsic::cosh:
2750 return TargetOpcode::G_FCOSH;
2751 case Intrinsic::ctpop:
2752 return TargetOpcode::G_CTPOP;
2753 case Intrinsic::exp:
2754 return TargetOpcode::G_FEXP;
2755 case Intrinsic::exp2:
2756 return TargetOpcode::G_FEXP2;
2757 case Intrinsic::exp10:
2758 return TargetOpcode::G_FEXP10;
2759 case Intrinsic::fabs:
2760 return TargetOpcode::G_FABS;
2761 case Intrinsic::copysign:
2762 return TargetOpcode::G_FCOPYSIGN;
2763 case Intrinsic::minnum:
2764 return TargetOpcode::G_FMINNUM;
2765 case Intrinsic::maxnum:
2766 return TargetOpcode::G_FMAXNUM;
2767 case Intrinsic::minimum:
2768 return TargetOpcode::G_FMINIMUM;
2769 case Intrinsic::maximum:
2770 return TargetOpcode::G_FMAXIMUM;
2771 case Intrinsic::minimumnum:
2772 return TargetOpcode::G_FMINIMUMNUM;
2773 case Intrinsic::maximumnum:
2774 return TargetOpcode::G_FMAXIMUMNUM;
2775 case Intrinsic::canonicalize:
2776 return TargetOpcode::G_FCANONICALIZE;
2777 case Intrinsic::floor:
2778 return TargetOpcode::G_FFLOOR;
2779 case Intrinsic::fma:
2780 return TargetOpcode::G_FMA;
2781 case Intrinsic::log:
2782 return TargetOpcode::G_FLOG;
2783 case Intrinsic::log2:
2784 return TargetOpcode::G_FLOG2;
2785 case Intrinsic::log10:
2786 return TargetOpcode::G_FLOG10;
2787 case Intrinsic::ldexp:
2788 return TargetOpcode::G_FLDEXP;
2789 case Intrinsic::nearbyint:
2790 return TargetOpcode::G_FNEARBYINT;
2791 case Intrinsic::pow:
2792 return TargetOpcode::G_FPOW;
2793 case Intrinsic::powi:
2794 return TargetOpcode::G_FPOWI;
2795 case Intrinsic::rint:
2796 return TargetOpcode::G_FRINT;
2797 case Intrinsic::round:
2798 return TargetOpcode::G_INTRINSIC_ROUND;
2799 case Intrinsic::roundeven:
2800 return TargetOpcode::G_INTRINSIC_ROUNDEVEN;
2801 case Intrinsic::sin:
2802 return TargetOpcode::G_FSIN;
2803 case Intrinsic::sinh:
2804 return TargetOpcode::G_FSINH;
2805 case Intrinsic::sqrt:
2806 return TargetOpcode::G_FSQRT;
2807 case Intrinsic::tan:
2808 return TargetOpcode::G_FTAN;
2809 case Intrinsic::tanh:
2810 return TargetOpcode::G_FTANH;
2811 case Intrinsic::trunc:
2812 return TargetOpcode::G_INTRINSIC_TRUNC;
2813 case Intrinsic::readcyclecounter:
2814 return TargetOpcode::G_READCYCLECOUNTER;
2815 case Intrinsic::readsteadycounter:
2816 return TargetOpcode::G_READSTEADYCOUNTER;
2817 case Intrinsic::ptrmask:
2818 return TargetOpcode::G_PTRMASK;
2819 case Intrinsic::lrint:
2820 return TargetOpcode::G_INTRINSIC_LRINT;
2821 case Intrinsic::llrint:
2822 return TargetOpcode::G_INTRINSIC_LLRINT;
2824 case Intrinsic::vector_reduce_fmin:
2825 return TargetOpcode::G_VECREDUCE_FMIN;
2826 case Intrinsic::vector_reduce_fmax:
2827 return TargetOpcode::G_VECREDUCE_FMAX;
2828 case Intrinsic::vector_reduce_fminimum:
2829 return TargetOpcode::G_VECREDUCE_FMINIMUM;
2830 case Intrinsic::vector_reduce_fmaximum:
2831 return TargetOpcode::G_VECREDUCE_FMAXIMUM;
2832 case Intrinsic::vector_reduce_fminimumnum:
2833 return TargetOpcode::G_VECREDUCE_FMINIMUMNUM;
2834 case Intrinsic::vector_reduce_fmaximumnum:
2835 return TargetOpcode::G_VECREDUCE_FMAXIMUMNUM;
2836 case Intrinsic::vector_reduce_add:
2837 return TargetOpcode::G_VECREDUCE_ADD;
2838 case Intrinsic::vector_reduce_mul:
2839 return TargetOpcode::G_VECREDUCE_MUL;
2840 case Intrinsic::vector_reduce_and:
2841 return TargetOpcode::G_VECREDUCE_AND;
2842 case Intrinsic::vector_reduce_or:
2843 return TargetOpcode::G_VECREDUCE_OR;
2844 case Intrinsic::vector_reduce_xor:
2845 return TargetOpcode::G_VECREDUCE_XOR;
2846 case Intrinsic::vector_reduce_smax:
2847 return TargetOpcode::G_VECREDUCE_SMAX;
2848 case Intrinsic::vector_reduce_smin:
2849 return TargetOpcode::G_VECREDUCE_SMIN;
2850 case Intrinsic::vector_reduce_umax:
2851 return TargetOpcode::G_VECREDUCE_UMAX;
2852 case Intrinsic::vector_reduce_umin:
2853 return TargetOpcode::G_VECREDUCE_UMIN;
2854 case Intrinsic::experimental_vector_compress:
2855 return TargetOpcode::G_VECTOR_COMPRESS;
2856 case Intrinsic::lround:
2857 return TargetOpcode::G_LROUND;
2858 case Intrinsic::llround:
2859 return TargetOpcode::G_LLROUND;
2860 case Intrinsic::get_fpenv:
2861 return TargetOpcode::G_GET_FPENV;
2862 case Intrinsic::get_fpmode:
2863 return TargetOpcode::G_GET_FPMODE;
2868bool IRTranslatorImpl::translateSimpleIntrinsic(
const CallInst &CI,
2872 unsigned Op = getSimpleIntrinsicOpcode(ID);
2880 for (
const auto &Arg : CI.
args())
2883 MIRBuilder.
buildInstr(
Op, {getOrCreateVReg(CI)}, VRegs,
2891 case Intrinsic::experimental_constrained_fadd:
2892 return TargetOpcode::G_STRICT_FADD;
2893 case Intrinsic::experimental_constrained_fsub:
2894 return TargetOpcode::G_STRICT_FSUB;
2895 case Intrinsic::experimental_constrained_fmul:
2896 return TargetOpcode::G_STRICT_FMUL;
2897 case Intrinsic::experimental_constrained_fdiv:
2898 return TargetOpcode::G_STRICT_FDIV;
2899 case Intrinsic::experimental_constrained_frem:
2900 return TargetOpcode::G_STRICT_FREM;
2901 case Intrinsic::experimental_constrained_fma:
2902 return TargetOpcode::G_STRICT_FMA;
2903 case Intrinsic::experimental_constrained_sqrt:
2904 return TargetOpcode::G_STRICT_FSQRT;
2905 case Intrinsic::experimental_constrained_ldexp:
2906 return TargetOpcode::G_STRICT_FLDEXP;
2907 case Intrinsic::experimental_constrained_fcmp:
2908 return TargetOpcode::G_STRICT_FCMP;
2909 case Intrinsic::experimental_constrained_fcmps:
2910 return TargetOpcode::G_STRICT_FCMPS;
2916bool IRTranslatorImpl::translateConstrainedFPIntrinsic(
2928 if (Opcode == TargetOpcode::G_STRICT_FCMP ||
2929 Opcode == TargetOpcode::G_STRICT_FCMPS) {
2931 Register Operand0 = getOrCreateVReg(*FPCmp->getArgOperand(0));
2932 Register Operand1 = getOrCreateVReg(*FPCmp->getArgOperand(1));
2935 .addPredicate(FPCmp->getPredicate())
2949std::optional<MCRegister> IRTranslatorImpl::getArgPhysReg(
Argument &Arg) {
2950 auto VRegs = getOrCreateVRegs(Arg);
2951 if (VRegs.
size() != 1)
2952 return std::nullopt;
2955 auto *VRegDef = MF->getRegInfo().getVRegDef(VRegs[0]);
2956 if (!VRegDef || !VRegDef->isCopy())
2957 return std::nullopt;
2958 return VRegDef->getOperand(1).getReg().asMCReg();
2961bool IRTranslatorImpl::translateIfEntryValueArgument(
2972 std::optional<MCRegister> PhysReg = getArgPhysReg(*Arg);
2974 LLVM_DEBUG(
dbgs() <<
"Dropping dbg." << (isDeclare ?
"declare" :
"value")
2975 <<
": expression is entry_value but "
2976 <<
"couldn't find a physical register\n");
2984 MF->setVariableDbgInfo(Var, Expr, *PhysReg, DL);
2996 case Intrinsic::experimental_convergence_anchor:
2997 return TargetOpcode::CONVERGENCECTRL_ANCHOR;
2998 case Intrinsic::experimental_convergence_entry:
2999 return TargetOpcode::CONVERGENCECTRL_ENTRY;
3000 case Intrinsic::experimental_convergence_loop:
3001 return TargetOpcode::CONVERGENCECTRL_LOOP;
3005bool IRTranslatorImpl::translateConvergenceControlIntrinsic(
3008 Register OutputReg = getOrCreateConvergenceTokenVReg(CI);
3011 if (ID == Intrinsic::experimental_convergence_loop) {
3013 assert(Bundle &&
"Expected a convergence control token.");
3015 getOrCreateConvergenceTokenVReg(*Bundle->Inputs[0].get());
3022bool IRTranslatorImpl::translateKnownIntrinsic(
const CallInst &CI,
3026 if (ORE->enabled()) {
3028 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3036 if (translateSimpleIntrinsic(CI, ID, MIRBuilder))
3042 case Intrinsic::lifetime_start:
3043 case Intrinsic::lifetime_end: {
3046 MF->getFunction().hasOptNone())
3049 unsigned Op =
ID == Intrinsic::lifetime_start ? TargetOpcode::LIFETIME_START
3050 : TargetOpcode::LIFETIME_END;
3059 case Intrinsic::fake_use: {
3061 for (
const auto &Arg : CI.
args())
3063 MIRBuilder.
buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
3064 MF->setHasFakeUses(
true);
3067 case Intrinsic::dbg_declare: {
3074 case Intrinsic::dbg_label: {
3080 "Expected inlined-at fields to agree");
3085 case Intrinsic::vaend:
3089 case Intrinsic::vastart: {
3091 unsigned ListSize = TLI->getVaListSizeInBits(*DL) / 8;
3094 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART, {}, {getOrCreateVReg(*Ptr)})
3095 .addMemOperand(MF->getMachineMemOperand(MachinePointerInfo(Ptr),
3097 ListSize, Alignment));
3100 case Intrinsic::dbg_assign:
3107 case Intrinsic::dbg_value: {
3114 case Intrinsic::uadd_with_overflow:
3115 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
3116 case Intrinsic::sadd_with_overflow:
3117 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
3118 case Intrinsic::usub_with_overflow:
3119 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
3120 case Intrinsic::ssub_with_overflow:
3121 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
3122 case Intrinsic::umul_with_overflow:
3123 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
3124 case Intrinsic::smul_with_overflow:
3125 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
3126 case Intrinsic::uadd_sat:
3127 return translateBinaryOp(TargetOpcode::G_UADDSAT, CI, MIRBuilder);
3128 case Intrinsic::sadd_sat:
3129 return translateBinaryOp(TargetOpcode::G_SADDSAT, CI, MIRBuilder);
3130 case Intrinsic::usub_sat:
3131 return translateBinaryOp(TargetOpcode::G_USUBSAT, CI, MIRBuilder);
3132 case Intrinsic::ssub_sat:
3133 return translateBinaryOp(TargetOpcode::G_SSUBSAT, CI, MIRBuilder);
3134 case Intrinsic::ushl_sat:
3135 return translateBinaryOp(TargetOpcode::G_USHLSAT, CI, MIRBuilder);
3136 case Intrinsic::sshl_sat:
3137 return translateBinaryOp(TargetOpcode::G_SSHLSAT, CI, MIRBuilder);
3138 case Intrinsic::umin:
3139 return translateBinaryOp(TargetOpcode::G_UMIN, CI, MIRBuilder);
3140 case Intrinsic::umax:
3141 return translateBinaryOp(TargetOpcode::G_UMAX, CI, MIRBuilder);
3142 case Intrinsic::smin:
3143 return translateBinaryOp(TargetOpcode::G_SMIN, CI, MIRBuilder);
3144 case Intrinsic::smax:
3145 return translateBinaryOp(TargetOpcode::G_SMAX, CI, MIRBuilder);
3146 case Intrinsic::abs:
3148 return translateUnaryOp(TargetOpcode::G_ABS, CI, MIRBuilder);
3149 case Intrinsic::smul_fix:
3150 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIX, CI, MIRBuilder);
3151 case Intrinsic::umul_fix:
3152 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIX, CI, MIRBuilder);
3153 case Intrinsic::smul_fix_sat:
3154 return translateFixedPointIntrinsic(TargetOpcode::G_SMULFIXSAT, CI, MIRBuilder);
3155 case Intrinsic::umul_fix_sat:
3156 return translateFixedPointIntrinsic(TargetOpcode::G_UMULFIXSAT, CI, MIRBuilder);
3157 case Intrinsic::sdiv_fix:
3158 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIX, CI, MIRBuilder);
3159 case Intrinsic::udiv_fix:
3160 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIX, CI, MIRBuilder);
3161 case Intrinsic::sdiv_fix_sat:
3162 return translateFixedPointIntrinsic(TargetOpcode::G_SDIVFIXSAT, CI, MIRBuilder);
3163 case Intrinsic::udiv_fix_sat:
3164 return translateFixedPointIntrinsic(TargetOpcode::G_UDIVFIXSAT, CI, MIRBuilder);
3165 case Intrinsic::fmuladd: {
3166 const TargetMachine &TM = MF->getTarget();
3167 Register Dst = getOrCreateVReg(CI);
3172 TLI->isFMAFasterThanFMulAndFAdd(*MF,
3173 TLI->getValueType(*DL, CI.
getType()))) {
3176 MIRBuilder.
buildFMA(Dst, Op0, Op1, Op2,
3187 case Intrinsic::frexp: {
3194 case Intrinsic::modf: {
3196 MIRBuilder.
buildModf(VRegs[0], VRegs[1],
3201 case Intrinsic::sincos: {
3208 case Intrinsic::fptosi_sat:
3212 case Intrinsic::fptoui_sat:
3216 case Intrinsic::memcpy_inline:
3217 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY_INLINE);
3218 case Intrinsic::memcpy:
3219 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMCPY);
3220 case Intrinsic::memmove:
3221 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMMOVE);
3222 case Intrinsic::memset:
3223 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET);
3224 case Intrinsic::memset_inline:
3225 return translateMemFunc(CI, MIRBuilder, TargetOpcode::G_MEMSET_INLINE);
3226 case Intrinsic::eh_typeid_for: {
3229 unsigned TypeID = MF->getTypeIDFor(GV);
3233 case Intrinsic::objectsize:
3236 case Intrinsic::is_constant:
3239 case Intrinsic::stackguard:
3240 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
3242 case Intrinsic::stackprotector: {
3245 if (TLI->useLoadStackGuardNode(*CI.
getModule())) {
3246 GuardVal = MRI->createGenericVirtualRegister(PtrTy);
3247 getStackGuard(GuardVal, MIRBuilder);
3252 int FI = getOrCreateFrameIndex(*Slot);
3253 MF->getFrameInfo().setStackProtectorIndex(FI);
3256 GuardVal, getOrCreateVReg(*Slot),
3263 case Intrinsic::stacksave: {
3264 MIRBuilder.
buildInstr(TargetOpcode::G_STACKSAVE, {getOrCreateVReg(CI)}, {});
3267 case Intrinsic::stackrestore: {
3268 MIRBuilder.
buildInstr(TargetOpcode::G_STACKRESTORE, {},
3272 case Intrinsic::cttz:
3273 case Intrinsic::ctlz: {
3275 bool isTrailing =
ID == Intrinsic::cttz;
3276 unsigned Opcode = isTrailing ? Cst->
isZero()
3277 ? TargetOpcode::G_CTTZ
3278 : TargetOpcode::G_CTTZ_ZERO_POISON
3279 : Cst->
isZero() ? TargetOpcode::G_CTLZ
3280 : TargetOpcode::G_CTLZ_ZERO_POISON;
3281 MIRBuilder.
buildInstr(Opcode, {getOrCreateVReg(CI)},
3285 case Intrinsic::invariant_start: {
3289 case Intrinsic::invariant_end:
3291 case Intrinsic::expect:
3292 case Intrinsic::expect_with_probability:
3293 case Intrinsic::annotation:
3294 case Intrinsic::ptr_annotation:
3295 case Intrinsic::launder_invariant_group:
3296 case Intrinsic::strip_invariant_group:
3297 case Intrinsic::threadlocal_address: {
3299 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3303 case Intrinsic::assume:
3304 case Intrinsic::experimental_noalias_scope_decl:
3305 case Intrinsic::var_annotation:
3306 case Intrinsic::sideeffect:
3309 case Intrinsic::read_volatile_register:
3310 case Intrinsic::read_register: {
3313 .
buildInstr(TargetOpcode::G_READ_REGISTER, {getOrCreateVReg(CI)}, {})
3317 case Intrinsic::write_register: {
3319 MIRBuilder.
buildInstr(TargetOpcode::G_WRITE_REGISTER)
3324 case Intrinsic::localescape: {
3325 MachineBasicBlock &EntryMBB = MF->front();
3330 for (
unsigned Idx = 0,
E = CI.
arg_size(); Idx <
E; ++Idx) {
3337 MF->getContext().getOrCreateFrameAllocSymbol(EscapedName, Idx);
3350 case Intrinsic::vector_reduce_fadd:
3351 case Intrinsic::vector_reduce_fmul: {
3354 Register Dst = getOrCreateVReg(CI);
3360 Opc =
ID == Intrinsic::vector_reduce_fadd
3361 ? TargetOpcode::G_VECREDUCE_SEQ_FADD
3362 : TargetOpcode::G_VECREDUCE_SEQ_FMUL;
3363 if (!MRI->getType(VecSrc).isVector())
3364 Opc =
ID == Intrinsic::vector_reduce_fadd ? TargetOpcode::G_FADD
3365 : TargetOpcode::G_FMUL;
3373 if (ID == Intrinsic::vector_reduce_fadd) {
3374 Opc = TargetOpcode::G_VECREDUCE_FADD;
3375 ScalarOpc = TargetOpcode::G_FADD;
3377 Opc = TargetOpcode::G_VECREDUCE_FMUL;
3378 ScalarOpc = TargetOpcode::G_FMUL;
3380 LLT DstTy = MRI->getType(Dst);
3383 MIRBuilder.
buildInstr(ScalarOpc, {Dst}, {ScalarSrc, Rdx},
3388 case Intrinsic::trap:
3389 return translateTrap(CI, MIRBuilder, TargetOpcode::G_TRAP);
3390 case Intrinsic::debugtrap:
3391 return translateTrap(CI, MIRBuilder, TargetOpcode::G_DEBUGTRAP);
3392 case Intrinsic::ubsantrap:
3393 return translateTrap(CI, MIRBuilder, TargetOpcode::G_UBSANTRAP);
3394 case Intrinsic::allow_runtime_check:
3395 case Intrinsic::allow_ubsan_check:
3396 MIRBuilder.
buildCopy(getOrCreateVReg(CI),
3399 case Intrinsic::amdgcn_cs_chain:
3400 case Intrinsic::amdgcn_call_whole_wave:
3401 return translateCallBase(CI, MIRBuilder);
3402 case Intrinsic::fptrunc_round: {
3407 std::optional<RoundingMode> RoundMode =
3412 .
buildInstr(TargetOpcode::G_INTRINSIC_FPTRUNC_ROUND,
3413 {getOrCreateVReg(CI)},
3415 .addImm((
int)*RoundMode);
3419 case Intrinsic::is_fpclass: {
3424 .
buildInstr(TargetOpcode::G_IS_FPCLASS, {getOrCreateVReg(CI)},
3425 {getOrCreateVReg(*FpValue)})
3430 case Intrinsic::set_fpenv: {
3435 case Intrinsic::reset_fpenv:
3438 case Intrinsic::set_fpmode: {
3443 case Intrinsic::reset_fpmode:
3446 case Intrinsic::get_rounding:
3449 case Intrinsic::set_rounding:
3452 case Intrinsic::vscale: {
3456 case Intrinsic::scmp:
3457 MIRBuilder.
buildSCmp(getOrCreateVReg(CI),
3461 case Intrinsic::ucmp:
3462 MIRBuilder.
buildUCmp(getOrCreateVReg(CI),
3466 case Intrinsic::vector_extract:
3467 return translateExtractVector(CI, MIRBuilder);
3468 case Intrinsic::vector_insert:
3469 return translateInsertVector(CI, MIRBuilder);
3470 case Intrinsic::stepvector: {
3474 case Intrinsic::prefetch: {
3481 auto &MMO = *MF->getMachineMemOperand(MachinePointerInfo(Addr), Flags,
3484 MIRBuilder.
buildPrefetch(getOrCreateVReg(*Addr), RW, Locality, CacheType,
3490 case Intrinsic::vector_interleave2:
3491 case Intrinsic::vector_deinterleave2: {
3499 return translateVectorInterleave2Intrinsic(CI, MIRBuilder);
3501 return translateVectorDeinterleave2Intrinsic(CI, MIRBuilder);
3504#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
3505 case Intrinsic::INTRINSIC:
3506#include "llvm/IR/ConstrainedOps.def"
3509 case Intrinsic::experimental_convergence_anchor:
3510 case Intrinsic::experimental_convergence_entry:
3511 case Intrinsic::experimental_convergence_loop:
3512 return translateConvergenceControlIntrinsic(CI, ID, MIRBuilder);
3513 case Intrinsic::reloc_none: {
3516 MIRBuilder.
buildInstr(TargetOpcode::RELOC_NONE)
3524bool IRTranslatorImpl::translateInlineAsm(
const CallBase &CB,
3526 if (!mayTranslateUserTypes(CB))
3529 const InlineAsmLowering *ALI = MF->getSubtarget().getInlineAsmLowering();
3533 dbgs() <<
"Inline asm lowering is not supported for this target yet\n");
3538 MIRBuilder, CB, [&](
const Value &Val) {
return getOrCreateVRegs(Val); });
3541bool IRTranslatorImpl::translateCallBase(
const CallBase &CB,
3548 for (
const auto &Arg : CB.
args()) {
3550 assert(SwiftInVReg == 0 &&
"Expected only one swift error argument");
3552 SwiftInVReg = MRI->createGenericVirtualRegister(Ty);
3553 MIRBuilder.
buildCopy(SwiftInVReg, SwiftError.getOrCreateVRegUseAt(
3554 &CB, &MIRBuilder.
getMBB(), Arg));
3557 SwiftError.getOrCreateVRegDefAt(&CB, &MIRBuilder.
getMBB(), Arg);
3560 Args.push_back(getOrCreateVRegs(*Arg));
3564 if (ORE->enabled()) {
3566 MemoryOpRemark
R(*ORE,
"gisel-irtranslator-memsize", *DL, *LibInfo);
3572 std::optional<CallLowering::PtrAuthInfo> PAI;
3577 const Value *
Key = Bundle->Inputs[0];
3584 if (!CalleeCPA || !
isa<Function>(CalleeCPA->getPointer()) ||
3585 !CalleeCPA->isKnownCompatibleWith(
Key, Discriminator, *DL)) {
3587 Register DiscReg = getOrCreateVReg(*Discriminator);
3595 const auto &Token = *Bundle->Inputs[0].get();
3596 ConvergenceCtrlToken = getOrCreateConvergenceTokenVReg(Token);
3602 bool Success = CLI->lowerCall(
3603 MIRBuilder, CB, Res, Args, SwiftErrorVReg, PAI, ConvergenceCtrlToken,
3608 assert(!HasTailCall &&
"Can't tail call return twice from block?");
3609 const TargetInstrInfo *
TII = MF->getSubtarget().getInstrInfo();
3616bool IRTranslatorImpl::translateCall(
const User &U,
3618 if (!mayTranslateUserTypes(U))
3626 if (
F && (
F->hasDLLImportStorageClass() ||
3627 (MF->getTarget().getTargetTriple().isOSWindows() &&
3628 F->hasExternalWeakLinkage())))
3640 return translateInlineAsm(CI, MIRBuilder);
3644 if (translateCallBase(CI, MIRBuilder)) {
3653 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3654 const Function &Fn = MF->getFunction();
3656 DiagnosticInfoUnsupportedTargetIntrinsic(Fn, ID, CI.
getDebugLoc()));
3659 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
3663 TLI->getTgtMemIntrinsic(Infos, CI, *MF, ID);
3665 return translateIntrinsic(CI, ID, MIRBuilder, Infos);
3669bool IRTranslatorImpl::translateIntrinsic(
3672 if (!MF->getSubtarget().isIntrinsicSupported(ID)) {
3674 F.getContext().diagnose(
3675 DiagnosticInfoUnsupportedTargetIntrinsic(
F, ID, CB.
getDebugLoc()));
3680 ResultRegs = getOrCreateVRegs(CB);
3684 MachineInstrBuilder MIB = MIRBuilder.
buildIntrinsic(ID, ResultRegs);
3695 assert(CI->getBitWidth() <= 64 &&
3696 "large intrinsic immediates not handled");
3697 MIB.
addImm(CI->getSExtValue());
3702 auto *MD = MDVal->getMetadata();
3706 MDN =
MDNode::get(MF->getFunction().getContext(), ConstMD);
3713 if (VRegs.
size() > 1)
3720 for (
const auto &Info : TgtMemIntrinsicInfos) {
3723 LLT MemTy =
Info.memVT.isSimple()
3725 : LLT::scalar(
Info.memVT.getStoreSizeInBits());
3729 MachinePointerInfo MPI;
3731 MPI = MachinePointerInfo(Info.ptrVal, Info.offset);
3732 }
else if (
Info.fallbackAddressSpace) {
3733 MPI = MachinePointerInfo(*Info.fallbackAddressSpace);
3742 auto *Token = Bundle->Inputs[0].get();
3743 Register TokenReg = getOrCreateVReg(*Token);
3754bool IRTranslatorImpl::findUnwindDestinations(
3775 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3781 UnwindDests.emplace_back(&getMBB(*EHPadBB), Prob);
3782 UnwindDests.back().first->setIsEHScopeEntry();
3783 UnwindDests.back().first->setIsEHFuncletEntry();
3788 for (
const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
3789 UnwindDests.emplace_back(&getMBB(*CatchPadBB), Prob);
3791 if (IsMSVCCXX || IsCoreCLR)
3792 UnwindDests.back().first->setIsEHFuncletEntry();
3794 UnwindDests.back().first->setIsEHScopeEntry();
3796 NewEHPadBB = CatchSwitch->getUnwindDest();
3801 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3802 if (BPI && NewEHPadBB)
3804 EHPadBB = NewEHPadBB;
3809bool IRTranslatorImpl::translateInvoke(
const User &U,
3812 MCContext &
Context = MF->getContext();
3817 const Function *Fn =
I.getCalledFunction();
3824 if (
I.hasDeoptState())
3838 (MF->getTarget().getTargetTriple().isOSWindows() &&
3842 bool LowerInlineAsm =
I.isInlineAsm();
3843 bool NeedEHLabel =
true;
3849 MIRBuilder.
buildInstr(TargetOpcode::G_INVOKE_REGION_START);
3850 BeginSymbol =
Context.createTempSymbol();
3854 if (LowerInlineAsm) {
3855 if (!translateInlineAsm(
I, MIRBuilder))
3857 }
else if (!translateCallBase(
I, MIRBuilder))
3862 EndSymbol =
Context.createTempSymbol();
3867 BranchProbabilityInfo *BPI = FuncInfo.BPI;
3868 MachineBasicBlock *InvokeMBB = &MIRBuilder.
getMBB();
3869 BranchProbability EHPadBBProb =
3873 if (!findUnwindDestinations(EHPadBB, EHPadBBProb, UnwindDests))
3876 MachineBasicBlock &EHPadMBB = getMBB(*EHPadBB),
3877 &ReturnMBB = getMBB(*ReturnBB);
3879 addSuccessorWithProb(InvokeMBB, &ReturnMBB);
3880 for (
auto &UnwindDest : UnwindDests) {
3881 UnwindDest.first->setIsEHPad();
3882 addSuccessorWithProb(InvokeMBB, UnwindDest.first, UnwindDest.second);
3887 assert(BeginSymbol &&
"Expected a begin symbol!");
3888 assert(EndSymbol &&
"Expected an end symbol!");
3889 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
3892 MIRBuilder.
buildBr(ReturnMBB);
3898bool IRTranslatorImpl::translateCallBr(
const User &U,
3900 if (!mayTranslateUserTypes(U))
3904 MachineBasicBlock *CallBrMBB = &MIRBuilder.
getMBB();
3907 if (
I.isInlineAsm()) {
3913 if (!translateIntrinsic(
I, IID, MIRBuilder))
3917 SmallPtrSet<BasicBlock *, 8> Dests = {
I.getDefaultDest()};
3918 MachineBasicBlock *
Return = &getMBB(*
I.getDefaultDest());
3927 for (BasicBlock *Dest :
I.getIndirectDests()) {
3928 MachineBasicBlock &
Target = getMBB(*Dest);
3929 Target.setIsInlineAsmBrIndirectTarget();
3930 Target.setLabelMustBeEmitted();
3932 if (Dests.
insert(Dest).second)
3944bool IRTranslatorImpl::translateLandingPad(
const User &U,
3948 MachineBasicBlock &
MBB = MIRBuilder.
getMBB();
3954 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
3955 if (TLI->getExceptionPointerRegister(
3956 TLI->getTargetMachine().getExceptionModel(), PersonalityFn) == 0 &&
3957 TLI->getExceptionSelectorRegister(
3958 TLI->getTargetMachine().getExceptionModel(), PersonalityFn) == 0)
3970 MIRBuilder.
buildInstr(TargetOpcode::EH_LABEL)
3975 const TargetRegisterInfo &
TRI = *MF->getSubtarget().getRegisterInfo();
3976 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*MF))
3977 MF->getRegInfo().addPhysRegsUsedFromRegMask(RegMask);
3986 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
3989 Register ExceptionReg = TLI->getExceptionPointerRegister(
3990 TLI->getTargetMachine().getExceptionModel(), PersonalityFn);
3996 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
3998 Register SelectorReg = TLI->getExceptionSelectorRegister(
3999 TLI->getTargetMachine().getExceptionModel(), PersonalityFn);
4004 Register PtrVReg = MRI->createGenericVirtualRegister(Tys[0]);
4005 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
4006 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
4011bool IRTranslatorImpl::translateAlloca(
const User &U,
4019 Register Res = getOrCreateVReg(AI);
4020 int FI = getOrCreateFrameIndex(AI);
4026 if (MF->getTarget().getTargetTriple().isOSWindows())
4031 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
4033 if (MRI->getType(NumElts) !=
IntPtrTy) {
4045 TySizeReg = MRI->createGenericVirtualRegister(
IntPtrTy);
4050 getOrCreateVReg(*ConstantInt::get(IntPtrIRTy, TySize.
getFixedValue()));
4052 MIRBuilder.
buildMul(AllocSize, NumElts, TySizeReg);
4057 Align StackAlign = MF->getSubtarget().getFrameLowering()->getStackAlign();
4066 if (Alignment <= StackAlign)
4070 MF->getFrameInfo().CreateVariableSizedObject(Alignment, &AI);
4071 assert(MF->getFrameInfo().hasVarSizedObjects());
4075bool IRTranslatorImpl::translateVAArg(
const User &U,
4081 MIRBuilder.
buildInstr(TargetOpcode::G_VAARG, {getOrCreateVReg(U)},
4082 {getOrCreateVReg(*
U.getOperand(0)),
4083 DL->getABITypeAlign(
U.getType()).value()});
4087bool IRTranslatorImpl::translateUnreachable(
const User &U,
4090 if (!UI.shouldLowerToTrap(MF->getTarget().Options.TrapUnreachable,
4091 MF->getTarget().Options.NoTrapAfterNoreturn))
4098bool IRTranslatorImpl::translateInsertElement(
const User &U,
4103 FVT && FVT->getNumElements() == 1)
4104 return translateCopy(U, *
U.getOperand(1), MIRBuilder);
4107 Register Val = getOrCreateVReg(*
U.getOperand(0));
4108 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4109 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4112 if (CI->getBitWidth() != PreferredVecIdxWidth) {
4113 APInt NewIdx = CI->getValue().zextOrTrunc(PreferredVecIdxWidth);
4114 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4115 Idx = getOrCreateVReg(*NewIdxCI);
4119 Idx = getOrCreateVReg(*
U.getOperand(2));
4120 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4121 const LLT VecIdxTy =
4122 MRI->getType(Idx).changeElementSize(PreferredVecIdxWidth);
4129bool IRTranslatorImpl::translateInsertVector(
const User &U,
4132 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4133 Register Elt = getOrCreateVReg(*
U.getOperand(1));
4136 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4141 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4146 ResultType && ResultType->getNumElements() == 1) {
4148 InputType && InputType->getNumElements() == 1) {
4152 return translateCopy(U, Vec, MIRBuilder);
4158 Register Idx = getOrCreateVReg(*CI);
4166 Register Idx = getOrCreateVReg(*CI);
4167 auto ScaledIndex = MIRBuilder.
buildMul(
4168 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4178bool IRTranslatorImpl::translateExtractElement(
const User &U,
4182 if (
const FixedVectorType *FVT =
4184 if (FVT->getNumElements() == 1)
4185 return translateCopy(U, *
U.getOperand(0), MIRBuilder);
4188 Register Val = getOrCreateVReg(*
U.getOperand(0));
4189 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4194 auto *NewIdxCI = ConstantInt::get(CI->
getContext(), NewIdx);
4195 Idx = getOrCreateVReg(*NewIdxCI);
4199 Idx = getOrCreateVReg(*
U.getOperand(1));
4200 if (MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
4201 const LLT VecIdxTy =
4209bool IRTranslatorImpl::translateExtractVector(
const User &U,
4212 Register Vec = getOrCreateVReg(*
U.getOperand(0));
4214 unsigned PreferredVecIdxWidth = TLI->getVectorIdxWidth(*DL);
4219 CI = ConstantInt::get(CI->
getContext(), NewIdx);
4224 ResultType && ResultType->getNumElements() == 1) {
4226 InputType && InputType->getNumElements() == 1) {
4229 return translateCopy(U, Vec, MIRBuilder);
4235 Register Idx = getOrCreateVReg(*CI);
4243 Register Idx = getOrCreateVReg(*CI);
4244 auto ScaledIndex = MIRBuilder.
buildMul(
4245 VecIdxTy, MIRBuilder.
buildVScale(VecIdxTy, 1), Idx);
4255bool IRTranslatorImpl::translateShuffleVector(
const User &U,
4261 if (
U.getOperand(0)->getType()->isScalableTy()) {
4262 Register Val = getOrCreateVReg(*
U.getOperand(0));
4264 MRI->getType(Val).getElementType(), Val, 0);
4271 Mask = SVI->getShuffleMask();
4282 unsigned M =
Mask[0];
4284 if (M == 0 || M == 1)
4285 return translateCopy(U, *
U.getOperand(M), MIRBuilder);
4291 Dst, getOrCreateVReg(*
U.getOperand(0)), M);
4292 }
else if (M < SrcElts * 2) {
4294 Dst, getOrCreateVReg(*
U.getOperand(1)), M - SrcElts);
4306 for (
int M : Mask) {
4308 if (M == 0 || M == 1) {
4309 Ops.push_back(getOrCreateVReg(*
U.getOperand(M)));
4311 if (!
Undef.isValid()) {
4312 Undef = MRI->createGenericVirtualRegister(SrcTy);
4322 ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
4324 .
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
4325 {getOrCreateVReg(*
U.getOperand(0)),
4326 getOrCreateVReg(*
U.getOperand(1))})
4327 .addShuffleMask(MaskAlloc);
4331bool IRTranslatorImpl::translatePHI(
const User &U,
4335 SmallVector<MachineInstr *, 4> Insts;
4336 for (
auto Reg : getOrCreateVRegs(PI)) {
4337 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
4341 PendingPHIs.emplace_back(&PI, std::move(Insts));
4345bool IRTranslatorImpl::translateAtomicCmpXchg(
const User &U,
4349 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4351 auto Res = getOrCreateVRegs(
I);
4354 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4355 Register Cmp = getOrCreateVReg(*
I.getCompareOperand());
4356 Register NewVal = getOrCreateVReg(*
I.getNewValOperand());
4359 OldValRes, SuccessRes, Addr, Cmp, NewVal,
4360 *MF->getMachineMemOperand(
4361 MachinePointerInfo(
I.getPointerOperand()), Flags, MRI->getType(Cmp),
4362 getMemOpAlign(
I),
I.getAAMetadata(),
I.getSyncScopeID(),
4363 I.getSuccessOrdering(),
I.getFailureOrdering()));
4367bool IRTranslatorImpl::translateAtomicRMW(
const User &U,
4369 if (!mayTranslateUserTypes(U))
4373 auto Flags = TLI->getAtomicMemOperandFlags(
I, *DL);
4376 Register Addr = getOrCreateVReg(*
I.getPointerOperand());
4377 Register Val = getOrCreateVReg(*
I.getValOperand());
4379 unsigned Opcode = 0;
4380 switch (
I.getOperation()) {
4384 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
4387 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
4390 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
4393 Opcode = TargetOpcode::G_ATOMICRMW_AND;
4396 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
4399 Opcode = TargetOpcode::G_ATOMICRMW_OR;
4402 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
4405 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
4408 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
4411 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
4414 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
4417 Opcode = TargetOpcode::G_ATOMICRMW_FADD;
4420 Opcode = TargetOpcode::G_ATOMICRMW_FSUB;
4423 Opcode = TargetOpcode::G_ATOMICRMW_FMAX;
4426 Opcode = TargetOpcode::G_ATOMICRMW_FMIN;
4429 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUM;
4432 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUM;
4435 Opcode = TargetOpcode::G_ATOMICRMW_FMAXIMUMNUM;
4438 Opcode = TargetOpcode::G_ATOMICRMW_FMINIMUMNUM;
4441 Opcode = TargetOpcode::G_ATOMICRMW_UINC_WRAP;
4444 Opcode = TargetOpcode::G_ATOMICRMW_UDEC_WRAP;
4447 Opcode = TargetOpcode::G_ATOMICRMW_USUB_COND;
4450 Opcode = TargetOpcode::G_ATOMICRMW_USUB_SAT;
4455 Opcode, Res, Addr, Val,
4456 *MF->getMachineMemOperand(MachinePointerInfo(
I.getPointerOperand()),
4457 Flags, MRI->getType(Val), getMemOpAlign(
I),
4458 I.getAAMetadata(),
I.getSyncScopeID(),
4463bool IRTranslatorImpl::translateFence(
const User &U,
4467 Fence.getSyncScopeID());
4471bool IRTranslatorImpl::translateFreeze(
const User &U,
4477 "Freeze with different source and destination type?");
4479 for (
unsigned I = 0;
I < DstRegs.
size(); ++
I) {
4486void IRTranslatorImpl::finishPendingPhis() {
4489 GISelObserverWrapper WrapperObserver(&
Verifier);
4490 RAIIMFObsDelInstaller ObsInstall(*MF, WrapperObserver);
4492 for (
auto &Phi : PendingPHIs) {
4493 const PHINode *PI =
Phi.first;
4497 MachineBasicBlock *PhiMBB = ComponentPHIs[0]->getParent();
4503 SmallPtrSet<const MachineBasicBlock *, 16> SeenPreds;
4507 for (
auto *Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
4511 for (
unsigned j = 0;
j < ValRegs.
size(); ++
j) {
4512 MachineInstrBuilder MIB(*MF, ComponentPHIs[j]);
4521void IRTranslatorImpl::translateDbgValueRecord(
Value *V,
bool HasArgList,
4527 "Expected inlined-at fields to agree");
4531 if (!V || HasArgList) {
4549 auto *ExprDerefRemoved =
4555 if (translateIfEntryValueArgument(
false, V, Variable, Expression, DL,
4567void IRTranslatorImpl::translateDbgDeclareRecord(
4572 LLVM_DEBUG(
dbgs() <<
"Dropping debug info for " << *Variable <<
"\n");
4577 "Expected inlined-at fields to agree");
4582 MF->setVariableDbgInfo(Variable, Expression,
4583 getOrCreateFrameIndex(*AI), DL);
4587 if (translateIfEntryValueArgument(
true,
Address, Variable,
4599void IRTranslatorImpl::translateDbgInfo(
const Instruction &Inst,
4604 assert(DLR->getLabel() &&
"Missing label");
4605 assert(DLR->getLabel()->isValidLocationForIntrinsic(
4607 "Expected inlined-at fields to agree");
4616 translateDbgDeclareRecord(V, DVR.
hasArgList(), Variable, Expression,
4619 translateDbgValueRecord(V, DVR.
hasArgList(), Variable, Expression,
4624bool IRTranslatorImpl::translate(
const Instruction &Inst) {
4626 CurBuilder->setPCSections(Inst.
getMetadata(LLVMContext::MD_pcsections));
4627 CurBuilder->setMMRAMetadata(Inst.
getMetadata(LLVMContext::MD_mmra));
4629 if (TLI->fallBackToDAGISel(Inst))
4633#define HANDLE_INST(NUM, OPCODE, CLASS) \
4634 case Instruction::OPCODE: \
4635 return translate##OPCODE(Inst, *CurBuilder.get());
4636#include "llvm/IR/Instruction.def"
4645 if (
auto CurrInstDL = CurBuilder->getDL())
4646 EntryBuilder->setDebugLoc(
DebugLoc());
4652 EntryBuilder->buildConstant(
Reg, *CI);
4656 EntryBuilder->buildConstant(
Reg, CB->getValue());
4660 CF = ConstantFP::get(CF->getContext(), CF->getValue());
4661 EntryBuilder->buildFConstant(
Reg, *CF);
4663 EntryBuilder->buildUndef(
Reg);
4665 EntryBuilder->buildConstant(
Reg, 0);
4667 EntryBuilder->buildGlobalValue(
Reg, GV);
4669 Register Addr = getOrCreateVReg(*CPA->getPointer());
4670 Register AddrDisc = getOrCreateVReg(*CPA->getAddrDiscriminator());
4671 EntryBuilder->buildConstantPtrAuth(
Reg, CPA, Addr, AddrDisc);
4673 Constant &Elt = *CAZ->getElementValue(0u);
4675 EntryBuilder->buildSplatVector(
Reg, getOrCreateVReg(Elt));
4679 unsigned NumElts = CAZ->getElementCount().getFixedValue();
4681 return translateCopy(
C, Elt, *EntryBuilder);
4683 EntryBuilder->buildSplatBuildVector(
Reg, getOrCreateVReg(Elt));
4686 if (CV->getNumElements() == 1)
4687 return translateCopy(
C, *CV->getElementAsConstant(0), *EntryBuilder);
4689 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
4690 Constant &Elt = *CV->getElementAsConstant(i);
4691 Ops.push_back(getOrCreateVReg(Elt));
4693 EntryBuilder->buildBuildVector(
Reg,
Ops);
4695 switch(
CE->getOpcode()) {
4696#define HANDLE_INST(NUM, OPCODE, CLASS) \
4697 case Instruction::OPCODE: \
4698 return translate##OPCODE(*CE, *EntryBuilder.get());
4699#include "llvm/IR/Instruction.def"
4704 if (CV->getNumOperands() == 1)
4705 return translateCopy(
C, *CV->getOperand(0), *EntryBuilder);
4707 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
4708 Ops.push_back(getOrCreateVReg(*CV->getOperand(i)));
4710 EntryBuilder->buildBuildVector(
Reg,
Ops);
4712 EntryBuilder->buildBlockAddress(
Reg, BA);
4719bool IRTranslatorImpl::mayTranslateUserTypes(
const User &U)
const {
4720 const TargetMachine &TM = TLI->getTargetMachine();
4729 (!
U.getType()->getScalarType()->isBFloatTy() &&
4731 return V->getType()->getScalarType()->isBFloatTy();
4735bool IRTranslatorImpl::finalizeBasicBlock(
const BasicBlock &BB,
4737 for (
auto &BTB : SL->BitTestCases) {
4740 emitBitTestHeader(BTB, BTB.Parent);
4742 BranchProbability UnhandledProb = BTB.Prob;
4743 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
4744 UnhandledProb -= BTB.Cases[
j].ExtraProb;
4746 MachineBasicBlock *
MBB = BTB.Cases[
j].ThisBB;
4755 MachineBasicBlock *NextMBB;
4756 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4759 NextMBB = BTB.Cases[
j + 1].TargetBB;
4760 }
else if (j + 1 == ej) {
4762 NextMBB = BTB.Default;
4765 NextMBB = BTB.Cases[
j + 1].ThisBB;
4768 emitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
MBB);
4770 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
4774 addMachineCFGPred({BTB.Parent->getBasicBlock(),
4775 BTB.Cases[ej - 1].TargetBB->getBasicBlock()},
4778 BTB.Cases.pop_back();
4784 CFGEdge HeaderToDefaultEdge = {BTB.Parent->getBasicBlock(),
4785 BTB.Default->getBasicBlock()};
4786 addMachineCFGPred(HeaderToDefaultEdge, BTB.Parent);
4787 if (!BTB.ContiguousRange) {
4788 addMachineCFGPred(HeaderToDefaultEdge, BTB.Cases.back().ThisBB);
4791 SL->BitTestCases.clear();
4793 for (
auto &JTCase : SL->JTCases) {
4795 if (!JTCase.first.Emitted)
4796 emitJumpTableHeader(JTCase.second, JTCase.first, JTCase.first.HeaderBB);
4798 emitJumpTable(JTCase.second, JTCase.second.MBB);
4800 SL->JTCases.clear();
4802 for (
auto &SwCase : SL->SwitchCases)
4803 emitSwitchCase(SwCase, &CurBuilder->getMBB(), *CurBuilder);
4804 SL->SwitchCases.clear();
4807 if (SPInfo->shouldEmitSDCheck(BB)) {
4808 bool FunctionBasedInstrumentation =
4809 TLI->getSSPStackGuardCheck(*MF->getFunction().getParent(), *Libcalls);
4810 SPDescriptor.initialize(&BB, &
MBB, FunctionBasedInstrumentation);
4813 if (SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
4816 }
else if (SPDescriptor.shouldEmitStackProtector()) {
4817 MachineBasicBlock *ParentMBB = SPDescriptor.getParentMBB();
4818 MachineBasicBlock *SuccessMBB = SPDescriptor.getSuccessMBB();
4827 ParentMBB, *MF->getSubtarget().getInstrInfo());
4830 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB, SplitPoint,
4834 if (!emitSPDescriptorParent(SPDescriptor, ParentMBB))
4838 MachineBasicBlock *FailureMBB = SPDescriptor.getFailureMBB();
4839 if (FailureMBB->
empty()) {
4840 if (!emitSPDescriptorFailure(SPDescriptor, FailureMBB))
4845 SPDescriptor.resetPerBBState();
4852 CurBuilder->setInsertPt(*ParentBB, ParentBB->
end());
4856 LLT PtrMemTy =
getLLTForMVT(TLI->getPointerMemTy(*DL));
4862 Register StackSlotPtr = CurBuilder->buildFrameIndex(PtrTy, FI).getReg(0);
4869 ->buildLoad(PtrMemTy, StackSlotPtr,
4875 if (
const Function *GuardCheckFn = TLI->getSSPStackGuardCheck(M, *Libcalls)) {
4887 FunctionType *FnTy = GuardCheckFn->getFunctionType();
4888 assert(FnTy->getNumParams() == 1 &&
"Invalid function signature");
4889 ISD::ArgFlagsTy
Flags;
4890 if (GuardCheckFn->hasAttribute(1, Attribute::AttrKind::InReg))
4892 CallLowering::ArgInfo GuardArgInfo(
4893 {GuardVal, FnTy->getParamType(0), {
Flags}});
4895 CallLowering::CallLoweringInfo
Info;
4896 Info.OrigArgs.push_back(GuardArgInfo);
4897 Info.CallConv = GuardCheckFn->getCallingConv();
4900 if (!CLI->lowerCall(MIRBuilder, Info)) {
4901 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector check\n");
4911 Guard = MRI->createGenericVirtualRegister(PtrMemTy);
4912 getStackGuard(Guard, *CurBuilder);
4915 const Value *IRGuard = TLI->getSDagStackGuard(M, *Libcalls);
4916 Register GuardPtr = getOrCreateVReg(*IRGuard);
4919 ->buildLoad(PtrMemTy, GuardPtr,
4938 const RTLIB::LibcallImpl LibcallImpl =
4939 Libcalls->getLibcallImpl(RTLIB::STACKPROTECTOR_CHECK_FAIL);
4940 if (LibcallImpl == RTLIB::Unsupported)
4943 CurBuilder->setInsertPt(*FailureBB, FailureBB->
end());
4945 CallLowering::CallLoweringInfo
Info;
4946 Info.CallConv = Libcalls->getLibcallImplCallingConv(LibcallImpl);
4948 StringRef LibcallName =
4953 if (!CLI->lowerCall(*CurBuilder, Info)) {
4954 LLVM_DEBUG(
dbgs() <<
"Failed to lower call to stack protector fail\n");
4959 const TargetOptions &TargetOpts = TLI->getTargetMachine().Options;
4961 CurBuilder->buildInstr(TargetOpcode::G_TRAP);
4966void IRTranslatorImpl::finalizeFunction() {
4969 PendingPHIs.clear();
4971 FrameIndices.clear();
4972 MachinePreds.clear();
4976 EntryBuilder.reset();
4979 SPDescriptor.resetPerFunctionState();
4992 return CI && CI->isMustTailCall();
5004 ORE = std::make_unique<OptimizationRemarkEmitter>(&
F);
5005 CLI = MF->getSubtarget().getCallLowering();
5006 SPInfo = StackProtectorInfo;
5008 if (CLI->fallBackToDAGISel(*MF)) {
5010 F.getSubprogram(), &
F.getEntryBlock());
5011 R <<
"unable to lower function: "
5012 <<
ore::NV(
"Prototype",
F.getFunctionType());
5029 EntryBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5030 CSEInfo = GetCSEInfo();
5031 EntryBuilder->setCSEInfo(CSEInfo);
5032 CurBuilder = std::make_unique<CSEMIRBuilder>(CurMF);
5033 CurBuilder->setCSEInfo(CSEInfo);
5035 EntryBuilder = std::make_unique<MachineIRBuilder>();
5036 CurBuilder = std::make_unique<MachineIRBuilder>();
5039 CurBuilder->setMF(*MF);
5040 EntryBuilder->setMF(*MF);
5041 MRI = &MF->getRegInfo();
5042 DL = &
F.getDataLayout();
5047 AA = GetAAResults();
5048 FuncInfo.BPI = GetBPI();
5052 FuncInfo.BPI =
nullptr;
5055 LibInfo = LibraryInfo;
5056 Libcalls = LibcallInfo;
5058 FuncInfo.CanLowerReturn = CLI->checkReturnTypeForCallConv(*MF);
5060 SL = std::make_unique<GISelSwitchLowering>(
this, FuncInfo);
5061 SL->init(*TLI, TM, *DL);
5063 assert(PendingPHIs.empty() &&
"stale PHIs");
5067 if (!DL->isLittleEndian() && !CLI->enableBigEndian()) {
5070 F.getSubprogram(), &
F.getEntryBlock());
5071 R <<
"unable to translate in big endian mode";
5082 EntryBuilder->setMBB(*EntryBB);
5084 DebugLoc DbgLoc =
F.getEntryBlock().getFirstNonPHIIt()->getDebugLoc();
5085 SwiftError.setFunction(CurMF);
5086 SwiftError.createEntriesInEntryBlock(DbgLoc);
5088 bool IsVarArg =
F.isVarArg();
5089 bool HasMustTailInVarArgFn =
false;
5092 FuncInfo.MBBMap.resize(
F.getMaxBlockNumber());
5096 MBB = MF->CreateMachineBasicBlock(&BB);
5104 if (!BA->hasZeroLiveUses())
5108 if (!HasMustTailInVarArgFn)
5112 MF->getFrameInfo().setHasMustTailInVarArgFunc(HasMustTailInVarArgFn);
5115 EntryBB->addSuccessor(&getMBB(
F.front()));
5120 if (DL->getTypeStoreSize(Arg.
getType()).isZero())
5125 if (CLI->supportSwiftError() && Arg.hasSwiftErrorAttr()) {
5126 assert(VRegs.
size() == 1 &&
"Too many vregs for Swift error");
5127 SwiftError.setCurrentVReg(EntryBB, SwiftError.getFunctionArg(), VRegs[0]);
5131 if (!CLI->lowerFormalArguments(*EntryBuilder,
F, VRegArgs, FuncInfo)) {
5133 F.getSubprogram(), &
F.getEntryBlock());
5134 R <<
"unable to lower arguments: "
5135 <<
ore::NV(
"Prototype",
F.getFunctionType());
5142 if (EnableCSE && CSEInfo)
5147 DILocationVerifier Verifier;
5155 CurBuilder->setMBB(
MBB);
5156 HasTailCall =
false;
5166 Verifier.setCurrentInst(&Inst);
5170 translateDbgInfo(Inst, *CurBuilder);
5172 if (translate(Inst))
5177 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
5179 if (ORE->allowExtraAnalysis(
"gisel-irtranslator")) {
5180 std::string InstStrStorage;
5184 R <<
": '" << InstStrStorage <<
"'";
5191 if (!finalizeBasicBlock(*BB,
MBB)) {
5193 BB->getTerminator()->getDebugLoc(), BB);
5194 R <<
"unable to translate basic block";
5204 finishPendingPhis();
5206 SwiftError.propagateVRegs();
5211 assert(EntryBB->succ_size() == 1 &&
5212 "Custom BB used for lowering should have only one successor");
5216 "LLVM-IR entry block has a predecessor!?");
5219 NewEntryBB.
splice(NewEntryBB.
begin(), EntryBB, EntryBB->begin(),
5228 EntryBB->removeSuccessor(&NewEntryBB);
5229 MF->remove(EntryBB);
5230 MF->deleteMachineBasicBlock(EntryBB);
5232 assert(&MF->front() == &NewEntryBB &&
5233 "New entry wasn't next in the list of basic block!");
5236 SPInfo->copyToMachineFrameInfo(MF->getFrameInfo());
5246 return Impl->runOnMachineFunction(
5265 *
F.getParent(), Subtarget),
5289 "LibcallLoweringModuleAnalysis must be available for IRTranslator");
5290 Impl->runOnMachineFunction(
5292 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.