diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-12-06 00:01:56 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-12-06 00:01:56 +0000 |
commit | 5ef3a04b542c4e585276768fa9ca2af698ef5c87 (patch) | |
tree | 6b72163b7ae2b198f8295130ebab1761ada9d43b /lib/CodeGen/LiveIntervalAnalysis.cpp | |
parent | bdcb726fcad1e3fddc70847a2b91d4d4f9396938 (diff) |
Fix for PR1831: if all defs of an interval are re-materializable, then it's a preferred spill candiate.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44644 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveIntervalAnalysis.cpp')
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index a9e69483be..92627345de 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -607,12 +607,16 @@ LiveInterval LiveIntervals::createInterval(unsigned reg) { /// isReMaterializable - Returns true if the definition MI of the specified /// val# of the specified interval is re-materializable. bool LiveIntervals::isReMaterializable(const LiveInterval &li, - const VNInfo *ValNo, MachineInstr *MI) { + const VNInfo *ValNo, MachineInstr *MI, + bool &isLoad) { if (DisableReMat) return false; - if (tii_->isTriviallyReMaterializable(MI)) + isLoad = false; + if (tii_->isTriviallyReMaterializable(MI)) { + isLoad = MI->getInstrDescriptor()->Flags & M_LOAD_FLAG; return true; + } int FrameIdx = 0; if (!tii_->isLoadFromStackSlot(MI, FrameIdx) || @@ -621,6 +625,7 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li, // This is a load from fixed stack slot. It can be rematerialized unless it's // re-defined by a two-address instruction. + isLoad = true; for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end(); i != e; ++i) { const VNInfo *VNI = *i; @@ -631,8 +636,32 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li, continue; // Dead val#. MachineInstr *DefMI = (DefIdx == ~0u) ? NULL : getInstructionFromIndex(DefIdx); - if (DefMI && DefMI->isRegReDefinedByTwoAddr(li.reg)) + if (DefMI && DefMI->isRegReDefinedByTwoAddr(li.reg)) { + isLoad = false; + return false; + } + } + return true; +} + +/// isReMaterializable - Returns true if every definition of MI of every +/// val# of the specified interval is re-materializable. +bool LiveIntervals::isReMaterializable(const LiveInterval &li, bool &isLoad) { + isLoad = false; + for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end(); + i != e; ++i) { + const VNInfo *VNI = *i; + unsigned DefIdx = VNI->def; + if (DefIdx == ~1U) + continue; // Dead val#. + // Is the def for the val# rematerializable? + if (DefIdx == ~0u) + return false; + MachineInstr *ReMatDefMI = getInstructionFromIndex(DefIdx); + bool DefIsLoad = false; + if (!ReMatDefMI || !isReMaterializable(li, VNI, ReMatDefMI, DefIsLoad)) return false; + isLoad |= DefIsLoad; } return true; } @@ -1225,7 +1254,8 @@ addIntervalsForSpills(const LiveInterval &li, // Is the def for the val# rematerializable? MachineInstr *ReMatDefMI = (DefIdx == ~0u) ? 0 : getInstructionFromIndex(DefIdx); - if (ReMatDefMI && isReMaterializable(li, VNI, ReMatDefMI)) { + bool dummy; + if (ReMatDefMI && isReMaterializable(li, VNI, ReMatDefMI, dummy)) { // Remember how to remat the def of this val#. ReMatOrigDefs[VN] = ReMatDefMI; // Original def may be modified so we have to make a copy here. vrm must |