mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
Provide utility to extract and use lexical scoping information from machine instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137237 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8533ebad6f
commit
103b8e653c
247
include/llvm/CodeGen/LexicalScopes.h
Normal file
247
include/llvm/CodeGen/LexicalScopes.h
Normal file
@ -0,0 +1,247 @@
|
||||
//===- LexicalScopes.cpp - Collecting lexical scope info -*- C++ -*--------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements LexicalScopes analysis.
|
||||
//
|
||||
// This pass collects lexical scope information and maps machine instructions
|
||||
// to respective lexical scopes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_LEXICALSCOPES_H
|
||||
#define LLVM_CODEGEN_LEXICALSCOPES_H
|
||||
|
||||
#include "llvm/Metadata.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/DebugLoc.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
#include <utility>
|
||||
namespace llvm {
|
||||
|
||||
class MachineInstr;
|
||||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class LexicalScope;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// InsnRange - This is used to track range of instructions with identical
|
||||
/// lexical scope.
|
||||
///
|
||||
typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// LexicalScopes - This class provides interface to collect and use lexical
|
||||
/// scoping information from machine instruction.
|
||||
///
|
||||
class LexicalScopes {
|
||||
public:
|
||||
LexicalScopes() : MF(NULL), CurrentFnLexicalScope(NULL) { }
|
||||
~LexicalScopes();
|
||||
|
||||
/// initialize - Scan machine function and constuct lexical scope nest.
|
||||
virtual void initialize(const MachineFunction &);
|
||||
|
||||
/// releaseMemory - release memory.
|
||||
virtual void releaseMemory();
|
||||
|
||||
/// empty - Return true if there is any lexical scope information available.
|
||||
bool empty() { return CurrentFnLexicalScope == NULL; }
|
||||
|
||||
/// isCurrentFunctionScope - Return true if given lexical scope represents
|
||||
/// current function.
|
||||
bool isCurrentFunctionScope(const LexicalScope *LS) {
|
||||
return LS == CurrentFnLexicalScope;
|
||||
}
|
||||
|
||||
/// getCurrentFunctionScope - Return lexical scope for the current function.
|
||||
LexicalScope *getCurrentFunctionScope() const { return CurrentFnLexicalScope;}
|
||||
|
||||
/// getMachineBasicBlocks - Populate given set using machine basic blocks which
|
||||
/// have machine instructions that belong to lexical scope identified by
|
||||
/// DebugLoc.
|
||||
void getMachineBasicBlocks(DebugLoc DL,
|
||||
SmallPtrSet<const MachineBasicBlock*, 4> &MBBs);
|
||||
|
||||
/// dominates - Return true if DebugLoc's lexical scope dominates at least one
|
||||
/// machine instruction's lexical scope in a given machine basic block.
|
||||
bool dominates(DebugLoc DL, MachineBasicBlock *MBB);
|
||||
|
||||
/// findLexicalScope - Find lexical scope, either regular or inlined, for the
|
||||
/// given DebugLoc. Return NULL if not found.
|
||||
LexicalScope *findLexicalScope(DebugLoc DL);
|
||||
|
||||
/// getAbstractScopesList - Return a reference to list of abstract scopes.
|
||||
SmallVector<LexicalScope *, 4> &getAbstractScopesList() {
|
||||
return AbstractScopesList;
|
||||
}
|
||||
|
||||
/// findAbstractScope - Find an abstract scope or return NULL.
|
||||
LexicalScope *findAbstractScope(const MDNode *N) {
|
||||
return AbstractScopeMap.lookup(N);
|
||||
}
|
||||
|
||||
/// findInlinedScope - Find an inlined scope for the given DebugLoc or return
|
||||
/// NULL.
|
||||
LexicalScope *findInlinedScope(DebugLoc DL) {
|
||||
return InlinedLexicalScopeMap.lookup(DL);
|
||||
}
|
||||
|
||||
/// findLexicalScope - Find regular lexical scope or return NULL.
|
||||
LexicalScope *findLexicalScope(const MDNode *N) {
|
||||
return LexicalScopeMap.lookup(N);
|
||||
}
|
||||
|
||||
/// dump - Print data structures to dbgs().
|
||||
void dump();
|
||||
|
||||
private:
|
||||
|
||||
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
|
||||
/// not available then create new lexical scope.
|
||||
LexicalScope *getOrCreateLexicalScope(DebugLoc DL);
|
||||
|
||||
/// getOrCreateRegularScope - Find or create a regular lexical scope.
|
||||
LexicalScope *getOrCreateRegularScope(MDNode *Scope);
|
||||
|
||||
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
|
||||
LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
|
||||
|
||||
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
|
||||
LexicalScope *getOrCreateAbstractScope(const MDNode *N);
|
||||
|
||||
/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
|
||||
/// for the given machine function.
|
||||
void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
|
||||
DenseMap<const MachineInstr *, LexicalScope *> &M);
|
||||
void constructScopeNest(LexicalScope *Scope);
|
||||
void assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
|
||||
DenseMap<const MachineInstr *, LexicalScope *> &M);
|
||||
|
||||
private:
|
||||
const MachineFunction *MF;
|
||||
|
||||
/// LexicalScopeMap - Tracks the scopes in the current function. Owns the
|
||||
/// contained LexicalScope*s.
|
||||
DenseMap<const MDNode *, LexicalScope *> LexicalScopeMap;
|
||||
|
||||
/// InlinedLexicalScopeMap - Tracks inlined function scopes in current function.
|
||||
DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap;
|
||||
|
||||
/// AbstractScopeMap - These scopes are not included LexicalScopeMap.
|
||||
/// AbstractScopes owns its LexicalScope*s.
|
||||
DenseMap<const MDNode *, LexicalScope *> AbstractScopeMap;
|
||||
|
||||
/// AbstractScopesList - Tracks abstract scopes constructed while processing
|
||||
/// a function.
|
||||
SmallVector<LexicalScope *, 4>AbstractScopesList;
|
||||
|
||||
/// CurrentFnLexicalScope - Top level scope for the current function.
|
||||
///
|
||||
LexicalScope *CurrentFnLexicalScope;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// LexicalScope - This class is used to track scope information.
|
||||
///
|
||||
class LexicalScope {
|
||||
|
||||
public:
|
||||
LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
|
||||
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
|
||||
LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0), IndentLevel(0) {
|
||||
if (Parent)
|
||||
Parent->addChild(this);
|
||||
}
|
||||
|
||||
virtual ~LexicalScope() {}
|
||||
|
||||
// Accessors.
|
||||
LexicalScope *getParent() const { return Parent; }
|
||||
const MDNode *getDesc() const { return Desc; }
|
||||
const MDNode *getInlinedAt() const { return InlinedAtLocation; }
|
||||
const MDNode *getScopeNode() const { return Desc; }
|
||||
bool isAbstractScope() const { return AbstractScope; }
|
||||
SmallVector<LexicalScope *, 4> &getChildren() { return Children; }
|
||||
SmallVector<InsnRange, 4> &getRanges() { return Ranges; }
|
||||
|
||||
/// addChild - Add a child scope.
|
||||
void addChild(LexicalScope *S) { Children.push_back(S); }
|
||||
|
||||
/// openInsnRange - This scope covers instruction range starting from MI.
|
||||
void openInsnRange(const MachineInstr *MI) {
|
||||
if (!FirstInsn)
|
||||
FirstInsn = MI;
|
||||
|
||||
if (Parent)
|
||||
Parent->openInsnRange(MI);
|
||||
}
|
||||
|
||||
/// extendInsnRange - Extend the current instruction range covered by
|
||||
/// this scope.
|
||||
void extendInsnRange(const MachineInstr *MI) {
|
||||
assert (FirstInsn && "MI Range is not open!");
|
||||
LastInsn = MI;
|
||||
if (Parent)
|
||||
Parent->extendInsnRange(MI);
|
||||
}
|
||||
|
||||
/// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
|
||||
/// until now. This is used when a new scope is encountered while walking
|
||||
/// machine instructions.
|
||||
void closeInsnRange(LexicalScope *NewScope = NULL) {
|
||||
assert (LastInsn && "Last insn missing!");
|
||||
Ranges.push_back(InsnRange(FirstInsn, LastInsn));
|
||||
FirstInsn = NULL;
|
||||
LastInsn = NULL;
|
||||
// If Parent dominates NewScope then do not close Parent's instruction
|
||||
// range.
|
||||
if (Parent && (!NewScope || !Parent->dominates(NewScope)))
|
||||
Parent->closeInsnRange(NewScope);
|
||||
}
|
||||
|
||||
/// dominates - Return true if current scope dominsates given lexical scope.
|
||||
bool dominates(const LexicalScope *S) {
|
||||
if (S == this)
|
||||
return true;
|
||||
if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Depth First Search support to walk and manipulate LexicalScope hierarchy.
|
||||
unsigned getDFSOut() const { return DFSOut; }
|
||||
void setDFSOut(unsigned O) { DFSOut = O; }
|
||||
unsigned getDFSIn() const { return DFSIn; }
|
||||
void setDFSIn(unsigned I) { DFSIn = I; }
|
||||
|
||||
/// dump - print lexical scope.
|
||||
void dump() const;
|
||||
|
||||
private:
|
||||
LexicalScope *Parent; // Parent to this scope.
|
||||
AssertingVH<const MDNode> Desc; // Debug info descriptor.
|
||||
AssertingVH<const MDNode> InlinedAtLocation; // Location at which this
|
||||
// scope is inlined.
|
||||
bool AbstractScope; // Abstract Scope
|
||||
SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope.
|
||||
// Contents not owned.
|
||||
SmallVector<InsnRange, 4> Ranges;
|
||||
|
||||
const MachineInstr *LastInsn; // Last instruction of this scope.
|
||||
const MachineInstr *FirstInsn; // First instruction of this scope.
|
||||
unsigned DFSIn, DFSOut; // In & Out Depth use to determine
|
||||
// scope nesting.
|
||||
mutable unsigned IndentLevel; // Private state for dump()
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
@ -23,6 +23,7 @@ add_llvm_library(LLVMCodeGen
|
||||
IntrinsicLowering.cpp
|
||||
LLVMTargetMachine.cpp
|
||||
LatencyPriorityQueue.cpp
|
||||
LexicalScopes.cpp
|
||||
LiveDebugVariables.cpp
|
||||
LiveInterval.cpp
|
||||
LiveIntervalAnalysis.cpp
|
||||
|
305
lib/CodeGen/LexicalScopes.cpp
Normal file
305
lib/CodeGen/LexicalScopes.cpp
Normal file
@ -0,0 +1,305 @@
|
||||
//===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements LexicalScopes analysis.
|
||||
//
|
||||
// This pass collects lexical scope information and maps machine instructions
|
||||
// to respective lexical scopes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "lexicalscopes"
|
||||
#include "llvm/CodeGen/LexicalScopes.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Analysis/DebugInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
using namespace llvm;
|
||||
|
||||
LexicalScopes::~LexicalScopes() {
|
||||
releaseMemory();
|
||||
}
|
||||
|
||||
/// releaseMemory - release memory.
|
||||
void LexicalScopes::releaseMemory() {
|
||||
MF = NULL;
|
||||
CurrentFnLexicalScope = NULL;
|
||||
DeleteContainerSeconds(LexicalScopeMap);
|
||||
DeleteContainerSeconds(AbstractScopeMap);
|
||||
InlinedLexicalScopeMap.clear();
|
||||
AbstractScopesList.clear();
|
||||
}
|
||||
|
||||
/// initialize - Scan machine function and constuct lexical scope nest.
|
||||
void LexicalScopes::initialize(const MachineFunction &Fn) {
|
||||
releaseMemory();
|
||||
MF = &Fn;
|
||||
SmallVector<InsnRange, 4> MIRanges;
|
||||
DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
|
||||
extractLexicalScopes(MIRanges, MI2ScopeMap);
|
||||
if (CurrentFnLexicalScope) {
|
||||
constructScopeNest(CurrentFnLexicalScope);
|
||||
assignInstructionRanges(MIRanges, MI2ScopeMap);
|
||||
}
|
||||
}
|
||||
|
||||
/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
|
||||
/// for the given machine function.
|
||||
void LexicalScopes::
|
||||
extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
|
||||
DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
|
||||
|
||||
// Scan each instruction and create scopes. First build working set of scopes.
|
||||
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
|
||||
I != E; ++I) {
|
||||
const MachineInstr *RangeBeginMI = NULL;
|
||||
const MachineInstr *PrevMI = NULL;
|
||||
DebugLoc PrevDL;
|
||||
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
|
||||
II != IE; ++II) {
|
||||
const MachineInstr *MInsn = II;
|
||||
|
||||
// Check if instruction has valid location information.
|
||||
const DebugLoc MIDL = MInsn->getDebugLoc();
|
||||
if (MIDL.isUnknown()) {
|
||||
PrevMI = MInsn;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If scope has not changed then skip this instruction.
|
||||
if (MIDL == PrevDL) {
|
||||
PrevMI = MInsn;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore DBG_VALUE. It does not contribute to any instruction in output.
|
||||
if (MInsn->isDebugValue())
|
||||
continue;
|
||||
|
||||
if (RangeBeginMI) {
|
||||
// If we have already seen a beginning of an instruction range and
|
||||
// current instruction scope does not match scope of first instruction
|
||||
// in this range then create a new instruction range.
|
||||
InsnRange R(RangeBeginMI, PrevMI);
|
||||
MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
|
||||
MIRanges.push_back(R);
|
||||
}
|
||||
|
||||
// This is a beginning of a new instruction range.
|
||||
RangeBeginMI = MInsn;
|
||||
|
||||
// Reset previous markers.
|
||||
PrevMI = MInsn;
|
||||
PrevDL = MIDL;
|
||||
}
|
||||
|
||||
// Create last instruction range.
|
||||
if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) {
|
||||
InsnRange R(RangeBeginMI, PrevMI);
|
||||
MIRanges.push_back(R);
|
||||
MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// findLexicalScope - Find lexical scope, either regular or inlined, for the
|
||||
/// given DebugLoc. Return NULL if not found.
|
||||
LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
|
||||
MDNode *Scope = NULL;
|
||||
MDNode *IA = NULL;
|
||||
DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
|
||||
if (!Scope) return NULL;
|
||||
if (IA)
|
||||
return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
|
||||
return LexicalScopeMap.lookup(DL.getScope(Scope->getContext()));
|
||||
}
|
||||
|
||||
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
|
||||
/// not available then create new lexical scope.
|
||||
LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) {
|
||||
MDNode *Scope = NULL;
|
||||
MDNode *InlinedAt = NULL;
|
||||
DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext());
|
||||
if (InlinedAt) {
|
||||
// Create an abstract scope for inlined function.
|
||||
getOrCreateAbstractScope(Scope);
|
||||
// Create an inlined scope for inlined function.
|
||||
return getOrCreateInlinedScope(Scope, InlinedAt);
|
||||
}
|
||||
|
||||
return getOrCreateRegularScope(Scope);
|
||||
}
|
||||
|
||||
/// getOrCreateRegularScope - Find or create a regular lexical scope.
|
||||
LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
|
||||
LexicalScope *WScope = LexicalScopeMap.lookup(Scope);
|
||||
if (WScope)
|
||||
return WScope;
|
||||
|
||||
LexicalScope *Parent = NULL;
|
||||
if (DIDescriptor(Scope).isLexicalBlock())
|
||||
Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
|
||||
WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false);
|
||||
LexicalScopeMap.insert(std::make_pair(Scope, WScope));
|
||||
if (!Parent && DIDescriptor(Scope).isSubprogram()
|
||||
&& DISubprogram(Scope).describes(MF->getFunction()))
|
||||
CurrentFnLexicalScope = WScope;
|
||||
|
||||
return WScope;
|
||||
}
|
||||
|
||||
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
|
||||
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
|
||||
MDNode *InlinedAt) {
|
||||
LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt);
|
||||
if (InlinedScope)
|
||||
return InlinedScope;
|
||||
|
||||
DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
|
||||
InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc),
|
||||
DIDescriptor(Scope), InlinedAt, false);
|
||||
InlinedLexicalScopeMap[InlinedLoc] = InlinedScope;
|
||||
LexicalScopeMap[InlinedAt] = InlinedScope;
|
||||
return InlinedScope;
|
||||
}
|
||||
|
||||
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
|
||||
LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
|
||||
assert(N && "Invalid Scope encoding!");
|
||||
|
||||
LexicalScope *AScope = AbstractScopeMap.lookup(N);
|
||||
if (AScope)
|
||||
return AScope;
|
||||
|
||||
LexicalScope *Parent = NULL;
|
||||
DIDescriptor Scope(N);
|
||||
if (Scope.isLexicalBlock()) {
|
||||
DILexicalBlock DB(N);
|
||||
DIDescriptor ParentDesc = DB.getContext();
|
||||
Parent = getOrCreateAbstractScope(ParentDesc);
|
||||
}
|
||||
AScope = new LexicalScope(Parent, DIDescriptor(N), NULL, true);
|
||||
AbstractScopeMap[N] = AScope;
|
||||
if (DIDescriptor(N).isSubprogram())
|
||||
AbstractScopesList.push_back(AScope);
|
||||
return AScope;
|
||||
}
|
||||
|
||||
/// constructScopeNest
|
||||
void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
|
||||
assert (Scope && "Unable to calculate scop edominance graph!");
|
||||
SmallVector<LexicalScope *, 4> WorkStack;
|
||||
WorkStack.push_back(Scope);
|
||||
unsigned Counter = 0;
|
||||
while (!WorkStack.empty()) {
|
||||
LexicalScope *WS = WorkStack.back();
|
||||
const SmallVector<LexicalScope *, 4> &Children = WS->getChildren();
|
||||
bool visitedChildren = false;
|
||||
for (SmallVector<LexicalScope *, 4>::const_iterator SI = Children.begin(),
|
||||
SE = Children.end(); SI != SE; ++SI) {
|
||||
LexicalScope *ChildScope = *SI;
|
||||
if (!ChildScope->getDFSOut()) {
|
||||
WorkStack.push_back(ChildScope);
|
||||
visitedChildren = true;
|
||||
ChildScope->setDFSIn(++Counter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!visitedChildren) {
|
||||
WorkStack.pop_back();
|
||||
WS->setDFSOut(++Counter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// assignInstructionRanges - Find ranges of instructions covered by each lexical
|
||||
/// scope.
|
||||
void LexicalScopes::
|
||||
assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
|
||||
DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
|
||||
|
||||
LexicalScope *PrevLexicalScope = NULL;
|
||||
for (SmallVectorImpl<InsnRange>::const_iterator RI = MIRanges.begin(),
|
||||
RE = MIRanges.end(); RI != RE; ++RI) {
|
||||
const InsnRange &R = *RI;
|
||||
LexicalScope *S = MI2ScopeMap.lookup(R.first);
|
||||
assert (S && "Lost LexicalScope for a machine instruction!");
|
||||
if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
|
||||
PrevLexicalScope->closeInsnRange(S);
|
||||
S->openInsnRange(R.first);
|
||||
S->extendInsnRange(R.second);
|
||||
PrevLexicalScope = S;
|
||||
}
|
||||
|
||||
if (PrevLexicalScope)
|
||||
PrevLexicalScope->closeInsnRange();
|
||||
}
|
||||
|
||||
/// getMachineBasicBlocks - Populate given set using machine basic blocks which
|
||||
/// have machine instructions that belong to lexical scope identified by
|
||||
/// DebugLoc.
|
||||
void LexicalScopes::
|
||||
getMachineBasicBlocks(DebugLoc DL, SmallPtrSet<const MachineBasicBlock*, 4> &MBBs) {
|
||||
MBBs.clear();
|
||||
LexicalScope *Scope = getOrCreateLexicalScope(DL);
|
||||
if (!Scope)
|
||||
return;
|
||||
|
||||
SmallVector<InsnRange, 4> &InsnRanges = Scope->getRanges();
|
||||
for (SmallVector<InsnRange, 4>::iterator I = InsnRanges.begin(),
|
||||
E = InsnRanges.end(); I != E; ++I) {
|
||||
InsnRange &R = *I;
|
||||
MBBs.insert(R.first->getParent());
|
||||
}
|
||||
}
|
||||
|
||||
/// dominates - Return true if DebugLoc's lexical scope dominates at least one
|
||||
/// machine instruction's lexical scope in a given machine basic block.
|
||||
bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) {
|
||||
LexicalScope *Scope = getOrCreateLexicalScope(DL);
|
||||
if (!Scope)
|
||||
return false;
|
||||
bool Result = false;
|
||||
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
|
||||
I != E; ++I) {
|
||||
DebugLoc IDL = I->getDebugLoc();
|
||||
if (IDL.isUnknown())
|
||||
continue;
|
||||
if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
|
||||
if (Scope->dominates(IScope))
|
||||
return true;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// dump - Print data structures.
|
||||
void LexicalScope::dump() const {
|
||||
#ifndef NDEBUG
|
||||
raw_ostream &err = dbgs();
|
||||
err.indent(IndentLevel);
|
||||
err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
|
||||
const MDNode *N = Desc;
|
||||
N->dump();
|
||||
if (AbstractScope)
|
||||
err << "Abstract Scope\n";
|
||||
|
||||
IndentLevel += 2;
|
||||
if (!Children.empty())
|
||||
err << "Children ...\n";
|
||||
for (unsigned i = 0, e = Children.size(); i != e; ++i)
|
||||
if (Children[i] != this)
|
||||
Children[i]->dump();
|
||||
|
||||
IndentLevel -= 2;
|
||||
#endif
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user