gimple-iterator.c (gsi_start_edge): New function.
2014-04-17 Martin Jambor <mjambor@suse.cz> * gimple-iterator.c (gsi_start_edge): New function. * gimple-iterator.h (gsi_start_edge): Declare. * tree-sra.c (single_non_eh_succ): New function. (disqualify_ops_if_throwing_stmt): Renamed to disqualify_if_bad_bb_terminating_stmt. Allow throwing statements having one non-EH successor BB. (sra_modify_expr): If stmt ends bb, use single non-EH successor to generate loads into replacements. (sra_modify_assign): Likewise and and also use the simple path for such statements. (sra_modify_function_body): Commit statements on edges. testsuite/ * gnat.dg/opt34.adb: New. * gnat.dg/opt34_pkg.ads: Likewise. From-SVN: r209487
This commit is contained in:
parent
b94970bc41
commit
104cb50bd1
@ -1,3 +1,17 @@
|
||||
2014-04-17 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* gimple-iterator.c (gsi_start_edge): New function.
|
||||
* gimple-iterator.h (gsi_start_edge): Declare.
|
||||
* tree-sra.c (single_non_eh_succ): New function.
|
||||
(disqualify_ops_if_throwing_stmt): Renamed to
|
||||
disqualify_if_bad_bb_terminating_stmt. Allow throwing statements
|
||||
having one non-EH successor BB.
|
||||
(sra_modify_expr): If stmt ends bb, use single non-EH successor to
|
||||
generate loads into replacements.
|
||||
(sra_modify_assign): Likewise and and also use the simple path for
|
||||
such statements.
|
||||
(sra_modify_function_body): Commit statements on edges.
|
||||
|
||||
2014-04-17 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/60849
|
||||
|
@ -689,6 +689,15 @@ gsi_insert_seq_on_edge (edge e, gimple_seq seq)
|
||||
gimple_seq_add_seq (&PENDING_STMT (e), seq);
|
||||
}
|
||||
|
||||
/* Return a new iterator pointing to the first statement in sequence of
|
||||
statements on edge E. Such statements need to be subsequently moved into a
|
||||
basic block by calling gsi_commit_edge_inserts. */
|
||||
|
||||
gimple_stmt_iterator
|
||||
gsi_start_edge (edge e)
|
||||
{
|
||||
return gsi_start (PENDING_STMT (e));
|
||||
}
|
||||
|
||||
/* Insert the statement pointed-to by GSI into edge E. Every attempt
|
||||
is made to place the statement in an existing basic block, but
|
||||
|
@ -123,6 +123,8 @@ gsi_start_bb (basic_block bb)
|
||||
return i;
|
||||
}
|
||||
|
||||
gimple_stmt_iterator gsi_start_edge (edge e);
|
||||
|
||||
/* Return a new iterator initially pointing to GIMPLE_SEQ's last statement. */
|
||||
|
||||
static inline gimple_stmt_iterator
|
||||
|
@ -1,3 +1,8 @@
|
||||
2014-04-17 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* gnat.dg/opt34.adb: New.
|
||||
* gnat.dg/opt34_pkg.ads: Likewise.
|
||||
|
||||
2014-04-17 Trevor Saunders <tsaunders@mozilla.com>
|
||||
|
||||
* g++.dg/plugin/dumb_plugin.c, g++.dg/plugin/selfasign.c,
|
||||
|
29
gcc/testsuite/gnat.dg/opt34.adb
Normal file
29
gcc/testsuite/gnat.dg/opt34.adb
Normal file
@ -0,0 +1,29 @@
|
||||
-- { dg-do compile }
|
||||
-- { dg-options "-O -fdump-tree-esra" }
|
||||
|
||||
with Opt34_Pkg; use Opt34_Pkg;
|
||||
|
||||
procedure Opt34 is
|
||||
|
||||
function Local_Fun (Arg : T_Private) return T_Private is
|
||||
Result : T_Private;
|
||||
begin
|
||||
|
||||
case Get_Integer (Arg) is
|
||||
when 1 =>
|
||||
Result := Get_Private (100);
|
||||
when 2 =>
|
||||
Result := T_Private_Zero;
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
|
||||
return Result;
|
||||
end Local_Fun;
|
||||
|
||||
begin
|
||||
Assert (Get_Integer (Local_Fun (Get_Private (1))) = 100);
|
||||
end;
|
||||
|
||||
-- { dg-final { scan-tree-dump "Created a replacement for result" "esra" } }
|
||||
-- { dg-final { cleanup-tree-dump "esra" } }
|
14
gcc/testsuite/gnat.dg/opt34_pkg.ads
Normal file
14
gcc/testsuite/gnat.dg/opt34_pkg.ads
Normal file
@ -0,0 +1,14 @@
|
||||
package Opt34_Pkg is
|
||||
|
||||
type T_Private is record
|
||||
I : Integer := 0;
|
||||
end record;
|
||||
|
||||
T_Private_Zero : constant T_Private := (I => 0);
|
||||
|
||||
function Get_Private (I : Integer) return T_Private;
|
||||
function Get_Integer (X : T_Private) return Integer;
|
||||
|
||||
procedure Assert (Cond : Boolean);
|
||||
|
||||
end Opt34_Pkg;
|
@ -1142,17 +1142,41 @@ build_access_from_expr (tree expr, gimple stmt, bool write)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Disqualify LHS and RHS for scalarization if STMT must end its basic block in
|
||||
modes in which it matters, return true iff they have been disqualified. RHS
|
||||
may be NULL, in that case ignore it. If we scalarize an aggregate in
|
||||
intra-SRA we may need to add statements after each statement. This is not
|
||||
possible if a statement unconditionally has to end the basic block. */
|
||||
/* Return the single non-EH successor edge of BB or NULL if there is none or
|
||||
more than one. */
|
||||
|
||||
static edge
|
||||
single_non_eh_succ (basic_block bb)
|
||||
{
|
||||
edge e, res = NULL;
|
||||
edge_iterator ei;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
if (!(e->flags & EDGE_EH))
|
||||
{
|
||||
if (res)
|
||||
return NULL;
|
||||
res = e;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Disqualify LHS and RHS for scalarization if STMT has to terminate its BB and
|
||||
there is no alternative spot where to put statements SRA might need to
|
||||
generate after it. The spot we are looking for is an edge leading to a
|
||||
single non-EH successor, if it exists and is indeed single. RHS may be
|
||||
NULL, in that case ignore it. */
|
||||
|
||||
static bool
|
||||
disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
|
||||
disqualify_if_bad_bb_terminating_stmt (gimple stmt, tree lhs, tree rhs)
|
||||
{
|
||||
if ((sra_mode == SRA_MODE_EARLY_INTRA || sra_mode == SRA_MODE_INTRA)
|
||||
&& (stmt_can_throw_internal (stmt) || stmt_ends_bb_p (stmt)))
|
||||
&& stmt_ends_bb_p (stmt))
|
||||
{
|
||||
if (single_non_eh_succ (gimple_bb (stmt)))
|
||||
return false;
|
||||
|
||||
disqualify_base_of_expr (lhs, "LHS of a throwing stmt.");
|
||||
if (rhs)
|
||||
disqualify_base_of_expr (rhs, "RHS of a throwing stmt.");
|
||||
@ -1180,7 +1204,7 @@ build_accesses_from_assign (gimple stmt)
|
||||
lhs = gimple_assign_lhs (stmt);
|
||||
rhs = gimple_assign_rhs1 (stmt);
|
||||
|
||||
if (disqualify_ops_if_throwing_stmt (stmt, lhs, rhs))
|
||||
if (disqualify_if_bad_bb_terminating_stmt (stmt, lhs, rhs))
|
||||
return false;
|
||||
|
||||
racc = build_access_from_expr_1 (rhs, stmt, false);
|
||||
@ -1319,7 +1343,7 @@ scan_function (void)
|
||||
}
|
||||
|
||||
t = gimple_call_lhs (stmt);
|
||||
if (t && !disqualify_ops_if_throwing_stmt (stmt, t, NULL))
|
||||
if (t && !disqualify_if_bad_bb_terminating_stmt (stmt, t, NULL))
|
||||
ret |= build_access_from_expr (t, stmt, true);
|
||||
break;
|
||||
|
||||
@ -2763,6 +2787,13 @@ sra_modify_expr (tree *expr, gimple_stmt_iterator *gsi, bool write)
|
||||
type = TREE_TYPE (*expr);
|
||||
|
||||
loc = gimple_location (gsi_stmt (*gsi));
|
||||
gimple_stmt_iterator alt_gsi = gsi_none ();
|
||||
if (write && stmt_ends_bb_p (gsi_stmt (*gsi)))
|
||||
{
|
||||
alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
|
||||
gsi = &alt_gsi;
|
||||
}
|
||||
|
||||
if (access->grp_to_be_replaced)
|
||||
{
|
||||
tree repl = get_access_replacement (access);
|
||||
@ -3226,14 +3257,23 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
|
||||
if (modify_this_stmt
|
||||
|| gimple_has_volatile_ops (*stmt)
|
||||
|| contains_vce_or_bfcref_p (rhs)
|
||||
|| contains_vce_or_bfcref_p (lhs))
|
||||
|| contains_vce_or_bfcref_p (lhs)
|
||||
|| stmt_ends_bb_p (*stmt))
|
||||
{
|
||||
if (access_has_children_p (racc))
|
||||
generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,
|
||||
gsi, false, false, loc);
|
||||
if (access_has_children_p (lacc))
|
||||
generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
|
||||
gsi, true, true, loc);
|
||||
{
|
||||
gimple_stmt_iterator alt_gsi = gsi_none ();
|
||||
if (stmt_ends_bb_p (*stmt))
|
||||
{
|
||||
alt_gsi = gsi_start_edge (single_non_eh_succ (gsi_bb (*gsi)));
|
||||
gsi = &alt_gsi;
|
||||
}
|
||||
generate_subtree_copies (lacc->first_child, lacc->base, 0, 0, 0,
|
||||
gsi, true, true, loc);
|
||||
}
|
||||
sra_stats.separate_lhs_rhs_handling++;
|
||||
|
||||
/* This gimplification must be done after generate_subtree_copies,
|
||||
@ -3397,6 +3437,7 @@ sra_modify_function_body (void)
|
||||
}
|
||||
}
|
||||
|
||||
gsi_commit_edge_inserts ();
|
||||
return cfg_changed;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user