[llvm-commits] [llvm] r53256 - /llvm/trunk/lib/CodeGen/RegAllocLocal.cpp

Devang Patel dpatel at apple.com
Tue Jul 8 16:15:19 PDT 2008


This breaks build.

RegAllocLocal.cpp:666: error: conversion from ‘llvm::MachineInstr’ to  
non-scalar type ‘llvm::alist_iterator<llvm::MachineInstr,  
llvm::MachineInstr, llvm::MachineInstr,  
llvm::ilist_iterator<llvm::alist_node<llvm::MachineInstr,  
llvm::MachineInstr> > >’ requested

On Jul 8, 2008, at 3:24 PM, Owen Anderson wrote:

> Author: resistor
> Date: Tue Jul  8 17:24:50 2008
> New Revision: 53256
>
> URL: http://llvm.org/viewvc/llvm-project?rev=53256&view=rev
> Log:
> Make the local register allocator compute (purely local) liveness  
> information for itself
> rather than depending on LiveVariables.  This decreases compile time  
> from:
> 0.5909s (LV + Regalloc) to 0.421s (just regalloc).
>
> Modified:
>    llvm/trunk/lib/CodeGen/RegAllocLocal.cpp
>
> Modified: llvm/trunk/lib/CodeGen/RegAllocLocal.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocLocal.cpp?rev=53256&r1=53255&r2=53256&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/RegAllocLocal.cpp (original)
> +++ llvm/trunk/lib/CodeGen/RegAllocLocal.cpp Tue Jul  8 17:24:50 2008
> @@ -14,7 +14,6 @@
>
> #define DEBUG_TYPE "regalloc"
> #include "llvm/BasicBlock.h"
> -#include "llvm/CodeGen/LiveVariables.h"
> #include "llvm/CodeGen/MachineFunctionPass.h"
> #include "llvm/CodeGen/MachineInstr.h"
> #include "llvm/CodeGen/MachineFrameInfo.h"
> @@ -101,6 +100,10 @@
>     // is no reason to spill it to memory when we need the register  
> back.
>     //
>     BitVector VirtRegModified;
> +
> +    // UsedInMultipleBlocks - Tracks whether a particular register  
> is used in
> +    // more than one block.
> +    BitVector UsedInMultipleBlocks;
>
>     void markVirtRegModified(unsigned Reg, bool Val = true) {
>       assert(TargetRegisterInfo::isVirtualRegister(Reg) && "Illegal  
> VirtReg!");
> @@ -147,7 +150,6 @@
>     }
>
>     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
> -      AU.addRequired<LiveVariables>();
>       AU.addRequiredID(PHIEliminationID);
>       AU.addRequiredID(TwoAddressInstructionPassID);
>       MachineFunctionPass::getAnalysisUsage(AU);
> @@ -539,6 +541,26 @@
>   return false;
> }
>
> +// precedes - Helper function to determine with MachineInstr A
> +// precedes MachineInstr B within the same MBB.
> +static bool precedes(MachineBasicBlock::iterator A,
> +                     MachineBasicBlock::iterator B) {
> +  if (A == B)
> +    return false;
> +
> +  MachineBasicBlock::iterator I = A->getParent()->begin();
> +  while (I != A->getParent()->end()) {
> +    if (I == A)
> +      return true;
> +    else if (I == B)
> +      return false;
> +
> +    ++I;
> +  }
> +
> +  return false;
> +}
> +
> void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
>   // loop over each instruction
>   MachineBasicBlock::iterator MII = MBB.begin();
> @@ -567,6 +589,97 @@
>     }
>   }
>
> +
> +  MachineRegisterInfo& MRI = MBB.getParent()->getRegInfo();
> +  // Keep track of the most recently seen previous use or def of  
> each reg,
> +  // so that we can update them with dead/kill markers.
> +  std::map<unsigned, std::pair<MachineInstr*, unsigned> > LastUseDef;
> +  for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
> +       I != E; ++I) {
> +    for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
> +      MachineOperand& MO = I->getOperand(i);
> +      // Uses don't trigger any flags, but we need to save
> +      // them for later.  Also, we have to process these
> +      // _before_ processing the defs, since an instr
> +      // uses regs before it defs them.
> +      if (MO.isReg() && MO.getReg() && MO.isUse())
> +        LastUseDef[MO.getReg()] = std::make_pair(I, i);
> +    }
> +
> +    for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
> +      MachineOperand& MO = I->getOperand(i);
> +      // Defs others than 2-addr redefs _do_ trigger flag changes:
> +      //   - A def followed by a def is dead
> +      //   - A use followed by a def is a kill
> +      if (MO.isReg() && MO.getReg() && MO.isDef() &&
> +         !I->isRegReDefinedByTwoAddr(MO.getReg())) {
> +        std::map<unsigned, std::pair<MachineInstr*, unsigned>  
> >::iterator
> +          last = LastUseDef.find(MO.getReg());
> +        if (last != LastUseDef.end()) {
> +          MachineOperand& lastUD =
> +                      last->second.first->getOperand(last- 
> >second.second);
> +          if (lastUD.isDef())
> +            lastUD.setIsDead(true);
> +          else if (lastUD.isUse())
> +            lastUD.setIsKill(true);
> +        }
> +
> +        LastUseDef[MO.getReg()] = std::make_pair(I, i);
> +      }
> +    }
> +  }
> +
> +  // Live-out (of the function) registers contain return values of  
> the function,
> +  // so we need to make sure they are alive at return time.
> +  if (!MBB.empty() && MBB.back().getDesc().isReturn()) {
> +    MachineInstr* Ret = &MBB.back();
> +    for (MachineRegisterInfo::liveout_iterator
> +         I = MF->getRegInfo().liveout_begin(),
> +         E = MF->getRegInfo().liveout_end(); I != E; ++I)
> +      if (!Ret->readsRegister(*I)) {
> +        Ret->addOperand(MachineOperand::CreateReg(*I, false, true));
> +        LastUseDef[*I] = std::make_pair(Ret, Ret- 
> >getNumOperands()-1);
> +      }
> +  }
> +
> +  // Finally, loop over the final use/def of each reg
> +  // in the block and determine if it is dead.
> +  for (std::map<unsigned, std::pair<MachineInstr*, unsigned>  
> >::iterator
> +       I = LastUseDef.begin(), E = LastUseDef.end(); I != E; ++I) {
> +    MachineInstr* MI = I->second.first;
> +    unsigned idx = I->second.second;
> +    MachineOperand& MO = MI->getOperand(idx);
> +
> +    bool isPhysReg =  
> TargetRegisterInfo::isPhysicalRegister(MO.getReg());
> +
> +    // A crude approximation of "live-out" calculation
> +    bool usedOutsideBlock = isPhysReg ? false :
> +          UsedInMultipleBlocks.test(MO.getReg() -
> +                                     
> TargetRegisterInfo::FirstVirtualRegister);
> +    if (!isPhysReg && !usedOutsideBlock)
> +      for (MachineRegisterInfo::reg_iterator UI =  
> MRI.reg_begin(MO.getReg()),
> +           UE = MRI.reg_end(); UI != UE; ++UI)
> +        // Two cases:
> +        // - used in another block
> +        // - used in the same block before it is defined (loop)
> +        if (UI->getParent() != &MBB ||
> +            (MO.isDef() && UI.getOperand().isUse() && precedes(*UI,  
> MI))) {
> +          UsedInMultipleBlocks.set(MO.getReg() -
> +                                    
> TargetRegisterInfo::FirstVirtualRegister);
> +          usedOutsideBlock = true;
> +          break;
> +        }
> +
> +    // Physical registers and those that are not live-out of the  
> block
> +    // are killed/dead at their last use/def within this block.
> +    if (isPhysReg || !usedOutsideBlock) {
> +      if (MO.isUse())
> +        MO.setIsKill(true);
> +      else if (MI->getOperand(idx).isDef())
> +        MO.setIsDead(true);
> +    }
> +  }
> +
>   // Otherwise, sequentially allocate each instruction in the MBB.
>   while (MII != MBB.end()) {
>     MachineInstr *MI = MII++;
> @@ -802,7 +915,6 @@
>   PhysRegsUseOrder.clear();
> }
>
> -
> /// runOnMachineFunction - Register allocate the whole function
> ///
> bool RALocal::runOnMachineFunction(MachineFunction &Fn) {
> @@ -830,7 +942,8 @@
>   Virt2PhysRegMap.grow(LastVirtReg);
>   Virt2LastUseMap.grow(LastVirtReg);
>   VirtRegModified.resize(LastVirtReg+1- 
> TargetRegisterInfo::FirstVirtualRegister);
> -
> +  UsedInMultipleBlocks.resize(LastVirtReg+1- 
> TargetRegisterInfo::FirstVirtualRegister);
> +
>   // Loop over all of the basic blocks, eliminating virtual register  
> references
>   for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
>        MBB != MBBe; ++MBB)
> @@ -839,6 +952,7 @@
>   StackSlotForVirtReg.clear();
>   PhysRegsUsed.clear();
>   VirtRegModified.clear();
> +  UsedInMultipleBlocks.clear();
>   Virt2PhysRegMap.clear();
>   Virt2LastUseMap.clear();
>   return true;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

-
Devang







More information about the llvm-commits mailing list