79#include "llvm/IR/IntrinsicsWebAssembly.h"
115#define DEBUG_TYPE "isel"
117STATISTIC(NumFastIselFailures,
"Number of instructions fast isel failed on");
118STATISTIC(NumFastIselSuccess,
"Number of instructions fast isel selected");
119STATISTIC(NumFastIselBlocks,
"Number of blocks selected entirely by fast isel");
120STATISTIC(NumDAGBlocks,
"Number of blocks selected using DAG");
121STATISTIC(NumDAGIselRetries,
"Number of times dag isel has to try another path");
122STATISTIC(NumEntryBlocks,
"Number of entry blocks encountered");
124 "Number of entry blocks where fast isel failed to lower arguments");
128 cl::desc(
"Enable abort calls when \"fast\" instruction selection "
129 "fails to lower an instruction: 0 disable the abort, 1 will "
130 "abort but for args, calls and terminators, 2 will also "
131 "abort for argument lowering, and 3 will never fallback "
132 "to SelectionDAG."));
136 cl::desc(
"Emit a diagnostic when \"fast\" instruction selection "
137 "falls back to SelectionDAG."));
141 cl::desc(
"use Machine Branch Probability Info"),
147 cl::desc(
"Only display the basic block whose name "
148 "matches this for all view-*-dags options"));
151 cl::desc(
"Pop up a window to show dags before the first "
152 "dag combine pass"));
155 cl::desc(
"Pop up a window to show dags before legalize types"));
158 cl::desc(
"Pop up a window to show dags before the post "
159 "legalize types dag combine pass"));
162 cl::desc(
"Pop up a window to show dags before legalize"));
165 cl::desc(
"Pop up a window to show dags before the second "
166 "dag combine pass"));
169 cl::desc(
"Pop up a window to show isel dags as they are selected"));
172 cl::desc(
"Pop up a window to show sched dags as they are processed"));
175 cl::desc(
"Pop up a window to show SUnit dags after they are processed"));
200 cl::desc(
"Instruction schedulers available (before register"
222 if (NewOptLevel == SavedOptLevel)
226 LLVM_DEBUG(
dbgs() <<
"\nChanging optimization level for Function "
228 LLVM_DEBUG(
dbgs() <<
"\tBefore: -O" <<
static_cast<int>(SavedOptLevel) <<
" ; After: -O"
229 <<
static_cast<int>(NewOptLevel) <<
"\n");
233 dbgs() <<
"\tFastISel is "
242 LLVM_DEBUG(
dbgs() <<
"\nRestoring optimization level for Function "
245 <<
" ; After: -O" <<
static_cast<int>(SavedOptLevel) <<
"\n");
261 if (
auto *SchedulerCtor = ST.getDAGScheduler(OptLevel)) {
262 return SchedulerCtor(IS, OptLevel);
266 (ST.enableMachineScheduler() && ST.enableMachineSchedDefaultSched()) ||
280 "Unknown sched type!");
299 dbgs() <<
"If a target marks an instruction with "
300 "'usesCustomInserter', it must implement "
301 "TargetLowering::EmitInstrWithCustomInserter!\n";
309 "If a target marks an instruction with 'hasPostISelHook', "
310 "it must implement TargetLowering::AdjustInstrPostInstrSelection!");
361 if (!TT.isWindowsMSVCEnvironment())
369 if (
I.getType()->isFPOrFPVectorTy()) {
373 for (
const auto &
Op :
I.operands()) {
374 if (
Op->getType()->isFPOrFPVectorTy()) {
389 "-fast-isel-abort > 0 requires -fast-isel");
414 LibInfo = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(Fn);
415 GFI = Fn.
hasGC() ? &getAnalysis<GCModuleInfo>().getFunctionInfo(Fn) :
nullptr;
416 ORE = std::make_unique<OptimizationRemarkEmitter>(&Fn);
417 AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(mf.
getFunction());
418 auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
421 BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
425 FnVarLocs = getAnalysis<AssignmentTrackingAnalysis>().getResults();
430 if (
auto *UAPass = getAnalysisIfAvailable<UniformityInfoWrapperPass>())
431 UA = &UAPass->getUniformityInfo();
442 FuncInfo->BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
447 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
468 if (isa<UnreachableInst>(Term) || isa<ReturnInst>(Term))
482 SelectAllBasicBlocks(Fn);
510 MRI.constrainRegClass(To,
MRI.getRegClass(
From));
516 if (!
MRI.use_empty(To))
536 if (Term !=
MBB.
end() && Term->isReturn()) {
545 if (!
FuncInfo->ArgDbgValues.empty())
551 for (
unsigned i = 0, e =
FuncInfo->ArgDbgValues.size(); i != e; ++i) {
553 assert(
MI->getOpcode() != TargetOpcode::DBG_VALUE_LIST &&
554 "Function parameters should not be described by DBG_VALUE_LIST.");
555 bool hasFI =
MI->getDebugOperand(0).isFI();
557 hasFI ?
TRI.getFrameRegister(*
MF) :
MI->getDebugOperand(0).getReg();
558 if (Reg.isPhysical())
565 Def->getParent()->insert(std::next(InsertPos),
MI);
577 if (LDI != LiveInMap.
end()) {
578 assert(!hasFI &&
"There's no handling of frame pointer updating here yet "
582 const MDNode *Variable =
MI->getDebugVariable();
583 const MDNode *Expr =
MI->getDebugExpression();
585 bool IsIndirect =
MI->isIndirectDebugValue();
587 assert(
MI->getDebugOffset().getImm() == 0 &&
588 "DBG_VALUE with nonzero offset");
589 assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(
DL) &&
590 "Expected inlined-at fields to agree");
591 assert(
MI->getOpcode() != TargetOpcode::DBG_VALUE_LIST &&
592 "Didn't expect to see a DBG_VALUE_LIST here");
595 IsIndirect, LDI->second, Variable, Expr);
607 CopyUseMI =
UseMI;
continue;
610 CopyUseMI =
nullptr;
break;
613 TRI.getRegSizeInBits(LDI->second,
MRI) ==
633 for (
const auto &
MBB : *
MF) {
637 for (
const auto &
MI :
MBB) {
640 MI.isStackAligningInlineAsm()) {
643 if (
MI.isInlineAsm()) {
671 if (!R.getLocation().isValid() || ShouldAbort)
672 R << (
" (in function: " + MF.
getName() +
")").str();
696 HadTailCall =
SDB->HasTailCall;
697 SDB->resolveOrClearDbgInfo();
704void SelectionDAGISel::ComputeLiveOutVRegInfo() {
718 if (
Op.getValueType() == MVT::Other &&
Added.insert(
Op.getNode()).second)
725 unsigned DestReg = cast<RegisterSDNode>(
N->getOperand(1))->getReg();
731 EVT SrcVT = Src.getValueType();
737 FuncInfo->AddLiveOutRegInfo(DestReg, NumSignBits, Known);
738 }
while (!Worklist.
empty());
741void SelectionDAGISel::CodeGenAndEmitDAG() {
743 StringRef GroupDescription =
"Instruction Selection and Scheduling";
744 std::string BlockName;
745 bool MatchFilterBB =
false; (void)MatchFilterBB;
748 getAnalysis<TargetTransformInfoWrapperPass>().getTTI(*
FuncInfo->Fn);
757 FuncInfo->MBB->getBasicBlock()->getName());
939 ComputeLiveOutVRegInfo();
949 DoInstructionSelection();
985 if (FirstMBB != LastMBB)
986 SDB->UpdateSplitBlock(FirstMBB, LastMBB);
1008 :
SelectionDAG::DAGUpdateListener(DAG), ISelPosition(isp) {}
1021 void NodeInserted(
SDNode *
N)
override {
1022 SDNode *CurNode = &*ISelPosition;
1023 if (
MDNode *MD = DAG.getPCSections(CurNode))
1024 DAG.addPCSections(
N, MD);
1054 while (!Nodes.
empty()) {
1056 for (
auto *U :
N->uses()) {
1057 auto UId = U->getNodeId();
1070 int InvalidId = -(
N->getNodeId() + 1);
1071 N->setNodeId(InvalidId);
1076 int Id =
N->getNodeId();
1082void SelectionDAGISel::DoInstructionSelection() {
1085 <<
FuncInfo->MBB->getName() <<
"'\n");
1103 ISelUpdater ISU(*
CurDAG, ISelPosition);
1110 SDNode *Node = &*--ISelPosition;
1114 if (Node->use_empty())
1121 while (!Nodes.
empty()) {
1138 "Node has already selected predecessor node");
1155 switch (
Node->getOpcode()) {
1164 ActionVT =
Node->getOperand(1).getValueType();
1167 ActionVT =
Node->getValueType(0);
1175 LLVM_DEBUG(
dbgs() <<
"\nISEL: Starting selection on root node: ";
1191 if (
const IntrinsicInst *EHPtrCall = dyn_cast<IntrinsicInst>(U)) {
1193 if (IID == Intrinsic::eh_exceptionpointer ||
1194 IID == Intrinsic::eh_exceptioncode)
1209 bool IsSingleCatchAllClause =
1214 bool IsCatchLongjmp = CPI->
arg_size() == 0;
1215 if (!IsSingleCatchAllClause && !IsCatchLongjmp) {
1217 bool IntrFound =
false;
1219 if (
const auto *Call = dyn_cast<IntrinsicInst>(U)) {
1221 if (IID == Intrinsic::wasm_landingpad_index) {
1222 Value *IndexArg = Call->getArgOperand(1);
1223 int Index = cast<ConstantInt>(IndexArg)->getZExtValue();
1230 assert(IntrFound &&
"wasm.landingpad.index intrinsic not found!");
1237bool SelectionDAGISel::PrepareEHLandingPad() {
1249 if (
const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->
getFirstNonPHI())) {
1254 assert(EHPhysReg &&
"target lacks exception pointer register");
1256 unsigned VReg =
FuncInfo->getCatchPadExceptionPointerVReg(CPI, PtrRC);
1258 TII->
get(TargetOpcode::COPY), VReg)
1276 if (
auto *RegMask =
TRI.getCustomEHPadPreservedMask(*
MF))
1280 if (
const auto *CPI = dyn_cast<CatchPadInst>(LLVMBB->
getFirstNonPHI()))
1318 TII->
get(TargetOpcode::EH_LABEL))
1327 TII->
get(TargetOpcode::EH_LABEL))
1338 return !
I->mayWriteToMemory() &&
1339 !
I->isTerminator() &&
1340 !isa<DbgInfoIntrinsic>(
I) &&
1352 auto ArgIt = FuncInfo.
ValueMap.find(Arg);
1353 if (ArgIt == FuncInfo.
ValueMap.end())
1355 Register ArgVReg = ArgIt->getSecond();
1359 if (VirtReg == ArgVReg) {
1363 LLVM_DEBUG(
dbgs() <<
"processDbgDeclare: setVariableDbgInfo Var=" << *Var
1364 <<
", Expr=" << *Expr <<
", MCRegister=" << PhysReg
1365 <<
", DbgLoc=" << DbgLoc <<
"\n");
1376 <<
" (bad address)\n");
1386 assert(Var &&
"Missing variable");
1387 assert(DbgLoc &&
"Missing location");
1397 int FI = std::numeric_limits<int>::max();
1398 if (
const auto *AI = dyn_cast<AllocaInst>(
Address)) {
1402 }
else if (
const auto *Arg = dyn_cast<Argument>(
Address))
1405 if (FI == std::numeric_limits<int>::max())
1408 if (
Offset.getBoolValue())
1412 LLVM_DEBUG(
dbgs() <<
"processDbgDeclare: setVariableDbgInfo Var=" << *Var
1413 <<
", Expr=" << *Expr <<
", FI=" << FI
1414 <<
", DbgLoc=" << DbgLoc <<
"\n");
1423 const auto *DI = dyn_cast<DbgDeclareInst>(&
I);
1425 DI->getVariable(), DI->getDebugLoc()))
1438 assert(!It->Values.hasArgList() &&
"Single loc variadic ops not supported");
1444void SelectionDAGISel::SelectAllBasicBlocks(
const Function &Fn) {
1474 ++NumFastIselFailLowerArguments;
1479 R <<
"FastISel didn't lower all arguments: "
1487 CodeGenAndEmitDAG();
1501 if (FastIS && Inserted)
1506 "expected AssignmentTrackingAnalysis pass results");
1516 bool AllPredsVisited =
true;
1518 if (!
FuncInfo->VisitedBBs.count(Pred)) {
1519 AllPredsVisited =
false;
1524 if (AllPredsVisited) {
1526 FuncInfo->ComputePHILiveOutRegInfo(&PN);
1529 FuncInfo->InvalidatePHILiveOutRegInfo(&PN);
1532 FuncInfo->VisitedBBs.insert(LLVMBB);
1548 FuncInfo->ExceptionPointerVirtReg = 0;
1549 FuncInfo->ExceptionSelectorVirtReg = 0;
1551 if (!PrepareEHLandingPad())
1559 unsigned NumFastIselRemaining = std::distance(Begin,
End);
1565 for (; BI != Begin; --BI) {
1571 --NumFastIselRemaining;
1581 --NumFastIselRemaining;
1582 ++NumFastIselSuccess;
1587 while (BeforeInst != &*Begin) {
1592 if (BeforeInst != Inst && isa<LoadInst>(BeforeInst) &&
1597 <<
"FastISel folded load: " << *BeforeInst <<
"\n");
1599 --NumFastIselRemaining;
1600 ++NumFastIselSuccess;
1612 if (isa<CallInst>(Inst) && !isa<GCStatepointInst>(Inst) &&
1613 !isa<GCRelocateInst>(Inst) && !isa<GCResultInst>(Inst)) {
1617 R <<
"FastISel missed call";
1620 std::string InstStrStorage;
1624 R <<
": " << InstStr.str();
1629 if (!Inst->getType()->isVoidTy() && !Inst->getType()->isTokenTy() &&
1630 !Inst->use_empty()) {
1636 bool HadTailCall =
false;
1638 SelectBasicBlock(Inst->getIterator(), BI, HadTailCall);
1650 unsigned RemainingNow = std::distance(Begin, BI);
1651 NumFastIselFailures += NumFastIselRemaining - RemainingNow;
1652 NumFastIselRemaining = RemainingNow;
1657 Inst->getDebugLoc(), LLVMBB);
1660 if (Inst->isTerminator()) {
1662 R <<
"FastISel missed terminator";
1666 R <<
"FastISel missed";
1670 std::string InstStrStorage;
1673 R <<
": " << InstStr.str();
1678 NumFastIselFailures += NumFastIselRemaining;
1686 bool FunctionBasedInstrumentation =
1688 SDB->SPDescriptor.initialize(LLVMBB,
FuncInfo->MBBMap[LLVMBB],
1689 FunctionBasedInstrumentation);
1695 ++NumFastIselBlocks;
1702 SelectBasicBlock(Begin, BI, HadTailCall);
1714 FuncInfo->PHINodesToUpdate.clear();
1720 reportIPToStateForBlocks(
MF);
1727 SDB->clearDanglingDebugInfo();
1728 SDB->SPDescriptor.resetPerFunctionState();
1732SelectionDAGISel::FinishBasicBlock() {
1734 <<
FuncInfo->PHINodesToUpdate.size() <<
"\n";
1735 for (
unsigned i = 0, e =
FuncInfo->PHINodesToUpdate.size(); i != e;
1737 <<
"Node " << i <<
" : (" <<
FuncInfo->PHINodesToUpdate[i].first
1738 <<
", " <<
FuncInfo->PHINodesToUpdate[i].second <<
")\n");
1742 for (
unsigned i = 0, e =
FuncInfo->PHINodesToUpdate.size(); i != e; ++i) {
1745 "This is not a machine PHI node that we are updating!");
1746 if (!
FuncInfo->MBB->isSuccessor(
PHI->getParent()))
1752 if (
SDB->SPDescriptor.shouldEmitFunctionBasedCheckStackProtector()) {
1761 SDB->visitSPDescriptorParent(
SDB->SPDescriptor, ParentMBB);
1764 CodeGenAndEmitDAG();
1767 SDB->SPDescriptor.resetPerBBState();
1768 }
else if (
SDB->SPDescriptor.shouldEmitStackProtector()) {
1782 SuccessMBB->
splice(SuccessMBB->
end(), ParentMBB,
1789 SDB->visitSPDescriptorParent(
SDB->SPDescriptor, ParentMBB);
1792 CodeGenAndEmitDAG();
1796 if (FailureMBB->
empty()) {
1799 SDB->visitSPDescriptorFailure(
SDB->SPDescriptor);
1802 CodeGenAndEmitDAG();
1806 SDB->SPDescriptor.resetPerBBState();
1810 for (
auto &BTB :
SDB->SL->BitTestCases) {
1820 CodeGenAndEmitDAG();
1824 for (
unsigned j = 0, ej = BTB.Cases.size(); j != ej; ++j) {
1825 UnhandledProb -= BTB.Cases[
j].ExtraProb;
1840 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
1843 NextMBB = BTB.Cases[
j + 1].TargetBB;
1844 }
else if (j + 1 == ej) {
1846 NextMBB = BTB.Default;
1849 NextMBB = BTB.Cases[
j + 1].ThisBB;
1852 SDB->visitBitTestCase(BTB, NextMBB, UnhandledProb, BTB.Reg, BTB.Cases[j],
1857 CodeGenAndEmitDAG();
1859 if ((BTB.ContiguousRange || BTB.FallthroughUnreachable) && j + 2 == ej) {
1861 BTB.Cases.pop_back();
1867 for (
const std::pair<MachineInstr *, unsigned> &
P :
1872 "This is not a machine PHI node that we are updating!");
1875 if (PHIBB == BTB.Default) {
1876 PHI.addReg(
P.second).addMBB(BTB.Parent);
1877 if (!BTB.ContiguousRange) {
1878 PHI.addReg(
P.second).addMBB(BTB.Cases.back().ThisBB);
1885 PHI.addReg(
P.second).addMBB(cBB);
1889 SDB->SL->BitTestCases.clear();
1894 for (
unsigned i = 0, e =
SDB->SL->JTCases.size(); i != e; ++i) {
1896 if (!
SDB->SL->JTCases[i].first.Emitted) {
1898 FuncInfo->MBB =
SDB->SL->JTCases[i].first.HeaderBB;
1901 SDB->visitJumpTableHeader(
SDB->SL->JTCases[i].second,
1905 CodeGenAndEmitDAG();
1912 SDB->visitJumpTable(
SDB->SL->JTCases[i].second);
1915 CodeGenAndEmitDAG();
1918 for (
unsigned pi = 0, pe =
FuncInfo->PHINodesToUpdate.size();
1923 "This is not a machine PHI node that we are updating!");
1925 if (PHIBB ==
SDB->SL->JTCases[i].second.Default)
1927 .addMBB(
SDB->SL->JTCases[i].first.HeaderBB);
1929 if (
FuncInfo->MBB->isSuccessor(PHIBB))
1933 SDB->SL->JTCases.clear();
1937 for (
unsigned i = 0, e =
SDB->SL->SwitchCases.size(); i != e; ++i) {
1945 if (
SDB->SL->SwitchCases[i].TrueBB !=
SDB->SL->SwitchCases[i].FalseBB)
1952 CodeGenAndEmitDAG();
1962 for (
unsigned i = 0, e = Succs.
size(); i != e; ++i) {
1973 for (
unsigned pn = 0; ; ++pn) {
1975 "Didn't find PHI entry!");
1976 if (
FuncInfo->PHINodesToUpdate[pn].first ==
PHI) {
1977 PHI.addReg(
FuncInfo->PHINodesToUpdate[pn].second).addMBB(ThisBB);
1985 SDB->SL->SwitchCases.clear();
2006 int64_t DesiredMaskS)
const {
2007 const APInt &ActualMask =
RHS->getAPIntValue();
2008 const APInt &DesiredMask =
APInt(
LHS.getValueSizeInBits(), DesiredMaskS);
2011 if (ActualMask == DesiredMask)
2020 APInt NeededMask = DesiredMask & ~ActualMask;
2035 int64_t DesiredMaskS)
const {
2036 const APInt &ActualMask =
RHS->getAPIntValue();
2037 const APInt &DesiredMask =
APInt(
LHS.getValueSizeInBits(), DesiredMaskS);
2040 if (ActualMask == DesiredMask)
2049 APInt NeededMask = DesiredMask & ~ActualMask;
2066 std::vector<SDValue> InOps;
2075 if (InOps[e-1].getValueType() == MVT::Glue)
2079 InlineAsm::Flag Flags(cast<ConstantSDNode>(InOps[i])->getZExtValue());
2080 if (!Flags.isMemKind() && !Flags.isFuncKind()) {
2082 Ops.insert(Ops.end(), InOps.begin() + i,
2083 InOps.begin() + i + Flags.getNumOperandRegisters() + 1);
2084 i += Flags.getNumOperandRegisters() + 1;
2086 assert(Flags.getNumOperandRegisters() == 1 &&
2087 "Memory operand with multiple values?");
2089 unsigned TiedToOperand;
2090 if (Flags.isUseOperandTiedToDef(TiedToOperand)) {
2095 for (; TiedToOperand; --TiedToOperand) {
2096 CurOp += Flags.getNumOperandRegisters() + 1;
2098 cast<ConstantSDNode>(InOps[CurOp])->getZExtValue());
2103 std::vector<SDValue> SelOps;
2105 Flags.getMemoryConstraintID();
2114 Flags.setMemConstraint(ConstraintID);
2122 if (e != InOps.size())
2123 Ops.push_back(InOps.back());
2130 unsigned FlagResNo =
N->getNumValues()-1;
2133 if (
Use.getResNo() == FlagResNo)
2142 bool IgnoreChains) {
2151 Visited.
insert(ImmedUse);
2156 if ((
Op.getValueType() == MVT::Other && IgnoreChains) ||
N == Def)
2158 if (!Visited.
insert(
N).second)
2164 if (Root != ImmedUse) {
2168 if ((
Op.getValueType() == MVT::Other && IgnoreChains) ||
N == Def)
2170 if (!Visited.
insert(
N).second)
2185 return N.hasOneUse();
2192 bool IgnoreChains) {
2241 while (VT == MVT::Glue) {
2252 IgnoreChains =
false;
2258void SelectionDAGISel::Select_INLINEASM(
SDNode *
N) {
2261 std::vector<SDValue> Ops(
N->op_begin(),
N->op_end());
2264 const EVT VTs[] = {MVT::Other, MVT::Glue};
2271void SelectionDAGISel::Select_READ_REGISTER(
SDNode *
Op) {
2276 EVT VT =
Op->getValueType(0);
2282 Op->getOperand(0), dl, Reg,
Op->getValueType(0));
2288void SelectionDAGISel::Select_WRITE_REGISTER(
SDNode *
Op) {
2293 EVT VT =
Op->getOperand(2).getValueType();
2299 Op->getOperand(0), dl, Reg,
Op->getOperand(2));
2305void SelectionDAGISel::Select_UNDEF(
SDNode *
N) {
2309void SelectionDAGISel::Select_FREEZE(
SDNode *
N) {
2317void SelectionDAGISel::Select_ARITH_FENCE(
SDNode *
N) {
2322void SelectionDAGISel::Select_MEMBARRIER(
SDNode *
N) {
2346void SelectionDAGISel::Select_STACKMAP(
SDNode *
N) {
2348 auto *It =
N->op_begin();
2357 assert(
ID.getValueType() == MVT::i64);
2366 for (; It !=
N->op_end(); It++)
2367 pushStackMapLiveVariable(Ops, *It,
DL);
2376void SelectionDAGISel::Select_PATCHPOINT(
SDNode *
N) {
2378 auto *It =
N->op_begin();
2383 std::optional<SDValue> Glue;
2384 if (It->getValueType() == MVT::Glue)
2390 assert(
ID.getValueType() == MVT::i64);
2410 for (
uint64_t I = cast<ConstantSDNode>(NumArgs)->getZExtValue();
I != 0;
I--)
2414 for (; It !=
N->op_end(); It++)
2415 pushStackMapLiveVariable(Ops, *It,
DL);
2420 if (Glue.has_value())
2430 assert(Val >= 128 &&
"Not a VBR");
2436 NextBits = MatcherTable[
Idx++];
2437 Val |= (NextBits&127) << Shift;
2439 }
while (NextBits & 128);
2444void SelectionDAGISel::Select_JUMP_TABLE_DEBUG_INFO(
SDNode *
N) {
2448 dl, MVT::i64,
true));
2453void SelectionDAGISel::UpdateChains(
2460 if (!ChainNodesMatched.
empty()) {
2462 "Matched input chains but didn't produce a chain");
2465 for (
unsigned i = 0, e = ChainNodesMatched.
size(); i != e; ++i) {
2466 SDNode *ChainNode = ChainNodesMatched[i];
2473 "Deleted node left in chain");
2477 if (ChainNode == NodeToMatch && isMorphNodeTo)
2486 std::replace(ChainNodesMatched.
begin(), ChainNodesMatched.
end(),
N,
2487 static_cast<SDNode *
>(
nullptr));
2493 if (ChainNode != NodeToMatch && ChainNode->
use_empty() &&
2499 if (!NowDeadNodes.
empty())
2518 unsigned int Max = 8192;
2521 if (ChainNodesMatched.
size() == 1)
2522 return ChainNodesMatched[0]->getOperand(0);
2526 std::function<void(
const SDValue)> AddChains = [&](
const SDValue V) {
2527 if (V.getValueType() != MVT::Other)
2531 if (!Visited.
insert(V.getNode()).second)
2534 for (
const SDValue &
Op : V->op_values())
2540 for (
auto *
N : ChainNodesMatched) {
2545 while (!Worklist.
empty())
2549 if (InputChains.
size() == 0)
2559 for (
auto *
N : ChainNodesMatched)
2564 if (InputChains.
size() == 1)
2565 return InputChains[0];
2567 MVT::Other, InputChains);
2571SDNode *SelectionDAGISel::
2580 int OldGlueResultNo = -1, OldChainResultNo = -1;
2582 unsigned NTMNumResults =
Node->getNumValues();
2583 if (
Node->getValueType(NTMNumResults-1) == MVT::Glue) {
2584 OldGlueResultNo = NTMNumResults-1;
2585 if (NTMNumResults != 1 &&
2586 Node->getValueType(NTMNumResults-2) == MVT::Other)
2587 OldChainResultNo = NTMNumResults-2;
2588 }
else if (
Node->getValueType(NTMNumResults-1) == MVT::Other)
2589 OldChainResultNo = NTMNumResults-1;
2607 (
unsigned)OldGlueResultNo != ResNumResults-1)
2609 SDValue(Res, ResNumResults - 1));
2615 if ((EmitNodeInfo &
OPFL_Chain) && OldChainResultNo != -1 &&
2616 (
unsigned)OldChainResultNo != ResNumResults-1)
2618 SDValue(Res, ResNumResults - 1));
2636 unsigned RecNo = MatcherTable[MatcherIndex++];
2637 assert(RecNo < RecordedNodes.size() &&
"Invalid CheckSame");
2638 return N == RecordedNodes[RecNo].first;
2643 const unsigned char *MatcherTable,
unsigned &MatcherIndex,
SDValue N,
2646 if (ChildNo >=
N.getNumOperands())
2648 return ::CheckSame(MatcherTable, MatcherIndex,
N.getOperand(ChildNo),
2656 unsigned PredNo = MatcherTable[MatcherIndex++];
2658 PredNo |= MatcherTable[MatcherIndex++] << 8;
2672 uint16_t Opc = MatcherTable[MatcherIndex++];
2673 Opc |= (
unsigned short)MatcherTable[MatcherIndex++] << 8;
2674 return N->getOpcode() == Opc;
2681 if (
N.getValueType() == VT)
return true;
2691 if (ChildNo >=
N.getNumOperands())
2693 return ::CheckType(MatcherTable, MatcherIndex,
N.getOperand(ChildNo), TLI,
2700 return cast<CondCodeSDNode>(
N)->get() ==
2707 if (2 >=
N.getNumOperands())
2709 return ::CheckCondCode(MatcherTable, MatcherIndex,
N.getOperand(2));
2716 if (cast<VTSDNode>(
N)->getVT() == VT)
2720 return VT == MVT::iPTR && cast<VTSDNode>(
N)->getVT() == TLI->
getPointerTy(
DL);
2737 int64_t Val = MatcherTable[MatcherIndex++];
2739 Val =
GetVBR(Val, MatcherTable, MatcherIndex);
2744 return C &&
C->getSExtValue() == Val;
2750 if (ChildNo >=
N.getNumOperands())
2752 return ::CheckInteger(MatcherTable, MatcherIndex,
N.getOperand(ChildNo));
2758 int64_t Val = MatcherTable[MatcherIndex++];
2760 Val =
GetVBR(Val, MatcherTable, MatcherIndex);
2762 if (
N->getOpcode() !=
ISD::AND)
return false;
2771 int64_t Val = MatcherTable[MatcherIndex++];
2773 Val =
GetVBR(Val, MatcherTable, MatcherIndex);
2775 if (
N->getOpcode() !=
ISD::OR)
return false;
2792 switch (Table[
Index++]) {
2809 Table,
Index, SDISel,
2823 unsigned Res = Table[
Index++];
2880 unsigned NumRecordedNodes;
2883 unsigned NumMatchedMemRefs;
2886 SDValue InputChain, InputGlue;
2889 bool HasChainNodesMatched;
2906 :
SelectionDAG::DAGUpdateListener(DAG), NodeToMatch(NodeToMatch),
2907 RecordedNodes(
RN), MatchScopes(MS) {}
2915 if (!
E ||
E->isMachineOpcode())
2918 if (
N == *NodeToMatch)
2923 for (
auto &
I : RecordedNodes)
2924 if (
I.first.getNode() ==
N)
2927 for (
auto &
I : MatchScopes)
2928 for (
auto &J :
I.NodeStack)
2929 if (J.getNode() ==
N)
2937 const unsigned char *MatcherTable,
2938 unsigned TableSize) {
2977 Select_INLINEASM(NodeToMatch);
2980 Select_READ_REGISTER(NodeToMatch);
2983 Select_WRITE_REGISTER(NodeToMatch);
2986 Select_UNDEF(NodeToMatch);
2989 Select_FREEZE(NodeToMatch);
2992 Select_ARITH_FENCE(NodeToMatch);
2995 Select_MEMBARRIER(NodeToMatch);
2998 Select_STACKMAP(NodeToMatch);
3001 Select_PATCHPOINT(NodeToMatch);
3004 Select_JUMP_TABLE_DEBUG_INFO(NodeToMatch);
3031 SDValue InputChain, InputGlue;
3045 unsigned MatcherIndex = 0;
3047 if (!OpcodeOffset.empty()) {
3049 if (
N.getOpcode() < OpcodeOffset.size())
3050 MatcherIndex = OpcodeOffset[
N.getOpcode()];
3051 LLVM_DEBUG(
dbgs() <<
" Initial Opcode index to " << MatcherIndex <<
"\n");
3060 unsigned CaseSize = MatcherTable[
Idx++];
3062 CaseSize =
GetVBR(CaseSize, MatcherTable,
Idx);
3063 if (CaseSize == 0)
break;
3067 Opc |= (
unsigned short)MatcherTable[
Idx++] << 8;
3068 if (Opc >= OpcodeOffset.size())
3069 OpcodeOffset.resize((Opc+1)*2);
3070 OpcodeOffset[Opc] =
Idx;
3075 if (
N.getOpcode() < OpcodeOffset.size())
3076 MatcherIndex = OpcodeOffset[
N.getOpcode()];
3080 assert(MatcherIndex < TableSize &&
"Invalid index");
3082 unsigned CurrentOpcodeIndex = MatcherIndex;
3095 unsigned NumToSkip = MatcherTable[MatcherIndex++];
3096 if (NumToSkip & 128)
3097 NumToSkip =
GetVBR(NumToSkip, MatcherTable, MatcherIndex);
3099 if (NumToSkip == 0) {
3104 FailIndex = MatcherIndex+NumToSkip;
3106 unsigned MatcherIndexOfPredicate = MatcherIndex;
3107 (void)MatcherIndexOfPredicate;
3114 Result, *
this, RecordedNodes);
3119 dbgs() <<
" Skipped scope entry (due to false predicate) at "
3120 <<
"index " << MatcherIndexOfPredicate <<
", continuing at "
3121 << FailIndex <<
"\n");
3122 ++NumDAGIselRetries;
3126 MatcherIndex = FailIndex;
3130 if (FailIndex == 0)
break;
3134 MatchScope NewEntry;
3135 NewEntry.FailIndex = FailIndex;
3136 NewEntry.NodeStack.append(NodeStack.
begin(), NodeStack.
end());
3137 NewEntry.NumRecordedNodes = RecordedNodes.
size();
3138 NewEntry.NumMatchedMemRefs = MatchedMemRefs.
size();
3139 NewEntry.InputChain = InputChain;
3140 NewEntry.InputGlue = InputGlue;
3141 NewEntry.HasChainNodesMatched = !ChainNodesMatched.
empty();
3147 SDNode *Parent =
nullptr;
3148 if (NodeStack.
size() > 1)
3149 Parent = NodeStack[NodeStack.
size()-2].getNode();
3150 RecordedNodes.
push_back(std::make_pair(
N, Parent));
3159 if (ChildNo >=
N.getNumOperands())
3162 RecordedNodes.
push_back(std::make_pair(
N->getOperand(ChildNo),
3167 if (
auto *MN = dyn_cast<MemSDNode>(
N))
3168 MatchedMemRefs.
push_back(MN->getMemOperand());
3178 if (
N->getNumOperands() != 0 &&
3179 N->getOperand(
N->getNumOperands()-1).getValueType() == MVT::Glue)
3180 InputGlue =
N->getOperand(
N->getNumOperands()-1);
3184 unsigned ChildNo = MatcherTable[MatcherIndex++];
3185 if (ChildNo >=
N.getNumOperands())
3187 N =
N.getOperand(ChildNo);
3197 if (ChildNo >=
N.getNumOperands())
3199 N =
N.getOperand(ChildNo);
3207 assert(!NodeStack.
empty() &&
"Node stack imbalance!");
3208 N = NodeStack.
back();
3212 if (!
::CheckSame(MatcherTable, MatcherIndex,
N, RecordedNodes))
break;
3234 unsigned OpNum = MatcherTable[MatcherIndex++];
3237 for (
unsigned i = 0; i < OpNum; ++i)
3238 Operands.push_back(RecordedNodes[MatcherTable[MatcherIndex++]].first);
3240 unsigned PredNo = MatcherTable[MatcherIndex++];
3246 unsigned CPNum = MatcherTable[MatcherIndex++];
3247 unsigned RecNo = MatcherTable[MatcherIndex++];
3248 assert(RecNo < RecordedNodes.
size() &&
"Invalid CheckComplexPat");
3252 std::unique_ptr<MatchStateUpdater> MSU;
3254 MSU.reset(
new MatchStateUpdater(*
CurDAG, &NodeToMatch, RecordedNodes,
3258 RecordedNodes[RecNo].first, CPNum,
3264 if (!
::CheckOpcode(MatcherTable, MatcherIndex,
N.getNode()))
break;
3274 unsigned Res = MatcherTable[MatcherIndex++];
3282 unsigned CurNodeOpcode =
N.getOpcode();
3283 unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart;
3287 CaseSize = MatcherTable[MatcherIndex++];
3289 CaseSize =
GetVBR(CaseSize, MatcherTable, MatcherIndex);
3290 if (CaseSize == 0)
break;
3292 uint16_t Opc = MatcherTable[MatcherIndex++];
3293 Opc |= (
unsigned short)MatcherTable[MatcherIndex++] << 8;
3296 if (CurNodeOpcode == Opc)
3300 MatcherIndex += CaseSize;
3304 if (CaseSize == 0)
break;
3307 LLVM_DEBUG(
dbgs() <<
" OpcodeSwitch from " << SwitchStart <<
" to "
3308 << MatcherIndex <<
"\n");
3313 MVT CurNodeVT =
N.getSimpleValueType();
3314 unsigned SwitchStart = MatcherIndex-1; (void)SwitchStart;
3318 CaseSize = MatcherTable[MatcherIndex++];
3320 CaseSize =
GetVBR(CaseSize, MatcherTable, MatcherIndex);
3321 if (CaseSize == 0)
break;
3324 if (CaseVT == MVT::iPTR)
3328 if (CurNodeVT == CaseVT)
3332 MatcherIndex += CaseSize;
3336 if (CaseSize == 0)
break;
3340 <<
"] from " << SwitchStart <<
" to " << MatcherIndex
3377 if (!
::CheckOrImm(MatcherTable, MatcherIndex,
N, *
this))
break;
3389 assert(NodeStack.
size() != 1 &&
"No parent node");
3392 bool HasMultipleUses =
false;
3393 for (
unsigned i = 1, e = NodeStack.
size()-1; i != e; ++i) {
3394 unsigned NNonChainUses = 0;
3395 SDNode *NS = NodeStack[i].getNode();
3397 if (UI.getUse().getValueType() != MVT::Other)
3398 if (++NNonChainUses > 1) {
3399 HasMultipleUses =
true;
3402 if (HasMultipleUses)
break;
3404 if (HasMultipleUses)
break;
3421 int64_t Val = MatcherTable[MatcherIndex++];
3423 Val =
GetVBR(Val, MatcherTable, MatcherIndex);
3426 RecordedNodes.
push_back(std::pair<SDValue, SDNode*>(
3434 unsigned RegNo = MatcherTable[MatcherIndex++];
3435 RecordedNodes.
push_back(std::pair<SDValue, SDNode*>(
3445 unsigned RegNo = MatcherTable[MatcherIndex++];
3446 RegNo |= MatcherTable[MatcherIndex++] << 8;
3447 RecordedNodes.
push_back(std::pair<SDValue, SDNode*>(
3454 unsigned RecNo = MatcherTable[MatcherIndex++];
3455 assert(RecNo < RecordedNodes.
size() &&
"Invalid EmitConvertToTarget");
3456 SDValue Imm = RecordedNodes[RecNo].first;
3459 const ConstantInt *Val=cast<ConstantSDNode>(Imm)->getConstantIntValue();
3461 Imm.getValueType());
3463 const ConstantFP *Val=cast<ConstantFPSDNode>(Imm)->getConstantFPValue();
3465 Imm.getValueType());
3468 RecordedNodes.
push_back(std::make_pair(Imm, RecordedNodes[RecNo].second));
3477 "EmitMergeInputChains should be the first chain producing node");
3479 "Should only have one EmitMergeInputChains per match");
3483 assert(RecNo < RecordedNodes.
size() &&
"Invalid EmitMergeInputChains");
3484 ChainNodesMatched.
push_back(RecordedNodes[RecNo].first.getNode());
3490 if (ChainNodesMatched.
back() != NodeToMatch &&
3491 !RecordedNodes[RecNo].first.hasOneUse()) {
3492 ChainNodesMatched.
clear();
3506 "EmitMergeInputChains should be the first chain producing node");
3513 unsigned NumChains = MatcherTable[MatcherIndex++];
3514 assert(NumChains != 0 &&
"Can't TF zero chains");
3517 "Should only have one EmitMergeInputChains per match");
3520 for (
unsigned i = 0; i != NumChains; ++i) {
3521 unsigned RecNo = MatcherTable[MatcherIndex++];
3522 assert(RecNo < RecordedNodes.
size() &&
"Invalid EmitMergeInputChains");
3523 ChainNodesMatched.
push_back(RecordedNodes[RecNo].first.getNode());
3529 if (ChainNodesMatched.
back() != NodeToMatch &&
3530 !RecordedNodes[RecNo].first.hasOneUse()) {
3531 ChainNodesMatched.
clear();
3537 if (ChainNodesMatched.
empty())
3551 unsigned RecNo = MatcherTable[MatcherIndex++];
3552 assert(RecNo < RecordedNodes.
size() &&
"Invalid EmitCopyToReg");
3553 unsigned DestPhysReg = MatcherTable[MatcherIndex++];
3555 DestPhysReg |= MatcherTable[MatcherIndex++] << 8;
3561 DestPhysReg, RecordedNodes[RecNo].first,
3564 InputGlue = InputChain.
getValue(1);
3569 unsigned XFormNo = MatcherTable[MatcherIndex++];
3570 unsigned RecNo = MatcherTable[MatcherIndex++];
3571 assert(RecNo < RecordedNodes.
size() &&
"Invalid EmitNodeXForm");
3573 RecordedNodes.
push_back(std::pair<SDValue,SDNode*>(Res,
nullptr));
3579 unsigned index = MatcherTable[MatcherIndex++];
3580 index |= (MatcherTable[MatcherIndex++] << 8);
3589 uint16_t TargetOpc = MatcherTable[MatcherIndex++];
3590 TargetOpc |= (
unsigned short)MatcherTable[MatcherIndex++] << 8;
3591 unsigned EmitNodeInfo = MatcherTable[MatcherIndex++];
3601 NumVTs = MatcherTable[MatcherIndex++];
3603 for (
unsigned i = 0; i != NumVTs; ++i) {
3606 if (VT == MVT::iPTR)
3619 if (VTs.
size() == 1)
3621 else if (VTs.
size() == 2)
3627 unsigned NumOps = MatcherTable[MatcherIndex++];
3629 for (
unsigned i = 0; i != NumOps; ++i) {
3630 unsigned RecNo = MatcherTable[MatcherIndex++];
3632 RecNo =
GetVBR(RecNo, MatcherTable, MatcherIndex);
3634 assert(RecNo < RecordedNodes.
size() &&
"Invalid EmitNode");
3635 Ops.
push_back(RecordedNodes[RecNo].first);
3642 FirstOpToCopy += (EmitNodeInfo &
OPFL_Chain) ? 1 : 0;
3644 "Invalid variadic node");
3647 for (
unsigned i = FirstOpToCopy, e = NodeToMatch->
getNumOperands();
3650 if (V.getValueType() == MVT::Glue)
break;
3665 bool MayRaiseFPException =
3674 if (!IsMorphNodeTo) {
3681 for (
unsigned i = 0, e = VTs.
size(); i != e; ++i) {
3682 if (VTs[i] == MVT::Other || VTs[i] == MVT::Glue)
break;
3688 "NodeToMatch was removed partway through selection");
3692 auto &Chain = ChainNodesMatched;
3694 "Chain node replaced during MorphNode");
3697 Res = cast<MachineSDNode>(MorphNode(NodeToMatch, TargetOpc, VTList,
3698 Ops, EmitNodeInfo));
3705 Flags.setNoFPExcept(
true);
3706 Res->setFlags(Flags);
3728 bool mayLoad = MCID.
mayLoad();
3735 if (MMO->isLoad()) {
3738 }
else if (MMO->isStore()) {
3750 <<
" Dropping mem operands\n";
3751 dbgs() <<
" " << (IsMorphNodeTo ?
"Morphed" :
"Created")
3756 if (IsMorphNodeTo) {
3758 UpdateChains(Res, InputChain, ChainNodesMatched,
true);
3768 unsigned NumResults = MatcherTable[MatcherIndex++];
3770 for (
unsigned i = 0; i != NumResults; ++i) {
3771 unsigned ResSlot = MatcherTable[MatcherIndex++];
3773 ResSlot =
GetVBR(ResSlot, MatcherTable, MatcherIndex);
3775 assert(ResSlot < RecordedNodes.
size() &&
"Invalid CompleteMatch");
3776 SDValue Res = RecordedNodes[ResSlot].first;
3778 assert(i < NodeToMatch->getNumValues() &&
3781 "Invalid number of results to complete!");
3787 "invalid replacement");
3792 UpdateChains(NodeToMatch, InputChain, ChainNodesMatched,
false);
3805 "Didn't replace all uses of the node?");
3815 LLVM_DEBUG(
dbgs() <<
" Match failed at index " << CurrentOpcodeIndex
3817 ++NumDAGIselRetries;
3819 if (MatchScopes.
empty()) {
3820 CannotYetSelect(NodeToMatch);
3826 MatchScope &LastScope = MatchScopes.
back();
3827 RecordedNodes.
resize(LastScope.NumRecordedNodes);
3829 NodeStack.
append(LastScope.NodeStack.begin(), LastScope.NodeStack.end());
3830 N = NodeStack.
back();
3832 if (LastScope.NumMatchedMemRefs != MatchedMemRefs.
size())
3833 MatchedMemRefs.
resize(LastScope.NumMatchedMemRefs);
3834 MatcherIndex = LastScope.FailIndex;
3838 InputChain = LastScope.InputChain;
3839 InputGlue = LastScope.InputGlue;
3840 if (!LastScope.HasChainNodesMatched)
3841 ChainNodesMatched.
clear();
3846 unsigned NumToSkip = MatcherTable[MatcherIndex++];
3847 if (NumToSkip & 128)
3848 NumToSkip =
GetVBR(NumToSkip, MatcherTable, MatcherIndex);
3852 if (NumToSkip != 0) {
3853 LastScope.FailIndex = MatcherIndex+NumToSkip;
3867 if (
N->isMachineOpcode()) {
3874 if (
N->isTargetOpcode())
3875 return N->isTargetStrictFPOpcode();
3876 return N->isStrictFPOpcode();
3881 auto *
C = dyn_cast<ConstantSDNode>(
N->getOperand(1));
3886 if (
auto *FN = dyn_cast<FrameIndexSDNode>(
N->getOperand(0))) {
3889 int32_t Off =
C->getSExtValue();
3892 return (Off >= 0) && (((
A.value() - 1) & Off) ==
unsigned(Off));
3897void SelectionDAGISel::CannotYetSelect(
SDNode *
N) {
3900 Msg <<
"Cannot select: ";
3906 Msg <<
"\nIn function: " <<
MF->
getName();
3908 bool HasInputChain =
N->getOperand(0).getValueType() == MVT::Other;
3910 cast<ConstantSDNode>(
N->getOperand(HasInputChain))->getZExtValue();
3911 if (iid < Intrinsic::num_intrinsics)
3914 Msg <<
"target intrinsic %" <<
TII->
getName(iid);
3916 Msg <<
"unknown intrinsic #" << iid;
unsigned const MachineRegisterInfo * MRI
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
MachineInstrBuilder & UseMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
amdgpu AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
BlockVerifier::State From
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines the FastISel class.
Select target instructions out of generic instructions
mir Rename Register Operands
Machine Instruction Scheduler
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckValueType(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const TargetLowering *TLI, const DataLayout &DL)
static cl::opt< bool > ViewSUnitDAGs("view-sunit-dags", cl::Hidden, cl::desc("Pop up a window to show SUnit dags after they are processed"))
static cl::opt< bool > ViewDAGCombineLT("view-dag-combine-lt-dags", cl::Hidden, cl::desc("Pop up a window to show dags before the post " "legalize types dag combine pass"))
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckChildSame(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const SmallVectorImpl< std::pair< SDValue, SDNode * > > &RecordedNodes, unsigned ChildNo)
CheckChildSame - Implements OP_CheckChildXSame.
static uint64_t decodeSignRotatedValue(uint64_t V)
Decode a signed value stored with the sign bit in the LSB for dense VBR encoding.
static cl::opt< bool > ViewISelDAGs("view-isel-dags", cl::Hidden, cl::desc("Pop up a window to show isel dags as they are selected"))
static LLVM_ATTRIBUTE_ALWAYS_INLINE uint64_t GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx)
GetVBR - decode a vbr encoding whose top bit is set.
static void computeUsesMSVCFloatingPoint(const Triple &TT, const Function &F, MachineModuleInfo &MMI)
static void reportFastISelFailure(MachineFunction &MF, OptimizationRemarkEmitter &ORE, OptimizationRemarkMissed &R, bool ShouldAbort)
static cl::opt< bool > ViewDAGCombine2("view-dag-combine2-dags", cl::Hidden, cl::desc("Pop up a window to show dags before the second " "dag combine pass"))
static RegisterScheduler defaultListDAGScheduler("default", "Best scheduler for the target", createDefaultScheduler)
static unsigned IsPredicateKnownToFail(const unsigned char *Table, unsigned Index, SDValue N, bool &Result, const SelectionDAGISel &SDISel, SmallVectorImpl< std::pair< SDValue, SDNode * > > &RecordedNodes)
IsPredicateKnownToFail - If we know how and can do so without pushing a scope, evaluate the current n...
static cl::opt< int > EnableFastISelAbort("fast-isel-abort", cl::Hidden, cl::desc("Enable abort calls when \"fast\" instruction selection " "fails to lower an instruction: 0 disable the abort, 1 will " "abort but for args, calls and terminators, 2 will also " "abort for argument lowering, and 3 will never fallback " "to SelectionDAG."))
static void mapWasmLandingPadIndex(MachineBasicBlock *MBB, const CatchPadInst *CPI)
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckNodePredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex, const SelectionDAGISel &SDISel, SDNode *N)
CheckNodePredicate - Implements OP_CheckNodePredicate.
static void processSingleLocVars(FunctionLoweringInfo &FuncInfo, FunctionVarLocs const *FnVarLocs)
Collect single location variable information generated with assignment tracking.
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N)
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckAndImm(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const SelectionDAGISel &SDISel)
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckOrImm(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const SelectionDAGISel &SDISel)
static cl::opt< bool > UseMBPI("use-mbpi", cl::desc("use Machine Branch Probability Info"), cl::init(true), cl::Hidden)
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckSame(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const SmallVectorImpl< std::pair< SDValue, SDNode * > > &RecordedNodes)
CheckSame - Implements OP_CheckSame.
static bool findNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse, bool IgnoreChains)
findNonImmUse - Return true if "Def" is a predecessor of "Root" via a path beyond "ImmedUse".
static cl::opt< bool > ViewDAGCombine1("view-dag-combine1-dags", cl::Hidden, cl::desc("Pop up a window to show dags before the first " "dag combine pass"))
static bool processIfEntryValueDbgDeclare(FunctionLoweringInfo &FuncInfo, const Value *Arg, DIExpression *Expr, DILocalVariable *Var, DebugLoc DbgLoc)
static cl::opt< bool > ViewSchedDAGs("view-sched-dags", cl::Hidden, cl::desc("Pop up a window to show sched dags as they are processed"))
static void processDbgDeclares(FunctionLoweringInfo &FuncInfo)
Collect llvm.dbg.declare information.
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckChildType(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const TargetLowering *TLI, const DataLayout &DL, unsigned ChildNo)
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckCondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N)
static bool hasExceptionPointerOrCodeUser(const CatchPadInst *CPI)
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckChild2CondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N)
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, const TargetLowering *TLI, const DataLayout &DL)
static cl::opt< bool > ViewLegalizeDAGs("view-legalize-dags", cl::Hidden, cl::desc("Pop up a window to show dags before legalize"))
static cl::opt< bool > ViewLegalizeTypesDAGs("view-legalize-types-dags", cl::Hidden, cl::desc("Pop up a window to show dags before legalize types"))
static SDNode * findGlueUse(SDNode *N)
findGlueUse - Return use of MVT::Glue value produced by the specified SDNode.
static cl::opt< RegisterScheduler::FunctionPassCtor, false, RegisterPassParser< RegisterScheduler > > ISHeuristic("pre-RA-sched", cl::init(&createDefaultScheduler), cl::Hidden, cl::desc("Instruction schedulers available (before register" " allocation):"))
ISHeuristic command line option for instruction schedulers.
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckPatternPredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex, const SelectionDAGISel &SDISel, bool TwoBytePredNo)
CheckPatternPredicate - Implements OP_CheckPatternPredicate.
static cl::opt< bool > EnableFastISelFallbackReport("fast-isel-report-on-fallback", cl::Hidden, cl::desc("Emit a diagnostic when \"fast\" instruction selection " "falls back to SelectionDAG."))
static bool processDbgDeclare(FunctionLoweringInfo &FuncInfo, const Value *Address, DIExpression *Expr, DILocalVariable *Var, DebugLoc DbgLoc)
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckOpcode(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDNode *N)
static LLVM_ATTRIBUTE_ALWAYS_INLINE bool CheckChildInteger(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N, unsigned ChildNo)
static cl::opt< std::string > FilterDAGBasicBlockName("filter-view-dags", cl::Hidden, cl::desc("Only display the basic block whose name " "matches this for all view-*-dags options"))
static SDValue HandleMergeInputChains(SmallVectorImpl< SDNode * > &ChainNodesMatched, SelectionDAG *CurDAG)
HandleMergeInputChains - This implements the OPC_EmitMergeInputChains operation for when the pattern ...
static bool isFoldedOrDeadInstruction(const Instruction *I, const FunctionLoweringInfo &FuncInfo)
isFoldedOrDeadInstruction - Return true if the specified instruction is side-effect free and is eithe...
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
DEMANGLE_DUMP_METHOD void dump() const
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Class for arbitrary precision integers.
bool isSubsetOf(const APInt &RHS) const
This operation checks that all bits set in this APInt are also set in RHS.
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
An immutable pass that tracks lazily created AssumptionCache objects.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
InstListType::const_iterator const_iterator
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
bool isEHPad() const
Return true if this basic block is an exception handling block.
const Instruction * getFirstMayFaultInst() const
Returns the first potential AsynchEH faulty instruction currently it checks for loads/stores (which m...
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Legacy analysis pass which computes BranchProbabilityInfo.
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
static DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
static DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)
Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Diagnostic information for ISel fallback path.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
void setLastLocalValue(MachineInstr *I)
Update the position of the last instruction emitted for materializing constants for use in the curren...
bool tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst)
We're checking to see if we can fold LI into FoldInst.
void removeDeadCode(MachineBasicBlock::iterator I, MachineBasicBlock::iterator E)
Remove all dead instructions between the I and E.
void startNewBlock()
Set the current block to which generated machine instructions will be appended.
bool selectInstruction(const Instruction *I)
Do "fast" instruction selection for the given LLVM IR instruction and append the generated machine in...
void finishBasicBlock()
Flush the local value map.
void recomputeInsertPt()
Reset InsertPt to prepare for inserting instructions into the current block.
bool lowerArguments()
Do "fast" instruction selection for function arguments and append the machine instructions to the cur...
unsigned arg_size() const
arg_size - Return the number of funcletpad arguments.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th funcletpad argument.
FunctionLoweringInfo - This contains information that is global to a function that is used when lower...
DenseMap< const AllocaInst *, int > StaticAllocaMap
StaticAllocaMap - Keep track of frame indices for fixed sized allocas in the entry block.
int getArgumentFrameIndex(const Argument *A)
getArgumentFrameIndex - Get frame index for the byval argument.
bool isExportedInst(const Value *V) const
isExportedInst - Return true if the specified value is an instruction exported from its block.
SmallPtrSet< const DbgDeclareInst *, 8 > PreprocessedDbgDeclares
Collection of dbg.declare instructions handled after argument lowering and before ISel proper.
DenseMap< const Value *, Register > ValueMap
ValueMap - Since we emit code for the function a basic block at a time, we must remember which virtua...
MachineRegisterInfo * RegInfo
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
Data structure describing the variable locations in a function.
const VarLocInfo * single_locs_begin() const
DILocalVariable * getDILocalVariable(const VarLocInfo *Loc) const
Return the DILocalVariable for the location definition represented by ID.
const VarLocInfo * single_locs_end() const
One past the last single-location variable location definition.
const BasicBlock & getEntryBlock() const
FunctionType * getFunctionType() const
Returns the FunctionType for me.
DISubprogram * getSubprogram() const
Get the attached subprogram.
bool hasGC() const
hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm to use during code generatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool callsFunctionThatReturnsTwice() const
callsFunctionThatReturnsTwice - Return true if the function has a call to setjmp or other function th...
An analysis pass which caches information about the entire Module.
Module * getParent()
Get the module that this global value is contained inside of...
This class is used to form a handle around another node that is persistent and is updated across invo...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
A wrapper class for inspecting calls to intrinsic functions.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
static void getLazyBFIAnalysisUsage(AnalysisUsage &AU)
Helper for client passes to set up the analysis usage on behalf of this pass.
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Describe properties that are true of each instruction in the target description file.
bool mayStore() const
Return true if this instruction could possibly modify memory.
bool mayLoad() const
Return true if this instruction could possibly read memory.
bool mayRaiseFPException() const
Return true if this instruction may raise a floating-point exception.
bool isCall() const
Return true if the instruction is a call.
bool isReturn() const
Return true if the instruction is a return.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
const MDNode * getMD() const
const MDOperand & getOperand(unsigned I) const
StringRef getString() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
instr_iterator instr_end()
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.
iterator insertAfter(iterator I, MachineInstr *MI)
Insert MI into the instruction list after I.
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this 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 '...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasCalls() const
Return true if the current function has any function calls.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool hasProperty(Property P) const
const WinEHFuncInfo * getWinEHFuncInfo() const
getWinEHFuncInfo - Return information about how the current function uses Windows exception handling.
bool useDebugInstrRef() const
Returns true if the function's variable locations are tracked with instruction referencing.
void setExposesReturnsTwice(bool B)
setCallsSetJmp - Set a flag that indicates if there's a call to a "returns twice" function.
void setHasInlineAsm(bool B)
Set a flag that indicates that the function contains inline assembly.
void setWasmLandingPadIndex(const MachineBasicBlock *LPad, unsigned Index)
Map the landing pad to its index. Used for Wasm exception handling.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool hasInlineAsm() const
Returns true if the function contains any inline assembly.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void finalizeDebugInstrRefs()
Finalise any partially emitted debug instructions.
void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef< unsigned > Sites)
Map the landing pad's EH symbol to the call site indexes.
void setUseDebugInstrRef(bool UseInstrRef)
Set whether this function will use instruction referencing or not.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
MCSymbol * addLandingPad(MachineBasicBlock *LandingPad)
Add a new panding pad, and extract the exception handling information from the landingpad instruction...
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineModuleInfo & getMMI() const
bool shouldUseDebugInstrRef() const
Determine whether, in the current machine configuration, we should use instruction referencing or not...
const MachineFunctionProperties & getProperties() const
Get the function properties.
void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr, int Slot, const DILocation *Loc)
Collect information used to emit debugging information of a variable in a stack slot.
const MachineBasicBlock & front() const
void print(raw_ostream &OS, const SlotIndexes *=nullptr) const
print - Print out the MachineFunction in a format suitable for debugging to the specified stream.
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
const MachineBasicBlock * getParent() const
bool isDebugValue() const
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
This class contains meta information specific to a module.
const MCContext & getContext() const
bool usesMSVCFloatingPoint() const
void setUsesMSVCFloatingPoint(bool b)
Register getReg() const
getReg - Returns the register number.
MachinePassRegistry - Track the registration of machine passes.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
void EmitLiveInCopies(MachineBasicBlock *EntryMBB, const TargetRegisterInfo &TRI, const TargetInstrInfo &TII)
EmitLiveInCopies - Emit copies to initialize livein virtual registers into the given entry block.
use_instr_iterator use_instr_begin(Register RegNo) const
ArrayRef< std::pair< MCRegister, Register > > liveins() const
static use_instr_iterator use_instr_end()
void addPhysRegsUsedFromRegMask(const uint32_t *RegMask)
addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
An SDNode that represents everything that will be needed to construct a MachineInstr.
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
This class is used by SelectionDAGISel to temporarily override the optimization level on a per-functi...
OptLevelChanger(SelectionDAGISel &ISel, CodeGenOptLevel NewOptLevel)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
RegisterPassParser class - Handle the addition of new machine passes.
ScheduleDAGSDNodes *(*)(SelectionDAGISel *, CodeGenOptLevel) FunctionPassCtor
static MachinePassRegistry< FunctionPassCtor > Registry
RegisterScheduler class - Track the registration of instruction schedulers.
Wrapper class representing virtual and physical registers.
static unsigned virtReg2Index(Register Reg)
Convert a virtual register number to a 0-based index.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static constexpr bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
This class provides iterator support for SDUse operands that use a specific SDNode.
Represents one node in the SelectionDAG.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
iterator_range< value_op_iterator > op_values() const
void setNodeId(int Id)
Set unique node id.
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
bool use_empty() const
Return true if there are no uses of this node.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
static use_iterator use_end()
Represents a use of a SDNode.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.
SelectionDAGBuilder - This is the common target-independent lowering implementation that is parameter...
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
std::unique_ptr< FunctionLoweringInfo > FuncInfo
SmallPtrSet< const Instruction *, 4 > ElidedArgCopyInstrs
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, InlineAsm::ConstraintCode ConstraintID, std::vector< SDValue > &OutOps)
SelectInlineAsmMemoryOperand - Select the specified address as a target addressing mode,...
bool CheckOrMask(SDValue LHS, ConstantSDNode *RHS, int64_t DesiredMaskS) const
CheckOrMask - The isel is trying to match something like (or X, 255).
const TargetLowering * TLI
virtual void PostprocessISelDAG()
PostprocessISelDAG() - This hook allows the target to hack on the graph right after selection.
virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const
CheckNodePredicate - This function is generated by tblgen in the target.
std::unique_ptr< OptimizationRemarkEmitter > ORE
Current optimization remark emitter.
MachineRegisterInfo * RegInfo
unsigned DAGSize
DAGSize - Size of DAG being instruction selected.