mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89530 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
983c7fe847
commit
323d8c3ed7
@ -107,6 +107,13 @@ public:
|
||||
/// 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 @@ public:
|
||||
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
|
||||
|
@ -656,35 +656,45 @@ void LiveVariables::analyzePHINodes(const MachineFunction& Fn) {
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
@ -353,7 +353,7 @@ bool llvm::PHIElimination::SplitPHIEdges(MachineFunction &MF,
|
||||
// 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 @@ bool llvm::PHIElimination::isLiveOut(unsigned Reg, const MachineBasicBlock &MBB,
|
||||
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 @@ MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
|
||||
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);
|
||||
|
@ -99,12 +99,6 @@ namespace llvm {
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user