X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fgvn_pre.c;h=51d33d3860fcd480e1073bec9adc430253f46117;hb=01c4c27c4b7824dd0020f6fd2218edbe9ab40548;hp=e8672d0848efde64f55476cb357b728df3859211;hpb=fd54b0a2d2d2d932dc02bfe0e388adb2f3a14675;p=libfirm diff --git a/ir/opt/gvn_pre.c b/ir/opt/gvn_pre.c index e8672d084..51d33d386 100644 --- a/ir/opt/gvn_pre.c +++ b/ir/opt/gvn_pre.c @@ -59,7 +59,7 @@ /* Attempt to reduce register pressure and reduce code size for hoisted nodes. */ -#define HOIST_HIGH 0 +#define HOIST_HIGH 1 #define COMMON_DOM 1 /* Seamless implementation of handling loads and generally memory @@ -77,12 +77,6 @@ TODO Broken for yet unknown reasons. */ #define OPTIMIZE_NODES 0 -#define OLD_DIVMODS 0 - -/* NIY Choose to be optimized nodes in a more sophisticated way - to reduce number of newly introduced phi nodes. */ -#define BETTER_GREED 0 - /** Additional info we need for every block. */ typedef struct block_info { @@ -158,20 +152,20 @@ typedef struct gvnpre_statistics { int infinite_loops; } gvnpre_statistics; -gvnpre_statistics *gvnpre_stats = NULL; +static gvnpre_statistics *gvnpre_stats = NULL; -static void init_stats() +static void init_stats(void) { gvnpre_stats = XMALLOCZ(gvnpre_statistics); } -static void free_stats() +static void free_stats(void) { free(gvnpre_stats); gvnpre_stats = NULL; } -static void print_stats() +static void print_stats(void) { gvnpre_statistics *stats = gvnpre_stats; DB((dbg, LEVEL_1, "replaced : %d\n", stats->replaced)); @@ -265,7 +259,9 @@ static int compare_gvn_identities(const void *elt, const void *key) /* memops are not the same, even if we want to optimize them we have to take the order in account */ - if (is_memop(a) || is_memop(b)) { + if (is_memop(a) || is_memop(b) || + get_irn_mode(a) == mode_T || + get_irn_mode(b) == mode_T) { /* Loads with the same predecessors are the same value; this should only happen after phi translation. */ if ((! is_Load(a) || ! is_Load(b)) && (! is_Store(a) || ! is_Store(b))) @@ -648,7 +644,7 @@ static unsigned is_nice_value(ir_node *n) if (is_Phi(n)) return 1; -#if LOADS || OLD_DIVMODS || DIVMODS +#if LOADS || DIVMODS if (is_Proj(n) && mode != mode_X && mode != mode_T) return 1; #else @@ -821,70 +817,6 @@ static void set_translated(ir_nodehashmap_t *map, ir_node *node, ir_node *trans) ir_nodehashmap_insert(map, node, trans); } -#if OLD_DIVMODS -/* Helper function to compare the values of pred and avail_pred. */ -static unsigned match_pred(ir_node *pred, ir_node *avail_pred, ir_node *block, int pos) -{ - ir_node *avail_value = identify(avail_pred); - ir_node *pred_block = get_Block_cfgpred_block(block, pos); - ir_node *trans_pred = get_translated(pred_block, pred); - ir_node *value; - - if (trans_pred == NULL) - trans_pred = pred; - value = identify(trans_pred); - - DB((dbg, LEVEL_3, "manual compare %+F %+F\n", pred, avail_pred)); - - return (value == avail_value); -} - -/** - * Does phi translation for redundant Div/Mod nodes only. - * Returns NULL for non-redundant node, which needs to be phi translated. - */ -static ir_node *phi_translate_divmod(ir_node *divmod, ir_node *block, int pos) -{ - ir_node *mem = get_memop_mem(divmod); - ir_node *trans = get_translated_pred(block, pos, mem); - - if (trans == NULL) - trans = mem; - - /* no partial redundancy if this is a mode_M phi */ - if (is_Proj(trans)) { - /* The last memory operation in predecessor block */ - ir_node *avail_op = get_Proj_pred(trans); - - if (get_irn_op(divmod) == get_irn_op(avail_op)) { - unsigned left, right; - - if (is_Div(avail_op)) { - if (get_Div_resmode(divmod) == get_Div_resmode(avail_op) && - get_Div_no_remainder(divmod) == get_Div_no_remainder(avail_op)) { - - left = match_pred(get_Div_left(divmod), get_Div_left(avail_op), block, pos); - right = match_pred(get_Div_right(divmod), get_Div_right(avail_op), block, pos); - - if (left && right) - return avail_op; - } - } else if (is_Mod(avail_op)) { - if (get_Mod_resmode(divmod) == get_Mod_resmode(avail_op)) { - - left = match_pred(get_Mod_left(divmod), get_Mod_left(avail_op), block, pos); - right = match_pred(get_Mod_right(divmod), get_Mod_right(avail_op), block, pos); - - if (left && right) - return avail_op; - } - } - } - } - return NULL; -} -#endif - /** * Translates an expression above a Phi. * @@ -911,14 +843,6 @@ static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, ir_valuese } arity = get_irn_arity(node); -#if OLD_DIVMODS - if (is_Div(node) || is_Mod(node)) { - ir_node *avail_op = phi_translate_divmod(node, block, pos); - if (avail_op) - return avail_op; - } -#endif - needed = 0; in = ALLOCANZ(ir_node *, arity); @@ -1270,13 +1194,6 @@ static ir_mode *is_partially_redundant(ir_node *block, ir_node *expr, ir_node *v } } -#if BETTER_GREED - /* value is redundant from last iteration, - but has not been removed from antic_in (is not optimized) */ - if (! environ->first_iter && is_redundant(block, expr)) - return mode; -#endif - /* If it is not the same value already existing along every predecessor and it is defined by some predecessor then it is partially redundant. */ if (! partially_redundant || fully_redundant) @@ -1312,21 +1229,6 @@ static void update_new_set(ir_node *block, ir_node *idom) #endif } /* update_new_set */ -#if BETTER_GREED -/* - * Returns redundant flag of node irn in block block. - */ -static unsigned is_redundant(ir_node *block, ir_node *irn) -{ - (void) block; - (void) irn; - - /* TODO Needs to use a flag, because antic_done should only be used - if node is finally processed by insert_nodes. */ - return 0; -} -#endif - /** * Checks if hoisting irn is greedy. * Greedy hoisting means that there are non partially redundant nodes @@ -1443,9 +1345,6 @@ static void insert_nodes_walker(ir_node *block, void *ctx) ir_node *idom; int pos; ir_valueset_iterator_t iter; -#if BETTER_GREED - plist_t *stack; -#endif /* only blocks */ if (! is_Block(block)) @@ -1470,14 +1369,6 @@ static void insert_nodes_walker(ir_node *block, void *ctx) return; } -#if BETTER_GREED - stack = plist_new(); - foreach_valueset(info->antic_in, value, expr, iter) { - /* inverse topologic */ - plist_insert_front(stack, expr); - } -#endif - /* This is the main reason antic_in is preverred over antic_out; we may iterate over every anticipated value first and not over the predecessor blocks. */ @@ -1506,25 +1397,16 @@ static void insert_nodes_walker(ir_node *block, void *ctx) continue; } -#if !BETTER_GREED if (is_hoisting_greedy(expr, block)) { DB((dbg, LEVEL_2, "greedy\n")); continue; } -#endif mode = is_partially_redundant(block, expr, value); if (mode == NULL) continue; -#if BETTER_GREED - if (is_hoisting_greedy(expr, block)) { - DB((dbg, LEVEL_2, "Better greed: greedy\n")); - continue; - } -#endif - -#if LOADS || OLD_DIVMODS || DIVMODS +#if LOADS || DIVMODS /* save old mode_M phis to remove keepalive edges later */ if (is_memop(expr)) { ir_node *mem = get_memop_mem(expr); @@ -1671,50 +1553,6 @@ static void insert_nodes_walker(ir_node *block, void *ctx) ir_valueset_insert(info->antic_done, value, expr); env->changes |= 1; } - -#if BETTER_GREED - /* TODO Unfinished - Better greed first determines which values are redundant - and decides then which to take. - insert_nodes needs to be split up for that. The cycle could be - for each block: flag redundant nodes, - use heuristic to adjust these flags (also consider antic_done), - do insert nodes. - This way we could decide if we should hoist a non redundant node, - if all its successors are redundant. - Or we might try to minimize the cut along hoisted nodes and their - non redundant successors. - */ - if (env->changes) { - plist_element_t *it; - /* iterate in inverse topological order */ - foreach_plist(stack, it) { - ir_node *irn = (ir_node *)plist_element_get_value(it); - ir_node *block = get_nodes_block(irn); - int j; - char redundant = 1; - - /* does irn only have redundant successors? */ - - foreach_out_edge(irn, edge) { - ir_node *succ = get_edge_src_irn(edge); - - /* if succ and irn are in the same block */ - if (get_nodes_block(succ) == block && is_redundant(block, succ)) { - continue; - } else { - redundant = 0; - break; - } - } - - if (redundant) - flag_redundant(irn, 1); - } - } - plist_free(stack); -#endif - } #if HOIST_HIGH