b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | From 0544c547682b878758eea731ef4b8e64e5ec91fb Mon Sep 17 00:00:00 2001 |
| 2 | From: Luc Van Oostenryck <lucvoo@kernel.org> |
| 3 | Date: Sat, 20 Jan 2024 01:24:12 +0100 |
| 4 | Subject: llvm: fix LLVM 15 deprecation warnings |
| 5 | |
| 6 | LLVM 15 switched to opaque pointers by default and no longer supports typed pointers. |
| 7 | Remove deprecated LLVM calls and update test. |
| 8 | |
| 9 | Original-patch-by: Vladimir Petko <vladimir.petko@canonical.com> |
| 10 | Signed-off-by: Luc Van Oostenryck <lucvoo@kernel.org> |
| 11 | --- |
| 12 | sparse-llvm.c | 35 ++++++++++++++++++++++++++++++++++- |
| 13 | validation/backend/call-variadic.c | 16 ++++------------ |
| 14 | 2 files changed, 38 insertions(+), 13 deletions(-) |
| 15 | |
| 16 | --- a/sparse-llvm.c |
| 17 | +++ b/sparse-llvm.c |
| 18 | @@ -32,6 +32,20 @@ static LLVMTypeRef func_return_type(stru |
| 19 | return symbol_type(sym->ctype.base_type); |
| 20 | } |
| 21 | |
| 22 | +#if LLVM_VERSION_MAJOR > 14 |
| 23 | +// A call can be done either with a SYM_FN or a SYM_PTR (pointing to a SYM_FN). |
| 24 | +// Return the type corresponding to the SYM_FN. |
| 25 | +static LLVMTypeRef func_full_type(struct symbol *type) |
| 26 | +{ |
| 27 | + if (type->type == SYM_NODE) { |
| 28 | + struct symbol *btype = type->ctype.base_type; |
| 29 | + if (btype->type == SYM_PTR) |
| 30 | + type = btype->ctype.base_type; |
| 31 | + } |
| 32 | + return symbol_type(type); |
| 33 | +} |
| 34 | +#endif |
| 35 | + |
| 36 | static LLVMTypeRef sym_func_type(struct symbol *sym) |
| 37 | { |
| 38 | int n_arg = symbol_list_size(sym->arguments); |
| 39 | @@ -302,7 +316,11 @@ static LLVMValueRef get_sym_value(LLVMMo |
| 40 | LLVMSetGlobalConstant(data, 1); |
| 41 | LLVMSetInitializer(data, LLVMConstString(strdup(s), strlen(s) + 1, true)); |
| 42 | |
| 43 | +#if LLVM_VERSION_MAJOR > 14 |
| 44 | + result = LLVMConstGEP2(LLVMTypeOf(data), data, indices, ARRAY_SIZE(indices)); |
| 45 | +#else |
| 46 | result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices)); |
| 47 | +#endif |
| 48 | return result; |
| 49 | } |
| 50 | default: |
| 51 | @@ -485,7 +503,11 @@ static LLVMValueRef calc_gep(LLVMBuilder |
| 52 | /* convert base to char* type */ |
| 53 | base = LLVMBuildPointerCast(builder, base, bytep, name); |
| 54 | /* addr = base + off */ |
| 55 | +#if LLVM_VERSION_MAJOR > 14 |
| 56 | + addr = LLVMBuildInBoundsGEP2(builder, LLVMTypeOf(base), base, &off, 1, name); |
| 57 | +#else |
| 58 | addr = LLVMBuildInBoundsGEP(builder, base, &off, 1, name); |
| 59 | +#endif |
| 60 | /* convert back to the actual pointer type */ |
| 61 | addr = LLVMBuildPointerCast(builder, addr, type, name); |
| 62 | return addr; |
| 63 | @@ -711,7 +733,11 @@ static void output_op_load(struct functi |
| 64 | |
| 65 | /* perform load */ |
| 66 | pseudo_name(insn->target, name); |
| 67 | +#if LLVM_VERSION_MAJOR > 14 |
| 68 | + target = LLVMBuildLoad2(fn->builder, symbol_type(insn->type), addr, name); |
| 69 | +#else |
| 70 | target = LLVMBuildLoad(fn->builder, addr, name); |
| 71 | +#endif |
| 72 | |
| 73 | insn->target->priv = target; |
| 74 | } |
| 75 | @@ -797,6 +823,7 @@ static void output_op_switch(struct func |
| 76 | static void output_op_call(struct function *fn, struct instruction *insn) |
| 77 | { |
| 78 | LLVMValueRef target, func; |
| 79 | + struct symbol *fntype; |
| 80 | struct symbol *ctype; |
| 81 | int n_arg = 0, i; |
| 82 | struct pseudo *arg; |
| 83 | @@ -812,14 +839,20 @@ static void output_op_call(struct functi |
| 84 | else |
| 85 | func = pseudo_to_value(fn, ctype, insn->func); |
| 86 | i = 0; |
| 87 | + fntype = ctype; // first symbol in the list is the function 'true' type |
| 88 | FOR_EACH_PTR(insn->arguments, arg) { |
| 89 | - NEXT_PTR_LIST(ctype); |
| 90 | + NEXT_PTR_LIST(ctype); // the remaining ones are the arguments' type |
| 91 | args[i++] = pseudo_to_rvalue(fn, ctype, arg); |
| 92 | } END_FOR_EACH_PTR(arg); |
| 93 | FINISH_PTR_LIST(ctype); |
| 94 | |
| 95 | pseudo_name(insn->target, name); |
| 96 | +#if LLVM_VERSION_MAJOR > 14 |
| 97 | + target = LLVMBuildCall2(fn->builder, func_full_type(fntype), func, args, n_arg, name); |
| 98 | +#else |
| 99 | + (void) fntype; |
| 100 | target = LLVMBuildCall(fn->builder, func, args, n_arg, name); |
| 101 | +#endif |
| 102 | |
| 103 | insn->target->priv = target; |
| 104 | } |
| 105 | --- a/validation/backend/call-variadic.c |
| 106 | +++ b/validation/backend/call-variadic.c |
| 107 | @@ -11,17 +11,9 @@ int foo(const char *fmt, int a, long l, |
| 108 | /* |
| 109 | * check-name: call-variadic |
| 110 | * check-command: sparse-llvm-dis -m64 $file |
| 111 | + * check-output-ignore |
| 112 | + * check-output-contains: , ...) @print(\\(i8\\*\\|ptr\\) %ARG1., i32 120, i32 %ARG2., i32 8, i64 %ARG3., i64 0, \\(i32\\*\\|ptr\\) %ARG4., \\(i8\\*\\|ptr\\) null) |
| 113 | + * check-output-contains: define i32 @foo( |
| 114 | + * check-output-contains: declare i32 @print( |
| 115 | * |
| 116 | - * check-output-start |
| 117 | -; ModuleID = '<stdin>' |
| 118 | -source_filename = "sparse" |
| 119 | - |
| 120 | -define i32 @foo(i8* %ARG1., i32 %ARG2., i64 %ARG3., i32* %ARG4.) { |
| 121 | -L0: |
| 122 | - %R5. = call i32 (i8*, ...) @print(i8* %ARG1., i32 120, i32 %ARG2., i32 8, i64 %ARG3., i64 0, i32* %ARG4., i8* null) |
| 123 | - ret i32 %R5. |
| 124 | -} |
| 125 | - |
| 126 | -declare i32 @print(i8*, ...) |
| 127 | - * check-output-end |
| 128 | */ |