diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-12-13 12:00:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:06:07 -0700 |
commit | 6278edfccdbb3b6a0bbe9f066991e28564ea0884 (patch) | |
tree | d1f3c4fe4125a8899eb74c16e4b289b08c25cb04 | |
parent | Make sure to mark all registers that have already been allocated (diff) | |
download | sparse-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.c | 10 | ||||
-rw-r--r-- | example.c | 4 | ||||
-rw-r--r-- | flow.c | 15 | ||||
-rw-r--r-- | linearize.c | 53 | ||||
-rw-r--r-- | linearize.h | 1 | ||||
-rw-r--r-- | liveness.c | 4 | ||||
-rw-r--r-- | memops.c | 2 | ||||
-rw-r--r-- | simplify.c | 10 |
8 files changed, 54 insertions, 45 deletions
@@ -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 */ @@ -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: @@ -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 */ @@ -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; @@ -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; @@ -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); |