Let each target determines whether a machine instruction is dead. If true, that allows late codeine passes to delete it.

This is considered a workaround. The problem is some targets are not modeling side effects correctly. PPC is apparently one of those. This patch allows ppc llvm-gcc to bootstrap on Darwin. Once we find out which instruction definitions are wrong, we can remove the PPCInstrInfo workaround.

llvm-svn: 76703
This commit is contained in:
Evan Cheng 2009-07-22 00:25:27 +00:00
parent 47db941fd3
commit 4dc848f3e8
4 changed files with 36 additions and 25 deletions

View File

@ -470,6 +470,10 @@ public:
return true; return true;
} }
/// isDeadInstruction - Return true if the instruction is considered dead.
/// This allows some late codegen passes to delete them.
virtual bool isDeadInstruction(const MachineInstr *MI) const = 0;
/// GetInstSize - Returns the size of the specified Instruction. /// GetInstSize - Returns the size of the specified Instruction.
/// ///
virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const { virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const {
@ -501,6 +505,8 @@ public:
MachineBasicBlock::iterator MI, MachineBasicBlock::iterator MI,
unsigned DestReg, unsigned SubReg, unsigned DestReg, unsigned SubReg,
const MachineInstr *Orig) const; const MachineInstr *Orig) const;
virtual bool isDeadInstruction(const MachineInstr *MI) const;
virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const; virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
}; };

View File

@ -139,6 +139,27 @@ void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
MBB.insert(I, MI); MBB.insert(I, MI);
} }
bool TargetInstrInfoImpl::isDeadInstruction(const MachineInstr *MI) const {
const TargetInstrDesc &TID = MI->getDesc();
if (TID.mayLoad() || TID.mayStore() || TID.isCall() || TID.isTerminator() ||
TID.isCall() || TID.isBarrier() || TID.isReturn() ||
TID.hasUnmodeledSideEffects())
return false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || !MO.getReg())
continue;
if (MO.isDef() && !MO.isDead())
return false;
if (MO.isUse() && MO.isKill())
// FIXME: We can't remove kill markers or else the scavenger will assert.
// An alternative is to add a ADD pseudo instruction to replace kill
// markers.
return false;
}
return true;
}
unsigned unsigned
TargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const { TargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const {
unsigned FnSize = 0; unsigned FnSize = 0;

View File

@ -1349,29 +1349,6 @@ private:
++NumStores; ++NumStores;
} }
/// isSafeToDelete - Return true if this instruction doesn't produce any side
/// effect and all of its defs are dead.
static bool isSafeToDelete(MachineInstr &MI) {
const TargetInstrDesc &TID = MI.getDesc();
if (TID.mayLoad() || TID.mayStore() || TID.isCall() || TID.isTerminator() ||
TID.isCall() || TID.isBarrier() || TID.isReturn() ||
TID.hasUnmodeledSideEffects())
return false;
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.getReg())
continue;
if (MO.isDef() && !MO.isDead())
return false;
if (MO.isUse() && MO.isKill())
// FIXME: We can't remove kill markers or else the scavenger will assert.
// An alternative is to add a ADD pseudo instruction to replace kill
// markers.
return false;
}
return true;
}
/// TransferDeadness - A identity copy definition is dead and it's being /// TransferDeadness - A identity copy definition is dead and it's being
/// removed. Find the last def or use and mark it as dead / kill. /// removed. Find the last def or use and mark it as dead / kill.
void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist, void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist,
@ -1413,7 +1390,7 @@ private:
if (LastUD->isDef()) { if (LastUD->isDef()) {
// If the instruction has no side effect, delete it and propagate // If the instruction has no side effect, delete it and propagate
// backward further. Otherwise, mark is dead and we are done. // backward further. Otherwise, mark is dead and we are done.
if (!isSafeToDelete(*LastUDMI)) { if (!TII->isDeadInstruction(LastUDMI)) {
LastUD->setIsDead(); LastUD->setIsDead();
break; break;
} }
@ -2198,7 +2175,7 @@ private:
} }
ProcessNextInst: ProcessNextInst:
// Delete dead instructions without side effects. // Delete dead instructions without side effects.
if (!Erased && !BackTracked && isSafeToDelete(MI)) { if (!Erased && !BackTracked && TII->isDeadInstruction(&MI)) {
InvalidateKills(MI, TRI, RegKills, KillOps); InvalidateKills(MI, TRI, RegKills, KillOps);
VRM.RemoveMachineInstrFromMaps(&MI); VRM.RemoveMachineInstrFromMaps(&MI);
MBB.erase(&MI); MBB.erase(&MI);

View File

@ -156,6 +156,13 @@ public:
virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const; virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const;
virtual virtual
bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const; bool ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const;
virtual bool isDeadInstruction(const MachineInstr *MI) const {
// FIXME: Without this, ppc llvm-gcc doesn't bootstrap. That means some
// instruction definitions are not modeling side effects correctly.
// This is a workaround until we know the exact cause.
return false;
}
/// GetInstSize - Return the number of bytes of code the specified /// GetInstSize - Return the number of bytes of code the specified
/// instruction may be. This returns the maximum number of bytes. /// instruction may be. This returns the maximum number of bytes.