Switch the type field in DIVariable and DIGlobalVariable over to DITypeRefs.

This allows us to catch more opportunities for ODR-based type uniquing
during LTO.
Paired commit with CFE which updates some testcases to verify the new
DIBuilder behavior.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204106 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Adrian Prantl 2014-03-18 02:34:58 +00:00
parent 4d82ca7462
commit 5e8144df32
9 changed files with 51 additions and 32 deletions

View File

@ -567,7 +567,7 @@ Local variables
metadata, ;; Reference to file where defined metadata, ;; Reference to file where defined
i32, ;; 24 bit - Line number where defined i32, ;; 24 bit - Line number where defined
;; 8 bit - Argument number. 1 indicates 1st argument. ;; 8 bit - Argument number. 1 indicates 1st argument.
metadata, ;; Type descriptor metadata, ;; Reference to the type descriptor
i32, ;; flags i32, ;; flags
metadata ;; (optional) Reference to inline location metadata ;; (optional) Reference to inline location
} }

View File

@ -466,7 +466,7 @@ namespace llvm {
/// @param Val llvm::Value of the variable. /// @param Val llvm::Value of the variable.
DIGlobalVariable DIGlobalVariable
createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo, createGlobalVariable(StringRef Name, DIFile File, unsigned LineNo,
DIType Ty, bool isLocalToUnit, llvm::Value *Val); DITypeRef Ty, bool isLocalToUnit, llvm::Value *Val);
/// \brief Create a new descriptor for the specified global. /// \brief Create a new descriptor for the specified global.
/// @param Name Name of the variable. /// @param Name Name of the variable.
@ -479,7 +479,7 @@ namespace llvm {
/// @param Val llvm::Value of the variable. /// @param Val llvm::Value of the variable.
DIGlobalVariable DIGlobalVariable
createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile File, createGlobalVariable(StringRef Name, StringRef LinkageName, DIFile File,
unsigned LineNo, DIType Ty, bool isLocalToUnit, unsigned LineNo, DITypeRef Ty, bool isLocalToUnit,
llvm::Value *Val); llvm::Value *Val);
/// createStaticVariable - Create a new descriptor for the specified /// createStaticVariable - Create a new descriptor for the specified
@ -497,7 +497,7 @@ namespace llvm {
DIGlobalVariable DIGlobalVariable
createStaticVariable(DIDescriptor Context, StringRef Name, createStaticVariable(DIDescriptor Context, StringRef Name,
StringRef LinkageName, DIFile File, unsigned LineNo, StringRef LinkageName, DIFile File, unsigned LineNo,
DIType Ty, bool isLocalToUnit, llvm::Value *Val, DITypeRef Ty, bool isLocalToUnit, llvm::Value *Val,
MDNode *Decl = NULL); MDNode *Decl = NULL);
@ -518,7 +518,7 @@ namespace llvm {
DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope, DIVariable createLocalVariable(unsigned Tag, DIDescriptor Scope,
StringRef Name, StringRef Name,
DIFile File, unsigned LineNo, DIFile File, unsigned LineNo,
DIType Ty, bool AlwaysPreserve = false, DITypeRef Ty, bool AlwaysPreserve = false,
unsigned Flags = 0, unsigned Flags = 0,
unsigned ArgNo = 0); unsigned ArgNo = 0);
@ -537,7 +537,7 @@ namespace llvm {
/// number. 1 indicates 1st argument. /// number. 1 indicates 1st argument.
DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope, DIVariable createComplexVariable(unsigned Tag, DIDescriptor Scope,
StringRef Name, DIFile F, unsigned LineNo, StringRef Name, DIFile F, unsigned LineNo,
DIType Ty, ArrayRef<Value *> Addr, DITypeRef Ty, ArrayRef<Value *> Addr,
unsigned ArgNo = 0); unsigned ArgNo = 0);
/// createFunction - Create a new descriptor for the specified subprogram. /// createFunction - Create a new descriptor for the specified subprogram.

View File

@ -224,6 +224,7 @@ template <typename T> class DIRef {
friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const; friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
friend DIScopeRef DIScope::getContext() const; friend DIScopeRef DIScope::getContext() const;
friend DIScopeRef DIScope::getRef() const; friend DIScopeRef DIScope::getRef() const;
friend class DIType;
/// Val can be either a MDNode or a MDString, in the latter, /// Val can be either a MDNode or a MDString, in the latter,
/// MDString specifies the type identifier. /// MDString specifies the type identifier.
@ -284,6 +285,11 @@ protected:
public: public:
explicit DIType(const MDNode *N = 0) : DIScope(N) {} explicit DIType(const MDNode *N = 0) : DIScope(N) {}
operator DITypeRef () const {
assert(isType() &&
"constructing DITypeRef from an MDNode that is not a type");
return DITypeRef(&*getRef());
}
/// Verify - Verify that a type descriptor is well formed. /// Verify - Verify that a type descriptor is well formed.
bool Verify() const; bool Verify() const;
@ -616,7 +622,7 @@ public:
} }
unsigned getLineNumber() const { return getUnsignedField(7); } unsigned getLineNumber() const { return getUnsignedField(7); }
DIType getType() const { return getFieldAs<DIType>(8); } DITypeRef getType() const { return getFieldAs<DITypeRef>(8); }
unsigned isLocalToUnit() const { return getUnsignedField(9); } unsigned isLocalToUnit() const { return getUnsignedField(9); }
unsigned isDefinition() const { return getUnsignedField(10); } unsigned isDefinition() const { return getUnsignedField(10); }
@ -648,7 +654,7 @@ public:
unsigned L = getUnsignedField(4); unsigned L = getUnsignedField(4);
return L >> 24; return L >> 24;
} }
DIType getType() const { return getFieldAs<DIType>(5); } DITypeRef getType() const { return getFieldAs<DITypeRef>(5); }
/// isArtificial - Return true if this variable is marked as "artificial". /// isArtificial - Return true if this variable is marked as "artificial".
bool isArtificial() const { bool isArtificial() const {
@ -681,7 +687,9 @@ public:
/// isBlockByrefVariable - Return true if the variable was declared as /// isBlockByrefVariable - Return true if the variable was declared as
/// a "__block" variable (Apple Blocks). /// a "__block" variable (Apple Blocks).
bool isBlockByrefVariable() const { return getType().isBlockByrefStruct(); } bool isBlockByrefVariable(const DITypeIdentifierMap &Map) const {
return (getType().resolve(Map)).isBlockByrefStruct();
}
/// isInlinedFnArgument - Return true if this variable provides debugging /// isInlinedFnArgument - Return true if this variable provides debugging
/// information for an inlined function arguments. /// information for an inlined function arguments.

View File

@ -115,11 +115,17 @@ template <typename T> T DbgVariable::resolve(DIRef<T> Ref) const {
return DD->resolve(Ref); return DD->resolve(Ref);
} }
bool DbgVariable::isBlockByrefVariable() const {
assert(Var.isVariable() && "Invalid complex DbgVariable!");
return Var.isBlockByrefVariable(DD->getTypeIdentifierMap());
}
DIType DbgVariable::getType() const { DIType DbgVariable::getType() const {
DIType Ty = Var.getType(); DIType Ty = Var.getType().resolve(DD->getTypeIdentifierMap());
// FIXME: isBlockByrefVariable should be reformulated in terms of complex // FIXME: isBlockByrefVariable should be reformulated in terms of complex
// addresses instead. // addresses instead.
if (Var.isBlockByrefVariable()) { if (Var.isBlockByrefVariable(DD->getTypeIdentifierMap())) {
/* Byref variables, in Blocks, are declared by the programmer as /* Byref variables, in Blocks, are declared by the programmer as
"SomeType VarName;", but the compiler creates a "SomeType VarName;", but the compiler creates a
__Block_byref_x_VarName struct, and gives the variable VarName __Block_byref_x_VarName struct, and gives the variable VarName
@ -2301,7 +2307,7 @@ void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
const DebugLocEntry &Entry) { const DebugLocEntry &Entry) {
DIVariable DV(Entry.getVariable()); DIVariable DV(Entry.getVariable());
if (Entry.isInt()) { if (Entry.isInt()) {
DIBasicType BTy(DV.getType()); DIBasicType BTy(resolve(DV.getType()));
if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed || if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed ||
BTy.getEncoding() == dwarf::DW_ATE_signed_char)) { BTy.getEncoding() == dwarf::DW_ATE_signed_char)) {
Streamer.EmitInt8(dwarf::DW_OP_consts, "DW_OP_consts"); Streamer.EmitInt8(dwarf::DW_OP_consts, "DW_OP_consts");

View File

@ -199,10 +199,7 @@ public:
assert(Var.isVariable() && "Invalid complex DbgVariable!"); assert(Var.isVariable() && "Invalid complex DbgVariable!");
return Var.hasComplexAddress(); return Var.hasComplexAddress();
} }
bool isBlockByrefVariable() const { bool isBlockByrefVariable() const;
assert(Var.isVariable() && "Invalid complex DbgVariable!");
return Var.isBlockByrefVariable();
}
unsigned getNumAddrElements() const { unsigned getNumAddrElements() const {
assert(Var.isVariable() && "Invalid complex DbgVariable!"); assert(Var.isVariable() && "Invalid complex DbgVariable!");
return Var.getNumAddrElements(); return Var.getNumAddrElements();
@ -777,6 +774,11 @@ public:
return Ref.resolve(TypeIdentifierMap); return Ref.resolve(TypeIdentifierMap);
} }
/// \brief Return the TypeIdentifierMap.
const DITypeIdentifierMap& getTypeIdentifierMap() const {
return TypeIdentifierMap;
}
/// Find the DwarfCompileUnit for the given CU Die. /// Find the DwarfCompileUnit for the given CU Die.
DwarfCompileUnit *lookupUnit(const DIE *CU) const { DwarfCompileUnit *lookupUnit(const DIE *CU) const {
return CUDieMap.lookup(CU); return CUDieMap.lookup(CU);

View File

@ -1604,7 +1604,7 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
assert(GV.isGlobalVariable()); assert(GV.isGlobalVariable());
DIScope GVContext = GV.getContext(); DIScope GVContext = GV.getContext();
DIType GTy = GV.getType(); DIType GTy = DD->resolve(GV.getType());
// If this is a static data member definition, some attributes belong // If this is a static data member definition, some attributes belong
// to the declaration DIE. // to the declaration DIE.

View File

@ -927,7 +927,7 @@ DISubrange DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) {
DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name,
StringRef LinkageName, StringRef LinkageName,
DIFile F, unsigned LineNumber, DIFile F, unsigned LineNumber,
DIType Ty, bool isLocalToUnit, DITypeRef Ty, bool isLocalToUnit,
Value *Val) { Value *Val) {
Value *Elts[] = { Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_variable), GetTagConstant(VMContext, dwarf::DW_TAG_variable),
@ -951,7 +951,8 @@ DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name,
/// \brief Create a new descriptor for the specified global. /// \brief Create a new descriptor for the specified global.
DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, DIFile F, DIGlobalVariable DIBuilder::createGlobalVariable(StringRef Name, DIFile F,
unsigned LineNumber, DIType Ty, unsigned LineNumber,
DITypeRef Ty,
bool isLocalToUnit, bool isLocalToUnit,
Value *Val) { Value *Val) {
return createGlobalVariable(Name, Name, F, LineNumber, Ty, isLocalToUnit, return createGlobalVariable(Name, Name, F, LineNumber, Ty, isLocalToUnit,
@ -964,7 +965,8 @@ DIGlobalVariable DIBuilder::createStaticVariable(DIDescriptor Context,
StringRef Name, StringRef Name,
StringRef LinkageName, StringRef LinkageName,
DIFile F, unsigned LineNumber, DIFile F, unsigned LineNumber,
DIType Ty, bool isLocalToUnit, DITypeRef Ty,
bool isLocalToUnit,
Value *Val, MDNode *Decl) { Value *Val, MDNode *Decl) {
Value *Elts[] = { Value *Elts[] = {
GetTagConstant(VMContext, dwarf::DW_TAG_variable), GetTagConstant(VMContext, dwarf::DW_TAG_variable),
@ -989,14 +991,12 @@ DIGlobalVariable DIBuilder::createStaticVariable(DIDescriptor Context,
/// createVariable - Create a new descriptor for the specified variable. /// createVariable - Create a new descriptor for the specified variable.
DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope, DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,
StringRef Name, DIFile File, StringRef Name, DIFile File,
unsigned LineNo, DIType Ty, unsigned LineNo, DITypeRef Ty,
bool AlwaysPreserve, unsigned Flags, bool AlwaysPreserve, unsigned Flags,
unsigned ArgNo) { unsigned ArgNo) {
DIDescriptor Context(getNonCompileUnitScope(Scope)); DIDescriptor Context(getNonCompileUnitScope(Scope));
assert((!Context || Context.isScope()) && assert((!Context || Context.isScope()) &&
"createLocalVariable should be called with a valid Context"); "createLocalVariable should be called with a valid Context");
assert(Ty.isType() &&
"createLocalVariable should be called with a valid type");
Value *Elts[] = { Value *Elts[] = {
GetTagConstant(VMContext, Tag), GetTagConstant(VMContext, Tag),
getNonCompileUnitScope(Scope), getNonCompileUnitScope(Scope),
@ -1027,7 +1027,8 @@ DIVariable DIBuilder::createLocalVariable(unsigned Tag, DIDescriptor Scope,
DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope, DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope,
StringRef Name, DIFile F, StringRef Name, DIFile F,
unsigned LineNo, unsigned LineNo,
DIType Ty, ArrayRef<Value *> Addr, DITypeRef Ty,
ArrayRef<Value *> Addr,
unsigned ArgNo) { unsigned ArgNo) {
SmallVector<Value *, 15> Elts; SmallVector<Value *, 15> Elts;
Elts.push_back(GetTagConstant(VMContext, Tag)); Elts.push_back(GetTagConstant(VMContext, Tag));

View File

@ -541,10 +541,11 @@ bool DIGlobalVariable::Verify() const {
if (getDisplayName().empty()) if (getDisplayName().empty())
return false; return false;
// Make sure context @ field 2 and type @ field 8 are MDNodes. // Make sure context @ field 2 is an MDNode.
if (!fieldIsMDNode(DbgNode, 2)) if (!fieldIsMDNode(DbgNode, 2))
return false; return false;
if (!fieldIsMDNode(DbgNode, 8)) // Make sure that type @ field 8 is a DITypeRef.
if (!fieldIsTypeRef(DbgNode, 8))
return false; return false;
// Make sure StaticDataMemberDeclaration @ field 12 is MDNode. // Make sure StaticDataMemberDeclaration @ field 12 is MDNode.
if (!fieldIsMDNode(DbgNode, 12)) if (!fieldIsMDNode(DbgNode, 12))
@ -558,10 +559,11 @@ bool DIVariable::Verify() const {
if (!isVariable()) if (!isVariable())
return false; return false;
// Make sure context @ field 1 and type @ field 5 are MDNodes. // Make sure context @ field 1 is an MDNode.
if (!fieldIsMDNode(DbgNode, 1)) if (!fieldIsMDNode(DbgNode, 1))
return false; return false;
if (!fieldIsMDNode(DbgNode, 5)) // Make sure that type @ field 5 is a DITypeRef.
if (!fieldIsTypeRef(DbgNode, 5))
return false; return false;
return DbgNode->getNumOperands() >= 8; return DbgNode->getNumOperands() >= 8;
} }
@ -999,7 +1001,7 @@ void DebugInfoFinder::processModule(const Module &M) {
DIGlobalVariable DIG(GVs.getElement(i)); DIGlobalVariable DIG(GVs.getElement(i));
if (addGlobalVariable(DIG)) { if (addGlobalVariable(DIG)) {
processScope(DIG.getContext()); processScope(DIG.getContext());
processType(DIG.getType()); processType(DIG.getType().resolve(TypeIdentifierMap));
} }
} }
DIArray SPs = CU.getSubprograms(); DIArray SPs = CU.getSubprograms();
@ -1133,7 +1135,7 @@ void DebugInfoFinder::processDeclare(const Module &M,
if (!NodesSeen.insert(DV)) if (!NodesSeen.insert(DV))
return; return;
processScope(DIVariable(N).getContext()); processScope(DIVariable(N).getContext());
processType(DIVariable(N).getType()); processType(DIVariable(N).getType().resolve(TypeIdentifierMap));
} }
void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) { void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
@ -1149,7 +1151,7 @@ void DebugInfoFinder::processValue(const Module &M, const DbgValueInst *DVI) {
if (!NodesSeen.insert(DV)) if (!NodesSeen.insert(DV))
return; return;
processScope(DIVariable(N).getContext()); processScope(DIVariable(N).getContext());
processType(DIVariable(N).getType()); processType(DIVariable(N).getType().resolve(TypeIdentifierMap));
} }
/// addType - Add type into Tys. /// addType - Add type into Tys.

View File

@ -93,6 +93,6 @@ attributes #1 = { nounwind readnone }
!21 = metadata !{i32 1, metadata !"Debug Info Version", i32 1} !21 = metadata !{i32 1, metadata !"Debug Info Version", i32 1}
!22 = metadata !{metadata !"clang version 3.5.0 "} !22 = metadata !{metadata !"clang version 3.5.0 "}
!23 = metadata !{i32 11, i32 0, metadata !15, null} !23 = metadata !{i32 11, i32 0, metadata !15, null}
!24 = metadata !{i32 786688, metadata !19, metadata !"a", metadata !16, i32 8, metadata !4, i32 0, i32 0} ; [ DW_TAG_auto_variable ] [a] [line 8] !24 = metadata !{i32 786688, metadata !19, metadata !"a", metadata !16, i32 8, metadata !"_ZTS1A", i32 0, i32 0} ; [ DW_TAG_auto_variable ] [a] [line 8]
!25 = metadata !{i32 8, i32 0, metadata !19, null} ; [ DW_TAG_imported_declaration ] !25 = metadata !{i32 8, i32 0, metadata !19, null} ; [ DW_TAG_imported_declaration ]
!26 = metadata !{i32 9, i32 0, metadata !19, null} !26 = metadata !{i32 9, i32 0, metadata !19, null}