23 #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();
59 extractLexicalScopes(MIRanges, MI2ScopeMap);
60 if (CurrentFnLexicalScope) {
61 constructScopeNest(CurrentFnLexicalScope);
62 assignInstructionRanges(MIRanges, MI2ScopeMap);
68 void LexicalScopes::extractLexicalScopes(
72 for (
const auto &MBB : *MF) {
76 for (
const auto &MInsn : MBB) {
92 if (MInsn.isMetaInstruction())
100 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
105 RangeBeginMI = &MInsn;
113 if (RangeBeginMI && PrevMI && PrevDL) {
116 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
132 if (
auto *IA = DL->getInlinedAt()) {
133 auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
134 return I != InlinedLexicalScopeMap.end() ? &
I->second :
nullptr;
147 return getOrCreateLexicalScope(IA);
151 return getOrCreateInlinedScope(Scope, IA);
154 return getOrCreateRegularScope(Scope);
159 LexicalScopes::getOrCreateRegularScope(
const DILocalScope *Scope) {
160 assert(Scope &&
"Invalid Scope encoding!");
163 auto I = LexicalScopeMap.find(Scope);
164 if (
I != LexicalScopeMap.end())
169 if (
auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
170 Parent = getOrCreateLexicalScope(Block->getScope());
171 I = LexicalScopeMap.emplace(std::piecewise_construct,
172 std::forward_as_tuple(Scope),
173 std::forward_as_tuple(Parent, Scope,
nullptr,
178 assert(!CurrentFnLexicalScope);
179 CurrentFnLexicalScope = &
I->second;
187 LexicalScopes::getOrCreateInlinedScope(
const DILocalScope *Scope,
189 assert(Scope &&
"Invalid Scope encoding!");
191 std::pair<const DILocalScope *, const DILocation *>
P(Scope, InlinedAt);
192 auto I = InlinedLexicalScopeMap.find(P);
193 if (
I != InlinedLexicalScopeMap.end())
197 if (
auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
198 Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt);
200 Parent = getOrCreateLexicalScope(InlinedAt);
202 I = InlinedLexicalScopeMap
203 .emplace(std::piecewise_construct, std::forward_as_tuple(P),
204 std::forward_as_tuple(Parent, Scope, InlinedAt,
false))
212 assert(Scope &&
"Invalid Scope encoding!");
214 auto I = AbstractScopeMap.find(Scope);
215 if (
I != AbstractScopeMap.end())
220 if (
auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
223 I = AbstractScopeMap.emplace(std::piecewise_construct,
224 std::forward_as_tuple(Scope),
225 std::forward_as_tuple(Parent, Scope,
226 nullptr,
true)).first;
227 if (isa<DISubprogram>(Scope))
228 AbstractScopesList.push_back(&
I->second);
233 void LexicalScopes::constructScopeNest(
LexicalScope *Scope) {
234 assert(Scope &&
"Unable to calculate scope dominance graph!");
237 unsigned Counter = 0;
238 while (!WorkStack.
empty()) {
241 bool visitedChildren =
false;
242 for (
auto &ChildScope : Children)
243 if (!ChildScope->getDFSOut()) {
245 visitedChildren =
true;
246 ChildScope->setDFSIn(++Counter);
249 if (!visitedChildren) {
258 void LexicalScopes::assignInstructionRanges(
262 for (
const auto &R : MIRanges) {
264 assert(S &&
"Lost LexicalScope for a machine instruction!");
265 if (PrevLexicalScope && !PrevLexicalScope->
dominates(S))
269 PrevLexicalScope = S;
272 if (PrevLexicalScope)
281 assert(MF &&
"Method called on a uninitialized LexicalScopes object!");
288 if (Scope == CurrentFnLexicalScope) {
289 for (
const auto &MBB : *MF)
295 for (
auto &R : InsnRanges)
296 MBBs.
insert(R.first->getParent());
302 assert(MF &&
"Unexpected uninitialized LexicalScopes object!");
308 if (Scope == CurrentFnLexicalScope && MBB->
getParent() == MF)
312 for (
auto &
I : *MBB) {
314 if (
LexicalScope *IScope = getOrCreateLexicalScope(IDL))
321 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 325 err <<
"DFSIn: " << DFSIn <<
" DFSOut: " << DFSOut <<
"\n";
330 err << std::string(Indent,
' ') <<
"Abstract Scope\n";
332 if (!Children.empty())
333 err << std::string(Indent + 2,
' ') <<
"Children ...\n";
334 for (
unsigned i = 0, e = Children.size(); i != e; ++i)
335 if (Children[i] !=
this)
336 Children[i]->dump(Indent + 2);
void openInsnRange(const MachineInstr *MI)
openInsnRange - This scope covers instruction range starting from MI.
void extendInsnRange(const MachineInstr *MI)
extendInsnRange - Extend the current instruction range covered by this scope.
This class represents lattice values for constants.
void dump(unsigned Indent=0) const
dump - print lexical scope.
void push_back(const T &Elt)
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.
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.
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.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
DISubprogram * getSubprogram() const
Get the attached subprogram.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void getMachineBasicBlocks(const DILocation *DL, SmallPtrSetImpl< const MachineBasicBlock *> &MBBs)
getMachineBasicBlocks - Populate given set using machine basic blocks which have machine instructions...
DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DISubprogram * getSubprogram() const
Get the subprogram for this scope.
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_NODISCARD bool empty() const
void closeInsnRange(LexicalScope *NewScope=nullptr)
closeInsnRange - Create a range based on FirstInsn and LastInsn collected until now.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
bool dominates(const LexicalScope *S) const
dominates - Return true if current scope dominates given lexical scope.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.