This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Remove gimplifier use from PRE
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 1 Oct 2015 15:39:37 +0200 (CEST)
- Subject: [PATCH] Remove gimplifier use from PRE
- Authentication-results: sourceware.org; auth=none
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 <rguenther@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);