aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2008-09-03 23:12:08 +0000
committerDan Gohman <gohman@apple.com>2008-09-03 23:12:08 +0000
commit3df24e667f04a7003342b534310919abc9c87418 (patch)
treebcfae226d659d20f4bd6c4b5e8c25e42001a50db /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
parent7bbb4339f905345f92fcd60bf8f64bdc29c8cc36 (diff)
Create HandlePHINodesInSuccessorBlocksFast, a version of
HandlePHINodesInSuccessorBlocks that works FastISel-style. This allows PHI nodes to be updated correctly while using FastISel. This also involves some code reorganization; ValueMap and MBBMap are now members of the FastISel class, so they needn't be passed around explicitly anymore. Also, SelectInstructions is changed to SelectInstruction, and only does one instruction at a time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55746 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp73
1 files changed, 41 insertions, 32 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index a2cf6a1b56..2b9ba38f20 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -408,8 +408,12 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
}
// Handle PHI nodes in successor blocks.
- if (End == LLVMBB->end())
+ if (End == LLVMBB->end()) {
HandlePHINodesInSuccessorBlocks(LLVMBB);
+
+ // Lower the terminator after the copies are emitted.
+ SDL->visit(*LLVMBB->getTerminator());
+ }
// Make sure the root of the DAG is up-to-date.
CurDAG->setRoot(SDL->getControlRoot());
@@ -606,8 +610,9 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) {
BasicBlock *LLVMBB = &*I;
BB = FuncInfo->MBBMap[LLVMBB];
- BasicBlock::iterator Begin = LLVMBB->begin();
- BasicBlock::iterator End = LLVMBB->end();
+ BasicBlock::iterator const Begin = LLVMBB->begin();
+ BasicBlock::iterator const End = LLVMBB->end();
+ BasicBlock::iterator I = Begin;
// Lower any arguments needed in this block if this is the entry block.
if (LLVMBB == &Fn.getEntryBlock())
@@ -616,7 +621,8 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) {
// Before doing SelectionDAG ISel, see if FastISel has been requested.
// FastISel doesn't support EH landing pads, which require special handling.
if (EnableFastISel && !BB->isLandingPad()) {
- if (FastISel *F = TLI.createFastISel(*FuncInfo->MF)) {
+ if (FastISel *F = TLI.createFastISel(*FuncInfo->MF, FuncInfo->ValueMap,
+ FuncInfo->MBBMap)) {
// Emit code for any incoming arguments. This must happen before
// beginning FastISel on the entry block.
if (LLVMBB == &Fn.getEntryBlock()) {
@@ -624,45 +630,51 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) {
CodeGenAndEmitDAG();
SDL->clear();
}
+ F->setCurrentBlock(BB);
// Do FastISel on as many instructions as possible.
- while (Begin != End) {
- Begin = F->SelectInstructions(Begin, End, FuncInfo->ValueMap,
- FuncInfo->MBBMap, BB);
+ for (; I != End; ++I) {
+ // Just before the terminator instruction, insert instructions to
+ // feed PHI nodes in successor blocks.
+ if (isa<TerminatorInst>(I))
+ if (!HandlePHINodesInSuccessorBlocksFast(LLVMBB, F)) {
+ if (DisableFastISelAbort)
+ break;
+#ifndef NDEBUG
+ I->dump();
+#endif
+ assert(0 && "FastISel didn't handle a PHI in a successor");
+ }
- // If the "fast" selector selected the entire block, we're done.
- if (Begin == End)
- break;
+ // First try normal tablegen-generated "fast" selection.
+ if (F->SelectInstruction(I))
+ continue;
// Next, try calling the target to attempt to handle the instruction.
- if (F->TargetSelectInstruction(Begin, FuncInfo->ValueMap,
- FuncInfo->MBBMap, BB)) {
- ++Begin;
+ if (F->TargetSelectInstruction(I))
continue;
- }
- // Handle certain instructions as single-LLVM-Instruction blocks.
- if (isa<CallInst>(Begin) || isa<LoadInst>(Begin) ||
- isa<StoreInst>(Begin)) {
- if (Begin->getType() != Type::VoidTy) {
- unsigned &R = FuncInfo->ValueMap[Begin];
+ // Then handle certain instructions as single-LLVM-Instruction blocks.
+ if (isa<CallInst>(I) || isa<LoadInst>(I) ||
+ isa<StoreInst>(I)) {
+ if (I->getType() != Type::VoidTy) {
+ unsigned &R = FuncInfo->ValueMap[I];
if (!R)
- R = FuncInfo->CreateRegForValue(Begin);
+ R = FuncInfo->CreateRegForValue(I);
}
- SelectBasicBlock(LLVMBB, Begin, next(Begin));
- ++Begin;
+ SelectBasicBlock(LLVMBB, I, next(I));
continue;
}
if (!DisableFastISelAbort &&
// For now, don't abort on non-conditional-branch terminators.
- (!isa<TerminatorInst>(Begin) ||
- (isa<BranchInst>(Begin) &&
- cast<BranchInst>(Begin)->isUnconditional()))) {
+ (!isa<TerminatorInst>(I) ||
+ (isa<BranchInst>(I) &&
+ cast<BranchInst>(I)->isUnconditional()))) {
// The "fast" selector couldn't handle something and bailed.
// For the purpose of debugging, just abort.
#ifndef NDEBUG
- Begin->dump();
+ I->dump();
#endif
assert(0 && "FastISel didn't select the entire block");
}
@@ -674,12 +686,9 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) {
// Run SelectionDAG instruction selection on the remainder of the block
// not handled by FastISel. If FastISel is not run, this is the entire
- // block. If FastISel is run and happens to handle all of the
- // LLVM Instructions in the block, [Begin,End) will be an empty range,
- // but we still need to run this so that
- // HandlePHINodesInSuccessorBlocks is called and any resulting code
- // is emitted.
- SelectBasicBlock(LLVMBB, Begin, End);
+ // block.
+ if (I != End)
+ SelectBasicBlock(LLVMBB, I, End);
FinishBasicBlock();
}