diff options
| author | Adrian Prantl <aprantl@apple.com> | 2014-10-01 17:55:39 +0000 |
|---|---|---|
| committer | Adrian Prantl <aprantl@apple.com> | 2014-10-01 17:55:39 +0000 |
| commit | 25a7174e7a2ef0267486170570380a4dc2d0dd32 (patch) | |
| tree | 5ee77fa5bc3d02a48871c8e348970ebfa5ef73bc /llvm/lib/CodeGen/AsmPrinter | |
| parent | 1400aaf8c82d439d5ca322519b29ff12b19338d3 (diff) | |
| download | bcm5719-llvm-25a7174e7a2ef0267486170570380a4dc2d0dd32.tar.gz bcm5719-llvm-25a7174e7a2ef0267486170570380a4dc2d0dd32.zip | |
Move the complex address expression out of DIVariable and into an extra
argument of the llvm.dbg.declare/llvm.dbg.value intrinsics.
Previously, DIVariable was a variable-length field that has an optional
reference to a Metadata array consisting of a variable number of
complex address expressions. In the case of OpPiece expressions this is
wasting a lot of storage in IR, because when an aggregate type is, e.g.,
SROA'd into all of its n individual members, the IR will contain n copies
of the DIVariable, all alike, only differing in the complex address
reference at the end.
By making the complex address into an extra argument of the
dbg.value/dbg.declare intrinsics, all of the pieces can reference the
same variable and the complex address expressions can be uniqued across
the CU, too.
Down the road, this will allow us to move other flags, such as
"indirection" out of the DIVariable, too.
The new intrinsics look like this:
declare void @llvm.dbg.declare(metadata %storage, metadata %var, metadata %expr)
declare void @llvm.dbg.value(metadata %storage, i64 %offset, metadata %var, metadata %expr)
This patch adds a new LLVM-local tag to DIExpressions, so we can detect
and pretty-print DIExpression metadata nodes.
What this patch doesn't do:
This patch does not touch the "Indirect" field in DIVariable; but moving
that into the expression would be a natural next step.
http://reviews.llvm.org/D4919
rdar://problem/17994491
Thanks to dblaikie and dexonsmith for reviewing this patch!
llvm-svn: 218778
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 12 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h | 46 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 94 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 21 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 24 |
6 files changed, 118 insertions, 85 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. |

