diff options
| author | Bill Wendling <isanbard@gmail.com> | 2006-09-27 09:04:15 +0000 | 
|---|---|---|
| committer | Bill Wendling <isanbard@gmail.com> | 2006-09-27 09:04:15 +0000 | 
| commit | 0a7f617a6c8e6d204c8eafe95307afb8f40abbfc (patch) | |
| tree | 708ba00c6b57db552f09943f7913c91234f0d515 /llvm/lib/CodeGen | |
| parent | e03ca2ca4abc54a888748254b2b13c642ed3325e (diff) | |
| download | bcm5719-llvm-0a7f617a6c8e6d204c8eafe95307afb8f40abbfc.tar.gz bcm5719-llvm-0a7f617a6c8e6d204c8eafe95307afb8f40abbfc.zip  | |
PR878: Instead of calculating the vreg to PHI use count everytime we get
a function, do it up front in linear time (going through all of the
instructions once). We create a map out of them. Then it's no problem to
use the information in it during elimination...
llvm-svn: 30624
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/PHIElimination.cpp | 68 | 
1 files changed, 44 insertions, 24 deletions
diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp index 1cffca6b8ff..ea26bef65ae 100644 --- a/llvm/lib/CodeGen/PHIElimination.cpp +++ b/llvm/lib/CodeGen/PHIElimination.cpp @@ -34,12 +34,15 @@ namespace {    struct VISIBILITY_HIDDEN PNE : public MachineFunctionPass {      bool runOnMachineFunction(MachineFunction &Fn) { +      analyzePHINodes(Fn); +        bool Changed = false;        // 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); +      VRegPHIUseCount.clear();        return Changed;      } @@ -54,15 +57,26 @@ namespace {      ///      bool EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB);      void LowerAtomicPHINode(MachineBasicBlock &MBB, -                            MachineBasicBlock::iterator AfterPHIsIt, -                            DenseMap<unsigned, VirtReg2IndexFunctor> &VUC); +                            MachineBasicBlock::iterator AfterPHIsIt); + +    /// analyzePHINodes - Gather information about the PHI nodes in +    /// here. In particular, we want to map the number of uses of a virtual +    /// register which is used in a PHI node. We map that to the BB the +    /// vreg is coming from. This is used later to determine when the vreg +    /// is killed in the BB. +    ///  +    void analyzePHINodes(const MachineFunction& Fn); + +    typedef std::pair<const MachineBasicBlock*, unsigned> BBVRegPair; +    typedef std::map<BBVRegPair, unsigned> VRegPHIUse; + +    VRegPHIUse VRegPHIUseCount;    };    RegisterPass<PNE> X("phi-node-elimination",                        "Eliminate PHI nodes for register allocation");  } -  const PassInfo *llvm::PHIEliminationID = X.getPassInfo();  /// EliminatePHINodes - Eliminate phi nodes by inserting copy instructions in @@ -72,20 +86,6 @@ bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) {    if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI)      return false;   // Quick exit for basic blocks without PHIs. -  // VRegPHIUseCount - Keep track of the number of times each virtual register -  // is used by PHI nodes in successors of this block. -  DenseMap<unsigned, VirtReg2IndexFunctor> VRegPHIUseCount; -  VRegPHIUseCount.grow(MF.getSSARegMap()->getLastVirtReg()); - -  for (MachineBasicBlock::pred_iterator PI = MBB.pred_begin(), -         E = MBB.pred_end(); PI != E; ++PI) -    for (MachineBasicBlock::succ_iterator SI = (*PI)->succ_begin(), -           E = (*PI)->succ_end(); SI != E; ++SI) -      for (MachineBasicBlock::iterator BBI = (*SI)->begin(), E = (*SI)->end(); -           BBI != E && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) -        for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) -          VRegPHIUseCount[BBI->getOperand(i).getReg()]++; -          // Get an iterator to the first instruction after the last PHI node (this may    // also be the end of the basic block).    MachineBasicBlock::iterator AfterPHIsIt = MBB.begin(); @@ -93,9 +93,9 @@ bool PNE::EliminatePHINodes(MachineFunction &MF, MachineBasicBlock &MBB) {           AfterPHIsIt->getOpcode() == TargetInstrInfo::PHI)      ++AfterPHIsIt;    // Skip over all of the PHI nodes... -  while (MBB.front().getOpcode() == TargetInstrInfo::PHI) { -    LowerAtomicPHINode(MBB, AfterPHIsIt, VRegPHIUseCount); -  } +  while (MBB.front().getOpcode() == TargetInstrInfo::PHI) +    LowerAtomicPHINode(MBB, AfterPHIsIt); +    return true;  } @@ -115,8 +115,7 @@ static bool InstructionUsesRegister(MachineInstr *MI, unsigned SrcReg) {  /// atomic execution of PHIs.  This lowering method is always correct all of the  /// time.  void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB, -                             MachineBasicBlock::iterator AfterPHIsIt, -                   DenseMap<unsigned, VirtReg2IndexFunctor> &VRegPHIUseCount) { +                             MachineBasicBlock::iterator AfterPHIsIt) {    // Unlink the PHI node from the basic block, but don't delete the PHI yet.    MachineInstr *MPhi = MBB.remove(MBB.begin()); @@ -167,7 +166,9 @@ void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB,    // node.    unsigned NumPreds = (MPhi->getNumOperands()-1)/2;    for (unsigned i = 1; i != MPhi->getNumOperands(); i += 2) -    VRegPHIUseCount[MPhi->getOperand(i).getReg()] -= NumPreds; +    VRegPHIUseCount[BBVRegPair( +                      MPhi->getOperand(i + 1).getMachineBasicBlock(), +                      MPhi->getOperand(i).getReg())] -= NumPreds;    // Now loop over all of the incoming arguments, changing them to copy into    // the IncomingReg register in the corresponding predecessor basic block. @@ -219,7 +220,10 @@ void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB,      //      // Is it used by any PHI instructions in this block? -    bool ValueIsLive = VRegPHIUseCount[SrcReg] != 0; +    bool ValueIsLive =  +      VRegPHIUseCount[BBVRegPair( +                        MPhi->getOperand(i).getMachineBasicBlock(), +                        SrcReg)] != 0;      std::vector<MachineBasicBlock*> OpSuccBlocks; @@ -317,3 +321,19 @@ void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB,    delete MPhi;    ++NumAtomic;  } + +/// analyzePHINodes - Gather information about the PHI nodes in here. In +/// particular, we want to map the number of uses of a virtual register which is +/// used in a PHI node. We map that to the BB the vreg is coming from. This is +/// used later to determine when the vreg is killed in the BB. +///  +void PNE::analyzePHINodes(const MachineFunction& Fn) { +  for (MachineFunction::const_iterator I = Fn.begin(), E = Fn.end(); +       I != E; ++I) +    for (MachineBasicBlock::const_iterator BBI = I->begin(), BBE = I->end(); +         BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) +      for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) +        VRegPHIUseCount[BBVRegPair( +                          BBI->getOperand(i + 1).getMachineBasicBlock(), +                          BBI->getOperand(i).getReg())]++; +}  | 

