forked from OSchip/llvm-project
Remove debug info anchors - llvm.dbg.compile_units, llvm.dbg.subprograms
and llvm.dbg.global_variables. llvm-svn: 74251
This commit is contained in:
parent
aa311ca000
commit
0751a28888
|
@ -24,7 +24,6 @@
|
|||
<ol>
|
||||
<li><a href="#debug_info_descriptors">Debug information descriptors</a>
|
||||
<ul>
|
||||
<li><a href="#format_anchors">Anchor descriptors</a></li>
|
||||
<li><a href="#format_compile_units">Compile unit descriptors</a></li>
|
||||
<li><a href="#format_global_variables">Global variable descriptors</a></li>
|
||||
<li><a href="#format_subprograms">Subprogram descriptors</a></li>
|
||||
|
@ -334,58 +333,6 @@ height="369">
|
|||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="format_anchors">Anchor descriptors</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
%<a href="#format_anchors">llvm.dbg.anchor.type</a> = type {
|
||||
i32, ;; Tag = 0 + <a href="#LLVMDebugVersion">LLVMDebugVersion</a>
|
||||
i32 ;; Tag of descriptors grouped by the anchor
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>One important aspect of the LLVM debug representation is that it allows the
|
||||
LLVM debugger to efficiently index all of the global objects without having
|
||||
to scan the program. To do this, all of the global objects use "anchor"
|
||||
descriptors with designated names. All of the global objects of a particular
|
||||
type (e.g., compile units) contain a pointer to the anchor. This pointer
|
||||
allows a debugger to use def-use chains to find all global objects of that
|
||||
type.</p>
|
||||
|
||||
<p>The following names are recognized as anchors by LLVM:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
%<a href="#format_compile_units">llvm.dbg.compile_units</a> = linkonce constant %<a href="#format_anchors">llvm.dbg.anchor.type</a> {
|
||||
i32 0,
|
||||
i32 17
|
||||
} ;; DW_TAG_compile_unit
|
||||
%<a href="#format_global_variables">llvm.dbg.global_variables</a> = linkonce constant %<a href="#format_anchors">llvm.dbg.anchor.type</a> {
|
||||
i32 0,
|
||||
i32 52
|
||||
} ;; DW_TAG_variable
|
||||
%<a href="#format_subprograms">llvm.dbg.subprograms</a> = linkonce constant %<a href="#format_anchors">llvm.dbg.anchor.type</a> {
|
||||
i32 0,
|
||||
i32 46
|
||||
} ;; DW_TAG_subprogram
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>Using anchors in this way (where the compile unit descriptor points to the
|
||||
anchors, as opposed to having a list of compile unit descriptors) allows for
|
||||
the standard dead global elimination and merging passes to automatically
|
||||
remove unused debugging information. If the globals were kept track of
|
||||
through lists, there would always be an object pointing to the descriptors,
|
||||
thus would never be deleted.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsubsection">
|
||||
<a name="format_compile_units">Compile unit descriptors</a>
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
#ifndef LLVM_ANALYSIS_DEBUGINFO_H
|
||||
#define LLVM_ANALYSIS_DEBUGINFO_H
|
||||
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Dwarf.h"
|
||||
|
||||
namespace llvm {
|
||||
|
@ -80,15 +83,6 @@ namespace llvm {
|
|||
void dump() const;
|
||||
};
|
||||
|
||||
/// DIAnchor - A wrapper for various anchor descriptors.
|
||||
class DIAnchor : public DIDescriptor {
|
||||
public:
|
||||
explicit DIAnchor(GlobalVariable *GV = 0)
|
||||
: DIDescriptor(GV, dwarf::DW_TAG_anchor) {}
|
||||
|
||||
unsigned getAnchorTag() const { return getUnsignedField(1); }
|
||||
};
|
||||
|
||||
/// DISubrange - This is used to represent ranges, for array bounds.
|
||||
class DISubrange : public DIDescriptor {
|
||||
public:
|
||||
|
@ -411,7 +405,6 @@ namespace llvm {
|
|||
class DIFactory {
|
||||
Module &M;
|
||||
// Cached values for uniquing and faster lookups.
|
||||
DIAnchor CompileUnitAnchor, SubProgramAnchor, GlobalVariableAnchor;
|
||||
const Type *EmptyStructPtr; // "{}*".
|
||||
Function *StopPointFn; // llvm.dbg.stoppoint
|
||||
Function *FuncStartFn; // llvm.dbg.func.start
|
||||
|
@ -426,18 +419,6 @@ namespace llvm {
|
|||
public:
|
||||
explicit DIFactory(Module &m);
|
||||
|
||||
/// GetOrCreateCompileUnitAnchor - Return the anchor for compile units,
|
||||
/// creating a new one if there isn't already one in the module.
|
||||
DIAnchor GetOrCreateCompileUnitAnchor();
|
||||
|
||||
/// GetOrCreateSubprogramAnchor - Return the anchor for subprograms,
|
||||
/// creating a new one if there isn't already one in the module.
|
||||
DIAnchor GetOrCreateSubprogramAnchor();
|
||||
|
||||
/// GetOrCreateGlobalVariableAnchor - Return the anchor for globals,
|
||||
/// creating a new one if there isn't already one in the module.
|
||||
DIAnchor GetOrCreateGlobalVariableAnchor();
|
||||
|
||||
/// GetOrCreateArray - Create an descriptor for an array of descriptors.
|
||||
/// This implicitly uniques the arrays created.
|
||||
DIArray GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys);
|
||||
|
@ -540,7 +521,6 @@ namespace llvm {
|
|||
private:
|
||||
Constant *GetTagConstant(unsigned TAG);
|
||||
Constant *GetStringConstant(const std::string &String);
|
||||
DIAnchor GetOrCreateAnchor(unsigned TAG, const char *Name);
|
||||
|
||||
/// getCastToEmpty - Return the descriptor as a Constant* with type '{}*'.
|
||||
Constant *getCastToEmpty(DIDescriptor D);
|
||||
|
@ -563,6 +543,13 @@ namespace llvm {
|
|||
|
||||
bool getLocationInfo(const Value *V, std::string &DisplayName, std::string &Type,
|
||||
unsigned &LineNo, std::string &File, std::string &Dir);
|
||||
|
||||
/// CollectDebugInfoAnchors - Collect debugging information anchors.
|
||||
void CollectDebugInfoAnchors(Module &M,
|
||||
SmallVector<GlobalVariable *, 2> &CompileUnits,
|
||||
SmallVector<GlobalVariable *, 4> &GlobalVars,
|
||||
SmallVector<GlobalVariable *, 4> &Subprograms);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
|
|
@ -367,71 +367,10 @@ Constant *DIFactory::GetStringConstant(const std::string &String) {
|
|||
return Slot = ConstantExpr::getBitCast(StrGV, DestTy);
|
||||
}
|
||||
|
||||
/// GetOrCreateAnchor - Look up an anchor for the specified tag and name. If it
|
||||
/// already exists, return it. If not, create a new one and return it.
|
||||
DIAnchor DIFactory::GetOrCreateAnchor(unsigned TAG, const char *Name) {
|
||||
const Type *EltTy = StructType::get(Type::Int32Ty, Type::Int32Ty, NULL);
|
||||
|
||||
// Otherwise, create the global or return it if already in the module.
|
||||
Constant *C = M.getOrInsertGlobal(Name, EltTy);
|
||||
assert(isa<GlobalVariable>(C) && "Incorrectly typed anchor?");
|
||||
GlobalVariable *GV = cast<GlobalVariable>(C);
|
||||
|
||||
// If it has an initializer, it is already in the module.
|
||||
if (GV->hasInitializer())
|
||||
return SubProgramAnchor = DIAnchor(GV);
|
||||
|
||||
GV->setLinkage(GlobalValue::LinkOnceAnyLinkage);
|
||||
GV->setSection("llvm.metadata");
|
||||
GV->setConstant(true);
|
||||
M.addTypeName("llvm.dbg.anchor.type", EltTy);
|
||||
|
||||
// Otherwise, set the initializer.
|
||||
Constant *Elts[] = {
|
||||
GetTagConstant(dwarf::DW_TAG_anchor),
|
||||
ConstantInt::get(Type::Int32Ty, TAG)
|
||||
};
|
||||
|
||||
GV->setInitializer(ConstantStruct::get(Elts, 2));
|
||||
return DIAnchor(GV);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DIFactory: Primary Constructors
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// GetOrCreateCompileUnitAnchor - Return the anchor for compile units,
|
||||
/// creating a new one if there isn't already one in the module.
|
||||
DIAnchor DIFactory::GetOrCreateCompileUnitAnchor() {
|
||||
// If we already created one, just return it.
|
||||
if (!CompileUnitAnchor.isNull())
|
||||
return CompileUnitAnchor;
|
||||
return CompileUnitAnchor = GetOrCreateAnchor(dwarf::DW_TAG_compile_unit,
|
||||
"llvm.dbg.compile_units");
|
||||
}
|
||||
|
||||
/// GetOrCreateSubprogramAnchor - Return the anchor for subprograms,
|
||||
/// creating a new one if there isn't already one in the module.
|
||||
DIAnchor DIFactory::GetOrCreateSubprogramAnchor() {
|
||||
// If we already created one, just return it.
|
||||
if (!SubProgramAnchor.isNull())
|
||||
return SubProgramAnchor;
|
||||
return SubProgramAnchor = GetOrCreateAnchor(dwarf::DW_TAG_subprogram,
|
||||
"llvm.dbg.subprograms");
|
||||
}
|
||||
|
||||
/// GetOrCreateGlobalVariableAnchor - Return the anchor for globals,
|
||||
/// creating a new one if there isn't already one in the module.
|
||||
DIAnchor DIFactory::GetOrCreateGlobalVariableAnchor() {
|
||||
// If we already created one, just return it.
|
||||
if (!GlobalVariableAnchor.isNull())
|
||||
return GlobalVariableAnchor;
|
||||
return GlobalVariableAnchor = GetOrCreateAnchor(dwarf::DW_TAG_variable,
|
||||
"llvm.dbg.global_variables");
|
||||
}
|
||||
|
||||
/// GetOrCreateArray - Create an descriptor for an array of descriptors.
|
||||
/// This implicitly uniques the arrays created.
|
||||
DIArray DIFactory::GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys) {
|
||||
|
@ -494,7 +433,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
|
|||
unsigned RunTimeVer) {
|
||||
Constant *Elts[] = {
|
||||
GetTagConstant(dwarf::DW_TAG_compile_unit),
|
||||
getCastToEmpty(GetOrCreateCompileUnitAnchor()),
|
||||
Constant::getNullValue(EmptyStructPtr),
|
||||
ConstantInt::get(Type::Int32Ty, LangID),
|
||||
GetStringConstant(Filename),
|
||||
GetStringConstant(Directory),
|
||||
|
@ -509,7 +448,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID,
|
|||
|
||||
M.addTypeName("llvm.dbg.compile_unit.type", Init->getType());
|
||||
GlobalVariable *GV = new GlobalVariable(Init->getType(), true,
|
||||
GlobalValue::InternalLinkage,
|
||||
GlobalValue::LinkOnceAnyLinkage,
|
||||
Init, "llvm.dbg.compile_unit", &M);
|
||||
GV->setSection("llvm.metadata");
|
||||
return DICompileUnit(GV);
|
||||
|
@ -655,7 +594,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
|
|||
|
||||
Constant *Elts[] = {
|
||||
GetTagConstant(dwarf::DW_TAG_subprogram),
|
||||
getCastToEmpty(GetOrCreateSubprogramAnchor()),
|
||||
Constant::getNullValue(EmptyStructPtr),
|
||||
getCastToEmpty(Context),
|
||||
GetStringConstant(Name),
|
||||
GetStringConstant(DisplayName),
|
||||
|
@ -671,7 +610,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
|
|||
|
||||
M.addTypeName("llvm.dbg.subprogram.type", Init->getType());
|
||||
GlobalVariable *GV = new GlobalVariable(Init->getType(), true,
|
||||
GlobalValue::InternalLinkage,
|
||||
GlobalValue::LinkOnceAnyLinkage,
|
||||
Init, "llvm.dbg.subprogram", &M);
|
||||
GV->setSection("llvm.metadata");
|
||||
return DISubprogram(GV);
|
||||
|
@ -687,7 +626,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
|
|||
bool isDefinition, llvm::GlobalVariable *Val) {
|
||||
Constant *Elts[] = {
|
||||
GetTagConstant(dwarf::DW_TAG_variable),
|
||||
getCastToEmpty(GetOrCreateGlobalVariableAnchor()),
|
||||
Constant::getNullValue(EmptyStructPtr),
|
||||
getCastToEmpty(Context),
|
||||
GetStringConstant(Name),
|
||||
GetStringConstant(DisplayName),
|
||||
|
@ -704,7 +643,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name,
|
|||
|
||||
M.addTypeName("llvm.dbg.global_variable.type", Init->getType());
|
||||
GlobalVariable *GV = new GlobalVariable(Init->getType(), true,
|
||||
GlobalValue::InternalLinkage,
|
||||
GlobalValue::LinkOnceAnyLinkage,
|
||||
Init, "llvm.dbg.global_variable", &M);
|
||||
GV->setSection("llvm.metadata");
|
||||
return DIGlobalVariable(GV);
|
||||
|
@ -954,6 +893,36 @@ namespace llvm {
|
|||
Unit.getDirectory(Dir);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// CollectDebugInfoAnchors - Collect debugging information anchors.
|
||||
void CollectDebugInfoAnchors(Module &M,
|
||||
SmallVector<GlobalVariable *, 2> &CUs,
|
||||
SmallVector<GlobalVariable *, 4> &GVs,
|
||||
SmallVector<GlobalVariable *, 4> &SPs) {
|
||||
|
||||
for (Module::global_iterator GVI = M.global_begin(), E = M.global_end();
|
||||
GVI != E; GVI++) {
|
||||
GlobalVariable *GV = GVI;
|
||||
if (GV->hasName() && strncmp(GV->getNameStart(), "llvm.dbg", 8) == 0
|
||||
&& GV->isConstant() && GV->hasInitializer()) {
|
||||
DICompileUnit C(GV);
|
||||
if (C.isNull() == false) {
|
||||
CUs.push_back(GV);
|
||||
continue;
|
||||
}
|
||||
DIGlobalVariable G(GV);
|
||||
if (G.isNull() == false) {
|
||||
GVs.push_back(GV);
|
||||
continue;
|
||||
}
|
||||
DISubprogram S(GV);
|
||||
if (S.isNull() == false) {
|
||||
SPs.push_back(GV);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// dump - Print descriptor.
|
||||
|
@ -1077,3 +1046,4 @@ void DIVariable::dump() const {
|
|||
getType().dump();
|
||||
cerr << "\n";
|
||||
}
|
||||
|
||||
|
|
|
@ -1242,27 +1242,7 @@ void DwarfDebug::ConstructCompileUnit(GlobalVariable *GV) {
|
|||
CompileUnits.push_back(Unit);
|
||||
}
|
||||
|
||||
/// ConstructCompileUnits - Create a compile unit DIEs.
|
||||
void DwarfDebug::ConstructCompileUnits() {
|
||||
GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.compile_units");
|
||||
if (!Root)
|
||||
return;
|
||||
assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
|
||||
"Malformed compile unit descriptor anchor type");
|
||||
Constant *RootC = cast<Constant>(*Root->use_begin());
|
||||
assert(RootC->hasNUsesOrMore(1) &&
|
||||
"Malformed compile unit descriptor anchor type");
|
||||
|
||||
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
|
||||
UI != UE; ++UI)
|
||||
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
|
||||
UUI != UUE; ++UUI) {
|
||||
GlobalVariable *GV = cast<GlobalVariable>(*UUI);
|
||||
ConstructCompileUnit(GV);
|
||||
}
|
||||
}
|
||||
|
||||
bool DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
|
||||
void DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
|
||||
DIGlobalVariable DI_GV(GV);
|
||||
CompileUnit *DW_Unit = MainCU;
|
||||
if (!DW_Unit)
|
||||
|
@ -1271,7 +1251,7 @@ bool DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
|
|||
// Check for pre-existence.
|
||||
DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV());
|
||||
if (Slot)
|
||||
return false;
|
||||
return;
|
||||
|
||||
DIE *VariableDie = CreateGlobalVariableDIE(DW_Unit, DI_GV);
|
||||
|
||||
|
@ -1292,33 +1272,10 @@ bool DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
|
|||
// Expose as global. FIXME - need to check external flag.
|
||||
std::string Name;
|
||||
DW_Unit->AddGlobal(DI_GV.getName(Name), VariableDie);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
/// ConstructGlobalVariableDIEs - Create DIEs for each of the externally visible
|
||||
/// global variables. Return true if at least one global DIE is created.
|
||||
bool DwarfDebug::ConstructGlobalVariableDIEs() {
|
||||
GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.global_variables");
|
||||
if (!Root)
|
||||
return false;
|
||||
|
||||
assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
|
||||
"Malformed global variable descriptor anchor type");
|
||||
Constant *RootC = cast<Constant>(*Root->use_begin());
|
||||
assert(RootC->hasNUsesOrMore(1) &&
|
||||
"Malformed global variable descriptor anchor type");
|
||||
|
||||
bool Result = false;
|
||||
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
|
||||
UI != UE; ++UI)
|
||||
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
|
||||
UUI != UUE; ++UUI)
|
||||
Result |= ConstructGlobalVariableDIE(cast<GlobalVariable>(*UUI));
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
bool DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
|
||||
void DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
|
||||
DISubprogram SP(GV);
|
||||
CompileUnit *Unit = MainCU;
|
||||
if (!Unit)
|
||||
|
@ -1327,12 +1284,12 @@ bool DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
|
|||
// Check for pre-existence.
|
||||
DIE *&Slot = Unit->getDieMapSlotFor(GV);
|
||||
if (Slot)
|
||||
return false;
|
||||
return;
|
||||
|
||||
if (!SP.isDefinition())
|
||||
// This is a method declaration which will be handled while constructing
|
||||
// class type.
|
||||
return false;
|
||||
return;
|
||||
|
||||
DIE *SubprogramDie = CreateSubprogramDIE(Unit, SP);
|
||||
|
||||
|
@ -1345,30 +1302,7 @@ bool DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
|
|||
// Expose as global.
|
||||
std::string Name;
|
||||
Unit->AddGlobal(SP.getName(Name), SubprogramDie);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ConstructSubprograms - Create DIEs for each of the externally visible
|
||||
/// subprograms. Return true if at least one subprogram DIE is created.
|
||||
bool DwarfDebug::ConstructSubprograms() {
|
||||
GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.subprograms");
|
||||
if (!Root)
|
||||
return false;
|
||||
|
||||
assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
|
||||
"Malformed subprogram descriptor anchor type");
|
||||
Constant *RootC = cast<Constant>(*Root->use_begin());
|
||||
assert(RootC->hasNUsesOrMore(1) &&
|
||||
"Malformed subprogram descriptor anchor type");
|
||||
|
||||
bool Result = false;
|
||||
for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
|
||||
UI != UE; ++UI)
|
||||
for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
|
||||
UUI != UUE; ++UUI)
|
||||
Result |= ConstructSubprogram(cast<GlobalVariable>(*UUI));
|
||||
|
||||
return Result;
|
||||
return;
|
||||
}
|
||||
|
||||
/// BeginModule - Emit all Dwarf sections that should come prior to the
|
||||
|
@ -1380,8 +1314,15 @@ void DwarfDebug::BeginModule(Module *M, MachineModuleInfo *mmi) {
|
|||
if (TimePassesIsEnabled)
|
||||
DebugTimer->startTimer();
|
||||
|
||||
SmallVector<GlobalVariable *, 2> CUs;
|
||||
SmallVector<GlobalVariable *, 4> GVs;
|
||||
SmallVector<GlobalVariable *, 4> SPs;
|
||||
CollectDebugInfoAnchors(*M, CUs, GVs, SPs);
|
||||
|
||||
// Create all the compile unit DIEs.
|
||||
ConstructCompileUnits();
|
||||
for (SmallVector<GlobalVariable *, 2>::iterator I = CUs.begin(),
|
||||
E = CUs.end(); I != E; ++I)
|
||||
ConstructCompileUnit(*I);
|
||||
|
||||
if (CompileUnits.empty()) {
|
||||
if (TimePassesIsEnabled)
|
||||
|
@ -1390,21 +1331,25 @@ void DwarfDebug::BeginModule(Module *M, MachineModuleInfo *mmi) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Create DIEs for each of the externally visible global variables.
|
||||
bool globalDIEs = ConstructGlobalVariableDIEs();
|
||||
|
||||
// Create DIEs for each of the externally visible subprograms.
|
||||
bool subprogramDIEs = ConstructSubprograms();
|
||||
|
||||
// If there is not any debug info available for any global variables and any
|
||||
// subprograms then there is not any debug info to emit.
|
||||
if (!globalDIEs && !subprogramDIEs) {
|
||||
if (GVs.empty() && SPs.empty()) {
|
||||
if (TimePassesIsEnabled)
|
||||
DebugTimer->stopTimer();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Create DIEs for each of the externally visible global variables.
|
||||
for (SmallVector<GlobalVariable *, 4>::iterator I = GVs.begin(),
|
||||
E = GVs.end(); I != E; ++I)
|
||||
ConstructGlobalVariableDIE(*I);
|
||||
|
||||
// Create DIEs for each of the externally visible subprograms.
|
||||
for (SmallVector<GlobalVariable *, 4>::iterator I = SPs.begin(),
|
||||
E = SPs.end(); I != E; ++I)
|
||||
ConstructSubprogram(*I);
|
||||
|
||||
MMI = mmi;
|
||||
shouldEmit = true;
|
||||
MMI->setDebugInfoAvailability(true);
|
||||
|
|
|
@ -460,21 +460,10 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {
|
|||
|
||||
void ConstructCompileUnit(GlobalVariable *GV);
|
||||
|
||||
/// ConstructCompileUnits - Create a compile unit DIEs.
|
||||
void ConstructCompileUnits();
|
||||
void ConstructGlobalVariableDIE(GlobalVariable *GV);
|
||||
|
||||
bool ConstructGlobalVariableDIE(GlobalVariable *GV);
|
||||
void ConstructSubprogram(GlobalVariable *GV);
|
||||
|
||||
/// ConstructGlobalVariableDIEs - Create DIEs for each of the externally
|
||||
/// visible global variables. Return true if at least one global DIE is
|
||||
/// created.
|
||||
bool ConstructGlobalVariableDIEs();
|
||||
|
||||
bool ConstructSubprogram(GlobalVariable *GV);
|
||||
|
||||
/// ConstructSubprograms - Create DIEs for each of the externally visible
|
||||
/// subprograms. Return true if at least one subprogram DIE is created.
|
||||
bool ConstructSubprograms();
|
||||
public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Main entry points.
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Analysis/DebugInfo.h"
|
||||
#include "llvm/ValueSymbolTable.h"
|
||||
#include "llvm/TypeSymbolTable.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
|
@ -210,6 +211,24 @@ bool StripDebugInfo(Module &M) {
|
|||
SmallPtrSet<const GlobalValue*, 8> llvmUsedValues;
|
||||
findUsedValues(M, llvmUsedValues);
|
||||
|
||||
SmallVector<GlobalVariable *, 2> CUs;
|
||||
SmallVector<GlobalVariable *, 4> GVs;
|
||||
SmallVector<GlobalVariable *, 4> SPs;
|
||||
CollectDebugInfoAnchors(M, CUs, GVs, SPs);
|
||||
// These anchors use LinkOnce linkage so that the optimizer does not
|
||||
// remove them accidently. Set InternalLinkage for all these debug
|
||||
// info anchors.
|
||||
for (SmallVector<GlobalVariable *, 2>::iterator I = CUs.begin(),
|
||||
E = CUs.end(); I != E; ++I)
|
||||
(*I)->setLinkage(GlobalValue::InternalLinkage);
|
||||
for (SmallVector<GlobalVariable *, 4>::iterator I = GVs.begin(),
|
||||
E = GVs.end(); I != E; ++I)
|
||||
(*I)->setLinkage(GlobalValue::InternalLinkage);
|
||||
for (SmallVector<GlobalVariable *, 4>::iterator I = SPs.begin(),
|
||||
E = SPs.end(); I != E; ++I)
|
||||
(*I)->setLinkage(GlobalValue::InternalLinkage);
|
||||
|
||||
|
||||
// Delete all dbg variables.
|
||||
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; ++I) {
|
||||
|
|
Loading…
Reference in New Issue