Until now all debug info MDNodes referred to a root MDNode, a compile unit. This simplified handling of these needs in dwarf writer. However, one side effect of this is that during link time optimization all these MDNodes are _not_ uniqued. In other words there will be N number of MDNodes describing "int", "char" and all other types, which would suddenly grow when each object file starts using libraries like STL.

MDNodes graph structure such that compiler unit keeps track of important MDNodes and update dwarf writer to process mdnodes top-down instead of bottom up.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137778 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2011-08-16 22:09:43 +00:00
parent 054ddf799b
commit 94c7ddb6f5
9 changed files with 249 additions and 179 deletions

View File

@ -355,7 +355,7 @@ height="369">
;; (DW_TAG_file_type)
metadata, ;; Source file name
metadata, ;; Source file directory (includes trailing slash)
metadata ;; Reference to compile unit where defined
metadata ;; Unused
}
</pre>
</div>
@ -365,8 +365,7 @@ height="369">
provide context for source line correspondence. </p>
<p>Each input file is encoded as a separate file descriptor in LLVM debugging
information output. Each file descriptor would be defined using a
compile unit. </p>
information output. </p>
</div>
@ -485,7 +484,7 @@ global variables are collected by named metadata <tt>!llvm.dbg.gv</tt>.</p>
!4 = metadata !{
i32, ;; Tag = 36 + <a href="#LLVMDebugVersion">LLVMDebugVersion</a>
;; (DW_TAG_base_type)
metadata, ;; Reference to context (typically a compile unit)
metadata, ;; Reference to context
metadata, ;; Name (may be "" for anonymous types)
metadata, ;; Reference to file where defined (may be NULL)
i32, ;; Line number where defined (may be 0)
@ -500,7 +499,7 @@ global variables are collected by named metadata <tt>!llvm.dbg.gv</tt>.</p>
<p>These descriptors define primitive types used in the code. Example int, bool
and float. The context provides the scope of the type, which is usually the
top level. Since basic types are not usually user defined the compile unit
top level. Since basic types are not usually user defined the context
and line number can be left as NULL and 0. The size, alignment and offset
are expressed in bits and can be 64 bit values. The alignment is used to
round the offset when embedded in a
@ -585,7 +584,7 @@ DW_TAG_restrict_type = 55
the <a href="#format_derived_type">derived type</a>. </p>
<p><a href="#format_derived_type">Derived type</a> location can be determined
from the compile unit and line number. The size, alignment and offset are
from the context and line number. The size, alignment and offset are
expressed in bits and can be 64 bit values. The alignment is used to round
the offset when embedded in a <a href="#format_composite_type">composite
type</a> (example to keep float doubles on 64 bit boundaries.) The offset is
@ -675,7 +674,7 @@ DW_TAG_inheritance = 28
the formal arguments to the subroutine.</p>
<p><a href="#format_composite_type">Composite type</a> location can be
determined from the compile unit and line number. The size, alignment and
determined from the context and line number. The size, alignment and
offset are expressed in bits and can be 64 bit values. The alignment is used
to round the offset when embedded in
a <a href="#format_composite_type">composite type</a> (as an example, to keep
@ -774,7 +773,7 @@ DW_TAG_return_variable = 258
has no source correspondent.</p>
<p>The context is either the subprogram or block where the variable is defined.
Name the source variable name. Compile unit and line indicate where the
Name the source variable name. Context and line indicate where the
variable was defined. Type descriptor defines the declared type of the
variable.</p>

View File

@ -48,9 +48,19 @@ namespace llvm {
LLVMContext & VMContext;
MDNode *TheCU;
MDNode *TempEnumTypes;
MDNode *TempRetainTypes;
MDNode *TempSubprograms;
MDNode *TempGVs;
Function *DeclareFn; // llvm.dbg.declare
Function *ValueFn; // llvm.dbg.value
SmallVector<Value *, 4> AllEnumTypes;
SmallVector<Value *, 4> AllRetainTypes;
SmallVector<Value *, 4> AllSubprograms;
SmallVector<Value *, 4> AllGVs;
DIBuilder(const DIBuilder &); // DO NOT IMPLEMENT
void operator=(const DIBuilder &); // DO NOT IMPLEMENT

View File

@ -182,6 +182,11 @@ namespace llvm {
StringRef getFlags() const { return getStringField(8); }
unsigned getRunTimeVersion() const { return getUnsignedField(9); }
DIArray getEnumTypes() const;
DIArray getRetainedTypes() const;
DIArray getSubprograms() const;
DIArray getGlobalVariables() const;
/// Verify - Verify that a compile unit is well formed.
bool Verify() const;
@ -201,7 +206,10 @@ namespace llvm {
}
StringRef getFilename() const { return getStringField(1); }
StringRef getDirectory() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{ return getFieldAs<DICompileUnit>(3); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid CompileUnit!");
return getFieldAs<DICompileUnit>(3);
}
};
/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
@ -237,6 +245,7 @@ namespace llvm {
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
@ -450,6 +459,7 @@ namespace llvm {
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(6);
@ -560,6 +570,7 @@ namespace llvm {
StringRef getDisplayName() const { return getStringField(4); }
StringRef getLinkageName() const { return getStringField(5); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(6);
@ -595,6 +606,7 @@ namespace llvm {
DIScope getContext() const { return getFieldAs<DIScope>(1); }
StringRef getName() const { return getStringField(2); }
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);
@ -687,6 +699,7 @@ namespace llvm {
return getFieldAs<DIFile>(3).getFilename();
}
DICompileUnit getCompileUnit() const{
assert (getVersion() <= LLVMDebugVersion10 && "Invalid getCompileUnit!");
if (getVersion() == llvm::LLVMDebugVersion7)
return getFieldAs<DICompileUnit>(3);

View File

@ -29,10 +29,30 @@ static Constant *GetTagConstant(LLVMContext &VMContext, unsigned Tag) {
}
DIBuilder::DIBuilder(Module &m)
: M(m), VMContext(M.getContext()), TheCU(0), DeclareFn(0), ValueFn(0) {}
: M(m), VMContext(M.getContext()), TheCU(0), TempEnumTypes(0),
TempRetainTypes(0), TempSubprograms(0), TempGVs(0), DeclareFn(0), ValueFn(0)
{}
/// finalize - Construct any deferred debug info descriptors.
void DIBuilder::finalize() {
DIArray Enums = getOrCreateArray(AllEnumTypes);
DIType(TempEnumTypes).replaceAllUsesWith(Enums);
DIArray RetainTypes = getOrCreateArray(AllRetainTypes);
DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes);
DIArray SPs = getOrCreateArray(AllSubprograms);
DIType(TempSubprograms).replaceAllUsesWith(SPs);
DIArray GVs = getOrCreateArray(AllGVs);
DIType(TempGVs).replaceAllUsesWith(GVs);
}
/// getNonCompileUnitScope - If N is compile unit return NULL otherwise return N.
static MDNode *getNonCompileUnitScope(MDNode *N) {
if (DIDescriptor(N).isCompileUnit())
return NULL;
return N;
}
/// createCompileUnit - A CompileUnit provides an anchor for all debugging
@ -41,6 +61,23 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
StringRef Directory, StringRef Producer,
bool isOptimized, StringRef Flags,
unsigned RunTimeVer) {
Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) };
TempEnumTypes = MDNode::getTemporary(VMContext, TElts);
Value *THElts[] = { TempEnumTypes };
MDNode *EnumHolder = MDNode::get(VMContext, THElts);
TempRetainTypes = MDNode::getTemporary(VMContext, TElts);
Value *TRElts[] = { TempRetainTypes };
MDNode *RetainHolder = MDNode::get(VMContext, TRElts);
TempSubprograms = MDNode::getTemporary(VMContext, TElts);
Value *TSElts[] = { TempSubprograms };
MDNode *SPHolder = MDNode::get(VMContext, TSElts);
TempGVs = MDNode::getTemporary(VMContext, TElts);
Value *TVElts[] = { TempGVs };
MDNode *GVHolder = MDNode::get(VMContext, TVElts);
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_compile_unit),
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
@ -52,7 +89,11 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
ConstantInt::get(Type::getInt1Ty(VMContext), true), // isMain
ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized),
MDString::get(VMContext, Flags),
ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer)
ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer),
EnumHolder,
RetainHolder,
SPHolder,
GVHolder
};
TheCU = DICompileUnit(MDNode::get(VMContext, Elts));
@ -69,7 +110,7 @@ DIFile DIBuilder::createFile(StringRef Filename, StringRef Directory) {
GetTagConstant(VMContext, dwarf::DW_TAG_file_type),
MDString::get(VMContext, Filename),
MDString::get(VMContext, Directory),
TheCU
NULL // TheCU
};
return DIFile(MDNode::get(VMContext, Elts));
}
@ -93,7 +134,7 @@ DIType DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
// offset and flags are always empty here.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_base_type),
TheCU,
NULL, //TheCU,
MDString::get(VMContext, Name),
NULL, // Filename
ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
@ -112,7 +153,7 @@ DIType DIBuilder::createQualifiedType(unsigned Tag, DIType FromTy) {
// Qualified types are encoded in DIDerivedType format.
Value *Elts[] = {
GetTagConstant(VMContext, Tag),
TheCU,
NULL, //TheCU,
MDString::get(VMContext, StringRef()), // Empty name.
NULL, // Filename
ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
@ -131,7 +172,7 @@ DIType DIBuilder::createPointerType(DIType PointeeTy, uint64_t SizeInBits,
// Pointer types are encoded in DIDerivedType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_pointer_type),
TheCU,
NULL, //TheCU,
MDString::get(VMContext, Name),
NULL, // Filename
ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
@ -149,7 +190,7 @@ DIType DIBuilder::createReferenceType(DIType RTy) {
// References are encoded in DIDerivedType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_reference_type),
TheCU,
NULL, //TheCU,
NULL, // Name
NULL, // Filename
ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Line
@ -169,7 +210,7 @@ DIType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File,
assert(Ty.Verify() && "Invalid typedef type!");
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_typedef),
Context,
getNonCompileUnitScope(Context),
MDString::get(VMContext, Name),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
@ -231,7 +272,7 @@ DIType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name,
// TAG_member is encoded in DIDerivedType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_member),
Scope,
getNonCompileUnitScope(Scope),
MDString::get(VMContext, Name),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
@ -256,7 +297,7 @@ DIType DIBuilder::createObjCIVar(StringRef Name,
// TAG_member is encoded in DIDerivedType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_member),
File, // Or TheCU ? Ty ?
getNonCompileUnitScope(File),
MDString::get(VMContext, Name),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
@ -283,7 +324,7 @@ DIType DIBuilder::createClassType(DIDescriptor Context, StringRef Name,
// TAG_class_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_class_type),
Context,
getNonCompileUnitScope(Context),
MDString::get(VMContext, Name),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
@ -308,7 +349,7 @@ DIBuilder::createTemplateTypeParameter(DIDescriptor Context, StringRef Name,
unsigned ColumnNo) {
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_template_type_parameter),
Context,
getNonCompileUnitScope(Context),
MDString::get(VMContext, Name),
Ty,
File,
@ -327,7 +368,7 @@ DIBuilder::createTemplateValueParameter(DIDescriptor Context, StringRef Name,
unsigned ColumnNo) {
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_template_value_parameter),
Context,
getNonCompileUnitScope(Context),
MDString::get(VMContext, Name),
Ty,
ConstantInt::get(Type::getInt64Ty(VMContext), Val),
@ -347,7 +388,7 @@ DIType DIBuilder::createStructType(DIDescriptor Context, StringRef Name,
// TAG_structure_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_structure_type),
Context,
getNonCompileUnitScope(Context),
MDString::get(VMContext, Name),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
@ -372,7 +413,7 @@ DIType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name,
// TAG_union_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_union_type),
Scope,
getNonCompileUnitScope(Scope),
MDString::get(VMContext, Name),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
@ -393,7 +434,7 @@ DIType DIBuilder::createSubroutineType(DIFile File, DIArray ParameterTypes) {
// TAG_subroutine_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_subroutine_type),
File,
getNonCompileUnitScope(File),
MDString::get(VMContext, ""),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), 0),
@ -418,7 +459,7 @@ DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name,
// TAG_enumeration_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_enumeration_type),
Scope,
getNonCompileUnitScope(Scope),
MDString::get(VMContext, Name),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
@ -432,8 +473,7 @@ DIType DIBuilder::createEnumerationType(DIDescriptor Scope, StringRef Name,
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
};
MDNode *Node = MDNode::get(VMContext, Elts);
NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.enum");
NMD->addOperand(Node);
AllEnumTypes.push_back(Node);
return DIType(Node);
}
@ -443,9 +483,9 @@ DIType DIBuilder::createArrayType(uint64_t Size, uint64_t AlignInBits,
// TAG_array_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_array_type),
TheCU,
NULL, //TheCU,
MDString::get(VMContext, ""),
TheCU,
NULL, //TheCU,
ConstantInt::get(Type::getInt32Ty(VMContext), 0),
ConstantInt::get(Type::getInt64Ty(VMContext), Size),
ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
@ -465,9 +505,9 @@ DIType DIBuilder::createVectorType(uint64_t Size, uint64_t AlignInBits,
// TAG_vector_type is encoded in DICompositeType format.
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_vector_type),
TheCU,
NULL, //TheCU,
MDString::get(VMContext, ""),
TheCU,
NULL, //TheCU,
ConstantInt::get(Type::getInt32Ty(VMContext), 0),
ConstantInt::get(Type::getInt64Ty(VMContext), Size),
ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
@ -508,8 +548,7 @@ DIType DIBuilder::createArtificialType(DIType Ty) {
/// retainType - Retain DIType in a module even if it is not referenced
/// through debug info anchors.
void DIBuilder::retainType(DIType T) {
NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.ty");
NMD->addOperand(T);
AllRetainTypes.push_back(T);
}
/// createUnspecifiedParameter - Create unspeicified type descriptor
@ -536,7 +575,7 @@ DIType DIBuilder::createTemporaryType(DIFile F) {
// use here as long as DIType accepts it.
Value *Elts[] = {
GetTagConstant(VMContext, DW_TAG_base_type),
F.getCompileUnit(),
TheCU,
NULL,
F
};
@ -572,7 +611,7 @@ createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber,
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_variable),
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
TheCU,
NULL, // TheCU,
MDString::get(VMContext, Name),
MDString::get(VMContext, Name),
MDString::get(VMContext, Name),
@ -584,9 +623,7 @@ createGlobalVariable(StringRef Name, DIFile F, unsigned LineNumber,
Val
};
MDNode *Node = MDNode::get(VMContext, Elts);
// Create a named metadata so that we do not lose this mdnode.
NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv");
NMD->addOperand(Node);
AllGVs.push_back(Node);
return DIGlobalVariable(Node);
}
@ -599,7 +636,7 @@ createStaticVariable(DIDescriptor Context, StringRef Name,
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_variable),
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
Context,
getNonCompileUnitScope(Context),
MDString::get(VMContext, Name),
MDString::get(VMContext, Name),
MDString::get(VMContext, LinkageName),
@ -611,9 +648,7 @@ createStaticVariable(DIDescriptor Context, StringRef Name,
Val
};
MDNode *Node = MDNode::get(VMContext, Elts);
// Create a named metadata so that we do not lose this mdnode.
NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv");
NMD->addOperand(Node);
AllGVs.push_back(Node);
return DIGlobalVariable(Node);
}
@ -625,7 +660,7 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,
unsigned ArgNo) {
Value *Elts[] = {
GetTagConstant(VMContext, Tag),
Scope,
getNonCompileUnitScope(Scope),
MDString::get(VMContext, Name),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), (LineNo | (ArgNo << 24))),
@ -660,7 +695,7 @@ DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope,
unsigned ArgNo) {
SmallVector<Value *, 15> Elts;
Elts.push_back(GetTagConstant(VMContext, Tag));
Elts.push_back(Scope);
Elts.push_back(getNonCompileUnitScope(Scope)),
Elts.push_back(MDString::get(VMContext, Name));
Elts.push_back(F);
Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), (LineNo | (ArgNo << 24))));
@ -686,7 +721,7 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context,
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_subprogram),
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
Context,
getNonCompileUnitScope(Context),
MDString::get(VMContext, Name),
MDString::get(VMContext, Name),
MDString::get(VMContext, LinkageName),
@ -707,8 +742,7 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context,
MDNode *Node = MDNode::get(VMContext, Elts);
// Create a named metadata so that we do not lose this mdnode.
NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.sp");
NMD->addOperand(Node);
AllSubprograms.push_back(Node);
return DISubprogram(Node);
}
@ -729,7 +763,7 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context,
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_subprogram),
llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
Context,
getNonCompileUnitScope(Context),
MDString::get(VMContext, Name),
MDString::get(VMContext, Name),
MDString::get(VMContext, LinkageName),
@ -747,10 +781,6 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context,
TParam,
};
MDNode *Node = MDNode::get(VMContext, Elts);
// Create a named metadata so that we do not lose this mdnode.
NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.sp");
NMD->addOperand(Node);
return DISubprogram(Node);
}
@ -760,7 +790,7 @@ DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name,
DIFile File, unsigned LineNo) {
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_namespace),
Scope,
getNonCompileUnitScope(Scope),
MDString::get(VMContext, Name),
File,
ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)
@ -774,7 +804,7 @@ DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File,
static unsigned int unique_id = 0;
Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block),
Scope,
getNonCompileUnitScope(Scope),
ConstantInt::get(Type::getInt32Ty(VMContext), Line),
ConstantInt::get(Type::getInt32Ty(VMContext), Col),
File,

View File

@ -359,7 +359,7 @@ bool DICompileUnit::Verify() const {
bool DIType::Verify() const {
if (!DbgNode)
return false;
if (!getContext().Verify())
if (getContext() && !getContext().Verify())
return false;
unsigned Tag = getTag();
if (!isBasicType() && Tag != dwarf::DW_TAG_const_type &&
@ -386,12 +386,9 @@ bool DIDerivedType::Verify() const {
bool DICompositeType::Verify() const {
if (!DbgNode)
return false;
if (!getContext().Verify())
if (getContext() && !getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
if (!CU.Verify())
return false;
return true;
}
@ -400,11 +397,7 @@ bool DISubprogram::Verify() const {
if (!DbgNode)
return false;
if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
if (!CU.Verify())
if (getContext() && !getContext().Verify())
return false;
DICompositeType Ty = getType();
@ -421,11 +414,7 @@ bool DIGlobalVariable::Verify() const {
if (getDisplayName().empty())
return false;
if (!getContext().Verify())
return false;
DICompileUnit CU = getCompileUnit();
if (!CU.Verify())
if (getContext() && !getContext().Verify())
return false;
DIType Ty = getType();
@ -443,10 +432,7 @@ bool DIVariable::Verify() const {
if (!DbgNode)
return false;
if (!getContext().Verify())
return false;
if (!getCompileUnit().Verify())
if (getContext() && !getContext().Verify())
return false;
DIType Ty = getType();
@ -470,8 +456,6 @@ bool DINameSpace::Verify() const {
return false;
if (getName().empty())
return false;
if (!getCompileUnit().Verify())
return false;
return true;
}
@ -566,6 +550,47 @@ StringRef DIScope::getDirectory() const {
return StringRef();
}
DIArray DICompileUnit::getEnumTypes() const {
if (!DbgNode || DbgNode->getNumOperands() < 14)
return DIArray();
if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(10)))
if (MDNode *A = dyn_cast_or_null<MDNode>(N->getOperand(0)))
return DIArray(A);
return DIArray();
}
DIArray DICompileUnit::getRetainedTypes() const {
if (!DbgNode || DbgNode->getNumOperands() < 14)
return DIArray();
if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(11)))
if (MDNode *A = dyn_cast_or_null<MDNode>(N->getOperand(0)))
return DIArray(A);
return DIArray();
}
DIArray DICompileUnit::getSubprograms() const {
if (!DbgNode || DbgNode->getNumOperands() < 14)
return DIArray();
if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(12)))
if (MDNode *A = dyn_cast_or_null<MDNode>(N->getOperand(0)))
return DIArray(A);
return DIArray();
}
DIArray DICompileUnit::getGlobalVariables() const {
if (!DbgNode || DbgNode->getNumOperands() < 14)
return DIArray();
if (MDNode *N = dyn_cast_or_null<MDNode>(DbgNode->getOperand(13)))
if (MDNode *A = dyn_cast_or_null<MDNode>(N->getOperand(0)))
return DIArray(A);
return DIArray();
}
//===----------------------------------------------------------------------===//
// DIDescriptor: dump routines for all descriptors.
//===----------------------------------------------------------------------===//
@ -597,7 +622,6 @@ void DIType::print(raw_ostream &OS) const {
OS << " [" << dwarf::TagString(Tag) << "] ";
// TODO : Print context
getCompileUnit().print(OS);
OS << " ["
<< "line " << getLineNumber() << ", "
<< getSizeInBits() << " bits, "
@ -653,7 +677,6 @@ void DISubprogram::print(raw_ostream &OS) const {
OS << " [" << dwarf::TagString(Tag) << "] ";
// TODO : Print context
getCompileUnit().print(OS);
OS << " [" << getLineNumber() << "] ";
if (isLocalToUnit())
@ -676,7 +699,6 @@ void DIGlobalVariable::print(raw_ostream &OS) const {
OS << " [" << dwarf::TagString(Tag) << "] ";
// TODO : Print context
getCompileUnit().print(OS);
OS << " [" << getLineNumber() << "] ";
if (isLocalToUnit())
@ -732,7 +754,6 @@ void DIVariable::print(raw_ostream &OS) const {
if (!Res.empty())
OS << " [" << Res << "] ";
getCompileUnit().print(OS);
OS << " [" << getLineNumber() << "] ";
getType().print(OS);
OS << "\n";

View File

@ -577,7 +577,10 @@ void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *CompileUnit::getOrCreateTypeDIE(DIType Ty) {
DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
DIType Ty(TyNode);
if (!Ty.Verify())
return NULL;
DIE *TyDIE = getDIE(Ty);
if (TyDIE)
return TyDIE;
@ -629,7 +632,8 @@ void CompileUnit::addType(DIE *Entity, DIType Ty) {
void CompileUnit::addGlobalType(DIType Ty) {
DIDescriptor Context = Ty.getContext();
if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl()
&& (Context.isCompileUnit() || Context.isFile() || Context.isNameSpace()))
&& (!Context || Context.isCompileUnit() || Context.isFile()
|| Context.isNameSpace()))
if (DIEEntry *Entry = getDIEEntry(Ty))
GlobalTypes[Ty.getName()] = Entry->getEntry();
}
@ -1358,7 +1362,7 @@ DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
dwarf::DW_ACCESS_private);
// Otherwise C++ member and base classes are considered public.
else if (DT.getCompileUnit().getLanguage() == dwarf::DW_LANG_C_plus_plus)
else
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
dwarf::DW_ACCESS_public);
if (DT.isVirtual())

View File

@ -236,7 +236,7 @@ public:
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *getOrCreateTypeDIE(DIType Ty);
DIE *getOrCreateTypeDIE(const MDNode *N);
/// getOrCreateTemplateTypeParameterDIE - Find existing DIE or create new DIE
/// for the given DITemplateTypeParameter.

View File

@ -465,7 +465,7 @@ unsigned DwarfDebug::GetOrCreateSourceID(StringRef FileName,
/// constructCompileUnit - Create new CompileUnit for the given
/// metadata node with tag DW_TAG_compile_unit.
void DwarfDebug::constructCompileUnit(const MDNode *N) {
CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
DICompileUnit DIUnit(N);
StringRef FN = DIUnit.getFilename();
StringRef Dir = DIUnit.getDirectory();
@ -507,35 +507,7 @@ void DwarfDebug::constructCompileUnit(const MDNode *N) {
if (!FirstCU)
FirstCU = NewCU;
CUMap.insert(std::make_pair(N, NewCU));
}
/// getCompileUnit - Get CompileUnit DIE.
CompileUnit *DwarfDebug::getCompileUnit(const MDNode *N) const {
assert (N && "Invalid DwarfDebug::getCompileUnit argument!");
DIDescriptor D(N);
const MDNode *CUNode = NULL;
if (D.isCompileUnit())
CUNode = N;
else if (D.isSubprogram())
CUNode = DISubprogram(N).getCompileUnit();
else if (D.isType())
CUNode = DIType(N).getCompileUnit();
else if (D.isGlobalVariable())
CUNode = DIGlobalVariable(N).getCompileUnit();
else if (D.isVariable())
CUNode = DIVariable(N).getCompileUnit();
else if (D.isNameSpace())
CUNode = DINameSpace(N).getCompileUnit();
else if (D.isFile())
CUNode = DIFile(N).getCompileUnit();
else
return FirstCU;
DenseMap<const MDNode *, CompileUnit *>::const_iterator I
= CUMap.find(CUNode);
if (I == CUMap.end())
return FirstCU;
return I->second;
return NewCU;
}
/// constructGlobalVariableDIE - Construct global variable DIE.
@ -571,22 +543,39 @@ void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU,
// Expose as global.
TheCU->addGlobal(SP.getName(), SubprogramDie);
SPMap[N] = TheCU;
return;
}
/// collectInfoFromNamedMDNodes - Collect debug info from named mdnodes such
/// as llvm.dbg.enum and llvm.dbg.ty
void DwarfDebug::collectInfoFromNamedMDNodes(Module *M) {
if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp"))
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
const MDNode *N = NMD->getOperand(i);
if (CompileUnit *CU = CUMap.lookup(DISubprogram(N).getCompileUnit()))
constructSubprogramDIE(CU, N);
}
if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv"))
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
const MDNode *N = NMD->getOperand(i);
if (CompileUnit *CU = CUMap.lookup(DIGlobalVariable(N).getCompileUnit()))
constructGlobalVariableDIE(CU, N);
}
if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.enum"))
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
DIType Ty(NMD->getOperand(i));
getCompileUnit(Ty)->getOrCreateTypeDIE(Ty);
if (CompileUnit *CU = CUMap.lookup(Ty.getCompileUnit()))
CU->getOrCreateTypeDIE(Ty);
}
if (NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.ty"))
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
DIType Ty(NMD->getOperand(i));
getCompileUnit(Ty)->getOrCreateTypeDIE(Ty);
if (CompileUnit *CU = CUMap.lookup(Ty.getCompileUnit()))
CU->getOrCreateTypeDIE(Ty);
}
}
@ -617,14 +606,16 @@ bool DwarfDebug::collectLegacyDebugInfo(Module *M) {
for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
E = DbgFinder.global_variable_end(); I != E; ++I) {
const MDNode *N = *I;
constructGlobalVariableDIE(getCompileUnit(N), N);
if (CompileUnit *CU = CUMap.lookup(DIGlobalVariable(N).getCompileUnit()))
constructGlobalVariableDIE(CU, N);
}
// Create DIEs for each subprogram.
for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
E = DbgFinder.subprogram_end(); I != E; ++I) {
const MDNode *N = *I;
constructSubprogramDIE(getCompileUnit(N), N);
if (CompileUnit *CU = CUMap.lookup(DISubprogram(N).getCompileUnit()))
constructSubprogramDIE(CU, N);
}
return HasDebugInfo;
@ -641,29 +632,22 @@ void DwarfDebug::beginModule(Module *M) {
// module using debug info finder to collect debug info.
NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
if (CU_Nodes) {
NamedMDNode *GV_Nodes = M->getNamedMetadata("llvm.dbg.gv");
NamedMDNode *SP_Nodes = M->getNamedMetadata("llvm.dbg.sp");
if (!GV_Nodes && !SP_Nodes)
// If there are not any global variables or any functions then
// there is not any debug info in this module.
return;
for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i)
constructCompileUnit(CU_Nodes->getOperand(i));
if (GV_Nodes)
for (unsigned i = 0, e = GV_Nodes->getNumOperands(); i != e; ++i) {
const MDNode *N = GV_Nodes->getOperand(i);
constructGlobalVariableDIE(getCompileUnit(N), N);
}
if (SP_Nodes)
for (unsigned i = 0, e = SP_Nodes->getNumOperands(); i != e; ++i) {
const MDNode *N = SP_Nodes->getOperand(i);
constructSubprogramDIE(getCompileUnit(N), N);
}
for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
DICompileUnit CUNode(CU_Nodes->getOperand(i));
CompileUnit *CU = constructCompileUnit(CUNode);
DIArray GVs = CUNode.getGlobalVariables();
for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i)
constructGlobalVariableDIE(CU, GVs.getElement(i));
DIArray SPs = CUNode.getSubprograms();
for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)
constructSubprogramDIE(CU, SPs.getElement(i));
DIArray EnumTypes = CUNode.getEnumTypes();
for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i)
CU->getOrCreateTypeDIE(EnumTypes.getElement(i));
DIArray RetainedTypes = CUNode.getRetainedTypes();
for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i)
CU->getOrCreateTypeDIE(RetainedTypes.getElement(i));
}
} else if (!collectLegacyDebugInfo(M))
return;
@ -685,39 +669,44 @@ void DwarfDebug::endModule() {
if (!FirstCU) return;
const Module *M = MMI->getModule();
DenseMap<const MDNode *, LexicalScope *> DeadFnScopeMap;
if (NamedMDNode *AllSPs = M->getNamedMetadata("llvm.dbg.sp")) {
for (unsigned SI = 0, SE = AllSPs->getNumOperands(); SI != SE; ++SI) {
if (ProcessedSPNodes.count(AllSPs->getOperand(SI)) != 0) continue;
DISubprogram SP(AllSPs->getOperand(SI));
if (!SP.Verify()) continue;
// Collect info for variables that were optimized out.
if (!SP.isDefinition()) continue;
StringRef FName = SP.getLinkageName();
if (FName.empty())
FName = SP.getName();
NamedMDNode *NMD = getFnSpecificMDNode(*(MMI->getModule()), FName);
if (!NMD) continue;
unsigned E = NMD->getNumOperands();
if (!E) continue;
LexicalScope *Scope = new LexicalScope(NULL, DIDescriptor(SP), NULL,
false);
DeadFnScopeMap[SP] = Scope;
SmallVector<DbgVariable, 8> Variables;
for (unsigned I = 0; I != E; ++I) {
DIVariable DV(NMD->getOperand(I));
if (!DV.Verify()) continue;
Variables.push_back(DbgVariable(DV, NULL));
}
// Construct subprogram DIE and add variables DIEs.
CompileUnit *SPCU = getCompileUnit(SP);
constructSubprogramDIE(SPCU, SP);
DIE *ScopeDIE = SPCU->getDIE(SP);
for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
if (DIE *VariableDIE =
SPCU->constructVariableDIE(&Variables[i], Scope->isAbstractScope()))
ScopeDIE->addChild(VariableDIE);
// Collect info for variables that were optimized out.
if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) {
for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
DICompileUnit TheCU(CU_Nodes->getOperand(i));
DIArray Subprograms = TheCU.getSubprograms();
for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) {
DISubprogram SP(Subprograms.getElement(i));
if (ProcessedSPNodes.count(SP) != 0) continue;
if (!SP.Verify()) continue;
if (!SP.isDefinition()) continue;
StringRef FName = SP.getLinkageName();
if (FName.empty())
FName = SP.getName();
NamedMDNode *NMD = getFnSpecificMDNode(*(MMI->getModule()), FName);
if (!NMD) continue;
unsigned E = NMD->getNumOperands();
if (!E) continue;
LexicalScope *Scope =
new LexicalScope(NULL, DIDescriptor(SP), NULL, false);
DeadFnScopeMap[SP] = Scope;
// Construct subprogram DIE and add variables DIEs.
SmallVector<DbgVariable, 8> Variables;
for (unsigned I = 0; I != E; ++I) {
DIVariable DV(NMD->getOperand(I));
if (!DV.Verify()) continue;
Variables.push_back(DbgVariable(DV, NULL));
}
CompileUnit *SPCU = CUMap.lookup(TheCU);
assert (SPCU && "Unable to find Compile Unit!");
constructSubprogramDIE(SPCU, SP);
DIE *ScopeDIE = SPCU->getDIE(SP);
for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
if (DIE *VariableDIE =
SPCU->constructVariableDIE(&Variables[i], Scope->isAbstractScope()))
ScopeDIE->addChild(VariableDIE);
}
}
}
}
@ -784,6 +773,7 @@ void DwarfDebug::endModule() {
// clean up.
DeleteContainerSeconds(DeadFnScopeMap);
SPMap.clear();
for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
E = CUMap.end(); I != E; ++I)
delete I->second;
@ -1333,7 +1323,8 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
collectVariableInfo(MF, ProcessedVars);
LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
CompileUnit *TheCU = getCompileUnit(FnScope->getScopeNode());
CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
assert (TheCU && "Unable to find compile unit!");
// Construct abstract scopes.
ArrayRef<LexicalScope *> AList = LScopes.getAbstractScopesList();

View File

@ -192,8 +192,13 @@ class DwarfDebug {
//
CompileUnit *FirstCU;
/// Maps MDNode with its corresponding CompileUnit.
DenseMap <const MDNode *, CompileUnit *> CUMap;
/// Maps subprogram MDNode with its corresponding CompileUnit.
DenseMap <const MDNode *, CompileUnit *> SPMap;
/// AbbreviationsSet - Used to uniquely define abbreviations.
///
FoldingSet<DIEAbbrev> AbbreviationsSet;
@ -410,10 +415,7 @@ private:
/// constructCompileUnit - Create new CompileUnit for the given
/// metadata node with tag DW_TAG_compile_unit.
void constructCompileUnit(const MDNode *N);
/// getCompielUnit - Get CompileUnit DIE.
CompileUnit *getCompileUnit(const MDNode *N) const;
CompileUnit *constructCompileUnit(const MDNode *N);
/// constructGlobalVariableDIE - Construct global variable DIE.
void constructGlobalVariableDIE(CompileUnit *TheCU, const MDNode *N);