aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp38
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp14
2 files changed, 48 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
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index 3d2669becd..6eec5ab885 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -1485,6 +1485,20 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
// it and hope it will be easier to allocate for this li.
if (isZeroLengthInterval(&LI))
LI.weight = HUGE_VALF;
+ else {
+ bool isLoad = false;
+ if (li_->isReMaterializable(LI, isLoad)) {
+ // If all of the definitions of the interval are re-materializable,
+ // it is a preferred candidate for spilling. If non of the defs are
+ // loads, then it's potentially very cheap to re-materialize.
+ // FIXME: this gets much more complicated once we support non-trivial
+ // re-materialization.
+ if (isLoad)
+ LI.weight *= 0.9F;
+ else
+ LI.weight *= 0.5F;
+ }
+ }
// Slightly prefer live interval that has been assigned a preferred reg.
if (LI.preference)