27 #define DEBUG_TYPE "lexicalscopes"
32 CurrentFnLexicalScope =
nullptr;
33 LexicalScopeMap.clear();
34 AbstractScopeMap.clear();
35 InlinedLexicalScopeMap.clear();
36 AbstractScopesList.clear();
45 extractLexicalScopes(MIRanges, MI2ScopeMap);
46 if (CurrentFnLexicalScope) {
47 constructScopeNest(CurrentFnLexicalScope);
48 assignInstructionRanges(MIRanges, MI2ScopeMap);
54 void LexicalScopes::extractLexicalScopes(
59 for (
const auto &MBB : *MF) {
63 for (
const auto &MInsn : MBB) {
78 if (MInsn.isDebugValue())
86 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
91 RangeBeginMI = &MInsn;
99 if (RangeBeginMI && PrevMI && PrevDL) {
102 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
116 if (
auto *
File = dyn_cast<DILexicalBlockFile>(Scope))
117 Scope =
File->getScope();
119 if (
auto *IA = DL->getInlinedAt()) {
120 auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
121 return I != InlinedLexicalScopeMap.end() ? &
I->second :
nullptr;
134 return getOrCreateInlinedScope(Scope, IA);
137 return getOrCreateRegularScope(Scope);
142 LexicalScopes::getOrCreateRegularScope(
const DILocalScope *Scope) {
143 if (
auto *
File = dyn_cast<DILexicalBlockFile>(Scope))
144 Scope =
File->getScope();
146 auto I = LexicalScopeMap.find(Scope);
147 if (
I != LexicalScopeMap.end())
152 if (
auto *
Block = dyn_cast<DILexicalBlockBase>(Scope))
153 Parent = getOrCreateLexicalScope(
Block->getScope());
154 I = LexicalScopeMap.emplace(std::piecewise_construct,
155 std::forward_as_tuple(Scope),
156 std::forward_as_tuple(Parent, Scope,
nullptr,
160 assert(cast<DISubprogram>(Scope)->describes(MF->getFunction()));
161 assert(!CurrentFnLexicalScope);
162 CurrentFnLexicalScope = &
I->second;
170 LexicalScopes::getOrCreateInlinedScope(
const DILocalScope *Scope,
172 std::pair<const DILocalScope *, const DILocation *>
P(Scope, InlinedAt);
173 auto I = InlinedLexicalScopeMap.find(
P);
174 if (
I != InlinedLexicalScopeMap.end())
178 if (
auto *
Block = dyn_cast<DILexicalBlockBase>(Scope))
179 Parent = getOrCreateInlinedScope(
Block->getScope(), InlinedAt);
181 Parent = getOrCreateLexicalScope(InlinedAt);
183 I = InlinedLexicalScopeMap.emplace(std::piecewise_construct,
184 std::forward_as_tuple(
P),
185 std::forward_as_tuple(Parent, Scope,
194 assert(Scope &&
"Invalid Scope encoding!");
196 if (
auto *
File = dyn_cast<DILexicalBlockFile>(Scope))
197 Scope =
File->getScope();
198 auto I = AbstractScopeMap.find(Scope);
199 if (
I != AbstractScopeMap.end())
204 if (
auto *
Block = dyn_cast<DILexicalBlockBase>(Scope))
207 I = AbstractScopeMap.emplace(std::piecewise_construct,
208 std::forward_as_tuple(Scope),
209 std::forward_as_tuple(Parent, Scope,
210 nullptr,
true)).first;
211 if (isa<DISubprogram>(Scope))
212 AbstractScopesList.push_back(&
I->second);
217 void LexicalScopes::constructScopeNest(
LexicalScope *Scope) {
218 assert(Scope &&
"Unable to calculate scope dominance graph!");
221 unsigned Counter = 0;
222 while (!WorkStack.
empty()) {
225 bool visitedChildren =
false;
232 visitedChildren =
true;
237 if (!visitedChildren) {
246 void LexicalScopes::assignInstructionRanges(
256 assert(S &&
"Lost LexicalScope for a machine instruction!");
257 if (PrevLexicalScope && !PrevLexicalScope->
dominates(S))
261 PrevLexicalScope = S;
264 if (PrevLexicalScope)
278 if (Scope == CurrentFnLexicalScope) {
279 for (
const auto &MBB : *MF)
286 E = InsnRanges.
end();
289 MBBs.
insert(R.first->getParent());
301 if (Scope == CurrentFnLexicalScope && MBB->
getParent() == MF)
308 if (
LexicalScope *IScope = getOrCreateLexicalScope(IDL))
320 err <<
"DFSIn: " << DFSIn <<
" DFSOut: " << DFSOut <<
"\n";
325 err << std::string(Indent,
' ') <<
"Abstract Scope\n";
327 if (!Children.
empty())
328 err << std::string(Indent + 2,
' ') <<
"Children ...\n";
329 for (
unsigned i = 0, e = Children.
size(); i != e; ++i)
330 if (Children[i] !=
this)
331 Children[i]->dump(Indent + 2);
void push_back(const T &Elt)
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
void openInsnRange(const MachineInstr *MI)
openInsnRange - This scope covers instruction range starting from MI.
void dump(unsigned Indent=0) const
dump - print lexical scope.
void extendInsnRange(const MachineInstr *MI)
extendInsnRange - Extend the current instruction range covered by this scope.
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
bool dominates(const DILocation *DL, MachineBasicBlock *MBB)
dominates - Return true if DebugLoc's lexical scope dominates at least one machine instruction's lexi...
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
SmallVectorImpl< InsnRange > & getRanges()
LexicalScope - This class is used to track scope information.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
LexicalScope * getOrCreateAbstractScope(const DILocalScope *Scope)
getOrCreateAbstractScope - Find or create an abstract lexical scope.
SmallVectorImpl< LexicalScope * > & getChildren()
void setDFSOut(unsigned O)
void reset()
releaseMemory - release memory.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
void initialize(const MachineFunction &)
initialize - Scan machine function and constuct lexical scope nest, resets the instance if necessary...
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
bundle_iterator< MachineInstr, instr_iterator > iterator
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
bool dominates(const LexicalScope *S) const
dominates - Return true if current scope dominates given lexical scope.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
unsigned getDFSOut() const
void setDFSIn(unsigned I)
void getMachineBasicBlocks(const DILocation *DL, SmallPtrSetImpl< const MachineBasicBlock * > &MBBs)
getMachineBasicBlocks - Populate given set using machine basic blocks which have machine instructions...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Representation of each machine instruction.
void closeInsnRange(LexicalScope *NewScope=nullptr)
closeInsnRange - Create a range based on FirstInsn and LastInsn collected until now.
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.
This class implements an extremely fast bulk output stream that can only output to a stream...