25
25
#include " llvm/IR/Metadata.h"
26
26
#include " llvm/IR/ValueHandle.h"
27
27
#include < utility>
28
+ #include < unordered_map>
28
29
namespace llvm {
29
30
30
31
class MachineInstr ;
31
32
class MachineBasicBlock ;
32
33
class MachineFunction ;
33
- class LexicalScope ;
34
34
35
35
// ===----------------------------------------------------------------------===//
36
36
// / InsnRange - This is used to track range of instructions with identical
37
37
// / lexical scope.
38
38
// /
39
39
typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
40
40
41
+ // ===----------------------------------------------------------------------===//
42
+ // / LexicalScope - This class is used to track scope information.
43
+ // /
44
+ class LexicalScope {
45
+
46
+ public:
47
+ LexicalScope (LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
48
+ : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
49
+ LastInsn (nullptr ), FirstInsn(nullptr ), DFSIn(0 ), DFSOut(0 ) {
50
+ if (Parent)
51
+ Parent->addChild (this );
52
+ }
53
+
54
+ // Accessors.
55
+ LexicalScope *getParent () const { return Parent; }
56
+ const MDNode *getDesc () const { return Desc; }
57
+ const MDNode *getInlinedAt () const { return InlinedAtLocation; }
58
+ const MDNode *getScopeNode () const { return Desc; }
59
+ bool isAbstractScope () const { return AbstractScope; }
60
+ SmallVectorImpl<LexicalScope *> &getChildren () { return Children; }
61
+ SmallVectorImpl<InsnRange> &getRanges () { return Ranges; }
62
+
63
+ // / addChild - Add a child scope.
64
+ void addChild (LexicalScope *S) { Children.push_back (S); }
65
+
66
+ // / openInsnRange - This scope covers instruction range starting from MI.
67
+ void openInsnRange (const MachineInstr *MI) {
68
+ if (!FirstInsn)
69
+ FirstInsn = MI;
70
+
71
+ if (Parent)
72
+ Parent->openInsnRange (MI);
73
+ }
74
+
75
+ // / extendInsnRange - Extend the current instruction range covered by
76
+ // / this scope.
77
+ void extendInsnRange (const MachineInstr *MI) {
78
+ assert (FirstInsn && " MI Range is not open!" );
79
+ LastInsn = MI;
80
+ if (Parent)
81
+ Parent->extendInsnRange (MI);
82
+ }
83
+
84
+ // / closeInsnRange - Create a range based on FirstInsn and LastInsn collected
85
+ // / until now. This is used when a new scope is encountered while walking
86
+ // / machine instructions.
87
+ void closeInsnRange (LexicalScope *NewScope = nullptr ) {
88
+ assert (LastInsn && " Last insn missing!" );
89
+ Ranges.push_back (InsnRange (FirstInsn, LastInsn));
90
+ FirstInsn = nullptr ;
91
+ LastInsn = nullptr ;
92
+ // If Parent dominates NewScope then do not close Parent's instruction
93
+ // range.
94
+ if (Parent && (!NewScope || !Parent->dominates (NewScope)))
95
+ Parent->closeInsnRange (NewScope);
96
+ }
97
+
98
+ // / dominates - Return true if current scope dominates given lexical scope.
99
+ bool dominates (const LexicalScope *S) const {
100
+ if (S == this )
101
+ return true ;
102
+ if (DFSIn < S->getDFSIn () && DFSOut > S->getDFSOut ())
103
+ return true ;
104
+ return false ;
105
+ }
106
+
107
+ // Depth First Search support to walk and manipulate LexicalScope hierarchy.
108
+ unsigned getDFSOut () const { return DFSOut; }
109
+ void setDFSOut (unsigned O) { DFSOut = O; }
110
+ unsigned getDFSIn () const { return DFSIn; }
111
+ void setDFSIn (unsigned I) { DFSIn = I; }
112
+
113
+ // / dump - print lexical scope.
114
+ void dump (unsigned Indent = 0 ) const ;
115
+
116
+ private:
117
+ LexicalScope *Parent; // Parent to this scope.
118
+ AssertingVH<const MDNode> Desc; // Debug info descriptor.
119
+ AssertingVH<const MDNode> InlinedAtLocation; // Location at which this
120
+ // scope is inlined.
121
+ bool AbstractScope; // Abstract Scope
122
+ SmallVector<LexicalScope *, 4 > Children; // Scopes defined in scope.
123
+ // Contents not owned.
124
+ SmallVector<InsnRange, 4 > Ranges;
125
+
126
+ const MachineInstr *LastInsn; // Last instruction of this scope.
127
+ const MachineInstr *FirstInsn; // First instruction of this scope.
128
+ unsigned DFSIn, DFSOut; // In & Out Depth use to determine
129
+ // scope nesting.
130
+ };
131
+
41
132
// ===----------------------------------------------------------------------===//
42
133
// / LexicalScopes - This class provides interface to collect and use lexical
43
134
// / scoping information from machine instruction.
44
135
// /
45
136
class LexicalScopes {
46
137
public:
47
138
LexicalScopes () : MF(nullptr ), CurrentFnLexicalScope(nullptr ) {}
48
- ~LexicalScopes ();
49
139
50
140
// / initialize - Scan machine function and constuct lexical scope nest, resets
51
141
// / the instance if necessary.
@@ -87,9 +177,10 @@ class LexicalScopes {
87
177
return AbstractScopesList;
88
178
}
89
179
90
- // / findAbstractScope - Find an abstract scope or return NULL .
180
+ // / findAbstractScope - Find an abstract scope or return null .
91
181
LexicalScope *findAbstractScope (const MDNode *N) {
92
- return AbstractScopeMap.lookup (N);
182
+ auto I = AbstractScopeMap.find (N);
183
+ return I != AbstractScopeMap.end () ? &I->second : nullptr ;
93
184
}
94
185
95
186
// / findInlinedScope - Find an inlined scope for the given DebugLoc or return
@@ -98,9 +189,10 @@ class LexicalScopes {
98
189
return InlinedLexicalScopeMap.lookup (DL);
99
190
}
100
191
101
- // / findLexicalScope - Find regular lexical scope or return NULL .
192
+ // / findLexicalScope - Find regular lexical scope or return null .
102
193
LexicalScope *findLexicalScope (const MDNode *N) {
103
- return LexicalScopeMap.lookup (N);
194
+ auto I = LexicalScopeMap.find (N);
195
+ return I != LexicalScopeMap.end () ? &I->second : nullptr ;
104
196
}
105
197
106
198
// / dump - Print data structures to dbgs().
@@ -134,15 +226,15 @@ class LexicalScopes {
134
226
135
227
// / LexicalScopeMap - Tracks the scopes in the current function. Owns the
136
228
// / contained LexicalScope*s.
137
- DenseMap <const MDNode *, LexicalScope * > LexicalScopeMap;
229
+ std::unordered_map <const MDNode *, LexicalScope> LexicalScopeMap;
138
230
139
231
// / InlinedLexicalScopeMap - Tracks inlined function scopes in current
140
232
// / function.
141
233
DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap;
142
234
143
235
// / AbstractScopeMap - These scopes are not included LexicalScopeMap.
144
236
// / AbstractScopes owns its LexicalScope*s.
145
- DenseMap <const MDNode *, LexicalScope * > AbstractScopeMap;
237
+ std::unordered_map <const MDNode *, LexicalScope> AbstractScopeMap;
146
238
147
239
// / AbstractScopesList - Tracks abstract scopes constructed while processing
148
240
// / a function.
@@ -153,97 +245,6 @@ class LexicalScopes {
153
245
LexicalScope *CurrentFnLexicalScope;
154
246
};
155
247
156
- // ===----------------------------------------------------------------------===//
157
- // / LexicalScope - This class is used to track scope information.
158
- // /
159
- class LexicalScope {
160
-
161
- public:
162
- LexicalScope (LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
163
- : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
164
- LastInsn (nullptr ), FirstInsn(nullptr ), DFSIn(0 ), DFSOut(0 ) {
165
- if (Parent)
166
- Parent->addChild (this );
167
- }
168
-
169
- // Accessors.
170
- LexicalScope *getParent () const { return Parent; }
171
- const MDNode *getDesc () const { return Desc; }
172
- const MDNode *getInlinedAt () const { return InlinedAtLocation; }
173
- const MDNode *getScopeNode () const { return Desc; }
174
- bool isAbstractScope () const { return AbstractScope; }
175
- SmallVectorImpl<LexicalScope *> &getChildren () { return Children; }
176
- SmallVectorImpl<InsnRange> &getRanges () { return Ranges; }
177
-
178
- // / addChild - Add a child scope.
179
- void addChild (LexicalScope *S) { Children.push_back (S); }
180
-
181
- // / openInsnRange - This scope covers instruction range starting from MI.
182
- void openInsnRange (const MachineInstr *MI) {
183
- if (!FirstInsn)
184
- FirstInsn = MI;
185
-
186
- if (Parent)
187
- Parent->openInsnRange (MI);
188
- }
189
-
190
- // / extendInsnRange - Extend the current instruction range covered by
191
- // / this scope.
192
- void extendInsnRange (const MachineInstr *MI) {
193
- assert (FirstInsn && " MI Range is not open!" );
194
- LastInsn = MI;
195
- if (Parent)
196
- Parent->extendInsnRange (MI);
197
- }
198
-
199
- // / closeInsnRange - Create a range based on FirstInsn and LastInsn collected
200
- // / until now. This is used when a new scope is encountered while walking
201
- // / machine instructions.
202
- void closeInsnRange (LexicalScope *NewScope = nullptr ) {
203
- assert (LastInsn && " Last insn missing!" );
204
- Ranges.push_back (InsnRange (FirstInsn, LastInsn));
205
- FirstInsn = nullptr ;
206
- LastInsn = nullptr ;
207
- // If Parent dominates NewScope then do not close Parent's instruction
208
- // range.
209
- if (Parent && (!NewScope || !Parent->dominates (NewScope)))
210
- Parent->closeInsnRange (NewScope);
211
- }
212
-
213
- // / dominates - Return true if current scope dominates given lexical scope.
214
- bool dominates (const LexicalScope *S) const {
215
- if (S == this )
216
- return true ;
217
- if (DFSIn < S->getDFSIn () && DFSOut > S->getDFSOut ())
218
- return true ;
219
- return false ;
220
- }
221
-
222
- // Depth First Search support to walk and manipulate LexicalScope hierarchy.
223
- unsigned getDFSOut () const { return DFSOut; }
224
- void setDFSOut (unsigned O) { DFSOut = O; }
225
- unsigned getDFSIn () const { return DFSIn; }
226
- void setDFSIn (unsigned I) { DFSIn = I; }
227
-
228
- // / dump - print lexical scope.
229
- void dump (unsigned Indent = 0 ) const ;
230
-
231
- private:
232
- LexicalScope *Parent; // Parent to this scope.
233
- AssertingVH<const MDNode> Desc; // Debug info descriptor.
234
- AssertingVH<const MDNode> InlinedAtLocation; // Location at which this
235
- // scope is inlined.
236
- bool AbstractScope; // Abstract Scope
237
- SmallVector<LexicalScope *, 4 > Children; // Scopes defined in scope.
238
- // Contents not owned.
239
- SmallVector<InsnRange, 4 > Ranges;
240
-
241
- const MachineInstr *LastInsn; // Last instruction of this scope.
242
- const MachineInstr *FirstInsn; // First instruction of this scope.
243
- unsigned DFSIn, DFSOut; // In & Out Depth use to determine
244
- // scope nesting.
245
- };
246
-
247
248
} // end llvm namespace
248
249
249
250
#endif
0 commit comments