[Mesa-dev] [PATCH] SI: further simplify SGPR liveness fix
Christian König
deathsimple at vodafone.de
Wed Nov 14 06:54:13 PST 2012
Based on already merged v4 of "fix SGPR liveness"
Signed-off-by: Christian König <deathsimple at 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
More information about the mesa-dev
mailing list