mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 20:53:29 +08:00
Revert "[DebugInfo][DwarfDebug] Separate creation and population of abstract subprogram DIEs" (#160349)
Reverts llvm/llvm-project#159104 due to the issues reported in https://github.com/llvm/llvm-project/issues/160197.
This commit is contained in:
committed by
GitHub
parent
d0eef22171
commit
310811af6d
@@ -144,8 +144,6 @@ public:
|
||||
static bool isUnsignedDIType(const DIType *Ty);
|
||||
|
||||
const InstructionOrdering &getInstOrdering() const { return InstOrdering; }
|
||||
|
||||
const LexicalScopes &getLexicalScopes() const { return LScopes; }
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
@@ -141,18 +141,12 @@ class LexicalScopes {
|
||||
public:
|
||||
LexicalScopes() = default;
|
||||
|
||||
/// Scan module to build subprogram-to-function map.
|
||||
LLVM_ABI void initialize(const Module &);
|
||||
|
||||
/// Scan machine function and constuct lexical scope nest, resets
|
||||
/// the instance if necessary.
|
||||
LLVM_ABI void scanFunction(const MachineFunction &);
|
||||
LLVM_ABI void initialize(const MachineFunction &);
|
||||
|
||||
/// Reset the instance so that it's prepared for another module.
|
||||
LLVM_ABI void resetModule();
|
||||
|
||||
/// Reset the instance so that it's prepared for another function.
|
||||
LLVM_ABI void resetFunction();
|
||||
/// Release memory.
|
||||
LLVM_ABI void reset();
|
||||
|
||||
/// Return true if there is any lexical scope information available.
|
||||
bool empty() { return CurrentFnLexicalScope == nullptr; }
|
||||
@@ -202,11 +196,6 @@ public:
|
||||
/// Find or create an abstract lexical scope.
|
||||
LLVM_ABI LexicalScope *getOrCreateAbstractScope(const DILocalScope *Scope);
|
||||
|
||||
/// Get function to which the given subprogram is attached, if exists.
|
||||
const Function *getFunction(const DISubprogram *SP) const {
|
||||
return FunctionMap.lookup(SP);
|
||||
}
|
||||
|
||||
private:
|
||||
/// Find lexical scope for the given Scope/IA. If not available
|
||||
/// then create new lexical scope.
|
||||
@@ -236,9 +225,6 @@ private:
|
||||
|
||||
const MachineFunction *MF = nullptr;
|
||||
|
||||
/// Mapping between DISubprograms and IR functions.
|
||||
DenseMap<const DISubprogram *, const Function *> FunctionMap;
|
||||
|
||||
/// Tracks the scopes in the current function.
|
||||
// Use an unordered_map to ensure value pointer validity over insertion.
|
||||
std::unordered_map<const DILocalScope *, LexicalScope> LexicalScopeMap;
|
||||
|
||||
@@ -105,8 +105,6 @@ DebugHandlerBase::~DebugHandlerBase() = default;
|
||||
void DebugHandlerBase::beginModule(Module *M) {
|
||||
if (M->debug_compile_units().empty())
|
||||
Asm = nullptr;
|
||||
else
|
||||
LScopes.initialize(*M);
|
||||
}
|
||||
|
||||
// Each LexicalScope has first instruction and last instruction to mark
|
||||
@@ -271,7 +269,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
|
||||
|
||||
// Grab the lexical scopes for the function, if we don't have any of those
|
||||
// then we're not going to be able to do anything.
|
||||
LScopes.scanFunction(*MF);
|
||||
LScopes.initialize(*MF);
|
||||
if (LScopes.empty()) {
|
||||
beginFunctionImpl(MF);
|
||||
return;
|
||||
|
||||
@@ -537,9 +537,8 @@ void DwarfCompileUnit::addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,
|
||||
// and DW_AT_high_pc attributes. If there are global variables in this
|
||||
// scope then create and insert DIEs for these variables.
|
||||
DIE &DwarfCompileUnit::updateSubprogramScopeDIE(const DISubprogram *SP,
|
||||
const Function &F,
|
||||
MCSymbol *LineTableSym) {
|
||||
DIE *SPDie = getOrCreateSubprogramDIE(SP, &F, includeMinimalInlineScopes());
|
||||
DIE *SPDie = getOrCreateSubprogramDIE(SP, includeMinimalInlineScopes());
|
||||
SmallVector<RangeSpan, 2> BB_List;
|
||||
// If basic block sections are on, ranges for each basic block section has
|
||||
// to be emitted separately.
|
||||
@@ -1123,10 +1122,9 @@ sortLocalVars(SmallVectorImpl<DbgVariable *> &Input) {
|
||||
}
|
||||
|
||||
DIE &DwarfCompileUnit::constructSubprogramScopeDIE(const DISubprogram *Sub,
|
||||
const Function &F,
|
||||
LexicalScope *Scope,
|
||||
MCSymbol *LineTableSym) {
|
||||
DIE &ScopeDIE = updateSubprogramScopeDIE(Sub, F, LineTableSym);
|
||||
DIE &ScopeDIE = updateSubprogramScopeDIE(Sub, LineTableSym);
|
||||
|
||||
if (Scope) {
|
||||
assert(!Scope->getInlinedAt());
|
||||
@@ -1200,17 +1198,32 @@ DIE *DwarfCompileUnit::createAndAddScopeChildren(LexicalScope *Scope,
|
||||
return ObjectPointer;
|
||||
}
|
||||
|
||||
DIE &DwarfCompileUnit::getOrCreateAbstractSubprogramDIE(
|
||||
const DISubprogram *SP) {
|
||||
if (auto *AbsDef = getAbstractScopeDIEs().lookup(SP))
|
||||
return *AbsDef;
|
||||
void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
|
||||
LexicalScope *Scope) {
|
||||
auto *SP = cast<DISubprogram>(Scope->getScopeNode());
|
||||
if (getAbstractScopeDIEs().count(SP))
|
||||
return;
|
||||
|
||||
auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);
|
||||
return createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);
|
||||
}
|
||||
DIE *ContextDIE;
|
||||
DwarfCompileUnit *ContextCU = this;
|
||||
|
||||
if (includeMinimalInlineScopes())
|
||||
ContextDIE = &getUnitDie();
|
||||
// Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
|
||||
// the important distinction that the debug node is not associated with the
|
||||
// DIE (since the debug node will be associated with the concrete DIE, if
|
||||
// any). It could be refactored to some common utility function.
|
||||
else if (auto *SPDecl = SP->getDeclaration()) {
|
||||
ContextDIE = &getUnitDie();
|
||||
getOrCreateSubprogramDIE(SPDecl);
|
||||
} else {
|
||||
ContextDIE = getOrCreateContextDIE(SP->getScope());
|
||||
// The scope may be shared with a subprogram that has already been
|
||||
// constructed in another CU, in which case we need to construct this
|
||||
// subprogram in the same CU.
|
||||
ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
|
||||
}
|
||||
|
||||
DIE &DwarfCompileUnit::createAbstractSubprogramDIE(
|
||||
const DISubprogram *SP, DIE *ContextDIE, DwarfCompileUnit *ContextCU) {
|
||||
// Passing null as the associated node because the abstract definition
|
||||
// shouldn't be found by lookup.
|
||||
DIE &AbsDef = ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram,
|
||||
@@ -1224,45 +1237,8 @@ DIE &DwarfCompileUnit::createAbstractSubprogramDIE(
|
||||
DD->getDwarfVersion() <= 4 ? std::optional<dwarf::Form>()
|
||||
: dwarf::DW_FORM_implicit_const,
|
||||
dwarf::DW_INL_inlined);
|
||||
|
||||
return AbsDef;
|
||||
}
|
||||
|
||||
std::pair<DIE *, DwarfCompileUnit *>
|
||||
DwarfCompileUnit::getOrCreateAbstractSubprogramContextDIE(
|
||||
const DISubprogram *SP) {
|
||||
bool Minimal = includeMinimalInlineScopes();
|
||||
bool IgnoreScope = shouldPlaceInUnitDIE(SP, Minimal);
|
||||
DIE *ContextDIE = getOrCreateSubprogramContextDIE(SP, IgnoreScope);
|
||||
|
||||
if (auto *SPDecl = SP->getDeclaration())
|
||||
if (!Minimal)
|
||||
getOrCreateSubprogramDIE(SPDecl, nullptr);
|
||||
|
||||
// The scope may be shared with a subprogram that has already been
|
||||
// constructed in another CU, in which case we need to construct this
|
||||
// subprogram in the same CU.
|
||||
auto *ContextCU = IgnoreScope ? this : DD->lookupCU(ContextDIE->getUnitDie());
|
||||
|
||||
return std::make_pair(ContextDIE, ContextCU);
|
||||
}
|
||||
|
||||
void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
|
||||
LexicalScope *Scope) {
|
||||
auto *SP = cast<DISubprogram>(Scope->getScopeNode());
|
||||
|
||||
// Populate subprogram DIE only once.
|
||||
if (!getFinalizedAbstractSubprograms().insert(SP).second)
|
||||
return;
|
||||
|
||||
auto [ContextDIE, ContextCU] = getOrCreateAbstractSubprogramContextDIE(SP);
|
||||
DIE *AbsDef = getAbstractScopeDIEs().lookup(SP);
|
||||
if (!AbsDef)
|
||||
AbsDef = &createAbstractSubprogramDIE(SP, ContextDIE, ContextCU);
|
||||
|
||||
if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, *AbsDef))
|
||||
ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer,
|
||||
*ObjectPointer);
|
||||
if (DIE *ObjectPointer = ContextCU->createAndAddScopeChildren(Scope, AbsDef))
|
||||
ContextCU->addDIEEntry(AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
|
||||
}
|
||||
|
||||
bool DwarfCompileUnit::useGNUAnalogForDwarf5Feature() const {
|
||||
@@ -1317,9 +1293,9 @@ DwarfCompileUnit::getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const {
|
||||
}
|
||||
|
||||
DIE &DwarfCompileUnit::constructCallSiteEntryDIE(
|
||||
DIE &ScopeDIE, const DISubprogram *CalleeSP, const Function *CalleeF,
|
||||
bool IsTail, const MCSymbol *PCAddr, const MCSymbol *CallAddr,
|
||||
unsigned CallReg, DIType *AllocSiteTy) {
|
||||
DIE &ScopeDIE, const DISubprogram *CalleeSP, bool IsTail,
|
||||
const MCSymbol *PCAddr, const MCSymbol *CallAddr, unsigned CallReg,
|
||||
DIType *AllocSiteTy) {
|
||||
// Insert a call site entry DIE within ScopeDIE.
|
||||
DIE &CallSiteDIE = createAndAddDIE(getDwarf5OrGNUTag(dwarf::DW_TAG_call_site),
|
||||
ScopeDIE, nullptr);
|
||||
@@ -1329,7 +1305,7 @@ DIE &DwarfCompileUnit::constructCallSiteEntryDIE(
|
||||
addAddress(CallSiteDIE, getDwarf5OrGNUAttr(dwarf::DW_AT_call_target),
|
||||
MachineLocation(CallReg));
|
||||
} else if (CalleeSP) {
|
||||
DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP, CalleeF);
|
||||
DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
|
||||
assert(CalleeDIE && "Could not create DIE for call site entry origin");
|
||||
if (AddLinkageNamesToDeclCallOriginsForTuning(DD) &&
|
||||
!CalleeSP->isDefinition() &&
|
||||
@@ -1420,7 +1396,7 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
|
||||
if (auto *AbsSPDie = getAbstractScopeDIEs().lookup(SP))
|
||||
EntityDie = AbsSPDie;
|
||||
else
|
||||
EntityDie = getOrCreateSubprogramDIE(SP, nullptr);
|
||||
EntityDie = getOrCreateSubprogramDIE(SP);
|
||||
} else if (auto *T = dyn_cast<DIType>(Entity))
|
||||
EntityDie = getOrCreateTypeDIE(T);
|
||||
else if (auto *GV = dyn_cast<DIGlobalVariable>(Entity))
|
||||
@@ -1829,16 +1805,3 @@ DIE *DwarfCompileUnit::getOrCreateContextDIE(const DIScope *Context) {
|
||||
}
|
||||
return DwarfUnit::getOrCreateContextDIE(Context);
|
||||
}
|
||||
|
||||
DIE *DwarfCompileUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,
|
||||
const Function *F,
|
||||
bool Minimal) {
|
||||
if (!F && SP->isDefinition()) {
|
||||
F = DD->getLexicalScopes().getFunction(SP);
|
||||
|
||||
if (!F)
|
||||
return &getCU().getOrCreateAbstractSubprogramDIE(SP);
|
||||
}
|
||||
|
||||
return DwarfUnit::getOrCreateSubprogramDIE(SP, F, Minimal);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,6 @@ class DwarfCompileUnit final : public DwarfUnit {
|
||||
|
||||
// List of abstract local scopes (either DISubprogram or DILexicalBlock).
|
||||
DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
|
||||
SmallPtrSet<const DISubprogram *, 8> FinalizedAbstractSubprograms;
|
||||
|
||||
// List of inlined lexical block scopes that belong to subprograms within this
|
||||
// CU.
|
||||
@@ -138,28 +137,12 @@ class DwarfCompileUnit final : public DwarfUnit {
|
||||
return DU->getAbstractEntities();
|
||||
}
|
||||
|
||||
auto &getFinalizedAbstractSubprograms() {
|
||||
if (isDwoUnit() && !DD->shareAcrossDWOCUs())
|
||||
return FinalizedAbstractSubprograms;
|
||||
return DU->getFinalizedAbstractSubprograms();
|
||||
}
|
||||
|
||||
void finishNonUnitTypeDIE(DIE& D, const DICompositeType *CTy) override;
|
||||
|
||||
/// Add info for Wasm-global-based relocation.
|
||||
void addWasmRelocBaseGlobal(DIELoc *Loc, StringRef GlobalName,
|
||||
uint64_t GlobalIndex);
|
||||
|
||||
/// Create context DIE for abstract subprogram.
|
||||
/// \returns The context DIE and the compile unit where abstract
|
||||
/// DIE should be constructed.
|
||||
std::pair<DIE *, DwarfCompileUnit *>
|
||||
getOrCreateAbstractSubprogramContextDIE(const DISubprogram *SP);
|
||||
|
||||
/// Create new DIE for abstract subprogram.
|
||||
DIE &createAbstractSubprogramDIE(const DISubprogram *SP, DIE *ContextDIE,
|
||||
DwarfCompileUnit *ContextCU);
|
||||
|
||||
public:
|
||||
DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A,
|
||||
DwarfDebug *DW, DwarfFile *DWU,
|
||||
@@ -233,8 +216,7 @@ public:
|
||||
/// DW_AT_low_pc, DW_AT_high_pc and DW_AT_LLVM_stmt_sequence attributes.
|
||||
/// If there are global variables in this scope then create and insert DIEs
|
||||
/// for these variables.
|
||||
DIE &updateSubprogramScopeDIE(const DISubprogram *SP, const Function &F,
|
||||
MCSymbol *LineTableSym);
|
||||
DIE &updateSubprogramScopeDIE(const DISubprogram *SP, MCSymbol *LineTableSym);
|
||||
|
||||
void constructScopeDIE(LexicalScope *Scope, DIE &ParentScopeDIE);
|
||||
|
||||
@@ -277,18 +259,12 @@ public:
|
||||
/// This instance of 'getOrCreateContextDIE()' can handle DILocalScope.
|
||||
DIE *getOrCreateContextDIE(const DIScope *Ty) override;
|
||||
|
||||
DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, const Function *F,
|
||||
bool Minimal = false) override;
|
||||
|
||||
/// Construct a DIE for this subprogram scope.
|
||||
DIE &constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F,
|
||||
LexicalScope *Scope, MCSymbol *LineTableSym);
|
||||
DIE &constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope,
|
||||
MCSymbol *LineTableSym);
|
||||
|
||||
DIE *createAndAddScopeChildren(LexicalScope *Scope, DIE &ScopeDIE);
|
||||
|
||||
/// Create an abstract subprogram DIE, that should later be populated
|
||||
/// by \ref constructAbstractSubprogramScopeDIE.
|
||||
DIE &getOrCreateAbstractSubprogramDIE(const DISubprogram *SP);
|
||||
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
|
||||
|
||||
/// Whether to use the GNU analog for a DWARF5 tag, attribute, or location
|
||||
@@ -305,15 +281,14 @@ public:
|
||||
dwarf::LocationAtom getDwarf5OrGNULocationAtom(dwarf::LocationAtom Loc) const;
|
||||
|
||||
/// Construct a call site entry DIE describing a call within \p Scope to a
|
||||
/// callee described by \p CalleeSP and \p CalleeF.
|
||||
/// callee described by \p CalleeSP.
|
||||
/// \p IsTail specifies whether the call is a tail call.
|
||||
/// \p PCAddr points to the PC value after the call instruction.
|
||||
/// \p CallAddr points to the PC value at the call instruction (or is null).
|
||||
/// \p CallReg is a register location for an indirect call. For direct calls
|
||||
/// the \p CallReg is set to 0.
|
||||
DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP,
|
||||
const Function *CalleeF, bool IsTail,
|
||||
const MCSymbol *PCAddr,
|
||||
bool IsTail, const MCSymbol *PCAddr,
|
||||
const MCSymbol *CallAddr, unsigned CallReg,
|
||||
DIType *AllocSiteTy);
|
||||
/// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params
|
||||
|
||||
@@ -997,9 +997,8 @@ void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,
|
||||
->getName(CallReg)))
|
||||
<< (IsTail ? " [IsTail]" : "") << "\n");
|
||||
|
||||
DIE &CallSiteDIE =
|
||||
CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, CalleeDecl, IsTail,
|
||||
PCAddr, CallAddr, CallReg, AllocSiteTy);
|
||||
DIE &CallSiteDIE = CU.constructCallSiteEntryDIE(
|
||||
ScopeDIE, CalleeSP, IsTail, PCAddr, CallAddr, CallReg, AllocSiteTy);
|
||||
|
||||
// Optionally emit call-site-param debug info.
|
||||
if (emitDebugEntryValues()) {
|
||||
@@ -2708,8 +2707,7 @@ void DwarfDebug::skippedNonDebugFunction() {
|
||||
|
||||
// Gather and emit post-function debug information.
|
||||
void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
||||
const Function &F = MF->getFunction();
|
||||
const DISubprogram *SP = F.getSubprogram();
|
||||
const DISubprogram *SP = MF->getFunction().getSubprogram();
|
||||
|
||||
assert(CurFn == MF &&
|
||||
"endFunction should be called with the same function as beginFunction");
|
||||
@@ -2778,12 +2776,11 @@ void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
|
||||
|
||||
ProcessedSPNodes.insert(SP);
|
||||
DIE &ScopeDIE =
|
||||
TheCU.constructSubprogramScopeDIE(SP, F, FnScope, FunctionLineTableLabel);
|
||||
TheCU.constructSubprogramScopeDIE(SP, FnScope, FunctionLineTableLabel);
|
||||
if (auto *SkelCU = TheCU.getSkeleton())
|
||||
if (!LScopes.getAbstractScopesList().empty() &&
|
||||
TheCU.getCUNode()->getSplitDebugInlining())
|
||||
SkelCU->constructSubprogramScopeDIE(SP, F, FnScope,
|
||||
FunctionLineTableLabel);
|
||||
SkelCU->constructSubprogramScopeDIE(SP, FnScope, FunctionLineTableLabel);
|
||||
|
||||
FunctionLineTableLabel = nullptr;
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include "DwarfStringPool.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/CodeGen/DIE.h"
|
||||
@@ -28,7 +27,6 @@ class DbgVariable;
|
||||
class DbgLabel;
|
||||
class DINode;
|
||||
class DILocalScope;
|
||||
class DISubprogram;
|
||||
class DwarfCompileUnit;
|
||||
class DwarfUnit;
|
||||
class LexicalScope;
|
||||
@@ -96,9 +94,6 @@ class DwarfFile {
|
||||
// Collection of abstract subprogram DIEs.
|
||||
DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
|
||||
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
|
||||
/// Keeps track of abstract subprograms to populate them only once.
|
||||
// FIXME: merge creation and population of abstract scopes.
|
||||
SmallPtrSet<const DISubprogram *, 8> FinalizedAbstractSubprograms;
|
||||
|
||||
/// Maps MDNodes for type system with the corresponding DIEs. These DIEs can
|
||||
/// be shared across CUs, that is why we keep the map here instead
|
||||
@@ -179,10 +174,6 @@ public:
|
||||
return AbstractEntities;
|
||||
}
|
||||
|
||||
auto &getFinalizedAbstractSubprograms() {
|
||||
return FinalizedAbstractSubprograms;
|
||||
}
|
||||
|
||||
void insertDIE(const MDNode *TypeMD, DIE *Die) {
|
||||
DITypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));
|
||||
}
|
||||
|
||||
@@ -573,7 +573,7 @@ DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) {
|
||||
if (auto *NS = dyn_cast<DINamespace>(Context))
|
||||
return getOrCreateNameSpace(NS);
|
||||
if (auto *SP = dyn_cast<DISubprogram>(Context))
|
||||
return getOrCreateSubprogramDIE(SP, nullptr);
|
||||
return getOrCreateSubprogramDIE(SP);
|
||||
if (auto *M = dyn_cast<DIModule>(Context))
|
||||
return getOrCreateModule(M);
|
||||
return getDIE(Context);
|
||||
@@ -1066,7 +1066,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
|
||||
if (!Element)
|
||||
continue;
|
||||
if (auto *SP = dyn_cast<DISubprogram>(Element))
|
||||
getOrCreateSubprogramDIE(SP, nullptr);
|
||||
getOrCreateSubprogramDIE(SP);
|
||||
else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
|
||||
if (DDTy->getTag() == dwarf::DW_TAG_friend) {
|
||||
DIE &ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer);
|
||||
@@ -1335,21 +1335,22 @@ DIE *DwarfUnit::getOrCreateModule(const DIModule *M) {
|
||||
return &MDie;
|
||||
}
|
||||
|
||||
DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP,
|
||||
const Function *FnHint, bool Minimal) {
|
||||
DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) {
|
||||
// Construct the context before querying for the existence of the DIE in case
|
||||
// such construction creates the DIE (as is the case for member function
|
||||
// declarations).
|
||||
DIE *ContextDIE =
|
||||
getOrCreateSubprogramContextDIE(SP, shouldPlaceInUnitDIE(SP, Minimal));
|
||||
Minimal ? &getUnitDie() : getOrCreateContextDIE(SP->getScope());
|
||||
|
||||
if (DIE *SPDie = getDIE(SP))
|
||||
return SPDie;
|
||||
|
||||
if (auto *SPDecl = SP->getDeclaration()) {
|
||||
if (!Minimal) {
|
||||
// Add subprogram definitions to the CU die directly.
|
||||
ContextDIE = &getUnitDie();
|
||||
// Build the decl now to ensure it precedes the definition.
|
||||
getOrCreateSubprogramDIE(SPDecl, nullptr);
|
||||
getOrCreateSubprogramDIE(SPDecl);
|
||||
// Check whether the DIE for SP has already been created after the call
|
||||
// above.
|
||||
// FIXME: Should the creation of definition subprogram DIE during
|
||||
|
||||
@@ -256,9 +256,7 @@ public:
|
||||
|
||||
DIE *getOrCreateNameSpace(const DINamespace *NS);
|
||||
DIE *getOrCreateModule(const DIModule *M);
|
||||
virtual DIE *getOrCreateSubprogramDIE(const DISubprogram *SP,
|
||||
const Function *FnHint,
|
||||
bool Minimal = false);
|
||||
DIE *getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal = false);
|
||||
|
||||
void applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
|
||||
bool SkipSPAttributes = false);
|
||||
@@ -345,18 +343,6 @@ protected:
|
||||
/// Emit the common part of the header for this unit.
|
||||
void emitCommonHeader(bool UseOffsets, dwarf::UnitType UT);
|
||||
|
||||
bool shouldPlaceInUnitDIE(const DISubprogram *SP, bool Minimal) {
|
||||
// Add subprogram declarations to the CU die directly.
|
||||
return Minimal || SP->getDeclaration();
|
||||
}
|
||||
|
||||
DIE *getOrCreateSubprogramContextDIE(const DISubprogram *SP,
|
||||
bool IgnoreScope) {
|
||||
if (IgnoreScope)
|
||||
return &getUnitDie();
|
||||
return getOrCreateContextDIE(SP->getScope());
|
||||
}
|
||||
|
||||
private:
|
||||
/// A helper to add a wide integer constant to a DIE using a block
|
||||
/// form.
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
@@ -37,16 +36,8 @@ using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "lexicalscopes"
|
||||
|
||||
static bool skipUnit(const DICompileUnit *CU) {
|
||||
return CU->getEmissionKind() == DICompileUnit::NoDebug;
|
||||
}
|
||||
|
||||
void LexicalScopes::resetModule() {
|
||||
FunctionMap.clear();
|
||||
resetFunction();
|
||||
}
|
||||
|
||||
void LexicalScopes::resetFunction() {
|
||||
/// reset - Reset the instance so that it's prepared for another function.
|
||||
void LexicalScopes::reset() {
|
||||
MF = nullptr;
|
||||
CurrentFnLexicalScope = nullptr;
|
||||
LexicalScopeMap.clear();
|
||||
@@ -56,19 +47,12 @@ void LexicalScopes::resetFunction() {
|
||||
DominatedBlocks.clear();
|
||||
}
|
||||
|
||||
void LexicalScopes::initialize(const Module &M) {
|
||||
resetModule();
|
||||
for (const Function &F : M) {
|
||||
DISubprogram *SP = F.getSubprogram();
|
||||
if (SP && (!SP->getUnit() || !skipUnit(SP->getUnit())))
|
||||
FunctionMap[SP] = &F;
|
||||
}
|
||||
}
|
||||
|
||||
void LexicalScopes::scanFunction(const MachineFunction &Fn) {
|
||||
resetFunction();
|
||||
/// initialize - Scan machine function and constuct lexical scope nest.
|
||||
void LexicalScopes::initialize(const MachineFunction &Fn) {
|
||||
reset();
|
||||
// Don't attempt any lexical scope creation for a NoDebug compile unit.
|
||||
if (skipUnit(Fn.getFunction().getSubprogram()->getUnit()))
|
||||
if (Fn.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
|
||||
DICompileUnit::NoDebug)
|
||||
return;
|
||||
MF = &Fn;
|
||||
SmallVector<InsnRange, 4> MIRanges;
|
||||
@@ -159,7 +143,8 @@ LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope,
|
||||
const DILocation *IA) {
|
||||
if (IA) {
|
||||
// Skip scopes inlined from a NoDebug compile unit.
|
||||
if (skipUnit(Scope->getSubprogram()->getUnit()))
|
||||
if (Scope->getSubprogram()->getUnit()->getEmissionKind() ==
|
||||
DICompileUnit::NoDebug)
|
||||
return getOrCreateLexicalScope(IA);
|
||||
// Create an abstract scope for inlined function.
|
||||
getOrCreateAbstractScope(Scope);
|
||||
|
||||
@@ -3721,7 +3721,7 @@ bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
|
||||
TFI = MF.getSubtarget().getFrameLowering();
|
||||
TFI->getCalleeSaves(MF, CalleeSavedRegs);
|
||||
MFI = &MF.getFrameInfo();
|
||||
LS.scanFunction(MF);
|
||||
LS.initialize(MF);
|
||||
|
||||
const auto &STI = MF.getSubtarget();
|
||||
AdjustsStackInCalls = MFI->adjustsStack() &&
|
||||
|
||||
@@ -2231,7 +2231,7 @@ bool VarLocBasedLDV::ExtendRanges(MachineFunction &MF,
|
||||
TFI->getCalleeSaves(MF, CalleeSavedRegs);
|
||||
this->ShouldEmitDebugEntryValues = ShouldEmitDebugEntryValues;
|
||||
|
||||
LS.scanFunction(MF);
|
||||
LS.initialize(MF);
|
||||
|
||||
bool Changed = false;
|
||||
bool OLChanged = false;
|
||||
|
||||
@@ -1263,7 +1263,7 @@ void UserValue::computeIntervals(MachineRegisterInfo &MRI,
|
||||
|
||||
void LiveDebugVariables::LDVImpl::computeIntervals() {
|
||||
LexicalScopes LS;
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
|
||||
for (const auto &UV : userValues) {
|
||||
UV->computeIntervals(MF->getRegInfo(), *TRI, *LIS, LS);
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
; RUN: llc -mtriple=x86_64 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck %s
|
||||
|
||||
; Ensure that static local variable elemnt is placed in abstract subprogram DIE.
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_inline (DW_INL_inlined)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: DW_TAG_variable
|
||||
; CHECK-NEXT: DW_AT_name ("elemnt")
|
||||
|
||||
;
|
||||
; CHECK: [[SYM:[a-z0-9]+]]: DW_TAG_formal_parameter
|
||||
; CHECK: DW_AT_name ("esym")
|
||||
; CHECK: DW_AT_type ([[TYPE:[a-z0-9]+]] "CHARACTER_1")
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
; Check that composite type DIEs go to debug_types section.
|
||||
|
||||
; RUN: llc -generate-type-units -filetype=obj %s -o - | llvm-dwarfdump -debug-info -debug-types - | FileCheck %s
|
||||
|
||||
; CHECK: .debug_info contents:
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_TAG_class_type
|
||||
; CHECK: DW_AT_signature ([[SIG_A:0x[0-9a-f]+]])
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: "_ZN1A6AppendEv"
|
||||
; CHECK: DW_TAG_class_type
|
||||
; CHECK: DW_AT_signature ([[SIG_LAMBDA:0x[0-9a-f]+]])
|
||||
; CHECK: DW_TAG_variable
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK: .debug_types contents:
|
||||
; CHECK: Type Unit: {{.*}} type_signature = [[SIG_A]]
|
||||
; CHECK: DW_TAG_class_type
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_name ("A")
|
||||
; CHECK: Type Unit: {{.*}} type_signature = [[SIG_LAMBDA]]
|
||||
; CHECK: DW_TAG_class_type
|
||||
; CHECK: DW_TAG_class_type
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_decl_line (7)
|
||||
|
||||
target triple = "aarch64-unknown-linux-gnu"
|
||||
|
||||
define void @_Z1f1A() !dbg !4 {
|
||||
entry:
|
||||
ret void, !dbg !8
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!3}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, emissionKind: FullDebug, globals: !2)
|
||||
!1 = !DIFile(filename: "<stdin>", directory: "")
|
||||
!2 = !{}
|
||||
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!4 = distinct !DISubprogram(name: "f", linkageName: "_Z1f1A", scope: !5, file: !5, line: 14, type: !6, scopeLine: 14, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
|
||||
!5 = !DIFile(filename: "repro.ii", directory: "")
|
||||
!6 = distinct !DISubroutineType(types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !DILocation(line: 8, column: 12, scope: !9, inlinedAt: !16)
|
||||
!9 = distinct !DISubprogram(name: "Append", linkageName: "_ZN1A6AppendEv", scope: !10, file: !5, line: 6, type: !11, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !12, retainedNodes: !13)
|
||||
!10 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A", file: !5, line: 3, size: 32, flags: DIFlagTypePassByValue, elements: !2, identifier: "_ZTS1A")
|
||||
!11 = distinct !DISubroutineType(types: !7)
|
||||
!12 = !DISubprogram(name: "Append", linkageName: "_ZN1A6AppendEv", scope: !10, file: !5, line: 6, type: !11, scopeLine: 6, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagOptimized)
|
||||
!13 = !{!14}
|
||||
!14 = !DILocalVariable(name: "raw_append", scope: !9, file: !5, line: 7, type: !15)
|
||||
!15 = distinct !DICompositeType(tag: DW_TAG_class_type, scope: !9, file: !5, line: 7, size: 8, flags: DIFlagTypePassByValue | DIFlagNonTrivial, elements: !2, identifier: "_ZTSZN1A6AppendEvEUlvE_")
|
||||
!16 = distinct !DILocation(line: 14, column: 15, scope: !4)
|
||||
@@ -1,67 +0,0 @@
|
||||
; Check that abstract DIEs for inlined subprograms and lexical scopes
|
||||
; are populated only once.
|
||||
|
||||
; RUN: llc -filetype=obj %s -o - | llvm-dwarfdump - -o - | FileCheck --implicit-check-not=DW_TAG_lexical_scope --implicit-check-not DW_TAG_subprogram %s
|
||||
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_TAG_namespace
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_declaration (true)
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_declaration (true)
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_declaration (true)
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK: [[ABSTRACT_SP:0x[0-9a-f]+]]: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_inline (DW_INL_inlined)
|
||||
|
||||
; CHECK: DW_TAG_lexical_block
|
||||
; CHECK: DW_TAG_imported_module
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK: NULL
|
||||
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: DW_AT_abstract_origin ([[ABSTRACT_SP]]
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: DW_AT_abstract_origin ([[ABSTRACT_SP]]
|
||||
; CHECK: NULL
|
||||
|
||||
target triple = "aarch64-unknown-linux-gnu"
|
||||
|
||||
define void @_ZN12_GLOBAL__N_117MapRegionCounters14TraverseIfStmtEPN5clang6IfStmtE() !dbg !4 {
|
||||
entry:
|
||||
ret void, !dbg !8
|
||||
}
|
||||
|
||||
define void @_ZN12_GLOBAL__N_117MapRegionCounters9VisitStmtEPN5clang4StmtE() !dbg !15 {
|
||||
entry:
|
||||
ret void, !dbg !17
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!3}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !2, globals: !2, imports: !2)
|
||||
!1 = !DIFile(filename: "CodeGenPGO.cpp", directory: "/")
|
||||
!2 = !{}
|
||||
!3 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!4 = distinct !DISubprogram(name: "TraverseIfStmt", linkageName: "_ZN12_GLOBAL__N_117MapRegionCounters14TraverseIfStmtEPN5clang6IfStmtE", scope: !5, file: !1, line: 364, type: !6, scopeLine: 364, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !7, retainedNodes: !2, keyInstructions: true)
|
||||
!5 = !DINamespace(name: "llvm", scope: null)
|
||||
!6 = distinct !DISubroutineType(types: !2)
|
||||
!7 = !DISubprogram(name: "TraverseIfStmt", linkageName: "_ZN12_GLOBAL__N_117MapRegionCounters14TraverseIfStmtEPN5clang6IfStmtE", scope: !5, file: !1, line: 364, type: !6, scopeLine: 364, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagOptimized)
|
||||
!8 = !DILocation(line: 982, column: 39, scope: !9, inlinedAt: !14, atomGroup: 6, atomRank: 2)
|
||||
!9 = distinct !DISubprogram(name: "combine", linkageName: "_ZN12_GLOBAL__N_17PGOHash7combineENS0_8HashTypeE", scope: !5, file: !1, line: 966, type: !6, scopeLine: 966, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !10, retainedNodes: !11, keyInstructions: true)
|
||||
!10 = !DISubprogram(name: "combine", linkageName: "_ZN12_GLOBAL__N_17PGOHash7combineENS0_8HashTypeE", scope: !5, file: !1, line: 140, type: !6, scopeLine: 140, flags: DIFlagPublic | DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagOptimized)
|
||||
!11 = !{!12}
|
||||
!12 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !13, entity: !5, file: !1, line: 973)
|
||||
!13 = distinct !DILexicalBlock(scope: !9, file: !1, line: 972, column: 7)
|
||||
!14 = distinct !DILocation(line: 393, column: 10, scope: !4)
|
||||
!15 = distinct !DISubprogram(name: "VisitStmt", linkageName: "_ZN12_GLOBAL__N_117MapRegionCounters9VisitStmtEPN5clang4StmtE", scope: !5, file: !1, line: 355, type: !6, scopeLine: 355, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !16, retainedNodes: !2, keyInstructions: true)
|
||||
!16 = !DISubprogram(name: "VisitStmt", linkageName: "_ZN12_GLOBAL__N_117MapRegionCounters9VisitStmtEPN5clang4StmtE", scope: !5, file: !1, line: 355, type: !6, scopeLine: 355, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagOptimized)
|
||||
!17 = !DILocation(line: 982, column: 13, scope: !9, inlinedAt: !18)
|
||||
!18 = distinct !DILocation(line: 360, column: 12, scope: !15)
|
||||
@@ -1,93 +0,0 @@
|
||||
; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --implicit-check-not "{{DW_TAG|NULL}}" %s
|
||||
|
||||
; inline __attribute__((always_inline))
|
||||
; int removed() { static int A; return A++; }
|
||||
;
|
||||
; __attribute__((always_inline))
|
||||
; int not_removed() { static int B; return B++; }
|
||||
;
|
||||
; int foo() { return removed() + not_removed(); }
|
||||
|
||||
; Ensure that global variables belong to the correct subprograms even if those
|
||||
; subprograms are inlined.
|
||||
|
||||
; CHECK: DW_TAG_compile_unit
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_abstract_origin {{.*}} "_Z11not_removedv"
|
||||
; TODO: This variable should be emitted in abstract subprogram DIE.
|
||||
; CHECK: DW_TAG_variable
|
||||
; CHECK: DW_AT_name ("B")
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_base_type
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("removed")
|
||||
; CHECK: DW_TAG_variable
|
||||
; CHECK: DW_AT_name ("A")
|
||||
; CHECK: NULL
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("not_removed")
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name ("foo")
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK: NULL
|
||||
; CHECK: NULL
|
||||
|
||||
@_ZZ11not_removedvE1A = internal global i32 0, align 4, !dbg !0
|
||||
@_ZZ7removedvE1A = linkonce_odr dso_local global i32 0, align 4, !dbg !10
|
||||
|
||||
define dso_local i32 @_Z11not_removedv() !dbg !2 {
|
||||
%1 = load i32, i32* @_ZZ11not_removedvE1A, align 4, !dbg !24
|
||||
%2 = add nsw i32 %1, 1, !dbg !24
|
||||
store i32 %2, i32* @_ZZ11not_removedvE1A, align 4, !dbg !24
|
||||
ret i32 %1, !dbg !25
|
||||
}
|
||||
|
||||
define dso_local i32 @_Z3foov() !dbg !26 {
|
||||
%1 = load i32, i32* @_ZZ7removedvE1A, align 4, !dbg !27
|
||||
%2 = add nsw i32 %1, 1, !dbg !27
|
||||
store i32 %2, i32* @_ZZ7removedvE1A, align 4, !dbg !27
|
||||
%3 = load i32, i32* @_ZZ11not_removedvE1A, align 4, !dbg !29
|
||||
%4 = add nsw i32 %3, 1, !dbg !29
|
||||
store i32 %4, i32* @_ZZ11not_removedvE1A, align 4, !dbg !29
|
||||
%5 = add nsw i32 %1, %3, !dbg !31
|
||||
ret i32 %5, !dbg !32
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!7}
|
||||
!llvm.module.flags = !{!14, !15, !16, !17, !18, !19, !20, !21, !22}
|
||||
!llvm.ident = !{!23}
|
||||
|
||||
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
|
||||
!1 = distinct !DIGlobalVariable(name: "B", scope: !2, file: !3, line: 5, type: !6, isLocal: true, isDefinition: true)
|
||||
!2 = distinct !DISubprogram(name: "not_removed", linkageName: "_Z11not_removedv", scope: !3, file: !3, line: 5, type: !4, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !13)
|
||||
!3 = !DIFile(filename: "example.cpp", directory: "")
|
||||
!4 = !DISubroutineType(types: !5)
|
||||
!5 = !{!6}
|
||||
!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !8, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None)
|
||||
!8 = !DIFile(filename: "example.cpp", directory: "")
|
||||
!9 = !{!0, !10}
|
||||
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
|
||||
!11 = distinct !DIGlobalVariable(name: "A", scope: !12, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true)
|
||||
!12 = distinct !DISubprogram(name: "removed", linkageName: "_Z7removedv", scope: !3, file: !3, line: 2, type: !4, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !13)
|
||||
!13 = !{}
|
||||
!14 = !{i32 7, !"Dwarf Version", i32 4}
|
||||
!15 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!16 = !{i32 1, !"wchar_size", i32 4}
|
||||
!17 = !{i32 1, !"branch-target-enforcement", i32 0}
|
||||
!18 = !{i32 1, !"sign-return-address", i32 0}
|
||||
!19 = !{i32 1, !"sign-return-address-all", i32 0}
|
||||
!20 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
|
||||
!21 = !{i32 7, !"uwtable", i32 1}
|
||||
!22 = !{i32 7, !"frame-pointer", i32 1}
|
||||
!23 = !{!"clang version 14.0.0"}
|
||||
!24 = !DILocation(line: 5, column: 43, scope: !2)
|
||||
!25 = !DILocation(line: 5, column: 35, scope: !2)
|
||||
!26 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !3, file: !3, line: 7, type: !4, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !13)
|
||||
!27 = !DILocation(line: 2, column: 39, scope: !12, inlinedAt: !28)
|
||||
!28 = distinct !DILocation(line: 7, column: 20, scope: !26)
|
||||
!29 = !DILocation(line: 5, column: 43, scope: !2, inlinedAt: !30)
|
||||
!30 = distinct !DILocation(line: 7, column: 32, scope: !26)
|
||||
!31 = !DILocation(line: 7, column: 30, scope: !26)
|
||||
!32 = !DILocation(line: 7, column: 13, scope: !26)
|
||||
@@ -159,7 +159,7 @@ public:
|
||||
// Setup things like the artifical block map, and BlockNo <=> RPO Order
|
||||
// mappings.
|
||||
LDV->initialSetup(*MF);
|
||||
LDV->LS.scanFunction(*MF);
|
||||
LDV->LS.initialize(*MF);
|
||||
addMTracker(MF);
|
||||
return &*LDV;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ public:
|
||||
std::unique_ptr<MachineFunction> MF;
|
||||
DICompileUnit *OurCU;
|
||||
DIFile *OurFile;
|
||||
DISubroutineType *OurSubT;
|
||||
DISubprogram *OurFunc;
|
||||
DILexicalBlock *OurBlock, *AnotherBlock;
|
||||
DISubprogram *ToInlineFunc;
|
||||
@@ -104,7 +103,7 @@ public:
|
||||
OurFile = DIB.createFile("xyzzy.c", "/cave");
|
||||
OurCU =
|
||||
DIB.createCompileUnit(dwarf::DW_LANG_C99, OurFile, "nou", false, "", 0);
|
||||
OurSubT = DIB.createSubroutineType(DIB.getOrCreateTypeArray({}));
|
||||
auto OurSubT = DIB.createSubroutineType(DIB.getOrCreateTypeArray({}));
|
||||
OurFunc =
|
||||
DIB.createFunction(OurCU, "bees", "", OurFile, 1, OurSubT, 1,
|
||||
DINode::FlagZero, DISubprogram::SPFlagDefinition);
|
||||
@@ -137,10 +136,10 @@ TEST_F(LexicalScopesTest, FlatLayout) {
|
||||
|
||||
LexicalScopes LS;
|
||||
EXPECT_TRUE(LS.empty());
|
||||
LS.resetFunction();
|
||||
LS.reset();
|
||||
EXPECT_EQ(LS.getCurrentFunctionScope(), nullptr);
|
||||
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
EXPECT_FALSE(LS.empty());
|
||||
LexicalScope *FuncScope = LS.getCurrentFunctionScope();
|
||||
EXPECT_EQ(FuncScope->getParent(), nullptr);
|
||||
@@ -183,7 +182,7 @@ TEST_F(LexicalScopesTest, BlockScopes) {
|
||||
BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
|
||||
|
||||
LexicalScopes LS;
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
LexicalScope *FuncScope = LS.getCurrentFunctionScope();
|
||||
EXPECT_EQ(FuncScope->getDesc(), OurFunc);
|
||||
auto &Children = FuncScope->getChildren();
|
||||
@@ -218,7 +217,7 @@ TEST_F(LexicalScopesTest, InlinedScopes) {
|
||||
BuildMI(*MBB4, MBB4->end(), InlinedLoc, BeanInst);
|
||||
|
||||
LexicalScopes LS;
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
LexicalScope *FuncScope = LS.getCurrentFunctionScope();
|
||||
auto &Children = FuncScope->getChildren();
|
||||
ASSERT_EQ(Children.size(), 1u);
|
||||
@@ -253,7 +252,7 @@ TEST_F(LexicalScopesTest, FuncWithEmptyGap) {
|
||||
BuildMI(*MBB4, MBB4->end(), OutermostLoc, BeanInst);
|
||||
|
||||
LexicalScopes LS;
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
LexicalScope *FuncScope = LS.getCurrentFunctionScope();
|
||||
|
||||
// A gap in a range that contains no other location, is not actually a
|
||||
@@ -274,7 +273,7 @@ TEST_F(LexicalScopesTest, FuncWithRealGap) {
|
||||
MachineInstr *LastI = BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
|
||||
|
||||
LexicalScopes LS;
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
|
||||
ASSERT_NE(BlockScope, nullptr);
|
||||
|
||||
@@ -307,7 +306,7 @@ TEST_F(LexicalScopesTest, NotNested) {
|
||||
MachineInstr *FourthI = BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
|
||||
|
||||
LexicalScopes LS;
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
LexicalScope *FuncScope = LS.getCurrentFunctionScope();
|
||||
LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
|
||||
LexicalScope *OtherBlockScope = LS.findLexicalScope(NotNestedBlockLoc.get());
|
||||
@@ -345,7 +344,7 @@ TEST_F(LexicalScopesTest, TestDominates) {
|
||||
BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
|
||||
|
||||
LexicalScopes LS;
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
LexicalScope *FuncScope = LS.getCurrentFunctionScope();
|
||||
LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
|
||||
LexicalScope *OtherBlockScope = LS.findLexicalScope(NotNestedBlockLoc.get());
|
||||
@@ -387,7 +386,7 @@ TEST_F(LexicalScopesTest, TestGetBlocks) {
|
||||
BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
|
||||
|
||||
LexicalScopes LS;
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
LexicalScope *FuncScope = LS.getCurrentFunctionScope();
|
||||
LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
|
||||
LexicalScope *OtherBlockScope = LS.findLexicalScope(NotNestedBlockLoc.get());
|
||||
@@ -444,7 +443,7 @@ TEST_F(LexicalScopesTest, TestMetaInst) {
|
||||
BuildMI(*MBB4, MBB4->end(), InBlockLoc, BeanInst);
|
||||
|
||||
LexicalScopes LS;
|
||||
LS.scanFunction(*MF);
|
||||
LS.initialize(*MF);
|
||||
LexicalScope *FuncScope = LS.getCurrentFunctionScope();
|
||||
LexicalScope *BlockScope = LS.findLexicalScope(InBlockLoc.get());
|
||||
ASSERT_NE(FuncScope, nullptr);
|
||||
@@ -460,24 +459,4 @@ TEST_F(LexicalScopesTest, TestMetaInst) {
|
||||
EXPECT_TRUE(LS.dominates(InBlockLoc.get(), MBB4));
|
||||
}
|
||||
|
||||
// Test function map creation.
|
||||
TEST_F(LexicalScopesTest, TestFunctionScan) {
|
||||
auto MF2 = createMachineFunction(Ctx, Mod, "Test2");
|
||||
DIBuilder DIB(Mod, false, OurCU);
|
||||
DISubprogram *Func2 =
|
||||
DIB.createFunction(OurCU, "Func2", "", OurFile, 1, OurSubT, 1,
|
||||
DINode::FlagZero, DISubprogram::SPFlagDefinition);
|
||||
DISubprogram *UnattachedFunc =
|
||||
DIB.createFunction(OurCU, "UnattachedFunc", "", OurFile, 1, OurSubT, 1,
|
||||
DINode::FlagZero, DISubprogram::SPFlagDefinition);
|
||||
MF2->getFunction().setSubprogram(Func2);
|
||||
DIB.finalize();
|
||||
|
||||
LexicalScopes LS;
|
||||
LS.initialize(Mod);
|
||||
ASSERT_EQ(LS.getFunction(OurFunc), &MF->getFunction());
|
||||
ASSERT_EQ(LS.getFunction(Func2), &MF2->getFunction());
|
||||
ASSERT_EQ(LS.getFunction(UnattachedFunc), nullptr);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
@@ -132,10 +132,10 @@ BogusTargetMachine *createTargetMachine() {
|
||||
return &BogusTM;
|
||||
}
|
||||
|
||||
std::unique_ptr<MachineFunction>
|
||||
createMachineFunction(LLVMContext &Ctx, Module &M, const Twine &Name = "Test") {
|
||||
std::unique_ptr<MachineFunction> createMachineFunction(LLVMContext &Ctx,
|
||||
Module &M) {
|
||||
auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
|
||||
auto F = Function::Create(Type, GlobalValue::ExternalLinkage, Name, &M);
|
||||
auto F = Function::Create(Type, GlobalValue::ExternalLinkage, "Test", &M);
|
||||
|
||||
auto TM = createTargetMachine();
|
||||
unsigned FunctionNum = 42;
|
||||
@@ -145,3 +145,4 @@ createMachineFunction(LLVMContext &Ctx, Module &M, const Twine &Name = "Test") {
|
||||
return std::make_unique<MachineFunction>(*F, *TM, STI, MMI.getContext(),
|
||||
FunctionNum);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user