Make debug info of HLSL vectors more user friendly (#2018)

The clang type we generate for HLSL vectors contains a single field h of type DependentSizedExtVectorType, which shows up as an int[4] in DWARF. This change specifically emits debug info for x, y, z and w fields instead.

With this change, we also stop emitting a vector member for operator[], whose implementation was marked "external" so I don't think it'll have any impact.
This commit is contained in:
Tristan Labelle 2019-03-18 14:12:49 -07:00 коммит произвёл GitHub
Родитель 8275b8103c
Коммит e487566946
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 71 добавлений и 13 удалений

Просмотреть файл

@ -1023,6 +1023,34 @@ void CGDebugInfo::CollectRecordFields(
} }
} }
// HLSL Change Begins
bool CGDebugInfo::TryCollectHLSLRecordElements(const RecordType *Ty,
llvm::DICompositeType *DITy,
SmallVectorImpl<llvm::Metadata *> &Elements) {
QualType QualTy(Ty, 0);
if (hlsl::IsHLSLVecType(QualTy)) {
// The HLSL vector type is defined as containing a field 'h' of
// extended vector type, which is represented as an array in DWARF.
// However, we logically represent it as one field per component.
QualType ElemQualTy = hlsl::GetHLSLVecElementType(QualTy);
unsigned VecSize = hlsl::GetHLSLVecSize(QualTy);
unsigned ElemSizeInBits = CGM.getContext().getTypeSize(ElemQualTy);
for (unsigned ElemIdx = 0; ElemIdx < VecSize; ++ElemIdx) {
StringRef FieldName = StringRef("xyzw" + ElemIdx, 1);
unsigned OffsetInBits = ElemSizeInBits * ElemIdx;
llvm::DIType *FieldType = createFieldType(FieldName, ElemQualTy, 0,
SourceLocation(), AccessSpecifier::AS_public, OffsetInBits,
/* tunit */ nullptr, DITy, Ty->getDecl());
Elements.emplace_back(FieldType);
}
return true;
}
return false;
}
// HLSL Chage Ends
llvm::DISubroutineType * llvm::DISubroutineType *
CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method, CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
llvm::DIFile *Unit) { llvm::DIFile *Unit) {
@ -1564,20 +1592,24 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
SmallVector<llvm::Metadata *, 16> EltTys; SmallVector<llvm::Metadata *, 16> EltTys;
// what about nested types? // what about nested types?
// Note: The split of CXXDecl information here is intentional, the if (!TryCollectHLSLRecordElements(Ty, FwdDecl, EltTys)) { // HLSL Change
// gdb tests will depend on a certain ordering at printout. The debug
// information offsets are still correct if we merge them all together
// though.
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
if (CXXDecl) {
CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
CollectVTableInfo(CXXDecl, DefUnit, EltTys);
}
// Collect data fields (including static variables and any initializers). // Note: The split of CXXDecl information here is intentional, the
CollectRecordFields(RD, DefUnit, EltTys, FwdDecl); // gdb tests will depend on a certain ordering at printout. The debug
if (CXXDecl) // information offsets are still correct if we merge them all together
CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl); // though.
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
if (CXXDecl) {
CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
CollectVTableInfo(CXXDecl, DefUnit, EltTys);
}
// Collect data fields (including static variables and any initializers).
CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
if (CXXDecl)
CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
} // HLSL Change
LexicalBlockStack.pop_back(); LexicalBlockStack.pop_back();
RegionMap.erase(Ty->getDecl()); RegionMap.erase(Ty->getDecl());

Просмотреть файл

@ -255,6 +255,13 @@ class CGDebugInfo {
/// Create a new lexical block node and push it on the stack. /// Create a new lexical block node and push it on the stack.
void CreateLexicalBlock(SourceLocation Loc); void CreateLexicalBlock(SourceLocation Loc);
// HLSL Change Begins
private:
bool TryCollectHLSLRecordElements(const RecordType *Ty,
llvm::DICompositeType *DITy,
SmallVectorImpl<llvm::Metadata *> &Elements);
// HLSL Change Ends
public: public:
CGDebugInfo(CodeGenModule &CGM); CGDebugInfo(CodeGenModule &CGM);
~CGDebugInfo(); ~CGDebugInfo();

Просмотреть файл

@ -0,0 +1,9 @@
// RUN: %dxc -T vs_6_0 -E main -Od -Zi %s | FileCheck %s
// Test that the debug info for HLSL vectors exposes per-component fields.
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "int2"
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "vector<int, 2>", {{.*}}, size: 64, align: 32
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 32, align: 32
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "y", {{.*}}, size: 32, align: 32, offset: 32
int2 main(int2 v : IN) : OUT { return v; }

Просмотреть файл

@ -0,0 +1,10 @@
// RUN: %dxc -T vs_6_0 -E main -Od -Zi %s | FileCheck %s
// Test that the debug info for HLSL bool vectors exposes per-component fields
// in the memory representation of bools (32-bits)
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "bool2"
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "vector<bool, 2>", {{.*}}, size: 64, align: 32
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 32, align: 32
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "y", {{.*}}, size: 32, align: 32, offset: 32
bool2 main(bool2 v : IN) : OUT { return v; }