mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 07:31:53 +00:00
[DWARF] Versioning for DWARF constants; verify FORMs
Associate the version-when-defined with definitions of standard DWARF constants. Identify the "vendor" for DWARF extensions. Use this information to verify FORMs in .debug_abbrev are defined as of the DWARF version specified in the associated unit. Removed two tests that had specified DWARF v1 (which essentially does not exist). Differential Revision: http://reviews.llvm.org/D30785 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300875 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1ec650ee5f
commit
ce35560497
@ -236,7 +236,7 @@ template <> struct MappingTraits<DWARFYAML::InitialLength> {
|
||||
static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
|
||||
};
|
||||
|
||||
#define HANDLE_DW_TAG(unused, name) \
|
||||
#define HANDLE_DW_TAG(unused, name, unused2, unused3) \
|
||||
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
|
||||
|
||||
template <> struct ScalarEnumerationTraits<dwarf::Tag> {
|
||||
@ -266,7 +266,7 @@ template <> struct ScalarEnumerationTraits<dwarf::LineNumberExtendedOps> {
|
||||
}
|
||||
};
|
||||
|
||||
#define HANDLE_DW_AT(unused, name) \
|
||||
#define HANDLE_DW_AT(unused, name, unused2, unused3) \
|
||||
io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name);
|
||||
|
||||
template <> struct ScalarEnumerationTraits<dwarf::Attribute> {
|
||||
@ -276,7 +276,7 @@ template <> struct ScalarEnumerationTraits<dwarf::Attribute> {
|
||||
}
|
||||
};
|
||||
|
||||
#define HANDLE_DW_FORM(unused, name) \
|
||||
#define HANDLE_DW_FORM(unused, name, unused2, unused3) \
|
||||
io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name);
|
||||
|
||||
template <> struct ScalarEnumerationTraits<dwarf::Form> {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -46,7 +46,15 @@ enum LLVMConstants : uint32_t {
|
||||
DWARF_VERSION = 4, // Default dwarf version we output.
|
||||
DW_PUBTYPES_VERSION = 2, // Section version number for .debug_pubtypes.
|
||||
DW_PUBNAMES_VERSION = 2, // Section version number for .debug_pubnames.
|
||||
DW_ARANGES_VERSION = 2 // Section version number for .debug_aranges.
|
||||
DW_ARANGES_VERSION = 2, // Section version number for .debug_aranges.
|
||||
// Identifiers we use to distinguish vendor extensions.
|
||||
DWARF_VENDOR_DWARF = 0, // Defined in v2 or later of the DWARF standard.
|
||||
DWARF_VENDOR_APPLE = 1,
|
||||
DWARF_VENDOR_BORLAND = 2,
|
||||
DWARF_VENDOR_GNU = 3,
|
||||
DWARF_VENDOR_GOOGLE = 4,
|
||||
DWARF_VENDOR_LLVM = 5,
|
||||
DWARF_VENDOR_MIPS = 6
|
||||
};
|
||||
|
||||
// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
|
||||
@ -55,7 +63,7 @@ const uint32_t DW_CIE_ID = UINT32_MAX;
|
||||
const uint64_t DW64_CIE_ID = UINT64_MAX;
|
||||
|
||||
enum Tag : uint16_t {
|
||||
#define HANDLE_DW_TAG(ID, NAME) DW_TAG_##NAME = ID,
|
||||
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) DW_TAG_##NAME = ID,
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
DW_TAG_lo_user = 0x4080,
|
||||
DW_TAG_hi_user = 0xffff,
|
||||
@ -92,20 +100,20 @@ inline bool isType(Tag T) {
|
||||
|
||||
/// Attributes.
|
||||
enum Attribute : uint16_t {
|
||||
#define HANDLE_DW_AT(ID, NAME) DW_AT_##NAME = ID,
|
||||
#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) DW_AT_##NAME = ID,
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
DW_AT_lo_user = 0x2000,
|
||||
DW_AT_hi_user = 0x3fff,
|
||||
};
|
||||
|
||||
enum Form : uint16_t {
|
||||
#define HANDLE_DW_FORM(ID, NAME) DW_FORM_##NAME = ID,
|
||||
#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) DW_FORM_##NAME = ID,
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
DW_FORM_lo_user = 0x1f00, ///< Not specified by DWARF.
|
||||
};
|
||||
|
||||
enum LocationAtom {
|
||||
#define HANDLE_DW_OP(ID, NAME) DW_OP_##NAME = ID,
|
||||
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) DW_OP_##NAME = ID,
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
DW_OP_lo_user = 0xe0,
|
||||
DW_OP_hi_user = 0xff,
|
||||
@ -113,7 +121,7 @@ enum LocationAtom {
|
||||
};
|
||||
|
||||
enum TypeKind {
|
||||
#define HANDLE_DW_ATE(ID, NAME) DW_ATE_##NAME = ID,
|
||||
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) DW_ATE_##NAME = ID,
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
DW_ATE_lo_user = 0x80,
|
||||
DW_ATE_hi_user = 0xff
|
||||
@ -164,7 +172,7 @@ enum DefaultedMemberAttribute {
|
||||
};
|
||||
|
||||
enum SourceLanguage {
|
||||
#define HANDLE_DW_LANG(ID, NAME) DW_LANG_##NAME = ID,
|
||||
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) DW_LANG_##NAME = ID,
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
DW_LANG_lo_user = 0x8000,
|
||||
DW_LANG_hi_user = 0xffff
|
||||
@ -406,6 +414,40 @@ unsigned getAttributeEncoding(StringRef EncodingString);
|
||||
unsigned getMacinfo(StringRef MacinfoString);
|
||||
/// @}
|
||||
|
||||
/// \defgroup DwarfConstantsVersioning Dwarf version for constants
|
||||
///
|
||||
/// For constants defined by DWARF, returns the DWARF version when the constant
|
||||
/// was first defined. For vendor extensions, if there is a version-related
|
||||
/// policy for when to emit it, returns a version number for that policy.
|
||||
/// Otherwise returns 0.
|
||||
///
|
||||
/// @{
|
||||
unsigned TagVersion(Tag T);
|
||||
unsigned AttributeVersion(Attribute A);
|
||||
unsigned FormVersion(Form F);
|
||||
unsigned OperationVersion(LocationAtom O);
|
||||
unsigned AttributeEncodingVersion(TypeKind E);
|
||||
unsigned LanguageVersion(SourceLanguage L);
|
||||
/// @}
|
||||
|
||||
/// \defgroup DwarfConstantsVendor Dwarf "vendor" for constants
|
||||
///
|
||||
/// These functions return an identifier describing "who" defined the constant,
|
||||
/// either the DWARF standard itself or the vendor who defined the extension.
|
||||
///
|
||||
/// @{
|
||||
unsigned TagVendor(Tag T);
|
||||
unsigned AttributeVendor(Attribute A);
|
||||
unsigned FormVendor(Form F);
|
||||
unsigned OperationVendor(LocationAtom O);
|
||||
unsigned AttributeEncodingVendor(TypeKind E);
|
||||
unsigned LanguageVendor(SourceLanguage L);
|
||||
/// @}
|
||||
|
||||
/// Tells whether the specified form is defined in the specified version,
|
||||
/// or is an extension if extensions are allowed.
|
||||
bool isValidFormForVersion(Form F, unsigned Version, bool ExtensionsOk = true);
|
||||
|
||||
/// \brief Returns the symbolic string representing Val when used as a value
|
||||
/// for attribute Attr.
|
||||
StringRef AttributeValueString(uint16_t Attr, unsigned Val);
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "dwarfdebug"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// DIEAbbrevData Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -79,15 +81,22 @@ void DIEAbbrev::Emit(const AsmPrinter *AP) const {
|
||||
dwarf::AttributeString(AttrData.getAttribute()).data());
|
||||
|
||||
// Emit form type.
|
||||
#ifndef NDEBUG
|
||||
// Could be an assertion, but this way we can see the failing form code
|
||||
// easily, which helps track down where it came from.
|
||||
if (!dwarf::isValidFormForVersion(AttrData.getForm(),
|
||||
AP->getDwarfVersion())) {
|
||||
DEBUG(dbgs() << "Invalid form " << format("0x%x", AttrData.getForm())
|
||||
<< " for DWARF version " << AP->getDwarfVersion() << "\n");
|
||||
llvm_unreachable("Invalid form for specified DWARF version");
|
||||
}
|
||||
#endif
|
||||
AP->EmitULEB128(AttrData.getForm(),
|
||||
dwarf::FormEncodingString(AttrData.getForm()).data());
|
||||
|
||||
// Emit value for DW_FORM_implicit_const.
|
||||
if (AttrData.getForm() == dwarf::DW_FORM_implicit_const) {
|
||||
assert(AP->getDwarfVersion() >= 5 &&
|
||||
"DW_FORM_implicit_const is supported starting from DWARFv5");
|
||||
if (AttrData.getForm() == dwarf::DW_FORM_implicit_const)
|
||||
AP->EmitSLEB128(AttrData.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// Mark end of abbreviation.
|
||||
|
@ -22,7 +22,7 @@ StringRef llvm::dwarf::TagString(unsigned Tag) {
|
||||
switch (Tag) {
|
||||
default:
|
||||
return StringRef();
|
||||
#define HANDLE_DW_TAG(ID, NAME) \
|
||||
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_TAG_##NAME: \
|
||||
return "DW_TAG_" #NAME;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
@ -31,11 +31,34 @@ StringRef llvm::dwarf::TagString(unsigned Tag) {
|
||||
|
||||
unsigned llvm::dwarf::getTag(StringRef TagString) {
|
||||
return StringSwitch<unsigned>(TagString)
|
||||
#define HANDLE_DW_TAG(ID, NAME) .Case("DW_TAG_" #NAME, DW_TAG_##NAME)
|
||||
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
|
||||
.Case("DW_TAG_" #NAME, DW_TAG_##NAME)
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
.Default(DW_TAG_invalid);
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::TagVersion(dwarf::Tag Tag) {
|
||||
switch (Tag) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_TAG_##NAME: \
|
||||
return VERSION;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::TagVendor(dwarf::Tag Tag) {
|
||||
switch (Tag) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_TAG_##NAME: \
|
||||
return DWARF_VENDOR_##VENDOR;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
StringRef llvm::dwarf::ChildrenString(unsigned Children) {
|
||||
switch (Children) {
|
||||
case DW_CHILDREN_no: return "DW_CHILDREN_no";
|
||||
@ -48,29 +71,73 @@ StringRef llvm::dwarf::AttributeString(unsigned Attribute) {
|
||||
switch (Attribute) {
|
||||
default:
|
||||
return StringRef();
|
||||
#define HANDLE_DW_AT(ID, NAME) \
|
||||
case DW_AT_##NAME: \
|
||||
#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_AT_##NAME: \
|
||||
return "DW_AT_" #NAME;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::AttributeVersion(dwarf::Attribute Attribute) {
|
||||
switch (Attribute) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_AT_##NAME: \
|
||||
return VERSION;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::AttributeVendor(dwarf::Attribute Attribute) {
|
||||
switch (Attribute) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_AT(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_AT_##NAME: \
|
||||
return DWARF_VENDOR_##VENDOR;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
StringRef llvm::dwarf::FormEncodingString(unsigned Encoding) {
|
||||
switch (Encoding) {
|
||||
default:
|
||||
return StringRef();
|
||||
#define HANDLE_DW_FORM(ID, NAME) \
|
||||
case DW_FORM_##NAME: \
|
||||
#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_FORM_##NAME: \
|
||||
return "DW_FORM_" #NAME;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::FormVersion(dwarf::Form Form) {
|
||||
switch (Form) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_FORM_##NAME: \
|
||||
return VERSION;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::FormVendor(dwarf::Form Form) {
|
||||
switch (Form) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_FORM(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_FORM_##NAME: \
|
||||
return DWARF_VENDOR_##VENDOR;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) {
|
||||
switch (Encoding) {
|
||||
default:
|
||||
return StringRef();
|
||||
#define HANDLE_DW_OP(ID, NAME) \
|
||||
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_OP_##NAME: \
|
||||
return "DW_OP_" #NAME;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
@ -81,17 +148,40 @@ StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) {
|
||||
|
||||
unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) {
|
||||
return StringSwitch<unsigned>(OperationEncodingString)
|
||||
#define HANDLE_DW_OP(ID, NAME) .Case("DW_OP_" #NAME, DW_OP_##NAME)
|
||||
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
|
||||
.Case("DW_OP_" #NAME, DW_OP_##NAME)
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
.Case("DW_OP_LLVM_fragment", DW_OP_LLVM_fragment)
|
||||
.Default(0);
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::OperationVersion(dwarf::LocationAtom Op) {
|
||||
switch (Op) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_OP_##NAME: \
|
||||
return VERSION;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::OperationVendor(dwarf::LocationAtom Op) {
|
||||
switch (Op) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_OP(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_OP_##NAME: \
|
||||
return DWARF_VENDOR_##VENDOR;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
StringRef llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
|
||||
switch (Encoding) {
|
||||
default:
|
||||
return StringRef();
|
||||
#define HANDLE_DW_ATE(ID, NAME) \
|
||||
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_ATE_##NAME: \
|
||||
return "DW_ATE_" #NAME;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
@ -100,11 +190,34 @@ StringRef llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
|
||||
|
||||
unsigned llvm::dwarf::getAttributeEncoding(StringRef EncodingString) {
|
||||
return StringSwitch<unsigned>(EncodingString)
|
||||
#define HANDLE_DW_ATE(ID, NAME) .Case("DW_ATE_" #NAME, DW_ATE_##NAME)
|
||||
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
|
||||
.Case("DW_ATE_" #NAME, DW_ATE_##NAME)
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
.Default(0);
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::AttributeEncodingVersion(dwarf::TypeKind ATE) {
|
||||
switch (ATE) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_ATE_##NAME: \
|
||||
return VERSION;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::AttributeEncodingVendor(dwarf::TypeKind ATE) {
|
||||
switch (ATE) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_ATE(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_ATE_##NAME: \
|
||||
return DWARF_VENDOR_##VENDOR;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
StringRef llvm::dwarf::DecimalSignString(unsigned Sign) {
|
||||
switch (Sign) {
|
||||
case DW_DS_unsigned: return "DW_DS_unsigned";
|
||||
@ -169,7 +282,7 @@ StringRef llvm::dwarf::LanguageString(unsigned Language) {
|
||||
switch (Language) {
|
||||
default:
|
||||
return StringRef();
|
||||
#define HANDLE_DW_LANG(ID, NAME) \
|
||||
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_LANG_##NAME: \
|
||||
return "DW_LANG_" #NAME;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
@ -178,11 +291,34 @@ StringRef llvm::dwarf::LanguageString(unsigned Language) {
|
||||
|
||||
unsigned llvm::dwarf::getLanguage(StringRef LanguageString) {
|
||||
return StringSwitch<unsigned>(LanguageString)
|
||||
#define HANDLE_DW_LANG(ID, NAME) .Case("DW_LANG_" #NAME, DW_LANG_##NAME)
|
||||
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \
|
||||
.Case("DW_LANG_" #NAME, DW_LANG_##NAME)
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
.Default(0);
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::LanguageVersion(dwarf::SourceLanguage Lang) {
|
||||
switch (Lang) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_LANG_##NAME: \
|
||||
return VERSION;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
unsigned llvm::dwarf::LanguageVendor(dwarf::SourceLanguage Lang) {
|
||||
switch (Lang) {
|
||||
default:
|
||||
return 0;
|
||||
#define HANDLE_DW_LANG(ID, NAME, VERSION, VENDOR) \
|
||||
case DW_LANG_##NAME: \
|
||||
return DWARF_VENDOR_##VENDOR;
|
||||
#include "llvm/Support/Dwarf.def"
|
||||
}
|
||||
}
|
||||
|
||||
StringRef llvm::dwarf::CaseString(unsigned Case) {
|
||||
switch (Case) {
|
||||
case DW_ID_case_sensitive: return "DW_ID_case_sensitive";
|
||||
@ -394,3 +530,12 @@ StringRef llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) {
|
||||
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
bool llvm::dwarf::isValidFormForVersion(Form F, unsigned Version,
|
||||
bool ExtensionsOk) {
|
||||
if (FormVendor(F) == DWARF_VENDOR_DWARF) {
|
||||
unsigned FV = FormVersion(F);
|
||||
return FV > 0 && FV <= Version;
|
||||
}
|
||||
return ExtensionsOk;
|
||||
}
|
||||
|
@ -1,70 +0,0 @@
|
||||
; 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)
|
@ -1,92 +0,0 @@
|
||||
; RUN: llc -O0 -mtriple=amdgcn-amd-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>
|
||||
;
|
||||
; global int GlobA;
|
||||
; global int GlobB;
|
||||
;
|
||||
; kernel void kernel1(unsigned int ArgN, global int *ArgA, global int *ArgB) {
|
||||
; ArgA[ArgN] += ArgB[ArgN];
|
||||
; }
|
||||
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
|
||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x05> 03 00 00 00 00 )
|
||||
@GlobA = common addrspace(1) global i32 0, align 4, !dbg !0
|
||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x05> 03 00 00 00 00 )
|
||||
@GlobB = common addrspace(1) global i32 0, align 4, !dbg !6
|
||||
|
||||
define amdgpu_kernel void @kernel1(
|
||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x06> 91 04 10 01 16 18 )
|
||||
i32 %ArgN,
|
||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x06> 91 08 10 01 16 18 )
|
||||
i32 addrspace(1)* %ArgA,
|
||||
; CHECK-NOT: DW_AT_location [DW_FORM_block1] (<0x06> 91 10 10 01 16 18 )
|
||||
i32 addrspace(1)* %ArgB) !dbg !13 {
|
||||
entry:
|
||||
%ArgN.addr = alloca i32, align 4
|
||||
%ArgA.addr = alloca i32 addrspace(1)*, align 4
|
||||
%ArgB.addr = alloca i32 addrspace(1)*, align 4
|
||||
store i32 %ArgN, i32* %ArgN.addr, align 4
|
||||
call void @llvm.dbg.declare(metadata i32* %ArgN.addr, metadata !22, metadata !23), !dbg !24
|
||||
store i32 addrspace(1)* %ArgA, i32 addrspace(1)** %ArgA.addr, align 4
|
||||
call void @llvm.dbg.declare(metadata i32 addrspace(1)** %ArgA.addr, metadata !25, metadata !23), !dbg !26
|
||||
store i32 addrspace(1)* %ArgB, i32 addrspace(1)** %ArgB.addr, align 4
|
||||
call void @llvm.dbg.declare(metadata i32 addrspace(1)** %ArgB.addr, metadata !27, metadata !23), !dbg !28
|
||||
%0 = load i32 addrspace(1)*, i32 addrspace(1)** %ArgB.addr, align 4, !dbg !29
|
||||
%1 = load i32, i32* %ArgN.addr, align 4, !dbg !30
|
||||
%idxprom = zext i32 %1 to i64, !dbg !29
|
||||
%arrayidx = getelementptr inbounds i32, i32 addrspace(1)* %0, i64 %idxprom, !dbg !29
|
||||
%2 = load i32, i32 addrspace(1)* %arrayidx, align 4, !dbg !29
|
||||
%3 = load i32 addrspace(1)*, i32 addrspace(1)** %ArgA.addr, align 4, !dbg !31
|
||||
%4 = load i32, i32* %ArgN.addr, align 4, !dbg !32
|
||||
%idxprom1 = zext i32 %4 to i64, !dbg !31
|
||||
%arrayidx2 = getelementptr inbounds i32, i32 addrspace(1)* %3, i64 %idxprom1, !dbg !31
|
||||
%5 = load i32, i32 addrspace(1)* %arrayidx2, align 4, !dbg !33
|
||||
%add = add nsw i32 %5, %2, !dbg !33
|
||||
store i32 %add, i32 addrspace(1)* %arrayidx2, align 4, !dbg !33
|
||||
ret void, !dbg !34
|
||||
}
|
||||
|
||||
!llvm.dbg.cu = !{!2}
|
||||
!opencl.ocl.version = !{!9}
|
||||
!llvm.module.flags = !{!10, !11}
|
||||
!llvm.ident = !{!12}
|
||||
|
||||
!0 = !DIGlobalVariableExpression(var: !1)
|
||||
!1 = distinct !DIGlobalVariable(name: "GlobA", scope: !2, file: !3, line: 1, type: !8, isLocal: false, isDefinition: true)
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 5.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
|
||||
!3 = !DIFile(filename: "variable-locations-dwarf-v1.cl", directory: "/some/random/directory")
|
||||
!4 = !{}
|
||||
!5 = !{!0, !6}
|
||||
!6 = !DIGlobalVariableExpression(var: !7)
|
||||
!7 = distinct !DIGlobalVariable(name: "GlobB", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true)
|
||||
!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
||||
!9 = !{i32 2, i32 0}
|
||||
!10 = !{i32 2, !"Dwarf Version", i32 1}
|
||||
!11 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!12 = !{!"clang version 5.0.0"}
|
||||
!13 = distinct !DISubprogram(name: "kernel1", scope: !3, file: !3, line: 4, type: !14, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: false, unit: !2, variables: !4)
|
||||
!14 = !DISubroutineType(types: !15)
|
||||
!15 = !{null, !16, !17, !17}
|
||||
!16 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
|
||||
!17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64)
|
||||
!18 = !{i32 0, i32 1, i32 1}
|
||||
!19 = !{!"none", !"none", !"none"}
|
||||
!20 = !{!"uint", !"int*", !"int*"}
|
||||
!21 = !{!"", !"", !""}
|
||||
!22 = !DILocalVariable(name: "ArgN", arg: 1, scope: !13, file: !3, line: 4, type: !16)
|
||||
!23 = !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)
|
||||
!24 = !DILocation(line: 4, column: 34, scope: !13)
|
||||
!25 = !DILocalVariable(name: "ArgA", arg: 2, scope: !13, file: !3, line: 4, type: !17)
|
||||
!26 = !DILocation(line: 4, column: 52, scope: !13)
|
||||
!27 = !DILocalVariable(name: "ArgB", arg: 3, scope: !13, file: !3, line: 4, type: !17)
|
||||
!28 = !DILocation(line: 4, column: 70, scope: !13)
|
||||
!29 = !DILocation(line: 5, column: 17, scope: !13)
|
||||
!30 = !DILocation(line: 5, column: 22, scope: !13)
|
||||
!31 = !DILocation(line: 5, column: 3, scope: !13)
|
||||
!32 = !DILocation(line: 5, column: 8, scope: !13)
|
||||
!33 = !DILocation(line: 5, column: 14, scope: !13)
|
||||
!34 = !DILocation(line: 6, column: 1, scope: !13)
|
@ -522,7 +522,8 @@ public:
|
||||
|
||||
/// \brief Emit the abbreviation table \p Abbrevs to the
|
||||
/// debug_abbrev section.
|
||||
void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs);
|
||||
void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
|
||||
unsigned DwarfVersion);
|
||||
|
||||
/// \brief Emit the string table described by \p Pool.
|
||||
void emitStrings(const NonRelocatableStringpool &Pool);
|
||||
@ -690,8 +691,10 @@ void DwarfStreamer::emitCompileUnitHeader(CompileUnit &Unit) {
|
||||
/// \brief Emit the \p Abbrevs array as the shared abbreviation table
|
||||
/// for the linked Dwarf file.
|
||||
void DwarfStreamer::emitAbbrevs(
|
||||
const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs) {
|
||||
const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
|
||||
unsigned DwarfVersion) {
|
||||
MS->SwitchSection(MOFI->getDwarfAbbrevSection());
|
||||
MC->setDwarfVersion(DwarfVersion);
|
||||
Asm->emitDwarfAbbrevs(Abbrevs);
|
||||
}
|
||||
|
||||
@ -1129,6 +1132,12 @@ private:
|
||||
/// \brief Called at the end of a debug object link.
|
||||
void endDebugObject();
|
||||
|
||||
/// Remembers the newest DWARF version we've seen in a unit.
|
||||
void maybeUpdateMaxDwarfVersion(unsigned Version) {
|
||||
if (MaxDwarfVersion < Version)
|
||||
MaxDwarfVersion = Version;
|
||||
}
|
||||
|
||||
/// Keeps track of relocations.
|
||||
class RelocationManager {
|
||||
struct ValidReloc {
|
||||
@ -1430,6 +1439,7 @@ private:
|
||||
std::unique_ptr<DwarfStreamer> Streamer;
|
||||
uint64_t OutputDebugInfoSize;
|
||||
unsigned UnitID; ///< A unique ID that identifies each compile unit.
|
||||
unsigned MaxDwarfVersion = 0;
|
||||
|
||||
/// The units of the current debug map object.
|
||||
std::vector<std::unique_ptr<CompileUnit>> Units;
|
||||
@ -3435,9 +3445,11 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
CUDie.dump(outs(), 0);
|
||||
}
|
||||
|
||||
if (!registerModuleReference(CUDie, *CU, ModuleMap))
|
||||
if (!registerModuleReference(CUDie, *CU, ModuleMap)) {
|
||||
Units.push_back(llvm::make_unique<CompileUnit>(*CU, UnitID++,
|
||||
!Options.NoODR, ""));
|
||||
maybeUpdateMaxDwarfVersion(CU->getVersion());
|
||||
}
|
||||
}
|
||||
|
||||
// Now build the DIE parent links that we will use during the next phase.
|
||||
@ -3471,7 +3483,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
|
||||
// Emit everything that's global.
|
||||
if (!Options.NoOutput) {
|
||||
Streamer->emitAbbrevs(Abbreviations);
|
||||
Streamer->emitAbbrevs(Abbreviations, MaxDwarfVersion);
|
||||
Streamer->emitStrings(StringPool);
|
||||
}
|
||||
|
||||
|
@ -170,7 +170,8 @@ void TestAllForms() {
|
||||
CUDie.addAttribute(Attr_DW_FORM_ref8, DW_FORM_ref8, Data8);
|
||||
|
||||
const auto Attr_DW_FORM_ref_sig8 = static_cast<dwarf::Attribute>(Attr++);
|
||||
CUDie.addAttribute(Attr_DW_FORM_ref_sig8, DW_FORM_ref_sig8, Data8_2);
|
||||
if (Version >= 4)
|
||||
CUDie.addAttribute(Attr_DW_FORM_ref_sig8, DW_FORM_ref_sig8, Data8_2);
|
||||
|
||||
const auto Attr_DW_FORM_ref_udata = static_cast<dwarf::Attribute>(Attr++);
|
||||
CUDie.addAttribute(Attr_DW_FORM_ref_udata, DW_FORM_ref_udata, UData[0]);
|
||||
@ -185,7 +186,8 @@ void TestAllForms() {
|
||||
CUDie.addAttribute(Attr_DW_FORM_flag_false, DW_FORM_flag, false);
|
||||
|
||||
const auto Attr_DW_FORM_flag_present = static_cast<dwarf::Attribute>(Attr++);
|
||||
CUDie.addAttribute(Attr_DW_FORM_flag_present, DW_FORM_flag_present);
|
||||
if (Version >= 4)
|
||||
CUDie.addAttribute(Attr_DW_FORM_flag_present, DW_FORM_flag_present);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Test SLEB128 based forms
|
||||
@ -213,8 +215,9 @@ void TestAllForms() {
|
||||
Dwarf32Values[0]);
|
||||
|
||||
const auto Attr_DW_FORM_sec_offset = static_cast<dwarf::Attribute>(Attr++);
|
||||
CUDie.addAttribute(Attr_DW_FORM_sec_offset, DW_FORM_sec_offset,
|
||||
Dwarf32Values[1]);
|
||||
if (Version >= 4)
|
||||
CUDie.addAttribute(Attr_DW_FORM_sec_offset, DW_FORM_sec_offset,
|
||||
Dwarf32Values[1]);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Add an address at the end to make sure we can decode this value
|
||||
@ -307,7 +310,8 @@ void TestAllForms() {
|
||||
EXPECT_EQ(Data2, toReference(DieDG.find(Attr_DW_FORM_ref2), 0));
|
||||
EXPECT_EQ(Data4, toReference(DieDG.find(Attr_DW_FORM_ref4), 0));
|
||||
EXPECT_EQ(Data8, toReference(DieDG.find(Attr_DW_FORM_ref8), 0));
|
||||
EXPECT_EQ(Data8_2, toReference(DieDG.find(Attr_DW_FORM_ref_sig8), 0));
|
||||
if (Version >= 4)
|
||||
EXPECT_EQ(Data8_2, toReference(DieDG.find(Attr_DW_FORM_ref_sig8), 0));
|
||||
EXPECT_EQ(UData[0], toReference(DieDG.find(Attr_DW_FORM_ref_udata), 0));
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -315,7 +319,8 @@ void TestAllForms() {
|
||||
//----------------------------------------------------------------------
|
||||
EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_true), 0));
|
||||
EXPECT_EQ(0ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_false), 1));
|
||||
EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_present), 0));
|
||||
if (Version >= 4)
|
||||
EXPECT_EQ(1ULL, toUnsigned(DieDG.find(Attr_DW_FORM_flag_present), 0));
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Test SLEB128 based forms
|
||||
@ -334,8 +339,9 @@ void TestAllForms() {
|
||||
//----------------------------------------------------------------------
|
||||
EXPECT_EQ(Dwarf32Values[0],
|
||||
toReference(DieDG.find(Attr_DW_FORM_GNU_ref_alt), 0));
|
||||
EXPECT_EQ(Dwarf32Values[1],
|
||||
toSectionOffset(DieDG.find(Attr_DW_FORM_sec_offset), 0));
|
||||
if (Version >= 4)
|
||||
EXPECT_EQ(Dwarf32Values[1],
|
||||
toSectionOffset(DieDG.find(Attr_DW_FORM_sec_offset), 0));
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Add an address at the end to make sure we can decode this value
|
||||
|
Loading…
Reference in New Issue
Block a user