Based on already merged v4 of "fix SGPR liveness" Signed-off-by: Christian König <deathsim...@vodafone.de> --- lib/Target/AMDGPU/AMDGPU.h | 4 +- lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 12 ++- lib/Target/AMDGPU/SIFixSGPRLiveness.cpp | 152 +++++++++++++++-------------- 3 files changed, 89 insertions(+), 79 deletions(-)
diff --git a/lib/Target/AMDGPU/AMDGPU.h b/lib/Target/AMDGPU/AMDGPU.h index 2a06ade..b51cc90 100644 --- a/lib/Target/AMDGPU/AMDGPU.h +++ b/lib/Target/AMDGPU/AMDGPU.h @@ -28,7 +28,9 @@ FunctionPass *createSIAssignInterpRegsPass(TargetMachine &tm); FunctionPass *createSILowerControlFlowPass(TargetMachine &tm); FunctionPass *createSICodeEmitterPass(formatted_raw_ostream &OS); FunctionPass *createSILowerLiteralConstantsPass(TargetMachine &tm); -FunctionPass *createSIFixSGPRLivenessPass(TargetMachine &tm); + +void initializeSIFixSGPRLivenessPass(PassRegistry &Registry); +extern char &SIFixSGPRLivenessID; // 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 5c4af91..67ea931 100644 --- a/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -73,7 +73,14 @@ namespace { class AMDGPUPassConfig : public TargetPassConfig { public: AMDGPUPassConfig(AMDGPUTargetMachine *TM, PassManagerBase &PM) - : TargetPassConfig(TM, PM) {} + : TargetPassConfig(TM, PM) { + + const AMDGPUSubtarget &ST = TM->getSubtarget<AMDGPUSubtarget>(); + if (ST.device()->getGeneration() > AMDGPUDeviceInfo::HD6XXX) { + initializeSIFixSGPRLivenessPass(*PassRegistry::getPassRegistry()); + insertPass(&TwoAddressInstructionPassID, &SIFixSGPRLivenessID); + } + } AMDGPUTargetMachine &getAMDGPUTargetMachine() const { return getTM<AMDGPUTargetMachine>(); @@ -111,9 +118,6 @@ 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/SIFixSGPRLiveness.cpp b/lib/Target/AMDGPU/SIFixSGPRLiveness.cpp index 71641d1..77f58f8 100644 --- a/lib/Target/AMDGPU/SIFixSGPRLiveness.cpp +++ b/lib/Target/AMDGPU/SIFixSGPRLiveness.cpp @@ -7,17 +7,18 @@ // //===----------------------------------------------------------------------===// // -// SGPRs are not affected by control flow. This pass adjust SGPR liveness in +// 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/ADT/DepthFirstIterator.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.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; @@ -25,12 +26,11 @@ namespace { class SIFixSGPRLiveness : public MachineFunctionPass { private: - static char ID; - const TargetInstrInfo *TII; MachineRegisterInfo *MRI; MachineDominatorTree *MD; MachinePostDominatorTree *MPD; + LiveIntervals *LI; bool isSGPR(const TargetRegisterClass *RegClass) { @@ -41,15 +41,19 @@ private: RegClass == &AMDGPU::SReg_256RegClass; } - void addKill(MachineBasicBlock::iterator I, unsigned Reg); - MachineBasicBlock *handleUses(unsigned VirtReg, MachineBasicBlock *Begin); - void handlePreds(MachineBasicBlock *Begin, MachineBasicBlock *End, - unsigned VirtReg); + void getBegin(unsigned VirtReg, MachineInstr *&BeginDef, + MachineBasicBlock *&Begin); + + void getEnd(unsigned VirtReg, bool &EndUses, + MachineBasicBlock *&End); - bool handleVirtReg(unsigned VirtReg); + void handleVirtReg(unsigned VirtReg); public: - SIFixSGPRLiveness(TargetMachine &tm); + static char ID; + + SIFixSGPRLiveness(): + MachineFunctionPass(ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); @@ -63,35 +67,59 @@ public: } // end anonymous namespace char SIFixSGPRLiveness::ID = 0; +char &llvm::SIFixSGPRLivenessID = SIFixSGPRLiveness::ID; -SIFixSGPRLiveness::SIFixSGPRLiveness(TargetMachine &tm): - MachineFunctionPass(ID), - TII(tm.getInstrInfo()) -{ - initializeLiveIntervalsPass(*PassRegistry::getPassRegistry()); -} +INITIALIZE_PASS(SIFixSGPRLiveness, "sifixsgprliveness", + "SI fix SGPR liveness pass", false, false) void SIFixSGPRLiveness::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); AU.addRequired<MachineDominatorTree>(); AU.addRequired<MachinePostDominatorTree>(); - AU.setPreservesCFG(); + AU.addRequired<LiveIntervals>(); MachineFunctionPass::getAnalysisUsage(AU); } -void SIFixSGPRLiveness::addKill(MachineBasicBlock::iterator I, unsigned Reg) +// Find the common dominator of all defines +void SIFixSGPRLiveness::getBegin(unsigned VirtReg, MachineInstr *&BeginDef, + MachineBasicBlock *&Begin) { - MachineBasicBlock *MBB = I->getParent(); + MachineBasicBlock *LastDef = 0; + BeginDef = 0; + Begin = 0; + + MachineRegisterInfo::def_iterator i, e; + for (i = MRI->def_begin(VirtReg), e = MRI->def_end(); i != e; ++i) { + MachineBasicBlock *MBB = i->getParent(); + + if (!Begin) { + BeginDef = &*i; + LastDef = Begin = MBB; + continue; + } + + if (LastDef == MBB) + continue; - BuildMI(*MBB, I, DebugLoc(), TII->get(TargetOpcode::KILL)).addReg(Reg); + LastDef = MBB; + MBB = MD->findNearestCommonDominator(Begin, MBB); + + if (MBB == LastDef) + BeginDef = &*i; + else if (MBB != Begin) + BeginDef = 0; + + Begin = MBB; + } } // Find the common post dominator of all uses -MachineBasicBlock *SIFixSGPRLiveness::handleUses(unsigned VirtReg, - MachineBasicBlock *Begin) +void SIFixSGPRLiveness::getEnd(unsigned VirtReg, bool &EndUses, + MachineBasicBlock *&End) { - MachineBasicBlock *LastUse = Begin, *End = Begin; - bool EndUsesReg = true; + MachineBasicBlock *LastUse = End; + EndUses = true; MachineRegisterInfo::use_iterator i, e; for (i = MRI->use_begin(VirtReg), e = MRI->use_end(); i != e; ++i) { @@ -103,84 +131,60 @@ MachineBasicBlock *SIFixSGPRLiveness::handleUses(unsigned VirtReg, MBB = MPD->findNearestCommonDominator(End, MBB); if (MBB == LastUse) - EndUsesReg = true; + EndUses = true; else if (MBB != End) - EndUsesReg = false; + EndUses = false; End = MBB; } - - return EndUsesReg ? Begin : End; } -// Handles predecessors separately, only add KILLs to dominated ones -void SIFixSGPRLiveness::handlePreds(MachineBasicBlock *Begin, - MachineBasicBlock *End, - unsigned VirtReg) +void SIFixSGPRLiveness::handleVirtReg(unsigned VirtReg) { - MachineBasicBlock::pred_iterator i, e; - for (i = End->pred_begin(), e = End->pred_end(); i != e; ++i) { + MachineBasicBlock *Begin, *End; + MachineInstr *BeginDef; + bool EndUses; - if (MD->dominates(End, *i)) - continue; // ignore loops + getBegin(VirtReg, BeginDef, Begin); + if (!Begin) + return; // Neither defines nor used - if (MD->dominates(*i, Begin)) - continue; // too far up, abort search + End = Begin; + getEnd(VirtReg, EndUses, End); - if (MD->dominates(Begin, *i)) { - // found end of livetime - addKill((*i)->getFirstTerminator(), VirtReg); - continue; - } + if (EndUses) + return; // End uses register anyway - handlePreds(Begin, *i, VirtReg); - } -} + // Remove invalid analysis results + LI->getInterval(VirtReg).clear(); + MRI->clearKillFlags(VirtReg); -bool SIFixSGPRLiveness::handleVirtReg(unsigned VirtReg) -{ + // And add new one + if (BeginDef) + LI->addLiveRangeToEndOfBlock(VirtReg, BeginDef); - 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 - - 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); + df_iterator<MachineBasicBlock*> i = df_begin(Begin), e = df_end(End); + for (++i; i != e; ++i) { + LI->addLiveRangeToEndOfBlock(VirtReg, &i->front()); } - return true; } bool SIFixSGPRLiveness::runOnMachineFunction(MachineFunction &MF) { - bool Changes = false; - MRI = &MF.getRegInfo(); MD = &getAnalysis<MachineDominatorTree>(); MPD = &getAnalysis<MachinePostDominatorTree>(); + LI = &getAnalysis<LiveIntervals>(); for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) { unsigned VirtReg = TargetRegisterInfo::index2VirtReg(i); const TargetRegisterClass *RegClass = MRI->getRegClass(VirtReg); - if (!isSGPR(RegClass)) + if (!isSGPR(RegClass) || !LI->hasInterval(VirtReg)) continue; - Changes |= handleVirtReg(VirtReg); + handleVirtReg(VirtReg); } - return Changes; -} - -FunctionPass *llvm::createSIFixSGPRLivenessPass(TargetMachine &tm) -{ - return new SIFixSGPRLiveness(tm); + return false; } -- 1.7.9.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev