From 453d7af76abaef3de7934bf7159443103cc56f6b Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sat, 20 Jan 2024 01:24:12 +0100 Subject: llvm: suppress warnings about deprecated API LLVM-14 still support LLVMBuildCall() and friends but deprecated them via the attribute, so warnings are issued when compiling. Suppress these warnings to keep builds clean. Signed-off-by: Luc Van Oostenryck --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 84b4527f..8450d8bc 100644 --- a/Makefile +++ b/Makefile @@ -216,6 +216,9 @@ INST_PROGRAMS += sparse-llvm sparsec sparse-llvm-cflags := $(LLVM_CFLAGS) sparse-llvm-ldflags := $(LLVM_LDFLAGS) sparse-llvm-ldlibs := $(LLVM_LIBS) +ifeq ($(LLVM_VERSION_MAJOR),14) +sparse-llvm-cflags += -Wno-deprecated-declarations +endif else $(warning LLVM 3.0 or later required. Your system has version $(LLVM_VERSION) installed.) endif -- cgit 1.2.3-korg From d7edb6c7b7c62db1a328fd88f7888324293b005c Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sat, 20 Jan 2024 01:24:12 +0100 Subject: llvm: add a few testcases for integer/pointer conversion Signed-off-by: Luc Van Oostenryck --- validation/backend/cast.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/validation/backend/cast.c b/validation/backend/cast.c index f4122409..9dfa6da5 100644 --- a/validation/backend/cast.c +++ b/validation/backend/cast.c @@ -6,10 +6,12 @@ typedef unsigned int uint; typedef unsigned long ulong; typedef long long longlong; typedef unsigned long long ulonglong; +typedef void *vptr; +typedef int *iptr; #define DEFINE_CAST(from, to) \ static to from##2##to(from x) { \ - return x; \ + return (to)x; \ } #define DEFINE_CASTS(from) \ @@ -43,6 +45,13 @@ DEFINE_CASTS(ulonglong) DEFINE_CASTS(float) DEFINE_CASTS(double) +DEFINE_CAST(long, vptr) +DEFINE_CAST(long, iptr) +DEFINE_CAST(vptr, long) +DEFINE_CAST(iptr, long) +DEFINE_CAST(int, vptr) +DEFINE_CAST(vptr, int) + /* * check-name: Cast code generation * check-command: sparsec -c $file -o tmp.o -- cgit 1.2.3-korg From d5a73d316e38f533d3ec61879149a1c33fac51a3 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sat, 20 Jan 2024 01:24:12 +0100 Subject: llvm: do not duplicate strings and use their length in struct string In 2 places, we duplicate the storage for a string (with strdup) and we also calculate its length via strlen(). Both operation are unneeded as the length is already calculated in the struct string and the pointer to the string data can be safely reused since Sparse will not modify or free it. Signed-off-by: Luc Van Oostenryck --- sparse-llvm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sparse-llvm.c b/sparse-llvm.c index 9ceb19a9..fc0399b4 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -294,13 +294,14 @@ static LLVMValueRef get_sym_value(LLVMModuleRef module, struct symbol *sym) switch (expr->type) { case EXPR_STRING: { const char *s = expr->string->data; + size_t len = expr->string->length; LLVMValueRef indices[] = { LLVMConstInt(LLVMInt64Type(), 0, 0), LLVMConstInt(LLVMInt64Type(), 0, 0) }; LLVMValueRef data; - data = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8Type(), strlen(s) + 1), ".str"); + data = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8Type(), len), ".str"); LLVMSetLinkage(data, LLVMPrivateLinkage); LLVMSetGlobalConstant(data, 1); - LLVMSetInitializer(data, LLVMConstString(strdup(s), strlen(s) + 1, true)); + LLVMSetInitializer(data, LLVMConstString(s, len, true)); result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices)); return result; @@ -1212,8 +1213,9 @@ static LLVMValueRef output_data(LLVMModuleRef module, struct symbol *sym) } case EXPR_STRING: { const char *s = initializer->string->data; + size_t len = initializer->string->length; - initial_value = LLVMConstString(strdup(s), strlen(s) + 1, true); + initial_value = LLVMConstString(s, len, true); break; } default: -- cgit 1.2.3-korg From b753d383f731984c0789366f064f59883d30d229 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sat, 20 Jan 2024 01:24:12 +0100 Subject: llvm: ensure SYM_NODE is stripped before accessing the return type Signed-off-by: Luc Van Oostenryck --- sparse-llvm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sparse-llvm.c b/sparse-llvm.c index fc0399b4..1028e861 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -29,6 +29,8 @@ static LLVMTypeRef symbol_type(struct symbol *sym); static LLVMTypeRef func_return_type(struct symbol *sym) { + if (sym->type == SYM_NODE) + sym = sym->ctype.base_type; return symbol_type(sym->ctype.base_type); } -- cgit 1.2.3-korg From 0544c547682b878758eea731ef4b8e64e5ec91fb Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Sat, 20 Jan 2024 01:24:12 +0100 Subject: llvm: fix LLVM 15 deprecation warnings LLVM 15 switched to opaque pointers by default and no longer supports typed pointers. Remove deprecated LLVM calls and update test. Original-patch-by: Vladimir Petko Signed-off-by: Luc Van Oostenryck --- sparse-llvm.c | 35 ++++++++++++++++++++++++++++++++++- validation/backend/call-variadic.c | 16 ++++------------ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/sparse-llvm.c b/sparse-llvm.c index 1028e861..0b826ce0 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -34,6 +34,20 @@ static LLVMTypeRef func_return_type(struct symbol *sym) return symbol_type(sym->ctype.base_type); } +#if LLVM_VERSION_MAJOR > 14 +// A call can be done either with a SYM_FN or a SYM_PTR (pointing to a SYM_FN). +// Return the type corresponding to the SYM_FN. +static LLVMTypeRef func_full_type(struct symbol *type) +{ + if (type->type == SYM_NODE) { + struct symbol *btype = type->ctype.base_type; + if (btype->type == SYM_PTR) + type = btype->ctype.base_type; + } + return symbol_type(type); +} +#endif + static LLVMTypeRef sym_func_type(struct symbol *sym) { int n_arg = symbol_list_size(sym->arguments); @@ -305,7 +319,11 @@ static LLVMValueRef get_sym_value(LLVMModuleRef module, struct symbol *sym) LLVMSetGlobalConstant(data, 1); LLVMSetInitializer(data, LLVMConstString(s, len, true)); +#if LLVM_VERSION_MAJOR > 14 + result = LLVMConstGEP2(LLVMTypeOf(data), data, indices, ARRAY_SIZE(indices)); +#else result = LLVMConstGEP(data, indices, ARRAY_SIZE(indices)); +#endif return result; } default: @@ -488,7 +506,11 @@ static LLVMValueRef calc_gep(LLVMBuilderRef builder, LLVMValueRef base, LLVMValu /* convert base to char* type */ base = LLVMBuildPointerCast(builder, base, bytep, name); /* addr = base + off */ +#if LLVM_VERSION_MAJOR > 14 + addr = LLVMBuildInBoundsGEP2(builder, LLVMTypeOf(base), base, &off, 1, name); +#else addr = LLVMBuildInBoundsGEP(builder, base, &off, 1, name); +#endif /* convert back to the actual pointer type */ addr = LLVMBuildPointerCast(builder, addr, type, name); return addr; @@ -714,7 +736,11 @@ static void output_op_load(struct function *fn, struct instruction *insn) /* perform load */ pseudo_name(insn->target, name); +#if LLVM_VERSION_MAJOR > 14 + target = LLVMBuildLoad2(fn->builder, symbol_type(insn->type), addr, name); +#else target = LLVMBuildLoad(fn->builder, addr, name); +#endif insn->target->priv = target; } @@ -800,6 +826,7 @@ static void output_op_switch(struct function *fn, struct instruction *insn) static void output_op_call(struct function *fn, struct instruction *insn) { LLVMValueRef target, func; + struct symbol *fntype; struct symbol *ctype; int n_arg = 0, i; struct pseudo *arg; @@ -815,14 +842,20 @@ static void output_op_call(struct function *fn, struct instruction *insn) else func = pseudo_to_value(fn, ctype, insn->func); i = 0; + fntype = ctype; // first symbol in the list is the function 'true' type FOR_EACH_PTR(insn->arguments, arg) { - NEXT_PTR_LIST(ctype); + NEXT_PTR_LIST(ctype); // the remaining ones are the arguments' type args[i++] = pseudo_to_rvalue(fn, ctype, arg); } END_FOR_EACH_PTR(arg); FINISH_PTR_LIST(ctype); pseudo_name(insn->target, name); +#if LLVM_VERSION_MAJOR > 14 + target = LLVMBuildCall2(fn->builder, func_full_type(fntype), func, args, n_arg, name); +#else + (void) fntype; target = LLVMBuildCall(fn->builder, func, args, n_arg, name); +#endif insn->target->priv = target; } diff --git a/validation/backend/call-variadic.c b/validation/backend/call-variadic.c index 4924e3f1..f6f3fe04 100644 --- a/validation/backend/call-variadic.c +++ b/validation/backend/call-variadic.c @@ -11,17 +11,9 @@ int foo(const char *fmt, int a, long l, int *p) /* * check-name: call-variadic * check-command: sparse-llvm-dis -m64 $file + * check-output-ignore + * check-output-contains: , ...) @print(\\(i8\\*\\|ptr\\) %ARG1., i32 120, i32 %ARG2., i32 8, i64 %ARG3., i64 0, \\(i32\\*\\|ptr\\) %ARG4., \\(i8\\*\\|ptr\\) null) + * check-output-contains: define i32 @foo( + * check-output-contains: declare i32 @print( * - * check-output-start -; ModuleID = '' -source_filename = "sparse" - -define i32 @foo(i8* %ARG1., i32 %ARG2., i64 %ARG3., i32* %ARG4.) { -L0: - %R5. = call i32 (i8*, ...) @print(i8* %ARG1., i32 120, i32 %ARG2., i32 8, i64 %ARG3., i64 0, i32* %ARG4., i8* null) - ret i32 %R5. -} - -declare i32 @print(i8*, ...) - * check-output-end */ -- cgit 1.2.3-korg