mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Fix for PR1831: if all defs of an interval are re-materializable, then it's a preferred spill candiate.
llvm-svn: 44644
This commit is contained in:
parent
9e69c0ada8
commit
1d289d0146
@ -233,6 +233,11 @@ namespace llvm {
|
||||
addIntervalsForSpills(const LiveInterval& i,
|
||||
const LoopInfo *loopInfo, VirtRegMap& vrm);
|
||||
|
||||
/// isReMaterializable - Returns true if every definition of MI of every
|
||||
/// val# of the specified interval is re-materializable. Also returns true
|
||||
/// by reference if all of the defs are load instructions.
|
||||
bool isReMaterializable(const LiveInterval &li, bool &isLoad);
|
||||
|
||||
private:
|
||||
/// computeIntervals - Compute live intervals.
|
||||
void computeIntervals();
|
||||
@ -265,9 +270,10 @@ namespace llvm {
|
||||
LiveInterval &interval, bool isAlias = false);
|
||||
|
||||
/// isReMaterializable - Returns true if the definition MI of the specified
|
||||
/// val# of the specified interval is re-materializable.
|
||||
/// val# of the specified interval is re-materializable. Also returns true
|
||||
/// by reference if the def is a load.
|
||||
bool isReMaterializable(const LiveInterval &li, const VNInfo *ValNo,
|
||||
MachineInstr *MI);
|
||||
MachineInstr *MI, bool &isLoad);
|
||||
|
||||
/// tryFoldMemoryOperand - Attempts to fold either a spill / restore from
|
||||
/// slot / to reg or any rematerialized load into ith operand of specified
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -1,4 +1,5 @@
|
||||
; RUN: llvm-as < %s | llc -stats |& grep {40.*Number of machine instrs printed}
|
||||
; RUN: llvm-as < %s | llc -stats |& grep {39.*Number of machine instrs printed}
|
||||
; RUN: llvm-as < %s | llc -stats |& grep {.*Number of re-materialization}
|
||||
; This test really wants to check that the resultant "cond_true" block only
|
||||
; has a single store in it, and that cond_true55 only has code to materialize
|
||||
; the constant and do a store. We do *not* want something like this:
|
||||
@ -7,7 +8,6 @@
|
||||
; add r8, r0, r6
|
||||
; str r10, [r8, #+4]
|
||||
;
|
||||
; XFAIL: *
|
||||
target triple = "arm-apple-darwin8"
|
||||
|
||||
define void @foo(i32* %mc, i32* %mpp, i32* %ip, i32* %dpp, i32* %tpmm, i32 %M, i32* %tpim, i32* %tpdm, i32* %bp, i32* %ms, i32 %xmb) {
|
||||
|
Loading…
Reference in New Issue
Block a user