diff options
Diffstat (limited to 'lib/CodeGen/PHIElimination.cpp')
-rw-r--r-- | lib/CodeGen/PHIElimination.cpp | 286 |
1 files changed, 195 insertions, 91 deletions
diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp index 8071b0a..cd38dd1 100644 --- a/lib/CodeGen/PHIElimination.cpp +++ b/lib/CodeGen/PHIElimination.cpp @@ -15,24 +15,32 @@ #define DEBUG_TYPE "phielim" #include "PHIElimination.h" -#include "llvm/BasicBlock.h" -#include "llvm/Instructions.h" #include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegAllocRegistry.h" +#include "llvm/Function.h" #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" #include <algorithm> #include <map> using namespace llvm; STATISTIC(NumAtomic, "Number of atomic phis lowered"); +STATISTIC(NumSplits, "Number of critical edges split on demand"); + +static cl::opt<bool> +SplitEdges("split-phi-edges", + cl::desc("Split critical edges during phi elimination"), + cl::init(false), cl::Hidden); char PHIElimination::ID = 0; static RegisterPass<PHIElimination> @@ -40,11 +48,26 @@ X("phi-node-elimination", "Eliminate PHI nodes for register allocation"); const PassInfo *const llvm::PHIEliminationID = &X; +namespace llvm { FunctionPass *createLocalRegisterAllocator(); } + +// Should we run edge splitting? +static bool shouldSplitEdges() { + // Edge splitting breaks the local register allocator. It cannot tolerate + // LiveVariables being run. + if (RegisterRegAlloc::getDefault() == createLocalRegisterAllocator) + return false; + return SplitEdges; +} + void llvm::PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); AU.addPreserved<LiveVariables>(); - AU.addPreservedID(MachineLoopInfoID); - AU.addPreservedID(MachineDominatorsID); + AU.addPreserved<MachineDominatorTree>(); + if (shouldSplitEdges()) { + AU.addRequired<LiveVariables>(); + } else { + AU.setPreservesCFG(); + AU.addPreservedID(MachineLoopInfoID); + } MachineFunctionPass::getAnalysisUsage(AU); } @@ -53,10 +76,16 @@ bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) { PHIDefs.clear(); PHIKills.clear(); - analyzePHINodes(Fn); - bool Changed = false; + // Split critical edges to help the coalescer + if (shouldSplitEdges()) + for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) + Changed |= SplitPHIEdges(Fn, *I); + + // Populate VRegPHIUseCount + analyzePHINodes(Fn); + // Eliminate PHI instructions by inserting copies into predecessor blocks. for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) Changed |= EliminatePHINodes(Fn, *I); @@ -75,7 +104,6 @@ bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) { return Changed; } - /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in /// predecessor basic blocks. /// @@ -107,26 +135,28 @@ static bool isSourceDefinedByImplicitDef(const MachineInstr *MPhi, return true; } -// FindCopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg. -// This needs to be after any def or uses of SrcReg, but before any subsequent -// point where control flow might jump out of the basic block. +// FindCopyInsertPoint - Find a safe place in MBB to insert a copy from SrcReg +// when following the CFG edge to SuccMBB. This needs to be after any def of +// SrcReg, but before any subsequent point where control flow might jump out of +// the basic block. MachineBasicBlock::iterator llvm::PHIElimination::FindCopyInsertPoint(MachineBasicBlock &MBB, + MachineBasicBlock &SuccMBB, unsigned SrcReg) { // Handle the trivial case trivially. if (MBB.empty()) return MBB.begin(); - // If this basic block does not contain an invoke, then control flow always - // reaches the end of it, so place the copy there. The logic below works in - // this case too, but is more expensive. - if (!isa<InvokeInst>(MBB.getBasicBlock()->getTerminator())) + // Usually, we just want to insert the copy before the first terminator + // instruction. However, for the edge going to a landing pad, we must insert + // the copy before the call/invoke instruction. + if (!SuccMBB.isLandingPad()) return MBB.getFirstTerminator(); - // Discover any definition/uses in this basic block. + // Discover any defs/uses in this basic block. SmallPtrSet<MachineInstr*, 8> DefUsesInMBB; for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(SrcReg), - RE = MRI->reg_end(); RI != RE; ++RI) { + RE = MRI->reg_end(); RI != RE; ++RI) { MachineInstr *DefUseMI = &*RI; if (DefUseMI->getParent() == &MBB) DefUsesInMBB.insert(DefUseMI); @@ -134,14 +164,14 @@ llvm::PHIElimination::FindCopyInsertPoint(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPoint; if (DefUsesInMBB.empty()) { - // No def/uses. Insert the copy at the start of the basic block. + // No defs. Insert the copy at the start of the basic block. InsertPoint = MBB.begin(); } else if (DefUsesInMBB.size() == 1) { - // Insert the copy immediately after the definition/use. + // Insert the copy immediately after the def/use. InsertPoint = *DefUsesInMBB.begin(); ++InsertPoint; } else { - // Insert the copy immediately after the last definition/use. + // Insert the copy immediately after the last def/use. InsertPoint = MBB.end(); while (!DefUsesInMBB.count(&*--InsertPoint)) {} ++InsertPoint; @@ -155,7 +185,7 @@ llvm::PHIElimination::FindCopyInsertPoint(MachineBasicBlock &MBB, /// under the assuption that it needs to be lowered in a way that supports /// atomic execution of PHIs. This lowering method is always correct all of the /// time. -/// +/// void llvm::PHIElimination::LowerAtomicPHINode( MachineBasicBlock &MBB, MachineBasicBlock::iterator AfterPHIsIt) { @@ -186,7 +216,7 @@ void llvm::PHIElimination::LowerAtomicPHINode( } // Record PHI def. - assert(!hasPHIDef(DestReg) && "Vreg has multiple phi-defs?"); + assert(!hasPHIDef(DestReg) && "Vreg has multiple phi-defs?"); PHIDefs[DestReg] = &MBB; // Update live variable information if there is any. @@ -250,92 +280,35 @@ void llvm::PHIElimination::LowerAtomicPHINode( // basic block. if (!MBBsInsertedInto.insert(&opBlock)) continue; // If the copy has already been emitted, we're done. - + // Find a safe location to insert the copy, this may be the first terminator // in the block (or end()). - MachineBasicBlock::iterator InsertPos = FindCopyInsertPoint(opBlock, SrcReg); + MachineBasicBlock::iterator InsertPos = + FindCopyInsertPoint(opBlock, MBB, SrcReg); // Insert the copy. TII->copyRegToReg(opBlock, InsertPos, IncomingReg, SrcReg, RC, RC); // Now update live variable information if we have it. Otherwise we're done if (!LV) continue; - + // We want to be able to insert a kill of the register if this PHI (aka, the // copy we just inserted) is the last use of the source value. Live // variable analysis conservatively handles this by saying that the value is // live until the end of the block the PHI entry lives in. If the value // really is dead at the PHI copy, there will be no successor blocks which // have the value live-in. - // - // Check to see if the copy is the last use, and if so, update the live - // variables information so that it knows the copy source instruction kills - // the incoming value. - LiveVariables::VarInfo &InRegVI = LV->getVarInfo(SrcReg); - - // Loop over all of the successors of the basic block, checking to see if - // the value is either live in the block, or if it is killed in the block. + // Also check to see if this register is in use by another PHI node which // has not yet been eliminated. If so, it will be killed at an appropriate // point later. // Is it used by any PHI instructions in this block? - bool ValueIsLive = VRegPHIUseCount[BBVRegPair(&opBlock, SrcReg)] != 0; - - std::vector<MachineBasicBlock*> OpSuccBlocks; - - // Otherwise, scan successors, including the BB the PHI node lives in. - for (MachineBasicBlock::succ_iterator SI = opBlock.succ_begin(), - E = opBlock.succ_end(); SI != E && !ValueIsLive; ++SI) { - MachineBasicBlock *SuccMBB = *SI; - - // Is it alive in this successor? - unsigned SuccIdx = SuccMBB->getNumber(); - if (InRegVI.AliveBlocks.test(SuccIdx)) { - ValueIsLive = true; - break; - } - - OpSuccBlocks.push_back(SuccMBB); - } - - // Check to see if this value is live because there is a use in a successor - // that kills it. - if (!ValueIsLive) { - switch (OpSuccBlocks.size()) { - case 1: { - MachineBasicBlock *MBB = OpSuccBlocks[0]; - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (InRegVI.Kills[i]->getParent() == MBB) { - ValueIsLive = true; - break; - } - break; - } - case 2: { - MachineBasicBlock *MBB1 = OpSuccBlocks[0], *MBB2 = OpSuccBlocks[1]; - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (InRegVI.Kills[i]->getParent() == MBB1 || - InRegVI.Kills[i]->getParent() == MBB2) { - ValueIsLive = true; - break; - } - break; - } - default: - std::sort(OpSuccBlocks.begin(), OpSuccBlocks.end()); - for (unsigned i = 0, e = InRegVI.Kills.size(); i != e; ++i) - if (std::binary_search(OpSuccBlocks.begin(), OpSuccBlocks.end(), - InRegVI.Kills[i]->getParent())) { - ValueIsLive = true; - break; - } - } - } + bool ValueIsUsed = VRegPHIUseCount[BBVRegPair(&opBlock, SrcReg)] != 0; // Okay, if we now know that the value is not live out of the block, we can // add a kill marker in this block saying that it kills the incoming value! - if (!ValueIsLive) { + if (!ValueIsUsed && !isLiveOut(SrcReg, opBlock, *LV)) { // In our final twist, we have to decide which instruction kills the // register. In most cases this is the copy, however, the first // terminator instruction at the end of the block may also use the value. @@ -346,7 +319,7 @@ void llvm::PHIElimination::LowerAtomicPHINode( if (Term != opBlock.end()) { if (Term->readsRegister(SrcReg)) KillInst = Term; - + // Check that no other terminators use values. #ifndef NDEBUG for (MachineBasicBlock::iterator TI = next(Term); TI != opBlock.end(); @@ -357,16 +330,16 @@ void llvm::PHIElimination::LowerAtomicPHINode( } #endif } - + // Finally, mark it killed. LV->addVirtualRegisterKilled(SrcReg, KillInst); // This vreg no longer lives all of the way through opBlock. unsigned opBlockNum = opBlock.getNumber(); - InRegVI.AliveBlocks.reset(opBlockNum); + LV->getVarInfo(SrcReg).AliveBlocks.reset(opBlockNum); } } - + // Really delete the PHI instruction now! MF.DeleteMachineInstr(MPhi); ++NumAtomic; @@ -386,3 +359,134 @@ void llvm::PHIElimination::analyzePHINodes(const MachineFunction& Fn) { ++VRegPHIUseCount[BBVRegPair(BBI->getOperand(i + 1).getMBB(), BBI->getOperand(i).getReg())]; } + +bool llvm::PHIElimination::SplitPHIEdges(MachineFunction &MF, + MachineBasicBlock &MBB) { + if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI) + return false; // Quick exit for basic blocks without PHIs. + LiveVariables &LV = getAnalysis<LiveVariables>(); + for (MachineBasicBlock::const_iterator BBI = MBB.begin(), BBE = MBB.end(); + BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) { + for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) { + unsigned Reg = BBI->getOperand(i).getReg(); + MachineBasicBlock *PreMBB = BBI->getOperand(i+1).getMBB(); + // We break edges when registers are live out from the predecessor block + // (not considering PHI nodes). If the register is live in to this block + // anyway, we would gain nothing from splitting. + if (isLiveOut(Reg, *PreMBB, LV) && !isLiveIn(Reg, MBB, LV)) + SplitCriticalEdge(PreMBB, &MBB); + } + } + return true; +} + +bool llvm::PHIElimination::isLiveOut(unsigned Reg, const MachineBasicBlock &MBB, + LiveVariables &LV) { + LiveVariables::VarInfo &VI = LV.getVarInfo(Reg); + + // Loop over all of the successors of the basic block, checking to see if + // the value is either live in the block, or if it is killed in the block. + std::vector<MachineBasicBlock*> OpSuccBlocks; + for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(), + E = MBB.succ_end(); SI != E; ++SI) { + MachineBasicBlock *SuccMBB = *SI; + + // Is it alive in this successor? + unsigned SuccIdx = SuccMBB->getNumber(); + if (VI.AliveBlocks.test(SuccIdx)) + return true; + OpSuccBlocks.push_back(SuccMBB); + } + + // Check to see if this value is live because there is a use in a successor + // that kills it. + switch (OpSuccBlocks.size()) { + case 1: { + MachineBasicBlock *SuccMBB = OpSuccBlocks[0]; + for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i) + if (VI.Kills[i]->getParent() == SuccMBB) + return true; + break; + } + case 2: { + MachineBasicBlock *SuccMBB1 = OpSuccBlocks[0], *SuccMBB2 = OpSuccBlocks[1]; + for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i) + if (VI.Kills[i]->getParent() == SuccMBB1 || + VI.Kills[i]->getParent() == SuccMBB2) + return true; + break; + } + default: + std::sort(OpSuccBlocks.begin(), OpSuccBlocks.end()); + for (unsigned i = 0, e = VI.Kills.size(); i != e; ++i) + if (std::binary_search(OpSuccBlocks.begin(), OpSuccBlocks.end(), + VI.Kills[i]->getParent())) + return true; + } + return false; +} + +bool llvm::PHIElimination::isLiveIn(unsigned Reg, const MachineBasicBlock &MBB, + LiveVariables &LV) { + LiveVariables::VarInfo &VI = LV.getVarInfo(Reg); + + if (VI.AliveBlocks.test(MBB.getNumber())) + return true; + + // defined in MBB? + const MachineInstr *Def = MRI->getVRegDef(Reg); + if (Def && Def->getParent() == &MBB) + return false; + + // killed in MBB? + return VI.findKill(&MBB); +} + +MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A, + MachineBasicBlock *B) { + assert(A && B && "Missing MBB end point"); + + MachineFunction *MF = A->getParent(); + + // We may need to update A's terminator, but we can't do that if AnalyzeBranch + // fails. If A uses a jump table, we won't touch it. + const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); + MachineBasicBlock *TBB = 0, *FBB = 0; + SmallVector<MachineOperand, 4> Cond; + if (TII->AnalyzeBranch(*A, TBB, FBB, Cond)) + return NULL; + + ++NumSplits; + + MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock(); + MF->push_back(NMBB); + DEBUG(errs() << "PHIElimination splitting critical edge:" + " BB#" << A->getNumber() + << " -- BB#" << NMBB->getNumber() + << " -- BB#" << B->getNumber() << '\n'); + + A->ReplaceUsesOfBlockWith(B, NMBB); + // If A may fall through to B, we may have to insert a branch. + if (A->isLayoutSuccessor(B)) + A->updateTerminator(); + + // Insert unconditional "jump B" instruction in NMBB. + NMBB->addSuccessor(B); + Cond.clear(); + MF->getTarget().getInstrInfo()->InsertBranch(*NMBB, B, NULL, Cond); + + // Fix PHI nodes in B so they refer to NMBB instead of A + for (MachineBasicBlock::iterator i = B->begin(), e = B->end(); + i != e && i->getOpcode() == TargetInstrInfo::PHI; ++i) + for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2) + if (i->getOperand(ni+1).getMBB() == A) + i->getOperand(ni+1).setMBB(NMBB); + + if (LiveVariables *LV=getAnalysisIfAvailable<LiveVariables>()) + LV->addNewBlock(NMBB, A); + + if (MachineDominatorTree *MDT=getAnalysisIfAvailable<MachineDominatorTree>()) + MDT->addNewBlock(NMBB, A); + + return NMBB; +} |