Skip to content

Commit 10c37a0

Browse files
committed
Try simplifying LexicalScopes ownership again.
Committed initially in r207724-r207726 and reverted due to compiler-rt crashes in r207732. Instead, fix this harder with unordered_map and store the LexicalScopes by value in the map. This did necessitate moving the definition of LexicalScope above the definition of LexicalScopes. Let's see how the buildbots/compilers tolerate unordered_map::emplace + std::piecewise_construct + std::forward_as_tuple... git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207876 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent c7b30d8 commit 10c37a0

File tree

2 files changed

+132
-127
lines changed

2 files changed

+132
-127
lines changed

include/llvm/CodeGen/LexicalScopes.h

Lines changed: 100 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,117 @@
2525
#include "llvm/IR/Metadata.h"
2626
#include "llvm/IR/ValueHandle.h"
2727
#include <utility>
28+
#include <unordered_map>
2829
namespace llvm {
2930

3031
class MachineInstr;
3132
class MachineBasicBlock;
3233
class MachineFunction;
33-
class LexicalScope;
3434

3535
//===----------------------------------------------------------------------===//
3636
/// InsnRange - This is used to track range of instructions with identical
3737
/// lexical scope.
3838
///
3939
typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
4040

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+
41132
//===----------------------------------------------------------------------===//
42133
/// LexicalScopes - This class provides interface to collect and use lexical
43134
/// scoping information from machine instruction.
44135
///
45136
class LexicalScopes {
46137
public:
47138
LexicalScopes() : MF(nullptr), CurrentFnLexicalScope(nullptr) {}
48-
~LexicalScopes();
49139

50140
/// initialize - Scan machine function and constuct lexical scope nest, resets
51141
/// the instance if necessary.
@@ -87,9 +177,10 @@ class LexicalScopes {
87177
return AbstractScopesList;
88178
}
89179

90-
/// findAbstractScope - Find an abstract scope or return NULL.
180+
/// findAbstractScope - Find an abstract scope or return null.
91181
LexicalScope *findAbstractScope(const MDNode *N) {
92-
return AbstractScopeMap.lookup(N);
182+
auto I = AbstractScopeMap.find(N);
183+
return I != AbstractScopeMap.end() ? &I->second : nullptr;
93184
}
94185

95186
/// findInlinedScope - Find an inlined scope for the given DebugLoc or return
@@ -98,9 +189,10 @@ class LexicalScopes {
98189
return InlinedLexicalScopeMap.lookup(DL);
99190
}
100191

101-
/// findLexicalScope - Find regular lexical scope or return NULL.
192+
/// findLexicalScope - Find regular lexical scope or return null.
102193
LexicalScope *findLexicalScope(const MDNode *N) {
103-
return LexicalScopeMap.lookup(N);
194+
auto I = LexicalScopeMap.find(N);
195+
return I != LexicalScopeMap.end() ? &I->second : nullptr;
104196
}
105197

106198
/// dump - Print data structures to dbgs().
@@ -134,15 +226,15 @@ class LexicalScopes {
134226

135227
/// LexicalScopeMap - Tracks the scopes in the current function. Owns the
136228
/// contained LexicalScope*s.
137-
DenseMap<const MDNode *, LexicalScope *> LexicalScopeMap;
229+
std::unordered_map<const MDNode *, LexicalScope> LexicalScopeMap;
138230

139231
/// InlinedLexicalScopeMap - Tracks inlined function scopes in current
140232
/// function.
141233
DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap;
142234

143235
/// AbstractScopeMap - These scopes are not included LexicalScopeMap.
144236
/// AbstractScopes owns its LexicalScope*s.
145-
DenseMap<const MDNode *, LexicalScope *> AbstractScopeMap;
237+
std::unordered_map<const MDNode *, LexicalScope> AbstractScopeMap;
146238

147239
/// AbstractScopesList - Tracks abstract scopes constructed while processing
148240
/// a function.
@@ -153,97 +245,6 @@ class LexicalScopes {
153245
LexicalScope *CurrentFnLexicalScope;
154246
};
155247

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-
247248
} // end llvm namespace
248249

249250
#endif

lib/CodeGen/LexicalScopes.cpp

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,12 @@ using namespace llvm;
2626

2727
#define DEBUG_TYPE "lexicalscopes"
2828

29-
/// ~LexicalScopes - final cleanup after ourselves.
30-
LexicalScopes::~LexicalScopes() { reset(); }
31-
3229
/// reset - Reset the instance so that it's prepared for another function.
3330
void LexicalScopes::reset() {
3431
MF = nullptr;
3532
CurrentFnLexicalScope = nullptr;
36-
DeleteContainerSeconds(LexicalScopeMap);
37-
DeleteContainerSeconds(AbstractScopeMap);
33+
LexicalScopeMap.clear();
34+
AbstractScopeMap.clear();
3835
InlinedLexicalScopeMap.clear();
3936
AbstractScopesList.clear();
4037
}
@@ -124,7 +121,7 @@ LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
124121

125122
if (IA)
126123
return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
127-
return LexicalScopeMap.lookup(Scope);
124+
return findLexicalScope(Scope);
128125
}
129126

130127
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
@@ -152,35 +149,40 @@ LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
152149
D = DIDescriptor(Scope);
153150
}
154151

155-
LexicalScope *WScope = LexicalScopeMap.lookup(Scope);
156-
if (WScope)
157-
return WScope;
152+
auto I = LexicalScopeMap.find(Scope);
153+
if (I != LexicalScopeMap.end())
154+
return &I->second;
158155

159156
LexicalScope *Parent = nullptr;
160157
if (D.isLexicalBlock())
161158
Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
162-
WScope = new LexicalScope(Parent, DIDescriptor(Scope), nullptr, false);
163-
LexicalScopeMap.insert(std::make_pair(Scope, WScope));
159+
I = LexicalScopeMap.emplace(std::piecewise_construct,
160+
std::forward_as_tuple(Scope),
161+
std::forward_as_tuple(Parent, DIDescriptor(Scope),
162+
nullptr, false)).first;
163+
164164
if (!Parent && DIDescriptor(Scope).isSubprogram() &&
165165
DISubprogram(Scope).describes(MF->getFunction()))
166-
CurrentFnLexicalScope = WScope;
166+
CurrentFnLexicalScope = &I->second;
167167

168-
return WScope;
168+
return &I->second;
169169
}
170170

171171
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
172172
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
173173
MDNode *InlinedAt) {
174-
LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt);
175-
if (InlinedScope)
176-
return InlinedScope;
174+
auto I = LexicalScopeMap.find(InlinedAt);
175+
if (I != LexicalScopeMap.end())
176+
return &I->second;
177177

178178
DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
179-
InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc),
180-
DIDescriptor(Scope), InlinedAt, false);
181-
InlinedLexicalScopeMap[InlinedLoc] = InlinedScope;
182-
LexicalScopeMap[InlinedAt] = InlinedScope;
183-
return InlinedScope;
179+
I = LexicalScopeMap.emplace(std::piecewise_construct,
180+
std::forward_as_tuple(InlinedAt),
181+
std::forward_as_tuple(
182+
getOrCreateLexicalScope(InlinedLoc),
183+
DIDescriptor(Scope), InlinedAt, false)).first;
184+
InlinedLexicalScopeMap[InlinedLoc] = &I->second;
185+
return &I->second;
184186
}
185187

186188
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
@@ -190,21 +192,23 @@ LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
190192
DIDescriptor Scope(N);
191193
if (Scope.isLexicalBlockFile())
192194
Scope = DILexicalBlockFile(Scope).getScope();
193-
LexicalScope *AScope = AbstractScopeMap.lookup(N);
194-
if (AScope)
195-
return AScope;
195+
auto I = AbstractScopeMap.find(N);
196+
if (I != AbstractScopeMap.end())
197+
return &I->second;
196198

197199
LexicalScope *Parent = nullptr;
198200
if (Scope.isLexicalBlock()) {
199201
DILexicalBlock DB(N);
200202
DIDescriptor ParentDesc = DB.getContext();
201203
Parent = getOrCreateAbstractScope(ParentDesc);
202204
}
203-
AScope = new LexicalScope(Parent, DIDescriptor(N), nullptr, true);
204-
AbstractScopeMap[N] = AScope;
205+
I = AbstractScopeMap.emplace(std::piecewise_construct,
206+
std::forward_as_tuple(N),
207+
std::forward_as_tuple(Parent, DIDescriptor(N),
208+
nullptr, true)).first;
205209
if (DIDescriptor(N).isSubprogram())
206-
AbstractScopesList.push_back(AScope);
207-
return AScope;
210+
AbstractScopesList.push_back(&I->second);
211+
return &I->second;
208212
}
209213

210214
/// constructScopeNest

0 commit comments

Comments
 (0)