* [RFC][PATCH 0/3] implement pseudo->ctype
@ 2012-06-04 6:54 Xi Wang
2012-06-04 6:54 ` [RFC][PATCH 1/3] add ->ctype to struct pseudo Xi Wang
` (5 more replies)
0 siblings, 6 replies; 14+ messages in thread
From: Xi Wang @ 2012-06-04 6:54 UTC (permalink / raw)
To: linux-sparse; +Cc: Xi Wang
This patchset tries to implement Chris's `counter RFC': adding ->ctype
to pseudo, while removing ->type and ->size from instruction. In this
way, it provides easy access to type information for backend.
The first patch adds ->ctype to struct pseudo and doesn't touch struct
instruction. It could be applied alone if we really want backward
compatibility.
The second patch does more destructive work. It removes ->type and
->size from struct instruction and updates client uses.
The third patch updates sparse-llvm in a naive way, which should have
been much simpler with the new ->ctype in pseudo. I guess in some cases
->ctype is even necessary. Consider the example below.
void foo(int x, ...);
foo(1, 2, 3LL);
Is it possible to get the types of the 2nd and 3rd arguments in current
code, which are simply PSEUDO_VAL?
Xi Wang (3):
add ->ctype to struct pseudo
remove ->type and ->size from struct instruction
sparse, llvm: sync with new struct instruction
cse.c | 6 +--
example.c | 12 ++---
flow.c | 12 ++---
linearize.c | 147 +++++++++++++++++++++++++--------------------------------
linearize.h | 17 ++++---
memops.c | 4 +-
simplify.c | 24 +++++-----
sparse-llvm.c | 50 ++++++++++----------
sparse.c | 2 +-
unssa.c | 3 +-
10 files changed, 131 insertions(+), 146 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 14+ messages in thread
* [RFC][PATCH 1/3] add ->ctype to struct pseudo
2012-06-04 6:54 [RFC][PATCH 0/3] implement pseudo->ctype Xi Wang
@ 2012-06-04 6:54 ` Xi Wang
2012-06-04 6:54 ` [RFC][PATCH 2/3] remove ->type and ->size from struct instruction Xi Wang
` (4 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Xi Wang @ 2012-06-04 6:54 UTC (permalink / raw)
To: linux-sparse; +Cc: Xi Wang
This patch implements Chris's `counter RFC' by adding ->ctype to
struct pseduo so that we have easy access to type information.
Suggested-by: Christopher Li <sparse@chrisli.org>
Signed-off-by: Xi Wang <xi.wang@gmail.com>
---
flow.c | 2 +-
linearize.c | 57 +++++++++++++++++++++++++++++++--------------------------
linearize.h | 5 +++--
memops.c | 2 +-
simplify.c | 10 +++++-----
unssa.c | 2 +-
6 files changed, 42 insertions(+), 36 deletions(-)
diff --git a/flow.c b/flow.c
index 7db9548..45f1c8f 100644
--- a/flow.c
+++ b/flow.c
@@ -462,7 +462,7 @@ found:
if (!local)
return 0;
check_access(insn);
- convert_load_instruction(insn, value_pseudo(0));
+ convert_load_instruction(insn, value_pseudo(insn->target->ctype, 0));
return 1;
}
diff --git a/linearize.c b/linearize.c
index 1d15cfd..a4bf309 100644
--- a/linearize.c
+++ b/linearize.c
@@ -734,12 +734,13 @@ static void add_branch(struct entrypoint *ep, struct expression *expr, pseudo_t
}
/* Dummy pseudo allocator */
-pseudo_t alloc_pseudo(struct instruction *def)
+pseudo_t alloc_pseudo(struct symbol *ctype, struct instruction *def)
{
static int nr = 0;
struct pseudo * pseudo = __alloc_pseudo(0);
pseudo->type = PSEUDO_REG;
pseudo->nr = ++nr;
+ pseudo->ctype = ctype;
pseudo->def = def;
return pseudo;
}
@@ -767,6 +768,7 @@ static pseudo_t symbol_pseudo(struct entrypoint *ep, struct symbol *sym)
pseudo->type = PSEUDO_SYM;
pseudo->sym = sym;
pseudo->ident = sym->ident;
+ pseudo->ctype = sym->ctype.base_type;
sym->pseudo = pseudo;
add_pseudo(&ep->accesses, pseudo);
}
@@ -774,21 +776,22 @@ static pseudo_t symbol_pseudo(struct entrypoint *ep, struct symbol *sym)
return pseudo;
}
-pseudo_t value_pseudo(long long val)
+pseudo_t value_pseudo(struct symbol *ctype, long long val)
{
#define MAX_VAL_HASH 64
static struct pseudo_list *prev[MAX_VAL_HASH];
- int hash = val & (MAX_VAL_HASH-1);
+ int hash = (val ^ type_size(ctype)) & (MAX_VAL_HASH-1);
struct pseudo_list **list = prev + hash;
pseudo_t pseudo;
FOR_EACH_PTR(*list, pseudo) {
- if (pseudo->value == val)
+ if (pseudo->ctype == ctype && pseudo->value == val)
return pseudo;
} END_FOR_EACH_PTR(pseudo);
pseudo = __alloc_pseudo(0);
pseudo->type = PSEUDO_VAL;
+ pseudo->ctype = ctype;
pseudo->value = val;
add_pseudo(list, pseudo);
@@ -796,13 +799,14 @@ pseudo_t value_pseudo(long long val)
return pseudo;
}
-static pseudo_t argument_pseudo(struct entrypoint *ep, int nr)
+static pseudo_t argument_pseudo(struct entrypoint *ep, struct symbol *ctype, int nr)
{
pseudo_t pseudo = __alloc_pseudo(0);
struct instruction *entry = ep->entry;
pseudo->type = PSEUDO_ARG;
pseudo->nr = nr;
+ pseudo->ctype = ctype;
pseudo->def = entry;
add_pseudo(&entry->arg_list, pseudo);
@@ -818,6 +822,7 @@ pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, int size)
phi->type = PSEUDO_PHI;
phi->nr = ++nr;
+ phi->ctype = pseudo->ctype;
phi->def = insn;
use_pseudo(insn, pseudo, &insn->phi_src);
@@ -911,7 +916,7 @@ static pseudo_t add_load(struct entrypoint *ep, struct access_data *ad)
return new;
insn = alloc_typed_instruction(OP_LOAD, ad->source_type);
- new = alloc_pseudo(insn);
+ new = alloc_pseudo(ad->source_type, insn);
ad->origval = new;
insn->target = new;
@@ -946,10 +951,10 @@ static pseudo_t linearize_store_gen(struct entrypoint *ep,
unsigned long long mask = (1ULL << ad->bit_size)-1;
if (shift) {
- store = add_binary_op(ep, ad->source_type, OP_SHL, value, value_pseudo(shift));
+ store = add_binary_op(ep, ad->source_type, OP_SHL, value, value_pseudo(value->ctype, shift));
mask <<= shift;
}
- orig = add_binary_op(ep, ad->source_type, OP_AND, orig, value_pseudo(~mask));
+ orig = add_binary_op(ep, ad->source_type, OP_AND, orig, value_pseudo(orig->ctype, ~mask));
store = add_binary_op(ep, ad->source_type, OP_OR, orig, store);
}
add_store(ep, ad, store);
@@ -959,7 +964,7 @@ static pseudo_t linearize_store_gen(struct entrypoint *ep,
static pseudo_t add_binary_op(struct entrypoint *ep, struct symbol *ctype, int op, pseudo_t left, pseudo_t right)
{
struct instruction *insn = alloc_typed_instruction(op, ctype);
- pseudo_t target = alloc_pseudo(insn);
+ pseudo_t target = alloc_pseudo(ctype, insn);
insn->target = target;
use_pseudo(insn, left, &insn->src1);
use_pseudo(insn, right, &insn->src2);
@@ -970,17 +975,17 @@ static pseudo_t add_binary_op(struct entrypoint *ep, struct symbol *ctype, int o
static pseudo_t add_setval(struct entrypoint *ep, struct symbol *ctype, struct expression *val)
{
struct instruction *insn = alloc_typed_instruction(OP_SETVAL, ctype);
- pseudo_t target = alloc_pseudo(insn);
+ pseudo_t target = alloc_pseudo(ctype, insn);
insn->target = target;
insn->val = val;
add_one_insn(ep, insn);
return target;
}
-static pseudo_t add_symbol_address(struct entrypoint *ep, struct symbol *sym)
+static pseudo_t add_symbol_address(struct entrypoint *ep, struct symbol *ctype, struct symbol *sym)
{
struct instruction *insn = alloc_instruction(OP_SYMADDR, bits_in_pointer);
- pseudo_t target = alloc_pseudo(insn);
+ pseudo_t target = alloc_pseudo(ctype, insn);
insn->target = target;
use_pseudo(insn, symbol_pseudo(ep, sym), &insn->symbol);
@@ -993,7 +998,7 @@ static pseudo_t linearize_load_gen(struct entrypoint *ep, struct access_data *ad
pseudo_t new = add_load(ep, ad);
if (ad->bit_offset) {
- pseudo_t shift = value_pseudo(ad->bit_offset);
+ pseudo_t shift = value_pseudo(new->ctype, ad->bit_offset);
pseudo_t newval = add_binary_op(ep, ad->source_type, OP_LSR, new, shift);
new = newval;
}
@@ -1024,7 +1029,7 @@ static pseudo_t linearize_inc_dec(struct entrypoint *ep, struct expression *expr
return VOID;
old = linearize_load_gen(ep, &ad);
- one = value_pseudo(expr->op_value);
+ one = value_pseudo(expr->ctype, expr->op_value);
new = add_binary_op(ep, expr->ctype, op, old, one);
linearize_store_gen(ep, new, &ad);
finish_address_gen(ep, &ad);
@@ -1034,7 +1039,7 @@ static pseudo_t linearize_inc_dec(struct entrypoint *ep, struct expression *expr
static pseudo_t add_uniop(struct entrypoint *ep, struct expression *expr, int op, pseudo_t src)
{
struct instruction *insn = alloc_typed_instruction(op, expr->ctype);
- pseudo_t new = alloc_pseudo(insn);
+ pseudo_t new = alloc_pseudo(expr->ctype, insn);
insn->target = new;
use_pseudo(insn, src, &insn->src1);
@@ -1046,7 +1051,7 @@ static pseudo_t linearize_slice(struct entrypoint *ep, struct expression *expr)
{
pseudo_t pre = linearize_expression(ep, expr->base);
struct instruction *insn = alloc_typed_instruction(OP_SLICE, expr->ctype);
- pseudo_t new = alloc_pseudo(insn);
+ pseudo_t new = alloc_pseudo(expr->ctype, insn);
insn->target = new;
insn->from = expr->r_bitpos;
@@ -1063,7 +1068,7 @@ static pseudo_t linearize_regular_preop(struct entrypoint *ep, struct expression
case '+':
return pre;
case '!': {
- pseudo_t zero = value_pseudo(0);
+ pseudo_t zero = value_pseudo(pre->ctype, 0);
return add_binary_op(ep, expr->unop->ctype, OP_SET_EQ, pre, zero);
}
case '~':
@@ -1130,7 +1135,7 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
if (from->bit_size < 0 || to->bit_size < 0)
return VOID;
insn = alloc_cast_instruction(from, to);
- result = alloc_pseudo(insn);
+ result = alloc_pseudo(to, insn);
insn->target = result;
insn->orig_type = from;
use_pseudo(insn, src, &insn->src);
@@ -1235,7 +1240,7 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
use_pseudo(insn, call, &insn->func);
retval = VOID;
if (expr->ctype != &void_ctype)
- retval = alloc_pseudo(insn);
+ retval = alloc_pseudo(expr->ctype, insn);
insn->target = retval;
add_one_insn(ep, insn);
@@ -1309,7 +1314,7 @@ static pseudo_t linearize_select(struct entrypoint *ep, struct expression *expr)
use_pseudo(insn, true, &insn->src2);
use_pseudo(insn, false, &insn->src3);
- res = alloc_pseudo(insn);
+ res = alloc_pseudo(expr->ctype, insn);
insn->target = res;
add_one_insn(ep, insn);
return res;
@@ -1329,7 +1334,7 @@ static pseudo_t add_join_conditional(struct entrypoint *ep, struct expression *e
phi_node = alloc_typed_instruction(OP_PHI, expr->ctype);
use_pseudo(phi_node, phi1, add_pseudo(&phi_node->phi_list, phi1));
use_pseudo(phi_node, phi2, add_pseudo(&phi_node->phi_list, phi2));
- phi_node->target = target = alloc_pseudo(phi_node);
+ phi_node->target = target = alloc_pseudo(expr->ctype, phi_node);
add_one_insn(ep, phi_node);
return target;
}
@@ -1533,7 +1538,7 @@ static void linearize_argument(struct entrypoint *ep, struct symbol *arg, int nr
ad.source_type = arg;
ad.result_type = arg;
ad.address = symbol_pseudo(ep, arg);
- linearize_store_gen(ep, argument_pseudo(ep, nr), &ad);
+ linearize_store_gen(ep, argument_pseudo(ep, arg, nr), &ad);
finish_address_gen(ep, &ad);
}
@@ -1546,10 +1551,10 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
switch (expr->type) {
case EXPR_SYMBOL:
linearize_one_symbol(ep, expr->symbol);
- return add_symbol_address(ep, expr->symbol);
+ return add_symbol_address(ep, expr->ctype, expr->symbol);
case EXPR_VALUE:
- return value_pseudo(expr->value);
+ return value_pseudo(expr->ctype, expr->value);
case EXPR_STRING: case EXPR_FVALUE: case EXPR_LABEL:
return add_setval(ep, expr->ctype, expr);
@@ -1730,7 +1735,7 @@ static void add_asm_output(struct entrypoint *ep, struct instruction *insn, stru
const char *constraint, const struct ident *ident)
{
struct access_data ad = { NULL, };
- pseudo_t pseudo = alloc_pseudo(insn);
+ pseudo_t pseudo = alloc_pseudo(expr->ctype, insn);
struct asm_constraint *rule;
if (!expr || !linearize_address_gen(ep, expr, &ad))
@@ -1863,7 +1868,7 @@ static pseudo_t linearize_return(struct entrypoint *ep, struct statement *stmt)
pseudo_t phi;
if (!phi_node) {
phi_node = alloc_typed_instruction(OP_PHI, expr->ctype);
- phi_node->target = alloc_pseudo(phi_node);
+ phi_node->target = alloc_pseudo(expr->ctype, phi_node);
phi_node->bb = bb_return;
add_instruction(&bb_return->insns, phi_node);
}
diff --git a/linearize.h b/linearize.h
index 61fbd83..ebecf25 100644
--- a/linearize.h
+++ b/linearize.h
@@ -33,6 +33,7 @@ struct pseudo {
enum pseudo_type type;
struct pseudo_user_list *users;
struct ident *ident;
+ struct symbol *ctype;
union {
struct symbol *sym;
struct instruction *def;
@@ -335,8 +336,8 @@ extern void insert_select(struct basic_block *bb, struct instruction *br, struct
extern void insert_branch(struct basic_block *bb, struct instruction *br, struct basic_block *target);
pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, int size);
-pseudo_t alloc_pseudo(struct instruction *def);
-pseudo_t value_pseudo(long long val);
+pseudo_t alloc_pseudo(struct symbol *ctype, struct instruction *def);
+pseudo_t value_pseudo(struct symbol *ctype, long long val);
struct entrypoint *linearize_symbol(struct symbol *sym);
int unssa(struct entrypoint *ep);
diff --git a/memops.c b/memops.c
index 45bd340..d72d42c 100644
--- a/memops.c
+++ b/memops.c
@@ -126,7 +126,7 @@ static void simplify_loads(struct basic_block *bb)
if (!dominators) {
if (local) {
assert(pseudo->type != PSEUDO_ARG);
- convert_load_instruction(insn, value_pseudo(0));
+ convert_load_instruction(insn, value_pseudo(insn->target->ctype, 0));
}
goto next_load;
}
diff --git a/simplify.c b/simplify.c
index bda4a5b..9f78e21 100644
--- a/simplify.c
+++ b/simplify.c
@@ -303,7 +303,7 @@ static int simplify_asr(struct instruction *insn, pseudo_t pseudo, long long val
if (value >= size) {
warning(insn->pos, "right shift by bigger than source value");
- return replace_with_pseudo(insn, value_pseudo(0));
+ return replace_with_pseudo(insn, value_pseudo(pseudo->ctype, 0));
}
if (!value)
return replace_with_pseudo(insn, pseudo);
@@ -318,7 +318,7 @@ static int simplify_constant_rightside(struct instruction *insn)
case OP_SUB:
if (value) {
insn->opcode = OP_ADD;
- insn->src2 = value_pseudo(-value);
+ insn->src2 = value_pseudo(insn->src2->ctype, -value);
return REPEAT_CSE;
}
/* Fall through */
@@ -480,7 +480,7 @@ static int simplify_constant_binop(struct instruction *insn)
}
res &= bits;
- replace_with_pseudo(insn, value_pseudo(res));
+ replace_with_pseudo(insn, value_pseudo(insn->target->ctype, res));
return REPEAT_CSE;
}
@@ -574,7 +574,7 @@ static int simplify_constant_unop(struct instruction *insn)
mask = 1ULL << (insn->size-1);
res &= mask | (mask-1);
- replace_with_pseudo(insn, value_pseudo(res));
+ replace_with_pseudo(insn, value_pseudo(insn->target->ctype, res));
return REPEAT_CSE;
}
@@ -681,7 +681,7 @@ static int simplify_cast(struct instruction *insn)
if (constant(src)) {
int sign = orig_type->ctype.modifiers & MOD_SIGNED;
long long val = get_cast_value(src->value, orig_size, size, sign);
- src = value_pseudo(val);
+ src = value_pseudo(src->ctype, val);
goto simplify;
}
diff --git a/unssa.c b/unssa.c
index 382095d..95d1877 100644
--- a/unssa.c
+++ b/unssa.c
@@ -44,7 +44,7 @@ static void replace_phi_node(struct instruction *phi)
{
pseudo_t tmp;
- tmp = alloc_pseudo(NULL);
+ tmp = alloc_pseudo(phi->target->ctype, NULL);
tmp->type = phi->target->type;
tmp->ident = phi->target->ident;
tmp->def = NULL; // defined by all the phisrc
--
1.7.9.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC][PATCH 2/3] remove ->type and ->size from struct instruction
2012-06-04 6:54 [RFC][PATCH 0/3] implement pseudo->ctype Xi Wang
2012-06-04 6:54 ` [RFC][PATCH 1/3] add ->ctype to struct pseudo Xi Wang
@ 2012-06-04 6:54 ` Xi Wang
2012-06-04 6:54 ` [RFC][PATCH 3/3] sparse, llvm: sync with new " Xi Wang
` (3 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Xi Wang @ 2012-06-04 6:54 UTC (permalink / raw)
To: linux-sparse; +Cc: Xi Wang
One can use insn->target->ctype and further ->bit_size to get ->type
and ->size of an instruction, respectively.
Suggested-by: Christopher Li <sparse@chrisli.org>
Signed-off-by: Xi Wang <xi.wang@gmail.com>
---
cse.c | 6 ++--
example.c | 12 +++----
flow.c | 10 +++---
linearize.c | 110 +++++++++++++++++++++++------------------------------------
linearize.h | 12 ++++---
memops.c | 2 +-
simplify.c | 14 ++++----
sparse.c | 2 +-
unssa.c | 1 -
9 files changed, 74 insertions(+), 95 deletions(-)
diff --git a/cse.c b/cse.c
index e8fbe34..b23d3b4 100644
--- a/cse.c
+++ b/cse.c
@@ -43,7 +43,7 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
return;
assert(insn->bb == bb);
repeat_phase |= simplify_instruction(insn);
- hash = (insn->opcode << 3) + (insn->size >> 3);
+ hash = (insn->opcode << 3) + (instruction_size(insn) >> 3);
switch (insn->opcode) {
case OP_SEL:
hash += hashval(insn->src3);
@@ -237,8 +237,8 @@ static int insn_compare(const void *_i1, const void *_i2)
default:
warning(i1->pos, "bad instruction on hash chain");
}
- if (i1->size != i2->size)
- return i1->size < i2->size ? -1 : 1;
+ if (instruction_size(i1) != instruction_size(i2))
+ return instruction_size(i1) < instruction_size(i2) ? -1 : 1;
return 0;
}
diff --git a/example.c b/example.c
index 24444c6..1c6414c 100644
--- a/example.c
+++ b/example.c
@@ -896,7 +896,7 @@ static void do_binop(struct bb_state *state, struct instruction *insn, pseudo_t
struct hardreg *dst;
dst = target_copy_reg(state, src->reg, insn->target);
- output_insn(state, "%s.%d %s,%s", op, insn->size, show_op(state, src2), dst->name);
+ output_insn(state, "%s.%d %s,%s", op, instruction_size(insn), show_op(state, src2), dst->name);
put_operand(state, src);
put_operand(state, src2);
add_pseudo_reg(state, insn->target, dst);
@@ -983,7 +983,7 @@ static void kill_dead_pseudos(struct bb_state *state)
static void generate_store(struct instruction *insn, struct bb_state *state)
{
- output_insn(state, "mov.%d %s,%s", insn->size, reg_or_imm(state, insn->target), address(state, insn));
+ output_insn(state, "mov.%d %s,%s", instruction_size(insn), reg_or_imm(state, insn->target), address(state, insn));
}
static void generate_load(struct instruction *insn, struct bb_state *state)
@@ -993,7 +993,7 @@ static void generate_load(struct instruction *insn, struct bb_state *state)
kill_dead_pseudos(state);
dst = target_reg(state, insn->target, NULL);
- output_insn(state, "mov.%d %s,%s", insn->size, input, dst->name);
+ output_insn(state, "mov.%d %s,%s", instruction_size(insn), input, dst->name);
}
static void kill_pseudo(struct bb_state *state, pseudo_t pseudo)
@@ -1031,7 +1031,7 @@ static void generate_cast(struct bb_state *state, struct instruction *insn)
struct hardreg *src = getreg(state, insn->src, insn->target);
struct hardreg *dst;
unsigned int old = insn->orig_type ? insn->orig_type->bit_size : 0;
- unsigned int new = insn->size;
+ unsigned int new = instruction_size(insn);
/*
* Cast to smaller type? Ignore the high bits, we
@@ -1050,7 +1050,7 @@ static void generate_cast(struct bb_state *state, struct instruction *insn)
unsigned long long mask;
mask = ~(~0ULL << old);
mask &= ~(~0ULL << new);
- output_insn(state, "andl.%d $%#llx,%s", insn->size, mask, dst->name);
+ output_insn(state, "andl.%d $%#llx,%s", instruction_size(insn), mask, dst->name);
}
add_pseudo_reg(state, insn->target, dst);
}
@@ -1358,7 +1358,7 @@ static void generate_compare(struct bb_state *state, struct instruction *insn)
src = getreg(state, insn->src1, insn->target);
src2 = generic(state, insn->src2);
- output_insn(state, "cmp.%d %s,%s", insn->size, src2, src->name);
+ output_insn(state, "cmp.%d %s,%s", instruction_size(insn), src2, src->name);
add_cc_cache(state, opcode, insn->target);
}
diff --git a/flow.c b/flow.c
index 45f1c8f..16a66db 100644
--- a/flow.c
+++ b/flow.c
@@ -268,8 +268,8 @@ static int overlapping_memop(struct instruction *a, struct instruction *b)
{
unsigned int a_start = bytes_to_bits(a->offset);
unsigned int b_start = bytes_to_bits(b->offset);
- unsigned int a_size = a->size;
- unsigned int b_size = b->size;
+ unsigned int a_size = instruction_size(a);
+ unsigned int b_size = instruction_size(b);
if (a_size + a_start <= b_start)
return 0;
@@ -280,7 +280,7 @@ static int overlapping_memop(struct instruction *a, struct instruction *b)
static inline int same_memop(struct instruction *a, struct instruction *b)
{
- return a->offset == b->offset && a->size == b->size;
+ return a->offset == b->offset && instruction_size(a) == instruction_size(b);
}
/*
@@ -359,7 +359,7 @@ no_dominance:
found_dominator:
br = delete_last_instruction(&parent->insns);
- phi = alloc_phi(parent, one->target, one->size);
+ phi = alloc_phi(parent, one->target);
phi->ident = phi->ident ? : pseudo->ident;
add_instruction(&parent->insns, br);
use_pseudo(insn, phi, add_pseudo(dominators, phi));
@@ -582,7 +582,7 @@ void check_access(struct instruction *insn)
pseudo_t pseudo = insn->src;
if (insn->bb && pseudo->type == PSEUDO_SYM) {
- int offset = insn->offset, bit = bytes_to_bits(offset) + insn->size;
+ int offset = insn->offset, bit = bytes_to_bits(offset) + instruction_size(insn);
struct symbol *sym = pseudo->sym;
if (sym->bit_size > 0 && (offset < 0 || bit > sym->bit_size))
diff --git a/linearize.c b/linearize.c
index a4bf309..82e8482 100644
--- a/linearize.c
+++ b/linearize.c
@@ -39,11 +39,10 @@ static struct position current_pos;
ALLOCATOR(pseudo_user, "pseudo_user");
-static struct instruction *alloc_instruction(int opcode, int size)
+static struct instruction *alloc_instruction(int opcode)
{
struct instruction * insn = __alloc_instruction(0);
insn->opcode = opcode;
- insn->size = size;
insn->pos = current_pos;
return insn;
}
@@ -53,13 +52,15 @@ static inline int type_size(struct symbol *type)
return type ? type->bit_size > 0 ? type->bit_size : 0 : 0;
}
-static struct instruction *alloc_typed_instruction(int opcode, struct symbol *type)
+static struct instruction *alloc_typed_instruction(int opcode, struct symbol *ctype)
{
- struct instruction *insn = alloc_instruction(opcode, type_size(type));
- insn->type = type;
+ struct instruction *insn = alloc_instruction(opcode);
+ struct pseudo *target = (ctype == &void_ctype) ? VOID : alloc_pseudo(ctype, insn);
+ insn->target = target;
return insn;
}
+
static struct entrypoint *alloc_entrypoint(void)
{
return __alloc_entrypoint(0);
@@ -288,8 +289,8 @@ const char *show_instruction(struct instruction *insn)
buf += sprintf(buf, "opcode:%d", opcode);
else
buf += sprintf(buf, "%s", op);
- if (insn->size)
- buf += sprintf(buf, ".%d", insn->size);
+ if (instruction_size(insn))
+ buf += sprintf(buf, ".%d", instruction_size(insn));
memset(buf, ' ', 20);
buf++;
}
@@ -602,7 +603,7 @@ static void add_goto(struct entrypoint *ep, struct basic_block *dst)
{
struct basic_block *src = ep->active;
if (bb_reachable(src)) {
- struct instruction *br = alloc_instruction(OP_BR, 0);
+ struct instruction *br = alloc_instruction(OP_BR);
br->bb_true = dst;
add_bb(&dst->parents, src);
add_bb(&src->children, dst);
@@ -649,7 +650,7 @@ void insert_branch(struct basic_block *bb, struct instruction *jmp, struct basic
old = delete_last_instruction(&bb->insns);
assert(old == jmp);
- br = alloc_instruction(OP_BR, 0);
+ br = alloc_instruction(OP_BR);
br->bb = bb;
br->bb_true = target;
add_instruction(&bb->insns, br);
@@ -674,7 +675,7 @@ void insert_select(struct basic_block *bb, struct instruction *br, struct instru
/* Remove the 'br' */
delete_last_instruction(&bb->insns);
- select = alloc_instruction(OP_SEL, phi_node->size);
+ select = alloc_instruction(OP_SEL);
select->bb = bb;
assert(br->cond);
@@ -721,7 +722,7 @@ static void add_branch(struct entrypoint *ep, struct expression *expr, pseudo_t
struct instruction *br;
if (bb_reachable(bb)) {
- br = alloc_instruction(OP_BR, 0);
+ br = alloc_instruction(OP_BR);
use_pseudo(br, cond, &br->cond);
br->bb_true = bb_true;
br->bb_false = bb_false;
@@ -814,9 +815,9 @@ static pseudo_t argument_pseudo(struct entrypoint *ep, struct symbol *ctype, int
return pseudo;
}
-pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, int size)
+pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo)
{
- struct instruction *insn = alloc_instruction(OP_PHISOURCE, size);
+ struct instruction *insn = alloc_instruction(OP_PHISOURCE);
pseudo_t phi = __alloc_pseudo(0);
static int nr = 0;
@@ -916,14 +917,12 @@ static pseudo_t add_load(struct entrypoint *ep, struct access_data *ad)
return new;
insn = alloc_typed_instruction(OP_LOAD, ad->source_type);
- new = alloc_pseudo(ad->source_type, insn);
- ad->origval = new;
+ ad->origval = insn->target;
- insn->target = new;
insn->offset = ad->offset;
use_pseudo(insn, ad->address, &insn->src);
add_one_insn(ep, insn);
- return new;
+ return insn->target;
}
static void add_store(struct entrypoint *ep, struct access_data *ad, pseudo_t value)
@@ -931,7 +930,7 @@ static void add_store(struct entrypoint *ep, struct access_data *ad, pseudo_t va
struct basic_block *bb = ep->active;
if (bb_reachable(bb)) {
- struct instruction *store = alloc_typed_instruction(OP_STORE, ad->source_type);
+ struct instruction *store = alloc_instruction(OP_STORE);
store->offset = ad->offset;
use_pseudo(store, value, &store->target);
use_pseudo(store, ad->address, &store->src);
@@ -964,27 +963,23 @@ static pseudo_t linearize_store_gen(struct entrypoint *ep,
static pseudo_t add_binary_op(struct entrypoint *ep, struct symbol *ctype, int op, pseudo_t left, pseudo_t right)
{
struct instruction *insn = alloc_typed_instruction(op, ctype);
- pseudo_t target = alloc_pseudo(ctype, insn);
- insn->target = target;
use_pseudo(insn, left, &insn->src1);
use_pseudo(insn, right, &insn->src2);
add_one_insn(ep, insn);
- return target;
+ return insn->target;
}
static pseudo_t add_setval(struct entrypoint *ep, struct symbol *ctype, struct expression *val)
{
struct instruction *insn = alloc_typed_instruction(OP_SETVAL, ctype);
- pseudo_t target = alloc_pseudo(ctype, insn);
- insn->target = target;
insn->val = val;
add_one_insn(ep, insn);
- return target;
+ return insn->target;
}
static pseudo_t add_symbol_address(struct entrypoint *ep, struct symbol *ctype, struct symbol *sym)
{
- struct instruction *insn = alloc_instruction(OP_SYMADDR, bits_in_pointer);
+ struct instruction *insn = alloc_instruction(OP_SYMADDR);
pseudo_t target = alloc_pseudo(ctype, insn);
insn->target = target;
@@ -1022,7 +1017,7 @@ static pseudo_t linearize_access(struct entrypoint *ep, struct expression *expr)
static pseudo_t linearize_inc_dec(struct entrypoint *ep, struct expression *expr, int postop)
{
struct access_data ad = { NULL, };
- pseudo_t old, new, one;
+ pseudo_t old, new, one;
int op = expr->op == SPECIAL_INCREMENT ? OP_ADD : OP_SUB;
if (!linearize_address_gen(ep, expr->unop, &ad))
@@ -1039,26 +1034,21 @@ static pseudo_t linearize_inc_dec(struct entrypoint *ep, struct expression *expr
static pseudo_t add_uniop(struct entrypoint *ep, struct expression *expr, int op, pseudo_t src)
{
struct instruction *insn = alloc_typed_instruction(op, expr->ctype);
- pseudo_t new = alloc_pseudo(expr->ctype, insn);
-
- insn->target = new;
use_pseudo(insn, src, &insn->src1);
add_one_insn(ep, insn);
- return new;
+ return insn->target;
}
static pseudo_t linearize_slice(struct entrypoint *ep, struct expression *expr)
{
pseudo_t pre = linearize_expression(ep, expr->base);
struct instruction *insn = alloc_typed_instruction(OP_SLICE, expr->ctype);
- pseudo_t new = alloc_pseudo(expr->ctype, insn);
- insn->target = new;
insn->from = expr->r_bitpos;
insn->len = expr->r_nrbits;
use_pseudo(insn, pre, &insn->base);
add_one_insn(ep, insn);
- return new;
+ return insn->target;
}
static pseudo_t linearize_regular_preop(struct entrypoint *ep, struct expression *expr)
@@ -1125,7 +1115,6 @@ static struct instruction *alloc_cast_instruction(struct symbol *src, struct sym
static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *from, struct symbol *to)
{
- pseudo_t result;
struct instruction *insn;
if (src == VOID)
@@ -1135,12 +1124,10 @@ static pseudo_t cast_pseudo(struct entrypoint *ep, pseudo_t src, struct symbol *
if (from->bit_size < 0 || to->bit_size < 0)
return VOID;
insn = alloc_cast_instruction(from, to);
- result = alloc_pseudo(to, insn);
- insn->target = result;
insn->orig_type = from;
use_pseudo(insn, src, &insn->src);
add_one_insn(ep, insn);
- return result;
+ return insn->target;
}
static int opcode_sign(int opcode, struct symbol *ctype)
@@ -1198,7 +1185,7 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
{
struct expression *arg, *fn;
struct instruction *insn = alloc_typed_instruction(OP_CALL, expr->ctype);
- pseudo_t retval, call;
+ pseudo_t call;
struct ctype *ctype = NULL;
struct symbol *fntype;
struct context *context;
@@ -1238,10 +1225,6 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
call = linearize_expression(ep, fn);
}
use_pseudo(insn, call, &insn->func);
- retval = VOID;
- if (expr->ctype != &void_ctype)
- retval = alloc_pseudo(expr->ctype, insn);
- insn->target = retval;
add_one_insn(ep, insn);
if (ctype) {
@@ -1260,7 +1243,7 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
}
context_diff = out - in;
if (check || context_diff) {
- insn = alloc_instruction(OP_CONTEXT, 0);
+ insn = alloc_instruction(OP_CONTEXT);
insn->increment = context_diff;
insn->check = check;
insn->context_expr = context->context;
@@ -1269,7 +1252,7 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
} END_FOR_EACH_PTR(context);
}
- return retval;
+ return insn->target;
}
static pseudo_t linearize_binop(struct entrypoint *ep, struct expression *expr)
@@ -1300,7 +1283,7 @@ pseudo_t linearize_cond_branch(struct entrypoint *ep, struct expression *expr, s
static pseudo_t linearize_select(struct entrypoint *ep, struct expression *expr)
{
- pseudo_t cond, true, false, res;
+ pseudo_t cond, true, false;
struct instruction *insn;
true = linearize_expression(ep, expr->cond_true);
@@ -1314,16 +1297,13 @@ static pseudo_t linearize_select(struct entrypoint *ep, struct expression *expr)
use_pseudo(insn, true, &insn->src2);
use_pseudo(insn, false, &insn->src3);
- res = alloc_pseudo(expr->ctype, insn);
- insn->target = res;
add_one_insn(ep, insn);
- return res;
+ return insn->target;
}
static pseudo_t add_join_conditional(struct entrypoint *ep, struct expression *expr,
pseudo_t phi1, pseudo_t phi2)
{
- pseudo_t target;
struct instruction *phi_node;
if (phi1 == VOID)
@@ -1334,10 +1314,9 @@ static pseudo_t add_join_conditional(struct entrypoint *ep, struct expression *e
phi_node = alloc_typed_instruction(OP_PHI, expr->ctype);
use_pseudo(phi_node, phi1, add_pseudo(&phi_node->phi_list, phi1));
use_pseudo(phi_node, phi2, add_pseudo(&phi_node->phi_list, phi2));
- phi_node->target = target = alloc_pseudo(expr->ctype, phi_node);
add_one_insn(ep, phi_node);
- return target;
-}
+ return phi_node->target;
+}
static pseudo_t linearize_short_conditional(struct entrypoint *ep, struct expression *expr,
struct expression *cond,
@@ -1347,19 +1326,18 @@ static pseudo_t linearize_short_conditional(struct entrypoint *ep, struct expres
struct basic_block *bb_false;
struct basic_block *merge = alloc_basic_block(ep, expr->pos);
pseudo_t phi1, phi2;
- int size = type_size(expr->ctype);
if (!expr_false || !ep->active)
return VOID;
bb_false = alloc_basic_block(ep, expr_false->pos);
src1 = linearize_expression(ep, cond);
- phi1 = alloc_phi(ep->active, src1, size);
+ phi1 = alloc_phi(ep->active, src1);
add_branch(ep, expr, src1, merge, bb_false);
set_activeblock(ep, bb_false);
src2 = linearize_expression(ep, expr_false);
- phi2 = alloc_phi(ep->active, src2, size);
+ phi2 = alloc_phi(ep->active, src2);
set_activeblock(ep, merge);
return add_join_conditional(ep, expr, phi1, phi2);
@@ -1373,7 +1351,6 @@ static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *
pseudo_t src1, src2;
pseudo_t phi1, phi2;
struct basic_block *bb_true, *bb_false, *merge;
- int size = type_size(expr->ctype);
if (!cond || !expr_true || !expr_false || !ep->active)
return VOID;
@@ -1385,12 +1362,12 @@ static pseudo_t linearize_conditional(struct entrypoint *ep, struct expression *
set_activeblock(ep, bb_true);
src1 = linearize_expression(ep, expr_true);
- phi1 = alloc_phi(ep->active, src1, size);
+ phi1 = alloc_phi(ep->active, src1);
add_goto(ep, merge);
set_activeblock(ep, bb_false);
src2 = linearize_expression(ep, expr_false);
- phi2 = alloc_phi(ep->active, src2, size);
+ phi2 = alloc_phi(ep->active, src2);
set_activeblock(ep, merge);
return add_join_conditional(ep, expr, phi1, phi2);
@@ -1666,7 +1643,7 @@ static pseudo_t linearize_compound_statement(struct entrypoint *ep, struct state
static pseudo_t linearize_inlined_call(struct entrypoint *ep, struct statement *stmt)
{
- struct instruction *insn = alloc_instruction(OP_INLINED_CALL, 0);
+ struct instruction *insn = alloc_instruction(OP_INLINED_CALL);
struct statement *args = stmt->args;
struct basic_block *bb;
pseudo_t pseudo;
@@ -1692,7 +1669,7 @@ static pseudo_t linearize_inlined_call(struct entrypoint *ep, struct statement *
static pseudo_t linearize_context(struct entrypoint *ep, struct statement *stmt)
{
- struct instruction *insn = alloc_instruction(OP_CONTEXT, 0);
+ struct instruction *insn = alloc_instruction(OP_CONTEXT);
struct expression *expr = stmt->expression;
int value = 0;
@@ -1707,7 +1684,7 @@ static pseudo_t linearize_context(struct entrypoint *ep, struct statement *stmt)
static pseudo_t linearize_range(struct entrypoint *ep, struct statement *stmt)
{
- struct instruction *insn = alloc_instruction(OP_RANGE, 0);
+ struct instruction *insn = alloc_instruction(OP_RANGE);
use_pseudo(insn, linearize_expression(ep, stmt->range_expression), &insn->src1);
use_pseudo(insn, linearize_expression(ep, stmt->range_low), &insn->src2);
@@ -1758,7 +1735,7 @@ static pseudo_t linearize_asm_statement(struct entrypoint *ep, struct statement
const char *constraint;
struct ident *ident;
- insn = alloc_instruction(OP_ASM, 0);
+ insn = alloc_instruction(OP_ASM);
expr = stmt->asm_string;
if (!expr || expr->type != EXPR_STRING) {
warning(stmt->pos, "expected string in inline asm");
@@ -1868,11 +1845,10 @@ static pseudo_t linearize_return(struct entrypoint *ep, struct statement *stmt)
pseudo_t phi;
if (!phi_node) {
phi_node = alloc_typed_instruction(OP_PHI, expr->ctype);
- phi_node->target = alloc_pseudo(expr->ctype, phi_node);
phi_node->bb = bb_return;
add_instruction(&bb_return->insns, phi_node);
}
- phi = alloc_phi(active, src, type_size(expr->ctype));
+ phi = alloc_phi(active, src);
phi->ident = &return_ident;
use_pseudo(phi_node, phi, add_pseudo(&phi_node->phi_list, phi));
}
@@ -1895,7 +1871,7 @@ static pseudo_t linearize_switch(struct entrypoint *ep, struct statement *stmt)
if (!bb_reachable(active))
return VOID;
- switch_ins = alloc_instruction(OP_SWITCH, 0);
+ switch_ins = alloc_instruction(OP_SWITCH);
use_pseudo(switch_ins, pseudo, &switch_ins->cond);
add_one_insn(ep, switch_ins);
finish_block(ep);
@@ -2063,7 +2039,7 @@ pseudo_t linearize_statement(struct entrypoint *ep, struct statement *stmt)
}
pseudo = linearize_expression(ep, expr);
- goto_ins = alloc_instruction(OP_COMPUTEDGOTO, 0);
+ goto_ins = alloc_instruction(OP_COMPUTEDGOTO);
use_pseudo(goto_ins, pseudo, &goto_ins->target);
add_one_insn(ep, goto_ins);
@@ -2141,7 +2117,7 @@ static struct entrypoint *linearize_fn(struct symbol *sym, struct symbol *base_t
sym->ep = ep;
set_activeblock(ep, bb);
- entry = alloc_instruction(OP_ENTRY, 0);
+ entry = alloc_instruction(OP_ENTRY);
add_one_insn(ep, entry);
ep->entry = entry;
diff --git a/linearize.h b/linearize.h
index ebecf25..8f24e67 100644
--- a/linearize.h
+++ b/linearize.h
@@ -69,11 +69,9 @@ struct asm_rules {
DECLARE_ALLOCATOR(asm_rules);
struct instruction {
- unsigned opcode:8,
- size:24;
+ unsigned opcode;
struct basic_block *bb;
struct position pos;
- struct symbol *type;
union {
pseudo_t target;
pseudo_t cond; /* for branch and switch */
@@ -237,6 +235,12 @@ struct basic_block {
void *priv;
};
+static inline int instruction_size(const struct instruction *insn)
+{
+ struct symbol *type = insn->target ? insn->target->ctype : NULL;
+ return type ? type->bit_size > 0 ? type->bit_size : 0 : 0;
+}
+
static inline int is_branch_goto(struct instruction *br)
{
return br && br->opcode==OP_BR && (!br->bb_true || !br->bb_false);
@@ -335,7 +339,7 @@ struct entrypoint {
extern void insert_select(struct basic_block *bb, struct instruction *br, struct instruction *phi, pseudo_t if_true, pseudo_t if_false);
extern void insert_branch(struct basic_block *bb, struct instruction *br, struct basic_block *target);
-pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo, int size);
+pseudo_t alloc_phi(struct basic_block *source, pseudo_t pseudo);
pseudo_t alloc_pseudo(struct symbol *ctype, struct instruction *def);
pseudo_t value_pseudo(struct symbol *ctype, long long val);
diff --git a/memops.c b/memops.c
index d72d42c..dcfeda9 100644
--- a/memops.c
+++ b/memops.c
@@ -56,7 +56,7 @@ no_dominance:
found_dominator:
br = delete_last_instruction(&parent->insns);
- phi = alloc_phi(parent, one->target, one->size);
+ phi = alloc_phi(parent, one->target);
phi->ident = phi->ident ? : one->target->ident;
add_instruction(&parent->insns, br);
use_pseudo(insn, phi, add_pseudo(dominators, phi));
diff --git a/simplify.c b/simplify.c
index 9f78e21..4c41436 100644
--- a/simplify.c
+++ b/simplify.c
@@ -279,7 +279,7 @@ static unsigned int value_size(long long value)
*/
static unsigned int operand_size(struct instruction *insn, pseudo_t pseudo)
{
- unsigned int size = insn->size;
+ unsigned int size = instruction_size(insn);
if (pseudo->type == PSEUDO_REG) {
struct instruction *src = pseudo->def;
@@ -375,7 +375,7 @@ static int simplify_constant_binop(struct instruction *insn)
unsigned long long ul, ur;
long long res, mask, bits;
- mask = 1ULL << (insn->size-1);
+ mask = 1ULL << (instruction_size(insn)-1);
bits = mask | (mask-1);
if (left & mask)
@@ -571,7 +571,7 @@ static int simplify_constant_unop(struct instruction *insn)
default:
return 0;
}
- mask = 1ULL << (insn->size-1);
+ mask = 1ULL << (instruction_size(insn)-1);
res &= mask | (mask-1);
replace_with_pseudo(insn, value_pseudo(insn->target->ctype, res));
@@ -670,11 +670,11 @@ static int simplify_cast(struct instruction *insn)
return 0;
/* Keep casts with pointer on either side (not only case of OP_PTRCAST) */
- if (is_ptr_type(orig_type) || is_ptr_type(insn->type))
+ if (is_ptr_type(orig_type) || is_ptr_type(insn->target->ctype))
return 0;
orig_size = orig_type->bit_size;
- size = insn->size;
+ size = instruction_size(insn);
src = insn->src;
/* A cast of a constant? */
@@ -688,7 +688,7 @@ static int simplify_cast(struct instruction *insn)
/* A cast of a "and" might be a no-op.. */
if (src->type == PSEUDO_REG) {
struct instruction *def = src->def;
- if (def->opcode == OP_AND && def->size >= size) {
+ if (def->opcode == OP_AND && instruction_size(def) >= size) {
pseudo_t val = def->src2;
if (val->type == PSEUDO_VAL) {
unsigned long long value = val->value;
@@ -854,7 +854,7 @@ static int simplify_branch(struct instruction *insn)
}
if (def->opcode == OP_CAST || def->opcode == OP_SCAST) {
int orig_size = def->orig_type ? def->orig_type->bit_size : 0;
- if (def->size > orig_size) {
+ if (instruction_size(def) > orig_size) {
use_pseudo(insn, def->src, &insn->cond);
remove_usage(cond, &insn->cond);
return REPEAT_CSE;
diff --git a/sparse.c b/sparse.c
index 67b7d9e..ba13f63 100644
--- a/sparse.c
+++ b/sparse.c
@@ -102,7 +102,7 @@ static void check_cast_instruction(struct instruction *insn)
struct symbol *orig_type = insn->orig_type;
if (orig_type) {
int old = orig_type->bit_size;
- int new = insn->size;
+ int new = instruction_size(insn);
int oldsigned = (orig_type->ctype.modifiers & MOD_SIGNED) != 0;
int newsigned = insn->opcode == OP_SCAST;
diff --git a/unssa.c b/unssa.c
index 95d1877..169e819 100644
--- a/unssa.c
+++ b/unssa.c
@@ -105,7 +105,6 @@ static void rewrite_phisrc_bb(struct basic_block *bb)
copy->bb = bb;
copy->opcode = OP_COPY;
- copy->size = insn->size;
copy->pos = insn->pos;
copy->target = tmp;
copy->src = src;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [RFC][PATCH 3/3] sparse, llvm: sync with new struct instruction
2012-06-04 6:54 [RFC][PATCH 0/3] implement pseudo->ctype Xi Wang
2012-06-04 6:54 ` [RFC][PATCH 1/3] add ->ctype to struct pseudo Xi Wang
2012-06-04 6:54 ` [RFC][PATCH 2/3] remove ->type and ->size from struct instruction Xi Wang
@ 2012-06-04 6:54 ` Xi Wang
2012-06-08 11:50 ` [RFC][PATCH 0/3] implement pseudo->ctype Pekka Enberg
` (2 subsequent siblings)
5 siblings, 0 replies; 14+ messages in thread
From: Xi Wang @ 2012-06-04 6:54 UTC (permalink / raw)
To: linux-sparse; +Cc: Xi Wang
This patch is basically substitutes insn->type and insn->size with
insn->target->ctype and instruction_size(insn), respectively. With
the new ->ctype in struct pseudo, generating LLVM IR should be much
simpler.
Signed-off-by: Xi Wang <xi.wang@gmail.com>
---
sparse-llvm.c | 50 +++++++++++++++++++++++++-------------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/sparse-llvm.c b/sparse-llvm.c
index 9226a21..49c00ca 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -236,17 +236,17 @@ static LLVMTypeRef symbol_type(LLVMModuleRef module, struct symbol *sym)
static LLVMTypeRef insn_symbol_type(LLVMModuleRef module, struct instruction *insn)
{
- if (insn->type)
- return symbol_type(module, insn->type);
+ if (insn->target && insn->target->ctype)
+ return symbol_type(module, insn->target->ctype);
- switch (insn->size) {
+ switch (instruction_size(insn)) {
case 8: return LLVMInt8Type();
case 16: return LLVMInt16Type();
case 32: return LLVMInt32Type();
case 64: return LLVMInt64Type();
default:
- die("invalid bit size %d", insn->size);
+ die("invalid bit size %d", instruction_size(insn));
break;
}
@@ -364,7 +364,7 @@ static LLVMTypeRef pseudo_type(struct function *fn, struct instruction *insn, ps
switch (pseudo->type) {
case PSEUDO_REG:
- result = symbol_type(fn->module, pseudo->def->type);
+ result = symbol_type(fn->module, pseudo->def->target->ctype);
break;
case PSEUDO_SYM: {
struct symbol *sym = pseudo->sym;
@@ -455,75 +455,75 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
switch (insn->opcode) {
/* Binary */
case OP_ADD:
- if (symbol_is_fp_type(insn->type))
+ if (symbol_is_fp_type(insn->target->ctype))
target = LLVMBuildFAdd(fn->builder, lhs, rhs, target_name);
else
target = LLVMBuildAdd(fn->builder, lhs, rhs, target_name);
break;
case OP_SUB:
- if (symbol_is_fp_type(insn->type))
+ if (symbol_is_fp_type(insn->target->ctype))
target = LLVMBuildFSub(fn->builder, lhs, rhs, target_name);
else
target = LLVMBuildSub(fn->builder, lhs, rhs, target_name);
break;
case OP_MULU:
- if (symbol_is_fp_type(insn->type))
+ if (symbol_is_fp_type(insn->target->ctype))
target = LLVMBuildFMul(fn->builder, lhs, rhs, target_name);
else
target = LLVMBuildMul(fn->builder, lhs, rhs, target_name);
break;
case OP_MULS:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildMul(fn->builder, lhs, rhs, target_name);
break;
case OP_DIVU:
- if (symbol_is_fp_type(insn->type))
+ if (symbol_is_fp_type(insn->target->ctype))
target = LLVMBuildFDiv(fn->builder, lhs, rhs, target_name);
else
target = LLVMBuildUDiv(fn->builder, lhs, rhs, target_name);
break;
case OP_DIVS:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildSDiv(fn->builder, lhs, rhs, target_name);
break;
case OP_MODU:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildURem(fn->builder, lhs, rhs, target_name);
break;
case OP_MODS:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildSRem(fn->builder, lhs, rhs, target_name);
break;
case OP_SHL:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildShl(fn->builder, lhs, rhs, target_name);
break;
case OP_LSR:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildLShr(fn->builder, lhs, rhs, target_name);
break;
case OP_ASR:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildAShr(fn->builder, lhs, rhs, target_name);
break;
/* Logical */
case OP_AND:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildAnd(fn->builder, lhs, rhs, target_name);
break;
case OP_OR:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildOr(fn->builder, lhs, rhs, target_name);
break;
case OP_XOR:
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildXor(fn->builder, lhs, rhs, target_name);
break;
case OP_AND_BOOL: {
LLVMValueRef x, y;
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
y = LLVMBuildICmp(fn->builder, LLVMIntNE, lhs, LLVMConstInt(LLVMTypeOf(lhs), 0, 0), "y");
x = LLVMBuildICmp(fn->builder, LLVMIntNE, rhs, LLVMConstInt(LLVMTypeOf(rhs), 0, 0), "x");
@@ -534,7 +534,7 @@ static void output_op_binary(struct function *fn, struct instruction *insn)
case OP_OR_BOOL: {
LLVMValueRef tmp;
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
tmp = LLVMBuildOr(fn->builder, rhs, lhs, "tmp");
@@ -914,7 +914,7 @@ static void output_op_ptrcast(struct function *fn, struct instruction *insn)
pseudo_name(insn->target, target_name);
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
target = LLVMBuildBitCast(fn->builder, src, insn_symbol_type(fn->module, insn), target_name);
@@ -932,9 +932,9 @@ static void output_op_cast(struct function *fn, struct instruction *insn, LLVMOp
pseudo_name(insn->target, target_name);
- assert(!symbol_is_fp_type(insn->type));
+ assert(!symbol_is_fp_type(insn->target->ctype));
- if (insn->size < LLVMGetIntTypeWidth(LLVMTypeOf(src)))
+ if (instruction_size(insn) < LLVMGetIntTypeWidth(LLVMTypeOf(src)))
target = LLVMBuildTrunc(fn->builder, src, insn_symbol_type(fn->module, insn), target_name);
else
target = LLVMBuildCast(fn->builder, op, src, insn_symbol_type(fn->module, insn), target_name);
@@ -960,7 +960,7 @@ static void output_op_copy(struct function *fn, struct instruction *insn,
* than using "X + 0" simply to produce a new LLVM pseudo
*/
- if (symbol_is_fp_type(insn->type))
+ if (symbol_is_fp_type(insn->target->ctype))
target = LLVMBuildFAdd(fn->builder, src,
LLVMConstReal(const_type, 0.0), target_name);
else
--
1.7.9.5
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-04 6:54 [RFC][PATCH 0/3] implement pseudo->ctype Xi Wang
` (2 preceding siblings ...)
2012-06-04 6:54 ` [RFC][PATCH 3/3] sparse, llvm: sync with new " Xi Wang
@ 2012-06-08 11:50 ` Pekka Enberg
2012-06-08 15:39 ` Xi Wang
2012-06-09 1:35 ` Xi Wang
2012-06-21 10:00 ` Christopher Li
5 siblings, 1 reply; 14+ messages in thread
From: Pekka Enberg @ 2012-06-08 11:50 UTC (permalink / raw)
To: Xi Wang; +Cc: linux-sparse, Jeff Garzik, Benjamin Herrenschmidt, Christopher Li
On Mon, Jun 4, 2012 at 9:54 AM, Xi Wang <xi.wang@gmail.com> wrote:
> This patchset tries to implement Chris's `counter RFC': adding ->ctype
> to pseudo, while removing ->type and ->size from instruction. In this
> way, it provides easy access to type information for backend.
Could you please CC me on patches that touch Sparse/LLVM in the future?
The LLVM parts look good to me:
Acked-by: Pekka Enberg <penberg@kernel.org>
--
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
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-08 11:50 ` [RFC][PATCH 0/3] implement pseudo->ctype Pekka Enberg
@ 2012-06-08 15:39 ` Xi Wang
0 siblings, 0 replies; 14+ messages in thread
From: Xi Wang @ 2012-06-08 15:39 UTC (permalink / raw)
To: Pekka Enberg
Cc: linux-sparse, Jeff Garzik, Benjamin Herrenschmidt, Christopher Li
I should have done that. Sorry.
Thanks for reviewing!
- xi
On Jun 8, 2012, at 7:50 AM, Pekka Enberg wrote:
>
> Could you please CC me on patches that touch Sparse/LLVM in the future?
>
> The LLVM parts look good to me:
>
> Acked-by: Pekka Enberg <penberg@kernel.org>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-04 6:54 [RFC][PATCH 0/3] implement pseudo->ctype Xi Wang
` (3 preceding siblings ...)
2012-06-08 11:50 ` [RFC][PATCH 0/3] implement pseudo->ctype Pekka Enberg
@ 2012-06-09 1:35 ` Xi Wang
2012-06-09 10:42 ` Pekka Enberg
2012-06-21 10:00 ` Christopher Li
5 siblings, 1 reply; 14+ messages in thread
From: Xi Wang @ 2012-06-09 1:35 UTC (permalink / raw)
To: linux-sparse
Cc: Pekka Enberg, Jeff Garzik, Benjamin Herrenschmidt, Christopher Li,
Linus Torvalds
I played with the new ->ctype in pseudo a little bit to generate LLVM IR.
It seems much easier to emit correct type at backend using ->ctype.
The code is available at:
git clone --recursive https://github.com/xiw/splay.git
Try `make' and `make check' if you have LLVM.
See example inputs in `test'. Currently the generator works for simple
programs like md5.c (with -D_FORTIFY_SOURCE=0).
You can also find patches to sparse at:
https://github.com/xiw/sparse/compare/splay
- xi
On Jun 4, 2012, at 2:54 AM, Xi Wang wrote:
> This patchset tries to implement Chris's `counter RFC': adding ->ctype
> to pseudo, while removing ->type and ->size from instruction. In this
> way, it provides easy access to type information for backend.
>
> The first patch adds ->ctype to struct pseudo and doesn't touch struct
> instruction. It could be applied alone if we really want backward
> compatibility.
>
> The second patch does more destructive work. It removes ->type and
> ->size from struct instruction and updates client uses.
>
> The third patch updates sparse-llvm in a naive way, which should have
> been much simpler with the new ->ctype in pseudo. I guess in some cases
> ->ctype is even necessary. Consider the example below.
>
> void foo(int x, ...);
> foo(1, 2, 3LL);
>
> Is it possible to get the types of the 2nd and 3rd arguments in current
> code, which are simply PSEUDO_VAL?
>
> Xi Wang (3):
> add ->ctype to struct pseudo
> remove ->type and ->size from struct instruction
> sparse, llvm: sync with new struct instruction
>
> cse.c | 6 +--
> example.c | 12 ++---
> flow.c | 12 ++---
> linearize.c | 147 +++++++++++++++++++++++++--------------------------------
> linearize.h | 17 ++++---
> memops.c | 4 +-
> simplify.c | 24 +++++-----
> sparse-llvm.c | 50 ++++++++++----------
> sparse.c | 2 +-
> unssa.c | 3 +-
> 10 files changed, 131 insertions(+), 146 deletions(-)
>
> --
> 1.7.9.5
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-09 1:35 ` Xi Wang
@ 2012-06-09 10:42 ` Pekka Enberg
2012-06-09 11:52 ` Xi Wang
0 siblings, 1 reply; 14+ messages in thread
From: Pekka Enberg @ 2012-06-09 10:42 UTC (permalink / raw)
To: Xi Wang
Cc: linux-sparse, Jeff Garzik, Benjamin Herrenschmidt, Christopher Li,
Linus Torvalds
On Sat, Jun 9, 2012 at 4:35 AM, Xi Wang <xi.wang@gmail.com> wrote:
> I played with the new ->ctype in pseudo a little bit to generate LLVM IR.
> It seems much easier to emit correct type at backend using ->ctype.
>
> The code is available at:
>
> git clone --recursive https://github.com/xiw/splay.git
>
> Try `make' and `make check' if you have LLVM.
>
> See example inputs in `test'. Currently the generator works for simple
> programs like md5.c (with -D_FORTIFY_SOURCE=0).
>
> You can also find patches to sparse at:
>
> https://github.com/xiw/sparse/compare/splay
Interesting. What are you planning to do with "splay"? Is there
something that prevents fixing the current LLVM backend in master?
--
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
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-09 10:42 ` Pekka Enberg
@ 2012-06-09 11:52 ` Xi Wang
2012-06-09 12:06 ` Jeff Garzik
2012-06-09 12:12 ` Pekka Enberg
0 siblings, 2 replies; 14+ messages in thread
From: Xi Wang @ 2012-06-09 11:52 UTC (permalink / raw)
To: Pekka Enberg
Cc: linux-sparse, Jeff Garzik, Benjamin Herrenschmidt, Christopher Li,
Linus Torvalds
On Jun 9, 2012, at 6:42 AM, Pekka Enberg wrote:
> Interesting. What are you planning to do with "splay"? Is there
> something that prevents fixing the current LLVM backend in master?
Just did this to try the new ->ctype in pseudo. I don't want to
maintain another llvm backend for sparse. :-)
BTW, I feel like LLVM's C interface is very incomplete. I had to
wrap some code in C++.
Besides, the phi nodes in sparse and LLVM are different. LLVM's
phi 1) requires one entry for each predecessor, and 2) must stay
at the beginning of a block. I didn't find an easy way to translate
sparse's phi to LLVM's, so instead generated load/store for phi
nodes.
- xi
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-09 11:52 ` Xi Wang
@ 2012-06-09 12:06 ` Jeff Garzik
2012-06-09 12:12 ` Pekka Enberg
1 sibling, 0 replies; 14+ messages in thread
From: Jeff Garzik @ 2012-06-09 12:06 UTC (permalink / raw)
To: Xi Wang
Cc: Pekka Enberg, linux-sparse, Benjamin Herrenschmidt,
Christopher Li, Linus Torvalds
On 06/09/2012 07:52 AM, Xi Wang wrote:
> Besides, the phi nodes in sparse and LLVM are different. LLVM's
> phi 1) requires one entry for each predecessor, and 2) must stay
> at the beginning of a block. I didn't find an easy way to translate
> sparse's phi to LLVM's, so instead generated load/store for phi
> nodes.
That is reasonable.
Jeff
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-09 11:52 ` Xi Wang
2012-06-09 12:06 ` Jeff Garzik
@ 2012-06-09 12:12 ` Pekka Enberg
1 sibling, 0 replies; 14+ messages in thread
From: Pekka Enberg @ 2012-06-09 12:12 UTC (permalink / raw)
To: Xi Wang
Cc: linux-sparse, Jeff Garzik, Benjamin Herrenschmidt, Christopher Li,
Linus Torvalds
On Sat, Jun 9, 2012 at 2:52 PM, Xi Wang <xi.wang@gmail.com> wrote:
> BTW, I feel like LLVM's C interface is very incomplete. I had to
> wrap some code in C++.
It'd probably be best to try to get the LLVM C API fixed upstream.
I've seen with the libcpu project what happens when you write your
core code in C but use the LLVM C++ APIs, and it's not pretty... ;-)
--
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
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-04 6:54 [RFC][PATCH 0/3] implement pseudo->ctype Xi Wang
` (4 preceding siblings ...)
2012-06-09 1:35 ` Xi Wang
@ 2012-06-21 10:00 ` Christopher Li
2012-06-22 2:08 ` Xi Wang
5 siblings, 1 reply; 14+ messages in thread
From: Christopher Li @ 2012-06-21 10:00 UTC (permalink / raw)
To: Xi Wang; +Cc: linux-sparse
On Sun, Jun 3, 2012 at 11:54 PM, Xi Wang <xi.wang@gmail.com> wrote:
> This patchset tries to implement Chris's `counter RFC': adding ->ctype
> to pseudo, while removing ->type and ->size from instruction. In this
> way, it provides easy access to type information for backend.
I like this series a lot. Do you have an update version of the patch?
Thanks
Chris
--
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
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-21 10:00 ` Christopher Li
@ 2012-06-22 2:08 ` Xi Wang
2012-06-22 17:59 ` Christopher Li
0 siblings, 1 reply; 14+ messages in thread
From: Xi Wang @ 2012-06-22 2:08 UTC (permalink / raw)
To: Christopher Li; +Cc: linux-sparse
On Jun 21, 2012, at 6:00 PM, Christopher Li wrote:
>
> I like this series a lot. Do you have an update version of the patch?
I will resend a revised version of these patches.
With ->ctype in pseudo, we might have to disable several simplifications
in simplify.c and cse.c for type consistency. One such example is:
unsigned int foo(unsigned long long x)
{
unsigned int tmp = x & 0x1fffffff;
return tmp;
}
sparse emits:
and.64 %r2 <- %arg1, $0x1fffffff
ret.32 %r2
%r2 seems to be interpreted as both 64 and 32 bits, which will also
trouble backends.
To fix the inconsistency, we may need to disable some simplification:
https://github.com/xiw/sparse/commit/7072002
Then we have:
and.64 %r2 <- %arg1, $0x1fffffff
cast.32 %r3 <- (64) %r2
ret.32 %r3
Does this make sense? Or should we just provide an option to turn
off all sparse simplifications, since backends usually have their own
optimization passes?
- xi
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC][PATCH 0/3] implement pseudo->ctype
2012-06-22 2:08 ` Xi Wang
@ 2012-06-22 17:59 ` Christopher Li
0 siblings, 0 replies; 14+ messages in thread
From: Christopher Li @ 2012-06-22 17:59 UTC (permalink / raw)
To: Xi Wang; +Cc: linux-sparse
On Thu, Jun 21, 2012 at 7:08 PM, Xi Wang <xi.wang@gmail.com> wrote:
> On Jun 21, 2012, at 6:00 PM, Christopher Li wrote:
> https://github.com/xiw/sparse/commit/7072002
>
> Then we have:
>
> and.64 %r2 <- %arg1, $0x1fffffff
> cast.32 %r3 <- (64) %r2
> ret.32 %r3
>
> Does this make sense? Or should we just provide an option to turn
> off all sparse simplifications, since backends usually have their own
> optimization passes?
Adding the cast from 64 to 32 bit make sense.
The sparse checker can still benefit from the simplifications. I think
it is OK we turn off those simplifications for sparse-llvm back end.
I want to have this module that, the back end can pick to chose
what kind of simplification/optimization done to the linearized
instructions.
I think the sparse-llvm back end need a different code path in the
front end for things like GEP any way.
Chris
--
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
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2012-06-22 17:59 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-06-04 6:54 [RFC][PATCH 0/3] implement pseudo->ctype Xi Wang
2012-06-04 6:54 ` [RFC][PATCH 1/3] add ->ctype to struct pseudo Xi Wang
2012-06-04 6:54 ` [RFC][PATCH 2/3] remove ->type and ->size from struct instruction Xi Wang
2012-06-04 6:54 ` [RFC][PATCH 3/3] sparse, llvm: sync with new " Xi Wang
2012-06-08 11:50 ` [RFC][PATCH 0/3] implement pseudo->ctype Pekka Enberg
2012-06-08 15:39 ` Xi Wang
2012-06-09 1:35 ` Xi Wang
2012-06-09 10:42 ` Pekka Enberg
2012-06-09 11:52 ` Xi Wang
2012-06-09 12:06 ` Jeff Garzik
2012-06-09 12:12 ` Pekka Enberg
2012-06-21 10:00 ` Christopher Li
2012-06-22 2:08 ` Xi Wang
2012-06-22 17:59 ` Christopher Li
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).