#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
using namespace llvm;
};
} // namespace
+STATISTIC(NumPHIsLowered, "Number of PHIs lowered");
+STATISTIC(NumDestCopiesInserted, "Number of destination copies inserted");
+STATISTIC(NumSrcCopiesInserted, "Number of source copies inserted");
+
char StrongPHIElimination::ID = 0;
INITIALIZE_PASS_BEGIN(StrongPHIElimination, "strong-phi-node-elimination",
"Eliminate PHI nodes for register allocation, intelligently", false, false)
return &MO;
}
}
- return NULL;
}
bool StrongPHIElimination::runOnMachineFunction(MachineFunction &MF) {
MachineOperand *LastUse = findLastUse(MBB, SrcReg);
assert(LastUse);
SlotIndex LastUseIndex = LI->getInstructionIndex(LastUse->getParent());
- SrcLI.removeRange(LastUseIndex.getDefIndex(), LI->getMBBEndIdx(MBB));
+ SrcLI.removeRange(LastUseIndex.getRegSlot(), LI->getMBBEndIdx(MBB));
LastUse->setIsKill(true);
}
- LI->renumber();
-
Allocator.Reset();
RegNodeMap.clear();
PHISrcDefs.clear();
// handle it here by tracking defining machine instructions rather than
// virtual registers. For now, we just handle the situation conservatively
// in a way that will possibly lead to false interferences.
- unsigned NewParent = CurrentDominatingParent[DestColor];
+ unsigned &CurrentParent = CurrentDominatingParent[DestColor];
+ unsigned NewParent = CurrentParent;
if (NewParent == DestReg)
continue;
// could be improved by using a heuristic that decides which of the two
// registers to isolate.
isolateReg(DestReg);
- CurrentDominatingParent[DestColor] = NewParent;
+ CurrentParent = NewParent;
} else {
// If there is no interference, update ImmediateDominatingParent and set
// the CurrentDominatingParent for this color to the current register.
ImmediateDominatingParent[DestReg] = NewParent;
- CurrentDominatingParent[DestColor] = DestReg;
+ CurrentParent = DestReg;
}
}
}
// We now walk the PHIs in successor blocks and check for interferences. This
- // is necesary because the use of a PHI's operands are logically contained in
+ // is necessary because the use of a PHI's operands are logically contained in
// the predecessor block. The def of a PHI's destination register is processed
// along with the other defs in a basic block.
// Pop registers from the stack represented by ImmediateDominatingParent
// until we find a parent that dominates the current instruction.
- unsigned NewParent = CurrentDominatingParent[Color];
+ unsigned &CurrentParent = CurrentDominatingParent[Color];
+ unsigned NewParent = CurrentParent;
while (NewParent
&& (!DT->dominates(MRI->getVRegDef(NewParent)->getParent(), &MBB)
|| !getRegColor(NewParent)))
NewParent = ImmediateDominatingParent[NewParent];
- CurrentDominatingParent[Color] = NewParent;
+ CurrentParent = NewParent;
// If there is an interference with a register, always isolate the
// register rather than the PHI. It is also possible to isolate the
&& NewParent != PredOperandReg)
isolateReg(NewParent);
- std::pair<MachineInstr*, unsigned> CurrentPHI = CurrentPHIForColor[Color];
+ std::pair<MachineInstr*, unsigned>
+ &CurrentPHI = CurrentPHIForColor[Color];
// If two PHIs have the same operand from every shared predecessor, then
// they don't actually interfere. Otherwise, isolate the current PHI. This
if (CurrentPHI.first && CurrentPHI.second != PredOperandReg)
isolatePHI(PHI);
else
- CurrentPHIForColor[Color] = std::make_pair(PHI, PredOperandReg);
+ CurrentPHI = std::make_pair(PHI, PredOperandReg);
}
}
}
void StrongPHIElimination::InsertCopiesForPHI(MachineInstr *PHI,
MachineBasicBlock *MBB) {
assert(PHI->isPHI());
+ ++NumPHIsLowered;
unsigned PHIColor = getPHIColor(PHI);
for (unsigned i = 1; i < PHI->getNumOperands(); i += 2) {
if (PHIColor && SrcColor == PHIColor) {
LiveInterval &SrcInterval = LI->getInterval(SrcReg);
SlotIndex PredIndex = LI->getMBBEndIdx(PredBB);
- VNInfo *SrcVNI = SrcInterval.getVNInfoAt(PredIndex.getPrevIndex());
+ VNInfo *SrcVNI = SrcInterval.getVNInfoBefore(PredIndex);
+ (void)SrcVNI;
assert(SrcVNI);
- SrcVNI->setHasPHIKill(true);
continue;
}
TII->get(TargetOpcode::COPY),
CopyReg).addReg(SrcReg, 0, SrcSubReg);
LI->InsertMachineInstrInMaps(CopyInstr);
+ ++NumSrcCopiesInserted;
// addLiveRangeToEndOfBlock() also adds the phikill flag to the VNInfo for
// the newly added range.
// Set the phi-def flag for the VN at this PHI.
SlotIndex PHIIndex = LI->getInstructionIndex(PHI);
- VNInfo *DestVNI = DestLI.getVNInfoAt(PHIIndex.getDefIndex());
+ VNInfo *DestVNI = DestLI.getVNInfoAt(PHIIndex.getRegSlot());
assert(DestVNI);
- DestVNI->setIsPHIDef(true);
// Prior to PHI elimination, the live ranges of PHIs begin at their defining
// instruction. After PHI elimination, PHI instructions are replaced by VNs
SlotIndex MBBStartIndex = LI->getMBBStartIdx(MBB);
DestVNI->def = MBBStartIndex;
DestLI.addRange(LiveRange(MBBStartIndex,
- PHIIndex.getDefIndex(),
+ PHIIndex.getRegSlot(),
DestVNI));
return;
}
DestReg).addReg(CopyReg);
LI->InsertMachineInstrInMaps(CopyInstr);
PHI->getOperand(0).setReg(CopyReg);
+ ++NumDestCopiesInserted;
// Add the region from the beginning of MBB to the copy instruction to
// CopyReg's live interval, and give the VNInfo the phidef flag.
SlotIndex MBBStartIndex = LI->getMBBStartIdx(MBB);
SlotIndex DestCopyIndex = LI->getInstructionIndex(CopyInstr);
VNInfo *CopyVNI = CopyLI.getNextValue(MBBStartIndex,
- CopyInstr,
LI->getVNInfoAllocator());
- CopyVNI->setIsPHIDef(true);
CopyLI.addRange(LiveRange(MBBStartIndex,
- DestCopyIndex.getDefIndex(),
+ DestCopyIndex.getRegSlot(),
CopyVNI));
// Adjust DestReg's live interval to adjust for its new definition at
// CopyInstr.
LiveInterval &DestLI = LI->getOrCreateInterval(DestReg);
SlotIndex PHIIndex = LI->getInstructionIndex(PHI);
- DestLI.removeRange(PHIIndex.getDefIndex(), DestCopyIndex.getDefIndex());
+ DestLI.removeRange(PHIIndex.getRegSlot(), DestCopyIndex.getRegSlot());
- VNInfo *DestVNI = DestLI.getVNInfoAt(DestCopyIndex.getDefIndex());
+ VNInfo *DestVNI = DestLI.getVNInfoAt(DestCopyIndex.getRegSlot());
assert(DestVNI);
- DestVNI->def = DestCopyIndex.getDefIndex();
+ DestVNI->def = DestCopyIndex.getRegSlot();
InsertedDestCopies[CopyReg] = CopyInstr;
}