22 #include "llvm/Config/llvm-config.h"
37 #define DEBUG_TYPE "lexicalscopes"
42 CurrentFnLexicalScope =
nullptr;
43 LexicalScopeMap.clear();
44 AbstractScopeMap.clear();
45 InlinedLexicalScopeMap.clear();
46 AbstractScopesList.clear();
47 DominatedBlocks.clear();
60 extractLexicalScopes(MIRanges, MI2ScopeMap);
61 if (CurrentFnLexicalScope) {
62 constructScopeNest(CurrentFnLexicalScope);
63 assignInstructionRanges(MIRanges, MI2ScopeMap);
69 void LexicalScopes::extractLexicalScopes(
73 for (
const auto &
MBB : *MF) {
77 for (
const auto &MInsn :
MBB) {
80 if (MInsn.isMetaInstruction())
101 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
102 MIRanges.push_back(R);
106 RangeBeginMI = &MInsn;
114 if (RangeBeginMI && PrevMI && PrevDL) {
116 MIRanges.push_back(R);
117 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
131 Scope = Scope->getNonLexicalBlockFileScope();
133 if (
auto *
IA =
DL->getInlinedAt()) {
134 auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope,
IA));
135 return I != InlinedLexicalScopeMap.end() ? &
I->second :
nullptr;
146 if (Scope->getSubprogram()->getUnit()->getEmissionKind() ==
148 return getOrCreateLexicalScope(
IA);
152 return getOrCreateInlinedScope(Scope,
IA);
155 return getOrCreateRegularScope(Scope);
160 LexicalScopes::getOrCreateRegularScope(
const DILocalScope *Scope) {
161 assert(Scope &&
"Invalid Scope encoding!");
164 auto I = LexicalScopeMap.find(Scope);
165 if (
I != LexicalScopeMap.end())
170 if (
auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
171 Parent = getOrCreateLexicalScope(
Block->getScope());
172 I = LexicalScopeMap.emplace(std::piecewise_construct,
173 std::forward_as_tuple(Scope),
174 std::forward_as_tuple(Parent, Scope,
nullptr,
178 assert(cast<DISubprogram>(Scope)->describes(&MF->getFunction()));
179 assert(!CurrentFnLexicalScope);
180 CurrentFnLexicalScope = &
I->second;
188 LexicalScopes::getOrCreateInlinedScope(
const DILocalScope *Scope,
190 assert(Scope &&
"Invalid Scope encoding!");
192 std::pair<const DILocalScope *, const DILocation *>
P(Scope, InlinedAt);
193 auto I = InlinedLexicalScopeMap.find(
P);
194 if (
I != InlinedLexicalScopeMap.end())
198 if (
auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
199 Parent = getOrCreateInlinedScope(
Block->getScope(), InlinedAt);
201 Parent = getOrCreateLexicalScope(InlinedAt);
203 I = InlinedLexicalScopeMap
204 .emplace(std::piecewise_construct, std::forward_as_tuple(
P),
205 std::forward_as_tuple(Parent, Scope, InlinedAt,
false))
213 assert(Scope &&
"Invalid Scope encoding!");
214 Scope = Scope->getNonLexicalBlockFileScope();
215 auto I = AbstractScopeMap.find(Scope);
216 if (
I != AbstractScopeMap.end())
221 if (
auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
224 I = AbstractScopeMap.emplace(std::piecewise_construct,
225 std::forward_as_tuple(Scope),
226 std::forward_as_tuple(Parent, Scope,
227 nullptr,
true)).first;
228 if (isa<DISubprogram>(Scope))
229 AbstractScopesList.push_back(&
I->second);
236 void LexicalScopes::constructScopeNest(
LexicalScope *Scope) {
237 assert(Scope &&
"Unable to calculate scope dominance graph!");
239 WorkStack.push_back(std::make_pair(Scope, 0));
240 unsigned Counter = 0;
241 while (!WorkStack.empty()) {
242 auto &ScopePosition = WorkStack.back();
244 size_t ChildNum = ScopePosition.second++;
246 if (ChildNum < Children.size()) {
247 auto &ChildScope = Children[ChildNum];
248 WorkStack.push_back(std::make_pair(ChildScope, 0));
249 ChildScope->setDFSIn(++Counter);
251 WorkStack.pop_back();
259 void LexicalScopes::assignInstructionRanges(
263 for (
const auto &R : MIRanges) {
265 assert(
S &&
"Lost LexicalScope for a machine instruction!");
266 if (PrevLexicalScope && !PrevLexicalScope->
dominates(
S))
268 S->openInsnRange(
R.first);
269 S->extendInsnRange(
R.second);
270 PrevLexicalScope =
S;
273 if (PrevLexicalScope)
282 assert(MF &&
"Method called on a uninitialized LexicalScopes object!");
289 if (Scope == CurrentFnLexicalScope) {
290 for (
const auto &
MBB : *MF)
299 for (
auto &R : InsnRanges)
300 for (
auto CurMBBIt = R.first->getParent()->getIterator(),
301 EndBBIt = std::next(R.second->getParent()->getIterator());
302 CurMBBIt != EndBBIt; CurMBBIt++)
307 assert(MF &&
"Unexpected uninitialized LexicalScopes object!");
313 if (Scope == CurrentFnLexicalScope &&
MBB->
getParent() == MF)
322 std::unique_ptr<BlockSetT> &Set = DominatedBlocks[
DL];
324 Set = std::make_unique<BlockSetT>();
327 return Set->contains(
MBB);
330 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
334 err <<
"DFSIn: " << DFSIn <<
" DFSOut: " << DFSOut <<
"\n";
339 err << std::string(Indent,
' ') <<
"Abstract Scope\n";
341 if (!Children.empty())
342 err << std::string(Indent + 2,
' ') <<
"Children ...\n";
343 for (
unsigned i = 0,
e = Children.size();
i !=
e; ++
i)
344 if (Children[
i] !=
this)
345 Children[
i]->dump(Indent + 2);