X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fopt_ldst.c;h=fb7ff964245331c4ba31ccd2db95cea4c59375fa;hb=8c9921a1fc166552f6e416434fd8394a4fc210a3;hp=f03f2fcd46c875299d3966b67da682de73a7021c;hpb=eebab16e6be8c73ebb7cb01d04567136f36b7337;p=libfirm diff --git a/ir/opt/opt_ldst.c b/ir/opt/opt_ldst.c index f03f2fcd4..fb7ff9642 100644 --- a/ir/opt/opt_ldst.c +++ b/ir/opt/opt_ldst.c @@ -22,7 +22,6 @@ * @brief Dataflow driven Load/Store optimizations, uses some ideas from * VanDrunen's LEPRE * @author Michael Beck - * @version $Id$ */ #include "config.h" @@ -38,7 +37,7 @@ #include "irgopt.h" #include "iropt.h" #include "iroptimize.h" -#include "irnodemap.h" +#include "irnodehashmap.h" #include "raw_bitset.h" #include "debug.h" #include "error.h" @@ -90,7 +89,7 @@ struct memop_t { memop_t *next; /**< links to the next memory op in the block in forward order. */ memop_t *prev; /**< links to the previous memory op in the block in forward order. */ unsigned flags; /**< memop flags */ - ir_node *projs[MAX_PROJ]; /**< Projs of this memory op */ + ir_node *projs[MAX_PROJ+1]; /**< Projs of this memory op */ }; /** @@ -115,8 +114,8 @@ struct block_t { * Metadata for this pass. */ typedef struct ldst_env_t { - struct obstack obst; /**< obstack for temporary data */ - ir_nodemap_t adr_map; /**< Map addresses to */ + struct obstack obst; /**< obstack for temporary data */ + ir_nodehashmap_t adr_map; /**< Map addresses to */ block_t *forward; /**< Inverse post-order list of all blocks Start->End */ block_t *backward; /**< Inverse post-order list of all blocks End->Start */ ir_node *start_bl; /**< start block of the current graph */ @@ -312,14 +311,14 @@ restart: goto restart; } - entry = (address_entry*)ir_nodemap_get(&env.adr_map, adr); + entry = (address_entry*)ir_nodehashmap_get(&env.adr_map, adr); if (entry == NULL) { /* new address */ entry = OALLOC(&env.obst, address_entry); entry->id = env.curr_adr_id++; - ir_nodemap_insert(&env.adr_map, adr, entry); + ir_nodehashmap_insert(&env.adr_map, adr, entry); DB((dbg, LEVEL_3, "ADDRESS %+F has ID %u\n", adr, entry->id)); #ifdef DEBUG_libfirm @@ -525,8 +524,8 @@ static unsigned get_Call_memory_properties(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); } @@ -1065,7 +1064,7 @@ static void update_Load_memop(memop_t *m) /* no exception, clear the m fields as it might be checked later again */ if (m->projs[pn_Load_X_except]) { ir_graph *irg = get_irn_irg(ptr); - exchange(m->projs[pn_Load_X_except], new_r_Bad(irg)); + exchange(m->projs[pn_Load_X_except], new_r_Bad(irg, mode_X)); m->projs[pn_Load_X_except] = NULL; m->flags &= ~FLAG_EXCEPTION; env.changed = 1; @@ -1205,7 +1204,7 @@ static void update_Call_memop(memop_t *m) * * @param m the memop */ -static void update_DivOp_memop(memop_t *m) +static void update_Div_memop(memop_t *m) { ir_node *div = m->node; int i; @@ -1218,15 +1217,38 @@ static void update_DivOp_memop(memop_t *m) continue; switch (get_Proj_proj(proj)) { - case pn_Generic_X_except: + case pn_Div_X_except: m->flags |= FLAG_EXCEPTION; break; - case pn_Generic_M: + case pn_Div_M: m->mem = proj; break; } } -} /* update_DivOp_memop */ +} + +static void update_Mod_memop(memop_t *m) +{ + ir_node *div = m->node; + int i; + + for (i = get_irn_n_outs(div) - 1; i >= 0; --i) { + ir_node *proj = get_irn_out(div, i); + + /* beware of keep edges */ + if (is_End(proj)) + continue; + + switch (get_Proj_proj(proj)) { + case pn_Mod_X_except: + m->flags |= FLAG_EXCEPTION; + break; + case pn_Mod_M: + m->mem = proj; + break; + } + } +} /** * Update a memop for a Phi. @@ -1291,8 +1313,10 @@ static void collect_memops(ir_node *irn, void *ctx) /* we can those to find the memory edge */ break; case iro_Div: + update_Div_memop(op); + break; case iro_Mod: - update_DivOp_memop(op); + update_Mod_memop(op); break; case iro_Builtin: @@ -1746,7 +1770,7 @@ static void replace_load(memop_t *op) proj = op->projs[pn_Load_X_except]; if (proj != NULL) { ir_graph *irg = get_irn_irg(load); - exchange(proj, new_r_Bad(irg)); + exchange(proj, new_r_Bad(irg, mode_X)); } proj = op->projs[pn_Load_X_regular]; if (proj != NULL) { @@ -1773,7 +1797,7 @@ static void remove_store(memop_t *op) proj = op->projs[pn_Store_X_except]; if (proj != NULL) { ir_graph *irg = get_irn_irg(store); - exchange(proj, new_r_Bad(irg)); + exchange(proj, new_r_Bad(irg, mode_X)); } proj = op->projs[pn_Store_X_regular]; if (proj != NULL) { @@ -2325,7 +2349,7 @@ int opt_ldst(ir_graph *irg) } obstack_init(&env.obst); - ir_nodemap_init(&env.adr_map); + ir_nodehashmap_init(&env.adr_map); env.forward = NULL; env.backward = NULL; @@ -2435,12 +2459,12 @@ int opt_ldst(ir_graph *irg) /* not only invalidate but free them. We might allocate new out arrays on our obstack which will be deleted yet. */ free_irg_outs(irg); - set_irg_entity_usage_state(irg, ir_entity_usage_not_computed); + clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE); } end: ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_BLOCK_MARK); - ir_nodemap_destroy(&env.adr_map); + ir_nodehashmap_destroy(&env.adr_map); obstack_free(&env.obst, NULL); #ifdef DEBUG_libfirm