mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
Only check for PHI uses inside the current loop.
Hoisting a value that is used by a PHI in the loop will introduce a copy because the live range is extended to cross the PHI. The same applies to PHIs in exit blocks. Also use this opportunity to make HasLoopPHIUse() non-recursive. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154454 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
89cdaf46ec
commit
8b560b8c48
@ -80,6 +80,14 @@ namespace {
|
|||||||
MachineLoop *CurLoop; // The current loop we are working on.
|
MachineLoop *CurLoop; // The current loop we are working on.
|
||||||
MachineBasicBlock *CurPreheader; // The preheader for CurLoop.
|
MachineBasicBlock *CurPreheader; // The preheader for CurLoop.
|
||||||
|
|
||||||
|
// Exit blocks for CurLoop.
|
||||||
|
SmallVector<MachineBasicBlock*, 8> ExitBlocks;
|
||||||
|
|
||||||
|
bool isExitBlock(const MachineBasicBlock *MBB) const {
|
||||||
|
return std::find(ExitBlocks.begin(), ExitBlocks.end(), MBB) !=
|
||||||
|
ExitBlocks.end();
|
||||||
|
}
|
||||||
|
|
||||||
// Track 'estimated' register pressure.
|
// Track 'estimated' register pressure.
|
||||||
SmallSet<unsigned, 32> RegSeen;
|
SmallSet<unsigned, 32> RegSeen;
|
||||||
SmallVector<unsigned, 8> RegPressure;
|
SmallVector<unsigned, 8> RegPressure;
|
||||||
@ -182,9 +190,9 @@ namespace {
|
|||||||
///
|
///
|
||||||
bool IsLoopInvariantInst(MachineInstr &I);
|
bool IsLoopInvariantInst(MachineInstr &I);
|
||||||
|
|
||||||
/// HasAnyPHIUse - Return true if the specified register is used by any
|
/// HasLoopPHIUse - Return true if the specified instruction is used by any
|
||||||
/// phi node.
|
/// phi node in the current loop.
|
||||||
bool HasAnyPHIUse(unsigned Reg) const;
|
bool HasLoopPHIUse(const MachineInstr *MI) const;
|
||||||
|
|
||||||
/// HasHighOperandLatency - Compute operand latency between a def of 'Reg'
|
/// HasHighOperandLatency - Compute operand latency between a def of 'Reg'
|
||||||
/// and an use in the current loop, return true if the target considered
|
/// and an use in the current loop, return true if the target considered
|
||||||
@ -348,6 +356,7 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
while (!Worklist.empty()) {
|
while (!Worklist.empty()) {
|
||||||
CurLoop = Worklist.pop_back_val();
|
CurLoop = Worklist.pop_back_val();
|
||||||
CurPreheader = 0;
|
CurPreheader = 0;
|
||||||
|
ExitBlocks.clear();
|
||||||
|
|
||||||
// If this is done before regalloc, only visit outer-most preheader-sporting
|
// If this is done before regalloc, only visit outer-most preheader-sporting
|
||||||
// loops.
|
// loops.
|
||||||
@ -356,6 +365,8 @@ bool MachineLICM::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurLoop->getExitBlocks(ExitBlocks);
|
||||||
|
|
||||||
if (!PreRegAlloc)
|
if (!PreRegAlloc)
|
||||||
HoistRegionPostRA();
|
HoistRegionPostRA();
|
||||||
else {
|
else {
|
||||||
@ -955,22 +966,40 @@ bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// HasAnyPHIUse - Return true if the specified register is used by any
|
/// HasLoopPHIUse - Return true if the specified instruction is used by a
|
||||||
/// phi node.
|
/// phi node and hoisting it could cause a copy to be inserted.
|
||||||
bool MachineLICM::HasAnyPHIUse(unsigned Reg) const {
|
bool MachineLICM::HasLoopPHIUse(const MachineInstr *MI) const {
|
||||||
|
SmallVector<const MachineInstr*, 8> Work(1, MI);
|
||||||
|
do {
|
||||||
|
MI = Work.pop_back_val();
|
||||||
|
for (ConstMIOperands MO(MI); MO.isValid(); ++MO) {
|
||||||
|
if (!MO->isReg() || !MO->isDef())
|
||||||
|
continue;
|
||||||
|
unsigned Reg = MO->getReg();
|
||||||
|
if (!TargetRegisterInfo::isVirtualRegister(Reg))
|
||||||
|
continue;
|
||||||
for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg),
|
for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg),
|
||||||
UE = MRI->use_end(); UI != UE; ++UI) {
|
UE = MRI->use_end(); UI != UE; ++UI) {
|
||||||
MachineInstr *UseMI = &*UI;
|
MachineInstr *UseMI = &*UI;
|
||||||
if (UseMI->isPHI())
|
// A PHI may cause a copy to be inserted.
|
||||||
|
if (UseMI->isPHI()) {
|
||||||
|
// A PHI inside the loop causes a copy because the live range of Reg is
|
||||||
|
// extended across the PHI.
|
||||||
|
if (CurLoop->contains(UseMI))
|
||||||
return true;
|
return true;
|
||||||
// Look pass copies as well.
|
// A PHI in an exit block can cause a copy to be inserted if the PHI
|
||||||
if (UseMI->isCopy()) {
|
// has multiple predecessors in the loop with different values.
|
||||||
unsigned Def = UseMI->getOperand(0).getReg();
|
// For now, approximate by rejecting all exit blocks.
|
||||||
if (TargetRegisterInfo::isVirtualRegister(Def) &&
|
if (isExitBlock(UseMI->getParent()))
|
||||||
HasAnyPHIUse(Def))
|
|
||||||
return true;
|
return true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Look past copies as well.
|
||||||
|
if (UseMI->isCopy() && CurLoop->contains(UseMI))
|
||||||
|
Work.push_back(UseMI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} while (!Work.empty());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1182,15 +1211,10 @@ bool MachineLICM::IsProfitableToHoist(MachineInstr &MI) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If result(s) of this instruction is used by PHIs outside of the loop, then
|
// If result(s) of this instruction is used by PHIs inside the loop, then
|
||||||
// don't hoist it if the instruction because it will introduce an extra copy.
|
// don't hoist it because it will introduce an extra copy.
|
||||||
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
|
if (HasLoopPHIUse(&MI))
|
||||||
const MachineOperand &MO = MI.getOperand(i);
|
|
||||||
if (!MO.isReg() || !MO.isDef())
|
|
||||||
continue;
|
|
||||||
if (HasAnyPHIUse(MO.getReg()))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user