From: Xi Wang <xi.wang@gmail.com>
To: "Jonathan Neuschäfer" <j.neuschaefer@gmx.net>
Cc: linux-sparse@vger.kernel.org, Pekka Enberg <penberg@kernel.org>,
Christopher Li <sparse@chrisli.org>,
Jeff Garzik <jgarzik@pobox.com>,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: [PATCH 3/4] sparse, llvm: base load/store address type on insn_symbol_type()
Date: Sat, 18 May 2013 18:45:18 -0400 [thread overview]
Message-ID: <5198047E.5000806@gmail.com> (raw)
In-Reply-To: <1368899527-2350-3-git-send-email-j.neuschaefer@gmx.net>
On 05/18/2013 01:52 PM, Jonathan Neuschäfer wrote:
> /* convert address back to pointer */
> - addr = LLVMBuildIntToPtr(fn->builder, addr_i,
> - LLVMTypeOf(src_p), "addr");
> + addr = LLVMBuildIntToPtr(fn->builder, addr_i, addr_type, "addr");
Actually, we shouldn't convert pointers to integers in the first place.
This effectively disables pointer analysis and future optimizations.
A better way is to use LLVM's GEP for pointer arithmetic, by converting
pointers to `char *', rather than integers.
See more examples here:
http://www.spinics.net/lists/linux-sparse/msg02768.html
Jonathan, how about this version using `char *' based on your patchset?
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 00ace6e..a01c4b7 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -541,24 +541,47 @@ static void output_op_ret(struct function *fn, struct instruction *insn)
LLVMBuildRetVoid(fn->builder);
}
-static void output_op_load(struct function *fn, struct instruction *insn)
+static LLVMValueRef calc_gep(LLVMBuilderRef builder, LLVMValueRef base, LLVMValueRef off)
+{
+ LLVMTypeRef type = LLVMTypeOf(base);
+ unsigned int as = LLVMGetPointerAddressSpace(type);
+ LLVMTypeRef bytep = LLVMPointerType(LLVMInt8Type(), as);
+ LLVMValueRef addr;
+
+ /* convert base to char* type */
+ base = LLVMBuildPointerCast(builder, base, bytep, "");
+ /* addr = base + off */
+ addr = LLVMBuildInBoundsGEP(builder, base, &off, 1, "");
+ /* convert base back to the actual pointer type */
+ addr = LLVMBuildPointerCast(builder, addr, type, "");
+ return addr;
+}
+
+static LLVMValueRef calc_memop_addr(struct function *fn, struct instruction *insn)
{
- LLVMTypeRef int_type;
- LLVMValueRef src_p, src_i, ofs_i, addr_i, addr, target;
+ LLVMTypeRef addr_type, int_type;
+ LLVMValueRef src, base, off, addr;
+ unsigned int as;
+
+ src = pseudo_to_value(fn, insn, insn->src);
+ as = LLVMGetPointerAddressSpace(LLVMTypeOf(src));
+ addr_type = LLVMPointerType(insn_symbol_type(fn->module, insn), as);
+ base = LLVMBuildPointerCast(fn->builder, src, addr_type, "");
/* int type large enough to hold a pointer */
int_type = LLVMIntType(bits_in_pointer);
+ off = LLVMConstInt(int_type, insn->offset, 0);
+
+ addr = calc_gep(fn->builder, base, off);
+ return addr;
+}
- /* convert to integer, add src + offset */
- src_p = pseudo_to_value(fn, insn, insn->src);
- src_i = LLVMBuildPtrToInt(fn->builder, src_p, int_type, "src_i");
- ofs_i = LLVMConstInt(int_type, insn->offset, 0);
- addr_i = LLVMBuildAdd(fn->builder, src_i, ofs_i, "addr_i");
+static void output_op_load(struct function *fn, struct instruction *insn)
+{
+ LLVMValueRef addr, target;
- /* convert address back to pointer */
- addr = LLVMBuildIntToPtr(fn->builder, addr_i,
- LLVMTypeOf(src_p), "addr");
+ addr = calc_memop_addr(fn, insn);
/* perform load */
target = LLVMBuildLoad(fn->builder, addr, "load_target");
@@ -568,22 +591,9 @@ static void output_op_load(struct function *fn, struct instruction *insn)
static void output_op_store(struct function *fn, struct instruction *insn)
{
- LLVMTypeRef int_type;
- LLVMValueRef src_p, src_i, ofs_i, addr_i, addr, target, target_in;
-
- /* int type large enough to hold a pointer */
- int_type = LLVMIntType(bits_in_pointer);
-
- /* convert to integer, add src + offset */
- src_p = pseudo_to_value(fn, insn, insn->src);
- src_i = LLVMBuildPtrToInt(fn->builder, src_p, int_type, "src_i");
-
- ofs_i = LLVMConstInt(int_type, insn->offset, 0);
- addr_i = LLVMBuildAdd(fn->builder, src_i, ofs_i, "addr_i");
+ LLVMValueRef addr, target, target_in;
- /* convert address back to pointer */
- addr = LLVMBuildIntToPtr(fn->builder, addr_i,
- LLVMPointerType(int_type, 0), "addr");
+ addr = calc_memop_addr(fn, insn);
target_in = pseudo_to_value(fn, insn, insn->target);
diff --git a/validation/backend/store-type.c b/validation/backend/store-type.c
new file mode 100644
index 0000000..9e2ce73
--- /dev/null
+++ b/validation/backend/store-type.c
@@ -0,0 +1,12 @@
+struct foo;
+static struct foo *var;
+
+static void set(struct foo *f)
+{
+ var = f;
+}
+
+/*
+ * check-name: Type of stored objects
+ * check-command: ./sparsec -c $file -o tmp.o
+ */
diff --git a/validation/backend/struct-access.c b/validation/backend/struct-access.c
new file mode 100644
index 0000000..884b470
--- /dev/null
+++ b/validation/backend/struct-access.c
@@ -0,0 +1,28 @@
+struct st {
+ int i, *d;
+};
+
+static int load_i(struct st *st)
+{
+ return st->i;
+}
+
+static void store_i(struct st *st, int i)
+{
+ st->i = i;
+}
+
+static int *load_d(struct st *st)
+{
+ return st->d;
+}
+
+static void store_d(struct st *st, int *d)
+{
+ st->d = d;
+}
+
+/*
+ * check-name: struct access code generation
+ * check-command: ./sparsec -c $file -o tmp.o
+ */
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2013-05-18 22:45 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-18 17:52 [PATCH 1/4] sparse, llvm: Fix resulting type of store address calculations Jonathan Neuschäfer
2013-05-18 17:52 ` [PATCH 2/4] sparse, llvm: de-duplicate load/store address calculation code Jonathan Neuschäfer
2013-05-18 17:52 ` [PATCH 3/4] sparse, llvm: base load/store address type on insn_symbol_type() Jonathan Neuschäfer
2013-05-18 22:45 ` Xi Wang [this message]
2013-05-19 0:17 ` Jonathan Neuschäfer
2013-05-18 17:52 ` [PATCH 4/4] sparse, llvm: add a struct access test case Jonathan Neuschäfer
2013-05-19 8:01 ` [PATCH 1/4] sparse, llvm: Fix resulting type of store address calculations Pekka Enberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5198047E.5000806@gmail.com \
--to=xi.wang@gmail.com \
--cc=j.neuschaefer@gmx.net \
--cc=jgarzik@pobox.com \
--cc=linux-sparse@vger.kernel.org \
--cc=penberg@kernel.org \
--cc=sparse@chrisli.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.