0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 // The LLVM Compiler Infrastructure
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 // This file implements LexicalScopes analysis.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 // This pass collects lexical scope information and maps machine instructions
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13 // to respective lexical scopes.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 #include "llvm/CodeGen/LexicalScopes.h"
|
121
|
18 #include "llvm/ADT/DenseMap.h"
|
|
19 #include "llvm/ADT/SmallVector.h"
|
|
20 #include "llvm/CodeGen/MachineBasicBlock.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
21 #include "llvm/CodeGen/MachineFunction.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 #include "llvm/CodeGen/MachineInstr.h"
|
121
|
23 #include "llvm/IR/DebugInfoMetadata.h"
|
|
24 #include "llvm/IR/Metadata.h"
|
|
25 #include "llvm/Support/Casting.h"
|
|
26 #include "llvm/Support/Compiler.h"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27 #include "llvm/Support/Debug.h"
|
121
|
28 #include "llvm/Support/raw_ostream.h"
|
|
29 #include <cassert>
|
|
30 #include <string>
|
|
31 #include <tuple>
|
|
32 #include <utility>
|
|
33
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34 using namespace llvm;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
35
|
77
|
36 #define DEBUG_TYPE "lexicalscopes"
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
37
|
33
|
38 /// reset - Reset the instance so that it's prepared for another function.
|
|
39 void LexicalScopes::reset() {
|
77
|
40 MF = nullptr;
|
|
41 CurrentFnLexicalScope = nullptr;
|
|
42 LexicalScopeMap.clear();
|
|
43 AbstractScopeMap.clear();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
44 InlinedLexicalScopeMap.clear();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
45 AbstractScopesList.clear();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
46 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
47
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
48 /// initialize - Scan machine function and constuct lexical scope nest.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
49 void LexicalScopes::initialize(const MachineFunction &Fn) {
|
33
|
50 reset();
|
121
|
51 // Don't attempt any lexical scope creation for a NoDebug compile unit.
|
134
|
52 if (Fn.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
|
121
|
53 DICompileUnit::NoDebug)
|
|
54 return;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
55 MF = &Fn;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
56 SmallVector<InsnRange, 4> MIRanges;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
57 DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
58 extractLexicalScopes(MIRanges, MI2ScopeMap);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
59 if (CurrentFnLexicalScope) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
60 constructScopeNest(CurrentFnLexicalScope);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
61 assignInstructionRanges(MIRanges, MI2ScopeMap);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
62 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
63 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
64
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
65 /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
66 /// for the given machine function.
|
33
|
67 void LexicalScopes::extractLexicalScopes(
|
|
68 SmallVectorImpl<InsnRange> &MIRanges,
|
|
69 DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
70 // Scan each instruction and create scopes. First build working set of scopes.
|
77
|
71 for (const auto &MBB : *MF) {
|
|
72 const MachineInstr *RangeBeginMI = nullptr;
|
|
73 const MachineInstr *PrevMI = nullptr;
|
95
|
74 const DILocation *PrevDL = nullptr;
|
77
|
75 for (const auto &MInsn : MBB) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
76 // Check if instruction has valid location information.
|
95
|
77 const DILocation *MIDL = MInsn.getDebugLoc();
|
|
78 if (!MIDL) {
|
77
|
79 PrevMI = &MInsn;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
80 continue;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
81 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
82
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
83 // If scope has not changed then skip this instruction.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
84 if (MIDL == PrevDL) {
|
77
|
85 PrevMI = &MInsn;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
86 continue;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
87 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
88
|
121
|
89 // Ignore DBG_VALUE and similar instruction that do not contribute to any
|
|
90 // instruction in the output.
|
|
91 if (MInsn.isMetaInstruction())
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
92 continue;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
93
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
94 if (RangeBeginMI) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
95 // If we have already seen a beginning of an instruction range and
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
96 // current instruction scope does not match scope of first instruction
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
97 // in this range then create a new instruction range.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
98 InsnRange R(RangeBeginMI, PrevMI);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
99 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
100 MIRanges.push_back(R);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
101 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
102
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
103 // This is a beginning of a new instruction range.
|
77
|
104 RangeBeginMI = &MInsn;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
105
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
106 // Reset previous markers.
|
77
|
107 PrevMI = &MInsn;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
108 PrevDL = MIDL;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
109 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
110
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
111 // Create last instruction range.
|
95
|
112 if (RangeBeginMI && PrevMI && PrevDL) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
113 InsnRange R(RangeBeginMI, PrevMI);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
114 MIRanges.push_back(R);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
115 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
116 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
117 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
118 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
119
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
120 /// findLexicalScope - Find lexical scope, either regular or inlined, for the
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
121 /// given DebugLoc. Return NULL if not found.
|
95
|
122 LexicalScope *LexicalScopes::findLexicalScope(const DILocation *DL) {
|
|
123 DILocalScope *Scope = DL->getScope();
|
33
|
124 if (!Scope)
|
77
|
125 return nullptr;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
126
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
127 // The scope that we were created with could have an extra file - which
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
128 // isn't what we care about in this case.
|
120
|
129 Scope = Scope->getNonLexicalBlockFileScope();
|
33
|
130
|
95
|
131 if (auto *IA = DL->getInlinedAt()) {
|
77
|
132 auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
|
|
133 return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
|
|
134 }
|
|
135 return findLexicalScope(Scope);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
136 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
137
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
138 /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
139 /// not available then create new lexical scope.
|
95
|
140 LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope,
|
|
141 const DILocation *IA) {
|
|
142 if (IA) {
|
121
|
143 // Skip scopes inlined from a NoDebug compile unit.
|
|
144 if (Scope->getSubprogram()->getUnit()->getEmissionKind() ==
|
|
145 DICompileUnit::NoDebug)
|
|
146 return getOrCreateLexicalScope(IA);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
147 // Create an abstract scope for inlined function.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
148 getOrCreateAbstractScope(Scope);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
149 // Create an inlined scope for inlined function.
|
95
|
150 return getOrCreateInlinedScope(Scope, IA);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
151 }
|
33
|
152
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
153 return getOrCreateRegularScope(Scope);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
154 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
155
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
156 /// getOrCreateRegularScope - Find or create a regular lexical scope.
|
95
|
157 LexicalScope *
|
|
158 LexicalScopes::getOrCreateRegularScope(const DILocalScope *Scope) {
|
120
|
159 assert(Scope && "Invalid Scope encoding!");
|
|
160 Scope = Scope->getNonLexicalBlockFileScope();
|
33
|
161
|
77
|
162 auto I = LexicalScopeMap.find(Scope);
|
|
163 if (I != LexicalScopeMap.end())
|
|
164 return &I->second;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
165
|
95
|
166 // FIXME: Should the following dyn_cast be DILexicalBlock?
|
77
|
167 LexicalScope *Parent = nullptr;
|
95
|
168 if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
|
|
169 Parent = getOrCreateLexicalScope(Block->getScope());
|
83
|
170 I = LexicalScopeMap.emplace(std::piecewise_construct,
|
|
171 std::forward_as_tuple(Scope),
|
95
|
172 std::forward_as_tuple(Parent, Scope, nullptr,
|
|
173 false)).first;
|
77
|
174
|
83
|
175 if (!Parent) {
|
134
|
176 assert(cast<DISubprogram>(Scope)->describes(&MF->getFunction()));
|
83
|
177 assert(!CurrentFnLexicalScope);
|
77
|
178 CurrentFnLexicalScope = &I->second;
|
83
|
179 }
|
33
|
180
|
77
|
181 return &I->second;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
182 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
183
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
184 /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
|
95
|
185 LexicalScope *
|
|
186 LexicalScopes::getOrCreateInlinedScope(const DILocalScope *Scope,
|
|
187 const DILocation *InlinedAt) {
|
120
|
188 assert(Scope && "Invalid Scope encoding!");
|
|
189 Scope = Scope->getNonLexicalBlockFileScope();
|
95
|
190 std::pair<const DILocalScope *, const DILocation *> P(Scope, InlinedAt);
|
77
|
191 auto I = InlinedLexicalScopeMap.find(P);
|
|
192 if (I != InlinedLexicalScopeMap.end())
|
|
193 return &I->second;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
194
|
77
|
195 LexicalScope *Parent;
|
95
|
196 if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
|
|
197 Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt);
|
77
|
198 else
|
95
|
199 Parent = getOrCreateLexicalScope(InlinedAt);
|
77
|
200
|
121
|
201 I = InlinedLexicalScopeMap
|
|
202 .emplace(std::piecewise_construct, std::forward_as_tuple(P),
|
|
203 std::forward_as_tuple(Parent, Scope, InlinedAt, false))
|
83
|
204 .first;
|
77
|
205 return &I->second;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
206 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
207
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
208 /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
|
95
|
209 LexicalScope *
|
|
210 LexicalScopes::getOrCreateAbstractScope(const DILocalScope *Scope) {
|
|
211 assert(Scope && "Invalid Scope encoding!");
|
120
|
212 Scope = Scope->getNonLexicalBlockFileScope();
|
77
|
213 auto I = AbstractScopeMap.find(Scope);
|
|
214 if (I != AbstractScopeMap.end())
|
|
215 return &I->second;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
216
|
95
|
217 // FIXME: Should the following isa be DILexicalBlock?
|
77
|
218 LexicalScope *Parent = nullptr;
|
95
|
219 if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
|
|
220 Parent = getOrCreateAbstractScope(Block->getScope());
|
|
221
|
77
|
222 I = AbstractScopeMap.emplace(std::piecewise_construct,
|
|
223 std::forward_as_tuple(Scope),
|
|
224 std::forward_as_tuple(Parent, Scope,
|
|
225 nullptr, true)).first;
|
95
|
226 if (isa<DISubprogram>(Scope))
|
77
|
227 AbstractScopesList.push_back(&I->second);
|
|
228 return &I->second;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
229 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
230
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
231 /// constructScopeNest
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
232 void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
|
33
|
233 assert(Scope && "Unable to calculate scope dominance graph!");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
234 SmallVector<LexicalScope *, 4> WorkStack;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
235 WorkStack.push_back(Scope);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
236 unsigned Counter = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
237 while (!WorkStack.empty()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
238 LexicalScope *WS = WorkStack.back();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
239 const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
240 bool visitedChildren = false;
|
120
|
241 for (auto &ChildScope : Children)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
242 if (!ChildScope->getDFSOut()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
243 WorkStack.push_back(ChildScope);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
244 visitedChildren = true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
245 ChildScope->setDFSIn(++Counter);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
246 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
247 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
248 if (!visitedChildren) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
249 WorkStack.pop_back();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
250 WS->setDFSOut(++Counter);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
251 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
252 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
253 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
254
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
255 /// assignInstructionRanges - Find ranges of instructions covered by each
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
256 /// lexical scope.
|
33
|
257 void LexicalScopes::assignInstructionRanges(
|
|
258 SmallVectorImpl<InsnRange> &MIRanges,
|
|
259 DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
|
77
|
260 LexicalScope *PrevLexicalScope = nullptr;
|
120
|
261 for (const auto &R : MIRanges) {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
262 LexicalScope *S = MI2ScopeMap.lookup(R.first);
|
33
|
263 assert(S && "Lost LexicalScope for a machine instruction!");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
264 if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
265 PrevLexicalScope->closeInsnRange(S);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
266 S->openInsnRange(R.first);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
267 S->extendInsnRange(R.second);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
268 PrevLexicalScope = S;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
269 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
270
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
271 if (PrevLexicalScope)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
272 PrevLexicalScope->closeInsnRange();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
273 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
274
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
275 /// getMachineBasicBlocks - Populate given set using machine basic blocks which
|
33
|
276 /// have machine instructions that belong to lexical scope identified by
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
277 /// DebugLoc.
|
33
|
278 void LexicalScopes::getMachineBasicBlocks(
|
95
|
279 const DILocation *DL, SmallPtrSetImpl<const MachineBasicBlock *> &MBBs) {
|
121
|
280 assert(MF && "Method called on a uninitialized LexicalScopes object!");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
281 MBBs.clear();
|
121
|
282
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
283 LexicalScope *Scope = getOrCreateLexicalScope(DL);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
284 if (!Scope)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
285 return;
|
33
|
286
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
287 if (Scope == CurrentFnLexicalScope) {
|
77
|
288 for (const auto &MBB : *MF)
|
|
289 MBBs.insert(&MBB);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
290 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
291 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
292
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
293 SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
|
120
|
294 for (auto &R : InsnRanges)
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
295 MBBs.insert(R.first->getParent());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
296 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
297
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
298 /// dominates - Return true if DebugLoc's lexical scope dominates at least one
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
299 /// machine instruction's lexical scope in a given machine basic block.
|
95
|
300 bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB) {
|
121
|
301 assert(MF && "Unexpected uninitialized LexicalScopes object!");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
302 LexicalScope *Scope = getOrCreateLexicalScope(DL);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
303 if (!Scope)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
304 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
305
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
306 // Current function scope covers all basic blocks in the function.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
307 if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
308 return true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
309
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
310 bool Result = false;
|
120
|
311 for (auto &I : *MBB) {
|
|
312 if (const DILocation *IDL = I.getDebugLoc())
|
95
|
313 if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
|
|
314 if (Scope->dominates(IScope))
|
|
315 return true;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
316 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
317 return Result;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
318 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
319
|
121
|
320 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
|
321 LLVM_DUMP_METHOD void LexicalScope::dump(unsigned Indent) const {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
322 raw_ostream &err = dbgs();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
323 err.indent(Indent);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
324 err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
325 const MDNode *N = Desc;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
326 err.indent(Indent);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
327 N->dump();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
328 if (AbstractScope)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
329 err << std::string(Indent, ' ') << "Abstract Scope\n";
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
330
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
331 if (!Children.empty())
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
332 err << std::string(Indent + 2, ' ') << "Children ...\n";
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
333 for (unsigned i = 0, e = Children.size(); i != e; ++i)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
334 if (Children[i] != this)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
335 Children[i]->dump(Indent + 2);
|
121
|
336 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
337 #endif
|