forked from OSchip/llvm-project
Rewrite instructions as part of ConnectedVNInfoEqClasses::Distribute.
llvm-svn: 127779
This commit is contained in:
parent
47a823b281
commit
315b42c354
|
@ -548,8 +548,8 @@ namespace llvm {
|
||||||
/// }
|
/// }
|
||||||
|
|
||||||
class ConnectedVNInfoEqClasses {
|
class ConnectedVNInfoEqClasses {
|
||||||
LiveIntervals &lis_;
|
LiveIntervals &LIS;
|
||||||
IntEqClasses eqClass_;
|
IntEqClasses EqClass;
|
||||||
|
|
||||||
// Note that values a and b are connected.
|
// Note that values a and b are connected.
|
||||||
void Connect(unsigned a, unsigned b);
|
void Connect(unsigned a, unsigned b);
|
||||||
|
@ -557,7 +557,7 @@ namespace llvm {
|
||||||
unsigned Renumber();
|
unsigned Renumber();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : lis_(lis) {}
|
explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {}
|
||||||
|
|
||||||
/// Classify - Classify the values in LI into connected components.
|
/// Classify - Classify the values in LI into connected components.
|
||||||
/// Return the number of connected components.
|
/// Return the number of connected components.
|
||||||
|
@ -565,12 +565,13 @@ namespace llvm {
|
||||||
|
|
||||||
/// getEqClass - Classify creates equivalence classes numbered 0..N. Return
|
/// getEqClass - Classify creates equivalence classes numbered 0..N. Return
|
||||||
/// the equivalence class assigned the VNI.
|
/// the equivalence class assigned the VNI.
|
||||||
unsigned getEqClass(const VNInfo *VNI) const { return eqClass_[VNI->id]; }
|
unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; }
|
||||||
|
|
||||||
/// Distribute - Distribute values in LIV[0] into a separate LiveInterval
|
/// Distribute - Distribute values in LIV[0] into a separate LiveInterval
|
||||||
/// for each connected component. LIV must have a LiveInterval for each
|
/// for each connected component. LIV must have a LiveInterval for each
|
||||||
/// connected component. The LiveIntervals in Liv[1..] must be empty.
|
/// connected component. The LiveIntervals in Liv[1..] must be empty.
|
||||||
void Distribute(LiveInterval *LIV[]);
|
/// Instructions using LIV[0] are rewritten.
|
||||||
|
void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -719,8 +719,8 @@ void LiveRange::print(raw_ostream &os) const {
|
||||||
|
|
||||||
unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
|
unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
|
||||||
// Create initial equivalence classes.
|
// Create initial equivalence classes.
|
||||||
eqClass_.clear();
|
EqClass.clear();
|
||||||
eqClass_.grow(LI->getNumValNums());
|
EqClass.grow(LI->getNumValNums());
|
||||||
|
|
||||||
const VNInfo *used = 0, *unused = 0;
|
const VNInfo *used = 0, *unused = 0;
|
||||||
|
|
||||||
|
@ -731,48 +731,65 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) {
|
||||||
// Group all unused values into one class.
|
// Group all unused values into one class.
|
||||||
if (VNI->isUnused()) {
|
if (VNI->isUnused()) {
|
||||||
if (unused)
|
if (unused)
|
||||||
eqClass_.join(unused->id, VNI->id);
|
EqClass.join(unused->id, VNI->id);
|
||||||
unused = VNI;
|
unused = VNI;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
used = VNI;
|
used = VNI;
|
||||||
if (VNI->isPHIDef()) {
|
if (VNI->isPHIDef()) {
|
||||||
const MachineBasicBlock *MBB = lis_.getMBBFromIndex(VNI->def);
|
const MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def);
|
||||||
assert(MBB && "Phi-def has no defining MBB");
|
assert(MBB && "Phi-def has no defining MBB");
|
||||||
// Connect to values live out of predecessors.
|
// Connect to values live out of predecessors.
|
||||||
for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
|
for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
|
||||||
PE = MBB->pred_end(); PI != PE; ++PI)
|
PE = MBB->pred_end(); PI != PE; ++PI)
|
||||||
if (const VNInfo *PVNI =
|
if (const VNInfo *PVNI =
|
||||||
LI->getVNInfoAt(lis_.getMBBEndIdx(*PI).getPrevSlot()))
|
LI->getVNInfoAt(LIS.getMBBEndIdx(*PI).getPrevSlot()))
|
||||||
eqClass_.join(VNI->id, PVNI->id);
|
EqClass.join(VNI->id, PVNI->id);
|
||||||
} else {
|
} else {
|
||||||
// Normal value defined by an instruction. Check for two-addr redef.
|
// Normal value defined by an instruction. Check for two-addr redef.
|
||||||
// FIXME: This could be coincidental. Should we really check for a tied
|
// FIXME: This could be coincidental. Should we really check for a tied
|
||||||
// operand constraint?
|
// operand constraint?
|
||||||
// Note that VNI->def may be a use slot for an early clobber def.
|
// Note that VNI->def may be a use slot for an early clobber def.
|
||||||
if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getPrevSlot()))
|
if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getPrevSlot()))
|
||||||
eqClass_.join(VNI->id, UVNI->id);
|
EqClass.join(VNI->id, UVNI->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lump all the unused values in with the last used value.
|
// Lump all the unused values in with the last used value.
|
||||||
if (used && unused)
|
if (used && unused)
|
||||||
eqClass_.join(used->id, unused->id);
|
EqClass.join(used->id, unused->id);
|
||||||
|
|
||||||
eqClass_.compress();
|
EqClass.compress();
|
||||||
return eqClass_.getNumClasses();
|
return EqClass.getNumClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) {
|
void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[],
|
||||||
|
MachineRegisterInfo &MRI) {
|
||||||
assert(LIV[0] && "LIV[0] must be set");
|
assert(LIV[0] && "LIV[0] must be set");
|
||||||
LiveInterval &LI = *LIV[0];
|
LiveInterval &LI = *LIV[0];
|
||||||
|
|
||||||
// First move runs to new intervals.
|
// Rewrite instructions.
|
||||||
|
for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg),
|
||||||
|
RE = MRI.reg_end(); RI != RE;) {
|
||||||
|
MachineOperand &MO = RI.getOperand();
|
||||||
|
MachineInstr *MI = MO.getParent();
|
||||||
|
++RI;
|
||||||
|
if (MO.isUse() && MO.isUndef())
|
||||||
|
continue;
|
||||||
|
// DBG_VALUE instructions should have been eliminated earlier.
|
||||||
|
SlotIndex Idx = LIS.getInstructionIndex(MI);
|
||||||
|
Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex();
|
||||||
|
const VNInfo *VNI = LI.getVNInfoAt(Idx);
|
||||||
|
assert(VNI && "Interval not live at use.");
|
||||||
|
MO.setReg(LIV[getEqClass(VNI)]->reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move runs to new intervals.
|
||||||
LiveInterval::iterator J = LI.begin(), E = LI.end();
|
LiveInterval::iterator J = LI.begin(), E = LI.end();
|
||||||
while (J != E && eqClass_[J->valno->id] == 0)
|
while (J != E && EqClass[J->valno->id] == 0)
|
||||||
++J;
|
++J;
|
||||||
for (LiveInterval::iterator I = J; I != E; ++I) {
|
for (LiveInterval::iterator I = J; I != E; ++I) {
|
||||||
if (unsigned eq = eqClass_[I->valno->id]) {
|
if (unsigned eq = EqClass[I->valno->id]) {
|
||||||
assert((LIV[eq]->empty() || LIV[eq]->expiredAt(I->start)) &&
|
assert((LIV[eq]->empty() || LIV[eq]->expiredAt(I->start)) &&
|
||||||
"New intervals should be empty");
|
"New intervals should be empty");
|
||||||
LIV[eq]->ranges.push_back(*I);
|
LIV[eq]->ranges.push_back(*I);
|
||||||
|
@ -783,11 +800,11 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) {
|
||||||
|
|
||||||
// Transfer VNInfos to their new owners and renumber them.
|
// Transfer VNInfos to their new owners and renumber them.
|
||||||
unsigned j = 0, e = LI.getNumValNums();
|
unsigned j = 0, e = LI.getNumValNums();
|
||||||
while (j != e && eqClass_[j] == 0)
|
while (j != e && EqClass[j] == 0)
|
||||||
++j;
|
++j;
|
||||||
for (unsigned i = j; i != e; ++i) {
|
for (unsigned i = j; i != e; ++i) {
|
||||||
VNInfo *VNI = LI.getValNumInfo(i);
|
VNInfo *VNI = LI.getValNumInfo(i);
|
||||||
if (unsigned eq = eqClass_[i]) {
|
if (unsigned eq = EqClass[i]) {
|
||||||
VNI->id = LIV[eq]->getNumValNums();
|
VNI->id = LIV[eq]->getNumValNums();
|
||||||
LIV[eq]->valnos.push_back(VNI);
|
LIV[eq]->valnos.push_back(VNI);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -771,28 +771,6 @@ void SplitEditor::rewriteAssigned(bool ExtendRanges) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// rewriteSplit - Rewrite uses of Intvs[0] according to the ConEQ mapping.
|
|
||||||
void SplitEditor::rewriteComponents(const SmallVectorImpl<LiveInterval*> &Intvs,
|
|
||||||
const ConnectedVNInfoEqClasses &ConEq) {
|
|
||||||
for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Intvs[0]->reg),
|
|
||||||
RE = MRI.reg_end(); RI != RE;) {
|
|
||||||
MachineOperand &MO = RI.getOperand();
|
|
||||||
MachineInstr *MI = MO.getParent();
|
|
||||||
++RI;
|
|
||||||
if (MO.isUse() && MO.isUndef())
|
|
||||||
continue;
|
|
||||||
// DBG_VALUE instructions should have been eliminated earlier.
|
|
||||||
SlotIndex Idx = LIS.getInstructionIndex(MI);
|
|
||||||
Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex();
|
|
||||||
DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t'
|
|
||||||
<< Idx << ':');
|
|
||||||
const VNInfo *VNI = Intvs[0]->getVNInfoAt(Idx);
|
|
||||||
assert(VNI && "Interval not live at use.");
|
|
||||||
MO.setReg(Intvs[ConEq.getEqClass(VNI)]->reg);
|
|
||||||
DEBUG(dbgs() << VNI->id << '\t' << *MI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SplitEditor::deleteRematVictims() {
|
void SplitEditor::deleteRematVictims() {
|
||||||
SmallVector<MachineInstr*, 8> Dead;
|
SmallVector<MachineInstr*, 8> Dead;
|
||||||
for (LiveInterval::const_vni_iterator I = Edit->getParent().vni_begin(),
|
for (LiveInterval::const_vni_iterator I = Edit->getParent().vni_begin(),
|
||||||
|
@ -889,8 +867,7 @@ void SplitEditor::finish() {
|
||||||
dups.push_back(li);
|
dups.push_back(li);
|
||||||
for (unsigned i = 1; i != NumComp; ++i)
|
for (unsigned i = 1; i != NumComp; ++i)
|
||||||
dups.push_back(&Edit->create(MRI, LIS, VRM));
|
dups.push_back(&Edit->create(MRI, LIS, VRM));
|
||||||
rewriteComponents(dups, ConEQ);
|
ConEQ.Distribute(&dups[0], MRI);
|
||||||
ConEQ.Distribute(&dups[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate spill weight and allocation hints for new intervals.
|
// Calculate spill weight and allocation hints for new intervals.
|
||||||
|
|
|
@ -265,13 +265,6 @@ class SplitEditor {
|
||||||
/// rewriteAssigned - Rewrite all uses of Edit.getReg() to assigned registers.
|
/// rewriteAssigned - Rewrite all uses of Edit.getReg() to assigned registers.
|
||||||
void rewriteAssigned(bool ExtendRanges);
|
void rewriteAssigned(bool ExtendRanges);
|
||||||
|
|
||||||
/// rewriteComponents - Rewrite all uses of Intv[0] according to the eq
|
|
||||||
/// classes in ConEQ.
|
|
||||||
/// This must be done when Intvs[0] is styill live at all uses, before calling
|
|
||||||
/// ConEq.Distribute().
|
|
||||||
void rewriteComponents(const SmallVectorImpl<LiveInterval*> &Intvs,
|
|
||||||
const ConnectedVNInfoEqClasses &ConEq);
|
|
||||||
|
|
||||||
/// deleteRematVictims - Delete defs that are dead after rematerializing.
|
/// deleteRematVictims - Delete defs that are dead after rematerializing.
|
||||||
void deleteRematVictims();
|
void deleteRematVictims();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue