mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-17 20:23:59 +00:00
If any def of a machine-sink candidate has local uses, it's obviously not safe to sink it to a successor block. This bug has been hidden because a later check for critical-edge disable these illegal optimizations. This patch should significantly reduce the amount of time spent on checking dominator information for obviously unsafe sinking.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111450 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -60,7 +60,8 @@ namespace {
|
|||||||
private:
|
private:
|
||||||
bool ProcessBlock(MachineBasicBlock &MBB);
|
bool ProcessBlock(MachineBasicBlock &MBB);
|
||||||
bool SinkInstruction(MachineInstr *MI, bool &SawStore);
|
bool SinkInstruction(MachineInstr *MI, bool &SawStore);
|
||||||
bool AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB) const;
|
bool AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB,
|
||||||
|
MachineBasicBlock *DefMBB, bool &LocalUse) const;
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
@ -71,9 +72,13 @@ INITIALIZE_PASS(MachineSinking, "machine-sink",
|
|||||||
FunctionPass *llvm::createMachineSinkingPass() { return new MachineSinking(); }
|
FunctionPass *llvm::createMachineSinkingPass() { return new MachineSinking(); }
|
||||||
|
|
||||||
/// AllUsesDominatedByBlock - Return true if all uses of the specified register
|
/// AllUsesDominatedByBlock - Return true if all uses of the specified register
|
||||||
/// occur in blocks dominated by the specified block.
|
/// occur in blocks dominated by the specified block. If any use is in the
|
||||||
|
/// definition block, then return false since it is never legal to move def
|
||||||
|
/// after uses.
|
||||||
bool MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
|
bool MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
|
||||||
MachineBasicBlock *MBB) const {
|
MachineBasicBlock *MBB,
|
||||||
|
MachineBasicBlock *DefMBB,
|
||||||
|
bool &LocalUse) const {
|
||||||
assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
|
assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
|
||||||
"Only makes sense for vregs");
|
"Only makes sense for vregs");
|
||||||
// Ignoring debug uses is necessary so debug info doesn't affect the code.
|
// Ignoring debug uses is necessary so debug info doesn't affect the code.
|
||||||
@ -86,6 +91,10 @@ bool MachineSinking::AllUsesDominatedByBlock(unsigned Reg,
|
|||||||
// Determine the block of the use.
|
// Determine the block of the use.
|
||||||
MachineInstr *UseInst = &*I;
|
MachineInstr *UseInst = &*I;
|
||||||
MachineBasicBlock *UseBlock = UseInst->getParent();
|
MachineBasicBlock *UseBlock = UseInst->getParent();
|
||||||
|
if (UseBlock == DefMBB) {
|
||||||
|
LocalUse = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (UseInst->isPHI()) {
|
if (UseInst->isPHI()) {
|
||||||
// PHI nodes use the operand in the predecessor block, not the block with
|
// PHI nodes use the operand in the predecessor block, not the block with
|
||||||
@ -189,6 +198,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
|||||||
// decide.
|
// decide.
|
||||||
MachineBasicBlock *SuccToSinkTo = 0;
|
MachineBasicBlock *SuccToSinkTo = 0;
|
||||||
|
|
||||||
|
bool LocalUse = false;
|
||||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
const MachineOperand &MO = MI->getOperand(i);
|
const MachineOperand &MO = MI->getOperand(i);
|
||||||
if (!MO.isReg()) continue; // Ignore non-register operands.
|
if (!MO.isReg()) continue; // Ignore non-register operands.
|
||||||
@ -246,7 +256,7 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
|||||||
if (SuccToSinkTo) {
|
if (SuccToSinkTo) {
|
||||||
// If a previous operand picked a block to sink to, then this operand
|
// If a previous operand picked a block to sink to, then this operand
|
||||||
// must be sinkable to the same block.
|
// must be sinkable to the same block.
|
||||||
if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo))
|
if (!AllUsesDominatedByBlock(Reg, SuccToSinkTo, ParentBlock, LocalUse))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -256,10 +266,13 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
|
|||||||
// we should sink to.
|
// we should sink to.
|
||||||
for (MachineBasicBlock::succ_iterator SI = ParentBlock->succ_begin(),
|
for (MachineBasicBlock::succ_iterator SI = ParentBlock->succ_begin(),
|
||||||
E = ParentBlock->succ_end(); SI != E; ++SI) {
|
E = ParentBlock->succ_end(); SI != E; ++SI) {
|
||||||
if (AllUsesDominatedByBlock(Reg, *SI)) {
|
if (AllUsesDominatedByBlock(Reg, *SI, ParentBlock, LocalUse)) {
|
||||||
SuccToSinkTo = *SI;
|
SuccToSinkTo = *SI;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (LocalUse)
|
||||||
|
// Def is used locally, it's never safe to move this def.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we couldn't find a block to sink to, ignore this instruction.
|
// If we couldn't find a block to sink to, ignore this instruction.
|
||||||
|
Reference in New Issue
Block a user