diff options
Diffstat (limited to 'lib/CodeGen/MachineInstr.cpp')
| -rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 930 | 
1 files changed, 170 insertions, 760 deletions
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 535757ed87c1..14655c6eb700 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -18,6 +18,7 @@  #include "llvm/ADT/Hashing.h"  #include "llvm/ADT/None.h"  #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallBitVector.h"  #include "llvm/ADT/SmallString.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/Analysis/AliasAnalysis.h" @@ -33,6 +34,9 @@  #include "llvm/CodeGen/MachineOperand.h"  #include "llvm/CodeGen/MachineRegisterInfo.h"  #include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h"  #include "llvm/IR/Constants.h"  #include "llvm/IR/DebugInfoMetadata.h"  #include "llvm/IR/DebugLoc.h" @@ -58,11 +62,8 @@  #include "llvm/Support/LowLevelTypeImpl.h"  #include "llvm/Support/MathExtras.h"  #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h"  #include "llvm/Target/TargetIntrinsicInfo.h"  #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h"  #include <algorithm>  #include <cassert>  #include <cstddef> @@ -73,695 +74,6 @@  using namespace llvm; -static cl::opt<bool> PrintWholeRegMask( -    "print-whole-regmask", -    cl::desc("Print the full contents of regmask operands in IR dumps"), -    cl::init(true), cl::Hidden); - -//===----------------------------------------------------------------------===// -// MachineOperand Implementation -//===----------------------------------------------------------------------===// - -void MachineOperand::setReg(unsigned Reg) { -  if (getReg() == Reg) return; // No change. - -  // Otherwise, we have to change the register.  If this operand is embedded -  // into a machine function, we need to update the old and new register's -  // use/def lists. -  if (MachineInstr *MI = getParent()) -    if (MachineBasicBlock *MBB = MI->getParent()) -      if (MachineFunction *MF = MBB->getParent()) { -        MachineRegisterInfo &MRI = MF->getRegInfo(); -        MRI.removeRegOperandFromUseList(this); -        SmallContents.RegNo = Reg; -        MRI.addRegOperandToUseList(this); -        return; -      } - -  // Otherwise, just change the register, no problem.  :) -  SmallContents.RegNo = Reg; -} - -void MachineOperand::substVirtReg(unsigned Reg, unsigned SubIdx, -                                  const TargetRegisterInfo &TRI) { -  assert(TargetRegisterInfo::isVirtualRegister(Reg)); -  if (SubIdx && getSubReg()) -    SubIdx = TRI.composeSubRegIndices(SubIdx, getSubReg()); -  setReg(Reg); -  if (SubIdx) -    setSubReg(SubIdx); -} - -void MachineOperand::substPhysReg(unsigned Reg, const TargetRegisterInfo &TRI) { -  assert(TargetRegisterInfo::isPhysicalRegister(Reg)); -  if (getSubReg()) { -    Reg = TRI.getSubReg(Reg, getSubReg()); -    // Note that getSubReg() may return 0 if the sub-register doesn't exist. -    // That won't happen in legal code. -    setSubReg(0); -    if (isDef()) -      setIsUndef(false); -  } -  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; -} - -// 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. -void MachineOperand::removeRegFromUses() { -  if (!isReg() || !isOnRegUseList()) -    return; - -  if (MachineInstr *MI = getParent()) { -    if (MachineBasicBlock *MBB = MI->getParent()) { -      if (MachineFunction *MF = MBB->getParent()) -        MF->getRegInfo().removeRegOperandFromUseList(this); -    } -  } -} - -/// 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) { -  assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); - -  removeRegFromUses(); - -  OpKind = MO_Immediate; -  Contents.ImmVal = ImmVal; -} - -void MachineOperand::ChangeToFPImmediate(const ConstantFP *FPImm) { -  assert((!isReg() || !isTied()) && "Cannot change a tied operand into an imm"); - -  removeRegFromUses(); - -  OpKind = MO_FPImmediate; -  Contents.CFP = FPImm; -} - -void MachineOperand::ChangeToES(const char *SymName, unsigned char TargetFlags) { -  assert((!isReg() || !isTied()) && -         "Cannot change a tied operand into an external symbol"); - -  removeRegFromUses(); - -  OpKind = MO_ExternalSymbol; -  Contents.OffsetedInfo.Val.SymbolName = SymName; -  setOffset(0); // Offset is always 0. -  setTargetFlags(TargetFlags); -} - -void MachineOperand::ChangeToMCSymbol(MCSymbol *Sym) { -  assert((!isReg() || !isTied()) && -         "Cannot change a tied operand into an MCSymbol"); - -  removeRegFromUses(); - -  OpKind = MO_MCSymbol; -  Contents.Sym = Sym; -} - -void MachineOperand::ChangeToFrameIndex(int Idx) { -  assert((!isReg() || !isTied()) && -         "Cannot change a tied operand into a FrameIndex"); - -  removeRegFromUses(); - -  OpKind = MO_FrameIndex; -  setIndex(Idx); -} - -/// ChangeToRegister - Replace this operand with a new register operand of -/// the specified value.  If an operand is known to be an register already, -/// the setReg method should be used. -void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp, -                                      bool isKill, bool isDead, bool isUndef, -                                      bool isDebug) { -  MachineRegisterInfo *RegInfo = nullptr; -  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. -  bool WasReg = isReg(); -  if (RegInfo && WasReg) -    RegInfo->removeRegOperandFromUseList(this); - -  // Change this to a register and set the reg#. -  OpKind = MO_Register; -  SmallContents.RegNo = Reg; -  SubReg_TargetFlags = 0; -  IsDef = isDef; -  IsImp = isImp; -  IsKill = isKill; -  IsDead = isDead; -  IsUndef = isUndef; -  IsInternalRead = false; -  IsEarlyClobber = false; -  IsDebug = isDebug; -  // Ensure isOnRegUseList() returns false. -  Contents.Reg.Prev = nullptr; -  // Preserve the tie when the operand was already a register. -  if (!WasReg) -    TiedTo = 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. 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()) -    return false; - -  switch (getType()) { -  case MachineOperand::MO_Register: -    return getReg() == Other.getReg() && isDef() == Other.isDef() && -           getSubReg() == Other.getSubReg(); -  case MachineOperand::MO_Immediate: -    return getImm() == Other.getImm(); -  case MachineOperand::MO_CImmediate: -    return getCImm() == Other.getCImm(); -  case MachineOperand::MO_FPImmediate: -    return getFPImm() == Other.getFPImm(); -  case MachineOperand::MO_MachineBasicBlock: -    return getMBB() == Other.getMBB(); -  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(); -  case MachineOperand::MO_GlobalAddress: -    return getGlobal() == Other.getGlobal() && getOffset() == Other.getOffset(); -  case MachineOperand::MO_ExternalSymbol: -    return strcmp(getSymbolName(), Other.getSymbolName()) == 0 && -           getOffset() == Other.getOffset(); -  case MachineOperand::MO_BlockAddress: -    return getBlockAddress() == Other.getBlockAddress() && -           getOffset() == Other.getOffset(); -  case MachineOperand::MO_RegisterMask: -  case MachineOperand::MO_RegisterLiveOut: { -    // Shallow compare of the two RegMasks -    const uint32_t *RegMask = getRegMask(); -    const uint32_t *OtherRegMask = Other.getRegMask(); -    if (RegMask == OtherRegMask) -      return true; - -    // Calculate the size of the RegMask -    const MachineFunction *MF = getParent()->getParent()->getParent(); -    const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); -    unsigned RegMaskSize = (TRI->getNumRegs() + 31) / 32; - -    // Deep compare of the two RegMasks -    return std::equal(RegMask, RegMask + RegMaskSize, OtherRegMask); -  } -  case MachineOperand::MO_MCSymbol: -    return getMCSymbol() == Other.getMCSymbol(); -  case MachineOperand::MO_CFIIndex: -    return getCFIIndex() == Other.getCFIIndex(); -  case MachineOperand::MO_Metadata: -    return getMetadata() == Other.getMetadata(); -  case MachineOperand::MO_IntrinsicID: -    return getIntrinsicID() == Other.getIntrinsicID(); -  case MachineOperand::MO_Predicate: -    return getPredicate() == Other.getPredicate(); -  } -  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: -    // Register operands don't have target flags. -    return hash_combine(MO.getType(), 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(), MO.getOffset()); -  case MachineOperand::MO_RegisterMask: -  case MachineOperand::MO_RegisterLiveOut: -    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()); -  case MachineOperand::MO_CFIIndex: -    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getCFIIndex()); -  case MachineOperand::MO_IntrinsicID: -    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getIntrinsicID()); -  case MachineOperand::MO_Predicate: -    return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getPredicate()); -  } -  llvm_unreachable("Invalid machine operand type"); -} - -void MachineOperand::print(raw_ostream &OS, const TargetRegisterInfo *TRI, -                           const TargetIntrinsicInfo *IntrinsicInfo) const { -  ModuleSlotTracker DummyMST(nullptr); -  print(OS, DummyMST, TRI, IntrinsicInfo); -} - -void MachineOperand::print(raw_ostream &OS, ModuleSlotTracker &MST, -                           const TargetRegisterInfo *TRI, -                           const TargetIntrinsicInfo *IntrinsicInfo) const { -  switch (getType()) { -  case MachineOperand::MO_Register: -    OS << PrintReg(getReg(), TRI, getSubReg()); - -    if (isDef() || isKill() || isDead() || isImplicit() || isUndef() || -        isInternalRead() || isEarlyClobber() || isTied()) { -      OS << '<'; -      bool NeedComma = false; -      if (isDef()) { -        if (NeedComma) OS << ','; -        if (isEarlyClobber()) -          OS << "earlyclobber,"; -        if (isImplicit()) -          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()) { -        if (NeedComma) OS << ','; -        OS << "kill"; -        NeedComma = true; -      } -      if (isDead()) { -        if (NeedComma) OS << ','; -        OS << "dead"; -        NeedComma = true; -      } -      if (isUndef() && isUse()) { -        if (NeedComma) OS << ','; -        OS << "undef"; -        NeedComma = true; -      } -      if (isInternalRead()) { -        if (NeedComma) OS << ','; -        OS << "internal"; -        NeedComma = true; -      } -      if (isTied()) { -        if (NeedComma) OS << ','; -        OS << "tied"; -        if (TiedTo != 15) -          OS << unsigned(TiedTo - 1); -      } -      OS << '>'; -    } -    break; -  case MachineOperand::MO_Immediate: -    OS << getImm(); -    break; -  case MachineOperand::MO_CImmediate: -    getCImm()->getValue().print(OS, false); -    break; -  case MachineOperand::MO_FPImmediate: -    if (getFPImm()->getType()->isFloatTy()) { -      OS << getFPImm()->getValueAPF().convertToFloat(); -    } else if (getFPImm()->getType()->isHalfTy()) { -      APFloat APF = getFPImm()->getValueAPF(); -      bool Unused; -      APF.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Unused); -      OS << "half " << APF.convertToFloat(); -    } else if (getFPImm()->getType()->isFP128Ty()) { -      APFloat APF = getFPImm()->getValueAPF(); -      SmallString<16> Str; -      getFPImm()->getValueAPF().toString(Str); -      OS << "quad " << Str; -    } else if (getFPImm()->getType()->isX86_FP80Ty()) { -      APFloat APF = getFPImm()->getValueAPF(); -      OS << "x86_fp80 0xK"; -      APInt API = APF.bitcastToAPInt(); -      OS << format_hex_no_prefix(API.getHiBits(16).getZExtValue(), 4, -                                 /*Upper=*/true); -      OS << format_hex_no_prefix(API.getLoBits(64).getZExtValue(), 16, -                                 /*Upper=*/true); -    } else { -      OS << getFPImm()->getValueAPF().convertToDouble(); -    } -    break; -  case MachineOperand::MO_MachineBasicBlock: -    OS << "<BB#" << getMBB()->getNumber() << ">"; -    break; -  case MachineOperand::MO_FrameIndex: -    OS << "<fi#" << getIndex() << '>'; -    break; -  case MachineOperand::MO_ConstantPoolIndex: -    OS << "<cp#" << getIndex(); -    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; -  case MachineOperand::MO_GlobalAddress: -    OS << "<ga:"; -    getGlobal()->printAsOperand(OS, /*PrintType=*/false, MST); -    if (getOffset()) OS << "+" << getOffset(); -    OS << '>'; -    break; -  case MachineOperand::MO_ExternalSymbol: -    OS << "<es:" << getSymbolName(); -    if (getOffset()) OS << "+" << getOffset(); -    OS << '>'; -    break; -  case MachineOperand::MO_BlockAddress: -    OS << '<'; -    getBlockAddress()->printAsOperand(OS, /*PrintType=*/false, MST); -    if (getOffset()) OS << "+" << getOffset(); -    OS << '>'; -    break; -  case MachineOperand::MO_RegisterMask: { -    unsigned NumRegsInMask = 0; -    unsigned NumRegsEmitted = 0; -    OS << "<regmask"; -    for (unsigned i = 0; i < TRI->getNumRegs(); ++i) { -      unsigned MaskWord = i / 32; -      unsigned MaskBit = i % 32; -      if (getRegMask()[MaskWord] & (1 << MaskBit)) { -        if (PrintWholeRegMask || NumRegsEmitted <= 10) { -          OS << " " << PrintReg(i, TRI); -          NumRegsEmitted++; -        } -        NumRegsInMask++; -      } -    } -    if (NumRegsEmitted != NumRegsInMask) -      OS << " and " << (NumRegsInMask - NumRegsEmitted) << " more..."; -    OS << ">"; -    break; -  } -  case MachineOperand::MO_RegisterLiveOut: -    OS << "<regliveout>"; -    break; -  case MachineOperand::MO_Metadata: -    OS << '<'; -    getMetadata()->printAsOperand(OS, MST); -    OS << '>'; -    break; -  case MachineOperand::MO_MCSymbol: -    OS << "<MCSym=" << *getMCSymbol() << '>'; -    break; -  case MachineOperand::MO_CFIIndex: -    OS << "<call frame instruction>"; -    break; -  case MachineOperand::MO_IntrinsicID: { -    Intrinsic::ID ID = getIntrinsicID(); -    if (ID < Intrinsic::num_intrinsics) -      OS << "<intrinsic:@" << Intrinsic::getName(ID, None) << '>'; -    else if (IntrinsicInfo) -      OS << "<intrinsic:@" << IntrinsicInfo->getName(ID) << '>'; -    else -      OS << "<intrinsic:" << ID << '>'; -    break; -  } -  case MachineOperand::MO_Predicate: { -    auto Pred = static_cast<CmpInst::Predicate>(getPredicate()); -    OS << '<' << (CmpInst::isIntPredicate(Pred) ? "intpred" : "floatpred") -       << CmpInst::getPredicateName(Pred) << '>'; -    break; -  } -  } -  if (unsigned TF = getTargetFlags()) -    OS << "[TF=" << TF << ']'; -} - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void MachineOperand::dump() const { -  dbgs() << *this << '\n'; -} -#endif - -//===----------------------------------------------------------------------===// -// MachineMemOperand Implementation -//===----------------------------------------------------------------------===// - -/// getAddrSpace - Return the LLVM IR address space number that this pointer -/// points into. -unsigned MachinePointerInfo::getAddrSpace() const { -  if (V.isNull() || V.is<const PseudoSourceValue*>()) return 0; -  return cast<PointerType>(V.get<const Value*>()->getType())->getAddressSpace(); -} - -/// isDereferenceable - Return true if V is always dereferenceable for  -/// Offset + Size byte. -bool MachinePointerInfo::isDereferenceable(unsigned Size, LLVMContext &C, -                                           const DataLayout &DL) const { -  if (!V.is<const Value*>()) -    return false; - -  const Value *BasePtr = V.get<const Value*>(); -  if (BasePtr == nullptr) -    return false; - -  return isDereferenceableAndAlignedPointer( -      BasePtr, 1, APInt(DL.getPointerSizeInBits(), Offset + Size), DL); -} - -/// getConstantPool - Return a MachinePointerInfo record that refers to the -/// constant pool. -MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) { -  return MachinePointerInfo(MF.getPSVManager().getConstantPool()); -} - -/// getFixedStack - Return a MachinePointerInfo record that refers to the -/// the specified FrameIndex. -MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF, -                                                     int FI, int64_t Offset) { -  return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset); -} - -MachinePointerInfo MachinePointerInfo::getJumpTable(MachineFunction &MF) { -  return MachinePointerInfo(MF.getPSVManager().getJumpTable()); -} - -MachinePointerInfo MachinePointerInfo::getGOT(MachineFunction &MF) { -  return MachinePointerInfo(MF.getPSVManager().getGOT()); -} - -MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF, -                                                int64_t Offset) { -  return MachinePointerInfo(MF.getPSVManager().getStack(), Offset); -} - -MachineMemOperand::MachineMemOperand(MachinePointerInfo ptrinfo, Flags f, -                                     uint64_t s, unsigned int a, -                                     const AAMDNodes &AAInfo, -                                     const MDNode *Ranges, -                                     SyncScope::ID SSID, -                                     AtomicOrdering Ordering, -                                     AtomicOrdering FailureOrdering) -    : PtrInfo(ptrinfo), Size(s), FlagVals(f), BaseAlignLog2(Log2_32(a) + 1), -      AAInfo(AAInfo), Ranges(Ranges) { -  assert((PtrInfo.V.isNull() || PtrInfo.V.is<const PseudoSourceValue*>() || -          isa<PointerType>(PtrInfo.V.get<const Value*>()->getType())) && -         "invalid pointer value"); -  assert(getBaseAlignment() == a && "Alignment is not a power of 2!"); -  assert((isLoad() || isStore()) && "Not a load/store!"); - -  AtomicInfo.SSID = static_cast<unsigned>(SSID); -  assert(getSyncScopeID() == SSID && "Value truncated"); -  AtomicInfo.Ordering = static_cast<unsigned>(Ordering); -  assert(getOrdering() == Ordering && "Value truncated"); -  AtomicInfo.FailureOrdering = static_cast<unsigned>(FailureOrdering); -  assert(getFailureOrdering() == FailureOrdering && "Value truncated"); -} - -/// Profile - Gather unique data for the object. -/// -void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { -  ID.AddInteger(getOffset()); -  ID.AddInteger(Size); -  ID.AddPointer(getOpaqueValue()); -  ID.AddInteger(getFlags()); -  ID.AddInteger(getBaseAlignment()); -} - -void MachineMemOperand::refineAlignment(const MachineMemOperand *MMO) { -  // The Value and Offset may differ due to CSE. But the flags and size -  // should be the same. -  assert(MMO->getFlags() == getFlags() && "Flags mismatch!"); -  assert(MMO->getSize() == getSize() && "Size mismatch!"); - -  if (MMO->getBaseAlignment() >= getBaseAlignment()) { -    // Update the alignment value. -    BaseAlignLog2 = Log2_32(MMO->getBaseAlignment()) + 1; -    // Also update the base and offset, because the new alignment may -    // not be applicable with the old ones. -    PtrInfo = MMO->PtrInfo; -  } -} - -/// getAlignment - Return the minimum known alignment in bytes of the -/// actual memory reference. -uint64_t MachineMemOperand::getAlignment() const { -  return MinAlign(getBaseAlignment(), getOffset()); -} - -void MachineMemOperand::print(raw_ostream &OS) const { -  ModuleSlotTracker DummyMST(nullptr); -  print(OS, DummyMST); -} -void MachineMemOperand::print(raw_ostream &OS, ModuleSlotTracker &MST) const { -  assert((isLoad() || isStore()) && -         "SV has to be a load, store or both."); - -  if (isVolatile()) -    OS << "Volatile "; - -  if (isLoad()) -    OS << "LD"; -  if (isStore()) -    OS << "ST"; -  OS << getSize(); - -  // Print the address information. -  OS << "["; -  if (const Value *V = getValue()) -    V->printAsOperand(OS, /*PrintType=*/false, MST); -  else if (const PseudoSourceValue *PSV = getPseudoValue()) -    PSV->printCustom(OS); -  else -    OS << "<unknown>"; - -  unsigned AS = getAddrSpace(); -  if (AS != 0) -    OS << "(addrspace=" << AS << ')'; - -  // If the alignment of the memory reference itself differs from the alignment -  // of the base pointer, print the base alignment explicitly, next to the base -  // pointer. -  if (getBaseAlignment() != getAlignment()) -    OS << "(align=" << getBaseAlignment() << ")"; - -  if (getOffset() != 0) -    OS << "+" << getOffset(); -  OS << "]"; - -  // Print the alignment of the reference. -  if (getBaseAlignment() != getAlignment() || getBaseAlignment() != getSize()) -    OS << "(align=" << getAlignment() << ")"; - -  // Print TBAA info. -  if (const MDNode *TBAAInfo = getAAInfo().TBAA) { -    OS << "(tbaa="; -    if (TBAAInfo->getNumOperands() > 0) -      TBAAInfo->getOperand(0)->printAsOperand(OS, MST); -    else -      OS << "<unknown>"; -    OS << ")"; -  } - -  // Print AA scope info. -  if (const MDNode *ScopeInfo = getAAInfo().Scope) { -    OS << "(alias.scope="; -    if (ScopeInfo->getNumOperands() > 0) -      for (unsigned i = 0, ie = ScopeInfo->getNumOperands(); i != ie; ++i) { -        ScopeInfo->getOperand(i)->printAsOperand(OS, MST); -        if (i != ie-1) -          OS << ","; -      } -    else -      OS << "<unknown>"; -    OS << ")"; -  } - -  // Print AA noalias scope info. -  if (const MDNode *NoAliasInfo = getAAInfo().NoAlias) { -    OS << "(noalias="; -    if (NoAliasInfo->getNumOperands() > 0) -      for (unsigned i = 0, ie = NoAliasInfo->getNumOperands(); i != ie; ++i) { -        NoAliasInfo->getOperand(i)->printAsOperand(OS, MST); -        if (i != ie-1) -          OS << ","; -      } -    else -      OS << "<unknown>"; -    OS << ")"; -  } - -  if (isNonTemporal()) -    OS << "(nontemporal)"; -  if (isDereferenceable()) -    OS << "(dereferenceable)"; -  if (isInvariant()) -    OS << "(invariant)"; -  if (getFlags() & MOTargetFlag1) -    OS << "(flag1)"; -  if (getFlags() & MOTargetFlag2) -    OS << "(flag2)"; -  if (getFlags() & MOTargetFlag3) -    OS << "(flag3)"; -} - -//===----------------------------------------------------------------------===// -// MachineInstr Implementation -//===----------------------------------------------------------------------===// -  void MachineInstr::addImplicitDefUseOperands(MachineFunction &MF) {    if (MCID->ImplicitDefs)      for (const MCPhysReg *ImpDefs = MCID->getImplicitDefs(); *ImpDefs; @@ -1034,7 +346,7 @@ MachineInstr::mergeMemRefsWith(const MachineInstr& Other) {    if (CombinedNumMemRefs != uint8_t(CombinedNumMemRefs))      return std::make_pair(nullptr, 0); -  MachineFunction *MF = getParent()->getParent(); +  MachineFunction *MF = getMF();    mmo_iterator MemBegin = MF->allocateMemRefsArray(CombinedNumMemRefs);    mmo_iterator MemEnd = std::copy(memoperands_begin(), memoperands_end(),                                    MemBegin); @@ -1108,9 +420,9 @@ bool MachineInstr::isIdenticalTo(const MachineInstr &Other,        if (Check == IgnoreDefs)          continue;        else if (Check == IgnoreVRegDefs) { -        if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) || -            TargetRegisterInfo::isPhysicalRegister(OMO.getReg())) -          if (MO.getReg() != OMO.getReg()) +        if (!TargetRegisterInfo::isVirtualRegister(MO.getReg()) || +            !TargetRegisterInfo::isVirtualRegister(OMO.getReg())) +          if (!MO.isIdenticalTo(OMO))              return false;        } else {          if (!MO.isIdenticalTo(OMO)) @@ -1133,6 +445,10 @@ bool MachineInstr::isIdenticalTo(const MachineInstr &Other,    return true;  } +const MachineFunction *MachineInstr::getMF() const { +  return getParent()->getParent(); +} +  MachineInstr *MachineInstr::removeFromParent() {    assert(getParent() && "Not embedded in a basic block!");    return getParent()->remove(this); @@ -1282,8 +598,8 @@ 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(); +  assert(getMF() && "Can't have an MF reference here!"); +  const MachineFunction &MF = *getMF();    // Most opcodes have fixed constraints in their MCInstrDesc.    if (!isInlineAsm()) @@ -1427,7 +743,7 @@ MachineInstr::readsWritesVirtualRegister(unsigned Reg,      if (MO.isUse())        Use |= !MO.isUndef();      else if (MO.getSubReg() && !MO.isUndef()) -      // A partial <def,undef> doesn't count as reading the register. +      // A partial def undef doesn't count as reading the register.        PartDef = true;      else        FullDef = true; @@ -1619,7 +935,7 @@ bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const {    // Treat volatile loads as stores. This is not strictly necessary for    // volatiles, but it is required for atomic loads. It is not allowed to move    // a load across an atomic load with Ordering > Monotonic. -  if (mayStore() || isCall() || +  if (mayStore() || isCall() || isPHI() ||        (mayLoad() && hasOrderedMemoryRef())) {      SawStore = true;      return false; @@ -1644,8 +960,9 @@ bool MachineInstr::isSafeToMove(AliasAnalysis *AA, bool &SawStore) const {  bool MachineInstr::mayAlias(AliasAnalysis *AA, MachineInstr &Other,                              bool UseTBAA) { -  const MachineFunction *MF = getParent()->getParent(); +  const MachineFunction *MF = getMF();    const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); +  const MachineFrameInfo &MFI = MF->getFrameInfo();    // If neither instruction stores to memory, they can't alias in any    // meaningful way, even if they read from the same address. @@ -1656,9 +973,6 @@ bool MachineInstr::mayAlias(AliasAnalysis *AA, MachineInstr &Other,    if (TII->areMemAccessesTriviallyDisjoint(*this, Other, AA))      return false; -  if (!AA) -    return true; -    // FIXME: Need to handle multiple memory operands to support all targets.    if (!hasOneMemOperand() || !Other.hasOneMemOperand())      return true; @@ -1666,9 +980,6 @@ bool MachineInstr::mayAlias(AliasAnalysis *AA, MachineInstr &Other,    MachineMemOperand *MMOa = *memoperands_begin();    MachineMemOperand *MMOb = *Other.memoperands_begin(); -  if (!MMOa->getValue() || !MMOb->getValue()) -    return true; -    // The following interface to AA is fashioned after DAGCombiner::isAlias    // and operates with MachineMemOperand offset with some important    // assumptions: @@ -1681,22 +992,53 @@ bool MachineInstr::mayAlias(AliasAnalysis *AA, MachineInstr &Other,    //   - There should never be any negative offsets here.    //    // FIXME: Modify API to hide this math from "user" -  // FIXME: Even before we go to AA we can reason locally about some +  // Even before we go to AA we can reason locally about some    // memory objects. It can save compile time, and possibly catch some    // corner cases not currently covered. -  assert((MMOa->getOffset() >= 0) && "Negative MachineMemOperand offset"); -  assert((MMOb->getOffset() >= 0) && "Negative MachineMemOperand offset"); +  int64_t OffsetA = MMOa->getOffset(); +  int64_t OffsetB = MMOb->getOffset(); + +  int64_t MinOffset = std::min(OffsetA, OffsetB); +  int64_t WidthA = MMOa->getSize(); +  int64_t WidthB = MMOb->getSize(); +  const Value *ValA = MMOa->getValue(); +  const Value *ValB = MMOb->getValue(); +  bool SameVal = (ValA && ValB && (ValA == ValB)); +  if (!SameVal) { +    const PseudoSourceValue *PSVa = MMOa->getPseudoValue(); +    const PseudoSourceValue *PSVb = MMOb->getPseudoValue(); +    if (PSVa && ValB && !PSVa->mayAlias(&MFI)) +      return false; +    if (PSVb && ValA && !PSVb->mayAlias(&MFI)) +      return false; +    if (PSVa && PSVb && (PSVa == PSVb)) +      SameVal = true; +  } -  int64_t MinOffset = std::min(MMOa->getOffset(), MMOb->getOffset()); -  int64_t Overlapa = MMOa->getSize() + MMOa->getOffset() - MinOffset; -  int64_t Overlapb = MMOb->getSize() + MMOb->getOffset() - MinOffset; +  if (SameVal) { +    int64_t MaxOffset = std::max(OffsetA, OffsetB); +    int64_t LowWidth = (MinOffset == OffsetA) ? WidthA : WidthB; +    return (MinOffset + LowWidth > MaxOffset); +  } + +  if (!AA) +    return true; + +  if (!ValA || !ValB) +    return true; -  AliasResult AAResult = -      AA->alias(MemoryLocation(MMOa->getValue(), Overlapa, -                               UseTBAA ? MMOa->getAAInfo() : AAMDNodes()), -                MemoryLocation(MMOb->getValue(), Overlapb, -                               UseTBAA ? MMOb->getAAInfo() : AAMDNodes())); +  assert((OffsetA >= 0) && "Negative MachineMemOperand offset"); +  assert((OffsetB >= 0) && "Negative MachineMemOperand offset"); + +  int64_t Overlapa = WidthA + OffsetA - MinOffset; +  int64_t Overlapb = WidthB + OffsetB - MinOffset; + +  AliasResult AAResult = AA->alias( +      MemoryLocation(ValA, Overlapa, +                     UseTBAA ? MMOa->getAAInfo() : AAMDNodes()), +      MemoryLocation(ValB, Overlapb, +                     UseTBAA ? MMOb->getAAInfo() : AAMDNodes()));    return (AAResult != NoAlias);  } @@ -1822,6 +1164,41 @@ void MachineInstr::copyImplicitOps(MachineFunction &MF,    }  } +bool MachineInstr::hasComplexRegisterTies() const { +  const MCInstrDesc &MCID = getDesc(); +  for (unsigned I = 0, E = getNumOperands(); I < E; ++I) { +    const auto &Operand = getOperand(I); +    if (!Operand.isReg() || Operand.isDef()) +      // Ignore the defined registers as MCID marks only the uses as tied. +      continue; +    int ExpectedTiedIdx = MCID.getOperandConstraint(I, MCOI::TIED_TO); +    int TiedIdx = Operand.isTied() ? int(findTiedOperandIdx(I)) : -1; +    if (ExpectedTiedIdx != TiedIdx) +      return true; +  } +  return false; +} + +LLT MachineInstr::getTypeToPrint(unsigned OpIdx, SmallBitVector &PrintedTypes, +                                 const MachineRegisterInfo &MRI) const { +  const MachineOperand &Op = getOperand(OpIdx); +  if (!Op.isReg()) +    return LLT{}; + +  if (isVariadic() || OpIdx >= getNumExplicitOperands()) +    return MRI.getType(Op.getReg()); + +  auto &OpInfo = getDesc().OpInfo[OpIdx]; +  if (!OpInfo.isGenericType()) +    return MRI.getType(Op.getReg()); + +  if (PrintedTypes[OpInfo.getGenericTypeIndex()]) +    return LLT{}; + +  PrintedTypes.set(OpInfo.getGenericTypeIndex()); +  return MRI.getType(Op.getReg()); +} +  #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)  LLVM_DUMP_METHOD void MachineInstr::dump() const {    dbgs() << "  "; @@ -1834,7 +1211,7 @@ void MachineInstr::print(raw_ostream &OS, bool SkipOpers, bool SkipDebugLoc,    const Module *M = nullptr;    if (const MachineBasicBlock *MBB = getParent())      if (const MachineFunction *MF = MBB->getParent()) -      M = MF->getFunction()->getParent(); +      M = MF->getFunction().getParent();    ModuleSlotTracker MST(M);    print(OS, MST, SkipOpers, SkipDebugLoc, TII); @@ -1863,21 +1240,31 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,    // Save a list of virtual registers.    SmallVector<unsigned, 8> VirtRegs; +  SmallBitVector PrintedTypes(8); +  bool ShouldPrintRegisterTies = hasComplexRegisterTies(); +  auto getTiedOperandIdx = [&](unsigned OpIdx) { +    if (!ShouldPrintRegisterTies) +      return 0U; +    const MachineOperand &MO = getOperand(OpIdx); +    if (MO.isReg() && MO.isTied() && !MO.isDef()) +      return findTiedOperandIdx(OpIdx); +    return 0U; +  };    // Print explicitly defined operands on the left of an assignment syntax.    unsigned StartOp = 0, e = getNumOperands();    for (; StartOp < e && getOperand(StartOp).isReg() && -         getOperand(StartOp).isDef() && -         !getOperand(StartOp).isImplicit(); +         getOperand(StartOp).isDef() && !getOperand(StartOp).isImplicit();         ++StartOp) { -    if (StartOp != 0) OS << ", "; -    getOperand(StartOp).print(OS, MST, TRI, IntrinsicInfo); +    if (StartOp != 0) +      OS << ", "; +    LLT TypeToPrint = MRI ? getTypeToPrint(StartOp, PrintedTypes, *MRI) : LLT{}; +    unsigned TiedOperandIdx = getTiedOperandIdx(StartOp); +    getOperand(StartOp).print(OS, MST, TypeToPrint, /*PrintDef=*/false, +                              ShouldPrintRegisterTies, TiedOperandIdx, TRI, +                              IntrinsicInfo);      unsigned Reg = getOperand(StartOp).getReg(); -    if (TargetRegisterInfo::isVirtualRegister(Reg)) { +    if (TargetRegisterInfo::isVirtualRegister(Reg))        VirtRegs.push_back(Reg); -      LLT Ty = MRI ? MRI->getType(Reg) : LLT{}; -      if (Ty.isValid()) -        OS << '(' << Ty << ')'; -    }    }    if (StartOp != 0) @@ -1900,7 +1287,12 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,    if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) {      // Print asm string.      OS << " "; -    getOperand(InlineAsm::MIOp_AsmString).print(OS, MST, TRI); +    const unsigned OpIdx = InlineAsm::MIOp_AsmString; +    LLT TypeToPrint = MRI ? getTypeToPrint(OpIdx, PrintedTypes, *MRI) : LLT{}; +    unsigned TiedOperandIdx = getTiedOperandIdx(OpIdx); +    getOperand(OpIdx).print(OS, MST, TypeToPrint, /*PrintDef=*/true, +                            ShouldPrintRegisterTies, TiedOperandIdx, TRI, +                            IntrinsicInfo);      // Print HasSideEffects, MayLoad, MayStore, IsAlignStack      unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); @@ -1943,8 +1335,12 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,        auto *DIV = dyn_cast<DILocalVariable>(MO.getMetadata());        if (DIV && !DIV->getName().empty())          OS << "!\"" << DIV->getName() << '\"'; -      else -        MO.print(OS, MST, TRI); +      else { +        LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{}; +        unsigned TiedOperandIdx = getTiedOperandIdx(i); +        MO.print(OS, MST, TypeToPrint, /*PrintDef=*/true, +                 ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo); +      }      } else if (TRI && (isInsertSubreg() || isRegSequence() ||                         (isSubregToReg() && i == 3)) && MO.isImm()) {        OS << TRI->getSubRegIndexName(MO.getImm()); @@ -2006,8 +1402,15 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,        // Compute the index of the next operand descriptor.        AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); -    } else -      MO.print(OS, MST, TRI); +    } else { +      LLT TypeToPrint = MRI ? getTypeToPrint(i, PrintedTypes, *MRI) : LLT{}; +      unsigned TiedOperandIdx = getTiedOperandIdx(i); +      if (MO.isImm() && isOperandSubregIdx(i)) +        MachineOperand::printSubregIdx(OS, MO.getImm(), TRI); +      else +        MO.print(OS, MST, TypeToPrint, /*PrintDef=*/true, +                 ShouldPrintRegisterTies, TiedOperandIdx, TRI, IntrinsicInfo); +    }    }    bool HaveSemi = false; @@ -2057,14 +1460,14 @@ void MachineInstr::print(raw_ostream &OS, ModuleSlotTracker &MST,        else          OS << " "             << TRI->getRegClassName(RC.get<const TargetRegisterClass *>()); -      OS << ':' << PrintReg(VirtRegs[i]); +      OS << ':' << printReg(VirtRegs[i]);        for (unsigned j = i+1; j != VirtRegs.size();) {          if (MRI->getRegClassOrRegBank(VirtRegs[j]) != RC) {            ++j;            continue;          }          if (VirtRegs[i] != VirtRegs[j]) -          OS << "," << PrintReg(VirtRegs[j]); +          OS << "," << printReg(VirtRegs[j]);          VirtRegs.erase(VirtRegs.begin()+j);        }      } @@ -2328,8 +1731,8 @@ void MachineInstr::emitError(StringRef Msg) const {  MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,                                    const MCInstrDesc &MCID, bool IsIndirect, -                                  unsigned Reg, unsigned Offset, -                                  const MDNode *Variable, const MDNode *Expr) { +                                  unsigned Reg, const MDNode *Variable, +                                  const MDNode *Expr) {    assert(isa<DILocalVariable>(Variable) && "not a variable");    assert(cast<DIExpression>(Expr)->isValid() && "not an expression");    assert(cast<DILocalVariable>(Variable)->isValidLocationForIntrinsic(DL) && @@ -2337,53 +1740,60 @@ MachineInstrBuilder llvm::BuildMI(MachineFunction &MF, const DebugLoc &DL,    if (IsIndirect)      return BuildMI(MF, DL, MCID)          .addReg(Reg, RegState::Debug) -        .addImm(Offset) +        .addImm(0U)          .addMetadata(Variable)          .addMetadata(Expr); -  else { -    assert(Offset == 0 && "A direct address cannot have an offset."); +  else      return BuildMI(MF, DL, MCID)          .addReg(Reg, RegState::Debug)          .addReg(0U, RegState::Debug)          .addMetadata(Variable)          .addMetadata(Expr); -  }  }  MachineInstrBuilder llvm::BuildMI(MachineBasicBlock &BB,                                    MachineBasicBlock::iterator I,                                    const DebugLoc &DL, const MCInstrDesc &MCID,                                    bool IsIndirect, unsigned Reg, -                                  unsigned Offset, const MDNode *Variable, -                                  const MDNode *Expr) { +                                  const MDNode *Variable, const MDNode *Expr) {    assert(isa<DILocalVariable>(Variable) && "not a variable");    assert(cast<DIExpression>(Expr)->isValid() && "not an expression");    MachineFunction &MF = *BB.getParent(); -  MachineInstr *MI = -      BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr); +  MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Variable, Expr);    BB.insert(I, MI);    return MachineInstrBuilder(MF, MI);  } +/// Compute the new DIExpression to use with a DBG_VALUE for a spill slot. +/// This prepends DW_OP_deref when spilling an indirect DBG_VALUE. +static const DIExpression *computeExprForSpill(const MachineInstr &MI) { +  assert(MI.getOperand(0).isReg() && "can't spill non-register"); +  assert(MI.getDebugVariable()->isValidLocationForIntrinsic(MI.getDebugLoc()) && +         "Expected inlined-at fields to agree"); + +  const DIExpression *Expr = MI.getDebugExpression(); +  if (MI.isIndirectDebugValue()) { +    assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset"); +    Expr = DIExpression::prepend(Expr, DIExpression::WithDeref); +  } +  return Expr; +} +  MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB,                                            MachineBasicBlock::iterator I,                                            const MachineInstr &Orig,                                            int FrameIndex) { -  const MDNode *Var = Orig.getDebugVariable(); -  const auto *Expr = cast_or_null<DIExpression>(Orig.getDebugExpression()); -  bool IsIndirect = Orig.isIndirectDebugValue(); -  uint64_t Offset = IsIndirect ? Orig.getOperand(1).getImm() : 0; -  DebugLoc DL = Orig.getDebugLoc(); -  assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) && -         "Expected inlined-at fields to agree"); -  // If the DBG_VALUE already was a memory location, add an extra -  // DW_OP_deref. Otherwise just turning this from a register into a -  // memory/indirect location is sufficient. -  if (IsIndirect) -    Expr = DIExpression::prepend(Expr, DIExpression::WithDeref); -  return BuildMI(BB, I, DL, Orig.getDesc()) +  const DIExpression *Expr = computeExprForSpill(Orig); +  return BuildMI(BB, I, Orig.getDebugLoc(), Orig.getDesc())        .addFrameIndex(FrameIndex) -      .addImm(Offset) -      .addMetadata(Var) +      .addImm(0U) +      .addMetadata(Orig.getDebugVariable())        .addMetadata(Expr);  } + +void llvm::updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex) { +  const DIExpression *Expr = computeExprForSpill(Orig); +  Orig.getOperand(0).ChangeToFrameIndex(FrameIndex); +  Orig.getOperand(1).ChangeToImmediate(0U); +  Orig.getOperand(3).setMetadata(Expr); +}  | 
