aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-13 12:00:29 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:06:07 -0700
commit6278edfccdbb3b6a0bbe9f066991e28564ea0884 (patch)
treed1f3c4fe4125a8899eb74c16e4b289b08c25cb04
parentMake sure to mark all registers that have already been allocated (diff)
downloadsparse-6278edfccdbb3b6a0bbe9f066991e28564ea0884.tar.gz
sparse-6278edfccdbb3b6a0bbe9f066991e28564ea0884.tar.bz2
sparse-6278edfccdbb3b6a0bbe9f066991e28564ea0884.zip
Split OP_SETVAL into OP_SETVAL (fp expressions and labels) and OP_SYMADDR
(symbol addresses). They are pretty different. Symbol addresses have special meaning during various phases, from symbol simplification to CSE.
-rw-r--r--cse.c10
-rw-r--r--example.c4
-rw-r--r--flow.c15
-rw-r--r--linearize.c53
-rw-r--r--linearize.h1
-rw-r--r--liveness.c4
-rw-r--r--memops.c2
-rw-r--r--simplify.c10
8 files changed, 54 insertions, 45 deletions
diff --git a/cse.c b/cse.c
index 31ceafd..758884c 100644
--- a/cse.c
+++ b/cse.c
@@ -76,6 +76,9 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
case OP_SETVAL:
hash += hashval(insn->val);
+ break;
+
+ case OP_SYMADDR:
hash += hashval(insn->symbol);
break;
@@ -188,11 +191,14 @@ static int insn_compare(const void *_i1, const void *_i2)
return i1->src1 < i2->src1 ? -1 : 1;
break;
+ case OP_SYMADDR:
+ if (i1->symbol != i2->symbol)
+ return i1->symbol < i2->symbol ? -1 : 1;
+ break;
+
case OP_SETVAL:
if (i1->val != i2->val)
return i1->val < i2->val ? -1 : 1;
- if (i1->symbol != i2->symbol)
- return i1->symbol < i2->symbol ? -1 : 1;
break;
/* Other */
diff --git a/example.c b/example.c
index 4716b54..5894fc9 100644
--- a/example.c
+++ b/example.c
@@ -502,7 +502,7 @@ static struct hardreg *fill_reg(struct bb_state *state, struct hardreg *hardreg,
case PSEUDO_REG:
def = pseudo->def;
if (def->opcode == OP_SETVAL) {
- output_insn(state, "movl $<%s>,%s", show_pseudo(def->symbol), hardreg->name);
+ output_insn(state, "movl $<%s>,%s", show_pseudo(def->target), hardreg->name);
break;
}
src = find_pseudo_storage(state, pseudo, hardreg);
@@ -1298,7 +1298,7 @@ static void fill_output(struct bb_state *state, pseudo_t pseudo, struct storage
case PSEUDO_REG:
def = pseudo->def;
if (def->opcode == OP_SETVAL) {
- write_val_to_storage(state, def->symbol, out);
+ write_val_to_storage(state, pseudo, out);
return;
}
default:
diff --git a/flow.c b/flow.c
index c523efc..9d2f0fb 100644
--- a/flow.c
+++ b/flow.c
@@ -53,15 +53,10 @@ static int pseudo_truth_value(pseudo_t pseudo)
case PSEUDO_REG: {
struct instruction *insn = pseudo->def;
- if (insn->opcode == OP_SETVAL && insn->target == pseudo) {
- struct expression *expr = insn->val;
-
- /* A symbol address is always considered true.. */
- if (!expr)
- return 1;
- if (expr->type == EXPR_VALUE)
- return !!expr->value;
- }
+
+ /* A symbol address is always considered true.. */
+ if (insn->opcode == OP_SYMADDR && insn->target == pseudo)
+ return 1;
}
/* Fall through */
default:
@@ -614,7 +609,7 @@ static void simplify_one_symbol(struct entrypoint *ep, struct symbol *sym)
break;
case OP_LOAD:
break;
- case OP_SETVAL:
+ case OP_SYMADDR:
if (!insn->bb)
continue;
mod |= MOD_ADDRESSABLE;
diff --git a/linearize.c b/linearize.c
index d2cf224..21eccd5 100644
--- a/linearize.c
+++ b/linearize.c
@@ -205,6 +205,7 @@ static const char* opcodes[] = {
[OP_LOAD] = "load",
[OP_STORE] = "store",
[OP_SETVAL] = "set",
+ [OP_SYMADDR] = "symaddr",
[OP_GET_ELEMENT_PTR] = "getelem",
/* Other */
@@ -289,27 +290,25 @@ const char *show_instruction(struct instruction *insn)
buf += sprintf(buf, ".L%p", insn->bb_true ? insn->bb_true : insn->bb_false);
break;
- case OP_SETVAL: {
- struct expression *expr = insn->val;
- pseudo_t pseudo = insn->symbol;
+ case OP_SYMADDR: {
+ struct symbol *sym = insn->symbol->sym;
buf += sprintf(buf, "%s <- ", show_pseudo(insn->target));
- if (pseudo) {
- struct symbol *sym = pseudo->sym;
- if (!sym) {
- buf += sprintf(buf, "%s", show_pseudo(pseudo));
- break;
- }
- if (sym->bb_target) {
- buf += sprintf(buf, ".L%p", sym->bb_target);
- break;
- }
- if (sym->ident) {
- buf += sprintf(buf, "%s", show_ident(sym->ident));
- break;
- }
- buf += sprintf(buf, "<anon symbol:%p>", sym);
+
+ if (sym->bb_target) {
+ buf += sprintf(buf, ".L%p", sym->bb_target);
break;
}
+ if (sym->ident) {
+ buf += sprintf(buf, "%s", show_ident(sym->ident));
+ break;
+ }
+ buf += sprintf(buf, "<anon symbol:%p>", sym);
+ break;
+ }
+
+ case OP_SETVAL: {
+ struct expression *expr = insn->val;
+ buf += sprintf(buf, "%s <- ", show_pseudo(insn->target));
if (!expr) {
buf += sprintf(buf, "%s", "<none>");
@@ -942,11 +941,17 @@ static pseudo_t add_setval(struct entrypoint *ep, struct symbol *ctype, struct e
pseudo_t target = alloc_pseudo(insn);
insn->target = target;
insn->val = val;
- if (!val) {
- pseudo_t addr = symbol_pseudo(ep, ctype);
- use_pseudo(addr, &insn->symbol);
- insn->size = bits_in_pointer;
- }
+ add_one_insn(ep, insn);
+ return target;
+}
+
+static pseudo_t add_symbol_address(struct entrypoint *ep, struct symbol *sym)
+{
+ struct instruction *insn = alloc_instruction(OP_SYMADDR, bits_in_pointer);
+ pseudo_t target = alloc_pseudo(insn);
+
+ insn->target = target;
+ use_pseudo(symbol_pseudo(ep, sym), &insn->symbol);
add_one_insn(ep, insn);
return target;
}
@@ -1442,7 +1447,7 @@ pseudo_t linearize_expression(struct entrypoint *ep, struct expression *expr)
switch (expr->type) {
case EXPR_SYMBOL:
linearize_one_symbol(ep, expr->symbol);
- return add_setval(ep, expr->symbol, NULL);
+ return add_symbol_address(ep, expr->symbol);
case EXPR_VALUE:
return value_pseudo(expr->value);
diff --git a/linearize.h b/linearize.h
index 401e665..4077542 100644
--- a/linearize.h
+++ b/linearize.h
@@ -173,6 +173,7 @@ enum opcode {
OP_LOAD,
OP_STORE,
OP_SETVAL,
+ OP_SYMADDR,
OP_GET_ELEMENT_PTR,
/* Other */
diff --git a/liveness.c b/liveness.c
index ecfc7fd..d21b3f1 100644
--- a/liveness.c
+++ b/liveness.c
@@ -93,6 +93,10 @@ static void track_instruction_usage(struct basic_block *bb, struct instruction *
break;
case OP_SETVAL:
+ DEFINES(target);
+ break;
+
+ case OP_SYMADDR:
USES(symbol); DEFINES(target);
break;
diff --git a/memops.c b/memops.c
index 7246ca5..daae061 100644
--- a/memops.c
+++ b/memops.c
@@ -69,7 +69,7 @@ static inline int address_taken(pseudo_t pseudo)
pseudo_t *usep;
FOR_EACH_PTR(pseudo->users, usep) {
struct instruction *insn = container(usep, struct instruction, src);
- if (insn->bb && insn->opcode == OP_SETVAL)
+ if (insn->bb && insn->opcode == OP_SYMADDR)
return 1;
} END_FOR_EACH_PTR(usep);
return 0;
diff --git a/simplify.c b/simplify.c
index b2bb8d7..8392241 100644
--- a/simplify.c
+++ b/simplify.c
@@ -188,11 +188,9 @@ void kill_instruction(struct instruction *insn)
repeat_phase |= REPEAT_CSE;
return;
- case OP_SETVAL:
+ case OP_SYMADDR:
insn->bb = NULL;
- repeat_phase |= REPEAT_CSE;
- if (insn->symbol)
- repeat_phase |= REPEAT_SYMBOL_CLEANUP;
+ repeat_phase |= REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
return;
}
}
@@ -485,7 +483,7 @@ static int simplify_one_memop(struct instruction *insn, pseudo_t orig)
if (addr->type == PSEUDO_REG) {
struct instruction *def = addr->def;
- if (def->opcode == OP_SETVAL && def->src) {
+ if (def->opcode == OP_SYMADDR && def->src) {
kill_use(&insn->src);
use_pseudo(def->src, &insn->src);
return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
@@ -736,7 +734,7 @@ int simplify_instruction(struct instruction *insn)
return simplify_unop(insn);
case OP_LOAD: case OP_STORE:
return simplify_memop(insn);
- case OP_SETVAL:
+ case OP_SYMADDR:
if (dead_insn(insn, NULL, NULL, NULL))
return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
return replace_with_pseudo(insn, insn->symbol);