forked from OSchip/llvm-project
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:
parent
47db941fd3
commit
4dc848f3e8
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue