X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fbe%2Fia32%2Fia32_address_mode.c;h=112baae74ed2b754afa67829a84179c810cc9441;hb=9e453a831d94e7ad329d16bfd5fe7a9476882905;hp=f6049eb6d2dacd5b20556341fc333df677cc5415;hpb=c2433f6a3ad1abb55975a472c00bc978b0aea5fd;p=libfirm diff --git a/ir/be/ia32/ia32_address_mode.c b/ir/be/ia32/ia32_address_mode.c index f6049eb6d..112baae74 100644 --- a/ir/be/ia32/ia32_address_mode.c +++ b/ir/be/ia32/ia32_address_mode.c @@ -36,14 +36,14 @@ #include "iredges_t.h" #include "irgwalk.h" -#include "../benode_t.h" +#include "../benode.h" +#include "../belive.h" #define AGGRESSIVE_AM /* gas/ld don't support negative symconsts :-( */ #undef SUPPORT_NEGATIVE_SYMCONSTS -static be_lv_t *lv; static bitset_t *non_address_mode_nodes; /** @@ -87,11 +87,14 @@ static int do_is_immediate(const ir_node *node, int *symconsts, int negate) return 0; return 1; + case iro_Unknown: + /* we can use '0' for Unknowns */ + return 1; case iro_Add: case iro_Sub: /* Add's and Sub's are typically supported as long as both operands are * immediates */ - if (bitset_is_set(non_address_mode_nodes, get_irn_idx(node))) + if (ia32_is_non_address_mode_node(node)) return 0; left = get_binop_left(node); @@ -116,7 +119,8 @@ static int do_is_immediate(const ir_node *node, int *symconsts, int negate) * @return non-zero if the DAG represents an immediate, 0 else */ #if 0 -static int is_immediate_simple(const ir_node *node) { +static int is_immediate_simple(const ir_node *node) +{ int symconsts = 0; return do_is_immediate(node, &symconsts, 0); } @@ -172,15 +176,17 @@ static void eat_immediate(ia32_address_t *addr, ir_node *node, int negate) #endif addr->symconst_sign = negate; break; + case iro_Unknown: + break; case iro_Add: - assert(!bitset_is_set(non_address_mode_nodes, get_irn_idx(node))); + assert(!ia32_is_non_address_mode_node(node)); left = get_Add_left(node); right = get_Add_right(node); eat_immediate(addr, left, negate); eat_immediate(addr, right, negate); break; case iro_Sub: - assert(!bitset_is_set(non_address_mode_nodes, get_irn_idx(node))); + assert(!ia32_is_non_address_mode_node(node)); left = get_Sub_left(node); right = get_Sub_right(node); eat_immediate(addr, left, negate); @@ -203,8 +209,9 @@ static void eat_immediate(ia32_address_t *addr, ir_node *node, int negate) static ir_node *eat_immediates(ia32_address_t *addr, ir_node *node, ia32_create_am_flags_t flags) { - if (!(flags & ia32_create_am_force) && - bitset_is_set(non_address_mode_nodes, get_irn_idx(node))) + if (!(flags & ia32_create_am_force) && + ia32_is_non_address_mode_node(node) && + (!(flags & ia32_create_am_double_use) || get_irn_n_edges(node) > 2)) return node; if (is_Add(node)) { @@ -283,7 +290,7 @@ static int eat_shl(ia32_address_t *addr, ir_node *node) /* we can only eat a shl if we don't have a scale or index set yet */ if (addr->scale != 0 || addr->index != NULL) return 0; - if (bitset_is_set(non_address_mode_nodes, get_irn_idx(node))) + if (ia32_is_non_address_mode_node(node)) return 0; #ifndef AGGRESSIVE_AM @@ -299,7 +306,6 @@ static int eat_shl(ia32_address_t *addr, ir_node *node) /* Create an address mode for a given node. */ void ia32_create_address_mode(ia32_address_t *addr, ir_node *node, ia32_create_am_flags_t flags) { - int res = 0; ir_node *eat_imms; if (is_immediate(addr, node, 0)) { @@ -314,8 +320,9 @@ void ia32_create_address_mode(ia32_address_t *addr, ir_node *node, ia32_create_a } #endif - if (!(flags & ia32_create_am_force) && - bitset_is_set(non_address_mode_nodes, get_irn_idx(node))) { + if (!(flags & ia32_create_am_force) && + ia32_is_non_address_mode_node(node) && + (!(flags & ia32_create_am_double_use) || get_irn_n_edges(node) > 2)) { addr->base = node; return; } @@ -326,7 +333,6 @@ void ia32_create_address_mode(ia32_address_t *addr, ir_node *node, ia32_create_a eat_imms = ia32_skip_downconv(eat_imms); } - res = 1; node = eat_imms; #ifndef AGGRESSIVE_AM if (get_irn_n_edges(node) > 1) { @@ -334,7 +340,7 @@ void ia32_create_address_mode(ia32_address_t *addr, ir_node *node, ia32_create_a return; } #endif - if (bitset_is_set(non_address_mode_nodes, get_irn_idx(node))) { + if (ia32_is_non_address_mode_node(node)) { addr->base = node; return; } @@ -375,7 +381,7 @@ void ia32_create_address_mode(ia32_address_t *addr, ir_node *node, ia32_create_a } if (left != NULL && be_is_FrameAddr(left) && - !bitset_is_set(non_address_mode_nodes, get_irn_idx(left))) { + !ia32_is_non_address_mode_node(left)) { assert(addr->base == NULL); assert(addr->frame_entity == NULL); addr->base = be_get_FrameAddr_frame(left); @@ -384,7 +390,7 @@ void ia32_create_address_mode(ia32_address_t *addr, ir_node *node, ia32_create_a left = NULL; } else if (right != NULL && be_is_FrameAddr(right) && - !bitset_is_set(non_address_mode_nodes, get_irn_idx(right))) { + !ia32_is_non_address_mode_node(right)) { assert(addr->base == NULL); assert(addr->frame_entity == NULL); addr->base = be_get_FrameAddr_frame(right); @@ -421,14 +427,14 @@ void ia32_mark_non_am(ir_node *node) bitset_set(non_address_mode_nodes, get_irn_idx(node)); } -int ia32_is_non_address_mode_node(ir_node *node) +int ia32_is_non_address_mode_node(ir_node const *node) { return bitset_is_set(non_address_mode_nodes, get_irn_idx(node)); } -static int value_last_used_here(ir_node *here, ir_node *value) +static int value_last_used_here(be_lv_t *lv, ir_node *here, ir_node *value) { - ir_node *block = get_nodes_block(here); + ir_node *block = get_nodes_block(here); const ir_edge_t *edge; /* If the value is live end it is for sure it does not die here */ @@ -453,12 +459,13 @@ static int value_last_used_here(ir_node *here, ir_node *value) */ static void mark_non_address_nodes(ir_node *node, void *env) { - int i, arity; + be_lv_t *lv = env; + int arity; + int i; ir_node *val; ir_node *left; ir_node *right; ir_mode *mode; - (void) env; mode = get_irn_mode(node); if (!mode_is_int(mode) && !mode_is_reference(mode) && mode != mode_b) @@ -473,7 +480,7 @@ static void mark_non_address_nodes(ir_node *node, void *env) case iro_Store: /* Do not mark the pointer, because we want to turn it into AM. */ val = get_Store_value(node); - bitset_set(non_address_mode_nodes, get_irn_idx(val)); + ia32_mark_non_am(val); break; case iro_Shl: @@ -495,15 +502,15 @@ static void mark_non_address_nodes(ir_node *node, void *env) * an addition and has the same register pressure for the case that only * one operand dies, but is faster (on Pentium 4). * && instead of || only folds AM if both operands do not die here */ - if (!value_last_used_here(node, left) || - !value_last_used_here(node, right)) { + if (!value_last_used_here(lv, node, left) || + !value_last_used_here(lv, node, right)) { return; } /* At least one of left and right are not used by anyone else, so it is * beneficial for the register pressure (if both are unused otherwise, * else neutral) and ALU use to not fold AM. */ - bitset_set(non_address_mode_nodes, get_irn_idx(node)); + ia32_mark_non_am(node); break; default: @@ -511,20 +518,19 @@ static void mark_non_address_nodes(ir_node *node, void *env) for (i = 0; i < arity; ++i) { ir_node *in = get_irn_n(node, i); - bitset_set(non_address_mode_nodes, get_irn_idx(in)); + ia32_mark_non_am(in); } break; } } -void ia32_calculate_non_address_mode_nodes(be_irg_t *birg) +void ia32_calculate_non_address_mode_nodes(ir_graph *irg) { - ir_graph *irg = be_get_birg_irg(birg); + be_lv_t *lv = be_assure_liveness(irg); - lv = be_assure_liveness(birg); non_address_mode_nodes = bitset_malloc(get_irg_last_idx(irg)); - irg_walk_graph(irg, NULL, mark_non_address_nodes, NULL); + irg_walk_graph(irg, NULL, mark_non_address_nodes, lv); } void ia32_free_non_address_mode_nodes(void)