aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp624
1 files changed, 456 insertions, 168 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 35abd990f968..a1cf4cbbee1b 100644
--- a/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/contrib/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -78,6 +78,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IntrinsicsWebAssembly.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/IR/PrintPasses.h"
#include "llvm/IR/Statepoint.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
@@ -113,6 +114,7 @@
using namespace llvm;
#define DEBUG_TYPE "isel"
+#define ISEL_DUMP_DEBUG_TYPE DEBUG_TYPE "-dump"
STATISTIC(NumFastIselFailures, "Number of instructions fast isel failed on");
STATISTIC(NumFastIselSuccess, "Number of instructions fast isel selected");
@@ -180,6 +182,19 @@ static const bool ViewDAGCombine1 = false, ViewLegalizeTypesDAGs = false,
ViewSchedDAGs = false, ViewSUnitDAGs = false;
#endif
+#ifndef NDEBUG
+#define ISEL_DUMP(X) \
+ do { \
+ if (llvm::DebugFlag && \
+ (isCurrentDebugType(DEBUG_TYPE) || \
+ (isCurrentDebugType(ISEL_DUMP_DEBUG_TYPE) && MatchFilterFuncName))) { \
+ X; \
+ } \
+ } while (false)
+#else
+#define ISEL_DUMP(X) do { } while (false)
+#endif
+
//===---------------------------------------------------------------------===//
///
/// RegisterScheduler class - Track the registration of instruction schedulers.
@@ -204,6 +219,16 @@ static RegisterScheduler
defaultListDAGScheduler("default", "Best scheduler for the target",
createDefaultScheduler);
+static bool dontUseFastISelFor(const Function &Fn) {
+ // Don't enable FastISel for functions with swiftasync Arguments.
+ // Debug info on those is reliant on good Argument lowering, and FastISel is
+ // not capable of lowering the entire function. Mixing the two selectors tend
+ // to result in poor lowering of Arguments.
+ return any_of(Fn.args(), [](const Argument &Arg) {
+ return Arg.hasAttribute(Attribute::AttrKind::SwiftAsync);
+ });
+}
+
namespace llvm {
//===--------------------------------------------------------------------===//
@@ -211,29 +236,31 @@ namespace llvm {
/// the optimization level on a per-function basis.
class OptLevelChanger {
SelectionDAGISel &IS;
- CodeGenOpt::Level SavedOptLevel;
+ CodeGenOptLevel SavedOptLevel;
bool SavedFastISel;
public:
- OptLevelChanger(SelectionDAGISel &ISel,
- CodeGenOpt::Level NewOptLevel) : IS(ISel) {
+ OptLevelChanger(SelectionDAGISel &ISel, CodeGenOptLevel NewOptLevel)
+ : IS(ISel) {
SavedOptLevel = IS.OptLevel;
SavedFastISel = IS.TM.Options.EnableFastISel;
- if (NewOptLevel == SavedOptLevel)
- return;
- IS.OptLevel = NewOptLevel;
- IS.TM.setOptLevel(NewOptLevel);
- LLVM_DEBUG(dbgs() << "\nChanging optimization level for Function "
- << IS.MF->getFunction().getName() << "\n");
- LLVM_DEBUG(dbgs() << "\tBefore: -O" << SavedOptLevel << " ; After: -O"
- << NewOptLevel << "\n");
- if (NewOptLevel == CodeGenOpt::None) {
- IS.TM.setFastISel(IS.TM.getO0WantsFastISel());
- LLVM_DEBUG(
- dbgs() << "\tFastISel is "
- << (IS.TM.Options.EnableFastISel ? "enabled" : "disabled")
- << "\n");
+ if (NewOptLevel != SavedOptLevel) {
+ IS.OptLevel = NewOptLevel;
+ IS.TM.setOptLevel(NewOptLevel);
+ LLVM_DEBUG(dbgs() << "\nChanging optimization level for Function "
+ << IS.MF->getFunction().getName() << "\n");
+ LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(SavedOptLevel)
+ << " ; After: -O" << static_cast<int>(NewOptLevel)
+ << "\n");
+ if (NewOptLevel == CodeGenOptLevel::None)
+ IS.TM.setFastISel(IS.TM.getO0WantsFastISel());
}
+ if (dontUseFastISelFor(IS.MF->getFunction()))
+ IS.TM.setFastISel(false);
+ LLVM_DEBUG(
+ dbgs() << "\tFastISel is "
+ << (IS.TM.Options.EnableFastISel ? "enabled" : "disabled")
+ << "\n");
}
~OptLevelChanger() {
@@ -241,8 +268,8 @@ namespace llvm {
return;
LLVM_DEBUG(dbgs() << "\nRestoring optimization level for Function "
<< IS.MF->getFunction().getName() << "\n");
- LLVM_DEBUG(dbgs() << "\tBefore: -O" << IS.OptLevel << " ; After: -O"
- << SavedOptLevel << "\n");
+ LLVM_DEBUG(dbgs() << "\tBefore: -O" << static_cast<int>(IS.OptLevel)
+ << " ; After: -O" << static_cast<int>(SavedOptLevel) << "\n");
IS.OptLevel = SavedOptLevel;
IS.TM.setOptLevel(SavedOptLevel);
IS.TM.setFastISel(SavedFastISel);
@@ -252,8 +279,8 @@ namespace llvm {
//===--------------------------------------------------------------------===//
/// createDefaultScheduler - This creates an instruction scheduler appropriate
/// for the target.
- ScheduleDAGSDNodes* createDefaultScheduler(SelectionDAGISel *IS,
- CodeGenOpt::Level OptLevel) {
+ ScheduleDAGSDNodes *createDefaultScheduler(SelectionDAGISel *IS,
+ CodeGenOptLevel OptLevel) {
const TargetLowering *TLI = IS->TLI;
const TargetSubtargetInfo &ST = IS->MF->getSubtarget();
@@ -262,7 +289,7 @@ namespace llvm {
return SchedulerCtor(IS, OptLevel);
}
- if (OptLevel == CodeGenOpt::None ||
+ if (OptLevel == CodeGenOptLevel::None ||
(ST.enableMachineScheduler() && ST.enableMachineSchedDefaultSched()) ||
TLI->getSchedulingPreference() == Sched::Source)
return createSourceListDAGScheduler(IS, OptLevel);
@@ -315,7 +342,7 @@ void TargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
//===----------------------------------------------------------------------===//
SelectionDAGISel::SelectionDAGISel(char &ID, TargetMachine &tm,
- CodeGenOpt::Level OL)
+ CodeGenOptLevel OL)
: MachineFunctionPass(ID), TM(tm), FuncInfo(new FunctionLoweringInfo()),
SwiftError(new SwiftErrorValueTracking()),
CurDAG(new SelectionDAG(tm, OL)),
@@ -335,23 +362,23 @@ SelectionDAGISel::~SelectionDAGISel() {
}
void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
- if (OptLevel != CodeGenOpt::None)
- AU.addRequired<AAResultsWrapperPass>();
+ if (OptLevel != CodeGenOptLevel::None)
+ AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<GCModuleInfo>();
AU.addRequired<StackProtector>();
AU.addPreserved<GCModuleInfo>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
AU.addRequired<AssumptionCacheTracker>();
- if (UseMBPI && OptLevel != CodeGenOpt::None)
- AU.addRequired<BranchProbabilityInfoWrapperPass>();
+ if (UseMBPI && OptLevel != CodeGenOptLevel::None)
+ AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.addRequired<ProfileSummaryInfoWrapperPass>();
// AssignmentTrackingAnalysis only runs if assignment tracking is enabled for
// the module.
AU.addRequired<AssignmentTrackingAnalysis>();
AU.addPreserved<AssignmentTrackingAnalysis>();
- if (OptLevel != CodeGenOpt::None)
- LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
+ if (OptLevel != CodeGenOptLevel::None)
+ LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -391,6 +418,13 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
const Function &Fn = mf.getFunction();
MF = &mf;
+#ifndef NDEBUG
+ StringRef FuncName = Fn.getName();
+ MatchFilterFuncName = isFunctionInPrintList(FuncName);
+#else
+ (void)MatchFilterFuncName;
+#endif
+
// Decide what flavour of variable location debug-info will be used, before
// we change the optimisation level.
bool InstrRef = mf.shouldUseDebugInstrRef();
@@ -403,9 +437,9 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// it wants to look at it.
TM.resetTargetOptions(Fn);
// Reset OptLevel to None for optnone functions.
- CodeGenOpt::Level NewOptLevel = OptLevel;
- if (OptLevel != CodeGenOpt::None && skipFunction(Fn))
- NewOptLevel = CodeGenOpt::None;
+ CodeGenOptLevel NewOptLevel = OptLevel;
+ if (OptLevel != CodeGenOptLevel::None && skipFunction(Fn))
+ NewOptLevel = CodeGenOptLevel::None;
OptLevelChanger OLC(*this, NewOptLevel);
TII = MF->getSubtarget().getInstrInfo();
@@ -417,14 +451,14 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(mf.getFunction());
auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
BlockFrequencyInfo *BFI = nullptr;
- if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOpt::None)
+ if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOptLevel::None)
BFI = &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
FunctionVarLocs const *FnVarLocs = nullptr;
if (isAssignmentTrackingEnabled(*Fn.getParent()))
FnVarLocs = getAnalysis<AssignmentTrackingAnalysis>().getResults();
- LLVM_DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
+ ISEL_DUMP(dbgs() << "\n\n\n=== " << FuncName << "\n");
UniformityInfo *UA = nullptr;
if (auto *UAPass = getAnalysisIfAvailable<UniformityInfoWrapperPass>())
@@ -438,12 +472,12 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// into account). That's unfortunate but OK because it just means we won't
// ask for passes that have been required anyway.
- if (UseMBPI && OptLevel != CodeGenOpt::None)
+ if (UseMBPI && OptLevel != CodeGenOptLevel::None)
FuncInfo->BPI = &getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
else
FuncInfo->BPI = nullptr;
- if (OptLevel != CodeGenOpt::None)
+ if (OptLevel != CodeGenOptLevel::None)
AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
else
AA = nullptr;
@@ -456,7 +490,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// We split CSR if the target supports it for the given function
// and the function has only return exits.
- if (OptLevel != CodeGenOpt::None && TLI->supportSplitCSR(MF)) {
+ if (OptLevel != CodeGenOptLevel::None && TLI->supportSplitCSR(MF)) {
FuncInfo->SplitCSR = true;
// Collect all the return blocks.
@@ -656,8 +690,8 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// at this point.
FuncInfo->clear();
- LLVM_DEBUG(dbgs() << "*** MachineFunction at end of ISel ***\n");
- LLVM_DEBUG(MF->print(dbgs()));
+ ISEL_DUMP(dbgs() << "*** MachineFunction at end of ISel ***\n");
+ ISEL_DUMP(MF->print(dbgs()));
return true;
}
@@ -685,10 +719,13 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock::const_iterator Begin,
CurDAG->NewNodesMustHaveLegalTypes = false;
// Lower the instructions. If a call is emitted as a tail call, cease emitting
- // nodes for this block.
+ // nodes for this block. If an instruction is elided, don't emit it, but do
+ // handle any debug-info attached to it.
for (BasicBlock::const_iterator I = Begin; I != End && !SDB->HasTailCall; ++I) {
if (!ElidedArgCopyInstrs.count(&*I))
SDB->visit(*I);
+ else
+ SDB->visitDbgInfo(*I);
}
// Make sure the root of the DAG is up-to-date.
@@ -765,10 +802,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
BlockName =
(MF->getName() + ":" + FuncInfo->MBB->getBasicBlock()->getName()).str();
}
- LLVM_DEBUG(dbgs() << "Initial selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nInitial selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
@@ -785,10 +822,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(BeforeLegalizeTypes, AA, OptLevel);
}
- LLVM_DEBUG(dbgs() << "Optimized lowered selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nOptimized lowered selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
@@ -807,10 +844,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
Changed = CurDAG->LegalizeTypes();
}
- LLVM_DEBUG(dbgs() << "Type-legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nType-legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
@@ -831,10 +868,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(AfterLegalizeTypes, AA, OptLevel);
}
- LLVM_DEBUG(dbgs() << "Optimized type-legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nOptimized type-legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
@@ -849,10 +886,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
}
if (Changed) {
- LLVM_DEBUG(dbgs() << "Vector-legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nVector-legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
@@ -865,10 +902,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->LegalizeTypes();
}
- LLVM_DEBUG(dbgs() << "Vector/type-legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nVector/type-legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
@@ -885,10 +922,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(AfterLegalizeVectorOps, AA, OptLevel);
}
- LLVM_DEBUG(dbgs() << "Optimized vector-legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nOptimized vector-legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
@@ -905,10 +942,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Legalize();
}
- LLVM_DEBUG(dbgs() << "Legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nLegalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
@@ -925,17 +962,17 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
CurDAG->Combine(AfterLegalizeDAG, AA, OptLevel);
}
- LLVM_DEBUG(dbgs() << "Optimized legalized selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nOptimized legalized selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
#ifndef NDEBUG
if (TTI.hasBranchDivergence())
CurDAG->VerifyDAGDivergence();
#endif
- if (OptLevel != CodeGenOpt::None)
+ if (OptLevel != CodeGenOptLevel::None)
ComputeLiveOutVRegInfo();
if (ViewISelDAGs && MatchFilterBB)
@@ -949,10 +986,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
DoInstructionSelection();
}
- LLVM_DEBUG(dbgs() << "Selected selection DAG: "
- << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
- << "'\n";
- CurDAG->dump());
+ ISEL_DUMP(dbgs() << "\nSelected selection DAG: "
+ << printMBBReference(*FuncInfo->MBB) << " '" << BlockName
+ << "'\n";
+ CurDAG->dump());
if (ViewSchedDAGs && MatchFilterBB)
CurDAG->viewGraph("scheduler input for " + BlockName);
@@ -1357,6 +1394,8 @@ static bool processIfEntryValueDbgDeclare(FunctionLoweringInfo &FuncInfo,
// Find the corresponding livein physical register to this argument.
for (auto [PhysReg, VirtReg] : FuncInfo.RegInfo->liveins())
if (VirtReg == ArgVReg) {
+ // Append an op deref to account for the fact that this is a dbg_declare.
+ Expr = DIExpression::append(Expr, dwarf::DW_OP_deref);
FuncInfo.MF->setVariableDbgInfo(Var, Expr, PhysReg, DbgLoc);
LLVM_DEBUG(dbgs() << "processDbgDeclare: setVariableDbgInfo Var=" << *Var
<< ", Expr=" << *Expr << ", MCRegister=" << PhysReg
@@ -1422,6 +1461,14 @@ static void processDbgDeclares(FunctionLoweringInfo &FuncInfo) {
if (DI && processDbgDeclare(FuncInfo, DI->getAddress(), DI->getExpression(),
DI->getVariable(), DI->getDebugLoc()))
FuncInfo.PreprocessedDbgDeclares.insert(DI);
+
+ for (const DPValue &DPV : I.getDbgValueRange()) {
+ if (DPV.getType() == DPValue::LocationType::Declare &&
+ processDbgDeclare(FuncInfo, DPV.getVariableLocationOp(0),
+ DPV.getExpression(), DPV.getVariable(),
+ DPV.getDebugLoc()))
+ FuncInfo.PreprocessedDPVDeclares.insert(&DPV);
+ }
}
}
@@ -1510,7 +1557,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
// Iterate over all basic blocks in the function.
StackProtector &SP = getAnalysis<StackProtector>();
for (const BasicBlock *LLVMBB : RPOT) {
- if (OptLevel != CodeGenOpt::None) {
+ if (OptLevel != CodeGenOptLevel::None) {
bool AllPredsVisited = true;
for (const BasicBlock *Pred : predecessors(LLVMBB)) {
if (!FuncInfo->VisitedBBs.count(Pred)) {
@@ -2074,41 +2121,43 @@ void SelectionDAGISel::SelectInlineAsmMemoryOperands(std::vector<SDValue> &Ops,
--e; // Don't process a glue operand if it is here.
while (i != e) {
- unsigned Flags = cast<ConstantSDNode>(InOps[i])->getZExtValue();
- if (!InlineAsm::isMemKind(Flags) && !InlineAsm::isFuncKind(Flags)) {
+ InlineAsm::Flag Flags(cast<ConstantSDNode>(InOps[i])->getZExtValue());
+ if (!Flags.isMemKind() && !Flags.isFuncKind()) {
// Just skip over this operand, copying the operands verbatim.
- Ops.insert(Ops.end(), InOps.begin()+i,
- InOps.begin()+i+InlineAsm::getNumOperandRegisters(Flags) + 1);
- i += InlineAsm::getNumOperandRegisters(Flags) + 1;
+ Ops.insert(Ops.end(), InOps.begin() + i,
+ InOps.begin() + i + Flags.getNumOperandRegisters() + 1);
+ i += Flags.getNumOperandRegisters() + 1;
} else {
- assert(InlineAsm::getNumOperandRegisters(Flags) == 1 &&
+ assert(Flags.getNumOperandRegisters() == 1 &&
"Memory operand with multiple values?");
unsigned TiedToOperand;
- if (InlineAsm::isUseOperandTiedToDef(Flags, TiedToOperand)) {
+ if (Flags.isUseOperandTiedToDef(TiedToOperand)) {
// We need the constraint ID from the operand this is tied to.
unsigned CurOp = InlineAsm::Op_FirstOperand;
- Flags = cast<ConstantSDNode>(InOps[CurOp])->getZExtValue();
+ Flags =
+ InlineAsm::Flag(cast<ConstantSDNode>(InOps[CurOp])->getZExtValue());
for (; TiedToOperand; --TiedToOperand) {
- CurOp += InlineAsm::getNumOperandRegisters(Flags)+1;
- Flags = cast<ConstantSDNode>(InOps[CurOp])->getZExtValue();
+ CurOp += Flags.getNumOperandRegisters() + 1;
+ Flags = InlineAsm::Flag(
+ cast<ConstantSDNode>(InOps[CurOp])->getZExtValue());
}
}
// Otherwise, this is a memory operand. Ask the target to select it.
std::vector<SDValue> SelOps;
- unsigned ConstraintID = InlineAsm::getMemoryConstraintID(Flags);
+ const InlineAsm::ConstraintCode ConstraintID =
+ Flags.getMemoryConstraintID();
if (SelectInlineAsmMemoryOperand(InOps[i+1], ConstraintID, SelOps))
report_fatal_error("Could not match memory address. Inline asm"
" failure!");
// Add this to the output node.
- unsigned NewFlags =
- InlineAsm::isMemKind(Flags)
- ? InlineAsm::getFlagWord(InlineAsm::Kind_Mem, SelOps.size())
- : InlineAsm::getFlagWord(InlineAsm::Kind_Func, SelOps.size());
- NewFlags = InlineAsm::getFlagWordForMem(NewFlags, ConstraintID);
- Ops.push_back(CurDAG->getTargetConstant(NewFlags, DL, MVT::i32));
+ Flags = InlineAsm::Flag(Flags.isMemKind() ? InlineAsm::Kind::Mem
+ : InlineAsm::Kind::Func,
+ SelOps.size());
+ Flags.setMemConstraint(ConstraintID);
+ Ops.push_back(CurDAG->getTargetConstant(Flags, DL, MVT::i32));
llvm::append_range(Ops, SelOps);
i += 2;
}
@@ -2176,18 +2225,20 @@ static bool findNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse,
/// operand node N of U during instruction selection that starts at Root.
bool SelectionDAGISel::IsProfitableToFold(SDValue N, SDNode *U,
SDNode *Root) const {
- if (OptLevel == CodeGenOpt::None) return false;
+ if (OptLevel == CodeGenOptLevel::None)
+ return false;
return N.hasOneUse();
}
/// IsLegalToFold - Returns true if the specific operand node N of
/// U can be folded during instruction selection that starts at Root.
bool SelectionDAGISel::IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
- CodeGenOpt::Level OptLevel,
+ CodeGenOptLevel OptLevel,
bool IgnoreChains) {
- if (OptLevel == CodeGenOpt::None) return false;
+ if (OptLevel == CodeGenOptLevel::None)
+ return false;
- // If Root use can somehow reach N through a path that that doesn't contain
+ // If Root use can somehow reach N through a path that doesn't contain
// U then folding N would create a cycle. e.g. In the following
// diagram, Root can reach N through X. If N is folded into Root, then
// X is both a predecessor and a successor of U.
@@ -2435,6 +2486,13 @@ GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) {
return Val;
}
+void SelectionDAGISel::Select_JUMP_TABLE_DEBUG_INFO(SDNode *N) {
+ SDLoc dl(N);
+ CurDAG->SelectNodeTo(N, TargetOpcode::JUMP_TABLE_DEBUG_INFO, MVT::Glue,
+ CurDAG->getTargetConstant(N->getConstantOperandVal(1),
+ dl, MVT::i64, true));
+}
+
/// When a match is complete, this method updates uses of interior chain results
/// to use the new results.
void SelectionDAGISel::UpdateChains(
@@ -2591,7 +2649,7 @@ MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList,
unsigned ResNumResults = Res->getNumValues();
// Move the glue if needed.
if ((EmitNodeInfo & OPFL_GlueOutput) && OldGlueResultNo != -1 &&
- (unsigned)OldGlueResultNo != ResNumResults-1)
+ static_cast<unsigned>(OldGlueResultNo) != ResNumResults - 1)
ReplaceUses(SDValue(Node, OldGlueResultNo),
SDValue(Res, ResNumResults - 1));
@@ -2600,7 +2658,7 @@ MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList,
// Move the chain reference if needed.
if ((EmitNodeInfo & OPFL_Chain) && OldChainResultNo != -1 &&
- (unsigned)OldChainResultNo != ResNumResults-1)
+ static_cast<unsigned>(OldChainResultNo) != ResNumResults - 1)
ReplaceUses(SDValue(Node, OldChainResultNo),
SDValue(Res, ResNumResults - 1));
@@ -2639,8 +2697,11 @@ LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckChildSame(
/// CheckPatternPredicate - Implements OP_CheckPatternPredicate.
LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckPatternPredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex,
- const SelectionDAGISel &SDISel) {
- return SDISel.CheckPatternPredicate(MatcherTable[MatcherIndex++]);
+ const SelectionDAGISel &SDISel, bool TwoBytePredNo) {
+ unsigned PredNo = MatcherTable[MatcherIndex++];
+ if (TwoBytePredNo)
+ PredNo |= MatcherTable[MatcherIndex++] << 8;
+ return SDISel.CheckPatternPredicate(PredNo);
}
/// CheckNodePredicate - Implements OP_CheckNodePredicate.
@@ -2654,35 +2715,34 @@ LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckOpcode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDNode *N) {
uint16_t Opc = MatcherTable[MatcherIndex++];
- Opc |= (unsigned short)MatcherTable[MatcherIndex++] << 8;
+ Opc |= static_cast<uint16_t>(MatcherTable[MatcherIndex++]) << 8;
return N->getOpcode() == Opc;
}
-LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
-CheckType(const unsigned char *MatcherTable, unsigned &MatcherIndex, SDValue N,
- const TargetLowering *TLI, const DataLayout &DL) {
- MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
- if (N.getValueType() == VT) return true;
+LLVM_ATTRIBUTE_ALWAYS_INLINE static bool CheckType(MVT::SimpleValueType VT,
+ SDValue N,
+ const TargetLowering *TLI,
+ const DataLayout &DL) {
+ if (N.getValueType() == VT)
+ return true;
// Handle the case when VT is iPTR.
return VT == MVT::iPTR && N.getValueType() == TLI->getPointerTy(DL);
}
LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
-CheckChildType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
- SDValue N, const TargetLowering *TLI, const DataLayout &DL,
- unsigned ChildNo) {
+CheckChildType(MVT::SimpleValueType VT, SDValue N, const TargetLowering *TLI,
+ const DataLayout &DL, unsigned ChildNo) {
if (ChildNo >= N.getNumOperands())
- return false; // Match fails if out of range child #.
- return ::CheckType(MatcherTable, MatcherIndex, N.getOperand(ChildNo), TLI,
- DL);
+ return false; // Match fails if out of range child #.
+ return ::CheckType(VT, N.getOperand(ChildNo), TLI, DL);
}
LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckCondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDValue N) {
return cast<CondCodeSDNode>(N)->get() ==
- (ISD::CondCode)MatcherTable[MatcherIndex++];
+ static_cast<ISD::CondCode>(MatcherTable[MatcherIndex++]);
}
LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
@@ -2696,7 +2756,8 @@ CheckChild2CondCode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
LLVM_ATTRIBUTE_ALWAYS_INLINE static bool
CheckValueType(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDValue N, const TargetLowering *TLI, const DataLayout &DL) {
- MVT::SimpleValueType VT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ MVT::SimpleValueType VT =
+ static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
if (cast<VTSDNode>(N)->getVT() == VT)
return true;
@@ -2773,7 +2834,8 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table,
bool &Result,
const SelectionDAGISel &SDISel,
SmallVectorImpl<std::pair<SDValue, SDNode*>> &RecordedNodes) {
- switch (Table[Index++]) {
+ unsigned Opcode = Table[Index++];
+ switch (Opcode) {
default:
Result = false;
return Index-1; // Could not evaluate this predicate.
@@ -2788,7 +2850,10 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table,
Table[Index-1] - SelectionDAGISel::OPC_CheckChild0Same);
return Index;
case SelectionDAGISel::OPC_CheckPatternPredicate:
- Result = !::CheckPatternPredicate(Table, Index, SDISel);
+ case SelectionDAGISel::OPC_CheckPatternPredicate2:
+ Result = !::CheckPatternPredicate(
+ Table, Index, SDISel,
+ Table[Index - 1] == SelectionDAGISel::OPC_CheckPatternPredicate2);
return Index;
case SelectionDAGISel::OPC_CheckPredicate:
Result = !::CheckNodePredicate(Table, Index, SDISel, N.getNode());
@@ -2797,12 +2862,27 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table,
Result = !::CheckOpcode(Table, Index, N.getNode());
return Index;
case SelectionDAGISel::OPC_CheckType:
- Result = !::CheckType(Table, Index, N, SDISel.TLI,
- SDISel.CurDAG->getDataLayout());
+ case SelectionDAGISel::OPC_CheckTypeI32:
+ case SelectionDAGISel::OPC_CheckTypeI64: {
+ MVT::SimpleValueType VT;
+ switch (Opcode) {
+ case SelectionDAGISel::OPC_CheckTypeI32:
+ VT = MVT::i32;
+ break;
+ case SelectionDAGISel::OPC_CheckTypeI64:
+ VT = MVT::i64;
+ break;
+ default:
+ VT = static_cast<MVT::SimpleValueType>(Table[Index++]);
+ break;
+ }
+ Result = !::CheckType(VT, N, SDISel.TLI, SDISel.CurDAG->getDataLayout());
return Index;
+ }
case SelectionDAGISel::OPC_CheckTypeRes: {
unsigned Res = Table[Index++];
- Result = !::CheckType(Table, Index, N.getValue(Res), SDISel.TLI,
+ Result = !::CheckType(static_cast<MVT::SimpleValueType>(Table[Index++]),
+ N.getValue(Res), SDISel.TLI,
SDISel.CurDAG->getDataLayout());
return Index;
}
@@ -2814,10 +2894,40 @@ static unsigned IsPredicateKnownToFail(const unsigned char *Table,
case SelectionDAGISel::OPC_CheckChild5Type:
case SelectionDAGISel::OPC_CheckChild6Type:
case SelectionDAGISel::OPC_CheckChild7Type:
- Result = !::CheckChildType(
- Table, Index, N, SDISel.TLI, SDISel.CurDAG->getDataLayout(),
- Table[Index - 1] - SelectionDAGISel::OPC_CheckChild0Type);
+ case SelectionDAGISel::OPC_CheckChild0TypeI32:
+ case SelectionDAGISel::OPC_CheckChild1TypeI32:
+ case SelectionDAGISel::OPC_CheckChild2TypeI32:
+ case SelectionDAGISel::OPC_CheckChild3TypeI32:
+ case SelectionDAGISel::OPC_CheckChild4TypeI32:
+ case SelectionDAGISel::OPC_CheckChild5TypeI32:
+ case SelectionDAGISel::OPC_CheckChild6TypeI32:
+ case SelectionDAGISel::OPC_CheckChild7TypeI32:
+ case SelectionDAGISel::OPC_CheckChild0TypeI64:
+ case SelectionDAGISel::OPC_CheckChild1TypeI64:
+ case SelectionDAGISel::OPC_CheckChild2TypeI64:
+ case SelectionDAGISel::OPC_CheckChild3TypeI64:
+ case SelectionDAGISel::OPC_CheckChild4TypeI64:
+ case SelectionDAGISel::OPC_CheckChild5TypeI64:
+ case SelectionDAGISel::OPC_CheckChild6TypeI64:
+ case SelectionDAGISel::OPC_CheckChild7TypeI64: {
+ MVT::SimpleValueType VT;
+ unsigned ChildNo;
+ if (Opcode >= SelectionDAGISel::OPC_CheckChild0TypeI32 &&
+ Opcode <= SelectionDAGISel::OPC_CheckChild7TypeI32) {
+ VT = MVT::i32;
+ ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI32;
+ } else if (Opcode >= SelectionDAGISel::OPC_CheckChild0TypeI64 &&
+ Opcode <= SelectionDAGISel::OPC_CheckChild7TypeI64) {
+ VT = MVT::i64;
+ ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI64;
+ } else {
+ VT = static_cast<MVT::SimpleValueType>(Table[Index++]);
+ ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0Type;
+ }
+ Result = !::CheckChildType(VT, N, SDISel.TLI,
+ SDISel.CurDAG->getDataLayout(), ChildNo);
return Index;
+ }
case SelectionDAGISel::OPC_CheckCondCode:
Result = !::CheckCondCode(Table, Index, N);
return Index;
@@ -2981,6 +3091,9 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
case ISD::PATCHPOINT:
Select_PATCHPOINT(NodeToMatch);
return;
+ case ISD::JUMP_TABLE_DEBUG_INFO:
+ Select_JUMP_TABLE_DEBUG_INFO(NodeToMatch);
+ return;
}
assert(!NodeToMatch->isMachineOpcode() && "Node already selected!");
@@ -3042,7 +3155,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
// Get the opcode, add the index to the table.
uint16_t Opc = MatcherTable[Idx++];
- Opc |= (unsigned short)MatcherTable[Idx++] << 8;
+ Opc |= static_cast<uint16_t>(MatcherTable[Idx++]) << 8;
if (Opc >= OpcodeOffset.size())
OpcodeOffset.resize((Opc+1)*2);
OpcodeOffset[Opc] = Idx;
@@ -3059,7 +3172,8 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
#ifndef NDEBUG
unsigned CurrentOpcodeIndex = MatcherIndex;
#endif
- BuiltinOpcodes Opcode = (BuiltinOpcodes)MatcherTable[MatcherIndex++];
+ BuiltinOpcodes Opcode =
+ static_cast<BuiltinOpcodes>(MatcherTable[MatcherIndex++]);
switch (Opcode) {
case OPC_Scope: {
// Okay, the semantics of this operation are that we should push a scope
@@ -3179,6 +3293,29 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
continue;
}
+ case OPC_MoveSibling:
+ case OPC_MoveSibling0:
+ case OPC_MoveSibling1:
+ case OPC_MoveSibling2:
+ case OPC_MoveSibling3:
+ case OPC_MoveSibling4:
+ case OPC_MoveSibling5:
+ case OPC_MoveSibling6:
+ case OPC_MoveSibling7: {
+ // Pop the current node off the NodeStack.
+ NodeStack.pop_back();
+ assert(!NodeStack.empty() && "Node stack imbalance!");
+ N = NodeStack.back();
+
+ unsigned SiblingNo = Opcode == OPC_MoveSibling
+ ? MatcherTable[MatcherIndex++]
+ : Opcode - OPC_MoveSibling0;
+ if (SiblingNo >= N.getNumOperands())
+ break; // Match fails if out of range sibling #.
+ N = N.getOperand(SiblingNo);
+ NodeStack.push_back(N);
+ continue;
+ }
case OPC_MoveParent:
// Pop the current node off the NodeStack.
NodeStack.pop_back();
@@ -3198,7 +3335,10 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
continue;
case OPC_CheckPatternPredicate:
- if (!::CheckPatternPredicate(MatcherTable, MatcherIndex, *this)) break;
+ case OPC_CheckPatternPredicate2:
+ if (!::CheckPatternPredicate(MatcherTable, MatcherIndex, *this,
+ Opcode == OPC_CheckPatternPredicate2))
+ break;
continue;
case OPC_CheckPredicate:
if (!::CheckNodePredicate(MatcherTable, MatcherIndex, *this,
@@ -3240,15 +3380,29 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
continue;
case OPC_CheckType:
- if (!::CheckType(MatcherTable, MatcherIndex, N, TLI,
- CurDAG->getDataLayout()))
+ case OPC_CheckTypeI32:
+ case OPC_CheckTypeI64:
+ MVT::SimpleValueType VT;
+ switch (Opcode) {
+ case OPC_CheckTypeI32:
+ VT = MVT::i32;
+ break;
+ case OPC_CheckTypeI64:
+ VT = MVT::i64;
+ break;
+ default:
+ VT = static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+ break;
+ }
+ if (!::CheckType(VT, N, TLI, CurDAG->getDataLayout()))
break;
continue;
case OPC_CheckTypeRes: {
unsigned Res = MatcherTable[MatcherIndex++];
- if (!::CheckType(MatcherTable, MatcherIndex, N.getValue(Res), TLI,
- CurDAG->getDataLayout()))
+ if (!::CheckType(
+ static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]),
+ N.getValue(Res), TLI, CurDAG->getDataLayout()))
break;
continue;
}
@@ -3265,7 +3419,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
if (CaseSize == 0) break;
uint16_t Opc = MatcherTable[MatcherIndex++];
- Opc |= (unsigned short)MatcherTable[MatcherIndex++] << 8;
+ Opc |= static_cast<uint16_t>(MatcherTable[MatcherIndex++]) << 8;
// If the opcode matches, then we will execute this case.
if (CurNodeOpcode == Opc)
@@ -3295,7 +3449,8 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex);
if (CaseSize == 0) break;
- MVT CaseVT = (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ MVT CaseVT =
+ static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
if (CaseVT == MVT::iPTR)
CaseVT = TLI->getPointerTy(CurDAG->getDataLayout());
@@ -3316,15 +3471,48 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
<< '\n');
continue;
}
- case OPC_CheckChild0Type: case OPC_CheckChild1Type:
- case OPC_CheckChild2Type: case OPC_CheckChild3Type:
- case OPC_CheckChild4Type: case OPC_CheckChild5Type:
- case OPC_CheckChild6Type: case OPC_CheckChild7Type:
- if (!::CheckChildType(MatcherTable, MatcherIndex, N, TLI,
- CurDAG->getDataLayout(),
- Opcode - OPC_CheckChild0Type))
+ case OPC_CheckChild0Type:
+ case OPC_CheckChild1Type:
+ case OPC_CheckChild2Type:
+ case OPC_CheckChild3Type:
+ case OPC_CheckChild4Type:
+ case OPC_CheckChild5Type:
+ case OPC_CheckChild6Type:
+ case OPC_CheckChild7Type:
+ case OPC_CheckChild0TypeI32:
+ case OPC_CheckChild1TypeI32:
+ case OPC_CheckChild2TypeI32:
+ case OPC_CheckChild3TypeI32:
+ case OPC_CheckChild4TypeI32:
+ case OPC_CheckChild5TypeI32:
+ case OPC_CheckChild6TypeI32:
+ case OPC_CheckChild7TypeI32:
+ case OPC_CheckChild0TypeI64:
+ case OPC_CheckChild1TypeI64:
+ case OPC_CheckChild2TypeI64:
+ case OPC_CheckChild3TypeI64:
+ case OPC_CheckChild4TypeI64:
+ case OPC_CheckChild5TypeI64:
+ case OPC_CheckChild6TypeI64:
+ case OPC_CheckChild7TypeI64: {
+ MVT::SimpleValueType VT;
+ unsigned ChildNo;
+ if (Opcode >= SelectionDAGISel::OPC_CheckChild0TypeI32 &&
+ Opcode <= SelectionDAGISel::OPC_CheckChild7TypeI32) {
+ VT = MVT::i32;
+ ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI32;
+ } else if (Opcode >= SelectionDAGISel::OPC_CheckChild0TypeI64 &&
+ Opcode <= SelectionDAGISel::OPC_CheckChild7TypeI64) {
+ VT = MVT::i64;
+ ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0TypeI64;
+ } else {
+ VT = static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+ ChildNo = Opcode - SelectionDAGISel::OPC_CheckChild0Type;
+ }
+ if (!::CheckChildType(VT, N, TLI, CurDAG->getDataLayout(), ChildNo))
break;
continue;
+ }
case OPC_CheckCondCode:
if (!::CheckCondCode(MatcherTable, MatcherIndex, N)) break;
continue;
@@ -3390,22 +3578,43 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
continue;
}
case OPC_EmitInteger:
- case OPC_EmitStringInteger: {
- MVT::SimpleValueType VT =
- (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ case OPC_EmitInteger8:
+ case OPC_EmitInteger16:
+ case OPC_EmitInteger32:
+ case OPC_EmitInteger64:
+ case OPC_EmitStringInteger:
+ case OPC_EmitStringInteger32: {
+ MVT::SimpleValueType VT;
+ switch (Opcode) {
+ case OPC_EmitInteger8:
+ VT = MVT::i8;
+ break;
+ case OPC_EmitInteger16:
+ VT = MVT::i16;
+ break;
+ case OPC_EmitInteger32:
+ case OPC_EmitStringInteger32:
+ VT = MVT::i32;
+ break;
+ case OPC_EmitInteger64:
+ VT = MVT::i64;
+ break;
+ default:
+ VT = static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
+ break;
+ }
int64_t Val = MatcherTable[MatcherIndex++];
if (Val & 128)
Val = GetVBR(Val, MatcherTable, MatcherIndex);
- if (Opcode == OPC_EmitInteger)
+ if (Opcode >= OPC_EmitInteger && Opcode <= OPC_EmitInteger64)
Val = decodeSignRotatedValue(Val);
- RecordedNodes.push_back(std::pair<SDValue, SDNode*>(
- CurDAG->getTargetConstant(Val, SDLoc(NodeToMatch),
- VT), nullptr));
+ RecordedNodes.push_back(std::pair<SDValue, SDNode *>(
+ CurDAG->getTargetConstant(Val, SDLoc(NodeToMatch), VT), nullptr));
continue;
}
case OPC_EmitRegister: {
MVT::SimpleValueType VT =
- (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
unsigned RegNo = MatcherTable[MatcherIndex++];
RecordedNodes.push_back(std::pair<SDValue, SDNode*>(
CurDAG->getRegister(RegNo, VT), nullptr));
@@ -3416,7 +3625,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
// values are stored in two bytes in the matcher table (just like
// opcodes).
MVT::SimpleValueType VT =
- (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
unsigned RegNo = MatcherTable[MatcherIndex++];
RegNo |= MatcherTable[MatcherIndex++] << 8;
RecordedNodes.push_back(std::pair<SDValue, SDNode*>(
@@ -3424,9 +3633,19 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
continue;
}
- case OPC_EmitConvertToTarget: {
+ case OPC_EmitConvertToTarget:
+ case OPC_EmitConvertToTarget0:
+ case OPC_EmitConvertToTarget1:
+ case OPC_EmitConvertToTarget2:
+ case OPC_EmitConvertToTarget3:
+ case OPC_EmitConvertToTarget4:
+ case OPC_EmitConvertToTarget5:
+ case OPC_EmitConvertToTarget6:
+ case OPC_EmitConvertToTarget7: {
// Convert from IMM/FPIMM to target version.
- unsigned RecNo = MatcherTable[MatcherIndex++];
+ unsigned RecNo = Opcode == OPC_EmitConvertToTarget
+ ? MatcherTable[MatcherIndex++]
+ : Opcode - OPC_EmitConvertToTarget0;
assert(RecNo < RecordedNodes.size() && "Invalid EmitConvertToTarget");
SDValue Imm = RecordedNodes[RecNo].first;
@@ -3522,11 +3741,22 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
}
case OPC_EmitCopyToReg:
- case OPC_EmitCopyToReg2: {
- unsigned RecNo = MatcherTable[MatcherIndex++];
+ case OPC_EmitCopyToReg0:
+ case OPC_EmitCopyToReg1:
+ case OPC_EmitCopyToReg2:
+ case OPC_EmitCopyToReg3:
+ case OPC_EmitCopyToReg4:
+ case OPC_EmitCopyToReg5:
+ case OPC_EmitCopyToReg6:
+ case OPC_EmitCopyToReg7:
+ case OPC_EmitCopyToRegTwoByte: {
+ unsigned RecNo =
+ Opcode >= OPC_EmitCopyToReg0 && Opcode <= OPC_EmitCopyToReg7
+ ? Opcode - OPC_EmitCopyToReg0
+ : MatcherTable[MatcherIndex++];
assert(RecNo < RecordedNodes.size() && "Invalid EmitCopyToReg");
unsigned DestPhysReg = MatcherTable[MatcherIndex++];
- if (Opcode == OPC_EmitCopyToReg2)
+ if (Opcode == OPC_EmitCopyToRegTwoByte)
DestPhysReg |= MatcherTable[MatcherIndex++] << 8;
if (!InputChain.getNode())
@@ -3558,26 +3788,83 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
continue;
}
- case OPC_EmitNode: case OPC_MorphNodeTo:
- case OPC_EmitNode0: case OPC_EmitNode1: case OPC_EmitNode2:
- case OPC_MorphNodeTo0: case OPC_MorphNodeTo1: case OPC_MorphNodeTo2: {
+ case OPC_EmitNode:
+ case OPC_EmitNode0:
+ case OPC_EmitNode1:
+ case OPC_EmitNode2:
+ case OPC_EmitNode0None:
+ case OPC_EmitNode1None:
+ case OPC_EmitNode2None:
+ case OPC_EmitNode0Chain:
+ case OPC_EmitNode1Chain:
+ case OPC_EmitNode2Chain:
+ case OPC_MorphNodeTo:
+ case OPC_MorphNodeTo0:
+ case OPC_MorphNodeTo1:
+ case OPC_MorphNodeTo2:
+ case OPC_MorphNodeTo0None:
+ case OPC_MorphNodeTo1None:
+ case OPC_MorphNodeTo2None:
+ case OPC_MorphNodeTo0Chain:
+ case OPC_MorphNodeTo1Chain:
+ case OPC_MorphNodeTo2Chain:
+ case OPC_MorphNodeTo0GlueInput:
+ case OPC_MorphNodeTo1GlueInput:
+ case OPC_MorphNodeTo2GlueInput:
+ case OPC_MorphNodeTo0GlueOutput:
+ case OPC_MorphNodeTo1GlueOutput:
+ case OPC_MorphNodeTo2GlueOutput: {
uint16_t TargetOpc = MatcherTable[MatcherIndex++];
- TargetOpc |= (unsigned short)MatcherTable[MatcherIndex++] << 8;
- unsigned EmitNodeInfo = MatcherTable[MatcherIndex++];
+ TargetOpc |= static_cast<uint16_t>(MatcherTable[MatcherIndex++]) << 8;
+ unsigned EmitNodeInfo;
+ if (Opcode >= OPC_EmitNode0None && Opcode <= OPC_EmitNode2Chain) {
+ if (Opcode >= OPC_EmitNode0Chain && Opcode <= OPC_EmitNode2Chain)
+ EmitNodeInfo = OPFL_Chain;
+ else
+ EmitNodeInfo = OPFL_None;
+ } else if (Opcode >= OPC_MorphNodeTo0None &&
+ Opcode <= OPC_MorphNodeTo2GlueOutput) {
+ if (Opcode >= OPC_MorphNodeTo0Chain && Opcode <= OPC_MorphNodeTo2Chain)
+ EmitNodeInfo = OPFL_Chain;
+ else if (Opcode >= OPC_MorphNodeTo0GlueInput &&
+ Opcode <= OPC_MorphNodeTo2GlueInput)
+ EmitNodeInfo = OPFL_GlueInput;
+ else if (Opcode >= OPC_MorphNodeTo0GlueOutput &&
+ Opcode <= OPC_MorphNodeTo2GlueOutput)
+ EmitNodeInfo = OPFL_GlueOutput;
+ else
+ EmitNodeInfo = OPFL_None;
+ } else
+ EmitNodeInfo = MatcherTable[MatcherIndex++];
// Get the result VT list.
unsigned NumVTs;
// If this is one of the compressed forms, get the number of VTs based
// on the Opcode. Otherwise read the next byte from the table.
if (Opcode >= OPC_MorphNodeTo0 && Opcode <= OPC_MorphNodeTo2)
NumVTs = Opcode - OPC_MorphNodeTo0;
+ else if (Opcode >= OPC_MorphNodeTo0None && Opcode <= OPC_MorphNodeTo2None)
+ NumVTs = Opcode - OPC_MorphNodeTo0None;
+ else if (Opcode >= OPC_MorphNodeTo0Chain &&
+ Opcode <= OPC_MorphNodeTo2Chain)
+ NumVTs = Opcode - OPC_MorphNodeTo0Chain;
+ else if (Opcode >= OPC_MorphNodeTo0GlueInput &&
+ Opcode <= OPC_MorphNodeTo2GlueInput)
+ NumVTs = Opcode - OPC_MorphNodeTo0GlueInput;
+ else if (Opcode >= OPC_MorphNodeTo0GlueOutput &&
+ Opcode <= OPC_MorphNodeTo2GlueOutput)
+ NumVTs = Opcode - OPC_MorphNodeTo0GlueOutput;
else if (Opcode >= OPC_EmitNode0 && Opcode <= OPC_EmitNode2)
NumVTs = Opcode - OPC_EmitNode0;
+ else if (Opcode >= OPC_EmitNode0None && Opcode <= OPC_EmitNode2None)
+ NumVTs = Opcode - OPC_EmitNode0None;
+ else if (Opcode >= OPC_EmitNode0Chain && Opcode <= OPC_EmitNode2Chain)
+ NumVTs = Opcode - OPC_EmitNode0Chain;
else
NumVTs = MatcherTable[MatcherIndex++];
SmallVector<EVT, 4> VTs;
for (unsigned i = 0; i != NumVTs; ++i) {
MVT::SimpleValueType VT =
- (MVT::SimpleValueType)MatcherTable[MatcherIndex++];
+ static_cast<MVT::SimpleValueType>(MatcherTable[MatcherIndex++]);
if (VT == MVT::iPTR)
VT = TLI->getPointerTy(CurDAG->getDataLayout()).SimpleTy;
VTs.push_back(VT);
@@ -3644,8 +3931,9 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
// Create the node.
MachineSDNode *Res = nullptr;
- bool IsMorphNodeTo = Opcode == OPC_MorphNodeTo ||
- (Opcode >= OPC_MorphNodeTo0 && Opcode <= OPC_MorphNodeTo2);
+ bool IsMorphNodeTo =
+ Opcode == OPC_MorphNodeTo ||
+ (Opcode >= OPC_MorphNodeTo0 && Opcode <= OPC_MorphNodeTo2GlueOutput);
if (!IsMorphNodeTo) {
// If this is a normal EmitNode command, just create the new node and
// add the results to the RecordedNodes list.
@@ -3667,7 +3955,7 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch,
auto &Chain = ChainNodesMatched;
assert((!E || !is_contained(Chain, N)) &&
"Chain node replaced during MorphNode");
- llvm::erase_value(Chain, N);
+ llvm::erase(Chain, N);
});
Res = cast<MachineSDNode>(MorphNode(NodeToMatch, TargetOpc, VTList,
Ops, EmitNodeInfo));