diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2011-10-20 21:10:27 +0000 | 
| commit | 30815c536baacc07e925f0aef23a5395883173dc (patch) | |
| tree | 2cbcf22585e99f8a87d12d5ff94f392c0d266819 /lib/CodeGen/MachineInstr.cpp | |
| parent | 411bd29eea3c360d5b48a18a17b5e87f5671af0e (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/MachineInstr.cpp')
| -rw-r--r-- | lib/CodeGen/MachineInstr.cpp | 366 | 
1 files changed, 200 insertions, 166 deletions
| diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index 143a29b08a1e..a240667f7d6a 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -51,7 +51,7 @@ using namespace llvm;  /// 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) { @@ -59,23 +59,23 @@ void MachineOperand::AddRegOperandToRegInfo(MachineRegisterInfo *RegInfo) {      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;  } @@ -86,7 +86,7 @@ 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;  +  *Contents.Reg.Prev = NextOp;    if (NextOp) {      assert(NextOp->getReg() == getReg() && "Corrupt reg use/def chain!");      NextOp->Contents.Reg.Prev = Contents.Reg.Prev; @@ -97,7 +97,7 @@ void MachineOperand::RemoveRegOperandFromRegInfo() {  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. @@ -109,7 +109,7 @@ void MachineOperand::setReg(unsigned Reg) {          AddRegOperandToRegInfo(&MF->getRegInfo());          return;        } -         +    // Otherwise, just change the register, no problem.  :)    SmallContents.RegNo = Reg;  } @@ -144,7 +144,7 @@ void MachineOperand::ChangeToImmediate(int64_t ImmVal) {    if (isReg() && getParent() && getParent()->getParent() &&        getParent()->getParent()->getParent())      RemoveRegOperandFromRegInfo(); -   +    OpKind = MO_Immediate;    Contents.ImmVal = ImmVal;  } @@ -155,7 +155,7 @@ 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  +  // If this operand is already a register operand, use setReg to update the    // register's use/def lists.    if (isReg()) {      assert(!isEarlyClobber()); @@ -189,7 +189,7 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {    if (getType() != Other.getType() ||        getTargetFlags() != Other.getTargetFlags())      return false; -   +    switch (getType()) {    default: llvm_unreachable("Unrecognized operand type");    case MachineOperand::MO_Register: @@ -322,7 +322,7 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {    default:      llvm_unreachable("Unrecognized operand type");    } -   +    if (unsigned TF = getTargetFlags())      OS << "[TF=" << TF << ']';  } @@ -408,7 +408,7 @@ uint64_t MachineMemOperand::getAlignment() const {  raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {    assert((MMO.isLoad() || MMO.isStore()) &&           "SV has to be a load, store or both."); -   +    if (MMO.isVolatile())      OS << "Volatile "; @@ -417,7 +417,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {    if (MMO.isStore())      OS << "ST";    OS << MMO.getSize(); -   +    // Print the address information.    OS << "[";    if (!MMO.getValue()) @@ -464,7 +464,7 @@ raw_ostream &llvm::operator<<(raw_ostream &OS, const MachineMemOperand &MMO) {  /// MachineInstr ctor - This constructor creates a dummy MachineInstr with  /// MCID NULL and no operands.  MachineInstr::MachineInstr() -  : MCID(0), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), +  : MCID(0), Flags(0), AsmPrinterFlags(0),      MemRefs(0), MemRefsEnd(0),      Parent(0) {    // Make sure that we get added to a machine basicblock @@ -484,8 +484,9 @@ void MachineInstr::addImplicitDefUseOperands() {  /// implicit operands. It reserves space for the number of operands specified by  /// the MCInstrDesc.  MachineInstr::MachineInstr(const MCInstrDesc &tid, bool NoImp) -  : MCID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), +  : MCID(&tid), Flags(0), AsmPrinterFlags(0),      MemRefs(0), MemRefsEnd(0), Parent(0) { +  unsigned NumImplicitOps = 0;    if (!NoImp)      NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses();    Operands.reserve(NumImplicitOps + MCID->getNumOperands()); @@ -498,8 +499,9 @@ MachineInstr::MachineInstr(const MCInstrDesc &tid, bool NoImp)  /// MachineInstr ctor - As above, but with a DebugLoc.  MachineInstr::MachineInstr(const MCInstrDesc &tid, const DebugLoc dl,                             bool NoImp) -  : MCID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), +  : MCID(&tid), Flags(0), AsmPrinterFlags(0),      MemRefs(0), MemRefsEnd(0), Parent(0), debugLoc(dl) { +  unsigned NumImplicitOps = 0;    if (!NoImp)      NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses();    Operands.reserve(NumImplicitOps + MCID->getNumOperands()); @@ -510,13 +512,14 @@ MachineInstr::MachineInstr(const MCInstrDesc &tid, const DebugLoc dl,  }  /// MachineInstr ctor - Work exactly the same as the ctor two above, except -/// that the MachineInstr is created and added to the end of the specified  +/// that the MachineInstr is created and added to the end of the specified  /// basic block.  MachineInstr::MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &tid) -  : MCID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), +  : MCID(&tid), Flags(0), AsmPrinterFlags(0),      MemRefs(0), MemRefsEnd(0), Parent(0) {    assert(MBB && "Cannot use inserting ctor with null basic block!"); -  NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses(); +  unsigned NumImplicitOps = +    MCID->getNumImplicitDefs() + MCID->getNumImplicitUses();    Operands.reserve(NumImplicitOps + MCID->getNumOperands());    addImplicitDefUseOperands();    // Make sure that we get added to a machine basicblock @@ -528,10 +531,11 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &tid)  ///  MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,                             const MCInstrDesc &tid) -  : MCID(&tid), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), +  : MCID(&tid), Flags(0), AsmPrinterFlags(0),      MemRefs(0), MemRefsEnd(0), Parent(0), debugLoc(dl) {    assert(MBB && "Cannot use inserting ctor with null basic block!"); -  NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses(); +  unsigned NumImplicitOps = +    MCID->getNumImplicitDefs() + MCID->getNumImplicitUses();    Operands.reserve(NumImplicitOps + MCID->getNumOperands());    addImplicitDefUseOperands();    // Make sure that we get added to a machine basicblock @@ -542,7 +546,7 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,  /// MachineInstr ctor - Copies MachineInstr arg exactly  ///  MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) -  : MCID(&MI.getDesc()), NumImplicitOps(0), Flags(0), AsmPrinterFlags(0), +  : MCID(&MI.getDesc()), Flags(0), AsmPrinterFlags(0),      MemRefs(MI.MemRefs), MemRefsEnd(MI.MemRefsEnd),      Parent(0), debugLoc(MI.getDebugLoc()) {    Operands.reserve(MI.getNumOperands()); @@ -550,7 +554,6 @@ MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)    // Add operands    for (unsigned i = 0; i != MI.getNumOperands(); ++i)      addOperand(MI.getOperand(i)); -  NumImplicitOps = MI.NumImplicitOps;    // Copy all the flags.    Flags = MI.Flags; @@ -605,102 +608,74 @@ void MachineInstr::AddRegOperandsToUseLists(MachineRegisterInfo &RegInfo) {  /// 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 -/// (before the first implicit operand).  +/// (before the first implicit operand).  void MachineInstr::addOperand(const MachineOperand &Op) { +  assert(MCID && "Cannot add operands before providing an instr descriptor");    bool isImpReg = Op.isReg() && Op.isImplicit(); -  assert((isImpReg || !OperandsComplete()) && -         "Trying to add an operand to a machine instr that is already done!"); -    MachineRegisterInfo *RegInfo = getRegInfo(); -  // If we are adding the operand to the end of the list, our job is simpler. -  // This is true most of the time, so this is a reasonable optimization. -  if (isImpReg || NumImplicitOps == 0) { -    // We can only do this optimization if we know that the operand list won't -    // reallocate. -    if (Operands.empty() || Operands.size()+1 <= Operands.capacity()) { -      Operands.push_back(Op); -     -      // Set the parent of the operand. -      Operands.back().ParentMI = this; -   -      // If the operand is a register, update the operand's use list. -      if (Op.isReg()) { -        Operands.back().AddRegOperandToRegInfo(RegInfo); -        // If the register operand is flagged as early, mark the operand as such -        unsigned OpNo = Operands.size() - 1; -        if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) -          Operands[OpNo].setIsEarlyClobber(true); -      } -      return; +  // If the Operands backing store is reallocated, all register operands must +  // be removed and re-added to RegInfo.  It is storing pointers to operands. +  bool Reallocate = RegInfo && +    !Operands.empty() && Operands.size() == Operands.capacity(); + +  // Find the insert location for the new operand.  Implicit registers go at +  // the end, everything goes before the implicit regs. +  unsigned OpNo = Operands.size(); + +  // Remove all the implicit operands from RegInfo if they need to be shifted. +  // FIXME: Allow mixed explicit and implicit operands on inline asm. +  // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as +  // implicit-defs, but they must not be moved around.  See the FIXME in +  // InstrEmitter.cpp. +  if (!isImpReg && !isInlineAsm()) { +    while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) { +      --OpNo; +      if (RegInfo) +        Operands[OpNo].RemoveRegOperandFromRegInfo();      }    } -   -  // Otherwise, we have to insert a real operand before any implicit ones. -  unsigned OpNo = Operands.size()-NumImplicitOps; -  // If this instruction isn't embedded into a function, then we don't need to -  // update any operand lists. -  if (RegInfo == 0) { -    // Simple insertion, no reginfo update needed for other register operands. -    Operands.insert(Operands.begin()+OpNo, Op); -    Operands[OpNo].ParentMI = this; - -    // Do explicitly set the reginfo for this operand though, to ensure the -    // next/prev fields are properly nulled out. -    if (Operands[OpNo].isReg()) { -      Operands[OpNo].AddRegOperandToRegInfo(0); -      // 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); -    } +  // 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()) && +         "Trying to add an operand to a machine instr that is already done!"); -  } else if (Operands.size()+1 <= Operands.capacity()) { -    // Otherwise, we have to remove register operands from their register use -    // list, add the operand, then add the register operands back to their use -    // list.  This also must handle the case when the operand list reallocates -    // to somewhere else. -   -    // If insertion of this operand won't cause reallocation of the operand -    // list, just remove the implicit operands, add the operand, then re-add all -    // the rest of the operands. -    for (unsigned i = OpNo, e = Operands.size(); i != e; ++i) { -      assert(Operands[i].isReg() && "Should only be an implicit reg!"); -      Operands[i].RemoveRegOperandFromRegInfo(); -    } -     -    // Add the operand.  If it is a register, add it to the reg list. -    Operands.insert(Operands.begin()+OpNo, Op); -    Operands[OpNo].ParentMI = this; - -    if (Operands[OpNo].isReg()) { -      Operands[OpNo].AddRegOperandToRegInfo(RegInfo); -      // 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); -    } -     -    // Re-add all the implicit ops. -    for (unsigned i = OpNo+1, e = Operands.size(); i != e; ++i) { +  // All operands from OpNo have been removed from RegInfo.  If the Operands +  // backing store needs to be reallocated, we also need to remove any other +  // register operands. +  if (Reallocate) +    for (unsigned i = 0; i != OpNo; ++i) +      if (Operands[i].isReg()) +        Operands[i].RemoveRegOperandFromRegInfo(); + +  // Insert the new operand at OpNo. +  Operands.insert(Operands.begin() + OpNo, Op); +  Operands[OpNo].ParentMI = this; + +  // The Operands backing store has now been reallocated, so we can re-add the +  // operands before OpNo. +  if (Reallocate) +    for (unsigned i = 0; i != OpNo; ++i) +      if (Operands[i].isReg()) +        Operands[i].AddRegOperandToRegInfo(RegInfo); + +  // 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); +    // 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); +  } + +  // Re-add all the implicit ops. +  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);      } -  } else { -    // Otherwise, we will be reallocating the operand list.  Remove all reg -    // operands from their list, then readd them after the operand list is -    // reallocated. -    RemoveRegOperandsFromUseLists(); -     -    Operands.insert(Operands.begin()+OpNo, Op); -    Operands[OpNo].ParentMI = this; -   -    // Re-add all the operands. -    AddRegOperandsToUseLists(*RegInfo); - -      // If the register operand is flagged as early, mark the operand as such -    if (Operands[OpNo].isReg() -        && MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1) -      Operands[OpNo].setIsEarlyClobber(true);    }  } @@ -709,13 +684,13 @@ void MachineInstr::addOperand(const MachineOperand &Op) {  ///  void MachineInstr::RemoveOperand(unsigned OpNo) {    assert(OpNo < Operands.size() && "Invalid operand number"); -   +    // 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(); -     +      Operands.pop_back();      return;    } @@ -730,7 +705,7 @@ void MachineInstr::RemoveOperand(unsigned OpNo) {          Operands[i].RemoveRegOperandFromRegInfo();      }    } -   +    Operands.erase(Operands.begin()+OpNo);    if (RegInfo) { @@ -827,15 +802,6 @@ void MachineInstr::eraseFromParent() {  } -/// OperandComplete - Return true if it's illegal to add a new operand -/// -bool MachineInstr::OperandsComplete() const { -  unsigned short NumOperands = MCID->getNumOperands(); -  if (!MCID->isVariadic() && getNumOperands()-NumImplicitOps >= NumOperands) -    return true;  // Broken: we have all the operands of this instruction! -  return false; -} -  /// getNumExplicitOperands - Returns the number of non-implicit operands.  ///  unsigned MachineInstr::getNumExplicitOperands() const { @@ -860,6 +826,67 @@ bool MachineInstr::isStackAligningInlineAsm() const {    return false;  } +int MachineInstr::findInlineAsmFlagIdx(unsigned OpIdx, +                                       unsigned *GroupNo) const { +  assert(isInlineAsm() && "Expected an inline asm instruction"); +  assert(OpIdx < getNumOperands() && "OpIdx out of range"); + +  // Ignore queries about the initial operands. +  if (OpIdx < InlineAsm::MIOp_FirstOperand) +    return -1; + +  unsigned Group = 0; +  unsigned NumOps; +  for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); i < e; +       i += NumOps) { +    const MachineOperand &FlagMO = getOperand(i); +    // If we reach the implicit register operands, stop looking. +    if (!FlagMO.isImm()) +      return -1; +    NumOps = 1 + InlineAsm::getNumOperandRegisters(FlagMO.getImm()); +    if (i + NumOps > OpIdx) { +      if (GroupNo) +        *GroupNo = Group; +      return i; +    } +    ++Group; +  } +  return -1; +} + +const TargetRegisterClass* +MachineInstr::getRegClassConstraint(unsigned OpIdx, +                                    const TargetInstrInfo *TII, +                                    const TargetRegisterInfo *TRI) const { +  // Most opcodes have fixed constraints in their MCInstrDesc. +  if (!isInlineAsm()) +    return TII->getRegClass(getDesc(), OpIdx, TRI); + +  if (!getOperand(OpIdx).isReg()) +    return NULL; + +  // For tied uses on inline asm, get the constraint from the def. +  unsigned DefIdx; +  if (getOperand(OpIdx).isUse() && isRegTiedToDefOperand(OpIdx, &DefIdx)) +    OpIdx = DefIdx; + +  // Inline asm stores register class constraints in the flag word. +  int FlagIdx = findInlineAsmFlagIdx(OpIdx); +  if (FlagIdx < 0) +    return NULL; + +  unsigned Flag = getOperand(FlagIdx).getImm(); +  unsigned RCID; +  if (InlineAsm::hasRegClassConstraint(Flag, RCID)) +    return TRI->getRegClass(RCID); + +  // Assume that all registers in a memory operand are pointers. +  if (InlineAsm::getKind(Flag) == InlineAsm::Kind_Mem) +    return TRI->getPointerRegClass(); + +  return NULL; +} +  /// findRegisterUseOperandIdx() - Returns the MachineOperand that is a use of  /// the specific register or -1 if it is not found. It further tightens  /// the search criteria to a use that kills the register if isKill is true. @@ -901,7 +928,8 @@ MachineInstr::readsWritesVirtualRegister(unsigned Reg,        Ops->push_back(i);      if (MO.isUse())        Use |= !MO.isUndef(); -    else if (MO.getSubReg()) +    else if (MO.getSubReg() && !MO.isUndef()) +      // A partial <def,undef> doesn't count as reading the register.        PartDef = true;      else        FullDef = true; @@ -941,6 +969,10 @@ MachineInstr::findRegisterDefOperandIdx(unsigned Reg, bool isDead, bool Overlap,  /// operand list that is used to represent the predicate. It returns -1 if  /// none is found.  int MachineInstr::findFirstPredOperandIdx() const { +  // Don't call MCID.findFirstPredOperandIdx() because this variant +  // is sometimes called on an instruction that's not yet complete, and +  // so the number of operands is less than the MCID indicates. In +  // particular, the PTX target does this.    const MCInstrDesc &MCID = getDesc();    if (MCID.isPredicable()) {      for (unsigned i = 0, e = getNumOperands(); i != e; ++i) @@ -950,7 +982,7 @@ int MachineInstr::findFirstPredOperandIdx() const {    return -1;  } -   +  /// isRegTiedToUseOperand - Given the index of a register def operand,  /// check if the register def is tied to a source operand, due to either  /// two-address elimination or inline assembly constraints. Returns the @@ -964,23 +996,13 @@ isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const {        return false;      // Determine the actual operand index that corresponds to this index.      unsigned DefNo = 0; -    unsigned DefPart = 0; -    for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands(); -         i < e; ) { -      const MachineOperand &FMO = getOperand(i); -      // After the normal asm operands there may be additional imp-def regs. -      if (!FMO.isImm()) -        return false; -      // Skip over this def. -      unsigned NumOps = InlineAsm::getNumOperandRegisters(FMO.getImm()); -      unsigned PrevDef = i + 1; -      i = PrevDef + NumOps; -      if (i > DefOpIdx) { -        DefPart = DefOpIdx - PrevDef; -        break; -      } -      ++DefNo; -    } +    int FlagIdx = findInlineAsmFlagIdx(DefOpIdx, &DefNo); +    if (FlagIdx < 0) +      return false; + +    // Which part of the group is DefOpIdx? +    unsigned DefPart = DefOpIdx - (FlagIdx + 1); +      for (unsigned i = InlineAsm::MIOp_FirstOperand, e = getNumOperands();           i != e; ++i) {        const MachineOperand &FMO = getOperand(i); @@ -1024,20 +1046,10 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {        return false;      // Find the flag operand corresponding to UseOpIdx -    unsigned FlagIdx, NumOps=0; -    for (FlagIdx = InlineAsm::MIOp_FirstOperand; -         FlagIdx < UseOpIdx; FlagIdx += NumOps+1) { -      const MachineOperand &UFMO = getOperand(FlagIdx); -      // After the normal asm operands there may be additional imp-def regs. -      if (!UFMO.isImm()) -        return false; -      NumOps = InlineAsm::getNumOperandRegisters(UFMO.getImm()); -      assert(NumOps < getNumOperands() && "Invalid inline asm flag"); -      if (UseOpIdx < FlagIdx+NumOps+1) -        break; -    } -    if (FlagIdx >= UseOpIdx) +    int FlagIdx = findInlineAsmFlagIdx(UseOpIdx); +    if (FlagIdx < 0)        return false; +      const MachineOperand &UFMO = getOperand(FlagIdx);      unsigned DefNo;      if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) { @@ -1211,7 +1223,7 @@ bool MachineInstr::hasVolatileMemoryRef() const {    // conservatively assume it wasn't preserved.    if (memoperands_empty())      return true; -   +    // Check the memory reference information for volatile references.    for (mmo_iterator I = memoperands_begin(), E = memoperands_end(); I != E; ++I)      if ((*I)->isVolatile()) @@ -1318,7 +1330,7 @@ void MachineInstr::dump() const {    dbgs() << "  " << *this;  } -static void printDebugLoc(DebugLoc DL, const MachineFunction *MF,  +static void printDebugLoc(DebugLoc DL, const MachineFunction *MF,                           raw_ostream &CommentOS) {    const LLVMContext &Ctx = MF->getFunction()->getContext();    if (!DL.isUnknown()) {          // Print source line info. @@ -1380,7 +1392,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {    unsigned AsmDescOp = ~0u;    unsigned AsmOpCount = 0; -  if (isInlineAsm()) { +  if (isInlineAsm() && e >= InlineAsm::MIOp_FirstOperand) {      // Print asm string.      OS << " ";      getOperand(InlineAsm::MIOp_AsmString).print(OS, TM); @@ -1451,18 +1463,28 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {        OS << '$' << AsmOpCount++;        unsigned Flag = MO.getImm();        switch (InlineAsm::getKind(Flag)) { -      case InlineAsm::Kind_RegUse:             OS << ":[reguse]"; break; -      case InlineAsm::Kind_RegDef:             OS << ":[regdef]"; break; -      case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec]"; break; -      case InlineAsm::Kind_Clobber:            OS << ":[clobber]"; break; -      case InlineAsm::Kind_Imm:                OS << ":[imm]"; break; -      case InlineAsm::Kind_Mem:                OS << ":[mem]"; break; -      default: OS << ":[??" << InlineAsm::getKind(Flag) << ']'; break; +      case InlineAsm::Kind_RegUse:             OS << ":[reguse"; break; +      case InlineAsm::Kind_RegDef:             OS << ":[regdef"; break; +      case InlineAsm::Kind_RegDefEarlyClobber: OS << ":[regdef-ec"; break; +      case InlineAsm::Kind_Clobber:            OS << ":[clobber"; break; +      case InlineAsm::Kind_Imm:                OS << ":[imm"; break; +      case InlineAsm::Kind_Mem:                OS << ":[mem"; break; +      default: OS << ":[??" << InlineAsm::getKind(Flag); break; +      } + +      unsigned RCID = 0; +      if (InlineAsm::hasRegClassConstraint(Flag, RCID)) { +        if (TM) +          OS << ':' << TM->getRegisterInfo()->getRegClass(RCID)->getName(); +        else +          OS << ":RC" << RCID;        }        unsigned TiedTo = 0;        if (InlineAsm::isUseOperandTiedToDef(Flag, TiedTo)) -        OS << " [tiedto:$" << TiedTo << ']'; +        OS << " tiedto:$" << TiedTo; + +      OS << ']';        // Compute the index of the next operand descriptor.        AsmDescOp += 1 + InlineAsm::getNumOperandRegisters(Flag); @@ -1516,7 +1538,19 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const {    }    // Print debug location information. -  if (!debugLoc.isUnknown() && MF) { +  if (isDebugValue() && getOperand(e - 1).isMetadata()) { +    if (!HaveSemi) OS << ";"; HaveSemi = true; +    DIVariable DV(getOperand(e - 1).getMetadata()); +    OS << " line no:" <<  DV.getLineNumber(); +    if (MDNode *InlinedAt = DV.getInlinedAt()) { +      DebugLoc InlinedAtDL = DebugLoc::getFromDILocation(InlinedAt); +      if (!InlinedAtDL.isUnknown()) { +        OS << " inlined @[ "; +        printDebugLoc(InlinedAtDL, MF, OS); +        OS << " ]"; +      } +    } +  } else if (!debugLoc.isUnknown() && MF) {      if (!HaveSemi) OS << ";"; HaveSemi = true;      OS << " dbg:";      printDebugLoc(debugLoc, MF, OS); @@ -1627,7 +1661,7 @@ bool MachineInstr::addRegisterDead(unsigned IncomingReg,    // new implicit operand if required.    if (Found || !AddIfNotFound)      return Found; -     +    addOperand(MachineOperand::CreateReg(IncomingReg,                                         true  /*IsDef*/,                                         true  /*IsImp*/, | 
