16#ifndef LLVM_CODEGEN_LEXICALSCOPES_H
17#define LLVM_CODEGEN_LEXICALSCOPES_H
26#include <unordered_map>
39using InsnRange = std::pair<const MachineInstr *, const MachineInstr *>;
48 : Parent(
P), Desc(
D), InlinedAtLocation(
I), AbstractScope(
A) {
50 assert(
D->getSubprogram()->getUnit()->getEmissionKind() !=
52 "Don't build lexical scopes for non-debug locations");
53 assert(
D->isResolved() &&
"Expected resolved node");
54 assert((!
I ||
I->isResolved()) &&
"Expected resolved node");
56 Parent->addChild(
this);
80 Parent->openInsnRange(
MI);
85 assert(FirstInsn &&
"MI Range is not open!");
88 Parent->extendInsnRange(
MI);
95 assert(LastInsn &&
"Last insn missing!");
96 Ranges.push_back(
InsnRange(FirstInsn, LastInsn));
101 if (Parent && (!NewScope || !Parent->dominates(NewScope)))
102 Parent->closeInsnRange(NewScope);
164 bool empty() {
return CurrentFnLexicalScope ==
nullptr; }
168 return CurrentFnLexicalScope;
187 return AbstractScopesList;
192 auto I = AbstractScopeMap.find(
N);
193 return I != AbstractScopeMap.end() ? &
I->second :
nullptr;
198 auto I = InlinedLexicalScopeMap.find(std::make_pair(
N, IA));
199 return I != InlinedLexicalScopeMap.end() ? &
I->second :
nullptr;
204 auto I = LexicalScopeMap.find(
N);
205 return I != LexicalScopeMap.end() ? &
I->second :
nullptr;
213 return FunctionMap.lookup(SP);
223 return DL ? getOrCreateLexicalScope(
DL->getScope(),
DL->getInlinedAt())
228 LexicalScope *getOrCreateRegularScope(
const DILocalScope *Scope);
231 LexicalScope *getOrCreateInlinedScope(
const DILocalScope *Scope,
232 const DILocation *InlinedAt);
236 void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
237 DenseMap<const MachineInstr *, LexicalScope *> &M);
238 void constructScopeNest(LexicalScope *Scope);
240 assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
241 DenseMap<const MachineInstr *, LexicalScope *> &M);
243 const MachineFunction *MF =
nullptr;
246 DenseMap<const DISubprogram *, const Function *> FunctionMap;
250 std::unordered_map<const DILocalScope *, LexicalScope> LexicalScopeMap;
253 std::unordered_map<std::pair<const DILocalScope *, const DILocation *>,
255 pair_hash<const DILocalScope *, const DILocation *>>
256 InlinedLexicalScopeMap;
260 std::unordered_map<const DILocalScope *, LexicalScope> AbstractScopeMap;
266 LexicalScope *CurrentFnLexicalScope =
nullptr;
270 using BlockSetT = SmallPtrSet<const MachineBasicBlock *, 4>;
271 DenseMap<const DILocation *, std::unique_ptr<BlockSetT>> DominatedBlocks;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This file defines the DenseMap class.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Subprogram description. Uses SubclassData1.
This class is used to track scope information.
unsigned getDFSIn() const
void extendInsnRange(const MachineInstr *MI)
Extend the current instruction range covered by this scope.
SmallVectorImpl< LexicalScope * > & getChildren()
LexicalScope(const LexicalScope &)=delete
const DILocation * getInlinedAt() const
SmallVectorImpl< InsnRange > & getRanges()
LexicalScope(LexicalScope *P, const DILocalScope *D, const DILocation *I, bool A)
const DILocalScope * getScopeNode() const
void setDFSOut(unsigned O)
unsigned getDFSOut() const
void openInsnRange(const MachineInstr *MI)
This scope covers instruction range starting from MI.
void addChild(LexicalScope *S)
Add a child scope.
LLVM_ABI void dump(unsigned Indent=0) const
Print lexical scope.
void setDFSIn(unsigned I)
LexicalScope & operator=(const LexicalScope &)=delete
LexicalScope * getParent() const
const MDNode * getDesc() const
bool dominates(const LexicalScope *S) const
Return true if current scope dominates given lexical scope.
void closeInsnRange(LexicalScope *NewScope=nullptr)
Create a range based on FirstInsn and LastInsn collected until now.
bool isAbstractScope() const
LexicalScopes & operator=(const LexicalScopes &)=delete
LLVM_ABI void scanFunction(const MachineFunction &)
Scan machine function and constuct lexical scope nest, resets the instance if necessary.
LLVM_ABI LexicalScope * getOrCreateAbstractScope(const DILocalScope *Scope)
Find or create an abstract lexical scope.
LLVM_ABI LexicalScope * findLexicalScope(const DILocation *DL)
Find lexical scope, either regular or inlined, for the given DebugLoc.
LLVM_ABI void getMachineBasicBlocks(const DILocation *DL, SmallPtrSetImpl< const MachineBasicBlock * > &MBBs)
Populate given set using machine basic blocks which have machine instructions that belong to lexical ...
LLVM_ABI void initialize(const Module &)
Scan module to build subprogram-to-function map.
const Function * getFunction(const DISubprogram *SP) const
Get function to which the given subprogram is attached, if exists.
ArrayRef< LexicalScope * > getAbstractScopesList() const
Return a reference to list of abstract scopes.
LexicalScope * findInlinedScope(const DILocalScope *N, const DILocation *IA)
Find an inlined scope for the given scope/inlined-at.
LexicalScope * findAbstractScope(const DILocalScope *N)
Find an abstract scope or return null.
LLVM_ABI void resetFunction()
Reset the instance so that it's prepared for another function.
LLVM_ABI void resetModule()
Reset the instance so that it's prepared for another module.
LexicalScope * findLexicalScope(const DILocalScope *N)
Find regular lexical scope or return null.
bool empty()
Return true if there is any lexical scope information available.
LLVM_ABI bool dominates(const DILocation *DL, MachineBasicBlock *MBB)
Return true if DebugLoc's lexical scope dominates at least one machine instruction's lexical scope in...
LexicalScopes(const LexicalScopes &)=delete
LexicalScope * getCurrentFunctionScope() const
Return lexical scope for the current function.
Representation of each machine instruction.
A Module instance is used to store all the information related to an LLVM module.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This is an optimization pass for GlobalISel generic memory operations.
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
This is used to track range of instructions with identical lexical scope.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...