aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <lucvoo@kernel.org>2024-01-29 18:11:38 +0100
committerLuc Van Oostenryck <lucvoo@kernel.org>2024-01-29 18:11:38 +0100
commitc991e5c68b48158410ebda9cd0ae0fde065faec7 (patch)
tree37c21b201a8de97a49d396e43c86c79fff572cca
parent1cf3d98cf171fa27944750daba5e80e17cb8e9d0 (diff)
parent0544c547682b878758eea731ef4b8e64e5ec91fb (diff)
downloadsparse-c991e5c68b48158410ebda9cd0ae0fde065faec7.tar.gz
Merge branch 'llvm-15'
* Support LLVM-15 and later
-rw-r--r--Makefile3
-rw-r--r--sparse-llvm.c45
-rw-r--r--validation/backend/call-variadic.c16
-rw-r--r--validation/backend/cast.c11
4 files changed, 58 insertions, 17 deletions
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
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 9ceb19a9..0b826ce0 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -29,9 +29,25 @@ 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);
}
+#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);
@@ -294,15 +310,20 @@ 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));
+#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:
@@ -485,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;
@@ -711,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;
}
@@ -797,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;
@@ -812,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;
}
@@ -1212,8 +1248,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:
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 = '<stdin>'
-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
*/
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