diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4893,19 +4893,27 @@ llvm::FoldingSetNodeID ID; BTFTagAttributedType::Profile(ID, Wrapped, BTFAttr); + // Split away local CVR qualifiers to make sure that + // BTFTagAttributedType is always applied to non-CVR qualified type. + // Apply CVR to a resulting QualType. + QualType WrappedNoCVR = Wrapped; + WrappedNoCVR.removeLocalCVRQualifiers(Qualifiers::CVRMask); + unsigned CVR = Wrapped.getLocalCVRQualifiers(); + void *InsertPos = nullptr; BTFTagAttributedType *Ty = BTFTagAttributedTypes.FindNodeOrInsertPos(ID, InsertPos); if (Ty) - return QualType(Ty, 0); + return QualType(Ty, CVR); QualType Canon = getCanonicalType(Wrapped); - Ty = new (*this, TypeAlignment) BTFTagAttributedType(Canon, Wrapped, BTFAttr); + Ty = new (*this, TypeAlignment) + BTFTagAttributedType(Canon, WrappedNoCVR, BTFAttr); Types.push_back(Ty); BTFTagAttributedTypes.InsertNode(Ty, InsertPos); - return QualType(Ty, 0); + return QualType(Ty, CVR); } /// Retrieve a substitution-result type. diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -212,6 +212,7 @@ llvm::DIType *CreateType(const MemberPointerType *Ty, llvm::DIFile *F); llvm::DIType *CreateType(const AtomicType *Ty, llvm::DIFile *F); llvm::DIType *CreateType(const PipeType *Ty, llvm::DIFile *F); + llvm::DIType *CreateType(const BTFTagAttributedType *Ty, llvm::DIFile *F); /// Get enumeration type. llvm::DIType *CreateEnumType(const EnumType *Ty); llvm::DIType *CreateTypeDefinition(const EnumType *Ty); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1156,6 +1156,65 @@ return RetTy; } +static QualType collectBTFTypeTagAnnotations( + llvm::LLVMContext &Context, llvm::DIBuilder &DBuilder, + llvm::SmallVectorImpl &Annots, + const BTFTagAttributedType *BTFAttrTy, const char *TagName) { + QualType WrappedTy; + + do { + StringRef TagValue = BTFAttrTy->getAttr()->getBTFTypeTag(); + if (!TagValue.empty()) { + llvm::Metadata *Ops[] = { + llvm::MDString::get(Context, TagName), + llvm::MDString::get(Context, TagValue), + }; + Annots.insert(Annots.begin(), llvm::MDNode::get(Context, Ops)); + } + WrappedTy = BTFAttrTy->getWrappedType(); + BTFAttrTy = dyn_cast(WrappedTy); + } while (BTFAttrTy); + + llvm::DINodeArray Annotations = nullptr; + if (Annots.size() > 0) + Annotations = DBuilder.getOrCreateArray(Annots); + + return WrappedTy; +} + +llvm::DIType *CGDebugInfo::CreateType(const BTFTagAttributedType *Ty, + llvm::DIFile *Unit) { + SmallVector Annotations; + auto WrappedTy = collectBTFTypeTagAnnotations( + CGM.getLLVMContext(), DBuilder, Annotations, Ty, "btf_type_tag:v2"); + + llvm::DIType *WrappedDI = getOrCreateType(WrappedTy, Unit); + if (Annotations.size() == 0) + return WrappedDI; + + auto AddAnnotations = [&](auto *Type) { + if (llvm::DINodeArray OldAnnotations = Type->getAnnotations()) + for (const llvm::Metadata *O : OldAnnotations->operands()) + Annotations.push_back(const_cast(O)); + auto Clone = Type->clone(); + Clone->replaceAnnotations(DBuilder.getOrCreateArray(Annotations)); + return llvm::MDNode::replaceWithPermanent(std::move(Clone)); + }; + + if (WrappedDI == nullptr) + return AddAnnotations(DBuilder.createUnspecifiedType("void")); + if (auto *Ty = dyn_cast(WrappedDI)) + return AddAnnotations(Ty); + if (auto *Ty = dyn_cast(WrappedDI)) + return AddAnnotations(Ty); + if (auto *Ty = dyn_cast(WrappedDI)) + return AddAnnotations(Ty); + if (auto *Ty = dyn_cast(WrappedDI)) + return AddAnnotations(Ty); + + return WrappedDI; +} + llvm::DIType *CGDebugInfo::CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty, QualType PointeeTy, @@ -1168,32 +1227,23 @@ CGM.getTarget().getDWARFAddressSpace( CGM.getTypes().getTargetAddressSpace(PointeeTy)); - SmallVector Annots; - auto *BTFAttrTy = dyn_cast(PointeeTy); - while (BTFAttrTy) { - StringRef Tag = BTFAttrTy->getAttr()->getBTFTypeTag(); - if (!Tag.empty()) { - llvm::Metadata *Ops[2] = { - llvm::MDString::get(CGM.getLLVMContext(), StringRef("btf_type_tag")), - llvm::MDString::get(CGM.getLLVMContext(), Tag)}; - Annots.insert(Annots.begin(), - llvm::MDNode::get(CGM.getLLVMContext(), Ops)); - } - BTFAttrTy = dyn_cast(BTFAttrTy->getWrappedType()); - } - llvm::DINodeArray Annotations = nullptr; - if (Annots.size() > 0) - Annotations = DBuilder.getOrCreateArray(Annots); + if (auto *BTFAttrTy = + dyn_cast(PointeeTy.getTypePtr())) { + SmallVector AnnotationsVec; + collectBTFTypeTagAnnotations(CGM.getLLVMContext(), DBuilder, AnnotationsVec, + BTFAttrTy, "btf_type_tag"); + Annotations = DBuilder.getOrCreateArray(AnnotationsVec); + } if (Tag == llvm::dwarf::DW_TAG_reference_type || Tag == llvm::dwarf::DW_TAG_rvalue_reference_type) return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit), Size, Align, DWARFAddressSpace); - else - return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size, - Align, DWARFAddressSpace, StringRef(), - Annotations); + + return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size, + Align, DWARFAddressSpace, StringRef(), + Annotations); } llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name, @@ -3319,9 +3369,6 @@ case Type::Attributed: T = cast(T)->getEquivalentType(); break; - case Type::BTFTagAttributed: - T = cast(T)->getWrappedType(); - break; case Type::Elaborated: T = cast(T)->getNamedType(); break; @@ -3477,6 +3524,8 @@ return CreateType(cast(Ty)); case Type::Pointer: return CreateType(cast(Ty), Unit); + case Type::BTFTagAttributed: + return CreateType(cast(Ty), Unit); case Type::BlockPointer: return CreateType(cast(Ty), Unit); case Type::Typedef: @@ -3514,7 +3563,6 @@ case Type::Auto: case Type::Attributed: - case Type::BTFTagAttributed: case Type::Adjusted: case Type::Decayed: case Type::DeducedTemplateSpecialization: diff --git a/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c b/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c --- a/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c +++ b/clang/test/CodeGen/attr-btf_type_tag-func-ptr.c @@ -8,8 +8,10 @@ return arg->a; } -// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "f" -// CHECK-SAME: baseType: ![[L18:[0-9]+]] -// CHECK: ![[L18]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#]], size: [[#]], annotations: ![[L21:[0-9]+]]) -// CHECK: ![[L21]] = !{![[L22:[0-9]+]]} -// CHECK: ![[L22]] = !{!"btf_type_tag", !"rcu"} +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "f", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L1:[0-9]+]], size: [[#]]) +// CHECK: ![[L1]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L2:[0-9]+]], size: [[#]], annotations: ![[L3:[0-9]+]]) +// CHECK: ![[L2]] = !DISubroutineType(types: ![[#]], annotations: ![[L4:[0-9]+]]) +// CHECK: ![[L4]] = !{![[L5:[0-9]+]]} +// CHECK: ![[L5]] = !{!"btf_type_tag:v2", !"rcu"} +// CHECK: ![[L3]] = !{![[L6:[0-9]+]]} +// CHECK: ![[L6]] = !{!"btf_type_tag", !"rcu"} diff --git a/clang/test/CodeGen/attr-btf_type_tag-func.c b/clang/test/CodeGen/attr-btf_type_tag-func.c --- a/clang/test/CodeGen/attr-btf_type_tag-func.c +++ b/clang/test/CodeGen/attr-btf_type_tag-func.c @@ -15,14 +15,17 @@ int __tag1 * __tag2 *foo(int __tag1 * __tag2 *arg) { return arg; } -// CHECK: distinct !DISubprogram(name: "foo", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L9:[0-9]+]] -// CHECK: ![[L9]] = !DISubroutineType(types: ![[L10:[0-9]+]] -// CHECK: ![[L10]] = !{![[L11:[0-9]+]], ![[L11]]} -// CHECK: ![[L11]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L12:[0-9]+]], size: [[#]], annotations: ![[L16:[0-9]+]] -// CHECK: ![[L12]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L13:[0-9]+]], size: [[#]], annotations: ![[L14:[0-9]+]] -// CHECK: ![[L13]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed -// CHECK: ![[L14]] = !{![[L15:[0-9]+]]} -// CHECK: ![[L15]] = !{!"btf_type_tag", !"tag1"} -// CHECK: ![[L16]] = !{![[L17:[0-9]+]]} -// CHECK: ![[L17]] = !{!"btf_type_tag", !"tag2"} -// CHECK: !DILocalVariable(name: "arg", arg: 1, scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L11]]) +// CHECK: distinct !DISubprogram(name: "foo", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L01:[0-9]+]], {{.*}}) +// CHECK: ![[L01]] = !DISubroutineType(types: ![[L02:[0-9]+]]) +// CHECK: ![[L02]] = !{![[L03:[0-9]+]], ![[L03]]} +// CHECK: ![[L03]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L04:[0-9]+]], size: [[#]], annotations: ![[L05:[0-9]+]]) +// CHECK: ![[L04]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L06:[0-9]+]], size: [[#]], annotations: ![[L07:[0-9]+]]) +// CHECK: ![[L06]] = !DIBasicType(name: "int", size: [[#]], encoding: DW_ATE_signed, annotations: ![[L08:[0-9]+]]) +// CHECK: ![[L08]] = !{![[L09:[0-9]+]]} +// CHECK: ![[L09]] = !{!"btf_type_tag:v2", !"tag1"} +// CHECK: ![[L07]] = !{![[L10:[0-9]+]], ![[L11:[0-9]+]]} +// CHECK: ![[L10]] = !{!"btf_type_tag:v2", !"tag2"} +// CHECK: ![[L11]] = !{!"btf_type_tag", !"tag1"} +// CHECK: ![[L05]] = !{![[L12:[0-9]+]]} +// CHECK: ![[L12]] = !{!"btf_type_tag", !"tag2"} +// CHECK: !DILocalVariable(name: "arg", arg: 1, scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L03]]) diff --git a/clang/test/CodeGen/attr-btf_type_tag-similar-type.c b/clang/test/CodeGen/attr-btf_type_tag-similar-type.c --- a/clang/test/CodeGen/attr-btf_type_tag-similar-type.c +++ b/clang/test/CodeGen/attr-btf_type_tag-similar-type.c @@ -12,15 +12,23 @@ return *arg->a; } -// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: ![[#]], line: [[#]], size: [[#]], elements: ![[L14:[0-9]+]] -// CHECK: ![[L14]] = !{![[L15:[0-9]+]], ![[L20:[0-9]+]]} -// CHECK: ![[L15]] = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L16:[0-9]+]] -// CHECK: ![[L16]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#]], size: [[#]], annotations: ![[L17:[0-9]+]] -// CHECK: ![[L17]] = !{![[L18:[0-9]+]], ![[L19:[0-9]+]]} -// CHECK: ![[L18]] = !{!"btf_type_tag", !"tag1"} -// CHECK: ![[L19]] = !{!"btf_type_tag", !"tag3"} -// CHECK: ![[L20]] = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L21:[0-9]+]] -// CHECK: ![[L21:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#]], size: [[#]], annotations: ![[L22:[0-9]+]] -// CHECK: ![[L22]] = !{![[L23:[0-9]+]], ![[L24:[0-9]+]]} -// CHECK: ![[L23]] = !{!"btf_type_tag", !"tag2"} -// CHECK: ![[L24]] = !{!"btf_type_tag", !"tag4"} +// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: ![[#]], line: [[#]], size: [[#]], elements: ![[L01:[0-9]+]]) +// CHECK: ![[L01]] = !{![[L02:[0-9]+]], ![[L03:[0-9]+]]} +// CHECK: ![[L02]] = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L04:[0-9]+]], size: [[#]]) +// CHECK: ![[L04]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L05:[0-9]+]], size: [[#]], annotations: ![[L06:[0-9]+]]) +// CHECK: ![[L05]] = !DIBasicType(name: "int", size: [[#]], encoding: DW_ATE_signed, annotations: ![[L07:[0-9]+]]) +// CHECK: ![[L07]] = !{![[L08:[0-9]+]], ![[L09:[0-9]+]]} +// CHECK: ![[L08]] = !{!"btf_type_tag:v2", !"tag1"} +// CHECK: ![[L09]] = !{!"btf_type_tag:v2", !"tag3"} +// CHECK: ![[L06]] = !{![[L10:[0-9]+]], ![[L11:[0-9]+]]} +// CHECK: ![[L10]] = !{!"btf_type_tag", !"tag1"} +// CHECK: ![[L11]] = !{!"btf_type_tag", !"tag3"} +// CHECK: ![[L03]] = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L12:[0-9]+]], size: [[#]], offset: [[#]]) +// CHECK: ![[L12]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L13:[0-9]+]], size: [[#]], annotations: ![[L14:[0-9]+]]) +// CHECK: ![[L13]] = !DIBasicType(name: "int", size: [[#]], encoding: DW_ATE_signed, annotations: ![[L15:[0-9]+]]) +// CHECK: ![[L15]] = !{![[L16:[0-9]+]], ![[L17:[0-9]+]]} +// CHECK: ![[L16]] = !{!"btf_type_tag:v2", !"tag2"} +// CHECK: ![[L17]] = !{!"btf_type_tag:v2", !"tag4"} +// CHECK: ![[L14]] = !{![[L18:[0-9]+]], ![[L19:[0-9]+]]} +// CHECK: ![[L18]] = !{!"btf_type_tag", !"tag2"} +// CHECK: ![[L19]] = !{!"btf_type_tag", !"tag4"} diff --git a/clang/test/CodeGen/attr-btf_type_tag-typedef-field.c b/clang/test/CodeGen/attr-btf_type_tag-typedef-field.c --- a/clang/test/CodeGen/attr-btf_type_tag-typedef-field.c +++ b/clang/test/CodeGen/attr-btf_type_tag-typedef-field.c @@ -14,22 +14,27 @@ return (int *)a1->c; } -// CHECK: ![[L4:[0-9]+]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: ![[#]], line: [[#]], size: [[#]], elements: ![[L16:[0-9]+]]) -// CHECK: ![[L16]] = !{![[L17:[0-9]+]], ![[L24:[0-9]+]], ![[L31:[0-9]+]]} -// CHECK: ![[L17]] = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L18:[0-9]+]], size: [[#]]) -// CHECK: ![[L18]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L19:[0-9]+]], size: [[#]], annotations: ![[L22:[0-9]+]]) -// CHECK: ![[L19]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L4]], size: [[#]], annotations: ![[L20:[0-9]+]]) -// CHECK: ![[L20]] = !{![[L21:[0-9]+]]} -// CHECK: ![[L21]] = !{!"btf_type_tag", !"tag1"} -// CHECK: ![[L22]] = !{![[L23:[0-9]+]]} -// CHECK: ![[L23]] = !{!"btf_type_tag", !"tag2"} -// CHECK: ![[L24]] = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L25:[0-9]+]] -// CHECK: ![[L25]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__fn2_t", file: ![[#]], line: [[#]], baseType: ![[L26:[0-9]+]]) -// CHECK: ![[L26]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L27:[0-9]+]], size: [[#]], annotations: ![[L30:[0-9]+]]) -// CHECK: ![[L27]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__fn_t", file: ![[#]], line: [[#]], baseType: ![[L28:[0-9]+]]) -// CHECK: ![[L28]] = !DISubroutineType(types: ![[L29:[0-9]+]]) -// CHECK: ![[L29]] = !{null, ![[L4]]} -// CHECK: ![[L30]] = !{![[L21]], ![[L23]]} -// CHECK: ![[L31]] = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: ![[#]], file: ![[#]], line: [[#]]1, baseType: ![[L32:[0-9]+]] -// CHECK: ![[L32]] = !DIBasicType(name: "long", size: [[#]], encoding: DW_ATE_signed) +// CHECK: ![[L01:[0-9]+]] = !DIBasicType(name: "int", size: [[#]], encoding: DW_ATE_signed) +// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: ![[#]], line: [[#]], size: [[#]], elements: ![[L02:[0-9]+]]) +// CHECK: ![[L02]] = !{![[L03:[0-9]+]], ![[L04:[0-9]+]], ![[L05:[0-9]+]]} +// CHECK: ![[L03]] = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L06:[0-9]+]], size: [[#]]) +// CHECK: ![[L06]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L07:[0-9]+]], size: [[#]], annotations: ![[L08:[0-9]+]]) +// CHECK: ![[L07]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L09:[0-9]+]], size: [[#]], annotations: ![[L10:[0-9]+]]) +// CHECK: ![[L09]] = !DIBasicType(name: "int", size: [[#]], encoding: DW_ATE_signed, annotations: ![[L11:[0-9]+]]) +// CHECK: ![[L11]] = !{![[L12:[0-9]+]]} +// CHECK: ![[L12]] = !{!"btf_type_tag:v2", !"tag1"} +// CHECK: ![[L10]] = !{![[L13:[0-9]+]], ![[L14:[0-9]+]]} +// CHECK: ![[L13]] = !{!"btf_type_tag:v2", !"tag2"} +// CHECK: ![[L14]] = !{!"btf_type_tag", !"tag1"} +// CHECK: ![[L08]] = !{![[L15:[0-9]+]]} +// CHECK: ![[L15]] = !{!"btf_type_tag", !"tag2"} +// CHECK: ![[L04]] = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L16:[0-9]+]], size: [[#]], offset: [[#]]) +// CHECK: ![[L16]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__fn2_t", file: ![[#]], line: [[#]], baseType: ![[L17:[0-9]+]]) +// CHECK: ![[L17]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L18:[0-9]+]], size: [[#]], annotations: ![[L19:[0-9]+]]) +// CHECK: ![[L18]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__fn_t", file: ![[#]], line: [[#]], baseType: ![[L20:[0-9]+]], annotations: ![[L21:[0-9]+]]) +// CHECK: ![[L20]] = !DISubroutineType(types: ![[L22:[0-9]+]]) +// CHECK: ![[L22]] = !{null, ![[L01]]} +// CHECK: ![[L21]] = !{![[L12]], ![[L13]]} +// CHECK: ![[L19]] = !{![[L14]], ![[L15]]} +// CHECK: ![[L05]] = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: ![[#]], file: ![[#]], line: [[#]], baseType: ![[L23:[0-9]+]], size: [[#]], offset: [[#]]) +// CHECK: ![[L23]] = !DIBasicType(name: "long", size: [[#]], encoding: DW_ATE_signed) diff --git a/clang/test/CodeGen/attr-btf_type_tag-var.c b/clang/test/CodeGen/attr-btf_type_tag-var.c --- a/clang/test/CodeGen/attr-btf_type_tag-var.c +++ b/clang/test/CodeGen/attr-btf_type_tag-var.c @@ -21,23 +21,30 @@ const int __tag1 __tag2 volatile * const __tag3 __tag4 volatile * __tag5 __tag6 const volatile * g; #endif -// CHECK: distinct !DIGlobalVariable(name: "g", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L6:[0-9]+]] -// CHECK: ![[L6]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L7:[0-9]+]], size: [[#]], annotations: ![[L22:[0-9]+]] -// CHECK: ![[L7]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L8:[0-9]+]] -// CHECK: ![[L8]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: ![[L9:[0-9]+]] -// CHECK: ![[L9]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L10:[0-9]+]], size: [[#]], annotations: ![[L19:[0-9]+]] -// CHECK: ![[L10]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L11:[0-9]+]] -// CHECK: ![[L11]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: ![[L12:[0-9]+]] -// CHECK: ![[L12]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L13:[0-9]+]], size: [[#]], annotations: ![[L16:[0-9]+]] -// CHECK: ![[L13]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L14:[0-9]+]] -// CHECK: ![[L14]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: ![[L15:[0-9]+]] -// CHECK: ![[L15]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed -// CHECK: ![[L16]] = !{![[L17:[0-9]+]], ![[L18:[0-9]+]]} -// CHECK: ![[L17]] = !{!"btf_type_tag", !"tag1"} -// CHECK: ![[L18]] = !{!"btf_type_tag", !"tag2"} -// CHECK: ![[L19]] = !{![[L20:[0-9]+]], ![[L21:[0-9]+]]} -// CHECK: ![[L20]] = !{!"btf_type_tag", !"tag3"} -// CHECK: ![[L21]] = !{!"btf_type_tag", !"tag4"} -// CHECK: ![[L22]] = !{![[L23:[0-9]+]], ![[L24:[0-9]+]]} -// CHECK: ![[L23]] = !{!"btf_type_tag", !"tag5"} -// CHECK: ![[L24]] = !{!"btf_type_tag", !"tag6"} +// CHECK: distinct !DIGlobalVariable(name: "g", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L01:[0-9]+]], isLocal: false, isDefinition: true) +// CHECK: ![[L01]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L02:[0-9]+]], size: [[#]], annotations: ![[L03:[0-9]+]]) +// CHECK: ![[L02]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L04:[0-9]+]]) +// CHECK: ![[L04]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: ![[L05:[0-9]+]]) +// CHECK: ![[L05]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L06:[0-9]+]], size: [[#]], annotations: ![[L07:[0-9]+]]) +// CHECK: ![[L06]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L08:[0-9]+]]) +// CHECK: ![[L08]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: ![[L09:[0-9]+]]) +// CHECK: ![[L09]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L10:[0-9]+]], size: [[#]], annotations: ![[L11:[0-9]+]]) +// CHECK: ![[L10]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[L12:[0-9]+]]) +// CHECK: ![[L12]] = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: ![[L13:[0-9]+]]) +// CHECK: ![[L13]] = !DIBasicType(name: "int", size: [[#]], encoding: DW_ATE_signed, annotations: ![[L14:[0-9]+]]) +// CHECK: ![[L14]] = !{![[L15:[0-9]+]], ![[L16:[0-9]+]]} +// CHECK: ![[L15]] = !{!"btf_type_tag:v2", !"tag1"} +// CHECK: ![[L16]] = !{!"btf_type_tag:v2", !"tag2"} +// CHECK: ![[L11]] = !{![[L17:[0-9]+]], ![[L18:[0-9]+]], ![[L19:[0-9]+]], ![[L20:[0-9]+]]} +// CHECK: ![[L17]] = !{!"btf_type_tag:v2", !"tag3"} +// CHECK: ![[L18]] = !{!"btf_type_tag:v2", !"tag4"} +// CHECK: ![[L19]] = !{!"btf_type_tag", !"tag1"} +// CHECK: ![[L20]] = !{!"btf_type_tag", !"tag2"} +// CHECK: ![[L07]] = !{![[L21:[0-9]+]], ![[L22:[0-9]+]], ![[L23:[0-9]+]], ![[L24:[0-9]+]]} +// CHECK: ![[L21]] = !{!"btf_type_tag:v2", !"tag5"} +// CHECK: ![[L22]] = !{!"btf_type_tag:v2", !"tag6"} +// CHECK: ![[L23]] = !{!"btf_type_tag", !"tag3"} +// CHECK: ![[L24]] = !{!"btf_type_tag", !"tag4"} +// CHECK: ![[L03]] = !{![[L25:[0-9]+]], ![[L26:[0-9]+]]} +// CHECK: ![[L25]] = !{!"btf_type_tag", !"tag5"} +// CHECK: ![[L26]] = !{!"btf_type_tag", !"tag6"} diff --git a/clang/test/CodeGen/attr-btf_type_tag-void.c b/clang/test/CodeGen/attr-btf_type_tag-void.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/attr-btf_type_tag-void.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck %s + +#define __tag1 __attribute__((btf_type_tag("tag1"))) +void __tag1 *g; + +// CHECK: distinct !DIGlobalVariable(name: "g", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[L1:[0-9]+]], isLocal: false, isDefinition: true) +// CHECK: ![[L1]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[L2:[0-9]+]], size: [[#]], annotations: ![[L3:[0-9]+]]) +// CHECK: ![[L2]] = !DIBasicType(tag: DW_TAG_unspecified_type, name: "void", annotations: ![[L4:[0-9]+]]) +// CHECK: ![[L4]] = !{![[L5:[0-9]+]]} +// CHECK: ![[L5]] = !{!"btf_type_tag:v2", !"tag1"} +// CHECK: ![[L3]] = !{![[L6:[0-9]+]]} +// CHECK: ![[L6]] = !{!"btf_type_tag", !"tag1"} diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h --- a/llvm/lib/Target/BPF/BTFDebug.h +++ b/llvm/lib/Target/BPF/BTFDebug.h @@ -14,13 +14,14 @@ #ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H #define LLVM_LIB_TARGET_BPF_BTFDEBUG_H +#include "BTF.h" +#include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringMap.h" #include "llvm/CodeGen/DebugHandlerBase.h" #include #include #include #include -#include "BTF.h" namespace llvm { @@ -285,6 +286,27 @@ uint32_t RelocKind; ///< What to patch the instruction }; +struct BTFTypeDedupKey { + const dwarf::Tag Kind; + const StringRef Name; + const uint64_t BasicTypeRepr; + + BTFTypeDedupKey(dwarf::Tag Kind, StringRef Name, uint64_t BasicTypeRepr) + : Kind(Kind), Name(Name), BasicTypeRepr(BasicTypeRepr) {} + + bool operator==(const BTFTypeDedupKey &Other) const { + return Kind == Other.Kind && Name == Other.Name && + BasicTypeRepr == Other.BasicTypeRepr; + } + + struct Hash { + size_t operator()(BTFTypeDedupKey const &Key) const { + return hash_combine(hash_value(Key.Kind), hash_value(Key.Name), + hash_value(Key.BasicTypeRepr)); + } + }; +}; + /// Collect and emit BTF information. class BTFDebug : public DebugHandlerBase { MCStreamer &OS; @@ -296,6 +318,8 @@ BTFStringTable StringTable; std::vector> TypeEntries; std::unordered_map DIToIdMap; + std::unordered_map + DIDedupMap; std::map> FuncInfoTable; std::map> LineInfoTable; std::map> FieldRelocTable; @@ -311,11 +335,14 @@ /// Add types to TypeEntries. /// @{ /// Add types to TypeEntries and DIToIdMap. - uint32_t addType(std::unique_ptr TypeEntry, const DIType *Ty); + uint32_t addType(std::unique_ptr TypeEntry, const DIType *Ty, + uint32_t *RealId = nullptr); /// Add types to TypeEntries only and return type id. uint32_t addType(std::unique_ptr TypeEntry); /// @} + std::optional lookupType(const DIType *Ty); + /// IR type visiting functions. /// @{ void visitTypeEntry(const DIType *Ty); @@ -365,7 +392,7 @@ /// the base type of DTy. Return the type id of the first BTF type_tag /// in the chain. If no type_tag's are generated, a negative value /// is returned. - int genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId); + uint32_t genBTFTypeTags(const DIType *Ty, uint32_t BaseId); /// Generate one field relocation record. void generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId, diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -510,13 +510,89 @@ addString("\0"); } +static DINodeArray lookupAnnotations(const DIType *Ty) { + DINodeArray Annots = {}; + if (auto *SubTy = dyn_cast(Ty)) + Annots = SubTy->getAnnotations(); + else if (auto *SubTy = dyn_cast(Ty)) + Annots = SubTy->getAnnotations(); + else if (auto *SubTy = dyn_cast(Ty)) + Annots = SubTy->getAnnotations(); + else if (auto *SubTy = dyn_cast(Ty)) + Annots = SubTy->getAnnotations(); + return Annots; +} + +static void collectBTFTypeTags(const DIType *Ty, + SmallVectorImpl &Tags) { + DINodeArray Annots = lookupAnnotations(Ty); + if (!Annots) + return; + + for (const Metadata *Annotations : Annots->operands()) { + const MDNode *MD = cast(Annotations); + if (MD->getNumOperands() != 2) + continue; + const MDString *Name = dyn_cast(MD->getOperand(0)); + if (!Name) + continue; + if (!Name->getString().equals("btf_type_tag:v2")) + continue; + // For type with "int __tag1 __tag2 *p", the Tags will have + // content: [__tag1, __tag2]. + Tags.push_back(cast(MD->getOperand(1))); + } +} + +/// Generate btf_type_tag chains. +uint32_t BTFDebug::genBTFTypeTags(const DIType *Ty, uint32_t BaseId) { + SmallVector MDStrs; + collectBTFTypeTags(Ty, MDStrs); + // With MDStrs [__tag1, __tag2], the output type chain looks like + // PTR -> __tag2 -> __tag1 -> BaseType + // In the below, we construct BTF types with the order of __tag1, __tag2 + // and PTR. + for (unsigned I = 0; I < MDStrs.size(); I++) { + const MDString *Value = MDStrs[I]; + auto TagEntry = + std::make_unique(BaseId, Value->getString()); + BaseId = addType(std::move(TagEntry)); + } + return BaseId; +} + +static std::optional makeDedupKey(const DIType *Ty) { + if (Ty->getName().empty()) + return std::nullopt; + + if (auto *BTy = dyn_cast(Ty)) { + uint32_t Repr = BTy->getEncoding() << 24 | BTy->getOffsetInBits() << 16 | + BTy->getSizeInBits(); + return std::optional(BTFTypeDedupKey(Ty->getTag(), Ty->getName(), Repr)); + } + + switch (Ty->getTag()) { + case dwarf::Tag::DW_TAG_enumeration_type: + case dwarf::Tag::DW_TAG_structure_type: + case dwarf::Tag::DW_TAG_union_type: + case dwarf::Tag::DW_TAG_typedef: + return std::optional(BTFTypeDedupKey(Ty->getTag(), Ty->getName(), 0)); + default: + return std::nullopt; + } +} + uint32_t BTFDebug::addType(std::unique_ptr TypeEntry, - const DIType *Ty) { - TypeEntry->setId(TypeEntries.size() + 1); - uint32_t Id = TypeEntry->getId(); - DIToIdMap[Ty] = Id; - TypeEntries.push_back(std::move(TypeEntry)); - return Id; + const DIType *Ty, uint32_t *RealId) { + uint32_t Id = TypeEntry ? addType(std::move(TypeEntry)) : 0; + auto Key = makeDedupKey(Ty); + if (Key.has_value()) + DIDedupMap[*Key] = Id; + uint32_t TagId = genBTFTypeTags(Ty, Id); + DIToIdMap[Ty] = TagId; + if (RealId) + *RealId = Id; + return TagId; } uint32_t BTFDebug::addType(std::unique_ptr TypeEntry) { @@ -526,7 +602,30 @@ return Id; } +std::optional BTFDebug::lookupType(const DIType *Ty) { + if (DIToIdMap.find(Ty) != DIToIdMap.end()) + return std::optional(DIToIdMap[Ty]); + + auto Key = makeDedupKey(Ty); + if (!Key.has_value() || (DIDedupMap.find(*Key) == DIDedupMap.end())) + return std::nullopt; + + SmallVector MDStrs; + collectBTFTypeTags(Ty, MDStrs); + auto TagId = genBTFTypeTags(Ty, DIDedupMap[*Key]); + DIToIdMap[Ty] = TagId; + return TagId; +} + void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) { + // Such "void" entries might arise from use btf_type_tag, e.g.: + // void __attribute__((btf_type_tag("foo"))) *p; + if (BTy->getTag() == dwarf::DW_TAG_unspecified_type && + BTy->getName() == "void") { + TypeId = addType(nullptr, BTy); + return; + } + // Only int and binary floating point types are supported in BTF. uint32_t Encoding = BTy->getEncoding(); std::unique_ptr TypeEntry; @@ -616,46 +715,6 @@ return FuncId; } -/// Generate btf_type_tag chains. -int BTFDebug::genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId) { - SmallVector MDStrs; - DINodeArray Annots = DTy->getAnnotations(); - if (Annots) { - // For type with "int __tag1 __tag2 *p", the MDStrs will have - // content: [__tag1, __tag2]. - for (const Metadata *Annotations : Annots->operands()) { - const MDNode *MD = cast(Annotations); - const MDString *Name = cast(MD->getOperand(0)); - if (!Name->getString().equals("btf_type_tag")) - continue; - MDStrs.push_back(cast(MD->getOperand(1))); - } - } - - if (MDStrs.size() == 0) - return -1; - - // With MDStrs [__tag1, __tag2], the output type chain looks like - // PTR -> __tag2 -> __tag1 -> BaseType - // In the below, we construct BTF types with the order of __tag1, __tag2 - // and PTR. - unsigned TmpTypeId; - std::unique_ptr TypeEntry; - if (BaseTypeId >= 0) - TypeEntry = - std::make_unique(BaseTypeId, MDStrs[0]->getString()); - else - TypeEntry = std::make_unique(DTy, MDStrs[0]->getString()); - TmpTypeId = addType(std::move(TypeEntry)); - - for (unsigned I = 1; I < MDStrs.size(); I++) { - const MDString *Value = MDStrs[I]; - TypeEntry = std::make_unique(TmpTypeId, Value->getString()); - TmpTypeId = addType(std::move(TypeEntry)); - } - return TmpTypeId; -} - /// Handle structure/union types. void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct, uint32_t &TypeId) { @@ -677,17 +736,18 @@ auto TypeEntry = std::make_unique(CTy, IsStruct, HasBitField, VLen); StructTypes.push_back(TypeEntry.get()); - TypeId = addType(std::move(TypeEntry), CTy); + uint32_t StructId; + TypeId = addType(std::move(TypeEntry), CTy, &StructId); // Check struct/union annotations - processDeclAnnotations(CTy->getAnnotations(), TypeId, -1); + processDeclAnnotations(CTy->getAnnotations(), StructId, -1); // Visit all struct members. int FieldNo = 0; for (const auto *Element : Elements) { const auto Elem = cast(Element); visitTypeEntry(Elem); - processDeclAnnotations(Elem->getAnnotations(), TypeId, FieldNo); + processDeclAnnotations(Elem->getAnnotations(), StructId, FieldNo); FieldNo++; } } @@ -814,19 +874,9 @@ } } - if (Tag == dwarf::DW_TAG_pointer_type) { - int TmpTypeId = genBTFTypeTags(DTy, -1); - if (TmpTypeId >= 0) { - auto TypeDEntry = - std::make_unique(TmpTypeId, Tag, DTy->getName()); - TypeId = addType(std::move(TypeDEntry), DTy); - } else { - auto TypeEntry = std::make_unique(DTy, Tag, false); - TypeId = addType(std::move(TypeEntry), DTy); - } - } else if (Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type || - Tag == dwarf::DW_TAG_volatile_type || - Tag == dwarf::DW_TAG_restrict_type) { + if (Tag == dwarf::DW_TAG_pointer_type || Tag == dwarf::DW_TAG_typedef || + Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type || + Tag == dwarf::DW_TAG_restrict_type) { auto TypeEntry = std::make_unique(DTy, Tag, false); TypeId = addType(std::move(TypeEntry), DTy); if (Tag == dwarf::DW_TAG_typedef) @@ -846,8 +896,13 @@ void BTFDebug::visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer, bool SeenPointer) { - if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) { + if (!Ty) { TypeId = DIToIdMap[Ty]; + return; + } + + if (auto OptTypeId = lookupType(Ty)) { + TypeId = *OptTypeId; // To handle the case like the following: // struct t; @@ -878,14 +933,14 @@ // We will traverse const/ptr/volatile which already have corresponding // BTF types and generate type for 'struct' which might be in Fixup // state. - if (Ty && (!CheckPointer || !SeenPointer)) { + if (!CheckPointer || !SeenPointer) { if (const auto *DTy = dyn_cast(Ty)) { while (DTy) { const DIType *BaseTy = DTy->getBaseType(); if (!BaseTy) break; - if (DIToIdMap.find(BaseTy) != DIToIdMap.end()) { + if (lookupType(BaseTy)) { DTy = dyn_cast(BaseTy); } else { uint32_t TmpTypeId; @@ -1579,27 +1634,17 @@ // Search through struct types uint32_t StructTypeId = 0; - for (const auto &StructType : StructTypes) { - if (StructType->getName() == TypeName) { - StructTypeId = StructType->getId(); - break; - } - } + if (auto OptId = lookupType(CTy)) + StructTypeId = *OptId; if (StructTypeId == 0) { auto FwdTypeEntry = std::make_unique(TypeName, IsUnion); - StructTypeId = addType(std::move(FwdTypeEntry)); + StructTypeId = addType(std::move(FwdTypeEntry), CTy); } for (auto &TypeInfo : Fixup.second) { - const DIDerivedType *DTy = TypeInfo.first; BTFTypeDerived *BDType = TypeInfo.second; - - int TmpTypeId = genBTFTypeTags(DTy, StructTypeId); - if (TmpTypeId >= 0) - BDType->setPointeeType(TmpTypeId); - else - BDType->setPointeeType(StructTypeId); + BDType->setPointeeType(StructTypeId); } } diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-enum.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-enum.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-enum.ll @@ -0,0 +1,118 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; enum foo { FOO }; +; +; struct bar { +; enum foo __tag1 aa; +; enum foo __tag2 bb; +; enum foo cc; +; }; +; +; void root(struct bar *bar) {} +; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @root(ptr noundef %bar) #0 !dbg !15 { +entry: + %bar.addr = alloca ptr, align 8 + store ptr %bar, ptr %bar.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %bar.addr, metadata !31, metadata !DIExpression()), !dbg !32 + ret void, !dbg !33 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!7, !8, !9, !10, !11, !12, !13} +!llvm.ident = !{!14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") +!2 = !{!3} +!3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "foo", file: !1, line: 4, baseType: !4, size: 32, elements: !5) +!4 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!5 = !{!6} +!6 = !DIEnumerator(name: "FOO", value: 0) +!7 = !{i32 7, !"Dwarf Version", i32 5} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 8, !"PIC Level", i32 2} +!11 = !{i32 7, !"PIE Level", i32 2} +!12 = !{i32 7, !"uwtable", i32 2} +!13 = !{i32 7, !"frame-pointer", i32 2} +!14 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)"} +!15 = distinct !DISubprogram(name: "root", scope: !1, file: !1, line: 12, type: !16, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !30) +!16 = !DISubroutineType(types: !17) +!17 = !{null, !18} +!18 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: !1, line: 6, size: 96, elements: !20) +!20 = !{!21, !25, !29} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: !19, file: !1, line: 7, baseType: !22, size: 32) +!22 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "foo", file: !1, line: 4, baseType: !4, size: 32, elements: !5, annotations: !23) +!23 = !{!24} +!24 = !{!"btf_type_tag:v2", !"tag1"} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "bb", scope: !19, file: !1, line: 8, baseType: !26, size: 32, offset: 32) +!26 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "foo", file: !1, line: 4, baseType: !4, size: 32, elements: !5, annotations: !27) +!27 = !{!28} +!28 = !{!"btf_type_tag:v2", !"tag2"} +!29 = !DIDerivedType(tag: DW_TAG_member, name: "cc", scope: !19, file: !1, line: 9, baseType: !3, size: 32, offset: 64) +!30 = !{} +!31 = !DILocalVariable(name: "bar", arg: 1, scope: !15, file: !1, line: 12, type: !18) +!32 = !DILocation(line: 12, column: 23, scope: !15) +!33 = !DILocation(line: 12, column: 29, scope: !15) + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .long 14 # BTF_KIND_ENUM(id = 4) +; CHECK-NEXT: .long 100663297 # 0x6000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 18 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 22 # BTF_KIND_TYPE_TAG(id = 5) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 27 # BTF_KIND_TYPE_TAG(id = 6) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # BTF_KIND_FUNC(id = 7) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "bar" # string offset=1 +; CHECK: .ascii "aa" # string offset=5 +; CHECK: .ascii "bb" # string offset=8 +; CHECK: .ascii "cc" # string offset=11 +; CHECK: .ascii "foo" # string offset=14 +; CHECK: .ascii "FOO" # string offset=18 +; CHECK: .ascii "tag1" # string offset=22 +; CHECK: .ascii "tag2" # string offset=27 +; CHECK: .ascii "root" # string offset=32 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-struct.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-struct.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-struct.ll @@ -0,0 +1,111 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; struct foo {}; +; +; struct bar { +; struct foo __tag1 aa; +; struct foo __tag2 bb; +; struct foo cc; +; }; +; +; void root(struct bar *bar) {} +; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @root(ptr noundef %bar) #0 !dbg !10 { +entry: + %bar.addr = alloca ptr, align 8 + store ptr %bar, ptr %bar.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %bar.addr, metadata !27, metadata !DIExpression()), !dbg !28 + ret void, !dbg !29 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 8, !"PIC Level", i32 2} +!6 = !{i32 7, !"PIE Level", i32 2} +!7 = !{i32 7, !"uwtable", i32 2} +!8 = !{i32 7, !"frame-pointer", i32 2} +!9 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)"} +!10 = distinct !DISubprogram(name: "root", scope: !1, file: !1, line: 12, type: !11, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !13} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: !1, line: 6, elements: !15) +!15 = !{!16, !21, !25} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: !14, file: !1, line: 7, baseType: !17) +!17 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, elements: !18, annotations: !19) +!18 = !{} +!19 = !{!20} +!20 = !{!"btf_type_tag:v2", !"tag1"} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "bb", scope: !14, file: !1, line: 8, baseType: !22) +!22 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, elements: !18, annotations: !23) +!23 = !{!24} +!24 = !{!"btf_type_tag:v2", !"tag2"} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "cc", scope: !14, file: !1, line: 9, baseType: !26) +!26 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, elements: !18) +!27 = !DILocalVariable(name: "bar", arg: 1, scope: !10, file: !1, line: 12, type: !13) +!28 = !DILocation(line: 12, column: 23, scope: !10) +!29 = !DILocation(line: 12, column: 29, scope: !10) + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 14 # BTF_KIND_STRUCT(id = 4) +; CHECK-NEXT: .long 67108864 # 0x4000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 18 # BTF_KIND_TYPE_TAG(id = 5) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 # BTF_KIND_TYPE_TAG(id = 6) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 28 # BTF_KIND_FUNC(id = 7) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "bar" # string offset=1 +; CHECK: .ascii "aa" # string offset=5 +; CHECK: .ascii "bb" # string offset=8 +; CHECK: .ascii "cc" # string offset=11 +; CHECK: .ascii "foo" # string offset=14 +; CHECK: .ascii "tag1" # string offset=18 +; CHECK: .ascii "tag2" # string offset=23 +; CHECK: .ascii "root" # string offset=28 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-typedef.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-typedef.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-typedef.ll @@ -0,0 +1,117 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; typedef int foo; +; +; struct bar { +; foo __tag1 aa; +; foo __tag2 bb; +; foo cc; +; }; +; +; void root(struct bar *bar) {} +; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @root(ptr noundef %bar) #0 !dbg !10 { +entry: + %bar.addr = alloca ptr, align 8 + store ptr %bar, ptr %bar.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %bar.addr, metadata !28, metadata !DIExpression()), !dbg !29 + ret void, !dbg !30 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 8, !"PIC Level", i32 2} +!6 = !{i32 7, !"PIE Level", i32 2} +!7 = !{i32 7, !"uwtable", i32 2} +!8 = !{i32 7, !"frame-pointer", i32 2} +!9 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)"} +!10 = distinct !DISubprogram(name: "root", scope: !1, file: !1, line: 12, type: !11, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !27) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !13} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: !1, line: 6, size: 96, elements: !15) +!15 = !{!16, !21, !25} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: !14, file: !1, line: 7, baseType: !17, size: 32) +!17 = !DIDerivedType(tag: DW_TAG_typedef, name: "foo", file: !1, line: 4, baseType: !18, annotations: !19) +!18 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!19 = !{!20} +!20 = !{!"btf_type_tag:v2", !"tag1"} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "bb", scope: !14, file: !1, line: 8, baseType: !22, size: 32, offset: 32) +!22 = !DIDerivedType(tag: DW_TAG_typedef, name: "foo", file: !1, line: 4, baseType: !18, annotations: !23) +!23 = !{!24} +!24 = !{!"btf_type_tag:v2", !"tag2"} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "cc", scope: !14, file: !1, line: 9, baseType: !26, size: 32, offset: 64) +!26 = !DIDerivedType(tag: DW_TAG_typedef, name: "foo", file: !1, line: 4, baseType: !18) +!27 = !{} +!28 = !DILocalVariable(name: "bar", arg: 1, scope: !10, file: !1, line: 12, type: !13) +!29 = !DILocation(line: 12, column: 23, scope: !10) +!30 = !DILocation(line: 12, column: 29, scope: !10) + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .long 14 # BTF_KIND_TYPEDEF(id = 4) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 18 # BTF_KIND_TYPE_TAG(id = 5) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 27 # BTF_KIND_TYPE_TAG(id = 7) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # BTF_KIND_FUNC(id = 8) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "bar" # string offset=1 +; CHECK: .ascii "aa" # string offset=5 +; CHECK: .ascii "bb" # string offset=8 +; CHECK: .ascii "cc" # string offset=11 +; CHECK: .ascii "foo" # string offset=14 +; CHECK: .ascii "tag1" # string offset=18 +; CHECK: .ascii "int" # string offset=23 +; CHECK: .ascii "tag2" # string offset=27 +; CHECK: .ascii "root" # string offset=32 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-union.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-union.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-dedup-union.ll @@ -0,0 +1,111 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; #define __tag2 __attribute__((btf_type_tag("tag2"))) +; +; union foo {}; +; +; struct bar { +; union foo __tag1 aa; +; union foo __tag2 bb; +; union foo cc; +; }; +; +; void root(struct bar *bar) {} +; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @root(ptr noundef %bar) #0 !dbg !10 { +entry: + %bar.addr = alloca ptr, align 8 + store ptr %bar, ptr %bar.addr, align 8 + call void @llvm.dbg.declare(metadata ptr %bar.addr, metadata !27, metadata !DIExpression()), !dbg !28 + ret void, !dbg !29 +} + +; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none) +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } +attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8} +!llvm.ident = !{!9} + +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 8, !"PIC Level", i32 2} +!6 = !{i32 7, !"PIE Level", i32 2} +!7 = !{i32 7, !"uwtable", i32 2} +!8 = !{i32 7, !"frame-pointer", i32 2} +!9 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git a90f030ce8ad757f5e5e122774569b00a5df0ae3)"} +!10 = distinct !DISubprogram(name: "root", scope: !1, file: !1, line: 12, type: !11, scopeLine: 12, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +!11 = !DISubroutineType(types: !12) +!12 = !{null, !13} +!13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !14, size: 64) +!14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "bar", file: !1, line: 6, elements: !15) +!15 = !{!16, !21, !25} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "aa", scope: !14, file: !1, line: 7, baseType: !17) +!17 = !DICompositeType(tag: DW_TAG_union_type, name: "foo", file: !1, line: 4, elements: !18, annotations: !19) +!18 = !{} +!19 = !{!20} +!20 = !{!"btf_type_tag:v2", !"tag1"} +!21 = !DIDerivedType(tag: DW_TAG_member, name: "bb", scope: !14, file: !1, line: 8, baseType: !22) +!22 = !DICompositeType(tag: DW_TAG_union_type, name: "foo", file: !1, line: 4, elements: !18, annotations: !23) +!23 = !{!24} +!24 = !{!"btf_type_tag:v2", !"tag2"} +!25 = !DIDerivedType(tag: DW_TAG_member, name: "cc", scope: !14, file: !1, line: 9, baseType: !26) +!26 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "foo", file: !1, line: 4, elements: !18) +!27 = !DILocalVariable(name: "bar", arg: 1, scope: !10, file: !1, line: 12, type: !13) +!28 = !DILocation(line: 12, column: 23, scope: !10) +!29 = !DILocation(line: 12, column: 29, scope: !10) + +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 14 # BTF_KIND_UNION(id = 4) +; CHECK-NEXT: .long 83886080 # 0x5000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 18 # BTF_KIND_TYPE_TAG(id = 5) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 23 # BTF_KIND_TYPE_TAG(id = 6) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 28 # BTF_KIND_FUNC(id = 7) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "bar" # string offset=1 +; CHECK: .ascii "aa" # string offset=5 +; CHECK: .ascii "bb" # string offset=8 +; CHECK: .ascii "cc" # string offset=11 +; CHECK: .ascii "foo" # string offset=14 +; CHECK: .ascii "tag1" # string offset=18 +; CHECK: .ascii "tag2" # string offset=23 +; CHECK: .ascii "root" # string offset=28 diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll --- a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-fwd.ll @@ -18,81 +18,78 @@ ; Compilation flag: ; clang -target bpf -O2 -g -S -emit-llvm test.c -%struct.map_value = type { %struct.foo* } -%struct.foo = type opaque +%struct.map_value = type { ptr } ; Function Attrs: nounwind define dso_local void @test() local_unnamed_addr #0 !dbg !7 { entry: %v = alloca %struct.map_value, align 8 - %0 = bitcast %struct.map_value* %v to i8*, !dbg !20 - call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !20 - call void @llvm.dbg.declare(metadata %struct.map_value* %v, metadata !11, metadata !DIExpression()), !dbg !21 - %1 = bitcast %struct.map_value* %v to i64*, !dbg !21 - store i64 0, i64* %1, align 8, !dbg !21 - call void @func(%struct.map_value* noundef nonnull %v) #4, !dbg !22 - call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #4, !dbg !23 - ret void, !dbg !23 + call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %v) #4, !dbg !23 + call void @llvm.dbg.declare(metadata ptr %v, metadata !11, metadata !DIExpression()), !dbg !24 + store i64 0, ptr %v, align 8, !dbg !24 + call void @func(ptr noundef nonnull %v) #4, !dbg !25 + call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %v) #4, !dbg !26 + ret void, !dbg !26 } -; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) -; CHECK-NEXT: .long 218103808 # 0xd000000 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) -; CHECK-NEXT: .long 201326593 # 0xc000001 -; CHECK-NEXT: .long 1 -; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) -; CHECK-NEXT: .long 218103809 # 0xd000001 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 5 -; CHECK-NEXT: .long 62 # BTF_KIND_STRUCT(id = 5) -; CHECK-NEXT: .long 67108865 # 0x4000001 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 72 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 0 # 0x0 -; CHECK-NEXT: .long 76 # BTF_KIND_TYPE_TAG(id = 6) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 9 -; CHECK-NEXT: .long 81 # BTF_KIND_TYPE_TAG(id = 7) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 6 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 8) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 7 -; CHECK-NEXT: .long 86 # BTF_KIND_FWD(id = 9) -; CHECK-NEXT: .long 117440512 # 0x7000000 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 90 # BTF_KIND_FUNC(id = 10) -; CHECK-NEXT: .long 201326594 # 0xc000002 -; CHECK-NEXT: .long 3 +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) +; CHECK-NEXT: .long 218103809 # 0xd000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 35 # BTF_KIND_STRUCT(id = 5) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 6) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 49 # BTF_KIND_FWD(id = 7) +; CHECK-NEXT: .long 117440512 # 0x7000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 53 # BTF_KIND_TYPE_TAG(id = 8) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 58 # BTF_KIND_TYPE_TAG(id = 9) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 63 # BTF_KIND_FUNC(id = 10) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 3 -; CHECK: .ascii "test" # string offset=1 -; CHECK: .ascii "map_value" # string offset=62 -; CHECK: .ascii "ptr" # string offset=72 -; CHECK: .ascii "tag2" # string offset=76 -; CHECK: .ascii "tag1" # string offset=81 -; CHECK: .ascii "foo" # string offset=86 -; CHECK: .ascii "func" # string offset=90 +; CHECK: .ascii "test" # string offset=1 +; CHECK: .ascii "map_value" # string offset=35 +; CHECK: .ascii "ptr" # string offset=45 +; CHECK: .ascii "foo" # string offset=49 +; CHECK: .ascii "tag2" # string offset=53 +; CHECK: .ascii "tag1" # string offset=58 +; CHECK: .ascii "func" # string offset=63 -; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn -declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1 -; Function Attrs: mustprogress nofree nosync nounwind readnone speculatable willreturn +; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 -declare !dbg !24 dso_local void @func(%struct.map_value* noundef) local_unnamed_addr #3 +declare !dbg !27 dso_local void @func(ptr noundef) local_unnamed_addr #3 -; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn -declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1 -attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -attributes #1 = { argmemonly mustprogress nofree nosync nounwind willreturn } -attributes #2 = { mustprogress nofree nosync nounwind readnone speculatable willreturn } +attributes #0 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +attributes #2 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) } attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } attributes #4 = { nounwind } @@ -100,13 +97,13 @@ !llvm.module.flags = !{!2, !3, !4, !5} !llvm.ident = !{!6} -!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag_type", checksumkind: CSK_MD5, checksum: "7735a89e98603fee29d352a8e9db5acb") +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !4 = !{i32 1, !"wchar_size", i32 4} !5 = !{i32 7, !"frame-pointer", i32 2} -!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)"} +!6 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)"} !7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 9, type: !8, scopeLine: 10, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) !8 = !DISubroutineType(types: !9) !9 = !{null} @@ -115,17 +112,21 @@ !12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: !1, line: 5, size: 64, elements: !13) !13 = !{!14} !14 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !12, file: !1, line: 6, baseType: !15, size: 64) -!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !17) -!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, flags: DIFlagFwdDecl) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !20) +!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, flags: DIFlagFwdDecl, annotations: !17) !17 = !{!18, !19} -!18 = !{!"btf_type_tag", !"tag2"} -!19 = !{!"btf_type_tag", !"tag1"} -!20 = !DILocation(line: 11, column: 9, scope: !7) -!21 = !DILocation(line: 11, column: 26, scope: !7) -!22 = !DILocation(line: 12, column: 9, scope: !7) -!23 = !DILocation(line: 13, column: 1, scope: !7) -!24 = !DISubprogram(name: "func", scope: !1, file: !1, line: 8, type: !25, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !28) -!25 = !DISubroutineType(types: !26) -!26 = !{null, !27} -!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) -!28 = !{} +!18 = !{!"btf_type_tag:v2", !"tag2"} +!19 = !{!"btf_type_tag:v2", !"tag1"} +!20 = !{!21, !22} +!21 = !{!"btf_type_tag", !"tag2"} +!22 = !{!"btf_type_tag", !"tag1"} +!23 = !DILocation(line: 11, column: 9, scope: !7) +!24 = !DILocation(line: 11, column: 26, scope: !7) +!25 = !DILocation(line: 12, column: 9, scope: !7) +!26 = !DILocation(line: 13, column: 1, scope: !7) +!27 = !DISubprogram(name: "func", scope: !1, file: !1, line: 8, type: !28, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !31) +!28 = !DISubroutineType(types: !29) +!29 = !{null, !30} +!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!31 = !{!32} +!32 = !DILocalVariable(arg: 1, scope: !27, file: !1, line: 8, type: !30) diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll --- a/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-fixup-resolved.ll @@ -20,95 +20,92 @@ ; Compilation flag: ; clang -target bpf -O2 -g -S -emit-llvm test.c -%struct.map_value = type { %struct.foo* } -%struct.foo = type { i32 } +%struct.map_value = type { ptr } ; Function Attrs: nounwind define dso_local void @test() local_unnamed_addr #0 !dbg !7 { entry: %v = alloca %struct.map_value, align 8 - %0 = bitcast %struct.map_value* %v to i8*, !dbg !23 - call void @llvm.lifetime.start.p0i8(i64 8, i8* nonnull %0) #4, !dbg !23 - call void @llvm.dbg.declare(metadata %struct.map_value* %v, metadata !11, metadata !DIExpression()), !dbg !24 - %1 = bitcast %struct.map_value* %v to i64*, !dbg !24 - store i64 0, i64* %1, align 8, !dbg !24 - call void @func(%struct.map_value* noundef nonnull %v, %struct.foo* noundef null) #4, !dbg !25 - call void @llvm.lifetime.end.p0i8(i64 8, i8* nonnull %0) #4, !dbg !26 - ret void, !dbg !26 + call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %v) #4, !dbg !27 + call void @llvm.dbg.declare(metadata ptr %v, metadata !11, metadata !DIExpression()), !dbg !28 + store i64 0, ptr %v, align 8, !dbg !28 + call void @func(ptr noundef nonnull %v, ptr noundef null) #4, !dbg !29 + call void @llvm.lifetime.end.p0(i64 8, ptr nonnull %v) #4, !dbg !30 + ret void, !dbg !30 } -; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) -; CHECK-NEXT: .long 218103808 # 0xd000000 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) -; CHECK-NEXT: .long 201326593 # 0xc000001 -; CHECK-NEXT: .long 1 -; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) -; CHECK-NEXT: .long 218103810 # 0xd000002 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 0 -; CHECK-NEXT: .long 7 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 5 -; CHECK-NEXT: .long 63 # BTF_KIND_STRUCT(id = 5) -; CHECK-NEXT: .long 67108865 # 0x4000001 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 73 -; CHECK-NEXT: .long 6 -; CHECK-NEXT: .long 0 # 0x0 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 6) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 12 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 7) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 77 # BTF_KIND_STRUCT(id = 8) -; CHECK-NEXT: .long 67108865 # 0x4000001 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 81 -; CHECK-NEXT: .long 9 -; CHECK-NEXT: .long 0 # 0x0 -; CHECK-NEXT: .long 83 # BTF_KIND_INT(id = 9) -; CHECK-NEXT: .long 16777216 # 0x1000000 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 16777248 # 0x1000020 -; CHECK-NEXT: .long 87 # BTF_KIND_FUNC(id = 10) -; CHECK-NEXT: .long 201326594 # 0xc000002 -; CHECK-NEXT: .long 3 -; CHECK-NEXT: .long 92 # BTF_KIND_TYPE_TAG(id = 11) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 8 -; CHECK-NEXT: .long 97 # BTF_KIND_TYPE_TAG(id = 12) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 11 +; CHECK: .long 0 # BTF_KIND_FUNC_PROTO(id = 1) +; CHECK-NEXT: .long 218103808 # 0xd000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC_PROTO(id = 3) +; CHECK-NEXT: .long 218103810 # 0xd000002 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 4) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 35 # BTF_KIND_STRUCT(id = 5) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 6) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 7) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 49 # BTF_KIND_STRUCT(id = 8) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 53 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 0 # 0x0 +; CHECK-NEXT: .long 55 # BTF_KIND_INT(id = 9) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 59 # BTF_KIND_FUNC(id = 10) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 64 # BTF_KIND_TYPE_TAG(id = 11) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 69 # BTF_KIND_TYPE_TAG(id = 12) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 11 -; CHECK: .ascii "test" # string offset=1 -; CHECK: .ascii "map_value" # string offset=63 -; CHECK: .ascii "ptr" # string offset=73 -; CHECK: .ascii "foo" # string offset=77 -; CHECK: .byte 105 # string offset=81 -; CHECK: .ascii "int" # string offset=83 -; CHECK: .ascii "func" # string offset=87 -; CHECK: .ascii "tag2" # string offset=92 -; CHECK: .ascii "tag1" # string offset=97 +; CHECK: .ascii "test" # string offset=1 +; CHECK: .ascii "map_value" # string offset=35 +; CHECK: .ascii "ptr" # string offset=45 +; CHECK: .ascii "foo" # string offset=49 +; CHECK: .byte 105 # string offset=53 +; CHECK: .ascii "int" # string offset=55 +; CHECK: .ascii "func" # string offset=59 +; CHECK: .ascii "tag2" # string offset=64 +; CHECK: .ascii "tag1" # string offset=69 -; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn -declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1 -; Function Attrs: mustprogress nofree nosync nounwind readnone speculatable willreturn +; Function Attrs: mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) declare void @llvm.dbg.declare(metadata, metadata, metadata) #2 -declare !dbg !27 dso_local void @func(%struct.map_value* noundef, %struct.foo* noundef) local_unnamed_addr #3 +declare !dbg !31 dso_local void @func(ptr noundef, ptr noundef) local_unnamed_addr #3 -; Function Attrs: argmemonly mustprogress nofree nosync nounwind willreturn -declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 +; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1 -attributes #0 = { nounwind "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } -attributes #1 = { argmemonly mustprogress nofree nosync nounwind willreturn } -attributes #2 = { mustprogress nofree nosync nounwind readnone speculatable willreturn } +attributes #0 = { nounwind "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } +attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +attributes #2 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) } attributes #3 = { "frame-pointer"="all" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } attributes #4 = { nounwind } @@ -116,13 +113,13 @@ !llvm.module.flags = !{!2, !3, !4, !5} !llvm.ident = !{!6} -!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) -!1 = !DIFile(filename: "test.c", directory: "/tmp//home/yhs/work/tests/llvm/btf_tag_type", checksumkind: CSK_MD5, checksum: "8b3b8281c3b4240403467e0c9461251d") +!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "some-file.c", directory: "/some/dir/") !2 = !{i32 7, !"Dwarf Version", i32 5} !3 = !{i32 2, !"Debug Info Version", i32 3} !4 = !{i32 1, !"wchar_size", i32 4} !5 = !{i32 7, !"frame-pointer", i32 2} -!6 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 25e8505f515bc9ef6c13527ffc4a902bae3a9071)"} +!6 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)"} !7 = distinct !DISubprogram(name: "test", scope: !1, file: !1, line: 11, type: !8, scopeLine: 12, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10) !8 = !DISubroutineType(types: !9) !9 = !{null} @@ -131,21 +128,27 @@ !12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "map_value", file: !1, line: 7, size: 64, elements: !13) !13 = !{!14} !14 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !12, file: !1, line: 8, baseType: !15, size: 64) -!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !20) -!16 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, size: 32, elements: !17) +!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64, annotations: !24) +!16 = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, size: 32, elements: !17, annotations: !21) !17 = !{!18} -!18 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !16, file: !1, line: 5, baseType: !19, size: 32) -!19 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) -!20 = !{!21, !22} -!21 = !{!"btf_type_tag", !"tag2"} -!22 = !{!"btf_type_tag", !"tag1"} -!23 = !DILocation(line: 13, column: 9, scope: !7) -!24 = !DILocation(line: 13, column: 26, scope: !7) -!25 = !DILocation(line: 14, column: 9, scope: !7) -!26 = !DILocation(line: 15, column: 1, scope: !7) -!27 = !DISubprogram(name: "func", scope: !1, file: !1, line: 10, type: !28, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !32) -!28 = !DISubroutineType(types: !29) -!29 = !{null, !30, !31} -!30 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) -!31 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 64) -!32 = !{} +!18 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !19, file: !1, line: 5, baseType: !20, size: 32) +!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", file: !1, line: 4, size: 32, elements: !17) +!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!21 = !{!22, !23} +!22 = !{!"btf_type_tag:v2", !"tag2"} +!23 = !{!"btf_type_tag:v2", !"tag1"} +!24 = !{!25, !26} +!25 = !{!"btf_type_tag", !"tag2"} +!26 = !{!"btf_type_tag", !"tag1"} +!27 = !DILocation(line: 13, column: 9, scope: !7) +!28 = !DILocation(line: 13, column: 26, scope: !7) +!29 = !DILocation(line: 14, column: 9, scope: !7) +!30 = !DILocation(line: 15, column: 1, scope: !7) +!31 = !DISubprogram(name: "func", scope: !1, file: !1, line: 10, type: !32, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !36) +!32 = !DISubroutineType(types: !33) +!33 = !{null, !34, !35} +!34 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!35 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64) +!36 = !{!37, !38} +!37 = !DILocalVariable(arg: 1, scope: !31, file: !1, line: 10, type: !34) +!38 = !DILocalVariable(arg: 2, scope: !31, file: !1, line: 10, type: !35) diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-var.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-var.ll --- a/llvm/test/CodeGen/BPF/BTF/type-tag-var.ll +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-var.ll @@ -11,53 +11,62 @@ @g = dso_local local_unnamed_addr global ptr null, align 8, !dbg !0 !llvm.dbg.cu = !{!2} -!llvm.module.flags = !{!12, !13, !14, !15} -!llvm.ident = !{!16} +!llvm.module.flags = !{!15, !16, !17, !18} +!llvm.ident = !{!19} !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) !1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 3, type: !5, isLocal: false, isDefinition: true) -!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 14.0.0 (https://github.com/llvm/llvm-project.git 077b2e0cf1e97c4d97ca5ceab3ec0192ed11c66e)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) -!3 = !DIFile(filename: "test.c", directory: "/tmp/home/yhs/work/tests/llvm/btf_tag_type") +!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/eddy/work/tmp", checksumkind: CSK_MD5, checksum: "9ae91fe3dd8e44985841816e35923786") !4 = !{!0} -!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, annotations: !10) -!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, annotations: !8) -!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, annotations: !13) +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, annotations: !10) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed, annotations: !8) !8 = !{!9} -!9 = !{!"btf_type_tag", !"tag1"} -!10 = !{!9, !11} -!11 = !{!"btf_type_tag", !"tag2"} +!9 = !{!"btf_type_tag:v2", !"tag1"} +!10 = !{!9, !11, !12} +!11 = !{!"btf_type_tag:v2", !"tag2"} +!12 = !{!"btf_type_tag", !"tag1"} +!13 = !{!12, !14} +!14 = !{!"btf_type_tag", !"tag2"} -; CHECK: .long 1 # BTF_KIND_TYPE_TAG(id = 1) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 5 -; CHECK-NEXT: .long 6 # BTF_KIND_TYPE_TAG(id = 2) -; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 1 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 3) +; CHECK: .long 0 # BTF_KIND_PTR(id = 1) ; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 3) +; CHECK-NEXT: .long 301989888 # 0x12000000 ; CHECK-NEXT: .long 2 -; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 4) +; CHECK-NEXT: .long 6 # BTF_KIND_TYPE_TAG(id = 4) ; CHECK-NEXT: .long 301989888 # 0x12000000 -; CHECK-NEXT: .long 6 -; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 5) -; CHECK-NEXT: .long 33554432 # 0x2000000 -; CHECK-NEXT: .long 4 -; CHECK-NEXT: .long 11 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 11 # BTF_KIND_INT(id = 5) ; CHECK-NEXT: .long 16777216 # 0x1000000 ; CHECK-NEXT: .long 4 ; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 6) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 5 ; CHECK-NEXT: .long 15 # BTF_KIND_VAR(id = 7) ; CHECK-NEXT: .long 234881024 # 0xe000000 -; CHECK-NEXT: .long 3 ; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 17 # BTF_KIND_DATASEC(id = 8) +; CHECK-NEXT: .long 251658241 # 0xf000001 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long g +; CHECK-NEXT: .long 8 ; CHECK: .ascii "tag1" # string offset=1 ; CHECK: .ascii "tag2" # string offset=6 ; CHECK: .ascii "int" # string offset=11 ; CHECK: .byte 103 # string offset=15 -!12 = !{i32 7, !"Dwarf Version", i32 4} -!13 = !{i32 2, !"Debug Info Version", i32 3} -!14 = !{i32 1, !"wchar_size", i32 4} -!15 = !{i32 7, !"frame-pointer", i32 2} -!16 = !{!"clang version 14.0.0 (https://github.com/llvm/llvm-project.git 077b2e0cf1e97c4d97ca5ceab3ec0192ed11c66e)"} +!15 = !{i32 7, !"Dwarf Version", i32 5} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{i32 7, !"frame-pointer", i32 2} +!19 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git 5aa6dd1e09616a455377f3066d2034d3e8a073ba)"} diff --git a/llvm/test/CodeGen/BPF/BTF/type-tag-void.ll b/llvm/test/CodeGen/BPF/BTF/type-tag-void.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/BPF/BTF/type-tag-void.ll @@ -0,0 +1,48 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; +; Source: +; #define __tag1 __attribute__((btf_type_tag("tag1"))) +; void __tag1 *foo; +; Compilation flag: +; clang -S -g -emit-llvm test.c -o test.ll + +@foo = dso_local local_unnamed_addr global ptr null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13, !14, !15, !16} +!llvm.ident = !{!17} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "foo", scope: !2, file: !3, line: 2, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 17.0.0 (https://github.com/llvm/llvm-project.git b0d4d11b535f4c3b730222013f4da5b0cbc4558a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: None) +!3 = !DIFile(filename: "test.c", directory: "/home/eddy/work/tmp", checksumkind: CSK_MD5, checksum: "d51e2505a6f475a2c1811fd5e5fa9c49") +!4 = !{!0} +!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64, annotations: !9) +!6 = !DIBasicType(tag: DW_TAG_unspecified_type, name: "void", annotations: !7) +!7 = !{!8} +!8 = !{!"btf_type_tag:v2", !"tag1"} +!9 = !{!10} +!10 = !{!"btf_type_tag", !"tag1"} +!11 = !{i32 7, !"Dwarf Version", i32 5} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{i32 8, !"PIC Level", i32 2} +!15 = !{i32 7, !"PIE Level", i32 2} +!16 = !{i32 7, !"uwtable", i32 2} +!17 = !{!"clang version 17.0.0 (https://github.com/llvm/llvm-project.git b0d4d11b535f4c3b730222013f4da5b0cbc4558a)"} + +; CHECK: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPE_TAG(id = 2) +; CHECK-NEXT: .long 301989888 # 0x12000000 +; CHECK-NEXT: .long 0 +; ^^^ void type id +; CHECK-NEXT: .long 6 # BTF_KIND_VAR(id = 3) +; CHECK-NEXT: .long 234881024 # 0xe000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 + +; CHECK: .ascii "tag1" # string offset=1 +; CHECK: .ascii "foo" # string offset=6