From: Jeff Garzik <jeff@garzik.org>
To: Pekka Enberg <penberg@kernel.org>
Cc: Christopher Li <sparse@chrisli.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Linux-Sparse <linux-sparse@vger.kernel.org>
Subject: Re: suggestion for Merging LLVM
Date: Wed, 23 Nov 2011 01:01:07 -0500 [thread overview]
Message-ID: <4ECC8C23.4080909@garzik.org> (raw)
In-Reply-To: <CAOJsxLGqsH9vbE9AQO2chV28Wx=iw5hA9dJzR3X1Cvrd5Sv6Eg@mail.gmail.com>
On 11/22/2011 03:38 PM, Pekka Enberg wrote:
> So pasting the above test program tohttp://llvm.org/demo/ and
> switching to "LLVM C++ API code" target seems to suggest you're
> interested in the LLVMReplaceAllUsesWith() API for forward references.
Sent pull req via github.
List implementation is cheesy (inefficient if list ever gets woefully
large) singly-linked list, but it is pretty simple. Turned out that
postponing LLVMAddIncoming() call works better than
LLVMReplaceAllUsesWith() API:
(warning: do not apply directly, patch is unfortunately word-wrapped;
see pull request)
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -17,11 +17,21 @@
#include "linearize.h"
#include "flow.h"
+struct phi_fwd {
+ struct phi_fwd *next;
+
+ LLVMValueRef phi;
+ pseudo_t pseudo;
+ bool resolved;
+};
+
struct function {
LLVMBuilderRef builder;
LLVMTypeRef type;
LLVMValueRef fn;
LLVMModuleRef module;
+
+ struct phi_fwd *fwd_list;
};
static inline bool symbol_is_fp_type(struct symbol *sym)
@@ -794,6 +804,67 @@ static void output_op_call(struct function *fn,
struct instruction *insn)
insn->target->priv = target;
}
+static void store_phi_fwd(struct function *fn, LLVMValueRef phi,
+ pseudo_t pseudo)
+{
+ struct phi_fwd *fwd;
+
+ fwd = calloc(1, sizeof(*fwd));
+ fwd->phi = phi;
+ fwd->pseudo = pseudo;
+
+ /* append fwd ref to function-wide list */
+ if (!fn->fwd_list)
+ fn->fwd_list = fwd;
+ else {
+ struct phi_fwd *last = fn->fwd_list;
+
+ while (last->next)
+ last = last->next;
+ last->next = fwd;
+ }
+}
+
+static void output_phi_fwd(struct function *fn, pseudo_t pseudo,
LLVMValueRef v)
+{
+ struct phi_fwd *fwd = fn->fwd_list;
+
+ while (fwd) {
+ struct phi_fwd *tmp;
+
+ tmp = fwd;
+ fwd = fwd->next;
+
+ if (tmp->pseudo == pseudo && !tmp->resolved) {
+ LLVMValueRef phi_vals[1];
+ LLVMBasicBlockRef phi_blks[1];
+
+ phi_vals[0] = v;
+ phi_blks[0] = pseudo->def->bb->priv;
+
+ LLVMAddIncoming(tmp->phi, phi_vals, phi_blks, 1);
+
+ tmp->resolved = true;
+ }
+ }
+}
+
+static void output_op_phisrc(struct function *fn, struct instruction *insn)
+{
+ LLVMValueRef v;
+
+ assert(insn->target->priv == NULL);
+
+ /* target = src */
+ v = pseudo_to_value(fn, insn, insn->phi_src);
+ insn->target->priv = v;
+
+ assert(insn->target->priv != NULL);
+
+ /* resolve forward references to this phi source, if present */
+ output_phi_fwd(fn, insn->target, v);
+}
+
static void output_op_phi(struct function *fn, struct instruction *insn)
{
pseudo_t phi;
@@ -803,7 +874,7 @@ static void output_op_phi(struct function *fn,
struct instruction *insn)
"phi");
int pll = 0;
FOR_EACH_PTR(insn->phi_list, phi) {
- if (pseudo_to_value(fn, insn, phi)) /* skip VOID */
+ if (pseudo_to_value(fn, insn, phi)) /* skip VOID,
fwd refs*/
pll++;
} END_FOR_EACH_PTR(phi);
@@ -815,11 +886,13 @@ static void output_op_phi(struct function *fn,
struct instruction *insn)
LLVMValueRef v;
v = pseudo_to_value(fn, insn, phi);
- if (v) { /* skip VOID */
+ if (v) { /* skip VOID, fwd refs */
phi_vals[idx] = v;
phi_blks[idx] = phi->def->bb->priv;
idx++;
}
+ else if (phi->type == PSEUDO_PHI) /* fwd ref */
+ store_phi_fwd(fn, target, phi);
} END_FOR_EACH_PTR(phi);
LLVMAddIncoming(target, phi_vals, phi_blks, pll);
@@ -916,8 +989,7 @@ static void output_insn(struct function *fn, struct
instruction *insn)
assert(0);
break;
case OP_PHISOURCE:
- /* target = src */
- insn->target->priv = pseudo_to_value(fn, insn,
insn->phi_src);
+ output_op_phisrc(fn, insn);
break;
case OP_PHI:
output_op_phi(fn, insn);
@@ -1026,7 +1098,7 @@ static void output_fn(LLVMModuleRef module, struct
entrypoint *ep)
struct symbol *ret_type = sym->ctype.base_type->ctype.base_type;
LLVMTypeRef arg_types[MAX_ARGS];
LLVMTypeRef return_type;
- struct function function;
+ struct function function = { .module = module };
struct basic_block *bb;
struct symbol *arg;
const char *name;
@@ -1043,8 +1115,6 @@ static void output_fn(LLVMModuleRef module, struct
entrypoint *ep)
return_type = symbol_type(module, ret_type);
- function.module = module;
next prev parent reply other threads:[~2011-11-23 6:01 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-22 2:43 suggestion for Merging LLVM Christopher Li
2011-11-22 5:52 ` Jeff Garzik
2011-11-22 6:01 ` Pekka Enberg
2011-11-22 20:32 ` Jeff Garzik
2011-11-22 20:38 ` Pekka Enberg
2011-11-23 4:11 ` Jeff Garzik
2011-11-23 6:01 ` Jeff Garzik [this message]
2011-11-23 6:58 ` Pekka Enberg
2011-11-25 1:45 ` Christopher Li
2011-11-25 2:25 ` Jeff Garzik
2011-11-25 5:52 ` Pekka Enberg
2011-11-25 6:28 ` Christopher Li
2011-11-25 6:43 ` Pekka Enberg
2011-11-25 8:05 ` Christopher Li
2011-11-25 8:29 ` Pekka Enberg
2011-11-25 17:52 ` Jeff Garzik
2011-11-25 19:13 ` Christopher Li
2011-11-25 20:18 ` Jeff Garzik
2011-11-25 20:30 ` Christopher Li
2011-12-13 20:29 ` Pekka Enberg
2011-12-15 21:34 ` Christopher Li
2011-12-20 8:53 ` 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=4ECC8C23.4080909@garzik.org \
--to=jeff@garzik.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox