Skip to content

Commit

Permalink
[DebugInfo] Emit address space with DW_AT_address_class attribute for…
Browse files Browse the repository at this point in the history
… pointer and reference types

Differential Revision: https://reviews.llvm.org/D29670

llvm-svn: 297320
  • Loading branch information
kzhuravl committed Mar 8, 2017
1 parent d4cb9c6 commit d5561e0
Show file tree
Hide file tree
Showing 29 changed files with 411 additions and 83 deletions.
3 changes: 2 additions & 1 deletion llvm/bindings/go/llvm/DIBuilderBindings.cpp
Expand Up @@ -119,7 +119,8 @@ LLVMMetadataRef LLVMDIBuilderCreatePointerType(LLVMDIBuilderRef Dref,
const char *Name) {
DIBuilder *D = unwrap(Dref);
return wrap(D->createPointerType(unwrap<DIType>(PointeeType), SizeInBits,
AlignInBits, Name));
AlignInBits, /* DWARFAddressSpace */ None,
Name));
}

LLVMMetadataRef
Expand Down
24 changes: 14 additions & 10 deletions llvm/docs/AMDGPUUsage.rst
Expand Up @@ -19,20 +19,24 @@ Address Spaces

The AMDGPU back-end uses the following address space mapping:

============= ============================================
Address Space Memory Space
============= ============================================
0 Private
1 Global
2 Constant
3 Local
4 Generic (Flat)
5 Region
============= ============================================
================== =================== ==============
LLVM Address Space DWARF Address Space Memory Space
================== =================== ==============
0 1 Private
1 N/A Global
2 N/A Constant
3 2 Local
4 N/A Generic (Flat)
5 N/A Region
================== =================== ==============

The terminology in the table, aside from the region memory space, is from the
OpenCL standard.

LLVM Address Space is used throughout LLVM (for example, in LLVM IR). DWARF
Address Space is emitted in DWARF, and is used by tools, such as debugger,
profiler and others.

Trap Handler ABI
----------------
The OS element of the target triple controls the trap handler behavior.
Expand Down
15 changes: 10 additions & 5 deletions llvm/include/llvm/IR/DIBuilder.h
Expand Up @@ -168,12 +168,15 @@ namespace llvm {
DIDerivedType *createQualifiedType(unsigned Tag, DIType *FromTy);

/// Create debugging information entry for a pointer.
/// \param PointeeTy Type pointed by this pointer.
/// \param SizeInBits Size.
/// \param AlignInBits Alignment. (optional)
/// \param Name Pointer type name. (optional)
/// \param PointeeTy Type pointed by this pointer.
/// \param SizeInBits Size.
/// \param AlignInBits Alignment. (optional)
/// \param DWARFAddressSpace DWARF address space. (optional)
/// \param Name Pointer type name. (optional)
DIDerivedType *createPointerType(DIType *PointeeTy, uint64_t SizeInBits,
uint32_t AlignInBits = 0,
Optional<unsigned> DWARFAddressSpace =
None,
StringRef Name = "");

/// Create debugging information entry for a pointer to member.
Expand All @@ -190,7 +193,9 @@ namespace llvm {
/// style reference or rvalue reference type.
DIDerivedType *createReferenceType(unsigned Tag, DIType *RTy,
uint64_t SizeInBits = 0,
uint32_t AlignInBits = 0);
uint32_t AlignInBits = 0,
Optional<unsigned> DWARFAddressSpace =
None);

/// Create debugging information entry for a typedef.
/// \param Ty Original type.
Expand Down
48 changes: 32 additions & 16 deletions llvm/include/llvm/IR/DebugInfoMetadata.h
Expand Up @@ -710,62 +710,78 @@ class DIDerivedType : public DIType {
friend class LLVMContextImpl;
friend class MDNode;

/// \brief The DWARF address space of the memory pointed to or referenced by a
/// pointer or reference type respectively.
Optional<unsigned> DWARFAddressSpace;

DIDerivedType(LLVMContext &C, StorageType Storage, unsigned Tag,
unsigned Line, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags, ArrayRef<Metadata *> Ops)
uint64_t OffsetInBits, Optional<unsigned> DWARFAddressSpace,
DIFlags Flags, ArrayRef<Metadata *> Ops)
: DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
AlignInBits, OffsetInBits, Flags, Ops) {}
AlignInBits, OffsetInBits, Flags, Ops),
DWARFAddressSpace(DWARFAddressSpace) {}
~DIDerivedType() = default;

static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, DIFile *File, unsigned Line,
DIScopeRef Scope, DITypeRef BaseType,
uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags,
Metadata *ExtraData, StorageType Storage,
bool ShouldCreate = true) {
uint64_t OffsetInBits,
Optional<unsigned> DWARFAddressSpace,
DIFlags Flags, Metadata *ExtraData,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
Flags, ExtraData, Storage, ShouldCreate);
DWARFAddressSpace, Flags, ExtraData, Storage, ShouldCreate);
}
static DIDerivedType *getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, Metadata *File, unsigned Line,
Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags,
Metadata *ExtraData, StorageType Storage,
bool ShouldCreate = true);
uint64_t OffsetInBits,
Optional<unsigned> DWARFAddressSpace,
DIFlags Flags, Metadata *ExtraData,
StorageType Storage, bool ShouldCreate = true);

TempDIDerivedType cloneImpl() const {
return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
getScope(), getBaseType(), getSizeInBits(),
getAlignInBits(), getOffsetInBits(), getFlags(),
getExtraData());
getAlignInBits(), getOffsetInBits(),
getDWARFAddressSpace(), getFlags(), getExtraData());
}

public:
DEFINE_MDNODE_GET(DIDerivedType,
(unsigned Tag, MDString *Name, Metadata *File,
unsigned Line, Metadata *Scope, Metadata *BaseType,
uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags,
uint64_t OffsetInBits,
Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Metadata *ExtraData = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, ExtraData))
AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
ExtraData))
DEFINE_MDNODE_GET(DIDerivedType,
(unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
DIScopeRef Scope, DITypeRef BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags, Metadata *ExtraData = nullptr),
Optional<unsigned> DWARFAddressSpace, DIFlags Flags,
Metadata *ExtraData = nullptr),
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, ExtraData))
AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
ExtraData))

TempDIDerivedType clone() const { return cloneImpl(); }

//// Get the base type this is derived from.
/// Get the base type this is derived from.
DITypeRef getBaseType() const { return DITypeRef(getRawBaseType()); }
Metadata *getRawBaseType() const { return getOperand(3); }

/// \returns The DWARF address space of the memory pointed to or referenced by
/// a pointer or reference type respectively.
Optional<unsigned> getDWARFAddressSpace() const { return DWARFAddressSpace; }

/// Get extra data associated with this derived type.
///
/// Class type for pointer-to-members, objective-c property node for ivars,
Expand Down
13 changes: 10 additions & 3 deletions llvm/lib/AsmParser/LLParser.cpp
Expand Up @@ -3908,7 +3908,8 @@ bool LLParser::ParseDIBasicType(MDNode *&Result, bool IsDistinct) {
/// ParseDIDerivedType:
/// ::= !DIDerivedType(tag: DW_TAG_pointer_type, name: "int", file: !0,
/// line: 7, scope: !1, baseType: !2, size: 32,
/// align: 32, offset: 0, flags: 0, extraData: !3)
/// align: 32, offset: 0, flags: 0, extraData: !3,
/// dwarfAddressSpace: 3)
bool LLParser::ParseDIDerivedType(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(tag, DwarfTagField, ); \
Expand All @@ -3921,14 +3922,20 @@ bool LLParser::ParseDIDerivedType(MDNode *&Result, bool IsDistinct) {
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(offset, MDUnsignedField, (0, UINT64_MAX)); \
OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(extraData, MDField, );
OPTIONAL(extraData, MDField, ); \
OPTIONAL(dwarfAddressSpace, MDUnsignedField, (UINT32_MAX, UINT32_MAX));
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS

Optional<unsigned> DWARFAddressSpace;
if (dwarfAddressSpace.Val != UINT32_MAX)
DWARFAddressSpace = dwarfAddressSpace.Val;

Result = GET_OR_DISTINCT(DIDerivedType,
(Context, tag.Val, name.Val, file.Val, line.Val,
scope.Val, baseType.Val, size.Val, align.Val,
offset.Val, flags.Val, extraData.Val));
offset.Val, DWARFAddressSpace, flags.Val,
extraData.Val));
return false;
}

Expand Down
11 changes: 9 additions & 2 deletions llvm/lib/Bitcode/Reader/MetadataLoader.cpp
Expand Up @@ -1110,9 +1110,15 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_DERIVED_TYPE: {
if (Record.size() != 12)
if (Record.size() < 12 || Record.size() > 13)
return error("Invalid record");

// DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means
// that there is no DWARF address space associated with DIDerivedType.
Optional<unsigned> DWARFAddressSpace;
if (Record.size() > 12 && Record[12])
DWARFAddressSpace = Record[12] - 1;

IsDistinct = Record[0];
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
MetadataList.assignValue(
Expand All @@ -1121,7 +1127,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
getMDOrNull(Record[3]), Record[4],
getDITypeRefOrNull(Record[5]),
getDITypeRefOrNull(Record[6]), Record[7], Record[8],
Record[9], Flags, getDITypeRefOrNull(Record[11]))),
Record[9], DWARFAddressSpace, Flags,
getDITypeRefOrNull(Record[11]))),
NextMetadataNo);
NextMetadataNo++;
break;
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
Expand Up @@ -1473,6 +1473,13 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
Record.push_back(N->getFlags());
Record.push_back(VE.getMetadataOrNullID(N->getExtraData()));

// DWARF address space is encoded as N->getDWARFAddressSpace() + 1. 0 means
// that there is no DWARF address space associated with DIDerivedType.
if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace())
Record.push_back(*DWARFAddressSpace + 1);
else
Record.push_back(0);

Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev);
Record.clear();
}
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
Expand Up @@ -853,6 +853,13 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) {
// Add source line info if available and TyDesc is not a forward declaration.
if (!DTy->isForwardDecl())
addSourceLine(Buffer, DTy);

// If DWARF address space value is other than None, add it for pointer and
// reference types as DW_AT_address_class.
if (DTy->getDWARFAddressSpace() && (Tag == dwarf::DW_TAG_pointer_type ||
Tag == dwarf::DW_TAG_reference_type))
addUInt(Buffer, dwarf::DW_AT_address_class, dwarf::DW_FORM_data4,
DTy->getDWARFAddressSpace().getValue());
}

void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeRefArray Args) {
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/IR/AsmWriter.cpp
Expand Up @@ -1614,6 +1614,9 @@ static void writeDIDerivedType(raw_ostream &Out, const DIDerivedType *N,
Printer.printInt("offset", N->getOffsetInBits());
Printer.printDIFlags("flags", N->getFlags());
Printer.printMetadata("extraData", N->getRawExtraData());
if (const auto &DWARFAddressSpace = N->getDWARFAddressSpace())
Printer.printInt("dwarfAddressSpace", *DWARFAddressSpace,
/* ShouldSkipZero */ false);
Out << ")";
}

Expand Down
43 changes: 25 additions & 18 deletions llvm/lib/IR/DIBuilder.cpp
Expand Up @@ -241,17 +241,20 @@ DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,

DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) {
return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0,
0, 0, DINode::FlagZero);
0, 0, None, DINode::FlagZero);
}

DIDerivedType *DIBuilder::createPointerType(DIType *PointeeTy,
uint64_t SizeInBits,
uint32_t AlignInBits,
StringRef Name) {
DIDerivedType *DIBuilder::createPointerType(
DIType *PointeeTy,
uint64_t SizeInBits,
uint32_t AlignInBits,
Optional<unsigned> DWARFAddressSpace,
StringRef Name) {
// FIXME: Why is there a name here?
return DIDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name,
nullptr, 0, nullptr, PointeeTy, SizeInBits,
AlignInBits, 0, DINode::FlagZero);
AlignInBits, 0, DWARFAddressSpace,
DINode::FlagZero);
}

DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy,
Expand All @@ -261,38 +264,41 @@ DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy,
DINode::DIFlags Flags) {
return DIDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "",
nullptr, 0, nullptr, PointeeTy, SizeInBits,
AlignInBits, 0, Flags, Base);
AlignInBits, 0, None, Flags, Base);
}

DIDerivedType *DIBuilder::createReferenceType(unsigned Tag, DIType *RTy,
uint64_t SizeInBits,
uint32_t AlignInBits) {
DIDerivedType *DIBuilder::createReferenceType(
unsigned Tag, DIType *RTy,
uint64_t SizeInBits,
uint32_t AlignInBits,
Optional<unsigned> DWARFAddressSpace) {
assert(RTy && "Unable to create reference type");
return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, RTy,
SizeInBits, AlignInBits, 0, DINode::FlagZero);
SizeInBits, AlignInBits, 0, DWARFAddressSpace,
DINode::FlagZero);
}

DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name,
DIFile *File, unsigned LineNo,
DIScope *Context) {
return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File,
LineNo, getNonCompileUnitScope(Context), Ty, 0, 0,
0, DINode::FlagZero);
0, None, DINode::FlagZero);
}

DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) {
assert(Ty && "Invalid type!");
assert(FriendTy && "Invalid friend type!");
return DIDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, Ty,
FriendTy, 0, 0, 0, DINode::FlagZero);
FriendTy, 0, 0, 0, None, DINode::FlagZero);
}

DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy,
uint64_t BaseOffset,
DINode::DIFlags Flags) {
assert(Ty && "Unable to create inheritance");
return DIDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr,
0, Ty, BaseTy, 0, 0, BaseOffset, Flags);
0, Ty, BaseTy, 0, 0, BaseOffset, None, Flags);
}

DIDerivedType *DIBuilder::createMemberType(DIScope *Scope, StringRef Name,
Expand All @@ -303,7 +309,7 @@ DIDerivedType *DIBuilder::createMemberType(DIScope *Scope, StringRef Name,
DINode::DIFlags Flags, DIType *Ty) {
return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,
LineNumber, getNonCompileUnitScope(Scope), Ty,
SizeInBits, AlignInBits, OffsetInBits, Flags);
SizeInBits, AlignInBits, OffsetInBits, None, Flags);
}

static ConstantAsMetadata *getConstantOrNull(Constant *C) {
Expand All @@ -320,7 +326,7 @@ DIDerivedType *DIBuilder::createBitFieldMemberType(
return DIDerivedType::get(
VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,
getNonCompileUnitScope(Scope), Ty, SizeInBits, /* AlignInBits */ 0,
OffsetInBits, Flags,
OffsetInBits, None, Flags,
ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64),
StorageOffsetInBits)));
}
Expand All @@ -333,7 +339,8 @@ DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File,
Flags |= DINode::FlagStaticMember;
return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,
LineNumber, getNonCompileUnitScope(Scope), Ty, 0,
AlignInBits, 0, Flags, getConstantOrNull(Val));
AlignInBits, 0, None, Flags,
getConstantOrNull(Val));
}

DIDerivedType *
Expand All @@ -343,7 +350,7 @@ DIBuilder::createObjCIVar(StringRef Name, DIFile *File, unsigned LineNumber,
DIType *Ty, MDNode *PropertyNode) {
return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,
LineNumber, getNonCompileUnitScope(File), Ty,
SizeInBits, AlignInBits, OffsetInBits, Flags,
SizeInBits, AlignInBits, OffsetInBits, None, Flags,
PropertyNode);
}

Expand Down

0 comments on commit d5561e0

Please sign in to comment.