diff mbox

PR/66760, ipa-inline-analysis.c compile-time hog

Message ID 1436737195-21165-1-git-send-email-bonzini@gnu.org
State New
Headers show

Commit Message

Paolo Bonzini July 12, 2015, 9:39 p.m. UTC
From: bonzini@gnu.org

In this PR, a lot of time is spent doing the same ipa_load_from_parm_agg
query over and over.  Luckily a memoization scheme is already there, it's
just not used by ipa-inline-analysis.c.  The patch moves the cache struct
(struct func_body_info) to ipa-prop.h and modify ipa-inline-analysis.c.
On some testcases from PR26854 the "alias stmt walking" timevar goes
off the profile while it used to be 30-70%.

Bootstrapped (regtest in progress) on x86_64-pc-linux-gnu.

Please commit the patch for me if approved, as I don't have anymore
the key I used to use for gcc.gnu.org.  One of these days I'll send
my new SSH public key to the overseers.

Paolo

* ipa-inline-analysis.c (unmodified_parm_or_parm_agg_item): Accept
struct func_body_info* instead of struct ipa_node_params*, expecting
fbi->info to be filled in.  Replace throughout.  Adjust call to
ipa_load_from_parm_agg.
(set_cond_stmt_execution_predicate): Accept struct func_body_info*
instead of struct ipa_node_params*.  Adjust calls to other functions
so that they pass either fbi or fbi->info.
(set_switch_stmt_execution_predicate): Likewise.
(will_be_nonconstant_predicate): Likewise.
(compute_bb_predicates): Likewise.
(estimate_function_body_sizes): Move asserts earlier.  Fill in
struct func_body_info, replace parms_info with fbi.info.  Adjust
calls to functions that now accept struct func_body_info.
* ipa-prop.c (struct param_aa_status, struct ipa_bb_info,
struct func_body_info).  Move to ipa-prop.h.
(ipa_load_from_parm_agg_1): Rename to ipa_load_from_parm_agg,
remove static.  Adjust callers.
(ipa_load_from_parm_agg): Remove.
* ipa-prop.h (struct param_aa_status, struct ipa_bb_info,
struct func_body_info).  Move from ipa-prop.c.
(ipa_load_from_parm_agg): Adjust prototype.

Comments

Martin Jambor July 13, 2015, 11:55 a.m. UTC | #1
Hi,

On Sun, Jul 12, 2015 at 11:39:55PM +0200, Paolo Bonzini wrote:
> From: bonzini@gnu.org
> 
> In this PR, a lot of time is spent doing the same ipa_load_from_parm_agg
> query over and over.  Luckily a memoization scheme is already there, it's
> just not used by ipa-inline-analysis.c.  The patch moves the cache struct
> (struct func_body_info) to ipa-prop.h and modify ipa-inline-analysis.c.
> On some testcases from PR26854 the "alias stmt walking" timevar goes
> off the profile while it used to be 30-70%.
> 
> Bootstrapped (regtest in progress) on x86_64-pc-linux-gnu.
> 
> Please commit the patch for me if approved, as I don't have anymore
> the key I used to use for gcc.gnu.org.  One of these days I'll send
> my new SSH public key to the overseers.

I can't approve it, but FWIW, I'm generally fine with the patch.
Although the original idea was to share one func_body_info in between
ipa-cp and ipa-inline analyses, this is certainly better than what we
have now and perhaps even good enough generally.

The only semi-issue I have is the name of func_body_info.  If it is
going to be exposed in a header file, perhaps it should get an ipa_
prefix.  I also think that its initialization should be put into a
common function, but that is somethig I can do as a followup, if need
be.

In any event, thanks for working on this,

Martin
Paolo Bonzini July 13, 2015, 12:13 p.m. UTC | #2
On 13/07/2015 13:55, Martin Jambor wrote:
> I can't approve it, but FWIW, I'm generally fine with the patch.
> Although the original idea was to share one func_body_info in between
> ipa-cp and ipa-inline analyses, this is certainly better than what we
> have now and perhaps even good enough generally.

Ah, so you'd add a pointer to cgraph_node?  I only have a question
then---does cgraph_node have a "destructor" where I can free the
func_body_info?  Or is there no such thing?

> The only semi-issue I have is the name of func_body_info.  If it is
> going to be exposed in a header file, perhaps it should get an ipa_
> prefix.

That's a patch as large as this one.  I can do the rename later, and
maybe have it preapproved to convince me to get the new public key in
place. :)

> I also think that its initialization should be put into a
> common function, but that is somethig I can do as a followup, if need
> be.

Tried doing that now...  it seems better to do it together with adding a
func_body_info* to cgraph_node*, so that the initialization is done
lazily in cgraph_node::get_func_body_info.

Paolo
Martin Jambor July 13, 2015, 12:34 p.m. UTC | #3
Hi,

On Mon, Jul 13, 2015 at 02:13:59PM +0200, Paolo Bonzini wrote:
> 
> 
> On 13/07/2015 13:55, Martin Jambor wrote:
> > I can't approve it, but FWIW, I'm generally fine with the patch.
> > Although the original idea was to share one func_body_info in between
> > ipa-cp and ipa-inline analyses, this is certainly better than what we
> > have now and perhaps even good enough generally.
> 
> Ah, so you'd add a pointer to cgraph_node?

No, that does not seem right, given that this data is only needed
during very limited time.  You might want to use Martin's shiny new
function_summary class in symbol-summary.c.  That is a mechanism
specifically designed to append to a cgraph_node information specific
to an optimization pass (or two, as ipa-cp and ipa-inline already both
use a few of them).  Unfortunately, the class is not very well
documented but you should be able to figure out how to use it from
other code using them.

If you then always deallocate everything there at the end of
ipa-inline analysis, you'll get exactly the right life-time for the
data.

> I only have a question
> then---does cgraph_node have a "destructor" where I can free the
> func_body_info?  Or is there no such thing?

No, not really, but a summary would give you that.

> 
> > The only semi-issue I have is the name of func_body_info.  If it is
> > going to be exposed in a header file, perhaps it should get an ipa_
> > prefix.
> 
> That's a patch as large as this one.  I can do the rename later, and
> maybe have it preapproved to convince me to get the new public key in
> place. :)

Yeah, I think that is good enough (but remember I can't approve or
preapprove anything).

> 
> > I also think that its initialization should be put into a
> > common function, but that is somethig I can do as a followup, if need
> > be.
> 
> Tried doing that now...  it seems better to do it together with adding a
> func_body_info* to cgraph_node*, so that the initialization is done
> lazily in cgraph_node::get_func_body_info.
> 

Well, see above, we're actually trying to  pull information like this
out of cgraph_node.

Martin
Paolo Bonzini July 13, 2015, 12:47 p.m. UTC | #4
On 13/07/2015 14:34, Martin Jambor wrote:
> You might want to use Martin's shiny new
> function_summary class in symbol-summary.c.  That is a mechanism
> specifically designed to append to a cgraph_node information specific
> to an optimization pass (or two, as ipa-cp and ipa-inline already both
> use a few of them).  Unfortunately, the class is not very well
> documented but you should be able to figure out how to use it from
> other code using them.
> 
> If you then always deallocate everything there at the end of
> ipa-inline analysis, you'll get exactly the right life-time for the
> data.

Good.  I might as well merge func_body_info and ipa_node_params then, so
I already have ipa_node_params_sum.  WDYT?

Paolo
Martin Jambor July 13, 2015, 1:30 p.m. UTC | #5
On Mon, Jul 13, 2015 at 02:47:23PM +0200, Paolo Bonzini wrote:
> 
> 
> On 13/07/2015 14:34, Martin Jambor wrote:
> > You might want to use Martin's shiny new
> > function_summary class in symbol-summary.c.  That is a mechanism
> > specifically designed to append to a cgraph_node information specific
> > to an optimization pass (or two, as ipa-cp and ipa-inline already both
> > use a few of them).  Unfortunately, the class is not very well
> > documented but you should be able to figure out how to use it from
> > other code using them.
> > 
> > If you then always deallocate everything there at the end of
> > ipa-inline analysis, you'll get exactly the right life-time for the
> > data.
> 
> Good.  I might as well merge func_body_info and ipa_node_params then, so
> I already have ipa_node_params_sum.  WDYT?

Well, perhaps but I am not so sure.  I have made a conscious decision
to make func_body_info a separate structure and not a part of
ipa_node_params exactly because of their different life-times.

func_body_info is something only used during intra-procedural stage of
IPA analysis and should be thrown away as soon as it is over.

ipa_node_params is a structure which contains results of that
analysis, which are streamed to disk during LTO and then read back for
the actual intEr-procedural propagation of information.  Yes, it also
contains quite a few fields that are used only during the IPA stage
and so perhaps a few more bits used only during the intra-stage might
be OK too.  But Honza recently told me the ipa-structures are
beginning to show in memory footprint of LTOing Firefox, so allocating
more unused memory for each and every function in Firefox and all its
clones is not really such a good idea.

I also tend to think that coding the deallocation is going to be
easier for you if you just use another summary.  For an
analysis-stage-only summary, you do not need to implement any of the
hooks (i.e. insert, remove, duplicate), for example.  Those should
never happen during intraprocedural phase, or so I believe :-), so
just put gcc_unreachable into them and that should be it.

I'm sorry for making this so complicated :-)

Martin
Richard Biener July 13, 2015, 1:45 p.m. UTC | #6
On Mon, Jul 13, 2015 at 3:30 PM, Martin Jambor <mjambor@suse.cz> wrote:
> On Mon, Jul 13, 2015 at 02:47:23PM +0200, Paolo Bonzini wrote:
>>
>>
>> On 13/07/2015 14:34, Martin Jambor wrote:
>> > You might want to use Martin's shiny new
>> > function_summary class in symbol-summary.c.  That is a mechanism
>> > specifically designed to append to a cgraph_node information specific
>> > to an optimization pass (or two, as ipa-cp and ipa-inline already both
>> > use a few of them).  Unfortunately, the class is not very well
>> > documented but you should be able to figure out how to use it from
>> > other code using them.
>> >
>> > If you then always deallocate everything there at the end of
>> > ipa-inline analysis, you'll get exactly the right life-time for the
>> > data.
>>
>> Good.  I might as well merge func_body_info and ipa_node_params then, so
>> I already have ipa_node_params_sum.  WDYT?
>
> Well, perhaps but I am not so sure.  I have made a conscious decision
> to make func_body_info a separate structure and not a part of
> ipa_node_params exactly because of their different life-times.
>
> func_body_info is something only used during intra-procedural stage of
> IPA analysis and should be thrown away as soon as it is over.
>
> ipa_node_params is a structure which contains results of that
> analysis, which are streamed to disk during LTO and then read back for
> the actual intEr-procedural propagation of information.  Yes, it also
> contains quite a few fields that are used only during the IPA stage
> and so perhaps a few more bits used only during the intra-stage might
> be OK too.  But Honza recently told me the ipa-structures are
> beginning to show in memory footprint of LTOing Firefox, so allocating
> more unused memory for each and every function in Firefox and all its
> clones is not really such a good idea.
>
> I also tend to think that coding the deallocation is going to be
> easier for you if you just use another summary.  For an
> analysis-stage-only summary, you do not need to implement any of the
> hooks (i.e. insert, remove, duplicate), for example.  Those should
> never happen during intraprocedural phase, or so I believe :-), so
> just put gcc_unreachable into them and that should be it.
>
> I'm sorry for making this so complicated :-)

It would be nice to have a patch that can be backported to the GCC 5 branch
as well.  We can improve this on trunk as followup,no?

Richard.

> Martin
Paolo Bonzini July 13, 2015, 1:46 p.m. UTC | #7
On 13/07/2015 15:45, Richard Biener wrote:
> It would be nice to have a patch that can be backported to the GCC 5 branch
> as well.  We can improve this on trunk as followup,no?

The patch I've already posted can be backported. O:-)

Paolo
Richard Biener July 13, 2015, 1:49 p.m. UTC | #8
On Mon, Jul 13, 2015 at 3:46 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 13/07/2015 15:45, Richard Biener wrote:
>> It would be nice to have a patch that can be backported to the GCC 5 branch
>> as well.  We can improve this on trunk as followup,no?
>
> The patch I've already posted can be backported. O:-)

So unless Martin objects consider the patch approved for trunk and for
backporting
after 5.2 is released and trunk shows no issues.

Martin - can you take care of committing if you are fine with it?

Thanks,
Richard.

> Paolo
Martin Jambor July 14, 2015, 9:43 a.m. UTC | #9
Hi,

On Mon, Jul 13, 2015 at 03:49:05PM +0200, Richard Biener wrote:
> On Mon, Jul 13, 2015 at 3:46 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
> >
> >
> > On 13/07/2015 15:45, Richard Biener wrote:
> >> It would be nice to have a patch that can be backported to the GCC 5 branch
> >> as well.  We can improve this on trunk as followup,no?
> >
> > The patch I've already posted can be backported. O:-)
> 
> So unless Martin objects consider the patch approved for trunk and for
> backporting
> after 5.2 is released and trunk shows no issues.
> 
> Martin - can you take care of committing if you are fine with it?

I will.  I will also do the renaming from func_body_info to
ipa_func_body_info as a followup.

Martin

> 
> Thanks,
> Richard.
> 
> > Paolo
diff mbox

Patch

diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index d5dbfbd..81a6860 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -1574,7 +1574,7 @@  unmodified_parm (gimple stmt, tree op)
    loaded.  */
 
 static bool
-unmodified_parm_or_parm_agg_item (struct ipa_node_params *info,
+unmodified_parm_or_parm_agg_item (struct func_body_info *fbi,
 				  gimple stmt, tree op, int *index_p,
 				  struct agg_position_info *aggpos)
 {
@@ -1583,7 +1583,7 @@  unmodified_parm_or_parm_agg_item (struct ipa_node_params *info,
   gcc_checking_assert (aggpos);
   if (res)
     {
-      *index_p = ipa_get_param_decl_index (info, res);
+      *index_p = ipa_get_param_decl_index (fbi->info, res);
       if (*index_p < 0)
 	return false;
       aggpos->agg_contents = false;
@@ -1599,13 +1599,14 @@  unmodified_parm_or_parm_agg_item (struct ipa_node_params *info,
       stmt = SSA_NAME_DEF_STMT (op);
       op = gimple_assign_rhs1 (stmt);
       if (!REFERENCE_CLASS_P (op))
-	return unmodified_parm_or_parm_agg_item (info, stmt, op, index_p,
+	return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p,
 						 aggpos);
     }
 
   aggpos->agg_contents = true;
-  return ipa_load_from_parm_agg (info, stmt, op, index_p, &aggpos->offset,
-				 &aggpos->by_ref);
+  return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
+				 stmt, op, index_p, &aggpos->offset,
+				 NULL, &aggpos->by_ref);
 }
 
 /* See if statement might disappear after inlining.
@@ -1744,7 +1745,7 @@  eliminated_by_inlining_prob (gimple stmt)
    predicates to the CFG edges.   */
 
 static void
-set_cond_stmt_execution_predicate (struct ipa_node_params *info,
+set_cond_stmt_execution_predicate (struct func_body_info *fbi,
 				   struct inline_summary *summary,
 				   basic_block bb)
 {
@@ -1767,7 +1768,7 @@  set_cond_stmt_execution_predicate (struct ipa_node_params *info,
   /* TODO: handle conditionals like
      var = op0 < 4;
      if (var != 0).  */
-  if (unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos))
+  if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos))
     {
       code = gimple_cond_code (last);
       inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
@@ -1810,8 +1811,7 @@  set_cond_stmt_execution_predicate (struct ipa_node_params *info,
       || gimple_call_num_args (set_stmt) != 1)
     return;
   op2 = gimple_call_arg (set_stmt, 0);
-  if (!unmodified_parm_or_parm_agg_item
-      (info, set_stmt, op2, &index, &aggpos))
+  if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &aggpos))
     return;
   FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
     {
@@ -1827,7 +1827,7 @@  set_cond_stmt_execution_predicate (struct ipa_node_params *info,
    predicates to the CFG edges.   */
 
 static void
-set_switch_stmt_execution_predicate (struct ipa_node_params *info,
+set_switch_stmt_execution_predicate (struct func_body_info *fbi,
 				     struct inline_summary *summary,
 				     basic_block bb)
 {
@@ -1845,7 +1845,7 @@  set_switch_stmt_execution_predicate (struct ipa_node_params *info,
     return;
   gswitch *last = as_a <gswitch *> (lastg);
   op = gimple_switch_index (last);
-  if (!unmodified_parm_or_parm_agg_item (info, last, op, &index, &aggpos))
+  if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos))
     return;
 
   FOR_EACH_EDGE (e, ei, bb->succs)
@@ -1888,8 +1888,8 @@  set_switch_stmt_execution_predicate (struct ipa_node_params *info,
    which it is executable.  */
 
 static void
-compute_bb_predicates (struct cgraph_node *node,
-		       struct ipa_node_params *parms_info,
+compute_bb_predicates (struct func_body_info *fbi,
+		       struct cgraph_node *node,
 		       struct inline_summary *summary)
 {
   struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
@@ -1898,8 +1898,8 @@  compute_bb_predicates (struct cgraph_node *node,
 
   FOR_EACH_BB_FN (bb, my_function)
     {
-      set_cond_stmt_execution_predicate (parms_info, summary, bb);
-      set_switch_stmt_execution_predicate (parms_info, summary, bb);
+      set_cond_stmt_execution_predicate (fbi, summary, bb);
+      set_switch_stmt_execution_predicate (fbi, summary, bb);
     }
 
   /* Entry block is always executable.  */
@@ -2031,7 +2031,7 @@  will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
    a compile time constant.  */
 
 static struct predicate
-will_be_nonconstant_predicate (struct ipa_node_params *info,
+will_be_nonconstant_predicate (struct func_body_info *fbi,
 			       struct inline_summary *summary,
 			       gimple stmt,
 			       vec<predicate_t> nonconstant_names)
@@ -2065,7 +2065,7 @@  will_be_nonconstant_predicate (struct ipa_node_params *info,
       tree op;
       gcc_assert (gimple_assign_single_p (stmt));
       op = gimple_assign_rhs1 (stmt);
-      if (!unmodified_parm_or_parm_agg_item (info, stmt, op, &base_index,
+      if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index,
 					     &aggpos))
 	return p;
     }
@@ -2078,7 +2078,7 @@  will_be_nonconstant_predicate (struct ipa_node_params *info,
     {
       tree parm = unmodified_parm (stmt, use);
       /* For arguments we can build a condition.  */
-      if (parm && ipa_get_param_decl_index (info, parm) >= 0)
+      if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
 	continue;
       if (TREE_CODE (use) != SSA_NAME)
 	return p;
@@ -2099,7 +2099,7 @@  will_be_nonconstant_predicate (struct ipa_node_params *info,
       tree parm = unmodified_parm (stmt, use);
       int index;
 
-      if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0)
+      if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
 	{
 	  if (index != base_index)
 	    p = add_condition (summary, index, NULL, CHANGED, NULL_TREE);
@@ -2481,13 +2481,17 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
   int freq;
   struct inline_summary *info = inline_summaries->get (node);
   struct predicate bb_predicate;
-  struct ipa_node_params *parms_info = NULL;
+  struct func_body_info fbi;
   vec<predicate_t> nonconstant_names = vNULL;
   int nblocks, n;
   int *order;
   predicate array_index = true_predicate ();
   gimple fix_builtin_expect_stmt;
 
+  gcc_assert (my_function && my_function->cfg);
+  gcc_assert (cfun == my_function);
+
+  memset(&fbi, 0, sizeof(fbi));
   info->conds = NULL;
   info->entry = NULL;
 
@@ -2510,7 +2514,11 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
 
       if (ipa_node_params_sum)
 	{
-	  parms_info = IPA_NODE_REF (node);
+	  fbi.node = node;
+	  fbi.info = IPA_NODE_REF (node);
+	  fbi.bb_infos = vNULL;
+	  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
+	  fbi.param_count = count_formal_params(node->decl);
 	  nonconstant_names.safe_grow_cleared
 	    (SSANAMES (my_function)->length ());
 	}
@@ -2528,10 +2536,8 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
   bb_predicate = not_inlined_predicate ();
   account_size_time (info, 2 * INLINE_SIZE_SCALE, 0, &bb_predicate);
 
-  gcc_assert (my_function && my_function->cfg);
-  if (parms_info)
-    compute_bb_predicates (node, parms_info, info);
-  gcc_assert (cfun == my_function);
+  if (fbi.info)
+    compute_bb_predicates (&fbi, node, info);
   order = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
   nblocks = pre_and_rev_post_order_compute (NULL, order, false);
   for (n = 0; n < nblocks; n++)
@@ -2548,7 +2554,7 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	}
 
       /* TODO: Obviously predicates can be propagated down across CFG.  */
-      if (parms_info)
+      if (fbi.info)
 	{
 	  if (bb->aux)
 	    bb_predicate = *(struct predicate *) bb->aux;
@@ -2564,7 +2570,7 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	  dump_predicate (dump_file, info->conds, &bb_predicate);
 	}
 
-      if (parms_info && nonconstant_names.exists ())
+      if (fbi.info && nonconstant_names.exists ())
 	{
 	  struct predicate phi_predicate;
 	  bool first_phi = true;
@@ -2573,7 +2579,7 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	       gsi_next (&bsi))
 	    {
 	      if (first_phi
-		  && !phi_result_unknown_predicate (parms_info, info, bb,
+		  && !phi_result_unknown_predicate (fbi.info, info, bb,
 						    &phi_predicate,
 						    nonconstant_names))
 		break;
@@ -2682,9 +2688,9 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	  /* TODO: When conditional jump or swithc is known to be constant, but
 	     we did not translate it into the predicates, we really can account
 	     just maximum of the possible paths.  */
-	  if (parms_info)
+	  if (fbi.info)
 	    will_be_nonconstant
-	      = will_be_nonconstant_predicate (parms_info, info,
+	      = will_be_nonconstant_predicate (&fbi, info,
 					       stmt, nonconstant_names);
 	  if (this_time || this_size)
 	    {
@@ -2699,7 +2705,7 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
 	      if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS))
 		fprintf (dump_file, "\t\tWill be eliminated by inlining\n");
 
-	      if (parms_info)
+	      if (fbi.info)
 		p = and_predicates (info->conds, &bb_predicate,
 				    &will_be_nonconstant);
 	      else
@@ -2767,7 +2773,7 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
 		&& !is_gimple_min_invariant (niter_desc.niter))
 	    {
 	      predicate will_be_nonconstant
-		= will_be_nonconstant_expr_predicate (parms_info, info,
+		= will_be_nonconstant_expr_predicate (fbi.info, info,
 						      niter_desc.niter,
 						      nonconstant_names);
 	      if (!true_predicate_p (&will_be_nonconstant))
@@ -2805,7 +2811,7 @@  estimate_function_body_sizes (struct cgraph_node *node, bool early)
 			|| is_gimple_min_invariant (iv.step))
 		      continue;
 		    will_be_nonconstant
-		      = will_be_nonconstant_expr_predicate (parms_info, info,
+		      = will_be_nonconstant_expr_predicate (fbi.info, info,
 							    iv.step,
 							    nonconstant_names);
 		    if (!true_predicate_p (&will_be_nonconstant))
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 6074194..2ba45e2 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -70,57 +70,6 @@  along with GCC; see the file COPYING3.  If not see
 #include "domwalk.h"
 #include "builtins.h"
 
-/* Intermediate information that we get from alias analysis about a particular
-   parameter in a particular basic_block.  When a parameter or the memory it
-   references is marked modified, we use that information in all dominatd
-   blocks without cosulting alias analysis oracle.  */
-
-struct param_aa_status
-{
-  /* Set when this structure contains meaningful information.  If not, the
-     structure describing a dominating BB should be used instead.  */
-  bool valid;
-
-  /* Whether we have seen something which might have modified the data in
-     question.  PARM is for the parameter itself, REF is for data it points to
-     but using the alias type of individual accesses and PT is the same thing
-     but for computing aggregate pass-through functions using a very inclusive
-     ao_ref.  */
-  bool parm_modified, ref_modified, pt_modified;
-};
-
-/* Information related to a given BB that used only when looking at function
-   body.  */
-
-struct ipa_bb_info
-{
-  /* Call graph edges going out of this BB.  */
-  vec<cgraph_edge *> cg_edges;
-  /* Alias analysis statuses of each formal parameter at this bb.  */
-  vec<param_aa_status> param_aa_statuses;
-};
-
-/* Structure with global information that is only used when looking at function
-   body. */
-
-struct func_body_info
-{
-  /* The node that is being analyzed.  */
-  cgraph_node *node;
-
-  /* Its info.  */
-  struct ipa_node_params *info;
-
-  /* Information about individual BBs. */
-  vec<ipa_bb_info> bb_infos;
-
-  /* Number of parameters.  */
-  int param_count;
-
-  /* Number of statements already walked by when analyzing this function.  */
-  unsigned int aa_walked;
-};
-
 /* Function summary where the parameter infos are actually stored. */
 ipa_node_params_t *ipa_node_params_sum = NULL;
 /* Vector of IPA-CP transformation data for each clone.  */
@@ -1010,12 +959,12 @@  parm_ref_data_pass_through_p (struct func_body_info *fbi, int index,
    within the aggregate and whether it is a load from a value passed by
    reference respectively.  */
 
-static bool
-ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
-			  vec<ipa_param_descriptor> descriptors,
-			  gimple stmt, tree op, int *index_p,
-			  HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
-			  bool *by_ref_p)
+bool
+ipa_load_from_parm_agg (struct func_body_info *fbi,
+			vec<ipa_param_descriptor> descriptors,
+			gimple stmt, tree op, int *index_p,
+			HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
+			bool *by_ref_p)
 {
   int index;
   HOST_WIDE_INT size, max_size;
@@ -1082,18 +1031,6 @@  ipa_load_from_parm_agg_1 (struct func_body_info *fbi,
   return false;
 }
 
-/* Just like the previous function, just without the param_analysis_info
-   pointer, for users outside of this file.  */
-
-bool
-ipa_load_from_parm_agg (struct ipa_node_params *info, gimple stmt,
-			tree op, int *index_p, HOST_WIDE_INT *offset_p,
-			bool *by_ref_p)
-{
-  return ipa_load_from_parm_agg_1 (NULL, info->descriptors, stmt, op, index_p,
-				   offset_p, NULL, by_ref_p);
-}
-
 /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
    of an assignment statement STMT, try to determine whether we are actually
    handling any of the following cases and construct an appropriate jump
@@ -1977,9 +1914,9 @@  ipa_analyze_indirect_call_uses (struct func_body_info *fbi, gcall *call,
   int index;
   gimple def = SSA_NAME_DEF_STMT (target);
   if (gimple_assign_single_p (def)
-      && ipa_load_from_parm_agg_1 (fbi, info->descriptors, def,
-				   gimple_assign_rhs1 (def), &index, &offset,
-				   NULL, &by_ref))
+      && ipa_load_from_parm_agg (fbi, info->descriptors, def,
+				 gimple_assign_rhs1 (def), &index, &offset,
+				 NULL, &by_ref))
     {
       struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
       cs->indirect_info->offset = offset;
@@ -5192,8 +5129,8 @@  ipcp_modif_dom_walker::before_dom_children (basic_block bb)
       if (vce)
 	continue;
 
-      if (!ipa_load_from_parm_agg_1 (m_fbi, m_descriptors, stmt, rhs, &index,
-				     &offset, &size, &by_ref))
+      if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
+				   &offset, &size, &by_ref))
 	continue;
       for (v = m_aggval; v; v = v->next)
 	if (v->index == index
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index e6725aa..af41ef1 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -336,6 +336,57 @@  struct ipa_node_params
   unsigned node_calling_single_call : 1;
 };
 
+/* Intermediate information that we get from alias analysis about a particular
+   parameter in a particular basic_block.  When a parameter or the memory it
+   references is marked modified, we use that information in all dominatd
+   blocks without cosulting alias analysis oracle.  */
+
+struct param_aa_status
+{
+  /* Set when this structure contains meaningful information.  If not, the
+     structure describing a dominating BB should be used instead.  */
+  bool valid;
+
+  /* Whether we have seen something which might have modified the data in
+     question.  PARM is for the parameter itself, REF is for data it points to
+     but using the alias type of individual accesses and PT is the same thing
+     but for computing aggregate pass-through functions using a very inclusive
+     ao_ref.  */
+  bool parm_modified, ref_modified, pt_modified;
+};
+
+/* Information related to a given BB that used only when looking at function
+   body.  */
+
+struct ipa_bb_info
+{
+  /* Call graph edges going out of this BB.  */
+  vec<cgraph_edge *> cg_edges;
+  /* Alias analysis statuses of each formal parameter at this bb.  */
+  vec<param_aa_status> param_aa_statuses;
+};
+
+/* Structure with global information that is only used when looking at function
+   body. */
+
+struct func_body_info
+{
+  /* The node that is being analyzed.  */
+  cgraph_node *node;
+
+  /* Its info.  */
+  struct ipa_node_params *info;
+
+  /* Information about individual BBs. */
+  vec<ipa_bb_info> bb_infos;
+
+  /* Number of parameters.  */
+  int param_count;
+
+  /* Number of statements already walked by when analyzing this function.  */
+  unsigned int aa_walked;
+};
+
 /* ipa_node_params access functions.  Please use these to access fields that
    are or will be shared among various passes.  */
 
@@ -585,8 +636,9 @@  void ipa_analyze_node (struct cgraph_node *);
 /* Aggregate jump function related functions.  */
 tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
 				 bool);
-bool ipa_load_from_parm_agg (struct ipa_node_params *, gimple, tree, int *,
-			     HOST_WIDE_INT *, bool *);
+bool ipa_load_from_parm_agg (struct func_body_info *,
+			     vec<ipa_param_descriptor>, gimple, tree, int *,
+			     HOST_WIDE_INT *, HOST_WIDE_INT *, bool *);
 
 /* Debugging interface.  */
 void ipa_print_node_params (FILE *, struct cgraph_node *node);