From 4dc848f3e81d369352e675f9195b3819e3b49cda Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 22 Jul 2009 00:25:27 +0000 Subject: [PATCH] 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 --- llvm/include/llvm/Target/TargetInstrInfo.h | 6 +++++ llvm/lib/CodeGen/TargetInstrInfoImpl.cpp | 21 +++++++++++++++++ llvm/lib/CodeGen/VirtRegRewriter.cpp | 27 ++-------------------- llvm/lib/Target/PowerPC/PPCInstrInfo.h | 7 ++++++ 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/llvm/include/llvm/Target/TargetInstrInfo.h b/llvm/include/llvm/Target/TargetInstrInfo.h index 0ab57ca08e4c..538d1390a180 100644 --- a/llvm/include/llvm/Target/TargetInstrInfo.h +++ b/llvm/include/llvm/Target/TargetInstrInfo.h @@ -470,6 +470,10 @@ public: 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. /// virtual unsigned GetInstSizeInBytes(const MachineInstr *MI) const { @@ -501,6 +505,8 @@ public: MachineBasicBlock::iterator MI, unsigned DestReg, unsigned SubReg, const MachineInstr *Orig) const; + virtual bool isDeadInstruction(const MachineInstr *MI) const; + virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const; }; diff --git a/llvm/lib/CodeGen/TargetInstrInfoImpl.cpp b/llvm/lib/CodeGen/TargetInstrInfoImpl.cpp index 0b791e4a71f5..8aca0ccd4240 100644 --- a/llvm/lib/CodeGen/TargetInstrInfoImpl.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfoImpl.cpp @@ -139,6 +139,27 @@ void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB, 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 TargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const { unsigned FnSize = 0; diff --git a/llvm/lib/CodeGen/VirtRegRewriter.cpp b/llvm/lib/CodeGen/VirtRegRewriter.cpp index 83224cc47428..745bfca9f26a 100644 --- a/llvm/lib/CodeGen/VirtRegRewriter.cpp +++ b/llvm/lib/CodeGen/VirtRegRewriter.cpp @@ -1349,29 +1349,6 @@ private: ++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 /// removed. Find the last def or use and mark it as dead / kill. void TransferDeadness(MachineBasicBlock *MBB, unsigned CurDist, @@ -1413,7 +1390,7 @@ private: if (LastUD->isDef()) { // If the instruction has no side effect, delete it and propagate // backward further. Otherwise, mark is dead and we are done. - if (!isSafeToDelete(*LastUDMI)) { + if (!TII->isDeadInstruction(LastUDMI)) { LastUD->setIsDead(); break; } @@ -2198,7 +2175,7 @@ private: } ProcessNextInst: // Delete dead instructions without side effects. - if (!Erased && !BackTracked && isSafeToDelete(MI)) { + if (!Erased && !BackTracked && TII->isDeadInstruction(&MI)) { InvalidateKills(MI, TRI, RegKills, KillOps); VRM.RemoveMachineInstrFromMaps(&MI); MBB.erase(&MI); diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.h b/llvm/lib/Target/PowerPC/PPCInstrInfo.h index 492634c979eb..c3acc685e8c2 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.h +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.h @@ -156,6 +156,13 @@ public: virtual bool BlockHasNoFallThrough(const MachineBasicBlock &MBB) const; virtual bool ReverseBranchCondition(SmallVectorImpl &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 /// instruction may be. This returns the maximum number of bytes.