mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Trace through sibling PHIs in bulk.
When traceSiblingValue() encounters a PHI-def value created by live range splitting, don't look at all the predecessor blocks. That can be very expensive in a complicated CFG. Instead, consider that all the non-PHI defs jointly dominate all the PHI-defs. Tracing directly to all the non-PHI defs is much faster that zipping around in the CFG when there are many PHIs with many predecessors. This significantly improves compile time for indirectbr interpreters. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139797 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b6e9a83349
commit
6b6e32d954
@ -120,11 +120,6 @@ private:
|
||||
typedef DenseMap<VNInfo*, SibValueInfo> SibValueMap;
|
||||
SibValueMap SibValues;
|
||||
|
||||
// Values live-out from basic blocks. This is the same as
|
||||
// LI.getVNInfoAt(LIS.getMBBEndIdx(MBB).getPrevSlot())
|
||||
typedef DenseMap<MachineBasicBlock*, VNInfo*> LiveOutMap;
|
||||
LiveOutMap LiveOutValues;
|
||||
|
||||
// Dead defs generated during spilling.
|
||||
SmallVector<MachineInstr*, 8> DeadDefs;
|
||||
|
||||
@ -500,6 +495,7 @@ MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
|
||||
|
||||
// Trace through PHI-defs created by live range splitting.
|
||||
if (VNI->isPHIDef()) {
|
||||
// Stop at original PHIs. We don't know the value at the predecessors.
|
||||
if (VNI->def == OrigVNI->def) {
|
||||
DEBUG(dbgs() << "orig phi value\n");
|
||||
SVI->second.DefByOrigPHI = true;
|
||||
@ -507,28 +503,60 @@ MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
|
||||
propagateSiblingValue(SVI);
|
||||
continue;
|
||||
}
|
||||
// Get values live-out of predecessors.
|
||||
|
||||
// This is a PHI inserted by live range splitting. We could trace the
|
||||
// live-out value from predecessor blocks, but that search can be very
|
||||
// expensive if there are many predecessors and many more PHIs as
|
||||
// generated by tail-dup when it sees an indirectbr. Instead, look at
|
||||
// all the non-PHI defs that have the same value as OrigVNI. They must
|
||||
// jointly dominate VNI->def. This is not optimal since VNI may actually
|
||||
// be jointly dominated by a smaller subset of defs, so there is a change
|
||||
// we will miss a AllDefsAreReloads optimization.
|
||||
|
||||
// Separate all values dominated by OrigVNI into PHIs and non-PHIs.
|
||||
SmallVector<VNInfo*, 8> PHIs, NonPHIs;
|
||||
LiveInterval &LI = LIS.getInterval(Reg);
|
||||
MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def);
|
||||
DEBUG(dbgs() << "split phi value, check " << MBB->pred_size()
|
||||
<< " preds\n");
|
||||
for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
|
||||
PE = MBB->pred_end(); PI != PE; ++PI) {
|
||||
// Use a cache of block live-out values. This is faster than using
|
||||
// getVNInfoAt on complex intervals.
|
||||
VNInfo *&PVNI = LiveOutValues[*PI];
|
||||
if (!PVNI)
|
||||
PVNI = LI.getVNInfoAt(LIS.getMBBEndIdx(*PI).getPrevSlot());
|
||||
if (!PVNI)
|
||||
LiveInterval &OrigLI = LIS.getInterval(Original);
|
||||
|
||||
for (LiveInterval::vni_iterator VI = LI.vni_begin(), VE = LI.vni_end();
|
||||
VI != VE; ++VI) {
|
||||
VNInfo *VNI2 = *VI;
|
||||
if (VNI2->isUnused())
|
||||
continue;
|
||||
// Known predecessor value? Try an insertion.
|
||||
tie(SVI, Inserted) =
|
||||
SibValues.insert(std::make_pair(PVNI, SibValueInfo(Reg, PVNI)));
|
||||
// This is the first time we see PVNI, add it to the worklist.
|
||||
if (Inserted)
|
||||
WorkList.push_back(std::make_pair(Reg, PVNI));
|
||||
propagateSiblingValue(SVI, VNI);
|
||||
if (!OrigLI.containsOneValue() &&
|
||||
OrigLI.getVNInfoAt(VNI2->def) != OrigVNI)
|
||||
continue;
|
||||
if (VNI2->isPHIDef() && VNI2->def != OrigVNI->def)
|
||||
PHIs.push_back(VNI2);
|
||||
else
|
||||
NonPHIs.push_back(VNI2);
|
||||
}
|
||||
DEBUG(dbgs() << "split phi value, checking " << PHIs.size()
|
||||
<< " phi-defs, and " << NonPHIs.size()
|
||||
<< " non-phi/orig defs\n");
|
||||
|
||||
// Create entries for all the PHIs. Don't add them to the worklist, we
|
||||
// are processing all of them in one go here.
|
||||
for (unsigned i = 0, e = PHIs.size(); i != e; ++i)
|
||||
SibValues.insert(std::make_pair(PHIs[i], SibValueInfo(Reg, PHIs[i])));
|
||||
|
||||
// Add every PHI as a dependent of all the non-PHIs.
|
||||
for (unsigned i = 0, e = NonPHIs.size(); i != e; ++i) {
|
||||
VNInfo *NonPHI = NonPHIs[i];
|
||||
// Known value? Try an insertion.
|
||||
tie(SVI, Inserted) =
|
||||
SibValues.insert(std::make_pair(NonPHI, SibValueInfo(Reg, NonPHI)));
|
||||
// Add all the PHIs as dependents of NonPHI.
|
||||
for (unsigned pi = 0, pe = PHIs.size(); pi != pe; ++pi)
|
||||
SVI->second.Deps.push_back(PHIs[pi]);
|
||||
// This is the first time we see NonPHI, add it to the worklist.
|
||||
if (Inserted)
|
||||
WorkList.push_back(std::make_pair(Reg, NonPHI));
|
||||
else
|
||||
// Propagate to all inserted PHIs, not just VNI.
|
||||
propagateSiblingValue(SVI);
|
||||
}
|
||||
|
||||
// Next work list item.
|
||||
continue;
|
||||
}
|
||||
@ -587,7 +615,6 @@ MachineInstr *InlineSpiller::traceSiblingValue(unsigned UseReg, VNInfo *UseVNI,
|
||||
/// Keep track of values that may be rematerializable.
|
||||
void InlineSpiller::analyzeSiblingValues() {
|
||||
SibValues.clear();
|
||||
LiveOutValues.clear();
|
||||
|
||||
// No siblings at all?
|
||||
if (Edit->getReg() == Original)
|
||||
|
Loading…
Reference in New Issue
Block a user