Skip to content

Commit 176a45a

Browse files
authored
llvm-dimeta issue workaround (#159)
1 parent 31b9af0 commit 176a45a

File tree

2 files changed

+109
-11
lines changed

2 files changed

+109
-11
lines changed

lib/passes/typegen/dimeta/DimetaTypeGen.cpp

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,28 +64,56 @@ std::pair<std::optional<typeart_builtin_type>, int> typeid_if_ptr(const Type& ty
6464
namespace detail {
6565

6666
template <typename Type, typename Func>
67-
auto apply_func(const Type& type, Func&& handle_qualified_type) {
67+
auto apply_function(const Type& type, Func&& handle_qualified_type) {
6868
using namespace dimeta;
6969

7070
if constexpr (std::is_same_v<Type, typename dimeta::QualifiedCompound> ||
7171
std::is_same_v<Type, typename dimeta::QualifiedFundamental>) {
7272
return std::forward<Func>(handle_qualified_type)(type);
7373
} else {
74-
return std::visit(overload{[&](const dimeta::QualifiedFundamental& f) {
75-
return apply_func(f, std::forward<Func>(handle_qualified_type));
76-
},
77-
[&](const dimeta::QualifiedCompound& q) {
78-
return apply_func(q, std::forward<Func>(handle_qualified_type));
79-
}},
80-
type);
74+
return std::visit(
75+
[&](auto&& qualified_type) {
76+
return apply_function(qualified_type, std::forward<Func>(handle_qualified_type));
77+
},
78+
type);
8179
}
8280
}
8381

8482
} // namespace detail
8583

84+
namespace workaround {
85+
void remove_pointer_level(const llvm::AllocaInst* alloc, dimeta::LocatedType& val) {
86+
// If the alloca instruction is not a pointer, but the located_type has a pointer-like qualifier, we remove it.
87+
// Workaround for inlining issue, see test typemapping/05_milc_inline_metadata.c
88+
// TODO Should be removed if dimeta fixes it.
89+
if (!alloc->getAllocatedType()->isPointerTy()) {
90+
LOG_DEBUG("Alloca is not a pointer")
91+
92+
const auto remove_pointer_level = [](auto& qual) {
93+
auto pointer_like_iter = llvm::find_if(qual, [](auto qualifier) {
94+
switch (qualifier) {
95+
case dimeta::Qualifier::kPtr:
96+
case dimeta::Qualifier::kRef:
97+
case dimeta::Qualifier::kPtrToMember:
98+
return true;
99+
default:
100+
break;
101+
}
102+
return false;
103+
});
104+
if (pointer_like_iter != std::end(qual)) {
105+
LOG_DEBUG("Removing pointer level " << static_cast<int>(*pointer_like_iter))
106+
qual.erase(pointer_like_iter);
107+
}
108+
};
109+
std::visit([&](auto&& qualified_type) { remove_pointer_level(qualified_type.qual); }, val.type);
110+
}
111+
}
112+
} // namespace workaround
113+
86114
template <typename Type>
87115
dimeta::ArraySize vector_num_elements(const Type& type) {
88-
return detail::apply_func(type, [](const auto& t) -> dimeta::Extent {
116+
return detail::apply_function(type, [](const auto& t) -> dimeta::Extent {
89117
if (t.is_vector) {
90118
int pos{-1};
91119
// Find kVector tag-position to determine vector size
@@ -110,7 +138,7 @@ dimeta::ArraySize vector_num_elements(const Type& type) {
110138

111139
template <typename Type>
112140
dimeta::ArraySize array_size(const Type& type) {
113-
return detail::apply_func(type, [](const auto& t) -> dimeta::Extent {
141+
return detail::apply_function(type, [](const auto& t) -> dimeta::Extent {
114142
if (t.array_size.size() > 1 || (t.is_vector && t.array_size.size() > 2)) {
115143
LOG_ERROR("Unsupported array size number count > 1 for array type or > 2 for vector")
116144
}
@@ -126,7 +154,7 @@ dimeta::ArraySize array_size(const Type& type) {
126154

127155
template <typename Type>
128156
std::string name_or_typedef_of(const Type& type) {
129-
return detail::apply_func(type, [](const auto& qual_type) {
157+
return detail::apply_function(type, [](const auto& qual_type) {
130158
const bool no_name = qual_type.type.name.empty();
131159
if constexpr (std::is_same_v<Type, typename dimeta::QualifiedCompound>) {
132160
const bool no_identifier = qual_type.type.identifier.empty();
@@ -389,6 +417,7 @@ class DimetaTypeManager final : public TypeIDGenerator {
389417
auto val = dimeta::located_type_for(alloc);
390418
if (val) {
391419
LOG_DEBUG("Registering alloca")
420+
workaround::remove_pointer_level(alloc, val.value());
392421
const auto type_id = getOrRegister(val->type, false);
393422
const auto array_size_val = array_size(val->type);
394423
LOG_DEBUG(array_size_val)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
; RUN: %apply-typeart --typeart-stack=true < %s -S | %filecheck %s
2+
; REQUIRES: llvm-14
3+
4+
; reduced from CAMPICC test/predefined/104_milc_ReproducerError.c
5+
6+
; CHECK-NOT: call void @__typeart_alloc_stack(i8* {{.*}}, i32 1,
7+
8+
define i32 @main() {
9+
entry:
10+
%c = alloca i64, i32 0, align 8
11+
call void @llvm.dbg.value(metadata i64* %c, metadata !18, metadata !DIExpression()), !dbg !32
12+
ret i32 0
13+
}
14+
15+
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
16+
declare void @llvm.dbg.value(metadata, metadata, metadata) #0
17+
18+
attributes #0 = { nofree nosync nounwind readnone speculatable willreturn }
19+
attributes #1 = { argmemonly nofree nosync nounwind willreturn }
20+
21+
!llvm.dbg.cu = !{!0}
22+
!llvm.module.flags = !{!14, !15, !16, !17}
23+
24+
!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.6", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !2, splitDebugInlining: false, nameTableKind: None)
25+
!1 = !DIFile(filename: "milc.c", directory: "tudasc-ta2/build", checksumkind: CSK_MD5, checksum: "fd0b55769b199b4db669ed1dc54da6c6")
26+
!2 = !{!3, !7, !8, !11}
27+
!3 = !DIDerivedType(tag: DW_TAG_typedef, name: "MPI_Datatype", file: !4, line: 424, baseType: !5)
28+
!4 = !DIFile(filename: "/usr/lib/x86_64-linux-gnu/openmpi/include/mpi.h", directory: "", checksumkind: CSK_MD5, checksum: "58b77b3315301c271bf9a6de605bbb3a")
29+
!5 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64)
30+
!6 = !DICompositeType(tag: DW_TAG_structure_type, name: "ompi_datatype_t", file: !4, line: 424, flags: DIFlagFwdDecl)
31+
!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
32+
!8 = !DIDerivedType(tag: DW_TAG_typedef, name: "MPI_Op", file: !4, line: 429, baseType: !9)
33+
!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64)
34+
!10 = !DICompositeType(tag: DW_TAG_structure_type, name: "ompi_op_t", file: !4, line: 429, flags: DIFlagFwdDecl)
35+
!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "MPI_Comm", file: !4, line: 423, baseType: !12)
36+
!12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64)
37+
!13 = !DICompositeType(tag: DW_TAG_structure_type, name: "ompi_communicator_t", file: !4, line: 423, flags: DIFlagFwdDecl)
38+
!14 = !{i32 7, !"Dwarf Version", i32 5}
39+
!15 = !{i32 2, !"Debug Info Version", i32 3}
40+
!16 = !{i32 1, !"wchar_size", i32 4}
41+
!17 = !{i32 7, !"uwtable", i32 1}
42+
!18 = !DILocalVariable(name: "cpt", arg: 1, scope: !19, file: !20, line: 11, type: !23)
43+
!19 = distinct !DISubprogram(name: "g_complexsum", scope: !20, file: !20, line: 11, type: !21, scopeLine: 11, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !30)
44+
!20 = !DIFile(filename: "test/staging/milc.c", directory: "tudasc-ta2", checksumkind: CSK_MD5, checksum: "fd0b55769b199b4db669ed1dc54da6c6")
45+
!21 = !DISubroutineType(types: !22)
46+
!22 = !{null, !23}
47+
!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !24, size: 64)
48+
!24 = !DIDerivedType(tag: DW_TAG_typedef, name: "complex", file: !20, line: 9, baseType: !25)
49+
!25 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !20, line: 6, size: 64, elements: !26)
50+
!26 = !{!27, !29}
51+
!27 = !DIDerivedType(tag: DW_TAG_member, name: "imag", scope: !25, file: !20, line: 7, baseType: !28, size: 32)
52+
!28 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
53+
!29 = !DIDerivedType(tag: DW_TAG_member, name: "real", scope: !25, file: !20, line: 8, baseType: !28, size: 32, offset: 32)
54+
!30 = !{!18, !31}
55+
!31 = !DILocalVariable(name: "work", scope: !19, file: !20, line: 12, type: !24)
56+
!32 = !DILocation(line: 0, scope: !19, inlinedAt: !33)
57+
!33 = distinct !DILocation(line: 24, column: 3, scope: !34)
58+
!34 = distinct !DISubprogram(name: "main", scope: !20, file: !20, line: 17, type: !35, scopeLine: 17, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !41)
59+
!35 = !DISubroutineType(types: !36)
60+
!36 = !{!37, !37, !38}
61+
!37 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
62+
!38 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !39, size: 64)
63+
!39 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !40, size: 64)
64+
!40 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
65+
!41 = !{!42, !43, !44, !45}
66+
!42 = !DILocalVariable(name: "argc", arg: 1, scope: !34, file: !20, line: 17, type: !37)
67+
!43 = !DILocalVariable(name: "argv", arg: 2, scope: !34, file: !20, line: 17, type: !38)
68+
!44 = !DILocalVariable(name: "rank", scope: !34, file: !20, line: 19, type: !37)
69+
!45 = !DILocalVariable(name: "c", scope: !34, file: !20, line: 23, type: !24)

0 commit comments

Comments
 (0)