Commit 104cb50b by Martin Jambor Committed by Martin Jambor

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
parent b94970bc
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
......
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,
......
-- { 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" } }
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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment