aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Li <sparse@chrisli.org>2012-10-11 19:37:23 -0700
committerChristopher Li <sparse@chrisli.org>2012-10-11 19:40:45 -0700
commit122820872558c308549a099066e994ec5ca2ce9e (patch)
tree7e3338775500723939fbda840698eb5eb105be34
parent063236fd3f46bc83b49172f5ecb597e0a91cede8 (diff)
parentd5bd3662e07343fbd82c05606f4c25951062d1bb (diff)
downloadsparse-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.c38
-rw-r--r--validation/backend/extern.c11
-rw-r--r--validation/backend/int-cond.c30
-rw-r--r--validation/backend/load-type.c12
-rw-r--r--validation/backend/void-return-type.c13
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
+ */