aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp68
1 files changed, 46 insertions, 22 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index d4e9a50..acae58c 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -144,7 +144,12 @@ EnableFastISelVerbose("fast-isel-verbose", cl::Hidden,
"instruction selector"));
static cl::opt<bool>
EnableFastISelAbort("fast-isel-abort", cl::Hidden,
- cl::desc("Enable abort calls when \"fast\" instruction fails"));
+ cl::desc("Enable abort calls when \"fast\" instruction selection "
+ "fails to lower an instruction"));
+static cl::opt<bool>
+EnableFastISelAbortArgs("fast-isel-abort-args", cl::Hidden,
+ cl::desc("Enable abort calls when \"fast\" instruction selection "
+ "fails to lower a formal argument"));
static cl::opt<bool>
UseMBPI("use-mbpi",
@@ -354,6 +359,10 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
TTI = getAnalysisIfAvailable<TargetTransformInfo>();
GFI = Fn.hasGC() ? &getAnalysis<GCModuleInfo>().getFunctionInfo(Fn) : 0;
+ TargetSubtargetInfo &ST =
+ const_cast<TargetSubtargetInfo&>(TM.getSubtarget<TargetSubtargetInfo>());
+ ST.resetSubtargetFeatures(MF);
+
DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
SplitCriticalSideEffectEdges(const_cast<Function&>(Fn), this);
@@ -368,6 +377,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
SDB->init(GFI, *AA, LibInfo);
+ MF->setHasMSInlineAsm(false);
SelectAllBasicBlocks(Fn);
// If the first basic block in the function has live ins that need to be
@@ -438,24 +448,26 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// Determine if there are any calls in this machine function.
MachineFrameInfo *MFI = MF->getFrameInfo();
- if (!MFI->hasCalls()) {
- for (MachineFunction::const_iterator
- I = MF->begin(), E = MF->end(); I != E; ++I) {
- const MachineBasicBlock *MBB = I;
- for (MachineBasicBlock::const_iterator
- II = MBB->begin(), IE = MBB->end(); II != IE; ++II) {
- const MCInstrDesc &MCID = TM.getInstrInfo()->get(II->getOpcode());
-
- if ((MCID.isCall() && !MCID.isReturn()) ||
- II->isStackAligningInlineAsm()) {
- MFI->setHasCalls(true);
- goto done;
- }
+ for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E;
+ ++I) {
+
+ if (MFI->hasCalls() && MF->hasMSInlineAsm())
+ break;
+
+ const MachineBasicBlock *MBB = I;
+ for (MachineBasicBlock::const_iterator II = MBB->begin(), IE = MBB->end();
+ II != IE; ++II) {
+ const MCInstrDesc &MCID = TM.getInstrInfo()->get(II->getOpcode());
+ if ((MCID.isCall() && !MCID.isReturn()) ||
+ II->isStackAligningInlineAsm()) {
+ MFI->setHasCalls(true);
+ }
+ if (II->isMSInlineAsm()) {
+ MF->setHasMSInlineAsm(true);
}
}
}
- done:
// Determine if there is a call to setjmp in the machine function.
MF->setExposesReturnsTwice(Fn.callsFunctionThatReturnsTwice());
@@ -1032,10 +1044,6 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
if (FuncInfo->MBB->isLandingPad())
PrepareEHLandingPad();
- // Lower any arguments needed in this block if this is the entry block.
- if (LLVMBB == &Fn.getEntryBlock())
- LowerArguments(LLVMBB);
-
// Before doing SelectionDAG ISel, see if FastISel has been requested.
if (FastIS) {
FastIS->startNewBlock();
@@ -1043,9 +1051,21 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
// Emit code for any incoming arguments. This must happen before
// beginning FastISel on the entry block.
if (LLVMBB == &Fn.getEntryBlock()) {
- CurDAG->setRoot(SDB->getControlRoot());
- SDB->clear();
- CodeGenAndEmitDAG();
+ // Lower any arguments needed in this block if this is the entry block.
+ if (!FastIS->LowerArguments()) {
+
+ if (EnableFastISelAbortArgs)
+ // The "fast" selector couldn't lower these arguments. For the
+ // purpose of debugging, just abort.
+ llvm_unreachable("FastISel didn't lower all arguments");
+
+ // Call target indepedent SDISel argument lowering code if the target
+ // specific routine is not successful.
+ LowerArguments(LLVMBB);
+ CurDAG->setRoot(SDB->getControlRoot());
+ SDB->clear();
+ CodeGenAndEmitDAG();
+ }
// If we inserted any instructions at the beginning, make a note of
// where they are, so we can be sure to emit subsequent instructions
@@ -1156,6 +1176,10 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
}
FastIS->recomputeInsertPt();
+ } else {
+ // Lower any arguments needed in this block if this is the entry block.
+ if (LLVMBB == &Fn.getEntryBlock())
+ LowerArguments(LLVMBB);
}
if (Begin != BI)