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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63728 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2009-02-04 09:19:56 +00:00
parent 9b61f33351
commit 45e94d68d7

View File

@ -76,6 +76,10 @@ namespace {
///
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 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
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 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
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.