[llvm-commits] [llvm] r89530 - in /llvm/trunk: include/llvm/CodeGen/LiveVariables.h lib/CodeGen/LiveVariables.cpp lib/CodeGen/PHIElimination.cpp lib/CodeGen/PHIElimination.h

Chris Lattner clattner at apple.com
Sun Nov 22 06:09:31 PST 2009


On Nov 20, 2009, at 6:05 PM, Jakob Stoklund Olesen wrote:

> Author: stoklund
> Date: Fri Nov 20 20:05:21 2009
> New Revision: 89530
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=89530&view=rev
> Log:
> Be more clever about calculating live variables through new basic blocks.
> 
> When splitting a critical edge, the registers live through the edge are:
> 
> - Used in a PHI instruction, or
> - Live out from the predecessor, and
> - Live in to the successor.
> 
> This allows the coalescer to eliminate even more phi joins.

Hi Jakob,

I haven't looked at the code at all, but I want to bring up one subtlety of critical edge splitting.  In switches which have multiple edges to the same destination (on different values), these edges are always critical.  However, they should be split together as a unit, not individually.  I don't know if your code considers this or not, but this is the idea behind the "SplitEdgeNicely" logic that appears in a couple places.

-Chris

> 
> Modified:
>    llvm/trunk/include/llvm/CodeGen/LiveVariables.h
>    llvm/trunk/lib/CodeGen/LiveVariables.cpp
>    llvm/trunk/lib/CodeGen/PHIElimination.cpp
>    llvm/trunk/lib/CodeGen/PHIElimination.h
> 
> Modified: llvm/trunk/include/llvm/CodeGen/LiveVariables.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveVariables.h?rev=89530&r1=89529&r2=89530&view=diff
> 
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/LiveVariables.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/LiveVariables.h Fri Nov 20 20:05:21 2009
> @@ -107,6 +107,13 @@
>     /// findKill - Find a kill instruction in MBB. Return NULL if none is found.
>     MachineInstr *findKill(const MachineBasicBlock *MBB) const;
> 
> +    /// isLiveIn - Is Reg live in to MBB? This means that Reg is live through
> +    /// MBB, or it is killed in MBB. If Reg is only used by PHI instructions in
> +    /// MBB, it is not considered live in.
> +    bool isLiveIn(const MachineBasicBlock &MBB,
> +                  unsigned Reg,
> +                  MachineRegisterInfo &MRI);
> +
>     void dump() const;
>   };
> 
> @@ -267,11 +274,17 @@
>   void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
>                         MachineInstr *MI);
> 
> -  /// addNewBlock - Add a new basic block BB as an empty succcessor to
> -  /// DomBB. All variables that are live out of DomBB will be marked as passing
> -  /// live through BB. This method assumes that the machine code is still in SSA
> -  /// form.
> -  void addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB);
> +  bool isLiveIn(unsigned Reg, const MachineBasicBlock &MBB) {
> +    return getVarInfo(Reg).isLiveIn(MBB, Reg, *MRI);
> +  }
> +
> +  /// addNewBlock - Add a new basic block BB between DomBB and SuccBB. All
> +  /// variables that are live out of DomBB and live into SuccBB will be marked
> +  /// as passing live through BB. This method assumes that the machine code is
> +  /// still in SSA form.
> +  void addNewBlock(MachineBasicBlock *BB,
> +                   MachineBasicBlock *DomBB,
> +                   MachineBasicBlock *SuccBB);
> };
> 
> } // End llvm namespace
> 
> Modified: llvm/trunk/lib/CodeGen/LiveVariables.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveVariables.cpp?rev=89530&r1=89529&r2=89530&view=diff
> 
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/LiveVariables.cpp (original)
> +++ llvm/trunk/lib/CodeGen/LiveVariables.cpp Fri Nov 20 20:05:21 2009
> @@ -656,35 +656,45 @@
>           .push_back(BBI->getOperand(i).getReg());
> }
> 
> +bool LiveVariables::VarInfo::isLiveIn(const MachineBasicBlock &MBB,
> +                                      unsigned Reg,
> +                                      MachineRegisterInfo &MRI) {
> +  unsigned Num = MBB.getNumber();
> +
> +  // Reg is live-through.
> +  if (AliveBlocks.test(Num))
> +    return true;
> +
> +  // Registers defined in MBB cannot be live in.
> +  const MachineInstr *Def = MRI.getVRegDef(Reg);
> +  if (Def && Def->getParent() == &MBB)
> +    return false;
> +
> + // Reg was not defined in MBB, was it killed here?
> +  return findKill(&MBB);
> +}
> +
> /// addNewBlock - Add a new basic block BB as an empty succcessor to DomBB. All
> /// variables that are live out of DomBB will be marked as passing live through
> /// BB.
> void LiveVariables::addNewBlock(MachineBasicBlock *BB,
> -                                MachineBasicBlock *DomBB) {
> +                                MachineBasicBlock *DomBB,
> +                                MachineBasicBlock *SuccBB) {
>   const unsigned NumNew = BB->getNumber();
> -  const unsigned NumDom = DomBB->getNumber();
> +
> +  // All registers used by PHI nodes in SuccBB must be live through BB.
> +  for (MachineBasicBlock::const_iterator BBI = SuccBB->begin(),
> +         BBE = SuccBB->end();
> +       BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI)
> +    for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2)
> +      if (BBI->getOperand(i+1).getMBB() == BB)
> +        getVarInfo(BBI->getOperand(i).getReg()).AliveBlocks.set(NumNew);
> 
>   // Update info for all live variables
>   for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
>          E = MRI->getLastVirtReg()+1; Reg != E; ++Reg) {
>     VarInfo &VI = getVarInfo(Reg);
> -
> -    // Anything live through DomBB is also live through BB.
> -    if (VI.AliveBlocks.test(NumDom)) {
> +    if (!VI.AliveBlocks.test(NumNew) && VI.isLiveIn(*SuccBB, Reg, *MRI))
>       VI.AliveBlocks.set(NumNew);
> -      continue;
> -    }
> -
> -    // Variables not defined in DomBB cannot be live out.
> -    const MachineInstr *Def = MRI->getVRegDef(Reg);
> -    if (!Def || Def->getParent() != DomBB)
> -      continue;
> -
> -    // Killed by DomBB?
> -    if (VI.findKill(DomBB))
> -      continue;
> -
> -    // This register is defined in DomBB and live out
> -    VI.AliveBlocks.set(NumNew);
>   }
> }
> 
> Modified: llvm/trunk/lib/CodeGen/PHIElimination.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.cpp?rev=89530&r1=89529&r2=89530&view=diff
> 
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/PHIElimination.cpp (original)
> +++ llvm/trunk/lib/CodeGen/PHIElimination.cpp Fri Nov 20 20:05:21 2009
> @@ -353,7 +353,7 @@
>       // 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))
> +      if (!LV.isLiveIn(Reg, MBB) && isLiveOut(Reg, *PreMBB, LV))
>         SplitCriticalEdge(PreMBB, &MBB);
>     }
>   }
> @@ -406,22 +406,6 @@
>   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");
> @@ -463,7 +447,7 @@
>         i->getOperand(ni+1).setMBB(NMBB);
> 
>   if (LiveVariables *LV=getAnalysisIfAvailable<LiveVariables>())
> -    LV->addNewBlock(NMBB, A);
> +    LV->addNewBlock(NMBB, A, B);
> 
>   if (MachineDominatorTree *MDT=getAnalysisIfAvailable<MachineDominatorTree>())
>     MDT->addNewBlock(NMBB, A);
> 
> Modified: llvm/trunk/lib/CodeGen/PHIElimination.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PHIElimination.h?rev=89530&r1=89529&r2=89530&view=diff
> 
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/PHIElimination.h (original)
> +++ llvm/trunk/lib/CodeGen/PHIElimination.h Fri Nov 20 20:05:21 2009
> @@ -99,12 +99,6 @@
>     bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB,
>                    LiveVariables &LV);
> 
> -    /// isLiveIn - Determine if Reg is live in to MBB, not considering PHI
> -    /// source registers. This means that Reg is either killed by MBB or passes
> -    /// through it.
> -    bool isLiveIn(unsigned Reg, const MachineBasicBlock &MBB,
> -                  LiveVariables &LV);
> -
>     /// SplitCriticalEdge - Split a critical edge from A to B by
>     /// inserting a new MBB. Update branches in A and PHI instructions
>     /// in B. Return the new block.
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list