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:
{
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:
{
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 ();
gcc_unreachable ();
}
- if (!useless_type_conversion_p (exprtype, TREE_TYPE (folded)))
- folded = fold_convert (exprtype, folded);
+ folded = gimple_convert (&forced_stmts, exprtype, folded);
+
+ /* 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;
- /* 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);
+ 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. */
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);
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);
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);
}
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)
- {
- /* 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)
+ if (!builtexpr)
{
- /* 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,
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);