aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/LiveIntervalAnalysis.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-10-09 23:27:56 +0000
committerDan Gohman <gohman@apple.com>2009-10-09 23:27:56 +0000
commita70dca156fa76d452f54829b5c5f962ddfd94ef2 (patch)
tree31322fbef91a904807aea13e1bc2ab409c0042c6 /lib/CodeGen/LiveIntervalAnalysis.cpp
parentac1ceb3dd33cb79ecb0dbd64b6abafa7ce067c5f (diff)
Factor out LiveIntervalAnalysis' code to determine whether an instruction
is trivially rematerializable and integrate it into TargetInstrInfo::isTriviallyReMaterializable. This way, all places that need to know whether an instruction is rematerializable will get the same answer. This enables the useful parts of the aggressive-remat option by default -- using AliasAnalysis to determine whether a memory location is invariant, and removes the questionable parts -- rematting operations with virtual register inputs that may not be live everywhere. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83687 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/LiveIntervalAnalysis.cpp')
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp99
1 files changed, 5 insertions, 94 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 135cc1719f..93d3d4c838 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -50,8 +50,6 @@ using namespace llvm;
static cl::opt<bool> DisableReMat("disable-rematerialization",
cl::init(false), cl::Hidden);
-static cl::opt<bool> EnableAggressiveRemat("aggressive-remat", cl::Hidden);
-
static cl::opt<bool> EnableFastSpilling("fast-spill",
cl::init(false), cl::Hidden);
@@ -1408,99 +1406,12 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
if (DisableReMat)
return false;
- if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
- return true;
-
- int FrameIdx = 0;
- if (tii_->isLoadFromStackSlot(MI, FrameIdx) &&
- mf_->getFrameInfo()->isImmutableObjectIndex(FrameIdx))
- // FIXME: Let target specific isReallyTriviallyReMaterializable determines
- // this but remember this is not safe to fold into a two-address
- // instruction.
- // This is a load from fixed stack slot. It can be rematerialized.
- return true;
-
- // If the target-specific rules don't identify an instruction as
- // being trivially rematerializable, use some target-independent
- // rules.
- if (!tii_->isTriviallyReMaterializable(MI)) {
- if (!EnableAggressiveRemat)
- return false;
-
- const TargetInstrDesc &TID = MI->getDesc();
-
- // Avoid instructions obviously unsafe for remat.
- if (TID.hasUnmodeledSideEffects() || TID.isNotDuplicable() ||
- TID.mayStore())
- return false;
-
- // Avoid instructions which load from potentially varying memory.
- if (TID.mayLoad() && !MI->isInvariantLoad(aa_))
- return false;
-
- // If any of the registers accessed are non-constant, conservatively assume
- // the instruction is not rematerializable.
- unsigned ImpUse = 0;
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg()) {
- unsigned Reg = MO.getReg();
- if (Reg == 0)
- continue;
- if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
- if (MO.isUse()) {
- // If the physreg has no defs anywhere, it's just an ambient register
- // and we can freely move its uses. Alternatively, if it's allocatable,
- // it could get allocated to something with a def during allocation.
- if (!mri_->def_empty(Reg))
- return false;
- if (allocatableRegs_.test(Reg))
- return false;
- // Check for a def among the register's aliases too.
- for (const unsigned *Alias = tri_->getAliasSet(Reg); *Alias; ++Alias) {
- unsigned AliasReg = *Alias;
- if (!mri_->def_empty(AliasReg))
- return false;
- if (allocatableRegs_.test(AliasReg))
- return false;
- }
- } else {
- // A physreg def. We can't remat it.
- return false;
- }
- continue;
- }
-
- // Only allow one def, and that in the first operand.
- if (MO.isDef() != (i == 0))
- return false;
-
- // Only allow constant-valued registers.
- bool IsLiveIn = mri_->isLiveIn(Reg);
- MachineRegisterInfo::def_iterator I = mri_->def_begin(Reg),
- E = mri_->def_end();
-
- // For the def, it should be the only def of that register.
- if (MO.isDef() && (next(I) != E || IsLiveIn))
- return false;
-
- if (MO.isUse()) {
- // Only allow one use other register use, as that's all the
- // remat mechanisms support currently.
- if (Reg != li.reg) {
- if (ImpUse == 0)
- ImpUse = Reg;
- else if (Reg != ImpUse)
- return false;
- }
- // For the use, there should be only one associated def.
- if (I != E && (next(I) != E || IsLiveIn))
- return false;
- }
- }
- }
- }
+ if (!tii_->isTriviallyReMaterializable(MI, aa_))
+ return false;
+ // Target-specific code can mark an instruction as being rematerializable
+ // if it has one virtual reg use, though it had better be something like
+ // a PIC base register which is likely to be live everywhere.
unsigned ImpUse = getReMatImplicitUse(li, MI);
if (ImpUse) {
const LiveInterval &ImpLi = getInterval(ImpUse);