diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2012-08-15 19:34:23 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2012-08-15 19:34:23 +0000 | 
| commit | 58b69754af0cbff56b1cfce9be9392e4451f6628 (patch) | |
| tree | eacfc83d988e4b9d11114387ae7dc41243f2a363 /lib/CodeGen/MachineInstr.cpp | |
| parent | 0378662f5bd3dbe8305a485b0282bceb8b52f465 (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/MachineInstr.cpp')
| -rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 295 | 
1 files changed, 147 insertions, 148 deletions
| diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index e553a0463a2af..b16684994696f 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -13,6 +13,7 @@  #include "llvm/CodeGen/MachineInstr.h"  #include "llvm/Constants.h" +#include "llvm/DebugInfo.h"  #include "llvm/Function.h"  #include "llvm/InlineAsm.h"  #include "llvm/LLVMContext.h" @@ -33,7 +34,6 @@  #include "llvm/Target/TargetInstrInfo.h"  #include "llvm/Target/TargetRegisterInfo.h"  #include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/Analysis/DebugInfo.h"  #include "llvm/Support/Debug.h"  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/LeakDetector.h" @@ -47,55 +47,6 @@ using namespace llvm;  // MachineOperand Implementation  //===----------------------------------------------------------------------===// -/// AddRegOperandToRegInfo - Add this register operand to the specified -/// MachineRegisterInfo.  If it is null, then the next/prev fields should be -/// explicitly nulled out. -void MachineOperand::AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo) { -  assert(isReg() && "Can only add reg operand to use lists"); - -  // If the reginfo pointer is null, just explicitly null out or next/prev -  // pointers, to ensure they are not garbage. -  if (RegInfo == 0) { -    Contents.Reg.Prev = 0; -    Contents.Reg.Next = 0; -    return; -  } - -  // Otherwise, add this operand to the head of the registers use/def list. -  MachineOperand **Head = &RegInfo->getRegUseDefListHead(getReg()); - -  // For SSA values, we prefer to keep the definition at the start of the list. -  // we do this by skipping over the definition if it is at the head of the -  // list. -  if (*Head && (*Head)->isDef()) -    Head = &(*Head)->Contents.Reg.Next; - -  Contents.Reg.Next = *Head; -  if (Contents.Reg.Next) { -    assert(getReg() == Contents.Reg.Next->getReg() && -           "Different regs on the same list!"); -    Contents.Reg.Next->Contents.Reg.Prev = &Contents.Reg.Next; -  } - -  Contents.Reg.Prev = Head; -  *Head = this; -} - -/// RemoveRegOperandFromRegInfo - Remove this register operand from the -/// MachineRegisterInfo it is linked with. -void MachineOperand::RemoveRegOperandFromRegInfo() { -  assert(isOnRegUseList() && "Reg operand is not on a use list"); -  // Unlink this from the doubly linked list of operands. -  MachineOperand *NextOp = Contents.Reg.Next; -  *Contents.Reg.Prev = NextOp; -  if (NextOp) { -    assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!"); -    NextOp->Contents.Reg.Prev = Contents.Reg.Prev; -  } -  Contents.Reg.Prev = 0; -  Contents.Reg.Next = 0; -} -  void MachineOperand::setReg(unsigned Reg) {    if (getReg() == Reg) return; // No change. @@ -105,9 +56,10 @@ void MachineOperand::setReg(unsigned Reg) {    if (MachineInstr *MI = getParent())      if (MachineBasicBlock *MBB = MI->getParent())        if (MachineFunction *MF = MBB->getParent()) { -        RemoveRegOperandFromRegInfo(); +        MachineRegisterInfo &MRI = MF->getRegInfo(); +        MRI.removeRegOperandFromUseList(this);          SmallContents.RegNo = Reg; -        AddRegOperandToRegInfo(&MF->getRegInfo()); +        MRI.addRegOperandToUseList(this);          return;        } @@ -136,15 +88,36 @@ void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) {    setReg(Reg);  } +/// Change a def to a use, or a use to a def. +void MachineOperand::setIsDef(bool Val) { +  assert(isReg() && "Wrong MachineOperand accessor"); +  assert((!Val || !isDebug()) && "Marking a debug operation as def"); +  if (IsDef == Val) +    return; +  // MRI may keep uses and defs in different list positions. +  if (MachineInstr *MI = getParent()) +    if (MachineBasicBlock *MBB = MI->getParent()) +      if (MachineFunction *MF = MBB->getParent()) { +        MachineRegisterInfo &MRI = MF->getRegInfo(); +        MRI.removeRegOperandFromUseList(this); +        IsDef = Val; +        MRI.addRegOperandToUseList(this); +        return; +      } +  IsDef = Val; +} +  /// ChangeToImmediate - Replace this operand with a new immediate operand of  /// the specified value.  If an operand is known to be an immediate already,  /// the setImm method should be used.  void MachineOperand::ChangeToImmediate(int64_t ImmVal) {    // If this operand is currently a register operand, and if this is in a    // function, deregister the operand from the register's use/def list. -  if (isReg() && getParent() && getParent()->getParent() && -      getParent()->getParent()->getParent()) -    RemoveRegOperandFromRegInfo(); +  if (isReg() && isOnRegUseList()) +    if (MachineInstr *MI = getParent()) +      if (MachineBasicBlock *MBB = MI->getParent()) +        if (MachineFunction *MF = MBB->getParent()) +          MF->getRegInfo().removeRegOperandFromUseList(this);    OpKind = MO_Immediate;    Contents.ImmVal = ImmVal; @@ -156,24 +129,20 @@ void MachineOperand::ChangeToImmediate(int64_t ImmVal) {  void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,                                        bool isKill, bool isDead, bool isUndef,                                        bool isDebug) { -  // If this operand is already a register operand, use setReg to update the +  MachineRegisterInfo *RegInfo = 0; +  if (MachineInstr *MI = getParent()) +    if (MachineBasicBlock *MBB = MI->getParent()) +      if (MachineFunction *MF = MBB->getParent()) +        RegInfo = &MF->getRegInfo(); +  // If this operand is already a register operand, remove it from the    // register's use/def lists. -  if (isReg()) { -    assert(!isEarlyClobber()); -    setReg(Reg); -  } else { -    // Otherwise, change this to a register and set the reg#. -    OpKind = MO_Register; -    SmallContents.RegNo = Reg; - -    // If this operand is embedded in a function, add the operand to the -    // register's use/def list. -    if (MachineInstr *MI = getParent()) -      if (MachineBasicBlock *MBB = MI->getParent()) -        if (MachineFunction *MF = MBB->getParent()) -          AddRegOperandToRegInfo(&MF->getRegInfo()); -  } +  if (RegInfo && isReg()) +    RegInfo->removeRegOperandFromUseList(this); +  // Change this to a register and set the reg#. +  OpKind = MO_Register; +  SmallContents.RegNo = Reg; +  SubReg = 0;    IsDef = isDef;    IsImp = isImp;    IsKill = isKill; @@ -182,11 +151,18 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,    IsInternalRead = false;    IsEarlyClobber = false;    IsDebug = isDebug; -  SubReg = 0; +  // Ensure isOnRegUseList() returns false. +  Contents.Reg.Prev = 0; + +  // If this operand is embedded in a function, add the operand to the +  // register's use/def list. +  if (RegInfo) +    RegInfo->addRegOperandToUseList(this);  }  /// isIdenticalTo - Return true if this operand is identical to the specified -/// operand. +/// operand. Note that this should stay in sync with the hash_value overload +/// below.  bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {    if (getType() != Other.getType() ||        getTargetFlags() != Other.getTargetFlags()) @@ -207,6 +183,7 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {    case MachineOperand::MO_FrameIndex:      return getIndex() == Other.getIndex();    case MachineOperand::MO_ConstantPoolIndex: +  case MachineOperand::MO_TargetIndex:      return getIndex() == Other.getIndex() && getOffset() == Other.getOffset();    case MachineOperand::MO_JumpTableIndex:      return getIndex() == Other.getIndex(); @@ -227,6 +204,47 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {    llvm_unreachable("Invalid machine operand type");  } +// Note: this must stay exactly in sync with isIdenticalTo above. +hash_code llvm::hash_value(const MachineOperand &MO) { +  switch (MO.getType()) { +  case MachineOperand::MO_Register: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getReg(), +                        MO.getSubReg(), MO.isDef()); +  case MachineOperand::MO_Immediate: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getImm()); +  case MachineOperand::MO_CImmediate: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCImm()); +  case MachineOperand::MO_FPImmediate: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getFPImm()); +  case MachineOperand::MO_MachineBasicBlock: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMBB()); +  case MachineOperand::MO_FrameIndex: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); +  case MachineOperand::MO_ConstantPoolIndex: +  case MachineOperand::MO_TargetIndex: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex(), +                        MO.getOffset()); +  case MachineOperand::MO_JumpTableIndex: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIndex()); +  case MachineOperand::MO_ExternalSymbol: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getOffset(), +                        MO.getSymbolName()); +  case MachineOperand::MO_GlobalAddress: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getGlobal(), +                        MO.getOffset()); +  case MachineOperand::MO_BlockAddress: +    return hash_combine(MO.getType(), MO.getTargetFlags(), +                        MO.getBlockAddress()); +  case MachineOperand::MO_RegisterMask: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask()); +  case MachineOperand::MO_Metadata: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMetadata()); +  case MachineOperand::MO_MCSymbol: +    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getMCSymbol()); +  } +  llvm_unreachable("Invalid machine operand type"); +} +  /// print - Print the specified machine operand.  ///  void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const { @@ -255,12 +273,16 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {            OS << "imp-";          OS << "def";          NeedComma = true; +        // <def,read-undef> only makes sense when getSubReg() is set. +        // Don't clutter the output otherwise. +        if (isUndef() && getSubReg()) +          OS << ",read-undef";        } else if (isImplicit()) {            OS << "imp-use";            NeedComma = true;        } -      if (isKill() || isDead() || isUndef() || isInternalRead()) { +      if (isKill() || isDead() || (isUndef() && isUse()) || isInternalRead()) {          if (NeedComma) OS << ',';          NeedComma = false;          if (isKill()) { @@ -271,7 +293,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {            OS << "dead";            NeedComma = true;          } -        if (isUndef()) { +        if (isUndef() && isUse()) {            if (NeedComma) OS << ',';            OS << "undef";            NeedComma = true; @@ -308,6 +330,11 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {      if (getOffset()) OS << "+" << getOffset();      OS << '>';      break; +  case MachineOperand::MO_TargetIndex: +    OS << "<ti#" << getIndex(); +    if (getOffset()) OS << "+" << getOffset(); +    OS << '>'; +    break;    case MachineOperand::MO_JumpTableIndex:      OS << "<jt#" << getIndex() << '>';      break; @@ -605,24 +632,21 @@ MachineRegisterInfo *MachineInstr::getRegInfo() {  /// RemoveRegOperandsFromUseLists - Unlink all of the register operands in  /// this instruction from their respective use lists.  This requires that the  /// operands already be on their use lists. -void MachineInstr::RemoveRegOperandsFromUseLists() { -  for (unsigned i = 0, e = Operands.size(); i != e; ++i) { +void MachineInstr::RemoveRegOperandsFromUseLists(MachineRegisterInfo &MRI) { +  for (unsigned i = 0, e = Operands.size(); i != e; ++i)      if (Operands[i].isReg()) -      Operands[i].RemoveRegOperandFromRegInfo(); -  } +      MRI.removeRegOperandFromUseList(&Operands[i]);  }  /// AddRegOperandsToUseLists - Add all of the register operands in  /// this instruction from their respective use lists.  This requires that the  /// operands not be on their use lists yet. -void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo) { -  for (unsigned i = 0, e = Operands.size(); i != e; ++i) { +void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &MRI) { +  for (unsigned i = 0, e = Operands.size(); i != e; ++i)      if (Operands[i].isReg()) -      Operands[i].AddRegOperandToRegInfo(&RegInfo); -  } +      MRI.addRegOperandToUseList(&Operands[i]);  } -  /// addOperand - Add the specified operand to the instruction.  If it is an  /// implicit operand, it is added to the end of the operand list.  If it is  /// an explicit operand it is added at the end of the explicit operand list @@ -650,13 +674,15 @@ void MachineInstr::addOperand(const MachineOperand &Op) {      while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) {        --OpNo;        if (RegInfo) -        Operands[OpNo].RemoveRegOperandFromRegInfo(); +        RegInfo->removeRegOperandFromUseList(&Operands[OpNo]);      }    }    // OpNo now points as the desired insertion point.  Unless this is a variadic    // instruction, only implicit regs are allowed beyond MCID->getNumOperands(). -  assert((isImpReg || MCID->isVariadic() || OpNo < MCID->getNumOperands()) && +  // RegMask operands go between the explicit and implicit operands. +  assert((isImpReg || Op.isRegMask() || MCID->isVariadic() || +          OpNo < MCID->getNumOperands()) &&           "Trying to add an operand to a machine instr that is already done!");    // All operands from OpNo have been removed from RegInfo.  If the Operands @@ -665,7 +691,7 @@ void MachineInstr::addOperand(const MachineOperand &Op) {    if (Reallocate)      for (unsigned i = 0; i != OpNo; ++i)        if (Operands[i].isReg()) -        Operands[i].RemoveRegOperandFromRegInfo(); +        RegInfo->removeRegOperandFromUseList(&Operands[i]);    // Insert the new operand at OpNo.    Operands.insert(Operands.begin() + OpNo, Op); @@ -676,13 +702,15 @@ void MachineInstr::addOperand(const MachineOperand &Op) {    if (Reallocate)      for (unsigned i = 0; i != OpNo; ++i)        if (Operands[i].isReg()) -        Operands[i].AddRegOperandToRegInfo(RegInfo); +        RegInfo->addRegOperandToUseList(&Operands[i]);    // When adding a register operand, tell RegInfo about it.    if (Operands[OpNo].isReg()) { -    // Add the new operand to RegInfo, even when RegInfo is NULL. -    // This will initialize the linked list pointers. -    Operands[OpNo].AddRegOperandToRegInfo(RegInfo); +    // Ensure isOnRegUseList() returns false, regardless of Op's status. +    Operands[OpNo].Contents.Reg.Prev = 0; +    // Add the new operand to RegInfo. +    if (RegInfo) +      RegInfo->addRegOperandToUseList(&Operands[OpNo]);      // If the register operand is flagged as early, mark the operand as such.      if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1)        Operands[OpNo].setIsEarlyClobber(true); @@ -692,7 +720,7 @@ void MachineInstr::addOperand(const MachineOperand &Op) {    if (RegInfo) {      for (unsigned i = OpNo + 1, e = Operands.size(); i != e; ++i) {        assert(Operands[i].isReg() && "Should only be an implicit reg!"); -      Operands[i].AddRegOperandToRegInfo(RegInfo); +      RegInfo->addRegOperandToUseList(&Operands[i]);      }    }  } @@ -702,12 +730,13 @@ void MachineInstr::addOperand(const MachineOperand &Op) {  ///  void MachineInstr::RemoveOperand(unsigned OpNo) {    assert(OpNo < Operands.size() && "Invalid operand number"); +  MachineRegisterInfo *RegInfo = getRegInfo();    // Special case removing the last one.    if (OpNo == Operands.size()-1) {      // If needed, remove from the reg def/use list. -    if (Operands.back().isReg() && Operands.back().isOnRegUseList()) -      Operands.back().RemoveRegOperandFromRegInfo(); +    if (RegInfo && Operands.back().isReg() && Operands.back().isOnRegUseList()) +      RegInfo->removeRegOperandFromUseList(&Operands.back());      Operands.pop_back();      return; @@ -716,11 +745,10 @@ void MachineInstr::RemoveOperand(unsigned OpNo) {    // Otherwise, we are removing an interior operand.  If we have reginfo to    // update, remove all operands that will be shifted down from their reg lists,    // move everything down, then re-add them. -  MachineRegisterInfo *RegInfo = getRegInfo();    if (RegInfo) {      for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) {        if (Operands[i].isReg()) -        Operands[i].RemoveRegOperandFromRegInfo(); +        RegInfo->removeRegOperandFromUseList(&Operands[i]);      }    } @@ -729,7 +757,7 @@ void MachineInstr::RemoveOperand(unsigned OpNo) {    if (RegInfo) {      for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) {        if (Operands[i].isReg()) -        Operands[i].AddRegOperandToRegInfo(RegInfo); +        RegInfo->addRegOperandToUseList(&Operands[i]);      }    }  } @@ -868,7 +896,8 @@ void MachineInstr::eraseFromParent() {        MBB->erase(MI);      }    } -  getParent()->erase(this); +  // Erase the individual instruction, which may itself be inside a bundle. +  getParent()->erase_instr(this);  } @@ -938,9 +967,13 @@ const TargetRegisterClass*  MachineInstr::getRegClassConstraint(unsigned OpIdx,                                      const TargetInstrInfo *TII,                                      const TargetRegisterInfo *TRI) const { +  assert(getParent() && "Can't have an MBB reference here!"); +  assert(getParent()->getParent() && "Can't have an MF reference here!"); +  const MachineFunction &MF = *getParent()->getParent(); +    // Most opcodes have fixed constraints in their MCInstrDesc.    if (!isInlineAsm()) -    return TII->getRegClass(getDesc(), OpIdx, TRI); +    return TII->getRegClass(getDesc(), OpIdx, TRI, MF);    if (!getOperand(OpIdx).isReg())      return NULL; @@ -962,7 +995,7 @@ MachineInstr::getRegClassConstraint(unsigned OpIdx,    // Assume that all registers in a memory operand are pointers.    if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) -    return TRI->getPointerRegClass(); +    return TRI->getPointerRegClass(MF);    return NULL;  } @@ -1530,12 +1563,14 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {          const MachineRegisterInfo &MRI = MF->getRegInfo();          if (MRI.use_empty(Reg) && !MRI.isLiveOut(Reg)) {            bool HasAliasLive = false; -          for (const uint16_t *Alias = TM->getRegisterInfo()->getAliasSet(Reg); -               unsigned AliasReg = *Alias; ++Alias) +          for (MCRegAliasIterator AI(Reg, TM->getRegisterInfo(), true); +               AI.isValid(); ++AI) { +            unsigned AliasReg = *AI;              if (!MRI.use_empty(AliasReg) || MRI.isLiveOut(AliasReg)) {                HasAliasLive = true;                break;              } +          }            if (!HasAliasLive) {              OmittedAnyCallClobbers = true;              continue; @@ -1667,7 +1702,8 @@ bool MachineInstr::addRegisterKilled(unsigned IncomingReg,                                       const TargetRegisterInfo *RegInfo,                                       bool AddIfNotFound) {    bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); -  bool hasAliases = isPhysReg && RegInfo->getAliasSet(IncomingReg); +  bool hasAliases = isPhysReg && +    MCRegAliasIterator(IncomingReg, RegInfo, false).isValid();    bool Found = false;    SmallVector<unsigned,4> DeadOps;    for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { @@ -1739,7 +1775,8 @@ bool MachineInstr::addRegisterDead(unsigned IncomingReg,                                     const TargetRegisterInfo *RegInfo,                                     bool AddIfNotFound) {    bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(IncomingReg); -  bool hasAliases = isPhysReg && RegInfo->getAliasSet(IncomingReg); +  bool hasAliases = isPhysReg && +    MCRegAliasIterator(IncomingReg, RegInfo, false).isValid();    bool Found = false;    SmallVector<unsigned,4> DeadOps;    for (unsigned i = 0, e = getNumOperands(); i != e; ++i) { @@ -1758,9 +1795,7 @@ bool MachineInstr::addRegisterDead(unsigned IncomingReg,        // There exists a super-register that's marked dead.        if (RegInfo->isSuperRegister(IncomingReg, Reg))          return true; -      if (RegInfo->getSubRegisters(IncomingReg) && -          RegInfo->getSuperRegisters(Reg) && -          RegInfo->isSubRegister(IncomingReg, Reg)) +      if (RegInfo->isSubRegister(IncomingReg, Reg))          DeadOps.push_back(i);      }    } @@ -1841,52 +1876,16 @@ void MachineInstr::setPhysRegsDeadExcept(ArrayRef<unsigned> UsedRegs,  unsigned  MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {    // Build up a buffer of hash code components. -  // -  // FIXME: This is a total hack. We should have a hash_value overload for -  // MachineOperand, but currently that doesn't work because there are many -  // different ideas of "equality" and thus different sets of information that -  // contribute to the hash code. This one happens to want to take a specific -  // subset. And it's still not clear that this routine uses the *correct* -  // subset of information when computing the hash code. The goal is to use the -  // same inputs for the hash code here that MachineInstr::isIdenticalTo uses to -  // test for equality when passed the 'IgnoreVRegDefs' filter flag. It would -  // be very useful to factor the selection of relevant inputs out of the two -  // functions and into a common routine, but it's not clear how that can be -  // done.    SmallVector<size_t, 8> HashComponents;    HashComponents.reserve(MI->getNumOperands() + 1);    HashComponents.push_back(MI->getOpcode());    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {      const MachineOperand &MO = MI->getOperand(i); -    switch (MO.getType()) { -    default: break; -    case MachineOperand::MO_Register: -      if (MO.isDef() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) -        continue;  // Skip virtual register defs. -      HashComponents.push_back(hash_combine(MO.getType(), MO.getReg())); -      break; -    case MachineOperand::MO_Immediate: -      HashComponents.push_back(hash_combine(MO.getType(), MO.getImm())); -      break; -    case MachineOperand::MO_FrameIndex: -    case MachineOperand::MO_ConstantPoolIndex: -    case MachineOperand::MO_JumpTableIndex: -      HashComponents.push_back(hash_combine(MO.getType(), MO.getIndex())); -      break; -    case MachineOperand::MO_MachineBasicBlock: -      HashComponents.push_back(hash_combine(MO.getType(), MO.getMBB())); -      break; -    case MachineOperand::MO_GlobalAddress: -      HashComponents.push_back(hash_combine(MO.getType(), MO.getGlobal())); -      break; -    case MachineOperand::MO_BlockAddress: -      HashComponents.push_back(hash_combine(MO.getType(), -                                            MO.getBlockAddress())); -      break; -    case MachineOperand::MO_MCSymbol: -      HashComponents.push_back(hash_combine(MO.getType(), MO.getMCSymbol())); -      break; -    } +    if (MO.isReg() && MO.isDef() && +        TargetRegisterInfo::isVirtualRegister(MO.getReg())) +      continue;  // Skip virtual register defs. + +    HashComponents.push_back(hash_value(MO));    }    return hash_combine_range(HashComponents.begin(), HashComponents.end());  } | 
