- 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;
}
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
/// opcode and same operands as) the specified instruction.
bool isIdenticalTo(const MachineInstr *Other) const {
if (Other->getOpcode() != getOpcode() ||
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;
}
bool isIdenticalTo(const MachineInstr *Other,
MICheckType Check = CheckDefs) const;
/// removeFromParent - This method unlinks 'this' from the containing basic
/// block, and returns it, but does not delete it.

View File

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

View File

@ -18,6 +18,7 @@
#include "llvm/Type.h"
#include "llvm/Value.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
@ -701,6 +702,28 @@ void MachineInstr::addMemOperand(MachineFunction &MF,
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
/// block, and returns it, but does not delete it.
MachineInstr *MachineInstr::removeFromParent() {

View File

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

View File

@ -150,6 +150,11 @@ void TargetInstrInfoImpl::reMaterialize(MachineBasicBlock &MBB,
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,
MachineFunction &MF) const {
assert(!Orig->getDesc().isNotDuplicable() &&
@ -157,37 +162,6 @@ MachineInstr *TargetInstrInfoImpl::duplicate(MachineInstr *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
TargetInstrInfoImpl::GetFunctionSizeInBytes(const MachineFunction &MF) const {
unsigned FnSize = 0;

View File

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

View File

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