mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Support the Nodebug emission kind for DICompileUnits.
Sample-based profiling and optimization remarks currently remove DICompileUnits from llvm.dbg.cu to suppress the emission of debug info from them. This is somewhat of a hack and only borderline legal IR. This patch uses the recently introduced NoDebug emission kind in DICompileUnit to achieve the same result without breaking the Verifier. A nice side-effect of this change is that it is now possible to combine NoDebug and regular compile units under LTO. http://reviews.llvm.org/D18808 <rdar://problem/25427165> llvm-svn: 265861
This commit is contained in:
parent
744e3da853
commit
4300f8a4c5
@ -92,23 +92,13 @@ namespace llvm {
|
|||||||
/// out into.
|
/// out into.
|
||||||
/// \param Kind The kind of debug information to generate.
|
/// \param Kind The kind of debug information to generate.
|
||||||
/// \param DWOId The DWOId if this is a split skeleton compile unit.
|
/// \param DWOId The DWOId if this is a split skeleton compile unit.
|
||||||
/// \param EmitDebugInfo A boolean flag which indicates whether
|
|
||||||
/// debug information should be written to
|
|
||||||
/// the final output or not. When this is
|
|
||||||
/// false, debug information annotations will
|
|
||||||
/// be present in the IL but they are not
|
|
||||||
/// written to the final assembly or object
|
|
||||||
/// file. This supports tracking source
|
|
||||||
/// location information in the back end
|
|
||||||
/// without actually changing the output
|
|
||||||
/// (e.g., when using optimization remarks).
|
|
||||||
DICompileUnit *
|
DICompileUnit *
|
||||||
createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
|
createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
|
||||||
StringRef Producer, bool isOptimized, StringRef Flags,
|
StringRef Producer, bool isOptimized, StringRef Flags,
|
||||||
unsigned RV, StringRef SplitName = StringRef(),
|
unsigned RV, StringRef SplitName = StringRef(),
|
||||||
DICompileUnit::DebugEmissionKind Kind =
|
DICompileUnit::DebugEmissionKind Kind =
|
||||||
DICompileUnit::DebugEmissionKind::FullDebug,
|
DICompileUnit::DebugEmissionKind::FullDebug,
|
||||||
uint64_t DWOId = 0, bool EmitDebugInfo = true);
|
uint64_t DWOId = 0);
|
||||||
|
|
||||||
/// Create a file descriptor to hold debugging information
|
/// Create a file descriptor to hold debugging information
|
||||||
/// for a file.
|
/// for a file.
|
||||||
|
@ -40,7 +40,7 @@ typedef DenseMap<const MDString *, DIType *> DITypeIdentifierMap;
|
|||||||
DISubprogram *getDISubprogram(const MDNode *Scope);
|
DISubprogram *getDISubprogram(const MDNode *Scope);
|
||||||
|
|
||||||
/// \brief Generate map by visiting all retained types.
|
/// \brief Generate map by visiting all retained types.
|
||||||
DITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
|
DITypeIdentifierMap generateDITypeIdentifierMap(const Module &M);
|
||||||
|
|
||||||
/// \brief Strip debug info in the module if it exists.
|
/// \brief Strip debug info in the module if it exists.
|
||||||
///
|
///
|
||||||
|
@ -626,6 +626,58 @@ public:
|
|||||||
return make_range(named_metadata_begin(), named_metadata_end());
|
return make_range(named_metadata_begin(), named_metadata_end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator for DICompileUnits that skips those marked NoDebug.
|
||||||
|
class debug_compile_units_iterator
|
||||||
|
: public std::iterator<std::input_iterator_tag, DICompileUnit *> {
|
||||||
|
NamedMDNode *CUs;
|
||||||
|
unsigned Idx;
|
||||||
|
void SkipNoDebugCUs();
|
||||||
|
public:
|
||||||
|
explicit debug_compile_units_iterator(NamedMDNode *CUs, unsigned Idx)
|
||||||
|
: CUs(CUs), Idx(Idx) {
|
||||||
|
SkipNoDebugCUs();
|
||||||
|
}
|
||||||
|
debug_compile_units_iterator &operator++() {
|
||||||
|
++Idx;
|
||||||
|
SkipNoDebugCUs();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
debug_compile_units_iterator operator++(int) {
|
||||||
|
debug_compile_units_iterator T(*this);
|
||||||
|
++Idx;
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
bool operator==(const debug_compile_units_iterator &I) const {
|
||||||
|
return Idx == I.Idx;
|
||||||
|
}
|
||||||
|
bool operator!=(const debug_compile_units_iterator &I) const {
|
||||||
|
return Idx != I.Idx;
|
||||||
|
}
|
||||||
|
DICompileUnit *operator*() const;
|
||||||
|
DICompileUnit *operator->() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
debug_compile_units_iterator debug_compile_units_begin() const {
|
||||||
|
auto *CUs = getNamedMetadata("llvm.dbg.cu");
|
||||||
|
return debug_compile_units_iterator(CUs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_compile_units_iterator debug_compile_units_end() const {
|
||||||
|
auto *CUs = getNamedMetadata("llvm.dbg.cu");
|
||||||
|
return debug_compile_units_iterator(CUs, CUs ? CUs->getNumOperands() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return an iterator for all DICompileUnits listed in this Module's
|
||||||
|
/// llvm.dbg.cu named metadata node and aren't explicitly marked as
|
||||||
|
/// NoDebug.
|
||||||
|
iterator_range<debug_compile_units_iterator> debug_compile_units() const {
|
||||||
|
auto *CUs = getNamedMetadata("llvm.dbg.cu");
|
||||||
|
return make_range(
|
||||||
|
debug_compile_units_iterator(CUs, 0),
|
||||||
|
debug_compile_units_iterator(CUs, CUs ? CUs->getNumOperands() : 0));
|
||||||
|
}
|
||||||
|
/// @}
|
||||||
|
|
||||||
/// Destroy ConstantArrays in LLVMContext if they are not used.
|
/// Destroy ConstantArrays in LLVMContext if they are not used.
|
||||||
/// ConstantArrays constructed during linking can cause quadratic memory
|
/// ConstantArrays constructed during linking can cause quadratic memory
|
||||||
/// explosion. Releasing all unused constants can cause a 20% LTO compile-time
|
/// explosion. Releasing all unused constants can cause a 20% LTO compile-time
|
||||||
@ -635,7 +687,6 @@ public:
|
|||||||
/// be called where all uses of the LLVMContext are understood.
|
/// be called where all uses of the LLVMContext are understood.
|
||||||
void dropTriviallyDeadConstantArrays();
|
void dropTriviallyDeadConstantArrays();
|
||||||
|
|
||||||
/// @}
|
|
||||||
/// @name Utility functions for printing and dumping Module objects
|
/// @name Utility functions for printing and dumping Module objects
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
@ -466,15 +466,18 @@ void DwarfDebug::beginModule() {
|
|||||||
|
|
||||||
const Module *M = MMI->getModule();
|
const Module *M = MMI->getModule();
|
||||||
|
|
||||||
NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
|
TypeIdentifierMap = generateDITypeIdentifierMap(*M);
|
||||||
if (!CU_Nodes)
|
unsigned NumDebugCUs = 0;
|
||||||
return;
|
for (DICompileUnit *CUNode : M->debug_compile_units()) {
|
||||||
TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
|
(void)CUNode;
|
||||||
|
++NumDebugCUs;
|
||||||
|
}
|
||||||
|
|
||||||
SingleCU = CU_Nodes->getNumOperands() == 1;
|
// Tell MMI whether we have debug info.
|
||||||
|
MMI->setDebugInfoAvailability(NumDebugCUs > 0);
|
||||||
|
SingleCU = NumDebugCUs == 1;
|
||||||
|
|
||||||
for (MDNode *N : CU_Nodes->operands()) {
|
for (DICompileUnit *CUNode : M->debug_compile_units()) {
|
||||||
auto *CUNode = cast<DICompileUnit>(N);
|
|
||||||
DwarfCompileUnit &CU = constructDwarfCompileUnit(CUNode);
|
DwarfCompileUnit &CU = constructDwarfCompileUnit(CUNode);
|
||||||
for (auto *IE : CUNode->getImportedEntities())
|
for (auto *IE : CUNode->getImportedEntities())
|
||||||
CU.addImportedEntity(IE);
|
CU.addImportedEntity(IE);
|
||||||
@ -500,9 +503,6 @@ void DwarfDebug::beginModule() {
|
|||||||
for (auto *IE : CUNode->getImportedEntities())
|
for (auto *IE : CUNode->getImportedEntities())
|
||||||
constructAndAddImportedEntityDIE(CU, IE);
|
constructAndAddImportedEntityDIE(CU, IE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell MMI that we have debug info.
|
|
||||||
MMI->setDebugInfoAvailability(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DwarfDebug::finishVariableDefinitions() {
|
void DwarfDebug::finishVariableDefinitions() {
|
||||||
@ -538,6 +538,9 @@ void DwarfDebug::collectDeadVariables() {
|
|||||||
if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) {
|
if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) {
|
||||||
for (MDNode *N : CU_Nodes->operands()) {
|
for (MDNode *N : CU_Nodes->operands()) {
|
||||||
auto *TheCU = cast<DICompileUnit>(N);
|
auto *TheCU = cast<DICompileUnit>(N);
|
||||||
|
if (TheCU->getEmissionKind() == DICompileUnit::NoDebug)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Construct subprogram DIE and add variables DIEs.
|
// Construct subprogram DIE and add variables DIEs.
|
||||||
DwarfCompileUnit *SPCU =
|
DwarfCompileUnit *SPCU =
|
||||||
static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));
|
static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));
|
||||||
@ -1090,7 +1093,10 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
|
|||||||
// includes the directory of the cpp file being built, even when the file name
|
// includes the directory of the cpp file being built, even when the file name
|
||||||
// is absolute (such as an <> lookup header)))
|
// is absolute (such as an <> lookup header)))
|
||||||
DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
|
DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
|
||||||
assert(TheCU && "Unable to find compile unit!");
|
if (!TheCU)
|
||||||
|
// Once DISubprogram points to the owning CU, we can assert that the CU has
|
||||||
|
// a NoDebug EmissionKind here.
|
||||||
|
return;
|
||||||
if (Asm->OutStreamer->hasRawTextSupport())
|
if (Asm->OutStreamer->hasRawTextSupport())
|
||||||
// Use a single line table if we are generating assembly.
|
// Use a single line table if we are generating assembly.
|
||||||
Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
|
Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);
|
||||||
@ -1113,7 +1119,10 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
|
|||||||
"endFunction should be called with the same function as beginFunction");
|
"endFunction should be called with the same function as beginFunction");
|
||||||
|
|
||||||
if (!MMI->hasDebugInfo() || LScopes.empty() ||
|
if (!MMI->hasDebugInfo() || LScopes.empty() ||
|
||||||
!MF->getFunction()->getSubprogram()) {
|
!MF->getFunction()->getSubprogram() ||
|
||||||
|
// Once DISubprogram points to the owning CU, we can check for a
|
||||||
|
// CU with a NoDebug EmissionKind here.
|
||||||
|
!SPMap.lookup(MF->getFunction()->getSubprogram())) {
|
||||||
// If we don't have a lexical scope for this function then there will
|
// If we don't have a lexical scope for this function then there will
|
||||||
// be a hole in the range information. Keep note of this by setting the
|
// be a hole in the range information. Keep note of this by setting the
|
||||||
// previously used section to nullptr.
|
// previously used section to nullptr.
|
||||||
|
@ -137,7 +137,7 @@ static DIScope *getNonCompileUnitScope(DIScope *N) {
|
|||||||
DICompileUnit *DIBuilder::createCompileUnit(
|
DICompileUnit *DIBuilder::createCompileUnit(
|
||||||
unsigned Lang, StringRef Filename, StringRef Directory, StringRef Producer,
|
unsigned Lang, StringRef Filename, StringRef Directory, StringRef Producer,
|
||||||
bool isOptimized, StringRef Flags, unsigned RunTimeVer, StringRef SplitName,
|
bool isOptimized, StringRef Flags, unsigned RunTimeVer, StringRef SplitName,
|
||||||
DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId, bool EmitDebugInfo) {
|
DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId) {
|
||||||
|
|
||||||
assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) ||
|
assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) ||
|
||||||
(Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&
|
(Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&
|
||||||
@ -152,15 +152,8 @@ DICompileUnit *DIBuilder::createCompileUnit(
|
|||||||
nullptr, nullptr, nullptr, nullptr, nullptr, DWOId);
|
nullptr, nullptr, nullptr, nullptr, nullptr, DWOId);
|
||||||
|
|
||||||
// Create a named metadata so that it is easier to find cu in a module.
|
// Create a named metadata so that it is easier to find cu in a module.
|
||||||
// Note that we only generate this when the caller wants to actually
|
NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
|
||||||
// emit debug information. When we are only interested in tracking
|
NMD->addOperand(CUNode);
|
||||||
// source line locations throughout the backend, we prevent codegen from
|
|
||||||
// emitting debug info in the final output by not generating llvm.dbg.cu.
|
|
||||||
if (EmitDebugInfo) {
|
|
||||||
NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
|
|
||||||
NMD->addOperand(CUNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
trackIfUnresolved(CUNode);
|
trackIfUnresolved(CUNode);
|
||||||
return CUNode;
|
return CUNode;
|
||||||
}
|
}
|
||||||
|
@ -39,10 +39,9 @@ DISubprogram *llvm::getDISubprogram(const MDNode *Scope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DITypeIdentifierMap
|
DITypeIdentifierMap
|
||||||
llvm::generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes) {
|
llvm::generateDITypeIdentifierMap(const Module &M) {
|
||||||
DITypeIdentifierMap Map;
|
DITypeIdentifierMap Map;
|
||||||
for (unsigned CUi = 0, CUe = CU_Nodes->getNumOperands(); CUi != CUe; ++CUi) {
|
for (DICompileUnit *CU : M.debug_compile_units()) {
|
||||||
auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(CUi));
|
|
||||||
DINodeArray Retain = CU->getRetainedTypes();
|
DINodeArray Retain = CU->getRetainedTypes();
|
||||||
for (unsigned Ti = 0, Te = Retain.size(); Ti != Te; ++Ti) {
|
for (unsigned Ti = 0, Te = Retain.size(); Ti != Te; ++Ti) {
|
||||||
if (!isa<DICompositeType>(Retain[Ti]))
|
if (!isa<DICompositeType>(Retain[Ti]))
|
||||||
@ -79,42 +78,38 @@ void DebugInfoFinder::reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DebugInfoFinder::InitializeTypeMap(const Module &M) {
|
void DebugInfoFinder::InitializeTypeMap(const Module &M) {
|
||||||
if (!TypeMapInitialized)
|
if (TypeMapInitialized)
|
||||||
if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {
|
return;
|
||||||
TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
|
TypeIdentifierMap = generateDITypeIdentifierMap(M);
|
||||||
TypeMapInitialized = true;
|
TypeMapInitialized = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugInfoFinder::processModule(const Module &M) {
|
void DebugInfoFinder::processModule(const Module &M) {
|
||||||
InitializeTypeMap(M);
|
InitializeTypeMap(M);
|
||||||
if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) {
|
for (auto *CU : M.debug_compile_units()) {
|
||||||
for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
|
addCompileUnit(CU);
|
||||||
auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
|
for (auto *DIG : CU->getGlobalVariables()) {
|
||||||
addCompileUnit(CU);
|
if (addGlobalVariable(DIG)) {
|
||||||
for (auto *DIG : CU->getGlobalVariables()) {
|
processScope(DIG->getScope());
|
||||||
if (addGlobalVariable(DIG)) {
|
processType(DIG->getType().resolve(TypeIdentifierMap));
|
||||||
processScope(DIG->getScope());
|
|
||||||
processType(DIG->getType().resolve(TypeIdentifierMap));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (auto *SP : CU->getSubprograms())
|
}
|
||||||
|
for (auto *SP : CU->getSubprograms())
|
||||||
|
processSubprogram(SP);
|
||||||
|
for (auto *ET : CU->getEnumTypes())
|
||||||
|
processType(ET);
|
||||||
|
for (auto *RT : CU->getRetainedTypes())
|
||||||
|
processType(RT);
|
||||||
|
for (auto *Import : CU->getImportedEntities()) {
|
||||||
|
auto *Entity = Import->getEntity().resolve(TypeIdentifierMap);
|
||||||
|
if (auto *T = dyn_cast<DIType>(Entity))
|
||||||
|
processType(T);
|
||||||
|
else if (auto *SP = dyn_cast<DISubprogram>(Entity))
|
||||||
processSubprogram(SP);
|
processSubprogram(SP);
|
||||||
for (auto *ET : CU->getEnumTypes())
|
else if (auto *NS = dyn_cast<DINamespace>(Entity))
|
||||||
processType(ET);
|
processScope(NS->getScope());
|
||||||
for (auto *RT : CU->getRetainedTypes())
|
else if (auto *M = dyn_cast<DIModule>(Entity))
|
||||||
processType(RT);
|
processScope(M->getScope());
|
||||||
for (auto *Import : CU->getImportedEntities()) {
|
|
||||||
auto *Entity = Import->getEntity().resolve(TypeIdentifierMap);
|
|
||||||
if (auto *T = dyn_cast<DIType>(Entity))
|
|
||||||
processType(T);
|
|
||||||
else if (auto *SP = dyn_cast<DISubprogram>(Entity))
|
|
||||||
processSubprogram(SP);
|
|
||||||
else if (auto *NS = dyn_cast<DINamespace>(Entity))
|
|
||||||
processScope(NS->getScope());
|
|
||||||
else if (auto *M = dyn_cast<DIModule>(Entity))
|
|
||||||
processScope(M->getScope());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
#include "llvm/IR/Constants.h"
|
#include "llvm/IR/Constants.h"
|
||||||
#include "llvm/IR/DerivedTypes.h"
|
#include "llvm/IR/DerivedTypes.h"
|
||||||
|
#include "llvm/IR/DebugInfoMetadata.h"
|
||||||
#include "llvm/IR/GVMaterializer.h"
|
#include "llvm/IR/GVMaterializer.h"
|
||||||
#include "llvm/IR/InstrTypes.h"
|
#include "llvm/IR/InstrTypes.h"
|
||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
@ -380,6 +381,19 @@ void Module::setDataLayout(const DataLayout &Other) { DL = Other; }
|
|||||||
|
|
||||||
const DataLayout &Module::getDataLayout() const { return DL; }
|
const DataLayout &Module::getDataLayout() const { return DL; }
|
||||||
|
|
||||||
|
DICompileUnit *Module::debug_compile_units_iterator::operator*() const {
|
||||||
|
return cast<DICompileUnit>(CUs->getOperand(Idx));
|
||||||
|
}
|
||||||
|
DICompileUnit *Module::debug_compile_units_iterator::operator->() const {
|
||||||
|
return cast<DICompileUnit>(CUs->getOperand(Idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::debug_compile_units_iterator::SkipNoDebugCUs() {
|
||||||
|
while (CUs && (Idx < CUs->getNumOperands()) &&
|
||||||
|
((*this)->getEmissionKind() == DICompileUnit::NoDebug))
|
||||||
|
++Idx;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Methods to control the materialization of GlobalValues in the Module.
|
// Methods to control the materialization of GlobalValues in the Module.
|
||||||
//
|
//
|
||||||
|
50
test/DebugInfo/X86/mixed-nodebug-cu.ll
Normal file
50
test/DebugInfo/X86/mixed-nodebug-cu.ll
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
; RUN: llc %s -o %t -filetype=obj
|
||||||
|
; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s
|
||||||
|
; CHECK: DW_TAG_compile_unit
|
||||||
|
; CHECK: DW_TAG_subprogram
|
||||||
|
; CHECK: DW_AT_name{{.*}}"f"
|
||||||
|
; CHECK-NOT: DW_TAG_compile_unit
|
||||||
|
;
|
||||||
|
; created from
|
||||||
|
; void f() {} // compile with -g
|
||||||
|
; void g() {} // compile with -Rpass=inline
|
||||||
|
; and llvm-linking the result.
|
||||||
|
|
||||||
|
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
target triple = "x86_64-apple-macosx10.11.0"
|
||||||
|
|
||||||
|
; Function Attrs: nounwind ssp uwtable
|
||||||
|
define void @f() #0 !dbg !4 {
|
||||||
|
entry:
|
||||||
|
ret void, !dbg !15
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nounwind ssp uwtable
|
||||||
|
define void @g() #0 !dbg !9 {
|
||||||
|
entry:
|
||||||
|
ret void, !dbg !16
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes #0 = { nounwind ssp uwtable }
|
||||||
|
|
||||||
|
!llvm.dbg.cu = !{!0, !7}
|
||||||
|
!llvm.ident = !{!11, !11}
|
||||||
|
!llvm.module.flags = !{!12, !13, !14}
|
||||||
|
|
||||||
|
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, subprograms: !3)
|
||||||
|
!1 = !DIFile(filename: "test.c", directory: "/Volumes/Data/llvm")
|
||||||
|
!2 = !{}
|
||||||
|
!3 = !{!4}
|
||||||
|
!4 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, variables: !2)
|
||||||
|
!5 = !DISubroutineType(types: !6)
|
||||||
|
!6 = !{null}
|
||||||
|
!7 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)", isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug, enums: !2, subprograms: !8)
|
||||||
|
!8 = !{!9}
|
||||||
|
!9 = distinct !DISubprogram(name: "g", scope: !1, file: !1, line: 1, type: !10, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, variables: !2)
|
||||||
|
!10 = !DISubroutineType(types: !2)
|
||||||
|
!11 = !{!"clang version 3.9.0 (trunk 265328) (llvm/trunk 265330)"}
|
||||||
|
!12 = !{i32 2, !"Dwarf Version", i32 2}
|
||||||
|
!13 = !{i32 2, !"Debug Info Version", i32 3}
|
||||||
|
!14 = !{i32 1, !"PIC Level", i32 2}
|
||||||
|
!15 = !DILocation(line: 1, column: 12, scope: !4)
|
||||||
|
!16 = !DILocation(line: 1, column: 12, scope: !9)
|
@ -45,9 +45,7 @@ struct BreakpointPrinter : public ModulePass {
|
|||||||
|
|
||||||
bool runOnModule(Module &M) override {
|
bool runOnModule(Module &M) override {
|
||||||
TypeIdentifierMap.clear();
|
TypeIdentifierMap.clear();
|
||||||
NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");
|
TypeIdentifierMap = generateDITypeIdentifierMap(M);
|
||||||
if (CU_Nodes)
|
|
||||||
TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
|
|
||||||
|
|
||||||
StringSet<> Processed;
|
StringSet<> Processed;
|
||||||
if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp"))
|
if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp"))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user