summaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveIntervalAnalysis.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-03-20 08:13:50 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-03-20 08:13:50 +0000
commit2638e1a6b9e3c0e22b398987e1db99bee81db4fb (patch)
treee3b4b57156d3fc3776657d0899fc255b3d4da09b /lib/CodeGen/LiveIntervalAnalysis.cpp
parentc70d1849b7b85b06adf7dce856b3b19028fff8f7 (diff)
downloadllvm-2638e1a6b9e3c0e22b398987e1db99bee81db4fb.tar.gz
llvm-2638e1a6b9e3c0e22b398987e1db99bee81db4fb.tar.bz2
llvm-2638e1a6b9e3c0e22b398987e1db99bee81db4fb.tar.xz
First cut trivial re-materialization support.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35208 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveIntervalAnalysis.cpp')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp31
1 files changed, 26 insertions, 5 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 36db38e1db..a968063c99 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -50,6 +50,11 @@ namespace {
EnableJoining("join-liveintervals",
cl::desc("Coallesce copies (default=true)"),
cl::init(true));
+
+ static cl::opt<bool>
+ EnableReMat("enable-rematerialization",
+ cl::desc("Perform trivial re-materialization"),
+ cl::init(false));
}
void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
@@ -155,8 +160,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
RemoveMachineInstrFromMaps(mii);
mii = mbbi->erase(mii);
++numPeep;
- }
- else {
+ } else {
for (unsigned i = 0, e = mii->getNumOperands(); i != e; ++i) {
const MachineOperand &mop = mii->getOperand(i);
if (mop.isRegister() && mop.getReg() &&
@@ -165,9 +169,13 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
unsigned reg = rep(mop.getReg());
mii->getOperand(i).setReg(reg);
+ // If the definition instruction is re-materializable, its spill
+ // weight is zero.
LiveInterval &RegInt = getInterval(reg);
- RegInt.weight +=
- (mop.isUse() + mop.isDef()) * pow(10.0F, (int)loopDepth);
+ if (!RegInt.remat) {
+ RegInt.weight +=
+ (mop.isUse() + mop.isDef()) * pow(10.0F, (int)loopDepth);
+ }
}
}
++mii;
@@ -300,7 +308,9 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& mop = MI->getOperand(i);
if (mop.isRegister() && mop.getReg() == li.reg) {
- if (MachineInstr *fmi = mri_->foldMemoryOperand(MI, i, slot)) {
+ MachineInstr *fmi = li.remat ? NULL
+ : mri_->foldMemoryOperand(MI, i, slot);
+ if (fmi) {
// Attempt to fold the memory reference into the instruction. If we
// can do this, we don't need to insert spill code.
if (lv_)
@@ -345,8 +355,11 @@ addIntervalsForSpills(const LiveInterval &li, VirtRegMap &vrm, int slot) {
// create a new register for this spill
vrm.grow();
+ if (li.remat)
+ vrm.setVirtIsReMaterialized(NewVReg, li.remat);
vrm.assignVirt2StackSlot(NewVReg, slot);
LiveInterval &nI = getOrCreateInterval(NewVReg);
+ nI.remat = li.remat;
assert(nI.empty());
// the spill weight is now infinity as it
@@ -422,6 +435,11 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
// done once for the vreg. We use an empty interval to detect the first
// time we see a vreg.
if (interval.empty()) {
+ // Remember if the definition can be rematerialized.
+ if (EnableReMat &&
+ vi.DefInst && tii_->isReMaterializable(vi.DefInst->getOpcode()))
+ interval.remat = vi.DefInst;
+
// Get the Idx of the defining instructions.
unsigned defIndex = getDefIndex(MIIdx);
@@ -497,6 +515,9 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
}
} else {
+ // Can't safely assume definition is rematierializable anymore.
+ interval.remat = NULL;
+
// If this is the second time we see a virtual register definition, it
// must be due to phi elimination or two addr elimination. If this is
// the result of two address elimination, then the vreg is one of the