Index: include/llvm/CodeGen/MachineInstr.h =================================================================== --- include/llvm/CodeGen/MachineInstr.h +++ include/llvm/CodeGen/MachineInstr.h @@ -244,7 +244,15 @@ /// DebugLoc getDebugLoc() const { return debugLoc; } - /// getDebugVariable() - Return the debug variable referenced by + /// \brief Return the complex address expression referenced by + /// this DBG_VALUE instruction. + DIExpression getDebugExpression() const { + assert(isDebugValue() && "not a DBG_VALUE"); + const MDNode *Expr = getOperand(getNumOperands() - 2).getMetadata(); + return DIExpression(Expr); + } + + /// \brief Return the debug variable referenced by /// this DBG_VALUE instruction. DIVariable getDebugVariable() const { assert(isDebugValue() && "not a DBG_VALUE"); Index: include/llvm/CodeGen/MachineInstrBuilder.h =================================================================== --- include/llvm/CodeGen/MachineInstrBuilder.h +++ include/llvm/CodeGen/MachineInstrBuilder.h @@ -351,18 +351,21 @@ bool IsIndirect, unsigned Reg, unsigned Offset, - const MDNode *MD) { + const MDNode *Expr, + const MDNode *Variable) { if (IsIndirect) return BuildMI(MF, DL, MCID) .addReg(Reg, RegState::Debug) .addImm(Offset) - .addMetadata(MD); + .addMetadata(Expr) + .addMetadata(Variable); else { assert(Offset == 0 && "A direct address cannot have an offset."); return BuildMI(MF, DL, MCID) .addReg(Reg, RegState::Debug) .addReg(0U, RegState::Debug) - .addMetadata(MD); + .addMetadata(Expr) + .addMetadata(Variable); } } @@ -377,9 +380,12 @@ bool IsIndirect, unsigned Reg, unsigned Offset, - const MDNode *MD) { + const MDNode *Expr, + const MDNode *Variable) { + MachineFunction &MF = *BB.getParent(); - MachineInstr *MI = BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, MD); + MachineInstr *MI = + BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Expr, Variable); BB.insert(I, MI); return MachineInstrBuilder(MF, MI); } Index: include/llvm/CodeGen/MachineModuleInfo.h =================================================================== --- include/llvm/CodeGen/MachineModuleInfo.h +++ include/llvm/CodeGen/MachineModuleInfo.h @@ -169,6 +169,7 @@ static char ID; // Pass identification, replacement for typeid struct VariableDbgInfo { + TrackingVH Expr; TrackingVH Var; unsigned Slot; DebugLoc Loc; @@ -403,8 +404,9 @@ /// setVariableDbgInfo - Collect information used to emit debugging /// information of a variable. - void setVariableDbgInfo(MDNode *N, unsigned Slot, DebugLoc Loc) { - VariableDbgInfo Info = { N, Slot, Loc }; + void setVariableDbgInfo(MDNode *Expr, MDNode *Var, + unsigned Slot, DebugLoc Loc) { + VariableDbgInfo Info = { Expr, Var, Slot, Loc }; VariableDbgInfos.push_back(std::move(Info)); } Index: include/llvm/CodeGen/SelectionDAG.h =================================================================== --- include/llvm/CodeGen/SelectionDAG.h +++ include/llvm/CodeGen/SelectionDAG.h @@ -984,15 +984,19 @@ /// getDbgValue - Creates a SDDbgValue node. /// - SDDbgValue *getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R, + /// SDNode + SDDbgValue *getDbgValue(MDNode *Expr, MDNode *Var, SDNode *N, unsigned R, bool IsIndirect, uint64_t Off, DebugLoc DL, unsigned O); - /// Constant. - SDDbgValue *getConstantDbgValue(MDNode *MDPtr, const Value *C, uint64_t Off, - DebugLoc DL, unsigned O); - /// Frame index. - SDDbgValue *getFrameIndexDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off, - DebugLoc DL, unsigned O); + + /// Constant + SDDbgValue *getConstantDbgValue(MDNode *Expr, MDNode *Var, const Value *C, + uint64_t Off, DebugLoc DL, unsigned O); + + /// FrameIndex + SDDbgValue *getFrameIndexDbgValue(MDNode *Expr, MDNode *Var, + unsigned FI, uint64_t Off, + DebugLoc DL, unsigned O); /// RemoveDeadNode - Remove the specified node from the system. If any of its /// operands then becomes dead, remove them as well. Inform UpdateListener Index: include/llvm/IR/DIBuilder.h =================================================================== --- include/llvm/IR/DIBuilder.h +++ include/llvm/IR/DIBuilder.h @@ -544,32 +544,22 @@ unsigned ArgNo = 0); - /// createComplexVariable - Create a new descriptor for the specified + /// createExpression - Create an empty DIExpression. + DIExpression createExpression(); + + /// createExpression - Create a new descriptor for the specified /// variable which has a complex address expression for its address. - /// @param Tag Dwarf TAG. Usually DW_TAG_auto_variable or - /// DW_TAG_arg_variable. - /// @param Scope Variable scope. - /// @param Name Variable name. - /// @param F File where this variable is defined. - /// @param LineNo Line number. - /// @param Ty Variable Type /// @param Addr An array of complex address operations. - /// @param ArgNo If this variable is an argument then this argument's - /// number. 1 indicates 1st argument. - DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope, - StringRef Name, DIFile F, unsigned LineNo, - DITypeRef Ty, ArrayRef Addr, - unsigned ArgNo = 0); + DIExpression createExpression(ArrayRef Addr); - /// createVariablePiece - Create a descriptor to describe one part + + /// createPieceExpression - Create a descriptor to describe one part /// of aggregate variable that is fragmented across multiple Values. /// - /// @param Variable Variable that is partially represented by this. /// @param OffsetInBytes Offset of the piece in bytes. /// @param SizeInBytes Size of the piece in bytes. - DIVariable createVariablePiece(DIVariable Variable, - unsigned OffsetInBytes, - unsigned SizeInBytes); + DIExpression createPieceExpression(unsigned OffsetInBytes, + unsigned SizeInBytes); /// createFunction - Create a new descriptor for the specified subprogram. /// See comments in DISubprogram for descriptions of these fields. @@ -702,34 +692,42 @@ /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. /// @param Storage llvm::Value of the variable + /// @param Expr A complex location expression. /// @param VarInfo Variable's debug info descriptor. /// @param InsertAtEnd Location for the new intrinsic. - Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo, + Instruction *insertDeclare(llvm::Value *Storage, + DIExpression Expr, DIVariable VarInfo, BasicBlock *InsertAtEnd); /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. /// @param Storage llvm::Value of the variable + /// @param Expr A complex location expression. /// @param VarInfo Variable's debug info descriptor. /// @param InsertBefore Location for the new intrinsic. - Instruction *insertDeclare(llvm::Value *Storage, DIVariable VarInfo, + Instruction *insertDeclare(llvm::Value *Storage, + DIExpression Expr, DIVariable VarInfo, Instruction *InsertBefore); /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. /// @param Val llvm::Value of the variable /// @param Offset Offset + /// @param Expr A complex location expression. /// @param VarInfo Variable's debug info descriptor. /// @param InsertAtEnd Location for the new intrinsic. Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset, + DIExpression Expr, DIVariable VarInfo, BasicBlock *InsertAtEnd); /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. /// @param Val llvm::Value of the variable /// @param Offset Offset + /// @param Expr A complex location expression. /// @param VarInfo Variable's debug info descriptor. /// @param InsertBefore Location for the new intrinsic. Instruction *insertDbgValueIntrinsic(llvm::Value *Val, uint64_t Offset, + DIExpression Expr, DIVariable VarInfo, Instruction *InsertBefore); Index: include/llvm/IR/DebugInfo.h =================================================================== --- include/llvm/IR/DebugInfo.h +++ include/llvm/IR/DebugInfo.h @@ -701,20 +701,6 @@ /// Verify - Verify that a variable descriptor is well formed. bool Verify() const; - /// HasComplexAddr - Return true if the variable has a complex address. - bool hasComplexAddress() const { return getNumAddrElements() > 0; } - - /// \brief Return the size of this variable's complex address or - /// zero if there is none. - unsigned getNumAddrElements() const { - if (DbgNode->getNumOperands() < 9) - return 0; - return getDescriptorField(8)->getNumOperands(); - } - - /// \brief return the Idx'th complex address element. - uint64_t getAddrElement(unsigned Idx) const; - /// isBlockByrefVariable - Return true if the variable was declared as /// a "__block" variable (Apple Blocks). bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const { @@ -725,6 +711,32 @@ /// information for an inlined function arguments. bool isInlinedFnArgument(const Function *CurFn); + /// Return the size reported by the variable's type. + unsigned getSizeInBits(const DITypeIdentifierMap &Map); + + void printExtendedName(raw_ostream &OS) const; +}; + +/// DIExpression - A complex location expression. +class DIExpression : public DIDescriptor { + friend class DIDescriptor; + void printInternal(raw_ostream &OS) const; + +public: + explicit DIExpression(const MDNode *N = nullptr) : DIDescriptor(N) {} + + /// Verify - Verify that a variable descriptor is well formed. + bool Verify() const; + + /// \brief Return the size of this variable's complex address or + /// zero if there is none. + unsigned getNumElements() const { + return DbgNode ? DbgNode->getNumOperands() : 0; + } + + /// \brief return the Idx'th complex address element. + uint64_t getElement(unsigned Idx) const; + /// isVariablePiece - Return whether this is a piece of an aggregate /// variable. bool isVariablePiece() const; @@ -732,11 +744,6 @@ uint64_t getPieceOffset() const; /// getPieceSize - Return the size of this piece in bytes. uint64_t getPieceSize() const; - - /// Return the size reported by the variable's type. - unsigned getSizeInBits(const DITypeIdentifierMap &Map); - - void printExtendedName(raw_ostream &OS) const; }; /// DILocation - This object holds location information. This object @@ -853,9 +860,6 @@ /// cleanseInlinedVariable - Remove inlined scope from the variable. DIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext); -/// getEntireVariable - Remove OpPiece exprs from the variable. -DIVariable getEntireVariable(DIVariable DV); - /// Construct DITypeIdentifierMap by going through retained types of each CU. DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes); Index: include/llvm/IR/IntrinsicInst.h =================================================================== --- include/llvm/IR/IntrinsicInst.h +++ include/llvm/IR/IntrinsicInst.h @@ -81,7 +81,8 @@ class DbgDeclareInst : public DbgInfoIntrinsic { public: Value *getAddress() const; - MDNode *getVariable() const { return cast(getArgOperand(1)); } + MDNode *getExpression() const { return cast(getArgOperand(1)); } + MDNode *getVariable() const { return cast(getArgOperand(2)); } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const IntrinsicInst *I) { @@ -102,7 +103,8 @@ return cast( const_cast(getArgOperand(1)))->getZExtValue(); } - MDNode *getVariable() const { return cast(getArgOperand(2)); } + MDNode *getExpression() const { return cast(getArgOperand(2)); } + MDNode *getVariable() const { return cast(getArgOperand(3)); } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const IntrinsicInst *I) { Index: include/llvm/IR/Intrinsics.td =================================================================== --- include/llvm/IR/Intrinsics.td +++ include/llvm/IR/Intrinsics.td @@ -373,9 +373,12 @@ // places. let Properties = [IntrNoMem] in { def int_dbg_declare : Intrinsic<[], - [llvm_metadata_ty, llvm_metadata_ty]>; + [llvm_metadata_ty, + llvm_metadata_ty, + llvm_metadata_ty]>; def int_dbg_value : Intrinsic<[], [llvm_metadata_ty, llvm_i64_ty, + llvm_metadata_ty, llvm_metadata_ty]>; } Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -608,24 +608,26 @@ /// 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; raw_svector_ostream OS(Str); OS << "DEBUG_VALUE: "; - DIVariable V(MI->getOperand(2).getMetadata()); + DIVariable V = MI->getDebugVariable(); if (V.getContext().isSubprogram()) { StringRef Name = DISubprogram(V.getContext()).getDisplayName(); if (!Name.empty()) OS << Name << ":"; } OS << V.getName(); - if (V.isVariablePiece()) - OS << " [piece offset=" << V.getPieceOffset() - << " size="<getDebugExpression(); + if (Expr.isVariablePiece()) + OS << " [piece offset=" << Expr.getPieceOffset() + << " size="<isIdenticalTo(&MI)) { @@ -193,7 +193,7 @@ // 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); Index: lib/CodeGen/AsmPrinter/DebugLocEntry.h =================================================================== --- lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -26,22 +26,25 @@ public: /// A single location or constant. struct Value { - Value(const MDNode *Var, int64_t i) - : Variable(Var), EntryKind(E_Integer) { + Value(const MDNode *Expr, const MDNode *Var, int64_t i) + : Expression(Expr), Variable(Var), EntryKind(E_Integer) { Constant.Int = i; } - Value(const MDNode *Var, const ConstantFP *CFP) - : Variable(Var), EntryKind(E_ConstantFP) { + Value(const MDNode *Expr, const MDNode *Var, const ConstantFP *CFP) + : Expression(Expr), Variable(Var), EntryKind(E_ConstantFP) { Constant.CFP = CFP; } - Value(const MDNode *Var, const ConstantInt *CIP) - : Variable(Var), EntryKind(E_ConstantInt) { + Value(const MDNode *Expr, const MDNode *Var, const ConstantInt *CIP) + : Expression(Expr), Variable(Var), EntryKind(E_ConstantInt) { Constant.CIP = CIP; } - Value(const MDNode *Var, MachineLocation Loc) - : Variable(Var), EntryKind(E_Location), Loc(Loc) { + Value(const MDNode *Expr, const MDNode *Var, MachineLocation Loc) + : Expression(Expr), Variable(Var), EntryKind(E_Location), Loc(Loc) { } + // Any complex address location expression for this Value. + const MDNode *Expression; + // The variable to which this location entry corresponds. const MDNode *Variable; @@ -69,7 +72,8 @@ MachineLocation getLoc() const { return Loc; } const MDNode *getVariableNode() const { return Variable; } DIVariable getVariable() const { return DIVariable(Variable); } - bool isVariablePiece() const { return getVariable().isVariablePiece(); } + DIExpression getExpression() const { return DIExpression(Expression); } + bool isVariablePiece() const { return getExpression().isVariablePiece(); } friend bool operator==(const Value &, const Value &); friend bool operator<(const Value &, const Value &); }; @@ -90,11 +94,13 @@ // 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,7 +139,8 @@ 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(); + return A.getVariable() == B.getVariable() + && A.getExpression() == B.getExpression(); }), Values.end()); } }; @@ -144,7 +151,10 @@ 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 +173,7 @@ /// 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(); } } Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -69,6 +69,7 @@ //===----------------------------------------------------------------------===// /// \brief This class is used to track local variable information. class DbgVariable { + DIExpression Expr; // Complex address location expression. DIVariable Var; // Variable Descriptor. DIE *TheDIE; // Variable DIE. unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries. @@ -78,18 +79,20 @@ public: /// Construct a DbgVariable from a DIVariable. - DbgVariable(DIVariable V, DwarfDebug *DD) - : Var(V), TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(nullptr), + DbgVariable(DIExpression E, DIVariable V, DwarfDebug *DD) + : Expr(E), Var(V), TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(nullptr), FrameIndex(~0), DD(DD) {} /// Construct a DbgVariable from a DEBUG_VALUE. /// AbstractVar may be NULL. DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD) - : Var(DbgValue->getDebugVariable()), TheDIE(nullptr), + : Expr(DbgValue->getDebugExpression()), + Var(DbgValue->getDebugVariable()), 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 +127,14 @@ bool variableHasComplexAddress() const { assert(Var.isVariable() && "Invalid complex DbgVariable!"); - return Var.hasComplexAddress(); + return Expr; } 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: Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -876,7 +876,7 @@ for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { DIVariable DV(Variables.getElement(vi)); assert(DV.isVariable()); - DbgVariable NewVar(DV, this); + DbgVariable NewVar(DIExpression(nullptr), DV, this); auto VariableDie = SPCU->constructVariableDIE(NewVar); SPCU->applyVariableAttributes(NewVar, *VariableDie); SPDIE->addChild(std::move(VariableDie)); @@ -1099,7 +1099,7 @@ void DwarfDebug::createAbstractVariable(const DIVariable &Var, LexicalScope *Scope) { - auto AbsDbgVariable = make_unique(Var, this); + auto AbsDbgVariable = make_unique(DIExpression(), Var, this); addScopeVariable(Scope, AbsDbgVariable.get()); AbstractVariables[Var] = std::move(AbsDbgVariable); } @@ -1154,6 +1154,7 @@ if (!VI.Var) continue; Processed.insert(VI.Var); + DIExpression Expr(VI.Expr); DIVariable DV(VI.Var); LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc); @@ -1162,7 +1163,7 @@ continue; ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); - ConcreteVariables.push_back(make_unique(DV, this)); + ConcreteVariables.push_back(make_unique(Expr, DV, this)); DbgVariable *RegVar = ConcreteVariables.back().get(); RegVar->setFrameIndex(VI.Slot); addScopeVariable(Scope, RegVar); @@ -1171,9 +1172,10 @@ // 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 @@ -1182,20 +1184,20 @@ 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(Expr, Var, MLoc); } if (MI->getOperand(0).isImm()) - return DebugLocEntry::Value(Var, MI->getOperand(0).getImm()); + return DebugLocEntry::Value(Expr, Var, MI->getOperand(0).getImm()); if (MI->getOperand(0).isFPImm()) - return DebugLocEntry::Value(Var, MI->getOperand(0).getFPImm()); + return DebugLocEntry::Value(Expr, Var, MI->getOperand(0).getFPImm()); if (MI->getOperand(0).isCImm()) - return DebugLocEntry::Value(Var, MI->getOperand(0).getCImm()); + return DebugLocEntry::Value(Expr, Var, 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(); @@ -1246,10 +1248,10 @@ } // 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()); @@ -1272,7 +1274,7 @@ 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); @@ -1298,9 +1300,11 @@ if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry)) DebugLoc.pop_back(); - DEBUG(dbgs() << "Values:\n"; - for (auto Value : CurEntry->getValues()) + DEBUG(dbgs() << CurEntry->getValues().size() << " Values:\n"; + for (auto Value : CurEntry->getValues()) { Value.getVariable()->dump(); + Value.getExpression()->dump(); + } dbgs() << "-----\n"); } } @@ -1336,7 +1340,7 @@ 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()); @@ -1370,7 +1374,8 @@ continue; if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) { ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode()); - ConcreteVariables.push_back(make_unique(DV, this)); + DIExpression NoExpr; + ConcreteVariables.push_back(make_unique(NoExpr, DV, this)); addScopeVariable(Scope, ConcreteVariables.back().get()); } } @@ -1558,18 +1563,17 @@ // 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()) + DIVariable DIVar(Ranges.front().first->getDebugVariable()); + if (DIVar.isVariable() && DIVar.getTag() == dwarf::DW_TAG_arg_variable && + getDISubprogram(DIVar.getContext()).describes(MF->getFunction())) { + if (Ranges.front().first->getDebugExpression().isVariablePiece()) { LabelsBeforeInsn[Ranges.front().first] = FunctionBeginSym; - else { // 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()); + return !piecesOverlap(Piece, Pred.first->getDebugExpression()); })) LabelsBeforeInsn[I->first] = FunctionBeginSym; else @@ -2071,9 +2075,9 @@ 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. @@ -2084,8 +2088,9 @@ 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"); @@ -2131,24 +2136,25 @@ } } 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) == DIBuilder::OpPlus) { 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; } @@ -2158,10 +2164,10 @@ // Emit remaining complex address elements. for (; i < N; ++i) { - uint64_t Element = DV.getAddrElement(i); + uint64_t Element = Expr.getElement(i); if (Element == DIBuilder::OpPlus) { Streamer.EmitInt8(dwarf::DW_OP_plus_uconst, "DW_OP_plus_uconst"); - Streamer.EmitULEB128(DV.getAddrElement(++i)); + Streamer.EmitULEB128(Expr.getElement(++i)); } else if (Element == DIBuilder::OpDeref) { if (!Loc.isReg()) Streamer.EmitInt8(dwarf::DW_OP_deref, "DW_OP_deref"); Index: lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -611,8 +611,8 @@ i = 2; } else if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpDeref) { addRegisterOpPiece(*Loc, Location.getReg(), - DV.getVariable().getPieceSize(), - DV.getVariable().getPieceOffset()); + DV.getExpression().getPieceSize(), + DV.getExpression().getPieceOffset()); i = 3; } else addRegisterOpPiece(*Loc, Location.getReg()); @@ -1853,7 +1853,7 @@ // 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. Index: lib/CodeGen/InlineSpiller.cpp =================================================================== --- lib/CodeGen/InlineSpiller.cpp +++ lib/CodeGen/InlineSpiller.cpp @@ -1213,12 +1213,14 @@ // 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 *Expr = MI->getDebugExpression(); + const MDNode *Var = MI->getDebugVariable(); 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(Expr).addMetadata(Var); continue; } Index: lib/CodeGen/LiveDebugVariables.cpp =================================================================== --- lib/CodeGen/LiveDebugVariables.cpp +++ lib/CodeGen/LiveDebugVariables.cpp @@ -111,6 +111,7 @@ class LDVImpl; class UserValue { const MDNode *variable; ///< The debug info variable we are part of. + const MDNode *expr; ///< 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,9 +141,10 @@ public: /// UserValue - Create a new UserValue. - UserValue(const MDNode *var, unsigned o, bool i, DebugLoc L, + UserValue(const MDNode *var, const MDNode *expr, + unsigned o, bool i, DebugLoc L, LocMap::Allocator &alloc) - : variable(var), offset(o), IsIndirect(i), dl(L), leader(this), + : variable(var), expr(expr), offset(o), IsIndirect(i), dl(L), leader(this), next(nullptr), locInts(alloc) {} @@ -158,8 +160,10 @@ 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 == expr + && Offset == offset && indirect == IsIndirect; } /// merge - Merge equivalence classes. @@ -307,8 +311,8 @@ 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); @@ -422,19 +426,19 @@ 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(Var, Offset, IsIndirect, DL, allocator)); + make_unique(Var, Expr, Offset, IsIndirect, DL, allocator)); UserValue *UV = userValues.back().get(); Leader = UserValue::merge(Leader, UV); return UV; @@ -454,7 +458,7 @@ 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 +468,10 @@ // 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 *Expr = MI->getOperand(2).getMetadata(); + const MDNode *Var = MI->getOperand(3).getMetadata(); //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,10 @@ if (Loc.isReg()) BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE), - IsIndirect, Loc.getReg(), offset, variable); + IsIndirect, Loc.getReg(), offset, expr, variable); else BuildMI(*MBB, I, findDebugLoc(), TII.get(TargetOpcode::DBG_VALUE)) - .addOperand(Loc).addImm(offset).addMetadata(variable); + .addOperand(Loc).addImm(offset).addMetadata(expr).addMetadata(variable); } void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS, Index: lib/CodeGen/RegAllocFast.cpp =================================================================== --- lib/CodeGen/RegAllocFast.cpp +++ lib/CodeGen/RegAllocFast.cpp @@ -299,7 +299,8 @@ 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 *Expr = DBG->getDebugExpression(); + const MDNode *Var = DBG->getDebugVariable(); bool IsIndirect = DBG->isIndirectDebugValue(); uint64_t Offset = IsIndirect ? DBG->getOperand(1).getImm() : 0; DebugLoc DL; @@ -312,7 +313,7 @@ MachineBasicBlock *MBB = DBG->getParent(); MachineInstr *NewDV = BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::DBG_VALUE)) - .addFrameIndex(FI).addImm(Offset).addMetadata(MDPtr); + .addFrameIndex(FI).addImm(Offset).addMetadata(Expr).addMetadata(Var); (void)NewDV; DEBUG(dbgs() << "Inserting debug info due to spill:" << "\n" << *NewDV); } @@ -863,13 +864,14 @@ // 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 *Expr = MI->getDebugExpression(); + const MDNode *Var = MI->getDebugVariable(); 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(Expr).addMetadata(Var); DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *NewDV); // Scan NewDV operands from the beginning. Index: lib/CodeGen/SelectionDAG/FastISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/FastISel.cpp +++ lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1138,12 +1138,13 @@ Op->setIsDebug(true); BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::DBG_VALUE), false, Op->getReg(), 0, - DI->getVariable()); + DI->getExpression(), DI->getVariable()); } else BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TargetOpcode::DBG_VALUE)) .addOperand(*Op) .addImm(0) + .addMetadata(DI->getExpression()) .addMetadata(DI->getVariable()); } else { // We can't yet handle anything else here because it would require @@ -1162,25 +1163,29 @@ // help debugging. Probably the optimizer should not do this. BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II) .addReg(0U).addImm(DI->getOffset()) + .addMetadata(DI->getExpression()) .addMetadata(DI->getVariable()); } else if (const ConstantInt *CI = dyn_cast(V)) { if (CI->getBitWidth() > 64) BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II) .addCImm(CI).addImm(DI->getOffset()) + .addMetadata(DI->getExpression()) .addMetadata(DI->getVariable()); else BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II) .addImm(CI->getZExtValue()).addImm(DI->getOffset()) + .addMetadata(DI->getExpression()) .addMetadata(DI->getVariable()); } else if (const ConstantFP *CF = dyn_cast(V)) { BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, II) .addFPImm(CF).addImm(DI->getOffset()) + .addMetadata(DI->getExpression()) .addMetadata(DI->getVariable()); } 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()); + Reg, DI->getOffset(), DI->getExpression(), DI->getVariable()); } else { // We can't yet handle anything else here because it would require // generating code, thus altering codegen because of debug info. Index: lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp =================================================================== --- lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp +++ lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp @@ -168,7 +168,8 @@ StaticAllocaMap.find(AI); if (SI != StaticAllocaMap.end()) { // Check for VLAs. int FI = SI->second; - MMI.setVariableDbgInfo(DI->getVariable(), + MMI.setVariableDbgInfo(DI->getExpression(), + DI->getVariable(), FI, DI->getDebugLoc()); } } Index: lib/CodeGen/SelectionDAG/InstrEmitter.cpp =================================================================== --- lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -649,14 +649,16 @@ InstrEmitter::EmitDbgValue(SDDbgValue *SD, DenseMap &VRBaseMap) { uint64_t Offset = SD->getOffset(); - MDNode* MDPtr = SD->getMDPtr(); + MDNode* Expr = SD->getExpression(); + MDNode* Var = SD->getVariable(); 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(Expr).addMetadata(Var); } // Otherwise, we're going to create an instruction here. const MCInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE); @@ -702,7 +704,8 @@ MIB.addReg(0U, RegState::Debug); } - MIB.addMetadata(MDPtr); + MIB.addMetadata(Expr); + MIB.addMetadata(Var); return &*MIB; } Index: lib/CodeGen/SelectionDAG/SDNodeDbgValue.h =================================================================== --- lib/CodeGen/SelectionDAG/SDNodeDbgValue.h +++ lib/CodeGen/SelectionDAG/SDNodeDbgValue.h @@ -44,7 +44,8 @@ const Value *Const; // valid for constants unsigned FrameIx; // valid for stack objects } u; - MDNode *mdPtr; + MDNode *Expr; + MDNode *Var; bool IsIndirect; uint64_t Offset; DebugLoc DL; @@ -52,9 +53,9 @@ bool Invalid; public: // Constructor for non-constants. - SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, + SDDbgValue(MDNode *Expr, MDNode *Var, SDNode *N, unsigned R, bool indir, uint64_t off, DebugLoc dl, - unsigned O) : mdPtr(mdP), IsIndirect(indir), + unsigned O) : Expr(Expr), Var(Var), IsIndirect(indir), Offset(off), DL(dl), Order(O), Invalid(false) { kind = SDNODE; @@ -63,17 +64,18 @@ } // Constructor for constants. - SDDbgValue(MDNode *mdP, const Value *C, uint64_t off, DebugLoc dl, + SDDbgValue(MDNode *Expr, MDNode *Var, const Value *C, uint64_t off, DebugLoc dl, unsigned O) : - mdPtr(mdP), IsIndirect(false), Offset(off), DL(dl), Order(O), + Expr(Expr), Var(Var), 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), + SDDbgValue(MDNode *Expr, MDNode *Var, + unsigned FI, uint64_t off, DebugLoc dl, unsigned O) : + Expr(Expr), Var(Var), IsIndirect(false), Offset(off), DL(dl), Order(O), Invalid(false) { kind = FRAMEIX; u.FrameIx = FI; @@ -82,8 +84,11 @@ // Returns the kind. DbgValueKind getKind() { return kind; } - // Returns the MDNode pointer. - MDNode *getMDPtr() { return mdPtr; } + // Returns the MDNode pointer for the expression. + MDNode *getExpression() { return Expr; } + + // Returns the MDNode pointer for the variable. + MDNode *getVariable() { return Var; } // Returns the SDNode* for a register ref SDNode *getSDNode() { assert (kind==SDNODE); return u.s.Node; } Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -5776,25 +5776,26 @@ /// /// SDNode SDDbgValue * -SelectionDAG::getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R, +SelectionDAG::getDbgValue(MDNode *Expr, MDNode *Var, SDNode *N, unsigned R, bool IsIndirect, uint64_t Off, DebugLoc DL, unsigned O) { - return new (Allocator) SDDbgValue(MDPtr, N, R, IsIndirect, Off, DL, O); + return new (Allocator) SDDbgValue(Expr, Var, N, R, IsIndirect, Off, DL, O); } /// Constant SDDbgValue * -SelectionDAG::getConstantDbgValue(MDNode *MDPtr, const Value *C, +SelectionDAG::getConstantDbgValue(MDNode *Expr, MDNode *Var, const Value *C, uint64_t Off, DebugLoc DL, unsigned O) { - return new (Allocator) SDDbgValue(MDPtr, C, Off, DL, O); + return new (Allocator) SDDbgValue(Expr, Var, C, Off, DL, O); } /// FrameIndex SDDbgValue * -SelectionDAG::getFrameIndexDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off, +SelectionDAG::getFrameIndexDbgValue(MDNode *Expr, MDNode *Var, + unsigned FI, uint64_t Off, DebugLoc DL, unsigned O) { - return new (Allocator) SDDbgValue(MDPtr, FI, Off, DL, O); + return new (Allocator) SDDbgValue(Expr, Var, FI, Off, DL, O); } namespace { @@ -6200,7 +6201,8 @@ I != E; ++I) { SDDbgValue *Dbg = *I; if (Dbg->getKind() == SDDbgValue::SDNODE) { - SDDbgValue *Clone = getDbgValue(Dbg->getMDPtr(), ToNode, To.getResNo(), + SDDbgValue *Clone = getDbgValue(Dbg->getExpression(), Dbg->getVariable(), + ToNode, To.getResNo(), Dbg->isIndirect(), Dbg->getOffset(), Dbg->getDebugLoc(), Dbg->getOrder()); Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -791,7 +791,8 @@ /// 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 *Expr, MDNode *Variable, int64_t Offset, bool IsIndirect, const SDValue &N); }; Index: lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -988,14 +988,15 @@ const DbgValueInst *DI = DDI.getDI(); DebugLoc dl = DDI.getdl(); unsigned DbgSDNodeOrder = DDI.getSDNodeOrder(); + MDNode *Expr = DI->getExpression(); MDNode *Variable = DI->getVariable(); uint64_t Offset = DI->getOffset(); // A dbg.value for an alloca is always indirect. bool IsIndirect = isa(V) || Offset != 0; SDDbgValue *SDV; if (Val.getNode()) { - if (!EmitFuncArgumentDbgValue(V, Variable, Offset, IsIndirect, Val)) { - SDV = DAG.getDbgValue(Variable, Val.getNode(), + if (!EmitFuncArgumentDbgValue(V, Expr, Variable, Offset, IsIndirect, Val)) { + SDV = DAG.getDbgValue(Expr, Variable, Val.getNode(), Val.getResNo(), IsIndirect, Offset, dl, DbgSDNodeOrder); DAG.AddDbgValue(SDV, Val.getNode(), false); @@ -4595,7 +4596,8 @@ /// 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, +SelectionDAGBuilder::EmitFuncArgumentDbgValue(const Value *V, MDNode *Expr, + MDNode *Variable, int64_t Offset, bool IsIndirect, const SDValue &N) { const Argument *Arg = dyn_cast(V); @@ -4652,11 +4654,12 @@ FuncInfo.ArgDbgValues.push_back(BuildMI(MF, getCurDebugLoc(), TII->get(TargetOpcode::DBG_VALUE), IsIndirect, - Op->getReg(), Offset, Variable)); + Op->getReg(), Offset, + Expr, Variable)); else FuncInfo.ArgDbgValues.push_back( BuildMI(MF, getCurDebugLoc(), TII->get(TargetOpcode::DBG_VALUE)) - .addOperand(*Op).addImm(Offset).addMetadata(Variable)); + .addOperand(*Op).addImm(Offset).addMetadata(Expr).addMetadata(Variable)); return true; } @@ -4775,6 +4778,7 @@ } case Intrinsic::dbg_declare: { const DbgDeclareInst &DI = cast(I); + MDNode *Expression = DI.getExpression(); MDNode *Variable = DI.getVariable(); const Value *Address = DI.getAddress(); DIVariable DIVar(Variable); @@ -4811,16 +4815,17 @@ FrameIndexSDNode *FINode = dyn_cast(N.getNode()); if (FINode) // Byval parameter. We have a frame index at this point. - SDV = DAG.getFrameIndexDbgValue(Variable, FINode->getIndex(), + SDV = DAG.getFrameIndexDbgValue(Expression, Variable, + 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, Expression, Variable, 0, false, N); return nullptr; } } else if (AI) - SDV = DAG.getDbgValue(Variable, N.getNode(), N.getResNo(), + SDV = DAG.getDbgValue(Expression, Variable, N.getNode(), N.getResNo(), true, 0, dl, SDNodeOrder); else { // Can't do anything with other non-AI cases yet. @@ -4833,7 +4838,7 @@ } 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, Expression, Variable, 0, false, N)) { // If variable is pinned by a alloca in dominating bb then // use StaticAllocaMap. if (const AllocaInst *AI = dyn_cast(Address)) { @@ -4841,7 +4846,7 @@ DenseMap::iterator SI = FuncInfo.StaticAllocaMap.find(AI); if (SI != FuncInfo.StaticAllocaMap.end()) { - SDV = DAG.getFrameIndexDbgValue(Variable, SI->second, + SDV = DAG.getFrameIndexDbgValue(Expression, Variable, SI->second, 0, dl, SDNodeOrder); DAG.AddDbgValue(SDV, nullptr, false); return nullptr; @@ -4861,6 +4866,7 @@ if (!DIVar) return nullptr; + MDNode *Expression = DI.getExpression(); MDNode *Variable = DI.getVariable(); uint64_t Offset = DI.getOffset(); const Value *V = DI.getValue(); @@ -4869,7 +4875,7 @@ SDDbgValue *SDV; if (isa(V) || isa(V) || isa(V)) { - SDV = DAG.getConstantDbgValue(Variable, V, Offset, dl, SDNodeOrder); + SDV = DAG.getConstantDbgValue(Expression, Variable, V, Offset, dl, SDNodeOrder); DAG.AddDbgValue(SDV, nullptr, false); } else { // Do not use getValue() in here; we don't want to generate code at @@ -4881,8 +4887,8 @@ if (N.getNode()) { // A dbg.value for an alloca is always indirect. bool IsIndirect = isa(V) || Offset != 0; - if (!EmitFuncArgumentDbgValue(V, Variable, Offset, IsIndirect, N)) { - SDV = DAG.getDbgValue(Variable, N.getNode(), + if (!EmitFuncArgumentDbgValue(V, Expression, Variable, Offset, IsIndirect, N)) { + SDV = DAG.getDbgValue(Expression, Variable, N.getNode(), N.getResNo(), IsIndirect, Offset, dl, SDNodeOrder); DAG.AddDbgValue(SDV, N.getNode(), false); Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -489,15 +489,15 @@ "- 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); + IsIndirect, LDI->second, Offset, + Expr, Variable); // If this vreg is directly copied into an exported register then // that COPY instructions also need DBG_VALUE, if it is the only @@ -520,7 +520,7 @@ TII.get(TargetOpcode::DBG_VALUE), IsIndirect, CopyUseMI->getOperand(0).getReg(), - Offset, Variable); + Offset, Expr, Variable); MachineBasicBlock::iterator Pos = CopyUseMI; EntryMBB->insertAfter(Pos, NewMI); } Index: lib/IR/DIBuilder.cpp =================================================================== --- lib/IR/DIBuilder.cpp +++ lib/IR/DIBuilder.cpp @@ -1076,35 +1076,22 @@ 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 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 Addr) { + return DIExpression(MDNode::get(VMContext, Addr)); +} + +/// createExpression - Create an empty DIExpression. +DIExpression DIBuilder::createExpression() { + return DIExpression(MDNode::get(VMContext, ArrayRef())); } /// 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), @@ -1112,14 +1099,7 @@ ConstantInt::get(Type::getInt32Ty(VMContext), SizeInBytes) }; - assert((Variable->getNumOperands() == 8 || Variable.isVariablePiece()) && - "variable already has a complex address"); - SmallVector Elts; - for (unsigned i = 0; i < 8; ++i) - Elts.push_back(Variable->getOperand(i)); - - 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. @@ -1290,7 +1270,8 @@ } /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. -Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, +Instruction *DIBuilder::insertDeclare(Value *Storage, + DIExpression Expr, DIVariable VarInfo, Instruction *InsertBefore) { assert(Storage && "no storage passed to dbg.declare"); assert(VarInfo.isVariable() && @@ -1298,12 +1279,14 @@ if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Args[] = { MDNode::get(Storage->getContext(), Storage), VarInfo }; + Value *Args[] = { MDNode::get(Storage->getContext(), Storage), + Expr, VarInfo }; return CallInst::Create(DeclareFn, Args, "", InsertBefore); } /// insertDeclare - Insert a new llvm.dbg.declare intrinsic call. -Instruction *DIBuilder::insertDeclare(Value *Storage, DIVariable VarInfo, +Instruction *DIBuilder::insertDeclare(Value *Storage, + DIExpression Expr, DIVariable VarInfo, BasicBlock *InsertAtEnd) { assert(Storage && "no storage passed to dbg.declare"); assert(VarInfo.isVariable() && @@ -1311,7 +1294,8 @@ if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Args[] = { MDNode::get(Storage->getContext(), Storage), VarInfo }; + Value *Args[] = { MDNode::get(Storage->getContext(), Storage), + Expr, VarInfo }; // If this block already has a terminator then insert this intrinsic // before the terminator. @@ -1323,6 +1307,7 @@ /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, + DIExpression Expr, DIVariable VarInfo, Instruction *InsertBefore) { assert(V && "no value passed to dbg.value"); @@ -1333,12 +1318,13 @@ Value *Args[] = { MDNode::get(V->getContext(), V), ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), - VarInfo }; + Expr, VarInfo }; return CallInst::Create(ValueFn, Args, "", InsertBefore); } /// insertDbgValueIntrinsic - Insert a new llvm.dbg.value intrinsic call. Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, + DIExpression Expr, DIVariable VarInfo, BasicBlock *InsertAtEnd) { assert(V && "no value passed to dbg.value"); @@ -1349,6 +1335,6 @@ Value *Args[] = { MDNode::get(V->getContext(), V), ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), - VarInfo }; + Expr, VarInfo }; return CallInst::Create(ValueFn, Args, "", InsertAtEnd); } Index: lib/IR/DebugInfo.cpp =================================================================== --- lib/IR/DebugInfo.cpp +++ lib/IR/DebugInfo.cpp @@ -138,33 +138,9 @@ } } -uint64_t DIVariable::getAddrElement(unsigned Idx) const { - DIDescriptor ComplexExpr = getDescriptorField(8); - if (Idx < ComplexExpr->getNumOperands()) - if (auto *CI = dyn_cast_or_null(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,7 +154,28 @@ return Ty.getSizeInBits(); } +uint64_t DIExpression::getElement(unsigned Idx) const { + if (Idx < DbgNode->getNumOperands()) + if (auto *CI = dyn_cast_or_null(DbgNode->getOperand(Idx))) + return CI->getZExtValue(); + assert(false && "non-existing complex address element requested"); + return 0; +} + +bool DIExpression::isVariablePiece() const { + return getNumElements() && getElement(0) == DIBuilder::OpPiece; +} + +uint64_t DIExpression::getPieceOffset() const { + assert(isVariablePiece()); + return getElement(1); +} + +uint64_t DIExpression::getPieceSize() const { + assert(isVariablePiece()); + return getElement(2); +} //===----------------------------------------------------------------------===// @@ -935,19 +932,6 @@ return DIVariable(MDNode::get(VMContext, Elts)); } - -/// getEntireVariable - Remove OpPiece exprs from the variable. -DIVariable llvm::getEntireVariable(DIVariable DV) { - if (!DV.isVariablePiece()) - return DV; - - SmallVector 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); @@ -1437,6 +1421,10 @@ OS << " [" << Res << ']'; OS << " [line " << getLineNumber() << ']'; +} + +void DIExpression::printInternal(raw_ostream &OS) const { + OS << " [complex location expr]"; if (isVariablePiece()) OS << " [piece, size " << getPieceSize() Index: lib/Target/AArch64/AArch64InstrInfo.h =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.h +++ lib/Target/AArch64/AArch64InstrInfo.h @@ -99,8 +99,8 @@ MachineInstr *Second) const override; MachineInstr *emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, - uint64_t Offset, const MDNode *MDPtr, - DebugLoc DL) const; + uint64_t Offset, const MDNode *Expr, + const MDNode *Var, DebugLoc DL) const; void copyPhysRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc, unsigned Opcode, Index: lib/Target/AArch64/AArch64InstrInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.cpp +++ lib/Target/AArch64/AArch64InstrInfo.cpp @@ -1315,13 +1315,15 @@ MachineInstr *AArch64InstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, int FrameIx, uint64_t Offset, - const MDNode *MDPtr, + const MDNode *Expr, + const MDNode *Var, DebugLoc DL) const { MachineInstrBuilder MIB = BuildMI(MF, DL, get(AArch64::DBG_VALUE)) .addFrameIndex(FrameIx) .addImm(0) .addImm(Offset) - .addMetadata(MDPtr); + .addMetadata(Expr) + .addMetadata(Var); return &*MIB; } Index: lib/Target/X86/X86FastISel.cpp =================================================================== --- lib/Target/X86/X86FastISel.cpp +++ lib/Target/X86/X86FastISel.cpp @@ -2287,7 +2287,7 @@ // 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()); + addImm(0).addMetadata(DI->getExpression()).addMetadata(DI->getVariable()); return true; } case Intrinsic::trap: { Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -890,8 +890,10 @@ continue; } Instruction *DbgVal = - DIB.insertDbgValueIntrinsic(Arg, 0, DIVariable(DVI->getVariable()), - Inst); + DIB.insertDbgValueIntrinsic(Arg, 0, + DIExpression(DVI->getExpression()), + DIVariable(DVI->getVariable()), + Inst); DbgVal->setDebugLoc(DVI->getDebugLoc()); } } Index: lib/Transforms/Scalar/ScalarReplAggregates.cpp =================================================================== --- lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1120,7 +1120,8 @@ continue; } Instruction *DbgVal = - DIB->insertDbgValueIntrinsic(Arg, 0, DIVariable(DVI->getVariable()), + DIB->insertDbgValueIntrinsic(Arg, 0, DIExpression(DVI->getExpression()), + DIVariable(DVI->getVariable()), Inst); DbgVal->setDebugLoc(DVI->getDebugLoc()); } Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -989,6 +989,7 @@ /// that has an associated llvm.dbg.decl intrinsic. bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, StoreInst *SI, DIBuilder &Builder) { + DIExpression DIExpr(DDI->getExpression()); DIVariable DIVar(DDI->getVariable()); assert((!DIVar || DIVar.isVariable()) && "Variable in DbgDeclareInst should be either null or a DIVariable."); @@ -1007,9 +1008,10 @@ if (SExtInst *SExt = dyn_cast(SI->getOperand(0))) ExtendedArg = dyn_cast(SExt->getOperand(0)); if (ExtendedArg) - DbgVal = Builder.insertDbgValueIntrinsic(ExtendedArg, 0, DIVar, SI); + DbgVal = Builder.insertDbgValueIntrinsic(ExtendedArg, 0, DIExpr, DIVar, SI); else - DbgVal = Builder.insertDbgValueIntrinsic(SI->getOperand(0), 0, DIVar, SI); + DbgVal = Builder.insertDbgValueIntrinsic(SI->getOperand(0), 0, DIExpr, + DIVar, SI); DbgVal->setDebugLoc(DDI->getDebugLoc()); return true; } @@ -1018,6 +1020,7 @@ /// that has an associated llvm.dbg.decl intrinsic. bool llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI, LoadInst *LI, DIBuilder &Builder) { + DIExpression DIExpr(DDI->getExpression()); DIVariable DIVar(DDI->getVariable()); assert((!DIVar || DIVar.isVariable()) && "Variable in DbgDeclareInst should be either null or a DIVariable."); @@ -1028,7 +1031,7 @@ return true; Instruction *DbgVal = - Builder.insertDbgValueIntrinsic(LI->getOperand(0), 0, + Builder.insertDbgValueIntrinsic(LI->getOperand(0), 0, DIExpr, DIVar, LI); DbgVal->setDebugLoc(DDI->getDebugLoc()); return true; @@ -1074,6 +1077,7 @@ // intrinsic that describes the alloca. auto DbgVal = DIB.insertDbgValueIntrinsic(AI, 0, + DIExpression(DDI->getExpression()), DIVariable(DDI->getVariable()), CI); DbgVal->setDebugLoc(DDI->getDebugLoc()); } @@ -1099,6 +1103,7 @@ DbgDeclareInst *DDI = FindAllocaDbgDeclare(AI); if (!DDI) return false; + DIExpression DIExpr(DDI->getExpression()); DIVariable DIVar(DDI->getVariable()); assert((!DIVar || DIVar.isVariable()) && "Variable in DbgDeclareInst should be either null or a DIVariable."); @@ -1110,23 +1115,20 @@ // will take a value storing address of the memory for variable, not // alloca itself. Type *Int64Ty = Type::getInt64Ty(AI->getContext()); - SmallVector NewDIVarAddress; - if (DIVar.hasComplexAddress()) { - for (unsigned i = 0, n = DIVar.getNumAddrElements(); i < n; ++i) { - NewDIVarAddress.push_back( - ConstantInt::get(Int64Ty, DIVar.getAddrElement(i))); + SmallVector 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, DIBuilder::OpDeref)); // 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, + Builder.createExpression(NewDIExpr), + DIVar, BB); DDI->eraseFromParent(); return true; } Index: tools/clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- tools/clang/lib/CodeGen/CGDebugInfo.cpp +++ tools/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2788,14 +2788,13 @@ // Create the descriptor for the variable. llvm::DIVariable D = - DBuilder.createComplexVariable(Tag, - llvm::DIDescriptor(Scope), - VD->getName(), Unit, Line, Ty, - addr, ArgNo); + DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope), + VD->getName(), Unit, Line, Ty, ArgNo); // Insert an llvm.dbg.declare into the current block. llvm::Instruction *Call = - DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock()); + DBuilder.insertDeclare(Storage, DBuilder.createExpression(addr), D, + Builder.GetInsertBlock()); Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope)); return; } else if (isa(VD->getType())) @@ -2822,7 +2821,8 @@ // Insert an llvm.dbg.declare into the current block. llvm::Instruction *Call = - DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock()); + DBuilder.insertDeclare(Storage, DBuilder.createExpression(), D, + Builder.GetInsertBlock()); Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope)); } return; @@ -2837,7 +2837,8 @@ // Insert an llvm.dbg.declare into the current block. llvm::Instruction *Call = - DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock()); + DBuilder.insertDeclare(Storage, DBuilder.createExpression(), D, + Builder.GetInsertBlock()); Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope)); } @@ -2918,13 +2919,14 @@ // Create the descriptor for the variable. llvm::DIVariable D = - DBuilder.createComplexVariable(llvm::dwarf::DW_TAG_auto_variable, - llvm::DIDescriptor(LexicalBlockStack.back()), - VD->getName(), Unit, Line, Ty, addr); + DBuilder.createLocalVariable(llvm::dwarf::DW_TAG_auto_variable, + llvm::DIDescriptor(LexicalBlockStack.back()), + VD->getName(), Unit, Line, Ty); // Insert an llvm.dbg.declare into the current block. llvm::Instruction *Call = - DBuilder.insertDeclare(Storage, D, Builder.GetInsertPoint()); + DBuilder.insertDeclare(Storage, DBuilder.createExpression(addr), D, + Builder.GetInsertPoint()); Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back())); } @@ -3087,14 +3089,15 @@ if (LocalAddr) { // Insert an llvm.dbg.value into the current block. llvm::Instruction *DbgVal = - DBuilder.insertDbgValueIntrinsic(LocalAddr, 0, debugVar, - Builder.GetInsertBlock()); + DBuilder.insertDbgValueIntrinsic(LocalAddr, 0, DBuilder.createExpression(), + debugVar, Builder.GetInsertBlock()); DbgVal->setDebugLoc(llvm::DebugLoc::get(line, column, scope)); } // Insert an llvm.dbg.declare into the current block. llvm::Instruction *DbgDecl = - DBuilder.insertDeclare(Arg, debugVar, Builder.GetInsertBlock()); + DBuilder.insertDeclare(Arg, DBuilder.createExpression(), debugVar, + Builder.GetInsertBlock()); DbgDecl->setDebugLoc(llvm::DebugLoc::get(line, column, scope)); } Index: unittests/Transforms/Utils/Cloning.cpp =================================================================== --- unittests/Transforms/Utils/Cloning.cpp +++ unittests/Transforms/Utils/Cloning.cpp @@ -255,10 +255,11 @@ // Create a local variable around the alloca DIType IntType = DBuilder.createBasicType("int", 32, 0, dwarf::DW_ATE_signed); + DIExpression E = DBuilder.createExpression(); DIVariable Variable = DBuilder.createLocalVariable( dwarf::DW_TAG_auto_variable, Subprogram, "x", File, 5, IntType, true); - DBuilder.insertDeclare(Alloca, Variable, Store); - DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, Variable, Terminator); + DBuilder.insertDeclare(Alloca, E, Variable, Store); + DBuilder.insertDbgValueIntrinsic(AllocaContent, 0, E, Variable, Terminator); // Finalize the debug info DBuilder.finalize();