diff options
author | Dan Gohman <gohman@apple.com> | 2008-09-03 23:12:08 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2008-09-03 23:12:08 +0000 |
commit | 3df24e667f04a7003342b534310919abc9c87418 (patch) | |
tree | bcfae226d659d20f4bd6c4b5e8c25e42001a50db /lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | |
parent | 7bbb4339f905345f92fcd60bf8f64bdc29c8cc36 (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.cpp | 73 |
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(); } |