llvm.org GIT mirror llvm / 103b8e6
Provide utility to extract and use lexical scoping information from machine instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137237 91177308-0d34-0410-b5e6-96231b3b80d8 Devang Patel 9 years ago
3 changed file(s) with 553 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===- LexicalScopes.cpp - Collecting lexical scope info -*- C++ -*--------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements LexicalScopes analysis.
10 //
11 // This pass collects lexical scope information and maps machine instructions
12 // to respective lexical scopes.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_CODEGEN_LEXICALSCOPES_H
17 #define LLVM_CODEGEN_LEXICALSCOPES_H
18
19 #include "llvm/Metadata.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/SmallPtrSet.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/Support/DebugLoc.h"
24 #include "llvm/Support/ValueHandle.h"
25 #include
26 namespace llvm {
27
28 class MachineInstr;
29 class MachineBasicBlock;
30 class MachineFunction;
31 class LexicalScope;
32
33 //===----------------------------------------------------------------------===//
34 /// InsnRange - This is used to track range of instructions with identical
35 /// lexical scope.
36 ///
37 typedef std::pair InsnRange;
38
39 //===----------------------------------------------------------------------===//
40 /// LexicalScopes - This class provides interface to collect and use lexical
41 /// scoping information from machine instruction.
42 ///
43 class LexicalScopes {
44 public:
45 LexicalScopes() : MF(NULL), CurrentFnLexicalScope(NULL) { }
46 ~LexicalScopes();
47
48 /// initialize - Scan machine function and constuct lexical scope nest.
49 virtual void initialize(const MachineFunction &);
50
51 /// releaseMemory - release memory.
52 virtual void releaseMemory();
53
54 /// empty - Return true if there is any lexical scope information available.
55 bool empty() { return CurrentFnLexicalScope == NULL; }
56
57 /// isCurrentFunctionScope - Return true if given lexical scope represents
58 /// current function.
59 bool isCurrentFunctionScope(const LexicalScope *LS) {
60 return LS == CurrentFnLexicalScope;
61 }
62
63 /// getCurrentFunctionScope - Return lexical scope for the current function.
64 LexicalScope *getCurrentFunctionScope() const { return CurrentFnLexicalScope;}
65
66 /// getMachineBasicBlocks - Populate given set using machine basic blocks which
67 /// have machine instructions that belong to lexical scope identified by
68 /// DebugLoc.
69 void getMachineBasicBlocks(DebugLoc DL,
70 SmallPtrSet &MBBs);
71
72 /// dominates - Return true if DebugLoc's lexical scope dominates at least one
73 /// machine instruction's lexical scope in a given machine basic block.
74 bool dominates(DebugLoc DL, MachineBasicBlock *MBB);
75
76 /// findLexicalScope - Find lexical scope, either regular or inlined, for the
77 /// given DebugLoc. Return NULL if not found.
78 LexicalScope *findLexicalScope(DebugLoc DL);
79
80 /// getAbstractScopesList - Return a reference to list of abstract scopes.
81 SmallVector &getAbstractScopesList() {
82 return AbstractScopesList;
83 }
84
85 /// findAbstractScope - Find an abstract scope or return NULL.
86 LexicalScope *findAbstractScope(const MDNode *N) {
87 return AbstractScopeMap.lookup(N);
88 }
89
90 /// findInlinedScope - Find an inlined scope for the given DebugLoc or return
91 /// NULL.
92 LexicalScope *findInlinedScope(DebugLoc DL) {
93 return InlinedLexicalScopeMap.lookup(DL);
94 }
95
96 /// findLexicalScope - Find regular lexical scope or return NULL.
97 LexicalScope *findLexicalScope(const MDNode *N) {
98 return LexicalScopeMap.lookup(N);
99 }
100
101 /// dump - Print data structures to dbgs().
102 void dump();
103
104 private:
105
106 /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
107 /// not available then create new lexical scope.
108 LexicalScope *getOrCreateLexicalScope(DebugLoc DL);
109
110 /// getOrCreateRegularScope - Find or create a regular lexical scope.
111 LexicalScope *getOrCreateRegularScope(MDNode *Scope);
112
113 /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
114 LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
115
116 /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
117 LexicalScope *getOrCreateAbstractScope(const MDNode *N);
118
119 /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
120 /// for the given machine function.
121 void extractLexicalScopes(SmallVectorImpl &MIRanges,
122 DenseMap &M);
123 void constructScopeNest(LexicalScope *Scope);
124 void assignInstructionRanges(SmallVectorImpl &MIRanges,
125 DenseMap &M);
126
127 private:
128 const MachineFunction *MF;
129
130 /// LexicalScopeMap - Tracks the scopes in the current function. Owns the
131 /// contained LexicalScope*s.
132 DenseMap LexicalScopeMap;
133
134 /// InlinedLexicalScopeMap - Tracks inlined function scopes in current function.
135 DenseMap InlinedLexicalScopeMap;
136
137 /// AbstractScopeMap - These scopes are not included LexicalScopeMap.
138 /// AbstractScopes owns its LexicalScope*s.
139 DenseMap AbstractScopeMap;
140
141 /// AbstractScopesList - Tracks abstract scopes constructed while processing
142 /// a function.
143 SmallVectorAbstractScopesList;
144
145 /// CurrentFnLexicalScope - Top level scope for the current function.
146 ///
147 LexicalScope *CurrentFnLexicalScope;
148 };
149
150 //===----------------------------------------------------------------------===//
151 /// LexicalScope - This class is used to track scope information.
152 ///
153 class LexicalScope {
154
155 public:
156 LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
157 : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
158 LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0), IndentLevel(0) {
159 if (Parent)
160 Parent->addChild(this);
161 }
162
163 virtual ~LexicalScope() {}
164
165 // Accessors.
166 LexicalScope *getParent() const { return Parent; }
167 const MDNode *getDesc() const { return Desc; }
168 const MDNode *getInlinedAt() const { return InlinedAtLocation; }
169 const MDNode *getScopeNode() const { return Desc; }
170 bool isAbstractScope() const { return AbstractScope; }
171 SmallVector &getChildren() { return Children; }
172 SmallVector &getRanges() { return Ranges; }
173
174 /// addChild - Add a child scope.
175 void addChild(LexicalScope *S) { Children.push_back(S); }
176
177 /// openInsnRange - This scope covers instruction range starting from MI.
178 void openInsnRange(const MachineInstr *MI) {
179 if (!FirstInsn)
180 FirstInsn = MI;
181
182 if (Parent)
183 Parent->openInsnRange(MI);
184 }
185
186 /// extendInsnRange - Extend the current instruction range covered by
187 /// this scope.
188 void extendInsnRange(const MachineInstr *MI) {
189 assert (FirstInsn && "MI Range is not open!");
190 LastInsn = MI;
191 if (Parent)
192 Parent->extendInsnRange(MI);
193 }
194
195 /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
196 /// until now. This is used when a new scope is encountered while walking
197 /// machine instructions.
198 void closeInsnRange(LexicalScope *NewScope = NULL) {
199 assert (LastInsn && "Last insn missing!");
200 Ranges.push_back(InsnRange(FirstInsn, LastInsn));
201 FirstInsn = NULL;
202 LastInsn = NULL;
203 // If Parent dominates NewScope then do not close Parent's instruction
204 // range.
205 if (Parent && (!NewScope || !Parent->dominates(NewScope)))
206 Parent->closeInsnRange(NewScope);
207 }
208
209 /// dominates - Return true if current scope dominsates given lexical scope.
210 bool dominates(const LexicalScope *S) {
211 if (S == this)
212 return true;
213 if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
214 return true;
215 return false;
216 }
217
218 // Depth First Search support to walk and manipulate LexicalScope hierarchy.
219 unsigned getDFSOut() const { return DFSOut; }
220 void setDFSOut(unsigned O) { DFSOut = O; }
221 unsigned getDFSIn() const { return DFSIn; }
222 void setDFSIn(unsigned I) { DFSIn = I; }
223
224 /// dump - print lexical scope.
225 void dump() const;
226
227 private:
228 LexicalScope *Parent; // Parent to this scope.
229 AssertingVH Desc; // Debug info descriptor.
230 AssertingVH InlinedAtLocation; // Location at which this
231 // scope is inlined.
232 bool AbstractScope; // Abstract Scope
233 SmallVector Children; // Scopes defined in scope.
234 // Contents not owned.
235 SmallVector Ranges;
236
237 const MachineInstr *LastInsn; // Last instruction of this scope.
238 const MachineInstr *FirstInsn; // First instruction of this scope.
239 unsigned DFSIn, DFSOut; // In & Out Depth use to determine
240 // scope nesting.
241 mutable unsigned IndentLevel; // Private state for dump()
242 };
243
244 } // end llvm namespace
245
246 #endif
2222 IntrinsicLowering.cpp
2323 LLVMTargetMachine.cpp
2424 LatencyPriorityQueue.cpp
25 LexicalScopes.cpp
2526 LiveDebugVariables.cpp
2627 LiveInterval.cpp
2728 LiveIntervalAnalysis.cpp
0 //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements LexicalScopes analysis.
10 //
11 // This pass collects lexical scope information and maps machine instructions
12 // to respective lexical scopes.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #define DEBUG_TYPE "lexicalscopes"
17 #include "llvm/CodeGen/LexicalScopes.h"
18 #include "llvm/Function.h"
19 #include "llvm/Analysis/DebugInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstr.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/FormattedStream.h"
25 using namespace llvm;
26
27 LexicalScopes::~LexicalScopes() {
28 releaseMemory();
29 }
30
31 /// releaseMemory - release memory.
32 void LexicalScopes::releaseMemory() {
33 MF = NULL;
34 CurrentFnLexicalScope = NULL;
35 DeleteContainerSeconds(LexicalScopeMap);
36 DeleteContainerSeconds(AbstractScopeMap);
37 InlinedLexicalScopeMap.clear();
38 AbstractScopesList.clear();
39 }
40
41 /// initialize - Scan machine function and constuct lexical scope nest.
42 void LexicalScopes::initialize(const MachineFunction &Fn) {
43 releaseMemory();
44 MF = &Fn;
45 SmallVector MIRanges;
46 DenseMap MI2ScopeMap;
47 extractLexicalScopes(MIRanges, MI2ScopeMap);
48 if (CurrentFnLexicalScope) {
49 constructScopeNest(CurrentFnLexicalScope);
50 assignInstructionRanges(MIRanges, MI2ScopeMap);
51 }
52 }
53
54 /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
55 /// for the given machine function.
56 void LexicalScopes::
57 extractLexicalScopes(SmallVectorImpl &MIRanges,
58 DenseMap &MI2ScopeMap) {
59
60 // Scan each instruction and create scopes. First build working set of scopes.
61 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
62 I != E; ++I) {
63 const MachineInstr *RangeBeginMI = NULL;
64 const MachineInstr *PrevMI = NULL;
65 DebugLoc PrevDL;
66 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
67 II != IE; ++II) {
68 const MachineInstr *MInsn = II;
69
70 // Check if instruction has valid location information.
71 const DebugLoc MIDL = MInsn->getDebugLoc();
72 if (MIDL.isUnknown()) {
73 PrevMI = MInsn;
74 continue;
75 }
76
77 // If scope has not changed then skip this instruction.
78 if (MIDL == PrevDL) {
79 PrevMI = MInsn;
80 continue;
81 }
82
83 // Ignore DBG_VALUE. It does not contribute to any instruction in output.
84 if (MInsn->isDebugValue())
85 continue;
86
87 if (RangeBeginMI) {
88 // If we have already seen a beginning of an instruction range and
89 // current instruction scope does not match scope of first instruction
90 // in this range then create a new instruction range.
91 InsnRange R(RangeBeginMI, PrevMI);
92 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
93 MIRanges.push_back(R);
94 }
95
96 // This is a beginning of a new instruction range.
97 RangeBeginMI = MInsn;
98
99 // Reset previous markers.
100 PrevMI = MInsn;
101 PrevDL = MIDL;
102 }
103
104 // Create last instruction range.
105 if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) {
106 InsnRange R(RangeBeginMI, PrevMI);
107 MIRanges.push_back(R);
108 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
109 }
110 }
111 }
112
113 /// findLexicalScope - Find lexical scope, either regular or inlined, for the
114 /// given DebugLoc. Return NULL if not found.
115 LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
116 MDNode *Scope = NULL;
117 MDNode *IA = NULL;
118 DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
119 if (!Scope) return NULL;
120 if (IA)
121 return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
122 return LexicalScopeMap.lookup(DL.getScope(Scope->getContext()));
123 }
124
125 /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
126 /// not available then create new lexical scope.
127 LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) {
128 MDNode *Scope = NULL;
129 MDNode *InlinedAt = NULL;
130 DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext());
131 if (InlinedAt) {
132 // Create an abstract scope for inlined function.
133 getOrCreateAbstractScope(Scope);
134 // Create an inlined scope for inlined function.
135 return getOrCreateInlinedScope(Scope, InlinedAt);
136 }
137
138 return getOrCreateRegularScope(Scope);
139 }
140
141 /// getOrCreateRegularScope - Find or create a regular lexical scope.
142 LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
143 LexicalScope *WScope = LexicalScopeMap.lookup(Scope);
144 if (WScope)
145 return WScope;
146
147 LexicalScope *Parent = NULL;
148 if (DIDescriptor(Scope).isLexicalBlock())
149 Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
150 WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false);
151 LexicalScopeMap.insert(std::make_pair(Scope, WScope));
152 if (!Parent && DIDescriptor(Scope).isSubprogram()
153 && DISubprogram(Scope).describes(MF->getFunction()))
154 CurrentFnLexicalScope = WScope;
155
156 return WScope;
157 }
158
159 /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
160 LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
161 MDNode *InlinedAt) {
162 LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt);
163 if (InlinedScope)
164 return InlinedScope;
165
166 DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
167 InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc),
168 DIDescriptor(Scope), InlinedAt, false);
169 InlinedLexicalScopeMap[InlinedLoc] = InlinedScope;
170 LexicalScopeMap[InlinedAt] = InlinedScope;
171 return InlinedScope;
172 }
173
174 /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
175 LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
176 assert(N && "Invalid Scope encoding!");
177
178 LexicalScope *AScope = AbstractScopeMap.lookup(N);
179 if (AScope)
180 return AScope;
181
182 LexicalScope *Parent = NULL;
183 DIDescriptor Scope(N);
184 if (Scope.isLexicalBlock()) {
185 DILexicalBlock DB(N);
186 DIDescriptor ParentDesc = DB.getContext();
187 Parent = getOrCreateAbstractScope(ParentDesc);
188 }
189 AScope = new LexicalScope(Parent, DIDescriptor(N), NULL, true);
190 AbstractScopeMap[N] = AScope;
191 if (DIDescriptor(N).isSubprogram())
192 AbstractScopesList.push_back(AScope);
193 return AScope;
194 }
195
196 /// constructScopeNest
197 void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
198 assert (Scope && "Unable to calculate scop edominance graph!");
199 SmallVector WorkStack;
200 WorkStack.push_back(Scope);
201 unsigned Counter = 0;
202 while (!WorkStack.empty()) {
203 LexicalScope *WS = WorkStack.back();
204 const SmallVector &Children = WS->getChildren();
205 bool visitedChildren = false;
206 for (SmallVector::const_iterator SI = Children.begin(),
207 SE = Children.end(); SI != SE; ++SI) {
208 LexicalScope *ChildScope = *SI;
209 if (!ChildScope->getDFSOut()) {
210 WorkStack.push_back(ChildScope);
211 visitedChildren = true;
212 ChildScope->setDFSIn(++Counter);
213 break;
214 }
215 }
216 if (!visitedChildren) {
217 WorkStack.pop_back();
218 WS->setDFSOut(++Counter);
219 }
220 }
221 }
222
223 /// assignInstructionRanges - Find ranges of instructions covered by each lexical
224 /// scope.
225 void LexicalScopes::
226 assignInstructionRanges(SmallVectorImpl &MIRanges,
227 DenseMap &MI2ScopeMap) {
228
229 LexicalScope *PrevLexicalScope = NULL;
230 for (SmallVectorImpl::const_iterator RI = MIRanges.begin(),
231 RE = MIRanges.end(); RI != RE; ++RI) {
232 const InsnRange &R = *RI;
233 LexicalScope *S = MI2ScopeMap.lookup(R.first);
234 assert (S && "Lost LexicalScope for a machine instruction!");
235 if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
236 PrevLexicalScope->closeInsnRange(S);
237 S->openInsnRange(R.first);
238 S->extendInsnRange(R.second);
239 PrevLexicalScope = S;
240 }
241
242 if (PrevLexicalScope)
243 PrevLexicalScope->closeInsnRange();
244 }
245
246 /// getMachineBasicBlocks - Populate given set using machine basic blocks which
247 /// have machine instructions that belong to lexical scope identified by
248 /// DebugLoc.
249 void LexicalScopes::
250 getMachineBasicBlocks(DebugLoc DL, SmallPtrSet &MBBs) {
251 MBBs.clear();
252 LexicalScope *Scope = getOrCreateLexicalScope(DL);
253 if (!Scope)
254 return;
255
256 SmallVector &InsnRanges = Scope->getRanges();
257 for (SmallVector::iterator I = InsnRanges.begin(),
258 E = InsnRanges.end(); I != E; ++I) {
259 InsnRange &R = *I;
260 MBBs.insert(R.first->getParent());
261 }
262 }
263
264 /// dominates - Return true if DebugLoc's lexical scope dominates at least one
265 /// machine instruction's lexical scope in a given machine basic block.
266 bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) {
267 LexicalScope *Scope = getOrCreateLexicalScope(DL);
268 if (!Scope)
269 return false;
270 bool Result = false;
271 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
272 I != E; ++I) {
273 DebugLoc IDL = I->getDebugLoc();
274 if (IDL.isUnknown())
275 continue;
276 if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
277 if (Scope->dominates(IScope))
278 return true;
279 }
280 return Result;
281 }
282
283 /// dump - Print data structures.
284 void LexicalScope::dump() const {
285 #ifndef NDEBUG
286 raw_ostream &err = dbgs();
287 err.indent(IndentLevel);
288 err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
289 const MDNode *N = Desc;
290 N->dump();
291 if (AbstractScope)
292 err << "Abstract Scope\n";
293
294 IndentLevel += 2;
295 if (!Children.empty())
296 err << "Children ...\n";
297 for (unsigned i = 0, e = Children.size(); i != e; ++i)
298 if (Children[i] != this)
299 Children[i]->dump();
300
301 IndentLevel -= 2;
302 #endif
303 }
304