diff options
Diffstat (limited to 'llvm/lib')
28 files changed, 442 insertions, 321 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 4eb289afc18..faba9f17c5f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -614,8 +614,8 @@ static void emitKill(const MachineInstr *MI, AsmPrinter &AP) {  /// of DBG_VALUE, returning true if it was able to do so.  A false return  /// means the target will need to handle MI in EmitInstruction.  static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { -  // This code handles only the 3-operand target-independent form. -  if (MI->getNumOperands() != 3) +  // This code handles only the 4-operand target-independent form. +  if (MI->getNumOperands() != 4)      return false;    SmallString<128> Str; @@ -629,9 +629,11 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {        OS << Name << ":";    }    OS << V.getName(); -  if (V.isVariablePiece()) -    OS << " [piece offset=" << V.getPieceOffset() -       << " size="<<V.getPieceSize()<<"]"; + +  DIExpression Expr = MI->getDebugExpression(); +  if (Expr.isVariablePiece()) +    OS << " [piece offset=" << Expr.getPieceOffset() +       << " size=" << Expr.getPieceSize() << "]";    OS << " <- ";    // The second operand is only an offset if it's an immediate. diff --git a/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp b/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp index 998c396924b..a258d621a6a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp @@ -27,7 +27,7 @@ namespace llvm {  // In the other case, returns 0.  static unsigned isDescribedByReg(const MachineInstr &MI) {    assert(MI.isDebugValue()); -  assert(MI.getNumOperands() == 3); +  assert(MI.getNumOperands() == 4);    // If location of variable is described using a register (directly or    // indirecltly), this register is always a first operand.    return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0; @@ -37,7 +37,7 @@ void DbgValueHistoryMap::startInstrRange(const MDNode *Var,                                           const MachineInstr &MI) {    // Instruction range should start with a DBG_VALUE instruction for the    // variable. -  assert(MI.isDebugValue() && getEntireVariable(MI.getDebugVariable()) == Var); +  assert(MI.isDebugValue() && "not a DBG_VALUE");    auto &Ranges = VarInstrRanges[Var];    if (!Ranges.empty() && Ranges.back().second == nullptr &&        Ranges.back().first->isIdenticalTo(&MI)) { @@ -193,7 +193,7 @@ void calculateDbgValueHistory(const MachineFunction *MF,        // Use the base variable (without any DW_OP_piece expressions)        // as index into History. The full variables including the        // piece expressions are attached to the MI. -      DIVariable Var = getEntireVariable(MI.getDebugVariable()); +      DIVariable Var = MI.getDebugVariable();        if (unsigned PrevReg = Result.getRegisterForVar(Var))          dropRegDescribedVar(RegVars, PrevReg, Var); diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h index 6af049ad683..6cca985cfce 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -26,25 +26,30 @@ class DebugLocEntry {  public:    /// A single location or constant.    struct Value { -    Value(const MDNode *Var, int64_t i) -      : Variable(Var), EntryKind(E_Integer) { +    Value(const MDNode *Var, const MDNode *Expr, int64_t i) +        : Variable(Var), Expression(Expr), EntryKind(E_Integer) {        Constant.Int = i;      } -    Value(const MDNode *Var, const ConstantFP *CFP) -      : Variable(Var), EntryKind(E_ConstantFP) { +    Value(const MDNode *Var, const MDNode *Expr, const ConstantFP *CFP) +        : Variable(Var), Expression(Expr), EntryKind(E_ConstantFP) {        Constant.CFP = CFP;      } -    Value(const MDNode *Var, const ConstantInt *CIP) -      : Variable(Var), EntryKind(E_ConstantInt) { +    Value(const MDNode *Var, const MDNode *Expr, const ConstantInt *CIP) +        : Variable(Var), Expression(Expr), EntryKind(E_ConstantInt) {        Constant.CIP = CIP;      } -    Value(const MDNode *Var, MachineLocation Loc) -      : Variable(Var), EntryKind(E_Location), Loc(Loc) { +    Value(const MDNode *Var, const MDNode *Expr, MachineLocation Loc) +        : Variable(Var), Expression(Expr), EntryKind(E_Location), Loc(Loc) { +      assert(DIVariable(Var).Verify()); +      assert(DIExpression(Expr).Verify());      }      // The variable to which this location entry corresponds.      const MDNode *Variable; +    // Any complex address location expression for this Value. +    const MDNode *Expression; +      // Type of entry that this represents.      enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };      enum EntryType EntryKind; @@ -69,7 +74,8 @@ public:      MachineLocation getLoc() const { return Loc; }      const MDNode *getVariableNode() const { return Variable; }      DIVariable getVariable() const { return DIVariable(Variable); } -    bool isVariablePiece() const { return getVariable().isVariablePiece(); } +    bool isVariablePiece() const { return getExpression().isVariablePiece(); } +    DIExpression getExpression() const { return DIExpression(Expression); }      friend bool operator==(const Value &, const Value &);      friend bool operator<(const Value &, const Value &);    }; @@ -90,11 +96,13 @@ public:    // list of values.    // Return true if the merge was successful.    bool MergeValues(const DebugLocEntry &Next) { -    if (Begin == Next.Begin && Values.size() > 0 && Next.Values.size() > 0) { +    if (Begin == Next.Begin) { +      DIExpression Expr(Values[0].Expression);        DIVariable Var(Values[0].Variable); +      DIExpression NextExpr(Next.Values[0].Expression);        DIVariable NextVar(Next.Values[0].Variable); -      if (Var.getName() == NextVar.getName() && -          Var.isVariablePiece() && NextVar.isVariablePiece()) { +      if (Var == NextVar && Expr.isVariablePiece() && +          NextExpr.isVariablePiece()) {          addValues(Next.Values);          End = Next.End;          return true; @@ -133,8 +141,10 @@ public:      std::sort(Values.begin(), Values.end());      Values.erase(std::unique(Values.begin(), Values.end(),                               [](const Value &A, const Value &B) { -                               return A.getVariable() == B.getVariable(); -                               }), Values.end()); +                   return A.getVariable() == B.getVariable() && +                          A.getExpression() == B.getExpression(); +                 }), +                 Values.end());    }  }; @@ -144,7 +154,10 @@ inline bool operator==(const DebugLocEntry::Value &A,    if (A.EntryKind != B.EntryKind)      return false; -  if (A.getVariable() != B.getVariable()) +  if (A.Expression != B.Expression) +    return false; + +  if (A.Variable != B.Variable)      return false;    switch (A.EntryKind) { @@ -163,7 +176,8 @@ inline bool operator==(const DebugLocEntry::Value &A,  /// Compare two pieces based on their offset.  inline bool operator<(const DebugLocEntry::Value &A,                        const DebugLocEntry::Value &B) { -  return A.getVariable().getPieceOffset() < B.getVariable().getPieceOffset(); +  return A.getExpression().getPieceOffset() < +         B.getExpression().getPieceOffset();  }  } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 4745974a3d2..c54fc989569 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -901,7 +901,7 @@ void DwarfDebug::collectDeadVariables() {          for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) {            DIVariable DV(Variables.getElement(vi));            assert(DV.isVariable()); -          DbgVariable NewVar(DV, this); +          DbgVariable NewVar(DV, DIExpression(nullptr), this);            auto VariableDie = SPCU->constructVariableDIE(NewVar);            SPCU->applyVariableAttributes(NewVar, *VariableDie);            SPDIE->addChild(std::move(VariableDie)); @@ -1121,7 +1121,7 @@ DbgVariable *DwarfDebug::getExistingAbstractVariable(const DIVariable &DV) {  void DwarfDebug::createAbstractVariable(const DIVariable &Var,                                          LexicalScope *Scope) { -  auto AbsDbgVariable = make_unique<DbgVariable>(Var, this); +  auto AbsDbgVariable = make_unique<DbgVariable>(Var, DIExpression(), this);    addScopeVariable(Scope, AbsDbgVariable.get());    AbstractVariables[Var] = std::move(AbsDbgVariable);  } @@ -1177,6 +1177,7 @@ void DwarfDebug::collectVariableInfoFromMMITable(        continue;      Processed.insert(VI.Var);      DIVariable DV(VI.Var); +    DIExpression Expr(VI.Expr);      LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);      // If variable scope is not found then skip this variable. @@ -1184,7 +1185,7 @@ void DwarfDebug::collectVariableInfoFromMMITable(        continue;      ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); -    ConcreteVariables.push_back(make_unique<DbgVariable>(DV, this)); +    ConcreteVariables.push_back(make_unique<DbgVariable>(DV, Expr, this));      DbgVariable *RegVar = ConcreteVariables.back().get();      RegVar->setFrameIndex(VI.Slot);      addScopeVariable(Scope, RegVar); @@ -1193,9 +1194,10 @@ void DwarfDebug::collectVariableInfoFromMMITable(  // Get .debug_loc entry for the instruction range starting at MI.  static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) { +  const MDNode *Expr = MI->getDebugExpression();    const MDNode *Var = MI->getDebugVariable(); -  assert(MI->getNumOperands() == 3); +  assert(MI->getNumOperands() == 4);    if (MI->getOperand(0).isReg()) {      MachineLocation MLoc;      // If the second operand is an immediate, this is a @@ -1204,20 +1206,20 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {        MLoc.set(MI->getOperand(0).getReg());      else        MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm()); -    return DebugLocEntry::Value(Var, MLoc); +    return DebugLocEntry::Value(Var, Expr, MLoc);    }    if (MI->getOperand(0).isImm()) -    return DebugLocEntry::Value(Var, MI->getOperand(0).getImm()); +    return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getImm());    if (MI->getOperand(0).isFPImm()) -    return DebugLocEntry::Value(Var, MI->getOperand(0).getFPImm()); +    return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getFPImm());    if (MI->getOperand(0).isCImm()) -    return DebugLocEntry::Value(Var, MI->getOperand(0).getCImm()); +    return DebugLocEntry::Value(Var, Expr, MI->getOperand(0).getCImm()); -  llvm_unreachable("Unexpected 3 operand DBG_VALUE instruction!"); +  llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");  }  /// Determine whether two variable pieces overlap. -static bool piecesOverlap(DIVariable P1, DIVariable P2) { +static bool piecesOverlap(DIExpression P1, DIExpression P2) {    if (!P1.isVariablePiece() || !P2.isVariablePiece())      return true;    unsigned l1 = P1.getPieceOffset(); @@ -1268,11 +1270,11 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,      }      // If this piece overlaps with any open ranges, truncate them. -    DIVariable DIVar = Begin->getDebugVariable(); +    DIExpression DIExpr = Begin->getDebugExpression();      auto Last = std::remove_if(OpenRanges.begin(), OpenRanges.end(),                                 [&](DebugLocEntry::Value R) { -                                 return piecesOverlap(DIVar, R.getVariable()); -                               }); +      return piecesOverlap(DIExpr, R.getExpression()); +    });      OpenRanges.erase(Last, OpenRanges.end());      const MCSymbol *StartLabel = getLabelBeforeInsn(Begin); @@ -1294,7 +1296,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,      bool couldMerge = false;      // If this is a piece, it may belong to the current DebugLocEntry. -    if (DIVar.isVariablePiece()) { +    if (DIExpr.isVariablePiece()) {        // Add this value to the list of open ranges.        OpenRanges.push_back(Value); @@ -1320,10 +1322,14 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,      if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))        DebugLoc.pop_back(); -    DEBUG(dbgs() << "Values:\n"; -          for (auto Value : CurEntry->getValues()) -            Value.getVariable()->dump(); -          dbgs() << "-----\n"); +    DEBUG({ +      dbgs() << CurEntry->getValues().size() << " Values:\n"; +      for (auto Value : CurEntry->getValues()) { +        Value.getVariable()->dump(); +        Value.getExpression()->dump(); +      } +      dbgs() << "-----\n"; +    });    }  } @@ -1358,7 +1364,7 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl<const MDNode *> &Processed) {      if (!Scope)        continue; -    Processed.insert(getEntireVariable(DV)); +    Processed.insert(DV);      const MachineInstr *MInsn = Ranges.front().first;      assert(MInsn->isDebugValue() && "History must begin with debug value");      ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); @@ -1392,7 +1398,8 @@ DwarfDebug::collectVariableInfo(SmallPtrSetImpl<const MDNode *> &Processed) {        continue;      if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) {        ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); -      ConcreteVariables.push_back(make_unique<DbgVariable>(DV, this)); +      DIExpression NoExpr; +      ConcreteVariables.push_back(make_unique<DbgVariable>(DV, NoExpr, this));        addScopeVariable(Scope, ConcreteVariables.back().get());      }    } @@ -1580,18 +1587,17 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {      // The first mention of a function argument gets the FunctionBeginSym      // label, so arguments are visible when breaking at function entry. -    DIVariable DV(Ranges.front().first->getDebugVariable()); -    if (DV.isVariable() && DV.getTag() == dwarf::DW_TAG_arg_variable && -        getDISubprogram(DV.getContext()).describes(MF->getFunction())) { -      if (!DV.isVariablePiece()) -        LabelsBeforeInsn[Ranges.front().first] = FunctionBeginSym; -      else { +    DIVariable DIVar(Ranges.front().first->getDebugVariable()); +    if (DIVar.isVariable() && DIVar.getTag() == dwarf::DW_TAG_arg_variable && +        getDISubprogram(DIVar.getContext()).describes(MF->getFunction())) { +      LabelsBeforeInsn[Ranges.front().first] = FunctionBeginSym; +      if (Ranges.front().first->getDebugExpression().isVariablePiece()) {          // Mark all non-overlapping initial pieces.          for (auto I = Ranges.begin(); I != Ranges.end(); ++I) { -          DIVariable Piece = I->first->getDebugVariable(); +          DIExpression Piece = I->first->getDebugExpression();            if (std::all_of(Ranges.begin(), I, -                          [&](DbgValueHistoryMap::InstrRange Pred){ -                return !piecesOverlap(Piece, Pred.first->getDebugVariable()); +                          [&](DbgValueHistoryMap::InstrRange Pred) { +                return !piecesOverlap(Piece, Pred.first->getDebugExpression());                }))              LabelsBeforeInsn[I->first] = FunctionBeginSym;            else @@ -2089,9 +2095,9 @@ void DwarfDebug::emitLocPieces(ByteStreamer &Streamer,    unsigned Offset = 0;    for (auto Piece : Values) { -    DIVariable Var = Piece.getVariable(); -    unsigned PieceOffset = Var.getPieceOffset(); -    unsigned PieceSize = Var.getPieceSize(); +    DIExpression Expr = Piece.getExpression(); +    unsigned PieceOffset = Expr.getPieceOffset(); +    unsigned PieceSize = Expr.getPieceSize();      assert(Offset <= PieceOffset && "overlapping or duplicate pieces");      if (Offset < PieceOffset) {        // The DWARF spec seriously mandates pieces with no locations for gaps. @@ -2102,8 +2108,9 @@ void DwarfDebug::emitLocPieces(ByteStreamer &Streamer,      Offset += PieceSize;      const unsigned SizeOfByte = 8; -    assert(!Var.isIndirect() && "indirect address for piece");  #ifndef NDEBUG +    DIVariable Var = Piece.getVariable(); +    assert(!Var.isIndirect() && "indirect address for piece");      unsigned VarSize = Var.getSizeInBits(Map);      assert(PieceSize+PieceOffset <= VarSize/SizeOfByte             && "piece is larger than or outside of variable"); @@ -2149,24 +2156,25 @@ void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer,      }    } else if (Value.isLocation()) {      MachineLocation Loc = Value.getLoc(); -    if (!DV.hasComplexAddress()) +    DIExpression Expr = Value.getExpression(); +    if (!Expr)        // Regular entry.        Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect());      else {        // Complex address entry. -      unsigned N = DV.getNumAddrElements(); +      unsigned N = Expr.getNumElements();        unsigned i = 0; -      if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { +      if (N >= 2 && Expr.getElement(0) == dwarf::DW_OP_plus) {          if (Loc.getOffset()) {            i = 2;            Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect());            Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref");            Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst"); -          Streamer.EmitSLEB128(DV.getAddrElement(1)); +          Streamer.EmitSLEB128(Expr.getElement(1));          } else {            // If first address element is OpPlus then emit            // DW_OP_breg + Offset instead of DW_OP_reg + Offset. -          MachineLocation TLoc(Loc.getReg(), DV.getAddrElement(1)); +          MachineLocation TLoc(Loc.getReg(), Expr.getElement(1));            Asm->EmitDwarfRegOp(Streamer, TLoc, DV.isIndirect());            i = 2;          } @@ -2176,14 +2184,14 @@ void DwarfDebug::emitDebugLocValue(ByteStreamer &Streamer,        // Emit remaining complex address elements.        for (; i < N; ++i) { -        uint64_t Element = DV.getAddrElement(i); -        if (Element == DIBuilder::OpPlus) { +        uint64_t Element = Expr.getElement(i); +        if (Element == dwarf::DW_OP_plus) {            Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst"); -          Streamer.EmitULEB128(DV.getAddrElement(++i)); -        } else if (Element == DIBuilder::OpDeref) { +          Streamer.EmitULEB128(Expr.getElement(++i)); +        } else if (Element == dwarf::DW_OP_deref) {            if (!Loc.isReg())              Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref"); -        } else if (Element == DIBuilder::OpPiece) { +        } else if (Element == dwarf::DW_OP_piece) {            i += 3;            // handled in emitDebugLocEntry.          } else diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 80f81853ddd..1432ecd58ae 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -70,6 +70,7 @@ public:  /// \brief This class is used to track local variable information.  class DbgVariable {    DIVariable Var;             // Variable Descriptor. +  DIExpression Expr;          // Complex address location expression.    DIE *TheDIE;                // Variable DIE.    unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries.    const MachineInstr *MInsn;  // DBG_VALUE instruction of the variable. @@ -78,18 +79,22 @@ class DbgVariable {  public:    /// Construct a DbgVariable from a DIVariable. -  DbgVariable(DIVariable V, DwarfDebug *DD) -      : Var(V), TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(nullptr), -        FrameIndex(~0), DD(DD) {} +  DbgVariable(DIVariable V, DIExpression E, DwarfDebug *DD) +      : Var(V), Expr(E), TheDIE(nullptr), DotDebugLocOffset(~0U), +        MInsn(nullptr), FrameIndex(~0), DD(DD) { +    assert(Var.Verify() && Expr.Verify()); +  }    /// Construct a DbgVariable from a DEBUG_VALUE.    /// AbstractVar may be NULL.    DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD) -      : Var(DbgValue->getDebugVariable()), TheDIE(nullptr), -        DotDebugLocOffset(~0U), MInsn(DbgValue), FrameIndex(~0), DD(DD) {} +      : Var(DbgValue->getDebugVariable()), Expr(DbgValue->getDebugExpression()), +        TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(DbgValue), +        FrameIndex(~0), DD(DD) {}    // Accessors.    DIVariable getVariable() const { return Var; } +  DIExpression getExpression() const { return Expr; }    void setDIE(DIE &D) { TheDIE = &D; }    DIE *getDIE() const { return TheDIE; }    void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; } @@ -124,14 +129,14 @@ public:    bool variableHasComplexAddress() const {      assert(Var.isVariable() && "Invalid complex DbgVariable!"); -    return Var.hasComplexAddress(); +    return Expr.getNumElements() > 0;    }    bool isBlockByrefVariable() const;    unsigned getNumAddrElements() const {      assert(Var.isVariable() && "Invalid complex DbgVariable!"); -    return Var.getNumAddrElements(); +    return Expr.getNumElements();    } -  uint64_t getAddrElement(unsigned i) const { return Var.getAddrElement(i); } +  uint64_t getAddrElement(unsigned i) const { return Expr.getElement(i); }    DIType getType() const;  private: diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 806b0e76fc6..b19b576cdf3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -607,16 +607,20 @@ void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,    unsigned N = DV.getNumAddrElements();    unsigned i = 0;    if (Location.isReg()) { -    if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) { +    if (N >= 2 && DV.getAddrElement(0) == dwarf::DW_OP_plus) { +      assert(!DV.getVariable().isIndirect() && +             "double indirection not handled");        // If first address element is OpPlus then emit        // DW_OP_breg + Offset instead of DW_OP_reg + Offset.        addRegisterOffset(*Loc, Location.getReg(), DV.getAddrElement(1));        i = 2; -    } else if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpDeref) { -        addRegisterOpPiece(*Loc, Location.getReg(), -                           DV.getVariable().getPieceSize(), -                           DV.getVariable().getPieceOffset()); -        i = 3; +    } else if (N >= 2 && DV.getAddrElement(0) == dwarf::DW_OP_deref) { +      assert(!DV.getVariable().isIndirect() && +             "double indirection not handled"); +      addRegisterOpPiece(*Loc, Location.getReg(), +                         DV.getExpression().getPieceSize(), +                         DV.getExpression().getPieceOffset()); +      i = 3;      } else        addRegisterOpPiece(*Loc, Location.getReg());    } else @@ -624,15 +628,15 @@ void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,    for (; i < N; ++i) {      uint64_t Element = DV.getAddrElement(i); -    if (Element == DIBuilder::OpPlus) { +    if (Element == dwarf::DW_OP_plus) {        addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);        addUInt(*Loc, dwarf::DW_FORM_udata, DV.getAddrElement(++i)); -    } else if (Element == DIBuilder::OpDeref) { +    } else if (Element == dwarf::DW_OP_deref) {        if (!Location.isReg())          addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref); -    } else if (Element == DIBuilder::OpPiece) { +    } else if (Element == dwarf::DW_OP_piece) {        const unsigned SizeOfByte = 8;        unsigned PieceOffsetInBits = DV.getAddrElement(++i)*SizeOfByte;        unsigned PieceSizeInBits = DV.getAddrElement(++i)*SizeOfByte; @@ -1861,7 +1865,7 @@ std::unique_ptr<DIE> DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV,    // Check if variable is described by a DBG_VALUE instruction.    if (const MachineInstr *DVInsn = DV.getMInsn()) { -    assert(DVInsn->getNumOperands() == 3); +    assert(DVInsn->getNumOperands() == 4);      if (DVInsn->getOperand(0).isReg()) {        const MachineOperand RegOp = DVInsn->getOperand(0);        // If the second operand is an immediate, this is an indirect value. diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp index c868cab6c15..4064d131239 100644 --- a/llvm/lib/CodeGen/InlineSpiller.cpp +++ b/llvm/lib/CodeGen/InlineSpiller.cpp @@ -1224,12 +1224,16 @@ void InlineSpiller::spillAroundUses(unsigned Reg) {        // Modify DBG_VALUE now that the value is in a spill slot.        bool IsIndirect = MI->isIndirectDebugValue();        uint64_t Offset = IsIndirect ? MI->getOperand(1).getImm() : 0; -      const MDNode *MDPtr = MI->getOperand(2).getMetadata(); +      const MDNode *Var = MI->getDebugVariable(); +      const MDNode *Expr = MI->getDebugExpression();        DebugLoc DL = MI->getDebugLoc();        DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *MI);        MachineBasicBlock *MBB = MI->getParent();        BuildMI(*MBB, MBB->erase(MI), DL, TII.get(TargetOpcode::DBG_VALUE)) -          .addFrameIndex(StackSlot).addImm(Offset).addMetadata(MDPtr); +          .addFrameIndex(StackSlot) +          .addImm(Offset) +          .addMetadata(Var) +          .addMetadata(Expr);        continue;      } diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp index 2790008b92c..72d0e138a3f 100644 --- a/llvm/lib/CodeGen/LiveDebugVariables.cpp +++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp @@ -110,7 +110,8 @@ public:  namespace {  class LDVImpl;  class UserValue { -  const MDNode *variable; ///< The debug info variable we are part of. +  const MDNode *Variable;   ///< The debug info variable we are part of. +  const MDNode *Expression; ///< Any complex address expression.    unsigned offset;        ///< Byte offset into variable.    bool IsIndirect;        ///< true if this is a register-indirect+offset value.    DebugLoc dl;            ///< The debug location for the variable. This is @@ -140,11 +141,10 @@ class UserValue {  public:    /// UserValue - Create a new UserValue. -  UserValue(const MDNode *var, unsigned o, bool i, DebugLoc L, -            LocMap::Allocator &alloc) -    : variable(var), offset(o), IsIndirect(i), dl(L), leader(this), -      next(nullptr), locInts(alloc) -  {} +  UserValue(const MDNode *var, const MDNode *expr, unsigned o, bool i, +            DebugLoc L, LocMap::Allocator &alloc) +      : Variable(var), Expression(expr), offset(o), IsIndirect(i), dl(L), +        leader(this), next(nullptr), locInts(alloc) {}    /// getLeader - Get the leader of this value's equivalence class.    UserValue *getLeader() { @@ -158,8 +158,10 @@ public:    UserValue *getNext() const { return next; }    /// match - Does this UserValue match the parameters? -  bool match(const MDNode *Var, unsigned Offset, bool indirect) const { -    return Var == variable && Offset == offset && indirect == IsIndirect; +  bool match(const MDNode *Var, const MDNode *Expr, unsigned Offset, +             bool indirect) const { +    return Var == Variable && Expr == Expression && Offset == offset && +           indirect == IsIndirect;    }    /// merge - Merge equivalence classes. @@ -307,8 +309,8 @@ class LDVImpl {    UVMap userVarMap;    /// getUserValue - Find or create a UserValue. -  UserValue *getUserValue(const MDNode *Var, unsigned Offset, -                          bool IsIndirect, DebugLoc DL); +  UserValue *getUserValue(const MDNode *Var, const MDNode *Expr, +                          unsigned Offset, bool IsIndirect, DebugLoc DL);    /// lookupVirtReg - Find the EC leader for VirtReg or null.    UserValue *lookupVirtReg(unsigned VirtReg); @@ -361,7 +363,7 @@ public:  } // namespace  void UserValue::print(raw_ostream &OS, const TargetMachine *TM) { -  DIVariable DV(variable); +  DIVariable DV(Variable);    OS << "!\"";    DV.printExtendedName(OS);    OS << "\"\t"; @@ -422,19 +424,20 @@ void UserValue::mapVirtRegs(LDVImpl *LDV) {        LDV->mapVirtReg(locations[i].getReg(), this);  } -UserValue *LDVImpl::getUserValue(const MDNode *Var, unsigned Offset, -                                 bool IsIndirect, DebugLoc DL) { +UserValue *LDVImpl::getUserValue(const MDNode *Var, const MDNode *Expr, +                                 unsigned Offset, bool IsIndirect, +                                 DebugLoc DL) {    UserValue *&Leader = userVarMap[Var];    if (Leader) {      UserValue *UV = Leader->getLeader();      Leader = UV;      for (; UV; UV = UV->getNext()) -      if (UV->match(Var, Offset, IsIndirect)) +      if (UV->match(Var, Expr, Offset, IsIndirect))          return UV;    }    userValues.push_back( -      make_unique<UserValue>(Var, Offset, IsIndirect, DL, allocator)); +      make_unique<UserValue>(Var, Expr, Offset, IsIndirect, DL, allocator));    UserValue *UV = userValues.back().get();    Leader = UserValue::merge(Leader, UV);    return UV; @@ -454,7 +457,7 @@ UserValue *LDVImpl::lookupVirtReg(unsigned VirtReg) {  bool LDVImpl::handleDebugValue(MachineInstr *MI, SlotIndex Idx) {    // DBG_VALUE loc, offset, variable -  if (MI->getNumOperands() != 3 || +  if (MI->getNumOperands() != 4 ||        !(MI->getOperand(1).isReg() || MI->getOperand(1).isImm()) ||        !MI->getOperand(2).isMetadata()) {      DEBUG(dbgs() << "Can't handle " << *MI); @@ -464,9 +467,11 @@ bool LDVImpl::handleDebugValue(MachineInstr *MI, SlotIndex Idx) {    // Get or create the UserValue for (variable,offset).    bool IsIndirect = MI->isIndirectDebugValue();    unsigned Offset = IsIndirect ? MI->getOperand(1).getImm() : 0; -  const MDNode *Var = MI->getOperand(2).getMetadata(); +  const MDNode *Var = MI->getDebugVariable(); +  const MDNode *Expr = MI->getDebugExpression();    //here. -  UserValue *UV = getUserValue(Var, Offset, IsIndirect, MI->getDebugLoc()); +  UserValue *UV = +      getUserValue(Var, Expr, Offset, IsIndirect, MI->getDebugLoc());    UV->addDef(Idx, MI->getOperand(0));    return true;  } @@ -951,10 +956,13 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,    if (Loc.isReg())      BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE), -            IsIndirect, Loc.getReg(), offset, variable); +            IsIndirect, Loc.getReg(), offset, Variable, Expression);    else      BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE)) -      .addOperand(Loc).addImm(offset).addMetadata(variable); +        .addOperand(Loc) +        .addImm(offset) +        .addMetadata(Variable) +        .addMetadata(Expression);  }  void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS, diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 493f5ee0977..d33d4a9d26a 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -1643,8 +1643,11 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM,      if (isDebugValue() && MO.isMetadata()) {        // Pretty print DBG_VALUE instructions.        const MDNode *MD = MO.getMetadata(); -      if (const MDString *MDS = dyn_cast<MDString>(MD->getOperand(2))) -        OS << "!\"" << MDS->getString() << '\"'; +      if (MD->getNumOperands() >= 2) +        if (const MDString *MDS = dyn_cast<MDString>(MD->getOperand(2))) +          OS << "!\"" << MDS->getString() << '\"'; +        else +          MO.print(OS, TM);        else          MO.print(OS, TM);      } else if (TM && (isInsertSubreg() || isRegSequence()) && MO.isImm()) { @@ -1747,6 +1750,8 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM,          OS << " ]";        }      } +    if (isIndirectDebugValue()) +      OS << " indirect";    } else if (!debugLoc.isUnknown() && MF) {      if (!HaveSemi) OS << ";";      OS << " dbg:"; diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp index 6e7e2c7e8ca..5efbb6306b6 100644 --- a/llvm/lib/CodeGen/RegAllocFast.cpp +++ b/llvm/lib/CodeGen/RegAllocFast.cpp @@ -299,7 +299,8 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI,        LiveDbgValueMap[LRI->VirtReg];      for (unsigned li = 0, le = LRIDbgValues.size(); li != le; ++li) {        MachineInstr *DBG = LRIDbgValues[li]; -      const MDNode *MDPtr = DBG->getOperand(2).getMetadata(); +      const MDNode *Var = DBG->getDebugVariable(); +      const MDNode *Expr = DBG->getDebugExpression();        bool IsIndirect = DBG->isIndirectDebugValue();        uint64_t Offset = IsIndirect ? DBG->getOperand(1).getImm() : 0;        DebugLoc DL; @@ -311,7 +312,10 @@ void RAFast::spillVirtReg(MachineBasicBlock::iterator MI,          DL = MI->getDebugLoc();        MachineInstr *NewDV =            BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::DBG_VALUE)) -              .addFrameIndex(FI).addImm(Offset).addMetadata(MDPtr); +              .addFrameIndex(FI) +              .addImm(Offset) +              .addMetadata(Var) +              .addMetadata(Expr);        assert(NewDV->getParent() == MBB && "dangling parent pointer");        (void)NewDV;        DEBUG(dbgs() << "Inserting debug info due to spill:" << "\n" << *NewDV); @@ -863,13 +867,16 @@ void RAFast::AllocateBasicBlock() {                // Modify DBG_VALUE now that the value is in a spill slot.                bool IsIndirect = MI->isIndirectDebugValue();                uint64_t Offset = IsIndirect ? MI->getOperand(1).getImm() : 0; -              const MDNode *MDPtr = -                MI->getOperand(MI->getNumOperands()-1).getMetadata(); +              const MDNode *Var = MI->getDebugVariable(); +              const MDNode *Expr = MI->getDebugExpression();                DebugLoc DL = MI->getDebugLoc();                MachineBasicBlock *MBB = MI->getParent();                MachineInstr *NewDV = BuildMI(*MBB, MBB->erase(MI), DL,                                              TII->get(TargetOpcode::DBG_VALUE)) -                  .addFrameIndex(SS).addImm(Offset).addMetadata(MDPtr); +                                        .addFrameIndex(SS) +                                        .addImm(Offset) +                                        .addMetadata(Var) +                                        .addMetadata(Expr);                DEBUG(dbgs() << "Modifying debug info due to spill:"                             << "\t" << *NewDV);                // Scan NewDV operands from the beginning. diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 7b656bfe34e..72390a94bfe 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1125,13 +1125,14 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {          Op->setIsDebug(true);          BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,                  TII.get(TargetOpcode::DBG_VALUE), false, Op->getReg(), 0, -                DI->getVariable()); +                DI->getVariable(), DI->getExpression());        } else          BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,                  TII.get(TargetOpcode::DBG_VALUE))              .addOperand(*Op)              .addImm(0) -            .addMetadata(DI->getVariable()); +            .addMetadata(DI->getVariable()) +            .addMetadata(DI->getExpression());      } else {        // We can't yet handle anything else here because it would require        // generating code, thus altering codegen because of debug info. @@ -1150,28 +1151,32 @@ bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) {        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)            .addReg(0U)            .addImm(DI->getOffset()) -          .addMetadata(DI->getVariable()); +          .addMetadata(DI->getVariable()) +          .addMetadata(DI->getExpression());      } else if (const auto *CI = dyn_cast<ConstantInt>(V)) {        if (CI->getBitWidth() > 64)          BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)              .addCImm(CI)              .addImm(DI->getOffset()) -            .addMetadata(DI->getVariable()); +            .addMetadata(DI->getVariable()) +            .addMetadata(DI->getExpression());        else          BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)              .addImm(CI->getZExtValue())              .addImm(DI->getOffset()) -            .addMetadata(DI->getVariable()); +            .addMetadata(DI->getVariable()) +            .addMetadata(DI->getExpression());      } else if (const auto *CF = dyn_cast<ConstantFP>(V)) {        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II)            .addFPImm(CF)            .addImm(DI->getOffset()) -          .addMetadata(DI->getVariable()); +          .addMetadata(DI->getVariable()) +          .addMetadata(DI->getExpression());      } else if (unsigned Reg = lookUpRegForValue(V)) {        // FIXME: This does not handle register-indirect values at offset 0.        bool IsIndirect = DI->getOffset() != 0;        BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II, IsIndirect, Reg, -              DI->getOffset(), DI->getVariable()); +              DI->getOffset(), DI->getVariable(), DI->getExpression());      } else {        // We can't yet handle anything else here because it would require        // generating code, thus altering codegen because of debug info. @@ -2181,4 +2186,4 @@ CmpInst::Predicate FastISel::optimizeCmpPredicate(const CmpInst *CI) const {    }    return Predicate; -}
\ No newline at end of file +} diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp index c06612dcfa2..d1fcbe54f26 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -197,7 +197,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,                  StaticAllocaMap.find(AI);                if (SI != StaticAllocaMap.end()) { // Check for VLAs.                  int FI = SI->second; -                MMI.setVariableDbgInfo(DI->getVariable(), +                MMI.setVariableDbgInfo(DI->getVariable(), DI->getExpression(),                                         FI, DI->getDebugLoc());                }              } diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 4d6de12161c..32d5ddca615 100644 --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -649,14 +649,18 @@ MachineInstr *  InstrEmitter::EmitDbgValue(SDDbgValue *SD,                             DenseMap<SDValue, unsigned> &VRBaseMap) {    uint64_t Offset = SD->getOffset(); -  MDNode* MDPtr = SD->getMDPtr(); +  MDNode *Var = SD->getVariable(); +  MDNode *Expr = SD->getExpression();    DebugLoc DL = SD->getDebugLoc();    if (SD->getKind() == SDDbgValue::FRAMEIX) {      // Stack address; this needs to be lowered in target-dependent fashion.      // EmitTargetCodeForFrameDebugValue is responsible for allocation.      return BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE)) -        .addFrameIndex(SD->getFrameIx()).addImm(Offset).addMetadata(MDPtr); +        .addFrameIndex(SD->getFrameIx()) +        .addImm(Offset) +        .addMetadata(Var) +        .addMetadata(Expr);    }    // Otherwise, we're going to create an instruction here.    const MCInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE); @@ -702,7 +706,8 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD,      MIB.addReg(0U, RegState::Debug);    } -  MIB.addMetadata(MDPtr); +  MIB.addMetadata(Var); +  MIB.addMetadata(Expr);    return &*MIB;  } diff --git a/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h b/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h index 307808e3578..c8bb3d8831c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h +++ b/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h @@ -44,7 +44,8 @@ private:      const Value *Const;     // valid for constants      unsigned FrameIx;       // valid for stack objects    } u; -  MDNode *mdPtr; +  MDNode *Var; +  MDNode *Expr;    bool IsIndirect;    uint64_t Offset;    DebugLoc DL; @@ -52,29 +53,29 @@ private:    bool Invalid;  public:    // Constructor for non-constants. -  SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, -	     bool indir, uint64_t off, DebugLoc dl, -             unsigned O) : mdPtr(mdP), IsIndirect(indir), -			   Offset(off), DL(dl), Order(O), -                           Invalid(false) { +  SDDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, unsigned R, bool indir, +             uint64_t off, DebugLoc dl, unsigned O) +      : Var(Var), Expr(Expr), IsIndirect(indir), Offset(off), DL(dl), Order(O), +        Invalid(false) {      kind = SDNODE;      u.s.Node = N;      u.s.ResNo = R;    }    // Constructor for constants. -  SDDbgValue(MDNode *mdP, const Value *C, uint64_t off, DebugLoc dl, -             unsigned O) :  -    mdPtr(mdP), IsIndirect(false), Offset(off), DL(dl), Order(O), -    Invalid(false) { +  SDDbgValue(MDNode *Var, MDNode *Expr, const Value *C, uint64_t off, +             DebugLoc dl, unsigned O) +      : Var(Var), Expr(Expr), IsIndirect(false), Offset(off), DL(dl), Order(O), +        Invalid(false) {      kind = CONST;      u.Const = C;    }    // Constructor for frame indices. -  SDDbgValue(MDNode *mdP, unsigned FI, uint64_t off, DebugLoc dl, unsigned O) :  -    mdPtr(mdP), IsIndirect(false), Offset(off), DL(dl), Order(O), -    Invalid(false) { +  SDDbgValue(MDNode *Var, MDNode *Expr, unsigned FI, uint64_t off, DebugLoc dl, +             unsigned O) +      : Var(Var), Expr(Expr), IsIndirect(false), Offset(off), DL(dl), Order(O), +        Invalid(false) {      kind = FRAMEIX;      u.FrameIx = FI;    } @@ -82,8 +83,11 @@ public:    // Returns the kind.    DbgValueKind getKind() { return kind; } -  // Returns the MDNode pointer. -  MDNode *getMDPtr() { return mdPtr; } +  // Returns the MDNode pointer for the variable. +  MDNode *getVariable() { return Var; } + +  // Returns the MDNode pointer for the expression. +  MDNode *getExpression() { return Expr; }    // Returns the SDNode* for a register ref    SDNode *getSDNode() { assert (kind==SDNODE); return u.s.Node; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index e2ead476fae..2322ce0104c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5764,26 +5764,24 @@ SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,  /// getDbgValue - Creates a SDDbgValue node.  ///  /// SDNode -SDDbgValue * -SelectionDAG::getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R, -			  bool IsIndirect, uint64_t Off, -                          DebugLoc DL, unsigned O) { -  return new (Allocator) SDDbgValue(MDPtr, N, R, IsIndirect, Off, DL, O); +SDDbgValue *SelectionDAG::getDbgValue(MDNode *Var, MDNode *Expr, SDNode *N, +                                      unsigned R, bool IsIndirect, uint64_t Off, +                                      DebugLoc DL, unsigned O) { +  return new (Allocator) SDDbgValue(Var, Expr, N, R, IsIndirect, Off, DL, O);  }  /// Constant -SDDbgValue * -SelectionDAG::getConstantDbgValue(MDNode *MDPtr, const Value *C, -				  uint64_t Off, -				  DebugLoc DL, unsigned O) { -  return new (Allocator) SDDbgValue(MDPtr, C, Off, DL, O); +SDDbgValue *SelectionDAG::getConstantDbgValue(MDNode *Var, MDNode *Expr, +                                              const Value *C, uint64_t Off, +                                              DebugLoc DL, unsigned O) { +  return new (Allocator) SDDbgValue(Var, Expr, C, Off, DL, O);  }  /// FrameIndex -SDDbgValue * -SelectionDAG::getFrameIndexDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off, -				    DebugLoc DL, unsigned O) { -  return new (Allocator) SDDbgValue(MDPtr, FI, Off, DL, O); +SDDbgValue *SelectionDAG::getFrameIndexDbgValue(MDNode *Var, MDNode *Expr, +                                                unsigned FI, uint64_t Off, +                                                DebugLoc DL, unsigned O) { +  return new (Allocator) SDDbgValue(Var, Expr, FI, Off, DL, O);  }  namespace { @@ -6189,10 +6187,10 @@ void SelectionDAG::TransferDbgValues(SDValue From, SDValue To) {         I != E; ++I) {      SDDbgValue *Dbg = *I;      if (Dbg->getKind() == SDDbgValue::SDNODE) { -      SDDbgValue *Clone = getDbgValue(Dbg->getMDPtr(), ToNode, To.getResNo(), -				      Dbg->isIndirect(), -                                      Dbg->getOffset(), Dbg->getDebugLoc(), -                                      Dbg->getOrder()); +      SDDbgValue *Clone = +          getDbgValue(Dbg->getVariable(), Dbg->getExpression(), ToNode, +                      To.getResNo(), Dbg->isIndirect(), Dbg->getOffset(), +                      Dbg->getDebugLoc(), Dbg->getOrder());        ClonedDVs.push_back(Clone);      }    } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 6a8cd2eb3b1..9bd5dfea0a6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -993,15 +993,16 @@ void SelectionDAGBuilder::resolveDanglingDebugInfo(const Value *V,      DebugLoc dl = DDI.getdl();      unsigned DbgSDNodeOrder = DDI.getSDNodeOrder();      MDNode *Variable = DI->getVariable(); +    MDNode *Expr = DI->getExpression();      uint64_t Offset = DI->getOffset();      // A dbg.value for an alloca is always indirect.      bool IsIndirect = isa<AllocaInst>(V) || Offset != 0;      SDDbgValue *SDV;      if (Val.getNode()) { -      if (!EmitFuncArgumentDbgValue(V, Variable, Offset, IsIndirect, Val)) { -        SDV = DAG.getDbgValue(Variable, Val.getNode(), -                              Val.getResNo(), IsIndirect, -			      Offset, dl, DbgSDNodeOrder); +      if (!EmitFuncArgumentDbgValue(V, Variable, Expr, Offset, IsIndirect, +                                    Val)) { +        SDV = DAG.getDbgValue(Variable, Expr, Val.getNode(), Val.getResNo(), +                              IsIndirect, Offset, dl, DbgSDNodeOrder);          DAG.AddDbgValue(SDV, Val.getNode(), false);        }      } else @@ -4603,10 +4604,11 @@ static unsigned getTruncatedArgReg(const SDValue &N) {  /// EmitFuncArgumentDbgValue - If the DbgValueInst is a dbg_value of a function  /// argument, create the corresponding DBG_VALUE machine instruction for it now.  /// At the end of instruction selection, they will be inserted to the entry BB. -bool -SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable, -                                              int64_t Offset, bool IsIndirect, -                                              const SDValue &N) { +bool SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, +                                                   MDNode *Variable, +                                                   MDNode *Expr, int64_t Offset, +                                                   bool IsIndirect, +                                                   const SDValue &N) {    const Argument *Arg = dyn_cast<Argument>(V);    if (!Arg)      return false; @@ -4658,14 +4660,16 @@ SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable,      return false;    if (Op->isReg()) -    FuncInfo.ArgDbgValues.push_back(BuildMI(MF, getCurDebugLoc(), -                                            TII->get(TargetOpcode::DBG_VALUE), -                                            IsIndirect, -                                            Op->getReg(), Offset, Variable)); +    FuncInfo.ArgDbgValues.push_back( +        BuildMI(MF, getCurDebugLoc(), TII->get(TargetOpcode::DBG_VALUE), +                IsIndirect, Op->getReg(), Offset, Variable, Expr));    else      FuncInfo.ArgDbgValues.push_back( -      BuildMI(MF, getCurDebugLoc(), TII->get(TargetOpcode::DBG_VALUE)) -          .addOperand(*Op).addImm(Offset).addMetadata(Variable)); +        BuildMI(MF, getCurDebugLoc(), TII->get(TargetOpcode::DBG_VALUE)) +            .addOperand(*Op) +            .addImm(Offset) +            .addMetadata(Variable) +            .addMetadata(Expr));    return true;  } @@ -4785,6 +4789,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {    case Intrinsic::dbg_declare: {      const DbgDeclareInst &DI = cast<DbgDeclareInst>(I);      MDNode *Variable = DI.getVariable(); +    MDNode *Expression = DI.getExpression();      const Value *Address = DI.getAddress();      DIVariable DIVar(Variable);      assert((!DIVar || DIVar.isVariable()) && @@ -4820,16 +4825,16 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {          FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(N.getNode());          if (FINode)            // Byval parameter.  We have a frame index at this point. -          SDV = DAG.getFrameIndexDbgValue(Variable, FINode->getIndex(), -					  0, dl, SDNodeOrder); +          SDV = DAG.getFrameIndexDbgValue( +              Variable, Expression, FINode->getIndex(), 0, dl, SDNodeOrder);          else {            // Address is an argument, so try to emit its dbg value using            // virtual register info from the FuncInfo.ValueMap. -          EmitFuncArgumentDbgValue(Address, Variable, 0, false, N); +          EmitFuncArgumentDbgValue(Address, Variable, Expression, 0, false, N);            return nullptr;          }        } else if (AI) -        SDV = DAG.getDbgValue(Variable, N.getNode(), N.getResNo(), +        SDV = DAG.getDbgValue(Variable, Expression, N.getNode(), N.getResNo(),                                true, 0, dl, SDNodeOrder);        else {          // Can't do anything with other non-AI cases yet. @@ -4842,7 +4847,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {      } else {        // If Address is an argument then try to emit its dbg value using        // virtual register info from the FuncInfo.ValueMap. -      if (!EmitFuncArgumentDbgValue(Address, Variable, 0, false, N)) { +      if (!EmitFuncArgumentDbgValue(Address, Variable, Expression, 0, false, +                                    N)) {          // If variable is pinned by a alloca in dominating bb then          // use StaticAllocaMap.          if (const AllocaInst *AI = dyn_cast<AllocaInst>(Address)) { @@ -4850,7 +4856,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {              DenseMap<const AllocaInst*, int>::iterator SI =                FuncInfo.StaticAllocaMap.find(AI);              if (SI != FuncInfo.StaticAllocaMap.end()) { -              SDV = DAG.getFrameIndexDbgValue(Variable, SI->second, +              SDV = DAG.getFrameIndexDbgValue(Variable, Expression, SI->second,                                                0, dl, SDNodeOrder);                DAG.AddDbgValue(SDV, nullptr, false);                return nullptr; @@ -4871,6 +4877,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {        return nullptr;      MDNode *Variable = DI.getVariable(); +    MDNode *Expression = DI.getExpression();      uint64_t Offset = DI.getOffset();      const Value *V = DI.getValue();      if (!V) @@ -4878,7 +4885,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {      SDDbgValue *SDV;      if (isa<ConstantInt>(V) || isa<ConstantFP>(V) || isa<UndefValue>(V)) { -      SDV = DAG.getConstantDbgValue(Variable, V, Offset, dl, SDNodeOrder); +      SDV = DAG.getConstantDbgValue(Variable, Expression, V, Offset, dl, +                                    SDNodeOrder);        DAG.AddDbgValue(SDV, nullptr, false);      } else {        // Do not use getValue() in here; we don't want to generate code at @@ -4890,10 +4898,10 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {        if (N.getNode()) {          // A dbg.value for an alloca is always indirect.          bool IsIndirect = isa<AllocaInst>(V) || Offset != 0; -        if (!EmitFuncArgumentDbgValue(V, Variable, Offset, IsIndirect, N)) { -          SDV = DAG.getDbgValue(Variable, N.getNode(), -                                N.getResNo(), IsIndirect, -				Offset, dl, SDNodeOrder); +        if (!EmitFuncArgumentDbgValue(V, Variable, Expression, Offset, +                                      IsIndirect, N)) { +          SDV = DAG.getDbgValue(Variable, Expression, N.getNode(), N.getResNo(), +                                IsIndirect, Offset, dl, SDNodeOrder);            DAG.AddDbgValue(SDV, N.getNode(), false);          }        } else if (!V->use_empty() ) { diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 45dd55412d2..6ecddc1608a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -791,7 +791,7 @@ private:    /// EmitFuncArgumentDbgValue - If V is an function argument then create    /// corresponding DBG_VALUE machine instruction for it now. At the end of    /// instruction selection, they will be inserted to the entry BB. -  bool EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable, +  bool EmitFuncArgumentDbgValue(const Value *V, MDNode *Variable, MDNode *Expr,                                  int64_t Offset, bool IsIndirect,                                  const SDValue &N);  }; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 4ef3e6f94f5..df2c6b8de0b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -486,15 +486,14 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {                         "- add if needed");        MachineInstr *Def = RegInfo->getVRegDef(LDI->second);        MachineBasicBlock::iterator InsertPos = Def; -      const MDNode *Variable = -        MI->getOperand(MI->getNumOperands()-1).getMetadata(); +      const MDNode *Variable = MI->getDebugVariable(); +      const MDNode *Expr = MI->getDebugExpression();        bool IsIndirect = MI->isIndirectDebugValue();        unsigned Offset = IsIndirect ? MI->getOperand(1).getImm() : 0;        // Def is never a terminator here, so it is ok to increment InsertPos.        BuildMI(*EntryMBB, ++InsertPos, MI->getDebugLoc(), -              TII.get(TargetOpcode::DBG_VALUE), -              IsIndirect, -              LDI->second, Offset, Variable); +              TII.get(TargetOpcode::DBG_VALUE), IsIndirect, LDI->second, Offset, +              Variable, Expr);        // If this vreg is directly copied into an exported register then        // that COPY instructions also need DBG_VALUE, if it is the only @@ -513,11 +512,9 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {        }        if (CopyUseMI) {          MachineInstr *NewMI = -          BuildMI(*MF, CopyUseMI->getDebugLoc(), -                  TII.get(TargetOpcode::DBG_VALUE), -                  IsIndirect, -                  CopyUseMI->getOperand(0).getReg(), -                  Offset, Variable); +            BuildMI(*MF, CopyUseMI->getDebugLoc(), +                    TII.get(TargetOpcode::DBG_VALUE), IsIndirect, +                    CopyUseMI->getOperand(0).getReg(), Offset, Variable, Expr);          MachineBasicBlock::iterator Pos = CopyUseMI;          EntryMBB->insertAfter(Pos, NewMI);        } diff --git a/llvm/lib/IR/AutoUpgrade.cpp b/llvm/lib/IR/AutoUpgrade.cpp index bbb8462652c..b4f327bab5c 100644 --- a/llvm/lib/IR/AutoUpgrade.cpp +++ b/llvm/lib/IR/AutoUpgrade.cpp @@ -17,6 +17,7 @@  #include "llvm/IR/Constants.h"  #include "llvm/IR/DebugInfo.h"  #include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DIBuilder.h"  #include "llvm/IR/Function.h"  #include "llvm/IR/IRBuilder.h"  #include "llvm/IR/Instruction.h" @@ -106,6 +107,20 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {      }      break;    } +  case 'd': { +    if (Name.startswith("dbg.declare") && F->arg_size() == 2) { +      F->setName(Name + ".old"); +      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_declare); +      return true; +    } +    if (Name.startswith("dbg.value") && F->arg_size() == 3) { +      F->setName(Name + ".old"); +      NewFn = Intrinsic::getDeclaration(F->getParent(), Intrinsic::dbg_value); +      return true; +    } +    break; +  } +    case 'o':      // We only need to change the name to match the mangling including the      // address space. @@ -239,6 +254,22 @@ bool llvm::UpgradeGlobalVariable(GlobalVariable *GV) {    return false;  } +static MDNode *getNodeField(const MDNode *DbgNode, unsigned Elt) { +  if (!DbgNode || Elt >= DbgNode->getNumOperands()) +    return nullptr; +  return dyn_cast_or_null<MDNode>(DbgNode->getOperand(Elt)); +} + +static DIExpression getExpression(Value *VarOperand, Function *F) { +  // Old-style DIVariables have an optional expression as the 8th element. +  DIExpression Expr(getNodeField(cast<MDNode>(VarOperand), 8)); +  if (!Expr) { +    DIBuilder DIB(*F->getParent()); +    Expr = DIB.createExpression(); +  } +  return Expr; +} +  // UpgradeIntrinsicCall - Upgrade a call to an old intrinsic to be a call the  // upgraded intrinsic. All argument and return casting must be provided in  // order to seamlessly integrate with existing context. @@ -402,12 +433,32 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) {    }    std::string Name = CI->getName().str(); -  CI->setName(Name + ".old"); +  if (!Name.empty()) +    CI->setName(Name + ".old");    switch (NewFn->getIntrinsicID()) {    default:      llvm_unreachable("Unknown function for CallInst upgrade."); +  // Upgrade debug intrinsics to use an additional DIExpression argument. +  case Intrinsic::dbg_declare: { +    auto NewCI = +        Builder.CreateCall3(NewFn, CI->getArgOperand(0), CI->getArgOperand(1), +                            getExpression(CI->getArgOperand(1), F), Name); +    NewCI->setDebugLoc(CI->getDebugLoc()); +    CI->replaceAllUsesWith(NewCI); +    CI->eraseFromParent(); +    return; +  } +  case Intrinsic::dbg_value: { +    auto NewCI = Builder.CreateCall4( +        NewFn, CI->getArgOperand(0), CI->getArgOperand(1), CI->getArgOperand(2), +        getExpression(CI->getArgOperand(2), F), Name); +    NewCI->setDebugLoc(CI->getDebugLoc()); +    CI->replaceAllUsesWith(NewCI); +    CI->eraseFromParent(); +    return; +  }    case Intrinsic::ctlz:    case Intrinsic::cttz:      assert(CI->getNumArgOperands() == 1 && diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index a5c09b60c4f..1ab52523d73 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -1042,50 +1042,28 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,    return RetVar;  } -/// createComplexVariable - Create a new descriptor for the specified variable -/// which has a complex address expression for its address. -DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope, -                                            StringRef Name, DIFile F, -                                            unsigned LineNo, -                                            DITypeRef Ty, -                                            ArrayRef<Value *> Addr, -                                            unsigned ArgNo) { -  assert(Addr.size() > 0 && "complex address is empty"); -  Value *Elts[] = { -    GetTagConstant(VMContext, Tag), -    getNonCompileUnitScope(Scope), -    MDString::get(VMContext, Name), -    F, -    ConstantInt::get(Type::getInt32Ty(VMContext), -                     (LineNo | (ArgNo << 24))), -    Ty, -    Constant::getNullValue(Type::getInt32Ty(VMContext)), -    Constant::getNullValue(Type::getInt32Ty(VMContext)), -    MDNode::get(VMContext, Addr) -  }; -  return DIVariable(MDNode::get(VMContext, Elts)); +/// createExpression - Create a new descriptor for the specified +/// variable which has a complex address expression for its address. +/// @param Addr        An array of complex address operations. +DIExpression DIBuilder::createExpression(ArrayRef<Value *> Addr) { +  SmallVector<llvm::Value *, 16> Elts; +  Elts.push_back(GetTagConstant(VMContext, DW_TAG_expression)); +  Elts.insert(Elts.end(), Addr.begin(), Addr.end()); +  return DIExpression(MDNode::get(VMContext, Elts));  }  /// createVariablePiece - Create a descriptor to describe one part  /// of aggregate variable that is fragmented across multiple Values. -DIVariable DIBuilder::createVariablePiece(DIVariable Variable, -                                          unsigned OffsetInBytes, -                                          unsigned SizeInBytes) { +DIExpression DIBuilder::createPieceExpression(unsigned OffsetInBytes, +                                              unsigned SizeInBytes) {    assert(SizeInBytes > 0 && "zero-size piece");    Value *Addr[] = { -    ConstantInt::get(Type::getInt32Ty(VMContext), OpPiece), -    ConstantInt::get(Type::getInt32Ty(VMContext), OffsetInBytes), -    ConstantInt::get(Type::getInt32Ty(VMContext), SizeInBytes) -  }; - -  assert((Variable->getNumOperands() == 8 || Variable.isVariablePiece()) && -         "variable already has a complex address"); -  SmallVector<Value *, 9> Elts; -  for (unsigned i = 0; i < 8; ++i) -    Elts.push_back(Variable->getOperand(i)); +      GetTagConstant(VMContext, DW_TAG_expression), +      ConstantInt::get(Type::getInt64Ty(VMContext), dwarf::DW_OP_piece), +      ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBytes), +      ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBytes)}; -  Elts.push_back(MDNode::get(VMContext, Addr)); -  return DIVariable(MDNode::get(VMContext, Elts)); +  return DIExpression(MDNode::get(VMContext, Addr));  }  /// createFunction - Create a new descriptor for the specified function. @@ -1292,6 +1270,7 @@ DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File,  /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.  Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, +                                      DIExpression Expr,                                        Instruction *InsertBefore) {    assert(Storage && "no storage passed to dbg.declare");    assert(VarInfo.isVariable() && @@ -1299,12 +1278,13 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,    if (!DeclareFn)      DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); -  Value *Args[] = { MDNode::get(Storage->getContext(), Storage), VarInfo }; +  Value *Args[] = {MDNode::get(Storage->getContext(), Storage), VarInfo, Expr};    return CallInst::Create(DeclareFn, Args, "", InsertBefore);  }  /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call.  Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, +                                      DIExpression Expr,                                        BasicBlock *InsertAtEnd) {    assert(Storage && "no storage passed to dbg.declare");    assert(VarInfo.isVariable() && @@ -1312,7 +1292,7 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,    if (!DeclareFn)      DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); -  Value *Args[] = { MDNode::get(Storage->getContext(), Storage), VarInfo }; +  Value *Args[] = {MDNode::get(Storage->getContext(), Storage), VarInfo, Expr};    // If this block already has a terminator then insert this intrinsic    // before the terminator. @@ -1325,6 +1305,7 @@ Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo,  /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.  Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,                                                  DIVariable VarInfo, +                                                DIExpression Expr,                                                  Instruction *InsertBefore) {    assert(V && "no value passed to dbg.value");    assert(VarInfo.isVariable() && @@ -1332,15 +1313,16 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,    if (!ValueFn)      ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); -  Value *Args[] = { MDNode::get(V->getContext(), V), -                    ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), -                    VarInfo }; +  Value *Args[] = {MDNode::get(V->getContext(), V), +                   ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), +                   VarInfo, Expr};    return CallInst::Create(ValueFn, Args, "", InsertBefore);  }  /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call.  Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,                                                  DIVariable VarInfo, +                                                DIExpression Expr,                                                  BasicBlock *InsertAtEnd) {    assert(V && "no value passed to dbg.value");    assert(VarInfo.isVariable() && @@ -1348,8 +1330,8 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset,    if (!ValueFn)      ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); -  Value *Args[] = { MDNode::get(V->getContext(), V), -                    ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), -                    VarInfo }; +  Value *Args[] = {MDNode::get(V->getContext(), V), +                   ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), +                   VarInfo, Expr};    return CallInst::Create(ValueFn, Args, "", InsertAtEnd);  } diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 4274d82d158..4e36a8df3e1 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -49,7 +49,7 @@ bool DIDescriptor::Verify() const {            DIObjCProperty(DbgNode).Verify() ||            DITemplateTypeParameter(DbgNode).Verify() ||            DITemplateValueParameter(DbgNode).Verify() || -          DIImportedEntity(DbgNode).Verify()); +          DIImportedEntity(DbgNode).Verify() || DIExpression(DbgNode).Verify());  }  static Value *getField(const MDNode *DbgNode, unsigned Elt) { @@ -138,33 +138,9 @@ void DIDescriptor::replaceFunctionField(unsigned Elt, Function *F) {    }  } -uint64_t DIVariable::getAddrElement(unsigned Idx) const { -  DIDescriptor ComplexExpr = getDescriptorField(8); -  if (Idx < ComplexExpr->getNumOperands()) -    if (auto *CI = dyn_cast_or_null<ConstantInt>(ComplexExpr->getOperand(Idx))) -      return CI->getZExtValue(); - -  assert(false && "non-existing complex address element requested"); -  return 0; -} -  /// getInlinedAt - If this variable is inlined then return inline location.  MDNode *DIVariable::getInlinedAt() const { return getNodeField(DbgNode, 7); } -bool DIVariable::isVariablePiece() const { -  return hasComplexAddress() && getAddrElement(0) == DIBuilder::OpPiece; -} - -uint64_t DIVariable::getPieceOffset() const { -  assert(isVariablePiece()); -  return getAddrElement(1); -} - -uint64_t DIVariable::getPieceSize() const { -  assert(isVariablePiece()); -  return getAddrElement(2); -} -  /// Return the size reported by the variable's type.  unsigned DIVariable::getSizeInBits(const DITypeIdentifierMap &Map) {    DIType Ty = getType().resolve(Map); @@ -178,8 +154,29 @@ unsigned DIVariable::getSizeInBits(const DITypeIdentifierMap &Map) {    return Ty.getSizeInBits();  } +uint64_t DIExpression::getElement(unsigned Idx) const { +  unsigned I = Idx + 1; +  if (I < DbgNode->getNumOperands()) +    if (auto *CI = dyn_cast_or_null<ConstantInt>(DbgNode->getOperand(I))) +      return CI->getZExtValue(); + +  assert(false && "non-existing complex address element requested"); +  return 0; +} + +bool DIExpression::isVariablePiece() const { +  return getNumElements() && getElement(0) == dwarf::DW_OP_piece; +} +uint64_t DIExpression::getPieceOffset() const { +  assert(isVariablePiece()); +  return getElement(1); +} +uint64_t DIExpression::getPieceSize() const { +  assert(isVariablePiece()); +  return getElement(2); +}  //===----------------------------------------------------------------------===//  // Predicates @@ -357,6 +354,12 @@ bool DIDescriptor::isImportedEntity() const {                       getTag() == dwarf::DW_TAG_imported_declaration);  } +/// \brief Return true if the specified tag is DW_TAG_imported_module or +/// DW_TAG_imported_declaration. +bool DIDescriptor::isExpression() const { +  return DbgNode && (getTag() == dwarf::DW_TAG_expression); +} +  //===----------------------------------------------------------------------===//  // Simple Descriptor Constructors and other Methods  //===----------------------------------------------------------------------===// @@ -596,14 +599,16 @@ bool DIVariable::Verify() const {    if (!fieldIsTypeRef(DbgNode, 5))      return false; -  // Variable without a complex expression. -  if (DbgNode->getNumOperands() == 8) +  // Variable without an inline location. +  if (DbgNode->getNumOperands() == 7)      return true; -  // Make sure the complex expression is an MDNode. -  return (DbgNode->getNumOperands() == 9 && fieldIsMDNode(DbgNode, 8)); +  return DbgNode->getNumOperands() == 8;  } +/// Verify - Verify that a variable descriptor is well formed. +bool DIExpression::Verify() const { return isExpression(); } +  /// Verify - Verify that a location descriptor is well formed.  bool DILocation::Verify() const {    if (!DbgNode) @@ -936,19 +941,6 @@ DIVariable llvm::cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext) {    return DIVariable(MDNode::get(VMContext, Elts));  } - -/// getEntireVariable - Remove OpPiece exprs from the variable. -DIVariable llvm::getEntireVariable(DIVariable DV) { -  if (!DV.isVariablePiece()) -    return DV; - -  SmallVector<Value *, 8> Elts; -  for (unsigned i = 0; i < 8; ++i) -    Elts.push_back(DV->getOperand(i)); - -  return DIVariable(MDNode::get(DV->getContext(), Elts)); -} -  /// getDISubprogram - Find subprogram that is enclosing this scope.  DISubprogram llvm::getDISubprogram(const MDNode *Scope) {    DIDescriptor D(Scope); @@ -1293,6 +1285,8 @@ void DIDescriptor::print(raw_ostream &OS) const {      DINameSpace(DbgNode).printInternal(OS);    } else if (this->isScope()) {      DIScope(DbgNode).printInternal(OS); +  } else if (this->isExpression()) { +    DIExpression(DbgNode).printInternal(OS);    }  } @@ -1442,10 +1436,28 @@ void DIVariable::printInternal(raw_ostream &OS) const {      OS << " [" << Res << ']';    OS << " [line " << getLineNumber() << ']'; +} -  if (isVariablePiece()) -    OS << " [piece, size " << getPieceSize() -       << ", offset " << getPieceOffset() << ']'; +void DIExpression::printInternal(raw_ostream &OS) const { +  for (unsigned I = 0; I < getNumElements(); ++I) { +    uint64_t OpCode = getElement(I); +    OS << " [" << OperationEncodingString(OpCode); +    switch (OpCode) { +    case DW_OP_plus: { +      OS << " " << getElement(++I); +      break; +    } +    case DW_OP_piece: { +      unsigned Offset = getElement(++I); +      unsigned Size = getElement(++I); +      OS << " offset=" << Offset << ", size= " << Size; +      break; +    } +    default: +      break; +    } +    OS << "]"; +  }  }  void DIObjCProperty::printInternal(raw_ostream &OS) const { diff --git a/llvm/lib/Support/Dwarf.cpp b/llvm/lib/Support/Dwarf.cpp index 5237ac22025..8f2013778ac 100644 --- a/llvm/lib/Support/Dwarf.cpp +++ b/llvm/lib/Support/Dwarf.cpp @@ -82,6 +82,8 @@ const char *llvm::dwarf::TagString(unsigned Tag) {    case DW_TAG_hi_user:                   return "DW_TAG_hi_user";    case DW_TAG_auto_variable:             return "DW_TAG_auto_variable";    case DW_TAG_arg_variable:              return "DW_TAG_arg_variable"; +  case DW_TAG_expression: +    return "DW_TAG_expression";    case DW_TAG_rvalue_reference_type:     return "DW_TAG_rvalue_reference_type";    case DW_TAG_template_alias:            return "DW_TAG_template_alias";    case DW_TAG_coarray_type:              return "DW_TAG_coarray_type"; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 2f633c21787..f984eb1ad15 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -1444,16 +1444,15 @@ bool AArch64InstrInfo::shouldScheduleAdjacent(MachineInstr *First,    }  } -MachineInstr *AArch64InstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, -                                                         int FrameIx, -                                                         uint64_t Offset, -                                                         const MDNode *MDPtr, -                                                         DebugLoc DL) const { +MachineInstr *AArch64InstrInfo::emitFrameIndexDebugValue( +    MachineFunction &MF, int FrameIx, uint64_t Offset, const MDNode *Var, +    const MDNode *Expr, DebugLoc DL) const {    MachineInstrBuilder MIB = BuildMI(MF, DL, get(AArch64::DBG_VALUE))                                  .addFrameIndex(FrameIx)                                  .addImm(0)                                  .addImm(Offset) -                                .addMetadata(MDPtr); +                                .addMetadata(Var) +                                .addMetadata(Expr);    return &*MIB;  } diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.h b/llvm/lib/Target/AArch64/AArch64InstrInfo.h index cdb25bebd94..64fc9fd56b8 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.h +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.h @@ -107,8 +107,8 @@ public:                                MachineInstr *Second) const override;    MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, -                                         uint64_t Offset, const MDNode *MDPtr, -                                         DebugLoc DL) const; +                                         uint64_t Offset, const MDNode *Var, +                                         const MDNode *Expr, DebugLoc DL) const;    void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,                          DebugLoc DL, unsigned DestReg, unsigned SrcReg,                          bool KillSrc, unsigned Opcode, diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index 828e251e753..70eec08cce2 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -2249,8 +2249,10 @@ bool X86FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {      const MCInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE);      // FIXME may need to add RegState::Debug to any registers produced,      // although ESP/EBP should be the only ones at the moment. -    addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II), AM). -      addImm(0).addMetadata(DI->getVariable()); +    addFullAddress(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II), AM) +        .addImm(0) +        .addMetadata(DI->getVariable()) +        .addMetadata(DI->getExpression());      return true;    }    case Intrinsic::trap: { diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index ada44cd5d28..6c01826a064 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -891,8 +891,8 @@ public:          continue;        }        Instruction *DbgVal = -        DIB.insertDbgValueIntrinsic(Arg, 0, DIVariable(DVI->getVariable()), -                                     Inst); +          DIB.insertDbgValueIntrinsic(Arg, 0, DIVariable(DVI->getVariable()), +                                      DIExpression(DVI->getExpression()), Inst);        DbgVal->setDebugLoc(DVI->getDebugLoc());      }    } diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index eb8d2a6f73f..c6d6ec73761 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1124,9 +1124,9 @@ public:        } else {          continue;        } -      Instruction *DbgVal = -        DIB->insertDbgValueIntrinsic(Arg, 0, DIVariable(DVI->getVariable()), -                                     Inst); +      Instruction *DbgVal = DIB->insertDbgValueIntrinsic( +          Arg, 0, DIVariable(DVI->getVariable()), +          DIExpression(DVI->getExpression()), Inst);        DbgVal->setDebugLoc(DVI->getDebugLoc());      }    } diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index e4ce699ecb4..69c9346c027 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -993,6 +993,7 @@ static bool LdStHasDebugValue(DIVariable &DIVar, Instruction *I) {  bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,                                             StoreInst *SI, DIBuilder &Builder) {    DIVariable DIVar(DDI->getVariable()); +  DIExpression DIExpr(DDI->getExpression());    assert((!DIVar || DIVar.isVariable()) &&           "Variable in DbgDeclareInst should be either null or a DIVariable.");    if (!DIVar) @@ -1010,9 +1011,10 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,    if (SExtInst *SExt = dyn_cast<SExtInst>(SI->getOperand(0)))      ExtendedArg = dyn_cast<Argument>(SExt->getOperand(0));    if (ExtendedArg) -    DbgVal = Builder.insertDbgValueIntrinsic(ExtendedArg, 0, DIVar, SI); +    DbgVal = Builder.insertDbgValueIntrinsic(ExtendedArg, 0, DIVar, DIExpr, SI);    else -    DbgVal = Builder.insertDbgValueIntrinsic(SI->getOperand(0), 0, DIVar, SI); +    DbgVal = Builder.insertDbgValueIntrinsic(SI->getOperand(0), 0, DIVar, +                                             DIExpr, SI);    DbgVal->setDebugLoc(DDI->getDebugLoc());    return true;  } @@ -1022,6 +1024,7 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,  bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,                                             LoadInst *LI, DIBuilder &Builder) {    DIVariable DIVar(DDI->getVariable()); +  DIExpression DIExpr(DDI->getExpression());    assert((!DIVar || DIVar.isVariable()) &&           "Variable in DbgDeclareInst should be either null or a DIVariable.");    if (!DIVar) @@ -1031,8 +1034,7 @@ bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,      return true;    Instruction *DbgVal = -    Builder.insertDbgValueIntrinsic(LI->getOperand(0), 0, -                                    DIVar, LI); +      Builder.insertDbgValueIntrinsic(LI->getOperand(0), 0, DIVar, DIExpr, LI);    DbgVal->setDebugLoc(DDI->getDebugLoc());    return true;  } @@ -1075,11 +1077,11 @@ bool llvm::LowerDbgDeclare(Function &F) {  	  // This is a call by-value or some other instruction that  	  // takes a pointer to the variable. Insert a *value*  	  // intrinsic that describes the alloca. -	  auto DbgVal = -	    DIB.insertDbgValueIntrinsic(AI, 0, -					DIVariable(DDI->getVariable()), CI); -	  DbgVal->setDebugLoc(DDI->getDebugLoc()); -	} +          auto DbgVal = DIB.insertDbgValueIntrinsic( +              AI, 0, DIVariable(DDI->getVariable()), +              DIExpression(DDI->getExpression()), CI); +          DbgVal->setDebugLoc(DDI->getDebugLoc()); +        }        DDI->eraseFromParent();      }    } @@ -1103,6 +1105,7 @@ bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,    if (!DDI)      return false;    DIVariable DIVar(DDI->getVariable()); +  DIExpression DIExpr(DDI->getExpression());    assert((!DIVar || DIVar.isVariable()) &&           "Variable in DbgDeclareInst should be either null or a DIVariable.");    if (!DIVar) @@ -1113,23 +1116,19 @@ bool llvm::replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,    // will take a value storing address of the memory for variable, not    // alloca itself.    Type *Int64Ty = Type::getInt64Ty(AI->getContext()); -  SmallVector<Value*, 4> NewDIVarAddress; -  if (DIVar.hasComplexAddress()) { -    for (unsigned i = 0, n = DIVar.getNumAddrElements(); i < n; ++i) { -      NewDIVarAddress.push_back( -          ConstantInt::get(Int64Ty, DIVar.getAddrElement(i))); +  SmallVector<Value *, 4> NewDIExpr; +  if (DIExpr) { +    for (unsigned i = 0, n = DIExpr.getNumElements(); i < n; ++i) { +      NewDIExpr.push_back(ConstantInt::get(Int64Ty, DIExpr.getElement(i)));      }    } -  NewDIVarAddress.push_back(ConstantInt::get(Int64Ty, DIBuilder::OpDeref)); -  DIVariable NewDIVar = Builder.createComplexVariable( -      DIVar.getTag(), DIVar.getContext(), DIVar.getName(), -      DIVar.getFile(), DIVar.getLineNumber(), DIVar.getType(), -      NewDIVarAddress, DIVar.getArgNumber()); +  NewDIExpr.push_back(ConstantInt::get(Int64Ty, dwarf::DW_OP_deref));    // Insert llvm.dbg.declare in the same basic block as the original alloca,    // and remove old llvm.dbg.declare.    BasicBlock *BB = AI->getParent(); -  Builder.insertDeclare(NewAllocaAddress, NewDIVar, BB); +  Builder.insertDeclare(NewAllocaAddress, DIVar, +                        Builder.createExpression(NewDIExpr), BB);    DDI->eraseFromParent();    return true;  }  | 

