tree-ssa-pre.c (create_component_ref_by_pieces_1): Move call handling ...

2015-10-05  Richard Biener  <rguenther@suse.de>

	* tree-ssa-pre.c (create_component_ref_by_pieces_1): Move
	call handling ...
	(create_expression_by_pieces): ... here and build GIMPLE
	calls directly.  Use gimple_build API and avoid force_gimple_operand.
	(insert_into_preds_of_block): Simplify.
	(do_regular_insertion): Add comment.

From-SVN: r228471
This commit is contained in:
Richard Biener 2015-10-05 11:13:14 +00:00 committed by Richard Biener
parent 562eadf8e0
commit 9c709f6465
2 changed files with 111 additions and 169 deletions

View File

@ -1,3 +1,12 @@
2015-10-05 Richard Biener <rguenther@suse.de>
* tree-ssa-pre.c (create_component_ref_by_pieces_1): Move
call handling ...
(create_expression_by_pieces): ... here and build GIMPLE
calls directly. Use gimple_build API and avoid force_gimple_operand.
(insert_into_preds_of_block): Simplify.
(do_regular_insertion): Add comment.
2015-10-04 Jason Merrill <jason@redhat.com>
* builtins.def (BUILT_IN_ABORT): Add transaction_pure attribute.

View File

@ -2474,42 +2474,7 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
switch (currop->opcode)
{
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
fn = find_or_generate_expression (block, currop->op0, stmts);
if (!fn)
return NULL_TREE;
if (currop->op1)
{
sc = find_or_generate_expression (block, currop->op1, stmts);
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;
}
gcc_unreachable ();
case MEM_REF:
{
@ -2798,21 +2763,75 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
switch (expr->kind)
{
/* We may hit the NAME/CONSTANT case if we have to convert types
that value numbering saw through. */
/* We may hit the NAME/CONSTANT case if we have to convert types
that value numbering saw through. */
case NAME:
folded = PRE_EXPR_NAME (expr);
if (useless_type_conversion_p (exprtype, TREE_TYPE (folded)))
return folded;
break;
case CONSTANT:
folded = PRE_EXPR_CONSTANT (expr);
break;
case REFERENCE:
{
vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
folded = create_component_ref_by_pieces (block, ref, stmts);
if (!folded)
return NULL_TREE;
{
folded = PRE_EXPR_CONSTANT (expr);
tree tem = fold_convert (exprtype, folded);
if (is_gimple_min_invariant (tem))
return tem;
break;
}
case REFERENCE:
if (PRE_EXPR_REFERENCE (expr)->operands[0].opcode == CALL_EXPR)
{
vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
unsigned int operand = 1;
vn_reference_op_t currop = &ref->operands[0];
tree sc = NULL_TREE;
tree fn;
if (TREE_CODE (currop->op0) == FUNCTION_DECL)
fn = currop->op0;
else
fn = find_or_generate_expression (block, currop->op0, stmts);
if (!fn)
return NULL_TREE;
if (currop->op1)
{
sc = find_or_generate_expression (block, currop->op1, stmts);
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 (&forced_stmts, call);
folded = forcedname;
}
else
{
folded = create_component_ref_by_pieces (block,
PRE_EXPR_REFERENCE (expr),
stmts);
if (!folded)
return NULL_TREE;
name = make_temp_ssa_name (exprtype, NULL, "pretmp");
newstmt = gimple_build_assign (name, folded);
gimple_seq_add_stmt_without_update (&forced_stmts, newstmt);
gimple_set_vuse (newstmt, BB_LIVE_VOP_ON_EXIT (block));
folded = name;
}
break;
case NARY:
{
@ -2845,22 +2864,26 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
for (i = 0; i < nary->length; ++i)
CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, genop[i]);
folded = build_constructor (nary->type, elts);
name = make_temp_ssa_name (exprtype, NULL, "pretmp");
newstmt = gimple_build_assign (name, folded);
gimple_seq_add_stmt_without_update (&forced_stmts, newstmt);
folded = name;
}
else
{
switch (nary->length)
{
case 1:
folded = fold_build1 (nary->opcode, nary->type,
genop[0]);
folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
genop[0]);
break;
case 2:
folded = fold_build2 (nary->opcode, nary->type,
genop[0], genop[1]);
folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
genop[0], genop[1]);
break;
case 3:
folded = fold_build3 (nary->opcode, nary->type,
genop[0], genop[1], genop[2]);
folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
genop[0], genop[1], genop[2]);
break;
default:
gcc_unreachable ();
@ -2872,17 +2895,15 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
gcc_unreachable ();
}
if (!useless_type_conversion_p (exprtype, TREE_TYPE (folded)))
folded = fold_convert (exprtype, folded);
folded = gimple_convert (&forced_stmts, 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 everything simplified to an exisiting SSA name or constant just
return that. */
if (gimple_seq_empty_p (forced_stmts)
|| is_gimple_min_invariant (folded))
return folded;
gcc_assert (TREE_CODE (folded) == SSA_NAME);
/* If we have any intermediate expressions to the value sets, add them
to the value sets and chain them in the instruction stream. */
@ -2895,9 +2916,8 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
tree forcedname = gimple_get_lhs (stmt);
pre_expr nameexpr;
if (TREE_CODE (forcedname) == SSA_NAME)
if (forcedname != folded)
{
bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
VN_INFO_GET (forcedname)->valnum = forcedname;
VN_INFO (forcedname)->value_id = get_next_value_id ();
nameexpr = get_or_alloc_expr_for_name (forcedname);
@ -2906,20 +2926,13 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
}
gimple_set_vuse (stmt, BB_LIVE_VOP_ON_EXIT (block));
gimple_set_modified (stmt, true);
bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
gimple_set_plf (stmt, NECESSARY, false);
}
gimple_seq_add_seq (stmts, forced_stmts);
}
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);
bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (name));
name = folded;
/* Fold the last statement. */
gsi = gsi_last (*stmts);
@ -2947,7 +2960,7 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Inserted ");
print_gimple_stmt (dump_file, newstmt, 0, 0);
print_gimple_stmt (dump_file, gsi_stmt (gsi_last (*stmts)), 0, 0);
fprintf (dump_file, " in predecessor %d (%04d)\n",
block->index, value_id);
}
@ -3004,106 +3017,25 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
tree builtexpr;
bprime = pred->src;
eprime = avail[pred->dest_idx];
if (eprime->kind != NAME && eprime->kind != CONSTANT)
builtexpr = create_expression_by_pieces (bprime, eprime,
&stmts, type);
gcc_assert (!(pred->flags & EDGE_ABNORMAL));
if (!gimple_seq_empty_p (stmts))
{
builtexpr = create_expression_by_pieces (bprime, eprime,
&stmts, type);
gcc_assert (!(pred->flags & EDGE_ABNORMAL));
gsi_insert_seq_on_edge (pred, stmts);
if (!builtexpr)
{
/* We cannot insert a PHI node if we failed to insert
on one edge. */
nophi = true;
continue;
}
avail[pred->dest_idx] = get_or_alloc_expr_for_name (builtexpr);
insertions = true;
}
else if (eprime->kind == CONSTANT)
if (!builtexpr)
{
/* 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)
{
/* We may have to do a conversion because our value
numbering can look through types in certain cases, but
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);
}
/* We cannot insert a PHI node if we failed to insert
on one edge. */
nophi = true;
continue;
}
if (is_gimple_min_invariant (builtexpr))
avail[pred->dest_idx] = get_or_alloc_expr_for_constant (builtexpr);
else
avail[pred->dest_idx] = get_or_alloc_expr_for_name (builtexpr);
}
/* If we didn't want a phi node, and we made insertions, we still have
inserted new stuff, and thus return true. If we didn't want a phi node,
@ -3267,6 +3199,7 @@ do_regular_insertion (basic_block block, basic_block dom)
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);