[DebugInfo] Emit address space with DW_AT_address_class attribute for pointer and reference types

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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297320 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Konstantin Zhuravlyov 2017-03-08 23:55:44 +00:00
parent 94a8180da7
commit 2cee5cc825
29 changed files with 411 additions and 83 deletions

View File

@ -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

View File

@ -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.

View File

@ -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.
@ -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.

View File

@ -710,37 +710,45 @@ 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:
@ -748,24 +756,32 @@ public:
(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,

View File

@ -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, ); \
@ -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;
}

View File

@ -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(
@ -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;

View File

@ -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();
}

View File

@ -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) {

View File

@ -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 << ")";
}

View File

@ -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,
@ -261,15 +264,18 @@ 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,
@ -277,14 +283,14 @@ DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name,
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,
@ -292,7 +298,7 @@ DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy,
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,
@ -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) {
@ -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)));
}
@ -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 *
@ -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);
}

View File

@ -245,16 +245,18 @@ DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
DIDerivedType *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) {
uint32_t AlignInBits, uint64_t OffsetInBits,
Optional<unsigned> DWARFAddressSpace, DIFlags Flags, Metadata *ExtraData,
StorageType Storage, bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIDerivedType,
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, ExtraData));
AlignInBits, OffsetInBits, DWARFAddressSpace, Flags,
ExtraData));
Metadata *Ops[] = {File, Scope, Name, BaseType, ExtraData};
DEFINE_GETIMPL_STORE(
DIDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits, Flags),
Ops);
DIDerivedType, (Tag, Line, SizeInBits, AlignInBits, OffsetInBits,
DWARFAddressSpace, Flags), Ops);
}
DICompositeType *DICompositeType::getImpl(

View File

@ -352,22 +352,26 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
uint64_t SizeInBits;
uint64_t OffsetInBits;
uint32_t AlignInBits;
Optional<unsigned> DWARFAddressSpace;
unsigned Flags;
Metadata *ExtraData;
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
uint32_t AlignInBits, uint64_t OffsetInBits, unsigned Flags,
uint32_t AlignInBits, uint64_t OffsetInBits,
Optional<unsigned> DWARFAddressSpace, unsigned Flags,
Metadata *ExtraData)
: Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
AlignInBits(AlignInBits), Flags(Flags), ExtraData(ExtraData) {}
AlignInBits(AlignInBits), DWARFAddressSpace(DWARFAddressSpace),
Flags(Flags), ExtraData(ExtraData) {}
MDNodeKeyImpl(const DIDerivedType *N)
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
Line(N->getLine()), Scope(N->getRawScope()),
BaseType(N->getRawBaseType()), SizeInBits(N->getSizeInBits()),
OffsetInBits(N->getOffsetInBits()), AlignInBits(N->getAlignInBits()),
Flags(N->getFlags()), ExtraData(N->getRawExtraData()) {}
DWARFAddressSpace(N->getDWARFAddressSpace()), Flags(N->getFlags()),
ExtraData(N->getRawExtraData()) {}
bool isKeyOf(const DIDerivedType *RHS) const {
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
@ -375,7 +379,9 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
Scope == RHS->getRawScope() && BaseType == RHS->getRawBaseType() &&
SizeInBits == RHS->getSizeInBits() &&
AlignInBits == RHS->getAlignInBits() &&
OffsetInBits == RHS->getOffsetInBits() && Flags == RHS->getFlags() &&
OffsetInBits == RHS->getOffsetInBits() &&
DWARFAddressSpace == RHS->getDWARFAddressSpace() &&
Flags == RHS->getFlags() &&
ExtraData == RHS->getRawExtraData();
}
unsigned getHashValue() const {

View File

@ -910,6 +910,13 @@ void Verifier::visitDIDerivedType(const DIDerivedType &N) {
AssertDI(isScope(N.getRawScope()), "invalid scope", &N, N.getRawScope());
AssertDI(isType(N.getRawBaseType()), "invalid base type", &N,
N.getRawBaseType());
if (N.getDWARFAddressSpace()) {
AssertDI(N.getTag() == dwarf::DW_TAG_pointer_type ||
N.getTag() == dwarf::DW_TAG_reference_type,
"DWARF address space only applies to pointer or reference types",
&N);
}
}
static bool hasConflictingReferenceFlags(unsigned Flags) {

View File

@ -37,8 +37,8 @@
!13 = distinct !{}
!14 = !DIFile(filename: "", directory: "")
; CHECK-NEXT: !13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 32, align: 32)
!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32)
; CHECK-NEXT: !13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 32, align: 32, dwarfAddressSpace: 1)
!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32, dwarfAddressSpace: 1)
; CHECK-NEXT: !14 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyType", file: !10, line: 2, size: 32, align: 32, identifier: "MangledMyType")
; CHECK-NEXT: !15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Base", scope: !14, file: !10, line: 3, size: 128, align: 32, offset: 64, flags: DIFlagPublic, elements: !16, runtimeLang: DW_LANG_C_plus_plus_11, vtableHolder: !15, templateParams: !18, identifier: "MangledBase")
@ -84,4 +84,4 @@
; CHECK-NEXT: !33 = !DIFile(filename: "file", directory: "dir")
!35 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "000102030405060708090a0b0c0d0e0f")
!36 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_None)
!37 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_None, checksum: "")
!37 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_None, checksum: "")

View File

@ -0,0 +1,5 @@
; RUN: llvm-dis -o - %s.bc | FileCheck %s
; CHECK-DAG: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}})
; CHECK-DAG: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}})
; CHECK-DAG: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}})

Binary file not shown.

View File

@ -0,0 +1,70 @@
; RUN: llc -O0 -mtriple=amdgcn--amdhsa -mcpu=fiji -verify-machineinstrs -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
; LLVM IR generated with the following command and OpenCL source:
;
; $clang -cl-std=CL2.0 -g -O0 -target amdgcn-amd-amdhsa -S -emit-llvm <path-to-file>
;
; kernel void kernel1() {
; global int *FuncVar0 = 0;
; constant int *FuncVar1 = 0;
; local int *FuncVar2 = 0;
; private int *FuncVar3 = 0;
; int *FuncVar4 = 0;
; }
; DW_AT_address_class is available since Dwarf Version 2.
; CHECK-NOT: DW_AT_address_class
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
define amdgpu_kernel void @kernel1() #0 !dbg !7 {
entry:
%FuncVar0 = alloca i32 addrspace(1)*, align 4
%FuncVar1 = alloca i32 addrspace(2)*, align 4
%FuncVar2 = alloca i32 addrspace(3)*, align 4
%FuncVar3 = alloca i32*, align 4
%FuncVar4 = alloca i32 addrspace(4)*, align 4
call void @llvm.dbg.declare(metadata i32 addrspace(1)** %FuncVar0, metadata !10, metadata !13), !dbg !14
store i32 addrspace(1)* null, i32 addrspace(1)** %FuncVar0, align 4, !dbg !14
call void @llvm.dbg.declare(metadata i32 addrspace(2)** %FuncVar1, metadata !15, metadata !13), !dbg !16
store i32 addrspace(2)* null, i32 addrspace(2)** %FuncVar1, align 4, !dbg !16
call void @llvm.dbg.declare(metadata i32 addrspace(3)** %FuncVar2, metadata !17, metadata !13), !dbg !19
store i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*), i32 addrspace(3)** %FuncVar2, align 4, !dbg !19
call void @llvm.dbg.declare(metadata i32** %FuncVar3, metadata !20, metadata !13), !dbg !22
store i32* addrspacecast (i32 addrspace(4)* null to i32*), i32** %FuncVar3, align 4, !dbg !22
call void @llvm.dbg.declare(metadata i32 addrspace(4)** %FuncVar4, metadata !23, metadata !13), !dbg !24
store i32 addrspace(4)* null, i32 addrspace(4)** %FuncVar4, align 4, !dbg !24
ret void, !dbg !25
}
!llvm.dbg.cu = !{!0}
!opencl.ocl.version = !{!3}
!llvm.module.flags = !{!4, !5}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "pointer-address-space-dwarf-v1.cl", directory: "/some/random/directory")
!2 = !{}
!3 = !{i32 2, i32 0}
!4 = !{i32 2, !"Dwarf Version", i32 1}
!5 = !{i32 2, !"Debug Info Version", i32 3}
!6 = !{!""}
!7 = distinct !DISubprogram(name: "kernel1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, variables: !2)
!8 = !DISubroutineType(types: !9)
!9 = !{null}
!10 = !DILocalVariable(name: "FuncVar0", scope: !7, file: !1, line: 2, type: !11)
!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!13 = !DIExpression()
!14 = !DILocation(line: 2, column: 15, scope: !7)
!15 = !DILocalVariable(name: "FuncVar1", scope: !7, file: !1, line: 3, type: !11)
!16 = !DILocation(line: 3, column: 17, scope: !7)
!17 = !DILocalVariable(name: "FuncVar2", scope: !7, file: !1, line: 4, type: !18)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 32, dwarfAddressSpace: 2)
!19 = !DILocation(line: 4, column: 14, scope: !7)
!20 = !DILocalVariable(name: "FuncVar3", scope: !7, file: !1, line: 5, type: !21)
!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 32, dwarfAddressSpace: 1)
!22 = !DILocation(line: 5, column: 16, scope: !7)
!23 = !DILocalVariable(name: "FuncVar4", scope: !7, file: !1, line: 6, type: !11)
!24 = !DILocation(line: 6, column: 8, scope: !7)
!25 = !DILocation(line: 7, column: 1, scope: !7)

View File

@ -0,0 +1,104 @@
; RUN: llc -O0 -mtriple=amdgcn--amdhsa -mcpu=fiji -verify-machineinstrs -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
; LLVM IR generated with the following command and OpenCL source:
;
; $clang -cl-std=CL2.0 -g -O0 -target amdgcn-amd-amdhsa -S -emit-llvm <path-to-file>
;
; kernel void kernel1() {
; global int *FuncVar0 = 0;
; constant int *FuncVar1 = 0;
; local int *FuncVar2 = 0;
; private int *FuncVar3 = 0;
; int *FuncVar4 = 0;
; }
; CHECK: DW_AT_name {{.*}}"FuncVar0"
; CHECK-NEXT: DW_AT_decl_file
; CHECK-NEXT: DW_AT_decl_line
; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x{{[a-f0-9]+}} => {0x[[NONE:[a-f0-9]+]]})
; CHECK: DW_AT_name {{.*}}"FuncVar1"
; CHECK-NEXT: DW_AT_decl_file
; CHECK-NEXT: DW_AT_decl_line
; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x{{[a-f0-9]+}} => {0x[[NONE]]})
; CHECK: DW_AT_name {{.*}}"FuncVar2"
; CHECK-NEXT: DW_AT_decl_file
; CHECK-NEXT: DW_AT_decl_line
; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x{{[a-f0-9]+}} => {0x[[LOCAL:[a-f0-9]+]]})
; CHECK: DW_AT_name {{.*}}"FuncVar3"
; CHECK-NEXT: DW_AT_decl_file
; CHECK-NEXT: DW_AT_decl_line
; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x{{[a-f0-9]+}} => {0x[[PRIVATE:[a-f0-9]+]]})
; CHECK: DW_AT_name {{.*}}"FuncVar4"
; CHECK-NEXT: DW_AT_decl_file
; CHECK-NEXT: DW_AT_decl_line
; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x{{[a-f0-9]+}} => {0x[[NONE]]})
; CHECK: 0x[[NONE]]: DW_TAG_pointer_type
; CHECK-NEXT: DW_AT_type
; CHECK-NOT: DW_AT_address_class
; CHECK: 0x[[LOCAL]]: DW_TAG_pointer_type
; CHECK-NEXT: DW_AT_type
; CHECK-NEXT: DW_AT_address_class [DW_FORM_data4] (0x00000002)
; CHECK: 0x[[PRIVATE]]: DW_TAG_pointer_type
; CHECK-NEXT: DW_AT_type
; CHECK-NEXT: DW_AT_address_class [DW_FORM_data4] (0x00000001)
declare void @llvm.dbg.declare(metadata, metadata, metadata)
define amdgpu_kernel void @kernel1() !dbg !7 {
entry:
%FuncVar0 = alloca i32 addrspace(1)*, align 4
%FuncVar1 = alloca i32 addrspace(2)*, align 4
%FuncVar2 = alloca i32 addrspace(3)*, align 4
%FuncVar3 = alloca i32*, align 4
%FuncVar4 = alloca i32 addrspace(4)*, align 4
call void @llvm.dbg.declare(metadata i32 addrspace(1)** %FuncVar0, metadata !10, metadata !13), !dbg !14
store i32 addrspace(1)* null, i32 addrspace(1)** %FuncVar0, align 4, !dbg !14
call void @llvm.dbg.declare(metadata i32 addrspace(2)** %FuncVar1, metadata !15, metadata !13), !dbg !16
store i32 addrspace(2)* null, i32 addrspace(2)** %FuncVar1, align 4, !dbg !16
call void @llvm.dbg.declare(metadata i32 addrspace(3)** %FuncVar2, metadata !17, metadata !13), !dbg !19
store i32 addrspace(3)* addrspacecast (i32 addrspace(4)* null to i32 addrspace(3)*), i32 addrspace(3)** %FuncVar2, align 4, !dbg !19
call void @llvm.dbg.declare(metadata i32** %FuncVar3, metadata !20, metadata !13), !dbg !22
store i32* addrspacecast (i32 addrspace(4)* null to i32*), i32** %FuncVar3, align 4, !dbg !22
call void @llvm.dbg.declare(metadata i32 addrspace(4)** %FuncVar4, metadata !23, metadata !13), !dbg !24
store i32 addrspace(4)* null, i32 addrspace(4)** %FuncVar4, align 4, !dbg !24
ret void, !dbg !25
}
!llvm.dbg.cu = !{!0}
!opencl.ocl.version = !{!3}
!llvm.module.flags = !{!4, !5}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "pointer-address-space.ll", directory: "/some/random/directory")
!2 = !{}
!3 = !{i32 2, i32 0}
!4 = !{i32 2, !"Dwarf Version", i32 2}
!5 = !{i32 2, !"Debug Info Version", i32 3}
!6 = !{!""}
!7 = distinct !DISubprogram(name: "kernel1", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, variables: !2)
!8 = !DISubroutineType(types: !9)
!9 = !{null}
!10 = !DILocalVariable(name: "FuncVar0", scope: !7, file: !1, line: 2, type: !11)
!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64)
!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!13 = !DIExpression()
!14 = !DILocation(line: 2, column: 15, scope: !7)
!15 = !DILocalVariable(name: "FuncVar1", scope: !7, file: !1, line: 3, type: !11)
!16 = !DILocation(line: 3, column: 17, scope: !7)
!17 = !DILocalVariable(name: "FuncVar2", scope: !7, file: !1, line: 4, type: !18)
!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 32, dwarfAddressSpace: 2)
!19 = !DILocation(line: 4, column: 14, scope: !7)
!20 = !DILocalVariable(name: "FuncVar3", scope: !7, file: !1, line: 5, type: !21)
!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 32, dwarfAddressSpace: 1)
!22 = !DILocation(line: 5, column: 16, scope: !7)
!23 = !DILocalVariable(name: "FuncVar4", scope: !7, file: !1, line: 6, type: !11)
!24 = !DILocation(line: 6, column: 8, scope: !7)
!25 = !DILocation(line: 7, column: 1, scope: !7)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_friend, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_inheritance, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_member, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_typedef, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -0,0 +1,6 @@
; RUN: not opt -S < %s 2>&1 | FileCheck %s
!named = !{!0, !1}
!0 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char)
; CHECK: DWARF address space only applies to pointer or reference types
!1 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: !0, size: 32, align: 32, dwarfAddressSpace: 1)

View File

@ -103,7 +103,7 @@ protected:
DIType *getDerivedType() {
return DIDerivedType::getDistinct(
Context, dwarf::DW_TAG_pointer_type, "", nullptr, 0, nullptr,
getBasicType("basictype"), 1, 2, 0, DINode::FlagZero);
getBasicType("basictype"), 1, 2, 0, None, DINode::FlagZero);
}
Constant *getConstant() {
return ConstantInt::get(Type::getInt32Ty(Context), Counter++);
@ -1053,12 +1053,14 @@ TEST_F(DIDerivedTypeTest, get) {
DIScope *Scope = getSubprogram();
DIType *BaseType = getBasicType("basic");
MDTuple *ExtraData = getTuple();
unsigned DWARFAddressSpace = 8;
DINode::DIFlags Flags5 = static_cast<DINode::DIFlags>(5);
DINode::DIFlags Flags4 = static_cast<DINode::DIFlags>(4);
auto *N =
DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "something", File,
1, Scope, BaseType, 2, 3, 4, Flags5, ExtraData);
1, Scope, BaseType, 2, 3, 4, DWARFAddressSpace, Flags5,
ExtraData);
EXPECT_EQ(dwarf::DW_TAG_pointer_type, N->getTag());
EXPECT_EQ("something", N->getName());
EXPECT_EQ(File, N->getFile());
@ -1068,45 +1070,51 @@ TEST_F(DIDerivedTypeTest, get) {
EXPECT_EQ(2u, N->getSizeInBits());
EXPECT_EQ(3u, N->getAlignInBits());
EXPECT_EQ(4u, N->getOffsetInBits());
EXPECT_EQ(DWARFAddressSpace, N->getDWARFAddressSpace().getValue());
EXPECT_EQ(5u, N->getFlags());
EXPECT_EQ(ExtraData, N->getExtraData());
EXPECT_EQ(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, Scope, BaseType, 2, 3,
4, Flags5, ExtraData));
4, DWARFAddressSpace, Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_reference_type,
"something", File, 1, Scope, BaseType, 2, 3,
4, Flags5, ExtraData));
4, DWARFAddressSpace, Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type, "else",
File, 1, Scope, BaseType, 2, 3, 4, Flags5,
ExtraData));
File, 1, Scope, BaseType, 2, 3,
4, DWARFAddressSpace, Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", getFile(), 1, Scope, BaseType, 2,
3, 4, Flags5, ExtraData));
3, 4, DWARFAddressSpace, Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 2, Scope, BaseType, 2, 3,
4, Flags5, ExtraData));
4, DWARFAddressSpace, Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, getSubprogram(),
BaseType, 2, 3, 4, Flags5, ExtraData));
BaseType, 2, 3, 4, DWARFAddressSpace, Flags5,
ExtraData));
EXPECT_NE(N, DIDerivedType::get(
Context, dwarf::DW_TAG_pointer_type, "something", File, 1,
Scope, getBasicType("basic2"), 2, 3, 4, Flags5, ExtraData));
Scope, getBasicType("basic2"), 2, 3, 4, DWARFAddressSpace,
Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, Scope, BaseType, 3, 3,
4, Flags5, ExtraData));
4, DWARFAddressSpace, Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, Scope, BaseType, 2, 2,
4, Flags5, ExtraData));
4, DWARFAddressSpace, Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, Scope, BaseType, 2, 3,
5, Flags5, ExtraData));
5, DWARFAddressSpace, Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, Scope, BaseType, 2, 3,
4, Flags4, ExtraData));
4, DWARFAddressSpace + 1, Flags5, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, Scope, BaseType, 2, 3,
4, Flags5, getTuple()));
4, DWARFAddressSpace, Flags4, ExtraData));
EXPECT_NE(N, DIDerivedType::get(Context, dwarf::DW_TAG_pointer_type,
"something", File, 1, Scope, BaseType, 2, 3,
4, DWARFAddressSpace, Flags5, getTuple()));
TempDIDerivedType Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
@ -1121,10 +1129,12 @@ TEST_F(DIDerivedTypeTest, getWithLargeValues) {
auto *N = DIDerivedType::get(
Context, dwarf::DW_TAG_pointer_type, "something", File, 1, Scope,
BaseType, UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, Flags, ExtraData);
BaseType, UINT64_MAX, UINT32_MAX - 1, UINT64_MAX - 2, UINT32_MAX - 3,
Flags, ExtraData);
EXPECT_EQ(UINT64_MAX, N->getSizeInBits());
EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits());
EXPECT_EQ(UINT64_MAX - 2, N->getOffsetInBits());
EXPECT_EQ(UINT32_MAX - 3, N->getDWARFAddressSpace().getValue());
}
typedef MetadataTest DICompositeTypeTest;