The following patch from the match-and-simplify branch removes gimplifier use from PRE replacing it with use of the gimple_build API building GIMPLE directly.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2015-10-01 Richard Biener <rguent...@suse.de> * tree-ssa-pre.c (create_component_ref_by_pieces_1): Build GIMPLE calls directly. (create_expression_by_pieces): Use gimple_build API and avoid force_gimple_operand. (insert_into_preds_of_block): Likewise. (do_regular_insertion): Add comment. Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 228320) --- gcc/tree-ssa-pre.c (working copy) *************** create_component_ref_by_pieces_1 (basic_ *** 2475,2483 **** { case CALL_EXPR: { ! tree folded, sc = NULL_TREE; ! unsigned int nargs = 0; ! tree fn, *args; if (TREE_CODE (currop->op0) == FUNCTION_DECL) fn = currop->op0; else --- 2475,2482 ---- { case CALL_EXPR: { ! tree sc = NULL_TREE; ! tree fn; if (TREE_CODE (currop->op0) == FUNCTION_DECL) fn = currop->op0; else *************** create_component_ref_by_pieces_1 (basic_ *** 2490,2514 **** if (!sc) return NULL_TREE; } ! args = XNEWVEC (tree, ref->operands.length () - 1); while (*operand < ref->operands.length ()) { ! args[nargs] = create_component_ref_by_pieces_1 (block, ref, ! operand, stmts); ! if (!args[nargs]) return NULL_TREE; ! nargs++; } ! folded = build_call_array (currop->type, ! (TREE_CODE (fn) == FUNCTION_DECL ! ? build_fold_addr_expr (fn) : fn), ! nargs, args); ! if (currop->with_bounds) ! CALL_WITH_BOUNDS_P (folded) = true; ! free (args); if (sc) ! CALL_EXPR_STATIC_CHAIN (folded) = sc; ! return folded; } case MEM_REF: --- 2489,2521 ---- if (!sc) return NULL_TREE; } ! auto_vec<tree> args (ref->operands.length () - 1); while (*operand < ref->operands.length ()) { ! tree arg = create_component_ref_by_pieces_1 (block, ref, ! operand, stmts); ! if (!arg) return NULL_TREE; ! args.quick_push (arg); } ! gcall *call = gimple_build_call_vec ((TREE_CODE (fn) == FUNCTION_DECL ! ? build_fold_addr_expr (fn) : fn), ! args); ! gimple_call_set_with_bounds (call, currop->with_bounds); if (sc) ! gimple_call_set_chain (call, sc); ! tree forcedname = make_ssa_name (currop->type); ! gimple_call_set_lhs (call, forcedname); ! gimple_set_vuse (call, BB_LIVE_VOP_ON_EXIT (block)); ! gimple_seq_add_stmt_without_update (stmts, call); ! bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname)); ! VN_INFO_GET (forcedname)->valnum = forcedname; ! VN_INFO (forcedname)->value_id = get_next_value_id (); ! pre_expr nameexpr = get_or_alloc_expr_for_name (forcedname); ! add_to_value (VN_INFO (forcedname)->value_id, nameexpr); ! bitmap_value_replace_in_set (NEW_SETS (block), nameexpr); ! bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr); ! return forcedname; } case MEM_REF: *************** create_expression_by_pieces (basic_block *** 2851,2866 **** switch (nary->length) { case 1: ! folded = fold_build1 (nary->opcode, nary->type, ! genop[0]); break; case 2: ! folded = fold_build2 (nary->opcode, nary->type, ! genop[0], genop[1]); break; case 3: ! folded = fold_build3 (nary->opcode, nary->type, ! genop[0], genop[1], genop[2]); break; default: gcc_unreachable (); --- 2858,2873 ---- switch (nary->length) { case 1: ! folded = gimple_build (&forced_stmts, nary->opcode, nary->type, ! genop[0]); break; case 2: ! folded = gimple_build (&forced_stmts, nary->opcode, nary->type, ! genop[0], genop[1]); break; case 3: ! folded = gimple_build (&forced_stmts, nary->opcode, nary->type, ! genop[0], genop[1], genop[2]); break; default: gcc_unreachable (); *************** create_expression_by_pieces (basic_block *** 2872,2888 **** gcc_unreachable (); } ! if (!useless_type_conversion_p (exprtype, TREE_TYPE (folded))) ! folded = fold_convert (exprtype, folded); ! ! /* Force the generated expression to be a sequence of GIMPLE ! statements. ! We have to call unshare_expr because force_gimple_operand may ! modify the tree we pass to it. */ ! gimple_seq tem = NULL; ! folded = force_gimple_operand (unshare_expr (folded), &tem, ! false, NULL); ! gimple_seq_add_seq_without_update (&forced_stmts, tem); /* If we have any intermediate expressions to the value sets, add them to the value sets and chain them in the instruction stream. */ --- 2879,2885 ---- gcc_unreachable (); } ! folded = gimple_convert (&forced_stmts, exprtype, folded); /* If we have any intermediate expressions to the value sets, add them to the value sets and chain them in the instruction stream. */ *************** create_expression_by_pieces (basic_block *** 2915,2921 **** name = make_temp_ssa_name (exprtype, NULL, "pretmp"); newstmt = gimple_build_assign (name, folded); gimple_set_vuse (newstmt, BB_LIVE_VOP_ON_EXIT (block)); - gimple_set_modified (newstmt, true); gimple_set_plf (newstmt, NECESSARY, false); gimple_seq_add_stmt (stmts, newstmt); --- 2912,2917 ---- *************** insert_into_preds_of_block (basic_block *** 3026,3069 **** /* Constants may not have the right type, fold_convert should give us back a constant with the right type. */ tree constant = PRE_EXPR_CONSTANT (eprime); ! if (!useless_type_conversion_p (type, TREE_TYPE (constant))) { ! tree builtexpr = fold_convert (type, constant); ! if (!is_gimple_min_invariant (builtexpr)) { ! tree forcedexpr = force_gimple_operand (builtexpr, ! &stmts, true, ! NULL); ! if (!is_gimple_min_invariant (forcedexpr)) { ! if (forcedexpr != builtexpr) ! { ! VN_INFO_GET (forcedexpr)->valnum = PRE_EXPR_CONSTANT (eprime); ! VN_INFO (forcedexpr)->value_id = get_expr_value_id (eprime); ! } ! if (stmts) ! { ! gimple_stmt_iterator gsi; ! gsi = gsi_start (stmts); ! for (; !gsi_end_p (gsi); gsi_next (&gsi)) ! { ! gimple *stmt = gsi_stmt (gsi); ! tree lhs = gimple_get_lhs (stmt); ! if (TREE_CODE (lhs) == SSA_NAME) ! bitmap_set_bit (inserted_exprs, ! SSA_NAME_VERSION (lhs)); ! gimple_set_plf (stmt, NECESSARY, false); ! } ! gsi_insert_seq_on_edge (pred, stmts); ! } ! avail[pred->dest_idx] ! = get_or_alloc_expr_for_name (forcedexpr); } } ! else ! avail[pred->dest_idx] ! = get_or_alloc_expr_for_constant (builtexpr); } } else if (eprime->kind == NAME) { --- 3022,3051 ---- /* Constants may not have the right type, fold_convert should give us back a constant with the right type. */ tree constant = PRE_EXPR_CONSTANT (eprime); ! tree forcedexpr = gimple_convert (&stmts, type, constant); ! if (!is_gimple_min_invariant (forcedexpr)) { ! VN_INFO_GET (forcedexpr)->valnum = PRE_EXPR_CONSTANT (eprime); ! VN_INFO (forcedexpr)->value_id = get_expr_value_id (eprime); ! if (!gimple_seq_empty_p (stmts)) { ! gimple_stmt_iterator gsi; ! gsi = gsi_start (stmts); ! for (; !gsi_end_p (gsi); gsi_next (&gsi)) { ! gimple *stmt = gsi_stmt (gsi); ! tree lhs = gimple_get_lhs (stmt); ! if (TREE_CODE (lhs) == SSA_NAME) ! bitmap_set_bit (inserted_exprs, ! SSA_NAME_VERSION (lhs)); ! gimple_set_plf (stmt, NECESSARY, false); } + gsi_insert_seq_on_edge (pred, stmts); } ! avail[pred->dest_idx] = get_or_alloc_expr_for_name (forcedexpr); } + else + avail[pred->dest_idx] = get_or_alloc_expr_for_constant (forcedexpr); } else if (eprime->kind == NAME) { *************** insert_into_preds_of_block (basic_block *** 3072,3108 **** our IL requires all operands of a phi node have the same type. */ tree name = PRE_EXPR_NAME (eprime); ! if (!useless_type_conversion_p (type, TREE_TYPE (name))) { ! tree builtexpr; ! tree forcedexpr; ! builtexpr = fold_convert (type, name); ! forcedexpr = force_gimple_operand (builtexpr, ! &stmts, true, ! NULL); ! ! if (forcedexpr != name) ! { ! VN_INFO_GET (forcedexpr)->valnum = VN_INFO (name)->valnum; ! VN_INFO (forcedexpr)->value_id = VN_INFO (name)->value_id; ! } ! ! if (stmts) { ! gimple_stmt_iterator gsi; ! gsi = gsi_start (stmts); ! for (; !gsi_end_p (gsi); gsi_next (&gsi)) ! { ! gimple *stmt = gsi_stmt (gsi); ! tree lhs = gimple_get_lhs (stmt); ! if (TREE_CODE (lhs) == SSA_NAME) ! bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (lhs)); ! gimple_set_plf (stmt, NECESSARY, false); ! } ! gsi_insert_seq_on_edge (pred, stmts); } ! avail[pred->dest_idx] = get_or_alloc_expr_for_name (forcedexpr); } } } /* If we didn't want a phi node, and we made insertions, we still have --- 3054,3080 ---- our IL requires all operands of a phi node have the same type. */ tree name = PRE_EXPR_NAME (eprime); ! tree forcedexpr = gimple_convert (&stmts, type, name); ! if (forcedexpr != name) { ! VN_INFO_GET (forcedexpr)->valnum = VN_INFO (name)->valnum; ! VN_INFO (forcedexpr)->value_id = VN_INFO (name)->value_id; ! } ! if (!gimple_seq_empty_p (stmts)) ! { ! gimple_stmt_iterator gsi; ! gsi = gsi_start (stmts); ! for (; !gsi_end_p (gsi); gsi_next (&gsi)) { ! gimple *stmt = gsi_stmt (gsi); ! tree lhs = gimple_get_lhs (stmt); ! if (TREE_CODE (lhs) == SSA_NAME) ! bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (lhs)); ! gimple_set_plf (stmt, NECESSARY, false); } ! gsi_insert_seq_on_edge (pred, stmts); } + avail[pred->dest_idx] = get_or_alloc_expr_for_name (forcedexpr); } } /* If we didn't want a phi node, and we made insertions, we still have *************** do_regular_insertion (basic_block block, *** 3267,3272 **** --- 3239,3245 ---- and so not come across fake pred edges. */ gcc_assert (!(pred->flags & EDGE_FAKE)); bprime = pred->src; + /* We are looking at ANTIC_OUT of bprime. */ eprime = phi_translate (expr, ANTIC_IN (block), NULL, bprime, block);