llvm.org GIT mirror llvm / 01a8dc8
AsmPrinter: Rewrite initialization of DbgVariable, NFC There are three types of `DbgVariable`: - alloca variables, created based on the MMI table, - register variables, created based on DBG_VALUE instructions, and - optimized-out variables. This commit reconfigures `DbgVariable` to make it easier to tell which kind we have, and make initialization a little clearer. For MMI/alloca variables, `FrameIndex.size()` must always equal `Expr.size()`, and there shouldn't be an `MInsn`. For register variables (with a `MInsn`), `FrameIndex` must be empty, and `Expr` should have 0 or 1 element depending on whether it has a complex expression (registers with multiple locations use `DebugLocListIndex`). Optimized-out variables shouldn't have any of these fields. Moreover, this separates DBG_VALUE initialization until after the variable is created, simplifying logic in a future commit that changes `collectVariableInfo()` to stop creating empty .debug_loc entries/lists. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240243 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 5 years ago
3 changed file(s) with 87 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
507507 }
508508
509509 // .. else use frame index.
510 if (DV.getFrameIndex().back() == ~0)
510 if (DV.getFrameIndex().empty())
511511 return VariableDie;
512512
513513 auto Expr = DV.getExpression().begin();
685685 SPDIE = getDIE(SP);
686686 assert(SPDIE);
687687 for (const DILocalVariable *DV : Variables) {
688 DbgVariable NewVar(DV, /* IA */ nullptr, /* Expr */ nullptr, DD);
688 DbgVariable NewVar(DV, /* IA */ nullptr, DD);
689689 auto VariableDie = constructVariableDIE(NewVar);
690690 applyVariableAttributes(NewVar, *VariableDie);
691691 SPDIE->addChild(std::move(VariableDie));
724724 /// DbgVariable based on provided MachineLocation.
725725 void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
726726 MachineLocation Location) {
727 if (DV.variableHasComplexAddress())
727 if (DV.hasComplexAddress())
728728 addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
729729 else if (DV.isBlockByrefVariable())
730730 addBlockByrefAddress(DV, Die, dwarf::DW_AT_location, Location);
677677
678678 void DwarfDebug::createAbstractVariable(const DILocalVariable *Var,
679679 LexicalScope *Scope) {
680 auto AbsDbgVariable =
681 make_unique(Var, /* IA */ nullptr, /* Expr */ nullptr, this);
680 auto AbsDbgVariable = make_unique(Var, /* IA */ nullptr, this);
682681 InfoHolder.addScopeVariable(Scope, AbsDbgVariable.get());
683682 AbstractVariables[Var] = std::move(AbsDbgVariable);
684683 }
721720 if (!Scope)
722721 continue;
723722
724 const DIExpression *Expr = cast_or_null(VI.Expr);
725723 ensureAbstractVariableIsCreatedIfScoped(Var, Scope->getScopeNode());
726 auto RegVar =
727 make_unique(Var.first, Var.second, Expr, this, VI.Slot);
724 auto RegVar = make_unique(Var.first, Var.second, this);
725 RegVar->initializeMMI(VI.Expr, VI.Slot);
728726 if (InfoHolder.addScopeVariable(Scope, RegVar.get()))
729727 ConcreteVariables.push_back(std::move(RegVar));
730728 }
869867 }
870868 }
871869
870 DbgVariable *DwarfDebug::createConcreteVariable(LexicalScope &Scope,
871 InlinedVariable IV) {
872 ensureAbstractVariableIsCreatedIfScoped(IV, Scope.getScopeNode());
873 ConcreteVariables.push_back(
874 make_unique(IV.first, IV.second, this));
875 InfoHolder.addScopeVariable(&Scope, ConcreteVariables.back().get());
876 return ConcreteVariables.back().get();
877 }
872878
873879 // Find variables for each lexical scope.
874880 void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU,
897903 continue;
898904
899905 Processed.insert(IV);
906 DbgVariable *RegVar = createConcreteVariable(*Scope, IV);
907
900908 const MachineInstr *MInsn = Ranges.front().first;
901909 assert(MInsn->isDebugValue() && "History must begin with debug value");
902 ensureAbstractVariableIsCreatedIfScoped(IV, Scope->getScopeNode());
903 ConcreteVariables.push_back(make_unique(MInsn, this));
904 DbgVariable *RegVar = ConcreteVariables.back().get();
905 InfoHolder.addScopeVariable(Scope, RegVar);
910 RegVar->initializeDbgValue(MInsn);
906911
907912 // Check if the first DBG_VALUE is valid for the rest of the function.
908913 if (Ranges.size() == 1 && Ranges.front().second == nullptr)
929934
930935 // Collect info for variables that were optimized out.
931936 for (const DILocalVariable *DV : SP->getVariables()) {
932 if (!Processed.insert(InlinedVariable(DV, nullptr)).second)
933 continue;
934 if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope())) {
935 ensureAbstractVariableIsCreatedIfScoped(InlinedVariable(DV, nullptr),
936 Scope->getScopeNode());
937 ConcreteVariables.push_back(make_unique(
938 DV, /* IA */ nullptr, /* Expr */ nullptr, this));
939 InfoHolder.addScopeVariable(Scope, ConcreteVariables.back().get());
940 }
937 if (Processed.insert(InlinedVariable(DV, nullptr)).second)
938 if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope()))
939 createConcreteVariable(*Scope, InlinedVariable(DV, nullptr));
941940 }
942941 }
943942
6666 };
6767
6868 //===----------------------------------------------------------------------===//
69 /// \brief This class is used to track local variable information.
69 /// This class is used to track local variable information.
7070 ///
71 /// - Variables whose location changes over time have a DebugLocListIndex and
72 /// the other fields are not used.
71 /// Variables can be created from allocas, in which case they're generated from
72 /// the MMI table. Such variables can have multiple expressions and frame
73 /// indices. The \a Expr and \a FrameIndices array must match.
7374 ///
74 /// - Variables that are described by multiple MMI table entries have multiple
75 /// expressions and frame indices.
75 /// Variables can be created from \c DBG_VALUE instructions. Those whose
76 /// location changes over time use \a DebugLocListIndex, while those with a
77 /// single instruction use \a MInsn and (optionally) a single entry of \a Expr.
78 ///
79 /// Variables that have been optimized out use none of these fields.
7680 class DbgVariable {
77 const DILocalVariable *Var; /// Variable Descriptor.
78 const DILocation *IA; /// Inlined at location.
79 SmallVector
80 Expr; /// Complex address location expression.
81 DIE *TheDIE; /// Variable DIE.
82 unsigned DebugLocListIndex; /// Offset in DebugLocs.
83 const MachineInstr *MInsn; /// DBG_VALUE instruction of the variable.
84 SmallVector FrameIndex; /// Frame index of the variable.
81 const DILocalVariable *Var; /// Variable Descriptor.
82 const DILocation *IA; /// Inlined at location.
83 SmallVector Expr; /// Complex address.
84 DIE *TheDIE = nullptr; /// Variable DIE.
85 unsigned DebugLocListIndex = ~0u; /// Offset in DebugLocs.
86 const MachineInstr *MInsn = nullptr; /// DBG_VALUE instruction.
87 SmallVector FrameIndex; /// Frame index.
8588 DwarfDebug *DD;
8689
8790 public:
88 /// Construct a DbgVariable from a variable.
89 DbgVariable(const DILocalVariable *V, const DILocation *IA,
90 const DIExpression *E, DwarfDebug *DD, int FI = ~0)
91 : Var(V), IA(IA), Expr(1, E), TheDIE(nullptr), DebugLocListIndex(~0U),
92 MInsn(nullptr), DD(DD) {
91 /// Construct a DbgVariable.
92 ///
93 /// Creates a variable without any DW_AT_location. Call \a initializeMMI()
94 /// for MMI entries, or \a initializeDbgValue() for DBG_VALUE instructions.
95 DbgVariable(const DILocalVariable *V, const DILocation *IA, DwarfDebug *DD)
96 : Var(V), IA(IA), DD(DD) {}
97
98 /// Initialize from the MMI table.
99 void initializeMMI(const DIExpression *E, int FI) {
100 assert(Expr.empty() && "Already initialized?");
101 assert(FrameIndex.empty() && "Already initialized?");
102 assert(!MInsn && "Already initialized?");
103
104 assert((!E || E->isValid()) && "Expected valid expression");
105 assert(~FI && "Expected valid index");
106
107 Expr.push_back(E);
93108 FrameIndex.push_back(FI);
94 assert(!E || E->isValid());
95 }
96
97 /// Construct a DbgVariable from a DEBUG_VALUE.
98 /// AbstractVar may be NULL.
99 DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD)
100 : Var(DbgValue->getDebugVariable()),
101 IA(DbgValue->getDebugLoc()->getInlinedAt()),
102 Expr(1, DbgValue->getDebugExpression()), TheDIE(nullptr),
103 DebugLocListIndex(~0U), MInsn(DbgValue), DD(DD) {
104 FrameIndex.push_back(~0);
109 }
110
111 /// Initialize from a DBG_VALUE instruction.
112 void initializeDbgValue(const MachineInstr *DbgValue) {
113 assert(Expr.empty() && "Already initialized?");
114 assert(FrameIndex.empty() && "Already initialized?");
115 assert(!MInsn && "Already initialized?");
116
117 assert(Var == DbgValue->getDebugVariable() && "Wrong variable");
118 assert(IA == DbgValue->getDebugLoc()->getInlinedAt() && "Wrong inlined-at");
119
120 MInsn = DbgValue;
121 if (auto *E = DbgValue->getDebugExpression())
122 if (E->getNumElements())
123 Expr.push_back(E);
105124 }
106125
107126 // Accessors.
122141 assert(V.Var == Var && "conflicting variable");
123142 assert(V.IA == IA && "conflicting inlined-at location");
124143
125 if (V.getFrameIndex().back() != ~0) {
126 auto E = V.getExpression();
127 auto FI = V.getFrameIndex();
128 Expr.append(E.begin(), E.end());
129 FrameIndex.append(FI.begin(), FI.end());
130 }
131 assert(Expr.size() > 1 ? std::all_of(Expr.begin(), Expr.end(),
132 [](const DIExpression *E) {
133 return E->isBitPiece();
134 })
135 : (true && "conflicting locations for variable"));
144 assert(!FrameIndex.empty() && "Expected an MMI entry");
145 assert(!V.FrameIndex.empty() && "Expected an MMI entry");
146 assert(Expr.size() == FrameIndex.size() && "Mismatched expressions");
147 assert(V.Expr.size() == V.FrameIndex.size() && "Mismatched expressions");
148
149 Expr.append(V.Expr.begin(), V.Expr.end());
150 FrameIndex.append(V.FrameIndex.begin(), V.FrameIndex.end());
151 assert(std::all_of(Expr.begin(), Expr.end(), [](const DIExpression *E) {
152 return E && E->isBitPiece();
153 }) && "conflicting locations for variable");
136154 }
137155
138156 // Translate tag to proper Dwarf tag.
159177 return false;
160178 }
161179
162 bool variableHasComplexAddress() const {
163 assert(Var && "Invalid complex DbgVariable!");
164 assert(Expr.size() == 1 &&
165 "variableHasComplexAddress() invoked on multi-FI variable");
166 return Expr.back()->getNumElements() > 0;
180 bool hasComplexAddress() const {
181 assert(MInsn && "Expected DBG_VALUE, not MMI variable");
182 assert(FrameIndex.empty() && "Expected DBG_VALUE, not MMI variable");
183 assert(
184 (Expr.empty() || (Expr.size() == 1 && Expr.back()->getNumElements())) &&
185 "Invalid Expr for DBG_VALUE");
186 return !Expr.empty();
167187 }
168188 bool isBlockByrefVariable() const;
169189 const DIType *getType() const;
343363 void ensureAbstractVariableIsCreatedIfScoped(InlinedVariable Var,
344364 const MDNode *Scope);
345365
366 DbgVariable *createConcreteVariable(LexicalScope &Scope, InlinedVariable IV);
367
346368 /// \brief Construct a DIE for this abstract scope.
347369 void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
348370