Commit 8810cc52 by Martin Jambor Committed by Martin Jambor

re PR fortran/48636 (Enable more inlining with -O2 and higher)

2012-08-11  Martin Jambor  <mjambor@suse.cz>

	PR fortran/48636
	* ipa-inline.h (condition): New fields offset, agg_contents and by_ref.
	* ipa-inline-analysis.c (agg_position_info): New type.
	(add_condition): New parameter aggpos, also store agg_contents, by_ref
	and offset.
	(dump_condition): Also dump aggregate conditions.
	(evaluate_conditions_for_known_args): Also handle aggregate
	conditions.  New parameter known_aggs.
	(evaluate_properties_for_edge): Gather known aggregate contents.
	(inline_node_duplication_hook): Pass NULL known_aggs to
	evaluate_conditions_for_known_args.
	(unmodified_parm): Split into unmodified_parm and unmodified_parm_1.
	(unmodified_parm_or_parm_agg_item): New function.
	(set_cond_stmt_execution_predicate): Handle values passed in
	aggregates.
	(set_switch_stmt_execution_predicate): Likewise.
	(will_be_nonconstant_predicate): Likewise.
	(estimate_edge_devirt_benefit): Pass new parameter known_aggs to
	ipa_get_indirect_edge_target.
	(estimate_calls_size_and_time): New parameter known_aggs, pass it
	recrsively to itself and to estimate_edge_devirt_benefit.
	(estimate_node_size_and_time): New vector known_aggs, pass it o
	functions which need it.
	(remap_predicate): New parameter offset_map, use it to remap aggregate
	conditions.
	(remap_edge_summaries): New parameter offset_map, pass it recursively
	to itself and to remap_predicate.
	(inline_merge_summary): Also create and populate vector offset_map.
	(do_estimate_edge_time): New vector of known aggregate contents,
	passed to functions which need it.
	(inline_read_section): Stream new fields of condition.
	(inline_write_summary): Likewise.
	* ipa-cp.c (ipa_get_indirect_edge_target): Also examine the aggregate
	contents.  Let all local callers pass NULL for known_aggs.

	* testsuite/gfortran.dg/pr48636.f90: New test.

From-SVN: r190313
parent ab96cc5b
2012-08-11 Martin Jambor <mjambor@suse.cz>
PR fortran/48636
* ipa-inline.h (condition): New fields offset, agg_contents and by_ref.
* ipa-inline-analysis.c (agg_position_info): New type.
(add_condition): New parameter aggpos, also store agg_contents, by_ref
and offset.
(dump_condition): Also dump aggregate conditions.
(evaluate_conditions_for_known_args): Also handle aggregate
conditions. New parameter known_aggs.
(evaluate_properties_for_edge): Gather known aggregate contents.
(inline_node_duplication_hook): Pass NULL known_aggs to
evaluate_conditions_for_known_args.
(unmodified_parm): Split into unmodified_parm and unmodified_parm_1.
(unmodified_parm_or_parm_agg_item): New function.
(set_cond_stmt_execution_predicate): Handle values passed in
aggregates.
(set_switch_stmt_execution_predicate): Likewise.
(will_be_nonconstant_predicate): Likewise.
(estimate_edge_devirt_benefit): Pass new parameter known_aggs to
ipa_get_indirect_edge_target.
(estimate_calls_size_and_time): New parameter known_aggs, pass it
recrsively to itself and to estimate_edge_devirt_benefit.
(estimate_node_size_and_time): New vector known_aggs, pass it o
functions which need it.
(remap_predicate): New parameter offset_map, use it to remap aggregate
conditions.
(remap_edge_summaries): New parameter offset_map, pass it recursively
to itself and to remap_predicate.
(inline_merge_summary): Also create and populate vector offset_map.
(do_estimate_edge_time): New vector of known aggregate contents,
passed to functions which need it.
(inline_read_section): Stream new fields of condition.
(inline_write_summary): Likewise.
* ipa-cp.c (ipa_get_indirect_edge_target): Also examine the aggregate
contents. Let all local callers pass NULL for known_aggs.
2012-08-11 Jan Hubicka <jh@suse.cz> 2012-08-11 Jan Hubicka <jh@suse.cz>
* lto-cgraph.c (output_cgraph): Rename to ... * lto-cgraph.c (output_cgraph): Rename to ...
......
...@@ -1084,7 +1084,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs) ...@@ -1084,7 +1084,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
tree tree
ipa_get_indirect_edge_target (struct cgraph_edge *ie, ipa_get_indirect_edge_target (struct cgraph_edge *ie,
VEC (tree, heap) *known_vals, VEC (tree, heap) *known_vals,
VEC (tree, heap) *known_binfos) VEC (tree, heap) *known_binfos,
VEC (ipa_agg_jump_function_p, heap) *known_aggs)
{ {
int param_index = ie->indirect_info->param_index; int param_index = ie->indirect_info->param_index;
HOST_WIDE_INT token, anc_offset; HOST_WIDE_INT token, anc_offset;
...@@ -1096,8 +1097,26 @@ ipa_get_indirect_edge_target (struct cgraph_edge *ie, ...@@ -1096,8 +1097,26 @@ ipa_get_indirect_edge_target (struct cgraph_edge *ie,
if (!ie->indirect_info->polymorphic) if (!ie->indirect_info->polymorphic)
{ {
tree t = (VEC_length (tree, known_vals) > (unsigned int) param_index tree t;
? VEC_index (tree, known_vals, param_index) : NULL);
if (ie->indirect_info->agg_contents)
{
if (VEC_length (ipa_agg_jump_function_p, known_aggs)
> (unsigned int) param_index)
{
struct ipa_agg_jump_function *agg;
agg = VEC_index (ipa_agg_jump_function_p, known_aggs,
param_index);
t = ipa_find_agg_cst_for_param (agg, ie->indirect_info->offset,
ie->indirect_info->by_ref);
}
else
t = NULL;
}
else
t = (VEC_length (tree, known_vals) > (unsigned int) param_index
? VEC_index (tree, known_vals, param_index) : NULL);
if (t && if (t &&
TREE_CODE (t) == ADDR_EXPR TREE_CODE (t) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL) && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
...@@ -1106,6 +1125,7 @@ ipa_get_indirect_edge_target (struct cgraph_edge *ie, ...@@ -1106,6 +1125,7 @@ ipa_get_indirect_edge_target (struct cgraph_edge *ie,
return NULL_TREE; return NULL_TREE;
} }
gcc_assert (!ie->indirect_info->agg_contents);
token = ie->indirect_info->otr_token; token = ie->indirect_info->otr_token;
anc_offset = ie->indirect_info->offset; anc_offset = ie->indirect_info->offset;
otr_type = ie->indirect_info->otr_type; otr_type = ie->indirect_info->otr_type;
...@@ -1156,7 +1176,8 @@ devirtualization_time_bonus (struct cgraph_node *node, ...@@ -1156,7 +1176,8 @@ devirtualization_time_bonus (struct cgraph_node *node,
struct inline_summary *isummary; struct inline_summary *isummary;
tree target; tree target;
target = ipa_get_indirect_edge_target (ie, known_csts, known_binfos); target = ipa_get_indirect_edge_target (ie, known_csts, known_binfos,
NULL);
if (!target) if (!target)
continue; continue;
...@@ -1673,7 +1694,7 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node, ...@@ -1673,7 +1694,7 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node,
tree target; tree target;
next_ie = ie->next_callee; next_ie = ie->next_callee;
target = ipa_get_indirect_edge_target (ie, known_vals, NULL); target = ipa_get_indirect_edge_target (ie, known_vals, NULL, NULL);
if (target) if (target)
ipa_make_edge_direct_to_target (ie, target); ipa_make_edge_direct_to_target (ie, target);
} }
......
...@@ -28,9 +28,18 @@ along with GCC; see the file COPYING3. If not see ...@@ -28,9 +28,18 @@ along with GCC; see the file COPYING3. If not see
typedef struct GTY(()) condition typedef struct GTY(()) condition
{ {
/* If agg_contents is set, this is the offset from which the used data was
loaded. */
HOST_WIDE_INT offset;
tree val; tree val;
int operand_num; int operand_num;
enum tree_code code; ENUM_BITFIELD(tree_code) code : 16;
/* Set if the used data were loaded from an aggregate parameter or from
data received by reference. */
unsigned agg_contents : 1;
/* If agg_contents is set, this differentiates between loads from data
passed by reference and by value. */
unsigned by_ref : 1;
} condition; } condition;
DEF_VEC_O (condition); DEF_VEC_O (condition);
......
...@@ -494,8 +494,9 @@ bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, ...@@ -494,8 +494,9 @@ bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
/* Indirect edge and binfo processing. */ /* Indirect edge and binfo processing. */
tree ipa_get_indirect_edge_target (struct cgraph_edge *ie, tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
VEC (tree, heap) *known_csts, VEC (tree, heap) *,
VEC (tree, heap) *known_binfs); VEC (tree, heap) *,
VEC (ipa_agg_jump_function_p, heap) *);
struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree); struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree);
/* Functions related to both. */ /* Functions related to both. */
......
2012-08-11 Martin Jambor <mjambor@suse.cz>
PR fortran/48636
* gfortran.dg/pr48636.f90: New test.
2012-08-10 Jakub Jelinek <jakub@redhat.com> 2012-08-10 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/torture/vector-shuffle1.c (f): Pass vectors indirectly * gcc.dg/torture/vector-shuffle1.c (f): Pass vectors indirectly
......
! { dg-do compile }
! { dg-options "-O3 -fdump-ipa-inline" }
module foo
implicit none
contains
subroutine bar(a,x)
real, dimension(:,:), intent(in) :: a
real, intent(out) :: x
integer :: i,j
x = 0
do j=1,ubound(a,2)
do i=1,ubound(a,1)
x = x + a(i,j)**2
end do
end do
end subroutine bar
end module foo
program main
use foo
implicit none
real, dimension(2,3) :: a
real :: x
integer :: i
data a /1.0, 2.0, 3.0, -1.0, -2.0, -3.0/
do i=1,2000000
call bar(a,x)
end do
print *,x
end program main
! { dg-final { scan-ipa-dump "bar\[^\\n\]*inline copy in MAIN" "inline" } }
! { dg-final { cleanup-ipa-dump "inline" } }
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