X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fcombo.c;h=4975e3d8bc80e951e1475d7be7ecb63a5467cf59;hb=30b992a490bfdcccb934dbe90710b663898c001f;hp=45f1250748a8ec177ac0825dc392e1b2cb563fe3;hpb=3e8f2f0194240ba72b0367e4d67205aec9d34475;p=libfirm diff --git a/ir/opt/combo.c b/ir/opt/combo.c index 45f125074..4975e3d8b 100644 --- a/ir/opt/combo.c +++ b/ir/opt/combo.c @@ -27,9 +27,9 @@ * - supports all Firm direct (by a data edge) identities except Mux * (Mux can be a 2-input or 1-input identity, only 2-input is implemented yet) * - supports Confirm nodes (handle them like Copies but do NOT remove them) - * - let Cmp nodes calculate Top like all othe data nodes: this would let + * - let Cmp nodes calculate Top like all other data nodes: this would let * Mux nodes to calculate Unknown instead of taking the true result - * - let Cond(Top) always select FALSE/default: This is tricky. Nodes are only reavaluated + * - let Cond(Top) always select FALSE/default: This is tricky. Nodes are only reevaluated * IFF the predecessor changed its type. Because nodes are initialized with Top * this never happens, let all Proj(Cond) be unreachable. * We avoid this condition by the same way we work around Phi: whenever a Block @@ -83,6 +83,7 @@ #include "irpass.h" #include "tv_t.h" #include "irtools.h" +#include "firmstat_t.h" #include "irprintf.h" #include "irdump.h" @@ -439,10 +440,13 @@ static void dump_all_partitions(const environment_t *env) static void dump_split_list(const partition_t *list) { const partition_t *p; + char split = ' '; DB((dbg, LEVEL_2, "Split by %s produced = {\n", what_reason)); - for (p = list; p != NULL; p = p->split_next) - DB((dbg, LEVEL_2, "part%u, ", p->nr)); + for (p = list; p != NULL; p = p->split_next) { + DB((dbg, LEVEL_2, "%c part%u", split, p->nr)); + split = ','; + } DB((dbg, LEVEL_2, "\n}\n")); } /* dump_split_list */ @@ -960,10 +964,11 @@ static partition_t *split_no_followers(partition_t *Z, node_t *g, environment_t /* for now, copy the type info tag, it will be adjusted in split_by(). */ Z_prime->type_is_T_or_C = Z->type_is_T_or_C; - update_worklist(Z, Z_prime, env); - dump_partition("Now ", Z); dump_partition("Created new ", Z_prime); + + update_worklist(Z, Z_prime, env); + return Z_prime; } /* split_no_followers */ @@ -1218,7 +1223,7 @@ static partition_t *split(partition_t **pX, node_t *gg, environment_t *env) * Some informations on the race that are not stated clearly in Click's * thesis. * 1) A follower stays on the side that reach him first. - * 2) If the other side reches a follower, if will be converted to + * 2) If the other side reaches a follower, if will be converted to * a leader. /This must be done after the race is over, else the * edges we are iterating on are renumbered./ * 3) /New leader might end up on both sides./ @@ -1288,6 +1293,9 @@ static partition_t *split(partition_t **pX, node_t *gg, environment_t *env) check_partition(X); check_partition(X_prime); + dump_partition("Now ", X); + dump_partition("Created new ", X_prime); + /* X' is the smaller part */ add_to_worklist(X_prime, env); @@ -1312,9 +1320,6 @@ static partition_t *split(partition_t **pX, node_t *gg, environment_t *env) } } - dump_partition("Now ", X); - dump_partition("Created new ", X_prime); - /* we have to ensure that the partition containing g is returned */ if (winner != 0) { *pX = X_prime; @@ -1911,7 +1916,8 @@ static void compute_Block(node_t *node) int i; ir_node *block = node->node; - if (block == get_irg_start_block(current_ir_graph) || get_Block_entity(block) != NULL) { + ir_graph *const irg = get_Block_irg(block); + if (block == get_irg_start_block(irg) || get_Block_entity(block) != NULL) { /* start block and labelled blocks are always reachable */ node->type.tv = tarval_reachable; return; @@ -2847,6 +2853,17 @@ static void propagate(environment_t *env) /* x will make the follower -> leader transition */ follower_to_leader(x); + + /* In case of a follower -> leader transition of a Phi node + * we have to ensure that the current partition will be split + * by lambda n.(n[i].partition). + * + * This split may already happened before when some predecessors + * of the Phi's Block are unreachable. Thus, we have to put the + * current partition in the worklist to repeat the check. + */ + if (is_Phi(x->node) && ! x->part->on_worklist) + add_to_worklist(x->part, env); } /* compute a new type for x */ @@ -3026,7 +3043,8 @@ static void apply_cf(ir_node *block, void *ctx) } } - if (block == get_irg_end_block(current_ir_graph)) { + ir_graph *const irg = get_Block_irg(block); + if (block == get_irg_end_block(irg)) { /* Analysis found out that the end block is unreachable, * hence we remove all its control flow predecessors. */ set_irn_in(block, 0, NULL);