diff options
author | Christopher Li <sparse@chrisli.org> | 2012-10-11 19:37:23 -0700 |
---|---|---|
committer | Christopher Li <sparse@chrisli.org> | 2012-10-11 19:40:45 -0700 |
commit | 122820872558c308549a099066e994ec5ca2ce9e (patch) | |
tree | 7e3338775500723939fbda840698eb5eb105be34 | |
parent | 063236fd3f46bc83b49172f5ecb597e0a91cede8 (diff) | |
parent | d5bd3662e07343fbd82c05606f4c25951062d1bb (diff) | |
download | sparse-122820872558c308549a099066e994ec5ca2ce9e.tar.gz |
Merge branch 'llvm/core' of github.com:penberg/sparse-llvm
Please pull the latest Sparse/LLVM tree from:
git@github.com:penberg/sparse-llvm.git llvm/core
It contains few LLVM backend fixes from myself and Jonathan Neuschäfer.
-rw-r--r-- | sparse-llvm.c | 38 | ||||
-rw-r--r-- | validation/backend/extern.c | 11 | ||||
-rw-r--r-- | validation/backend/int-cond.c | 30 | ||||
-rw-r--r-- | validation/backend/load-type.c | 12 | ||||
-rw-r--r-- | validation/backend/void-return-type.c | 13 |
5 files changed, 99 insertions, 5 deletions
diff --git a/sparse-llvm.c b/sparse-llvm.c index 6b94205d..6f2fbd69 100644 --- a/sparse-llvm.c +++ b/sparse-llvm.c @@ -5,6 +5,7 @@ #include <llvm-c/Core.h> #include <llvm-c/BitWriter.h> +#include <llvm-c/Analysis.h> #include <stdbool.h> #include <stdio.h> @@ -149,7 +150,13 @@ static LLVMTypeRef sym_union_type(LLVMModuleRef module, struct symbol *sym) static LLVMTypeRef sym_ptr_type(LLVMModuleRef module, struct symbol *sym) { - LLVMTypeRef type = symbol_type(module, sym->ctype.base_type); + LLVMTypeRef type; + + /* 'void *' is treated like 'char *' */ + if (is_void_type(sym->ctype.base_type)) + type = LLVMInt8Type(); + else + type = symbol_type(module, sym->ctype.base_type); return LLVMPointerType(type, 0); } @@ -175,10 +182,12 @@ static LLVMTypeRef sym_basetype_type(struct symbol *sym) } } else { switch (sym->bit_size) { + case -1: + ret = LLVMVoidType(); + break; case 1: ret = LLVMInt1Type(); break; - case -1: /* 'void *' is treated like 'char *' */ case 8: ret = LLVMInt8Type(); break; @@ -335,6 +344,14 @@ static LLVMValueRef pseudo_to_value(struct function *fn, struct instruction *ins default: assert(0); } + } else { + const char *name = show_ident(sym->ident); + + result = LLVMGetNamedGlobal(fn->module, name); + if (!result) { + LLVMTypeRef type = symbol_type(fn->module, sym); + result = LLVMAddGlobal(fn->module, type, name); + } } break; } @@ -598,7 +615,7 @@ static void output_op_load(struct function *fn, struct instruction *insn) /* convert address back to pointer */ addr = LLVMBuildIntToPtr(fn->builder, addr_i, - LLVMPointerType(int_type, 0), "addr"); + LLVMTypeOf(src_p), "addr"); /* perform load */ target = LLVMBuildLoad(fn->builder, addr, "load_target"); @@ -633,10 +650,19 @@ static void output_op_store(struct function *fn, struct instruction *insn) insn->target->priv = target; } +static LLVMValueRef bool_value(struct function *fn, LLVMValueRef value) +{ + if (LLVMTypeOf(value) != LLVMInt1Type()) + value = LLVMBuildIsNotNull(fn->builder, value, "cond"); + + return value; +} + static void output_op_br(struct function *fn, struct instruction *br) { if (br->cond) { - LLVMValueRef cond = pseudo_to_value(fn, br, br->cond); + LLVMValueRef cond = bool_value(fn, + pseudo_to_value(fn, br, br->cond)); LLVMBuildCondBr(fn->builder, cond, br->bb_true->priv, @@ -651,7 +677,7 @@ static void output_op_sel(struct function *fn, struct instruction *insn) { LLVMValueRef target, src1, src2, src3; - src1 = pseudo_to_value(fn, insn, insn->src1); + src1 = bool_value(fn, pseudo_to_value(fn, insn, insn->src1)); src2 = pseudo_to_value(fn, insn, insn->src2); src3 = pseudo_to_value(fn, insn, insn->src3); @@ -1245,6 +1271,8 @@ int main(int argc, char **argv) compile(module, sparse(file)); } END_FOR_EACH_PTR_NOTAG(file); + LLVMVerifyModule(module, LLVMPrintMessageAction, NULL); + LLVMWriteBitcodeToFD(module, STDOUT_FILENO, 0, 0); LLVMDisposeModule(module); diff --git a/validation/backend/extern.c b/validation/backend/extern.c new file mode 100644 index 00000000..24cbae55 --- /dev/null +++ b/validation/backend/extern.c @@ -0,0 +1,11 @@ +extern unsigned long foo; + +static unsigned long bar(void) +{ + return foo; +} + +/* + * check-name: Extern symbol code generation + * check-command: ./sparsec -c $file -o tmp.o + */ diff --git a/validation/backend/int-cond.c b/validation/backend/int-cond.c new file mode 100644 index 00000000..48b25a77 --- /dev/null +++ b/validation/backend/int-cond.c @@ -0,0 +1,30 @@ +static long foo(long a, long b, long c) +{ + return a? b:c; +} + +static long foo_bool(_Bool a, long b, long c) +{ + return a? b:c; +} + +static long bar(long a, long b, long c) +{ + if (a) + return b; + else + return b + c; +} + +static long bar_bool(_Bool a, long b, long c) +{ + if (a) + return b; + else + return b + c; +} + +/* + * check-name: Non-bool condition values in branch/select + * check-command: ./sparsec -c $file -o tmp.o + */ diff --git a/validation/backend/load-type.c b/validation/backend/load-type.c new file mode 100644 index 00000000..80416cad --- /dev/null +++ b/validation/backend/load-type.c @@ -0,0 +1,12 @@ +extern struct _IO_FILE *stdin; + +static void sub(struct _IO_FILE *in) {} + +static void test(void) { + sub(stdin); +} + +/* + * check-name: Type of loaded objects + * check-command: ./sparsec -c $file -o tmp.o + */ diff --git a/validation/backend/void-return-type.c b/validation/backend/void-return-type.c new file mode 100644 index 00000000..b282fdee --- /dev/null +++ b/validation/backend/void-return-type.c @@ -0,0 +1,13 @@ +static void foo(void) +{ +} + +static void *bar(void *p) +{ + return p; +} + +/* + * check-name: void return type code generation + * check-command: ./sparsec -c $file -o tmp.o + */ |