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:
parent
562eadf8e0
commit
9c709f6465
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user