mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-19 04:32:19 +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.
|
/// findKill - Find a kill instruction in MBB. Return NULL if none is found.
|
||||||
MachineInstr *findKill(const MachineBasicBlock *MBB) const;
|
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;
|
void dump() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -267,11 +274,17 @@ public:
|
|||||||
void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
|
void HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
|
||||||
MachineInstr *MI);
|
MachineInstr *MI);
|
||||||
|
|
||||||
/// addNewBlock - Add a new basic block BB as an empty succcessor to
|
bool isLiveIn(unsigned Reg, const MachineBasicBlock &MBB) {
|
||||||
/// DomBB. All variables that are live out of DomBB will be marked as passing
|
return getVarInfo(Reg).isLiveIn(MBB, Reg, *MRI);
|
||||||
/// live through BB. This method assumes that the machine code is still in SSA
|
}
|
||||||
/// form.
|
|
||||||
void addNewBlock(MachineBasicBlock *BB, MachineBasicBlock *DomBB);
|
/// 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
|
} // End llvm namespace
|
||||||
|
@ -656,35 +656,45 @@ void LiveVariables::analyzePHINodes(const MachineFunction& Fn) {
|
|||||||
.push_back(BBI->getOperand(i).getReg());
|
.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
|
/// 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
|
/// variables that are live out of DomBB will be marked as passing live through
|
||||||
/// BB.
|
/// BB.
|
||||||
void LiveVariables::addNewBlock(MachineBasicBlock *BB,
|
void LiveVariables::addNewBlock(MachineBasicBlock *BB,
|
||||||
MachineBasicBlock *DomBB) {
|
MachineBasicBlock *DomBB,
|
||||||
|
MachineBasicBlock *SuccBB) {
|
||||||
const unsigned NumNew = BB->getNumber();
|
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
|
// Update info for all live variables
|
||||||
for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
|
for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
|
||||||
E = MRI->getLastVirtReg()+1; Reg != E; ++Reg) {
|
E = MRI->getLastVirtReg()+1; Reg != E; ++Reg) {
|
||||||
VarInfo &VI = getVarInfo(Reg);
|
VarInfo &VI = getVarInfo(Reg);
|
||||||
|
if (!VI.AliveBlocks.test(NumNew) && VI.isLiveIn(*SuccBB, Reg, *MRI))
|
||||||
// Anything live through DomBB is also live through BB.
|
|
||||||
if (VI.AliveBlocks.test(NumDom)) {
|
|
||||||
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);
|
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
|
// 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
|
// (not considering PHI nodes). If the register is live in to this block
|
||||||
// anyway, we would gain nothing from splitting.
|
// 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);
|
SplitCriticalEdge(PreMBB, &MBB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -406,22 +406,6 @@ bool llvm::PHIElimination::isLiveOut(unsigned Reg, const MachineBasicBlock &MBB,
|
|||||||
return false;
|
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 *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
|
||||||
MachineBasicBlock *B) {
|
MachineBasicBlock *B) {
|
||||||
assert(A && B && "Missing MBB end point");
|
assert(A && B && "Missing MBB end point");
|
||||||
@ -463,7 +447,7 @@ MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
|
|||||||
i->getOperand(ni+1).setMBB(NMBB);
|
i->getOperand(ni+1).setMBB(NMBB);
|
||||||
|
|
||||||
if (LiveVariables *LV=getAnalysisIfAvailable<LiveVariables>())
|
if (LiveVariables *LV=getAnalysisIfAvailable<LiveVariables>())
|
||||||
LV->addNewBlock(NMBB, A);
|
LV->addNewBlock(NMBB, A, B);
|
||||||
|
|
||||||
if (MachineDominatorTree *MDT=getAnalysisIfAvailable<MachineDominatorTree>())
|
if (MachineDominatorTree *MDT=getAnalysisIfAvailable<MachineDominatorTree>())
|
||||||
MDT->addNewBlock(NMBB, A);
|
MDT->addNewBlock(NMBB, A);
|
||||||
|
@ -99,12 +99,6 @@ namespace llvm {
|
|||||||
bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB,
|
bool isLiveOut(unsigned Reg, const MachineBasicBlock &MBB,
|
||||||
LiveVariables &LV);
|
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
|
/// SplitCriticalEdge - Split a critical edge from A to B by
|
||||||
/// inserting a new MBB. Update branches in A and PHI instructions
|
/// inserting a new MBB. Update branches in A and PHI instructions
|
||||||
/// in B. Return the new block.
|
/// in B. Return the new block.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user