diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-03-20 08:13:50 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-03-20 08:13:50 +0000 |
commit | 2638e1a6b9e3c0e22b398987e1db99bee81db4fb (patch) | |
tree | e3b4b57156d3fc3776657d0899fc255b3d4da09b /lib/CodeGen/LiveIntervalAnalysis.cpp | |
parent | c70d1849b7b85b06adf7dce856b3b19028fff8f7 (diff) |
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.cpp | 31 |
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 |