* @brief Dataflow driven Load/Store optimizations, uses some ideas from
* VanDrunen's LEPRE
* @author Michael Beck
- * @version $Id$
*/
#include "config.h"
#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"
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 */
};
/**
* 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 */
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
/* 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);
}
*
* @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;
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.
/* 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:
}
obstack_init(&env.obst);
- ir_nodemap_init(&env.adr_map);
+ ir_nodehashmap_init(&env.adr_map);
env.forward = NULL;
env.backward = NULL;
/* 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