* [PATCH 1/2] sparse, llvm: Make 'sparsec' error handling more robust
@ 2011-11-18 15:30 Pekka Enberg
2011-11-18 15:30 ` [PATCH 2/2] sparse, llvm: Function pointer code generation Pekka Enberg
0 siblings, 1 reply; 2+ messages in thread
From: Pekka Enberg @ 2011-11-18 15:30 UTC (permalink / raw)
To: linux-sparse; +Cc: Pekka Enberg, Christopher Li, Jeff Garzik, Linus Torvalds
Make 'sparsec' more robust against SIGSEGV in Sparse/LLVM code so that 'make
check' detects test breakage.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
---
sparsec | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/sparsec b/sparsec
index 1e5c8bd..33e1a2b 100755
--- a/sparsec
+++ b/sparsec
@@ -2,6 +2,8 @@
#
# GCC compatible C compiler based on Sparse LLVM
+set +e
+
SPARSEOPTS=""
DIRNAME=`dirname $0`
@@ -27,9 +29,12 @@ while [ $# -gt 0 ]; do
shift
done
+TMPLLVM=`mktemp -t tmp.XXXXXX`".llvm"
TMPFILE=`mktemp -t tmp.XXXXXX`".o"
-$DIRNAME/sparse-llvm $SPARSEOPTS | llc | as -o $TMPFILE
+$DIRNAME/sparse-llvm $SPARSEOPTS > $TMPLLVM
+
+llc $TMPLLVM | as -o $TMPFILE
if [ $NEED_LINK -eq 1 ]; then
if [ -z $OUTFILE ]; then
@@ -43,3 +48,5 @@ else
fi
mv $TMPFILE $OUTFILE
fi
+
+rm -f $TMPLLVM
--
1.7.6.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 2/2] sparse, llvm: Function pointer code generation
2011-11-18 15:30 [PATCH 1/2] sparse, llvm: Make 'sparsec' error handling more robust Pekka Enberg
@ 2011-11-18 15:30 ` Pekka Enberg
0 siblings, 0 replies; 2+ messages in thread
From: Pekka Enberg @ 2011-11-18 15:30 UTC (permalink / raw)
To: linux-sparse; +Cc: Pekka Enberg, Christopher Li, Jeff Garzik, Linus Torvalds
This patch implements support for function pointer types and function pointer
calls to the LLVM backend.
Cc: Christopher Li <sparse@chrisli.org>
Cc: Jeff Garzik <jgarzik@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
---
sparse-llvm.c | 54 +++++++++++++++++++++++++++++++++++-
validation/backend/function-ptr.c | 11 +++++++
2 files changed, 63 insertions(+), 2 deletions(-)
create mode 100644 validation/backend/function-ptr.c
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 7f46c8a..c037e02 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -34,6 +34,46 @@ static inline bool symbol_is_fp_type(struct symbol *sym)
static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym);
+static LLVMTypeRef func_return_type(LLVMModuleRef module, struct symbol *sym)
+{
+ return symbol_type(module, sym->ctype.base_type);
+}
+
+static LLVMTypeRef sym_func_type(LLVMModuleRef module, struct symbol *sym)
+{
+ LLVMTypeRef *arg_type;
+ LLVMTypeRef func_type;
+ LLVMTypeRef ret_type;
+ struct symbol *arg;
+ int n_arg = 0;
+
+ /* to avoid strangeness with varargs [for now], we build
+ * the function and type anew, for each call. This
+ * is probably wrong. We should look up the
+ * symbol declaration info.
+ */
+
+ ret_type = func_return_type(module, sym);
+
+ /* count args, build argument type information */
+ FOR_EACH_PTR(sym->arguments, arg) {
+ n_arg++;
+ } END_FOR_EACH_PTR(arg);
+
+ arg_type = calloc(n_arg, sizeof(LLVMTypeRef));
+
+ int idx = 0;
+ FOR_EACH_PTR(sym->arguments, arg) {
+ struct symbol *arg_sym = arg->ctype.base_type;
+
+ arg_type[idx++] = symbol_type(module, arg_sym);
+ } END_FOR_EACH_PTR(arg);
+ func_type = LLVMFunctionType(ret_type, arg_type, n_arg,
+ /* varargs? */ 0);
+
+ return func_type;
+}
+
static LLVMTypeRef sym_array_type(LLVMModuleRef module, struct symbol *sym)
{
LLVMTypeRef elem_type;
@@ -172,6 +212,9 @@ static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym)
case SYM_ARRAY:
ret = sym_array_type(module, sym);
break;
+ case SYM_FN:
+ ret = sym_func_type(module, sym);
+ break;
default:
assert(0);
}
@@ -638,7 +681,10 @@ static LLVMTypeRef get_func_type(struct function *fn, struct instruction *insn)
int n_arg = 0;
LLVMTypeRef *arg_type;
- sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
+ if (sym->ident)
+ sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
+ else
+ sprintf(buffer, "<anon sym %p>", sym);
/* VERIFY: is this correct, for functions? */
func_type = LLVMGetTypeByName(fn->module, buffer);
@@ -682,7 +728,11 @@ static LLVMValueRef get_function(struct function *fn, struct instruction *insn)
LLVMValueRef func;
struct llfunc *f;
- sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
+ if (sym->ident)
+ sprintf(buffer, "%.*s", sym->ident->len, sym->ident->name);
+ else
+ sprintf(buffer, "<anon sym %p>", sym);
+
/* search for pre-built function type definition */
FOR_EACH_PTR(mi.llfunc_list, f) {
diff --git a/validation/backend/function-ptr.c b/validation/backend/function-ptr.c
new file mode 100644
index 0000000..fc022b3
--- /dev/null
+++ b/validation/backend/function-ptr.c
@@ -0,0 +1,11 @@
+typedef int (*fn_t)(int x, int y);
+
+static int run(fn_t fn, int x, int y)
+{
+ return fn(x, y);
+}
+
+/*
+ * check-name: Function pointer code generation
+ * check-command: ./sparsec -c $file -o tmp.o
+ */
--
1.7.6.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2011-11-18 15:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-18 15:30 [PATCH 1/2] sparse, llvm: Make 'sparsec' error handling more robust Pekka Enberg
2011-11-18 15:30 ` [PATCH 2/2] sparse, llvm: Function pointer code generation Pekka Enberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).