- Change MachineInstr::isIdenticalTo to take a new option that determines whether it should skip checking defs or at least virtual register defs. This subsumes part of the TargetInstrInfo::isIdentical functionality.

- Eliminate TargetInstrInfo::isIdentical and replace it with produceSameValue. In the default case, produceSameValue just checks whether two machine instructions are identical (except for virtual register defs). But targets may override it to check for unusual cases (e.g. ARM pic loads from constant pools).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97628 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-03-03 01:44:33 +00:00
parent d89347cb49
commit 506049f29f
7 changed files with 54 additions and 63 deletions

View File

@ -179,17 +179,16 @@ public:
return MemRefsEnd - MemRefs == 1; return MemRefsEnd - MemRefs == 1;
} }
enum MICheckType {
CheckDefs, // Check all operands for equality
IgnoreDefs, // Ignore all definitions
IgnoreVRegDefs // Ignore virtual register definitions
};
/// isIdenticalTo - Return true if this instruction is identical to (same /// isIdenticalTo - Return true if this instruction is identical to (same
/// opcode and same operands as) the specified instruction. /// opcode and same operands as) the specified instruction.
bool isIdenticalTo(const MachineInstr *Other) const { bool isIdenticalTo(const MachineInstr *Other,
if (Other->getOpcode() != getOpcode() || MICheckType Check = CheckDefs) const;
Other->getNumOperands() != getNumOperands())
return false;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
if (!getOperand(i).isIdenticalTo(Other->getOperand(i)))
return false;
return true;
}
/// removeFromParent - This method unlinks 'this' from the containing basic /// removeFromParent - This method unlinks 'this' from the containing basic
/// block, and returns it, but does not delete it. /// block, and returns it, but does not delete it.

View File

@ -19,14 +19,14 @@
namespace llvm { namespace llvm {
class MCAsmInfo;
class TargetRegisterClass;
class TargetRegisterInfo;
class LiveVariables;
class CalleeSavedInfo; class CalleeSavedInfo;
class LiveVariables;
class MCAsmInfo;
class MachineMemOperand;
class SDNode; class SDNode;
class SelectionDAG; class SelectionDAG;
class MachineMemOperand; class TargetRegisterClass;
class TargetRegisterInfo;
template<class T> class SmallVectorImpl; template<class T> class SmallVectorImpl;
@ -243,13 +243,11 @@ public:
virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1, virtual bool findCommutedOpIndices(MachineInstr *MI, unsigned &SrcOpIdx1,
unsigned &SrcOpIdx2) const = 0; unsigned &SrcOpIdx2) const = 0;
/// isIdentical - Return true if two instructions are identical. This differs /// produceSameValue - Return true if two machine instructions would produce
/// from MachineInstr::isIdenticalTo() in that it does not require the /// identical values. By default, this is only true when the two instructions
/// virtual destination registers to be the same. This is used by MachineLICM /// are deemed identical except for defs.
/// and other MI passes to perform CSE. virtual bool produceSameValue(const MachineInstr *MI0,
virtual bool isIdentical(const MachineInstr *MI, const MachineInstr *MI1) const = 0;
const MachineInstr *Other,
const MachineRegisterInfo *MRI) const = 0;
/// AnalyzeBranch - Analyze the branching code at the end of MBB, returning /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
/// true if it cannot be understood (e.g. it's a switch dispatch or isn't /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
@ -560,10 +558,8 @@ public:
const TargetRegisterInfo *TRI) const; const TargetRegisterInfo *TRI) const;
virtual MachineInstr *duplicate(MachineInstr *Orig, virtual MachineInstr *duplicate(MachineInstr *Orig,
MachineFunction &MF) const; MachineFunction &MF) const;
virtual bool isIdentical(const MachineInstr *MI, virtual bool produceSameValue(const MachineInstr *MI0,
const MachineInstr *Other, const MachineInstr *MI1) const;
const MachineRegisterInfo *MRI) const;
virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const; virtual unsigned GetFunctionSizeInBytes(const MachineFunction &MF) const;
}; };

View File

@ -18,6 +18,7 @@
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/Value.h" #include "llvm/Value.h"
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h"
@ -701,6 +702,28 @@ void MachineInstr::addMemOperand(MachineFunction &MF,
MemRefsEnd = NewMemRefsEnd; MemRefsEnd = NewMemRefsEnd;
} }
bool MachineInstr::isIdenticalTo(const MachineInstr *Other,
MICheckType Check) const {
if (Other->getOpcode() != getOpcode() ||
Other->getNumOperands() != getNumOperands())
return false;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
const MachineOperand &MO = getOperand(i);
const MachineOperand &OMO = Other->getOperand(i);
if (Check != CheckDefs && MO.isReg() && MO.isDef()) {
if (Check == IgnoreDefs)
continue;
// Check == IgnoreVRegDefs
if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) ||
TargetRegisterInfo::isPhysicalRegister(OMO.getReg()))
if (MO.getReg() != OMO.getReg())
return false;
} else if (!MO.isIdenticalTo(OMO))
return false;
}
return true;
}
/// removeFromParent - This method unlinks 'this' from the containing basic /// removeFromParent - This method unlinks 'this' from the containing basic
/// block, and returns it, but does not delete it. /// block, and returns it, but does not delete it.
MachineInstr *MachineInstr::removeFromParent() { MachineInstr *MachineInstr::removeFromParent() {

View File

@ -445,7 +445,7 @@ MachineLICM::LookForDuplicate(const MachineInstr *MI,
std::vector<const MachineInstr*> &PrevMIs) { std::vector<const MachineInstr*> &PrevMIs) {
for (unsigned i = 0, e = PrevMIs.size(); i != e; ++i) { for (unsigned i = 0, e = PrevMIs.size(); i != e; ++i) {
const MachineInstr *PrevMI = PrevMIs[i]; const MachineInstr *PrevMI = PrevMIs[i];
if (TII->isIdentical(MI, PrevMI, RegInfo)) if (TII->produceSameValue(MI, PrevMI))
return PrevMI; return PrevMI;
} }
return 0; return 0;

View File

@ -150,6 +150,11 @@ void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
MBB.insert(I, MI); MBB.insert(I, MI);
} }
bool TargetInstrInfoImpl::produceSameValue(const MachineInstr *MI0,
const MachineInstr *MI1) const {
return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
}
MachineInstr *TargetInstrInfoImpl::duplicate(MachineInstr *Orig, MachineInstr *TargetInstrInfoImpl::duplicate(MachineInstr *Orig,
MachineFunction &MF) const { MachineFunction &MF) const {
assert(!Orig->getDesc().isNotDuplicable() && assert(!Orig->getDesc().isNotDuplicable() &&
@ -157,37 +162,6 @@ MachineInstr *TargetInstrInfoImpl::duplicate(MachineInstr *Orig,
return MF.CloneMachineInstr(Orig); return MF.CloneMachineInstr(Orig);
} }
bool
TargetInstrInfoImpl::isIdentical(const MachineInstr *MI,
const MachineInstr *Other,
const MachineRegisterInfo *MRI) const {
if (MI->getOpcode() != Other->getOpcode() ||
MI->getNumOperands() != Other->getNumOperands())
return false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = MI->getOperand(i);
const MachineOperand &OMO = Other->getOperand(i);
if (MO.isReg() && MO.isDef()) {
assert(OMO.isReg() && OMO.isDef());
unsigned Reg = MO.getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
if (Reg != OMO.getReg())
return false;
} else if (MRI->getRegClass(MO.getReg()) !=
MRI->getRegClass(OMO.getReg()))
return false;
continue;
}
if (!MO.isIdenticalTo(OMO))
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

@ -1037,9 +1037,8 @@ ARMBaseInstrInfo::duplicate(MachineInstr *Orig, MachineFunction &MF) const {
return MI; return MI;
} }
bool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0, bool ARMBaseInstrInfo::produceSameValue(const MachineInstr *MI0,
const MachineInstr *MI1, const MachineInstr *MI1) const {
const MachineRegisterInfo *MRI) const {
int Opcode = MI0->getOpcode(); int Opcode = MI0->getOpcode();
if (Opcode == ARM::t2LDRpci || if (Opcode == ARM::t2LDRpci ||
Opcode == ARM::t2LDRpci_pic || Opcode == ARM::t2LDRpci_pic ||
@ -1068,7 +1067,7 @@ bool ARMBaseInstrInfo::isIdentical(const MachineInstr *MI0,
return ACPV0->hasSameValue(ACPV1); return ACPV0->hasSameValue(ACPV1);
} }
return TargetInstrInfoImpl::isIdentical(MI0, MI1, MRI); return MI0->isIdenticalTo(MI1, MachineInstr::IgnoreVRegDefs);
} }
/// getInstrPredicate - If instruction is predicated, returns its predicate /// getInstrPredicate - If instruction is predicated, returns its predicate

View File

@ -289,8 +289,8 @@ public:
MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const; MachineInstr *duplicate(MachineInstr *Orig, MachineFunction &MF) const;
virtual bool isIdentical(const MachineInstr *MI, const MachineInstr *Other, virtual bool produceSameValue(const MachineInstr *MI0,
const MachineRegisterInfo *MRI) const; const MachineInstr *MI1) const;
}; };
static inline static inline