[llvm-commits] [llvm] r63728 - /llvm/trunk/lib/CodeGen/MachineLICM.cpp
Evan Cheng
evan.cheng at apple.com
Wed Feb 4 01:19:56 PST 2009
Author: evancheng
Date: Wed Feb 4 03:19:56 2009
New Revision: 63728
URL: http://llvm.org/viewvc/llvm-project?rev=63728&view=rev
Log:
Don't bother hoisting out a "cheap" instruction if all of its uses are PHIs. LICM "cheap" instructions are not particularly beneficial to start with. This will just end up making the copies harder to coalesce.
Modified:
llvm/trunk/lib/CodeGen/MachineLICM.cpp
Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=63728&r1=63727&r2=63728&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Wed Feb 4 03:19:56 2009
@@ -76,6 +76,10 @@
///
bool IsLoopInvariantInst(MachineInstr &I);
+ /// IsProfitableToHoist - Return true if it is potentially profitable to
+ /// hoist the given loop invariant.
+ bool IsProfitableToHoist(MachineInstr &MI);
+
/// HoistRegion - Walk the specified region of the CFG (defined by all
/// blocks dominated by the specified block, and that are in the current
/// loop) in depth first order w.r.t the DominatorTree. This allows us to
@@ -187,26 +191,17 @@
TID.hasUnmodeledSideEffects())
return false;
- bool isInvLoad = false;
if (TID.mayLoad()) {
// Okay, this instruction does a load. As a refinement, we allow the target
// to decide whether the loaded value is actually a constant. If so, we can
// actually use it as a load.
- isInvLoad = TII->isInvariantLoad(&I);
- if (!isInvLoad)
+ if (!TII->isInvariantLoad(&I))
// FIXME: we should be able to sink loads with no other side effects if
// there is nothing that can change memory from here until the end of
// block. This is a trivial form of alias analysis.
return false;
}
- // FIXME: For now, only hoist re-materilizable instructions. LICM will
- // increase register pressure. We want to make sure it doesn't increase
- // spilling.
- if (!isInvLoad && (!TID.isRematerializable() ||
- !TII->isTriviallyReMaterializable(&I)))
- return false;
-
DEBUG({
DOUT << "--- Checking if we can hoist " << I;
if (I.getDesc().getImplicitUses()) {
@@ -263,11 +258,61 @@
return true;
}
+/// HasOnlyPHIUses - Return true if the only uses of Reg are PHIs.
+static bool HasOnlyPHIUses(unsigned Reg, MachineRegisterInfo *RegInfo) {
+ bool OnlyPHIUse = false;
+ for (MachineRegisterInfo::use_iterator UI = RegInfo->use_begin(Reg),
+ UE = RegInfo->use_end(); UI != UE; ++UI) {
+ MachineInstr *UseMI = &*UI;
+ if (UseMI->getOpcode() != TargetInstrInfo::PHI)
+ return false;
+ OnlyPHIUse = true;
+ }
+ return OnlyPHIUse;
+}
+
+/// IsProfitableToHoist - Return true if it is potentially profitable to hoist
+/// the given loop invariant.
+bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) {
+ const TargetInstrDesc &TID = MI.getDesc();
+
+ bool isInvLoad = false;
+ if (TID.mayLoad()) {
+ isInvLoad = TII->isInvariantLoad(&MI);
+ if (!isInvLoad)
+ return false;
+ }
+
+ // FIXME: For now, only hoist re-materilizable instructions. LICM will
+ // increase register pressure. We want to make sure it doesn't increase
+ // spilling.
+ if (!isInvLoad && (!TID.isRematerializable() ||
+ !TII->isTriviallyReMaterializable(&MI)))
+ return false;
+
+ if (!TID.isAsCheapAsAMove())
+ return true;
+
+ // If the instruction is "cheap" and the only uses of the register(s) defined
+ // by this MI are PHIs, then don't hoist it. Otherwise we just end up with a
+ // cheap instruction (e.g. constant) with long live interval feeeding into
+ // copies that are not always coalesced away.
+ bool OnlyPHIUses = false;
+ for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = MI.getOperand(i);
+ if (!MO.isReg() || !MO.isDef())
+ continue;
+ OnlyPHIUses |= HasOnlyPHIUses(MO.getReg(), RegInfo);
+ }
+ return !OnlyPHIUses;
+}
+
/// Hoist - When an instruction is found to use only loop invariant operands
/// that are safe to hoist, this instruction is called to do the dirty work.
///
void MachineLICM::Hoist(MachineInstr &MI) {
if (!IsLoopInvariantInst(MI)) return;
+ if (!IsProfitableToHoist(MI)) return;
// Now move the instructions to the predecessor, inserting it before any
// terminator instructions.
More information about the llvm-commits
mailing list