Currently computa_avail consumes an unreasonable amount of memory in the FRE case for PR46590. The following patch makes some obvious adjustments but does not cure the underlying issue.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2012-09-04 Richard Guenther <rguent...@suse.de> * tree-ssa-pre.c (add_to_exp_gen): Adjust. (make_values_for_phi): Do not add to PHI_GEN for FRE. (compute_avail): Stop processing after adding all defs to AVAIL_OUT for FRE. (init_pre): Do not allocate not needed bitmap sets for FRE. Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 190918) --- gcc/tree-ssa-pre.c (working copy) *************** insert (void) *** 3786,3799 **** static void add_to_exp_gen (basic_block block, tree op) { ! if (!in_fre) ! { ! pre_expr result; ! if (TREE_CODE (op) == SSA_NAME && ssa_undefined_value_p (op)) ! return; ! result = get_or_alloc_expr_for_name (op); ! bitmap_value_insert_into_set (EXP_GEN (block), result); ! } } /* Create value ids for PHI in BLOCK. */ --- 3786,3800 ---- static void add_to_exp_gen (basic_block block, tree op) { ! pre_expr result; ! ! gcc_checking_assert (!in_fre); ! ! if (TREE_CODE (op) == SSA_NAME && ssa_undefined_value_p (op)) ! return; ! ! result = get_or_alloc_expr_for_name (op); ! bitmap_value_insert_into_set (EXP_GEN (block), result); } /* Create value ids for PHI in BLOCK. */ *************** make_values_for_phi (gimple phi, basic_b *** 3805,3827 **** /* We have no need for virtual phis, as they don't represent actual computations. */ ! if (!virtual_operand_p (result)) { ! pre_expr e = get_or_alloc_expr_for_name (result); ! add_to_value (get_expr_value_id (e), e); bitmap_insert_into_set (PHI_GEN (block), e); ! bitmap_value_insert_into_set (AVAIL_OUT (block), e); ! if (!in_fre) { ! unsigned i; ! for (i = 0; i < gimple_phi_num_args (phi); ++i) { ! tree arg = gimple_phi_arg_def (phi, i); ! if (TREE_CODE (arg) == SSA_NAME) ! { ! e = get_or_alloc_expr_for_name (arg); ! add_to_value (get_expr_value_id (e), e); ! } } } } --- 3806,3828 ---- /* We have no need for virtual phis, as they don't represent actual computations. */ ! if (virtual_operand_p (result)) ! return; ! ! pre_expr e = get_or_alloc_expr_for_name (result); ! add_to_value (get_expr_value_id (e), e); ! bitmap_value_insert_into_set (AVAIL_OUT (block), e); ! if (!in_fre) { ! unsigned i; bitmap_insert_into_set (PHI_GEN (block), e); ! for (i = 0; i < gimple_phi_num_args (phi); ++i) { ! tree arg = gimple_phi_arg_def (phi, i); ! if (TREE_CODE (arg) == SSA_NAME) { ! e = get_or_alloc_expr_for_name (arg); ! add_to_value (get_expr_value_id (e), e); } } } *************** compute_avail (void) *** 3934,3939 **** --- 3935,3944 ---- bitmap_value_insert_into_set (AVAIL_OUT (block), e); } + /* That's all we need to do when doing FRE. */ + if (in_fre) + continue; + if (gimple_has_side_effects (stmt) || stmt_could_throw_p (stmt)) continue; *************** compute_avail (void) *** 3992,3999 **** get_or_alloc_expression_id (result); add_to_value (get_expr_value_id (result), result); ! if (!in_fre) ! bitmap_value_insert_into_set (EXP_GEN (block), result); } continue; } --- 3997,4003 ---- get_or_alloc_expression_id (result); add_to_value (get_expr_value_id (result), result); ! bitmap_value_insert_into_set (EXP_GEN (block), result); } continue; } *************** compute_avail (void) *** 4105,4112 **** get_or_alloc_expression_id (result); add_to_value (get_expr_value_id (result), result); ! if (!in_fre) ! bitmap_value_insert_into_set (EXP_GEN (block), result); continue; } --- 4109,4115 ---- get_or_alloc_expression_id (result); add_to_value (get_expr_value_id (result), result); ! bitmap_value_insert_into_set (EXP_GEN (block), result); continue; } *************** my_rev_post_order_compute (int *post_ord *** 4733,4747 **** src = ei_edge (ei)->src; dest = ei_edge (ei)->dest; ! /* Check if the edge destination has been visited yet. */ if (src != ENTRY_BLOCK_PTR && ! TEST_BIT (visited, src->index)) { /* Mark that we have visited the destination. */ SET_BIT (visited, src->index); if (EDGE_COUNT (src->preds) > 0) ! /* Since the DEST node has been visited for the first ! time, check its successors. */ stack[sp++] = ei_start (src->preds); else post_order[post_order_num++] = src->index; --- 4736,4750 ---- src = ei_edge (ei)->src; dest = ei_edge (ei)->dest; ! /* Check if the edge source has been visited yet. */ if (src != ENTRY_BLOCK_PTR && ! TEST_BIT (visited, src->index)) { /* Mark that we have visited the destination. */ SET_BIT (visited, src->index); if (EDGE_COUNT (src->preds) > 0) ! /* Since the SRC node has been visited for the first ! time, check its predecessors. */ stack[sp++] = ei_start (src->preds); else post_order[post_order_num++] = src->index; *************** init_pre (bool do_fre) *** 4807,4815 **** sizeof (struct pre_expr_d), 30); FOR_ALL_BB (bb) { ! EXP_GEN (bb) = bitmap_set_new (); ! PHI_GEN (bb) = bitmap_set_new (); ! TMP_GEN (bb) = bitmap_set_new (); AVAIL_OUT (bb) = bitmap_set_new (); } --- 4810,4821 ---- sizeof (struct pre_expr_d), 30); FOR_ALL_BB (bb) { ! if (!do_fre) ! { ! EXP_GEN (bb) = bitmap_set_new (); ! PHI_GEN (bb) = bitmap_set_new (); ! TMP_GEN (bb) = bitmap_set_new (); ! } AVAIL_OUT (bb) = bitmap_set_new (); }