From: Christoph Mallon Date: Tue, 1 Apr 2008 10:38:08 +0000 (+0000) Subject: Improve equivalent_node_Sync() and transform_node_Sync() so they remove Bad and dupli... X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=d1d5979d9967004773067d0e170eacdac48715a8;p=libfirm Improve equivalent_node_Sync() and transform_node_Sync() so they remove Bad and duplicate predecessors. [r19034] --- diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 69da73dfa..f6367d04a 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -1297,45 +1297,36 @@ static ir_node *equivalent_node_Phi(ir_node *n) { * themselves. */ static ir_node *equivalent_node_Sync(ir_node *n) { - int i, n_preds; - - ir_node *oldn = n; - ir_node *first_val = NULL; /* to shutup gcc */ - - if (!get_opt_normalize()) return n; + int arity = get_Sync_n_preds(n); + int i; - n_preds = get_Sync_n_preds(n); + for (i = 0; i < arity;) { + ir_node *pred = get_Sync_pred(n, i); + int j; - /* Find first non-self-referencing input */ - for (i = 0; i < n_preds; ++i) { - first_val = get_Sync_pred(n, i); - if ((first_val != n) /* not self pointer */ && - (! is_Bad(first_val)) - ) { /* value not dead */ - break; /* then found first value. */ + /* Remove Bad predecessors */ + if (is_Bad(pred)) { + del_Sync_n(n, i); + --arity; + continue; } - } - - if (i >= n_preds) - /* A totally Bad or self-referencing Sync (we didn't break the above loop) */ - return new_Bad(); - /* search the rest of inputs, determine if any of these - are non-self-referencing */ - while (++i < n_preds) { - ir_node *scnd_val = get_Sync_pred(n, i); - if ((scnd_val != n) && - (scnd_val != first_val) && - (! is_Bad(scnd_val)) - ) - break; + /* Remove duplicate predecessors */ + for (j = 0;; ++j) { + if (j >= i) { + ++i; + break; + } + if (get_Sync_pred(n, j) == pred) { + del_Sync_n(n, i); + --arity; + break; + } + } } - if (i >= n_preds) { - /* Fold, if no multiple distinct non-self-referencing inputs */ - n = first_val; - DBG_OPT_SYNC(oldn, n); - } + if (arity == 0) return new_Bad(); + if (arity == 1) return get_Sync_pred(n, 0); return n; } /* equivalent_node_Sync */ @@ -4873,28 +4864,35 @@ static ir_node *transform_node_Psi(ir_node *n) { * of the other sync to our own inputs */ static ir_node *transform_node_Sync(ir_node *n) { - int i, arity; + int arity = get_Sync_n_preds(n); + int i; + + for (i = 0; i < arity;) { + ir_node *pred = get_Sync_pred(n, i); + int pred_arity; + int j; - arity = get_irn_arity(n); - for(i = 0; i < get_irn_arity(n); /*empty*/) { - int i2, arity2; - ir_node *in = get_irn_n(n, i); - if(!is_Sync(in)) { + if (!is_Sync(pred)) { ++i; continue; } - /* set sync input 0 instead of the sync */ - set_irn_n(n, i, get_irn_n(in, 0)); - /* so we check this input again for syncs */ - - /* append all other inputs of the sync to our sync */ - arity2 = get_irn_arity(in); - for(i2 = 1; i2 < arity2; ++i2) { - ir_node *in_in = get_irn_n(in, i2); - add_irn_n(n, in_in); - /* increase arity so we also check the new inputs for syncs */ - arity++; + del_Sync_n(n, i); + --arity; + + pred_arity = get_Sync_n_preds(pred); + for (j = 0; j < pred_arity; ++j) { + ir_node *pred_pred = get_Sync_pred(pred, j); + int k; + + for (k = 0;; ++k) { + if (k >= arity) { + add_irn_n(n, pred_pred); + ++arity; + break; + } + if (get_Sync_pred(n, k) == pred_pred) break; + } } }