mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-20 02:58:10 +00:00
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:
parent
9b61f33351
commit
45e94d68d7
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user