[Mesa-dev] [PATCH] SI: fix SGPR liveness v2

Tom Stellard tom at stellard.net
Fri Nov 9 06:55:27 PST 2012


On Fri, Nov 09, 2012 at 03:25:33PM +0100, Christian König wrote:
> SGPRs are not affected by flow control.
> 
> v2: don't use liveness analyse any more, handle partial
>     dominated end notes.
>

Reviewed-by: Tom Stellard <thomas.stellard at amd.com> 
> Signed-off-by: Christian König <deathsimple at vodafone.de>
> ---
>  lib/Target/AMDGPU/AMDGPU.h                |    1 +
>  lib/Target/AMDGPU/AMDGPUTargetMachine.cpp |    3 +
>  lib/Target/AMDGPU/CMakeLists.txt          |    1 +
>  lib/Target/AMDGPU/SIFixSGPRLiveness.cpp   |  192 +++++++++++++++++++++++++++++
>  4 files changed, 197 insertions(+)
>  create mode 100644 lib/Target/AMDGPU/SIFixSGPRLiveness.cpp
> 
> diff --git a/lib/Target/AMDGPU/AMDGPU.h b/lib/Target/AMDGPU/AMDGPU.h
> index c722d04..33a74dc 100644
> --- a/lib/Target/AMDGPU/AMDGPU.h
> +++ b/lib/Target/AMDGPU/AMDGPU.h
> @@ -28,6 +28,7 @@ FunctionPass *createSIAssignInterpRegsPass(TargetMachine &tm);
>  FunctionPass *createSILowerFlowControlPass(TargetMachine &tm);
>  FunctionPass *createSICodeEmitterPass(formatted_raw_ostream &OS);
>  FunctionPass *createSILowerLiteralConstantsPass(TargetMachine &tm);
> +FunctionPass *createSIFixSGPRLivenessPass(TargetMachine &tm);
>  
>  // Passes common to R600 and SI
>  FunctionPass *createAMDGPUConvertToISAPass(TargetMachine &tm);
> diff --git a/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
> index dd4b733..024ff3d 100644
> --- a/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
> +++ b/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
> @@ -111,6 +111,9 @@ bool AMDGPUPassConfig::addPreRegAlloc() {
>      addPass(createSIAssignInterpRegsPass(*TM));
>    }
>    addPass(createAMDGPUConvertToISAPass(*TM));
> +  if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) {
> +    addPass(createSIFixSGPRLivenessPass(*TM));
> +  }
>    return false;
>  }
>  
> diff --git a/lib/Target/AMDGPU/CMakeLists.txt b/lib/Target/AMDGPU/CMakeLists.txt
> index 6bb7ba0..5e013f6 100644
> --- a/lib/Target/AMDGPU/CMakeLists.txt
> +++ b/lib/Target/AMDGPU/CMakeLists.txt
> @@ -44,6 +44,7 @@ add_llvm_target(AMDGPUCodeGen
>    SILowerFlowControl.cpp
>    SIMachineFunctionInfo.cpp
>    SIRegisterInfo.cpp
> +  SIPreColorSGPRs.cpp
>    )
>  
>  add_dependencies(LLVMAMDGPUCodeGen intrinsics_gen)
> diff --git a/lib/Target/AMDGPU/SIFixSGPRLiveness.cpp b/lib/Target/AMDGPU/SIFixSGPRLiveness.cpp
> new file mode 100644
> index 0000000..028753e
> --- /dev/null
> +++ b/lib/Target/AMDGPU/SIFixSGPRLiveness.cpp
> @@ -0,0 +1,192 @@
> +//===-- SIFixSGPRLiveness.cpp - SGPR liveness adjustment ------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// SGPRs are not affected by flow control. This pass adjust SGPR liveness in
> +// so that the register allocator can still correctly allocate them.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "AMDGPU.h"
> +#include "llvm/CodeGen/MachineFunctionPass.h"
> +#include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/CodeGen/MachineDominators.h"
> +#include "llvm/CodeGen/MachinePostDominators.h"
> +#include "llvm/CodeGen/MachineInstrBuilder.h"
> +
> +using namespace llvm;
> +
> +namespace {
> +
> +class SIFixSGPRLiveness : public MachineFunctionPass {
> +private:
> +  static char ID;
> +
> +  const TargetInstrInfo *TII;
> +  MachineRegisterInfo *MRI;
> +  MachineDominatorTree *MD;
> +  MachinePostDominatorTree *MPD;
> +
> +  bool isSGPR(const TargetRegisterClass *RegClass)
> +  {
> +    return RegClass == &AMDGPU::SReg_1RegClass ||
> +           RegClass == &AMDGPU::SReg_32RegClass ||
> +           RegClass == &AMDGPU::SReg_64RegClass ||
> +           RegClass == &AMDGPU::SReg_128RegClass ||
> +           RegClass == &AMDGPU::SReg_256RegClass;
> +  }
> +
> +  void addKill(MachineBasicBlock::iterator I, unsigned Reg);
> +  MachineBasicBlock *handleUses(unsigned VirtReg, MachineBasicBlock *Begin);
> +  MachineBasicBlock *handleSuccs(MachineBasicBlock *Begin,
> +                                 MachineBasicBlock *End);
> +  void handlePreds(MachineBasicBlock *Begin, MachineBasicBlock *End,
> +                   unsigned VirtReg);
> +
> +  bool handleVirtReg(unsigned VirtReg);
> +
> +public:
> +  SIFixSGPRLiveness(TargetMachine &tm);
> +
> +  virtual bool runOnMachineFunction(MachineFunction &MF);
> +
> +  virtual const char *getPassName() const {
> +    return "SI fix SGPR liveness pass";
> +  }
> +
> +  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
> +};
> +
> +} // end anonymous namespace
> +
> +char SIFixSGPRLiveness::ID = 0;
> +
> +SIFixSGPRLiveness::SIFixSGPRLiveness(TargetMachine &tm):
> +  MachineFunctionPass(ID),
> +  TII(tm.getInstrInfo())
> +{
> +  initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
> +}
> +
> +void SIFixSGPRLiveness::getAnalysisUsage(AnalysisUsage &AU) const
> +{
> +  AU.addRequired<MachineDominatorTree>();
> +  AU.addRequired<MachinePostDominatorTree>();
> +  AU.setPreservesCFG();
> +  MachineFunctionPass::getAnalysisUsage(AU);
> +}
> +
> +void SIFixSGPRLiveness::addKill(MachineBasicBlock::iterator I, unsigned Reg)
> +{
> +  MachineBasicBlock *MBB = I->getParent();
> +
> +  BuildMI(*MBB, I, DebugLoc(), TII->get(TargetOpcode::KILL)).addReg(Reg);
> +}
> +
> +// Find the common post dominator of all uses
> +MachineBasicBlock *SIFixSGPRLiveness::handleUses(unsigned VirtReg,
> +                                                 MachineBasicBlock *Begin)
> +{
> +  MachineBasicBlock *LastUse = Begin, *End = Begin;
> +
> +  MachineRegisterInfo::use_iterator i, e;
> +  for (i = MRI->use_begin(VirtReg), e = MRI->use_end(); i != e; ++i) {
> +    MachineBasicBlock *MBB = i->getParent();
> +    if (LastUse == MBB)
> +      continue;
> +
> +    LastUse = MBB;
> +    End = MPD->findNearestCommonDominator(End, MBB);
> +  }
> +
> +  return End;
> +}
> +
> +// Find the common post dominator of all successors
> +MachineBasicBlock *SIFixSGPRLiveness::handleSuccs(MachineBasicBlock *Begin,
> +                                                  MachineBasicBlock *End)
> +{
> +  MachineBasicBlock::succ_iterator i, e;
> +  for (i = Begin->succ_begin(), e = Begin->succ_end(); i != e; ++i) {
> +    End = MPD->findNearestCommonDominator(End, *i);
> +  }
> +  return End;
> +}
> +
> +// Handles predecessors separately, only add KILLs to dominated ones
> +void SIFixSGPRLiveness::handlePreds(MachineBasicBlock *Begin,
> +                                    MachineBasicBlock *End,
> +                                    unsigned VirtReg)
> +{
> +  MachineBasicBlock::pred_iterator i, e;
> +  for (i = End->pred_begin(), e = End->pred_end(); i != e; ++i) {
> +
> +    if (MD->dominates(End, *i))
> +      continue; // ignore loops
> +
> +    if (MD->dominates(*i, Begin))
> +      continue; // too far up, abort search
> +
> +    if (MD->dominates(Begin, *i)) {
> +      // found end of livetime
> +      addKill((*i)->getFirstTerminator(), VirtReg);
> +      continue;
> +    }
> +
> +    handlePreds(Begin, *i, VirtReg);
> +  }
> +}
> +
> +bool SIFixSGPRLiveness::handleVirtReg(unsigned VirtReg)
> +{
> +
> +  MachineInstr *Def = MRI->getVRegDef(VirtReg);
> +  if (!Def || MRI->use_empty(VirtReg))
> +    return false; // No definition or not used
> +
> +  MachineBasicBlock *Begin = Def->getParent();
> +  MachineBasicBlock *End = handleUses(VirtReg, Begin);
> +  if (Begin == End)
> +    return false; // Defined and only used in the same block
> +
> +  End = handleSuccs(Begin, End);
> +  if (MD->dominates(Begin, End)) {
> +    // Lifetime dominate the end node, just kill it here
> +    addKill(End->getFirstNonPHI(), VirtReg);
> +  } else {
> +    // only some predecessors are dominate, handle them separately
> +    handlePreds(Begin, End, VirtReg);
> +  }
> +  return true;
> +}
> +
> +bool SIFixSGPRLiveness::runOnMachineFunction(MachineFunction &MF)
> +{
> +  bool Changes = false;
> +
> +  MRI = &MF.getRegInfo();
> +  MD = &getAnalysis<MachineDominatorTree>();
> +  MPD = &getAnalysis<MachinePostDominatorTree>();
> +
> +  for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
> +    unsigned VirtReg = TargetRegisterInfo::index2VirtReg(i);
> +
> +    const TargetRegisterClass *RegClass = MRI->getRegClass(VirtReg);
> +    if (!isSGPR(RegClass))
> +      continue;
> +
> +    Changes |= handleVirtReg(VirtReg);
> +  }
> +
> +  return Changes;
> +}
> +
> +FunctionPass *llvm::createSIFixSGPRLivenessPass(TargetMachine &tm)
> +{
> +  return new SIFixSGPRLiveness(tm);
> +}
> -- 
> 1.7.9.5
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list