diff options
author | Daniel Berlin <dberlin@dberlin.org> | 2004-11-30 14:49:37 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@gcc.gnu.org> | 2004-11-30 14:49:37 +0000 |
commit | e92845664c623d7b8cf9bcf41d27183d2081a9fa (patch) | |
tree | 87e56b92f614c34099494e971e4a652d4970f806 /gcc/tree-ssa-pre.c | |
parent | f2b60e4039b662779ffc4a59eacb186b5b821cd6 (diff) | |
download | gcc-e92845664c623d7b8cf9bcf41d27183d2081a9fa.zip gcc-e92845664c623d7b8cf9bcf41d27183d2081a9fa.tar.gz gcc-e92845664c623d7b8cf9bcf41d27183d2081a9fa.tar.bz2 |
re PR tree-optimization/18673 (Tree-PRE is O(N^4) in the depth of the dominator tree)
2004-11-29 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/18673
* tree-ssa-pre.c: Remove splay-tree.h include.
(bitmap_value_replace_in_set): Fix to add if it does not exist.
(find_or_generate_expression): Remove now-wrong condition.
(create_expression_by_pieces): Fix condition and comment reason
for it.
(insert_aux): Fix condition and comment reasons for it.
Factor insertion code from here.
(insert_into_preds_of_block): To here. Fix conditions in factored
function and comment reasons for them.
From-SVN: r91522
Diffstat (limited to 'gcc/tree-ssa-pre.c')
-rw-r--r-- | gcc/tree-ssa-pre.c | 197 |
1 files changed, 117 insertions, 80 deletions
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 7cffc56..29cd567 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -41,7 +41,6 @@ Boston, MA 02111-1307, USA. */ #include "alloc-pool.h" #include "tree-pass.h" #include "flags.h" -#include "splay-tree.h" #include "bitmap.h" #include "langhooks.h" @@ -652,6 +651,7 @@ bitmap_set_replace_value (bitmap_set_t set, tree lookfor, tree expr) return; if (!bitmap_set_contains_value (set, lookfor)) return; + /* The number of expressions having a given value is usually significantly less than the total number of expressions in SET. Thus, rather than check, for each expression in SET, whether it @@ -713,13 +713,17 @@ set_equal (value_set_t a, value_set_t b) return true; } -/* Replace an instance of EXPR's VALUE with EXPR in SET. */ +/* Replace an instance of EXPR's VALUE with EXPR in SET if it exists, + and add it otherwise. */ static void bitmap_value_replace_in_set (bitmap_set_t set, tree expr) { tree val = get_value_handle (expr); - bitmap_set_replace_value (set, val, expr); + if (bitmap_set_contains_value (set, val)) + bitmap_set_replace_value (set, val, expr); + else + bitmap_insert_into_set (set, expr); } /* Insert EXPR into SET if EXPR's value is not already present in @@ -1278,15 +1282,8 @@ compute_antic (void) static tree find_or_generate_expression (basic_block block, tree expr, tree stmts) { - tree genop; - genop = bitmap_find_leader (AVAIL_OUT (block), expr); - /* Depending on the order we process DOM branches in, the value - may not have propagated to all the dom children yet during - this iteration. In this case, the value will always be in - the NEW_SETS for us already, having been propagated from our - dominator. */ - if (genop == NULL) - genop = bitmap_find_leader (NEW_SETS (block), expr); + tree genop = bitmap_find_leader (AVAIL_OUT (block), expr); + /* If it's still NULL, see if it is a complex expression, and if so, generate it recursively, otherwise, abort, because it's not really . */ @@ -1374,8 +1371,13 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts) } v = get_value_handle (expr); vn_add (name, v, NULL); - bitmap_insert_into_set (NEW_SETS (block), name); - bitmap_value_insert_into_set (AVAIL_OUT (block), name); + + /* The value may already exist in either NEW_SETS, or AVAIL_OUT, because + we are creating the expression by pieces, and this particular piece of + the expression may have been represented. There is no harm in replacing + here. */ + bitmap_value_replace_in_set (NEW_SETS (block), name); + bitmap_value_replace_in_set (AVAIL_OUT (block), name); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Inserted "); @@ -1384,6 +1386,90 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts) } return name; } + +/* Insert the to-be-made-available values of NODE for each predecessor, stored + in AVAIL, into the predecessors of BLOCK, and merge the result with a phi + node, given the same value handle as NODE. The prefix of the phi node is + given with TMPNAME*/ + +static bool +insert_into_preds_of_block (basic_block block, value_set_node_t node, + tree *avail, const char *tmpname) +{ + tree val = get_value_handle (node->expr); + edge pred; + basic_block bprime; + tree eprime; + edge_iterator ei; + tree type = TREE_TYPE (avail[EDGE_PRED (block, 0)->src->index]); + tree temp; + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Found partial redundancy for expression "); + print_generic_expr (dump_file, node->expr, 0); + fprintf (dump_file, "\n"); + } + + /* Make the necessary insertions. */ + FOR_EACH_EDGE (pred, ei, block->preds) + { + tree stmts = alloc_stmt_list (); + tree builtexpr; + bprime = pred->src; + eprime = avail[bprime->index]; + if (BINARY_CLASS_P (eprime) + || UNARY_CLASS_P (eprime)) + { + builtexpr = create_expression_by_pieces (bprime, + eprime, + stmts); + bsi_insert_on_edge (pred, stmts); + avail[bprime->index] = builtexpr; + } + } + /* Now build a phi for the new variable. */ + temp = create_tmp_var (type, tmpname); + add_referenced_tmp_var (temp); + temp = create_phi_node (temp, block); + + FOR_EACH_EDGE (pred, ei, block->preds) + add_phi_arg (temp, avail[pred->src->index], pred); + + vn_add (PHI_RESULT (temp), val, NULL); + + /* The value should *not* exist in PHI_GEN, or else we wouldn't be doing + this insertion, since we test for the existence of this value in PHI_GEN + before proceeding with the partial redundancy checks in insert_aux. + + The value may exist in AVAIL_OUT, in particular, it could be represented + by the expression we are trying to eliminate, in which case we want the + replacement to occur. If it's not existing in AVAIL_OUT, we want it + inserted there. + + Similarly, to the PHI_GEN case, the value should not exist in NEW_SETS of + this block, because if it did, it would have existed in our dominator's + AVAIL_OUT, and would have been skipped due to the full redundancy check. + */ + + bitmap_insert_into_set (PHI_GEN (block), + PHI_RESULT (temp)); + bitmap_value_replace_in_set (AVAIL_OUT (block), + PHI_RESULT (temp)); + bitmap_insert_into_set (NEW_SETS (block), + PHI_RESULT (temp)); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Created phi "); + print_generic_expr (dump_file, temp, 0); + fprintf (dump_file, " in block %d\n", block->index); + } + pre_stats.phis++; + return true; +} + + /* Perform insertion of partially redundant values. For BLOCK, do the following: @@ -1399,6 +1485,7 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts) 3. Recursively call ourselves on the dominator children of BLOCK. */ + static bool insert_aux (basic_block block) { @@ -1413,12 +1500,18 @@ insert_aux (basic_block block) { unsigned i; bitmap_iterator bi; - bitmap_set_t newset = NEW_SETS (dom); - EXECUTE_IF_SET_IN_BITMAP (newset->expressions, 0, i, bi) + if (newset) { - bitmap_insert_into_set (NEW_SETS (block), ssa_name (i)); - bitmap_value_replace_in_set (AVAIL_OUT (block), ssa_name (i)); + /* Note that we need to value_replace both NEW_SETS, and + AVAIL_OUT. For both the case of NEW_SETS, the value may be + represented by some non-simple expression here that we want + to replace it with. */ + EXECUTE_IF_SET_IN_BITMAP (newset->expressions, 0, i, bi) + { + bitmap_value_replace_in_set (NEW_SETS (block), ssa_name (i)); + bitmap_value_replace_in_set (AVAIL_OUT (block), ssa_name (i)); + } } if (EDGE_COUNT (block->preds) > 1) { @@ -1438,7 +1531,7 @@ insert_aux (basic_block block) tree first_s = NULL; edge pred; basic_block bprime; - tree eprime; + tree eprime = NULL_TREE; edge_iterator ei; val = get_value_handle (node->expr); @@ -1500,11 +1593,9 @@ insert_aux (basic_block block) by_some = true; if (first_s == NULL) first_s = edoubleprime; - else if (first_s != edoubleprime) + else if (!operand_equal_p (first_s, edoubleprime, + 0)) all_same = false; - gcc_assert (first_s == edoubleprime - || !operand_equal_p - (first_s, edoubleprime, 0)); } } /* If we can insert it, it's not the same value @@ -1513,63 +1604,9 @@ insert_aux (basic_block block) partially redundant. */ if (!cant_insert && !all_same && by_some) { - tree type = TREE_TYPE (avail[EDGE_PRED (block, 0)->src->index]); - tree temp; - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Found partial redundancy for expression "); - print_generic_expr (dump_file, node->expr, 0); - fprintf (dump_file, "\n"); - } - - /* Make the necessary insertions. */ - FOR_EACH_EDGE (pred, ei, block->preds) - { - tree stmts = alloc_stmt_list (); - tree builtexpr; - bprime = pred->src; - eprime = avail[bprime->index]; - if (BINARY_CLASS_P (eprime) - || UNARY_CLASS_P (eprime)) - { - builtexpr = create_expression_by_pieces (bprime, - eprime, - stmts); - bsi_insert_on_edge (pred, stmts); - avail[bprime->index] = builtexpr; - } - } - /* Now build a phi for the new variable. */ - temp = create_tmp_var (type, "prephitmp"); - add_referenced_tmp_var (temp); - temp = create_phi_node (temp, block); - vn_add (PHI_RESULT (temp), val, NULL); - -#if 0 - if (!set_contains_value (AVAIL_OUT (block), val)) - insert_into_set (AVAIL_OUT (block), - PHI_RESULT (temp)); - else -#endif - bitmap_value_replace_in_set (AVAIL_OUT (block), - PHI_RESULT (temp)); - FOR_EACH_EDGE (pred, ei, block->preds) - { - add_phi_arg (temp, avail[pred->src->index], - pred); - } - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Created phi "); - print_generic_expr (dump_file, temp, 0); - fprintf (dump_file, " in block %d\n", block->index); - } - pre_stats.phis++; - new_stuff = true; - bitmap_insert_into_set (NEW_SETS (block), - PHI_RESULT (temp)); - bitmap_insert_into_set (PHI_GEN (block), - PHI_RESULT (temp)); + if (insert_into_preds_of_block (block, node, avail, + "prephitmp")) + new_stuff = true; } free (avail); |