X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fldstopt.c;h=2711ac40be0ec316931511264e091886003a8799;hb=8c9921a1fc166552f6e416434fd8394a4fc210a3;hp=d8cd2d3b69578cf645f411909671dc82f50521dc;hpb=8a98cf06c4fb193ea8025a6dfcdbe161187d143f;p=libfirm diff --git a/ir/opt/ldstopt.c b/ir/opt/ldstopt.c index d8cd2d3b6..2711ac40b 100644 --- a/ir/opt/ldstopt.c +++ b/ir/opt/ldstopt.c @@ -21,7 +21,6 @@ * @file * @brief Load/Store optimizations. * @author Michael Beck - * @version $Id$ */ #include "config.h" @@ -35,6 +34,7 @@ #include "ircons_t.h" #include "irgmod.h" #include "irgwalk.h" +#include "irtools.h" #include "tv_t.h" #include "dbginfo_t.h" #include "iropt_dbg.h" @@ -43,9 +43,8 @@ #include "irhooks.h" #include "iredges.h" #include "irpass.h" -#include "opt_polymorphy.h" #include "irmemory.h" -#include "irphase_t.h" +#include "irnodehashmap.h" #include "irgopt.h" #include "set.h" #include "be.h" @@ -781,8 +780,8 @@ static unsigned is_Call_pure(ir_node *call) /* try the called entity */ ir_node *ptr = get_Call_ptr(call); - if (is_Global(ptr)) { - ir_entity *ent = get_Global_entity(ptr); + if (is_SymConst_addr_ent(ptr)) { + ir_entity *ent = get_SymConst_entity(ptr); prop = get_entity_additional_properties(ent); } @@ -1142,61 +1141,56 @@ static unsigned optimize_load(ir_node *load) return res | DF_CHANGED; } - /* Load from a constant polymorphic field, where we can resolve - polymorphism. */ - value = transform_polymorph_Load(load); - if (value == load) { - value = NULL; - /* check if we can determine the entity that will be loaded */ - ent = find_constant_entity(ptr); - if (ent != NULL - && get_entity_visibility(ent) != ir_visibility_external) { - /* a static allocation that is not external: there should be NO - * exception when loading even if we cannot replace the load itself. - */ + value = NULL; + /* check if we can determine the entity that will be loaded */ + ent = find_constant_entity(ptr); + if (ent != NULL + && get_entity_visibility(ent) != ir_visibility_external) { + /* a static allocation that is not external: there should be NO + * exception when loading even if we cannot replace the load itself. + */ - /* no exception, clear the info field as it might be checked later again */ - if (info->projs[pn_Load_X_except]) { - ir_graph *irg = get_irn_irg(load); - exchange(info->projs[pn_Load_X_except], new_r_Bad(irg, mode_X)); - info->projs[pn_Load_X_except] = NULL; - res |= CF_CHANGED; - } - if (info->projs[pn_Load_X_regular]) { - exchange(info->projs[pn_Load_X_regular], new_r_Jmp(get_nodes_block(load))); - info->projs[pn_Load_X_regular] = NULL; - res |= CF_CHANGED; - } + /* no exception, clear the info field as it might be checked later again */ + if (info->projs[pn_Load_X_except]) { + ir_graph *irg = get_irn_irg(load); + exchange(info->projs[pn_Load_X_except], new_r_Bad(irg, mode_X)); + info->projs[pn_Load_X_except] = NULL; + res |= CF_CHANGED; + } + if (info->projs[pn_Load_X_regular]) { + exchange(info->projs[pn_Load_X_regular], new_r_Jmp(get_nodes_block(load))); + info->projs[pn_Load_X_regular] = NULL; + res |= CF_CHANGED; + } - if (get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) { - if (has_entity_initializer(ent)) { - /* new style initializer */ - value = find_compound_ent_value(ptr); - } else if (entity_has_compound_ent_values(ent)) { - /* old style initializer */ - compound_graph_path *path = get_accessed_path(ptr); + if (get_entity_linkage(ent) & IR_LINKAGE_CONSTANT) { + if (has_entity_initializer(ent)) { + /* new style initializer */ + value = find_compound_ent_value(ptr); + } else if (entity_has_compound_ent_values(ent)) { + /* old style initializer */ + compound_graph_path *path = get_accessed_path(ptr); - if (path != NULL) { - assert(is_proper_compound_graph_path(path, get_compound_graph_path_length(path)-1)); + if (path != NULL) { + assert(is_proper_compound_graph_path(path, get_compound_graph_path_length(path)-1)); - value = get_compound_ent_value_by_path(ent, path); - DB((dbg, LEVEL_1, " Constant access at %F%F resulted in %+F\n", ent, path, value)); - free_compound_graph_path(path); - } + value = get_compound_ent_value_by_path(ent, path); + DB((dbg, LEVEL_1, " Constant access at %F%F resulted in %+F\n", ent, path, value)); + free_compound_graph_path(path); } - if (value != NULL) { - ir_graph *irg = get_irn_irg(load); - value = can_replace_load_by_const(load, value); - if (value != NULL && is_Sel(ptr) && - !is_irg_state(irg, IR_GRAPH_STATE_IMPLICIT_BITFIELD_MASKING)) { - /* frontend has inserted masking operations after bitfield accesses, - * so we might have to shift the const. */ - unsigned char bit_offset = get_entity_offset_bits_remainder(get_Sel_entity(ptr)); - ir_tarval *tv_old = get_Const_tarval(value); - ir_tarval *tv_offset = new_tarval_from_long(bit_offset, mode_Bu); - ir_tarval *tv_new = tarval_shl(tv_old, tv_offset); - value = new_r_Const(irg, tv_new); - } + } + if (value != NULL) { + ir_graph *irg = get_irn_irg(load); + value = can_replace_load_by_const(load, value); + if (value != NULL && is_Sel(ptr) && + !is_irg_state(irg, IR_GRAPH_STATE_IMPLICIT_BITFIELD_MASKING)) { + /* frontend has inserted masking operations after bitfield accesses, + * so we might have to shift the const. */ + unsigned char bit_offset = get_entity_offset_bits_remainder(get_Sel_entity(ptr)); + ir_tarval *tv_old = get_Const_tarval(value); + ir_tarval *tv_offset = new_tarval_from_long(bit_offset, mode_Bu); + ir_tarval *tv_new = tarval_shl(tv_old, tv_offset); + value = new_r_Const(irg, tv_new); } } } @@ -1713,13 +1707,14 @@ typedef struct node_entry { /** A loop entry. */ typedef struct loop_env { - ir_phase ph; /**< the phase object */ - ir_node **stack; /**< the node stack */ - size_t tos; /**< tos index */ - unsigned nextDFSnum; /**< the current DFS number */ - unsigned POnum; /**< current post order number */ - - unsigned changes; /**< a bitmask of graph changes */ + ir_nodehashmap_t map; + struct obstack obst; + ir_node **stack; /**< the node stack */ + size_t tos; /**< tos index */ + unsigned nextDFSnum; /**< the current DFS number */ + unsigned POnum; /**< current post order number */ + + unsigned changes; /**< a bitmask of graph changes */ } loop_env; /** @@ -1727,13 +1722,12 @@ typedef struct loop_env { */ static node_entry *get_irn_ne(ir_node *irn, loop_env *env) { - ir_phase *ph = &env->ph; - node_entry *e = (node_entry*)phase_get_irn_data(&env->ph, irn); + node_entry *e = (node_entry*)ir_nodehashmap_get(&env->map, irn); - if (! e) { - e = (node_entry*)phase_alloc(ph, sizeof(*e)); + if (e == NULL) { + e = OALLOC(&env->obst, node_entry); memset(e, 0, sizeof(*e)); - phase_set_irn_data(ph, irn, e); + ir_nodehashmap_insert(&env->map, irn, e); } return e; } /* get_irn_ne */ @@ -1856,7 +1850,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) if (pe->pscc != ne->pscc) { /* not in the same SCC, is region const */ - phi_entry *pe = (phi_entry*)phase_alloc(&env->ph, sizeof(*pe)); + phi_entry *pe = OALLOC(&env->obst, phi_entry); pe->phi = phi; pe->pos = j; @@ -1886,7 +1880,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) continue; /* for now, we can only move Load(Global) */ - if (! is_Global(ptr)) + if (! is_SymConst_addr_ent(ptr)) continue; load_mode = get_Load_mode(load); for (other = pscc->head; other != NULL; other = next_other) { @@ -1933,7 +1927,7 @@ static void move_loads_out_of_loops(scc *pscc, loop_env *env) DB((dbg, LEVEL_1, " Created %+F in %+F\n", irn, pred)); } pe->load = irn; - ninfo = get_ldst_info(irn, phase_obst(&env->ph)); + ninfo = get_ldst_info(irn, &env->obst); ninfo->projs[pn_Load_M] = mem = new_r_Proj(irn, mode_M, pn_Load_M); if (res == NULL) { @@ -2148,7 +2142,7 @@ static void dfs(ir_node *irn, loop_env *env) node->low = MIN(o->DFSnum, node->low); } } else if (is_fragile_op(irn)) { - ir_node *pred = get_fragile_op_mem(irn); + ir_node *pred = get_memop_mem(irn); node_entry *o = get_irn_ne(pred, env); if (!irn_visited(pred)) { @@ -2173,7 +2167,7 @@ static void dfs(ir_node *irn, loop_env *env) } if (node->low == node->DFSnum) { - scc *pscc = (scc*)phase_alloc(&env->ph, sizeof(*pscc)); + scc *pscc = OALLOC(&env->obst, scc); ir_node *x; pscc->head = NULL; @@ -2215,7 +2209,7 @@ static void do_dfs(ir_graph *irg, loop_env *env) } else if (is_Raise(pred)) { dfs(get_Raise_mem(pred), env); } else if (is_fragile_op(pred)) { - dfs(get_fragile_op_mem(pred), env); + dfs(get_memop_mem(pred), env); } else if (is_Bad(pred)) { /* ignore non-optimized block predecessor */ } else { @@ -2247,13 +2241,15 @@ static int optimize_loops(ir_graph *irg) env.nextDFSnum = 0; env.POnum = 0; env.changes = 0; - phase_init(&env.ph, irg, phase_irn_init_default); + ir_nodehashmap_init(&env.map); + obstack_init(&env.obst); /* calculate the SCC's and drive loop optimization. */ do_dfs(irg, &env); DEL_ARR_F(env.stack); - phase_deinit(&env.ph); + obstack_free(&env.obst, NULL); + ir_nodehashmap_destroy(&env.map); return env.changes; } /* optimize_loops */ @@ -2292,23 +2288,19 @@ static ir_graph_state_t do_loadstore_opt(ir_graph *irg) /* Handle graph state */ if (env.changes) { - set_irg_entity_usage_state(irg, ir_entity_usage_not_computed); edges_deactivate(irg); } - if (env.changes & CF_CHANGED) { - /* control flow changed, block might have Bad() predecessors. */ - set_irg_doms_inconsistent(irg); - } else { - res |= IR_GRAPH_STATE_CONSISTENT_DOMINANCE | IR_GRAPH_STATE_NO_BAD_BLOCKS; + if (!(env.changes & CF_CHANGED)) { + res |= IR_GRAPH_STATE_CONSISTENT_DOMINANCE | IR_GRAPH_STATE_NO_BADS; } return res; } -optdesc_t opt_loadstore = { +static optdesc_t opt_loadstore = { "load-store", - IR_GRAPH_STATE_NO_UNREACHABLE_BLOCKS | IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_NO_CRITICAL_EDGES | IR_GRAPH_STATE_CONSISTENT_DOMINANCE | IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE, + IR_GRAPH_STATE_NO_UNREACHABLE_CODE | IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_NO_CRITICAL_EDGES | IR_GRAPH_STATE_CONSISTENT_DOMINANCE | IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE, do_loadstore_opt, };