Internal callback edges cause some trouble during ipa-fnsummary summary
generation.

First one is that fnsummary only looks at regular (i.e. not internal) calls
and tries to fetch their callgraph edges.  Because internal callback
edges will be created as a part of ipa-prop, the edge might not always
exist.  We can anticipate this situation and guard it with an assert to
make sure it only happens for internal IFN_ASSUME calls.

The second one is the summary itself.  The existing callback edge logic
assumes the existence of a callback-carrying edge, which the internal
callback edges lack.  In order to have the correct size and time (both
being 0) filled, we need to special case this situation as well.

gcc/ChangeLog:

        * ipa-fnsummary.cc (analyze_function_body): Adjust summary
        generation for internal callback edges.

Signed-off-by: Josef Melcr <[email protected]>
---
 gcc/ipa-fnsummary.cc | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index b8571c5b718..423b1c4fdf8 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -90,6 +90,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "symtab-clones.h"
 #include "gimple-range.h"
 #include "tree-dfa.h"
+#include "attr-callback.h"
+#include "callback-info.h"
 
 /* Summaries.  */
 fast_function_summary <ipa_fn_summary *, va_gc> *ipa_fn_summaries;
@@ -3058,9 +3060,18 @@ analyze_function_body (struct cgraph_node *node, bool 
early)
            }
 
          if (is_gimple_call (stmt)
-             && !gimple_call_internal_p (stmt))
+             && (!gimple_call_internal_p (stmt)
+                 || gimple_call_internal_fn (stmt) == IFN_ASSUME))
            {
              struct cgraph_edge *edge = node->get_edge (stmt);
+             if (!edge)
+               {
+                 /* The edge for .ASSUME outlined bodies is created when
+                    generating ipa-sra summaries.  Ignore the call statement
+                    for now.  */
+                 gcc_checking_assert (callback_ifn_assume_call_p (stmt));
+                 continue;
+               }
              ipa_call_summary *es = ipa_call_summaries->get_create (edge);
 
              /* Special case: results of BUILT_IN_CONSTANT_P will be always
@@ -3147,6 +3158,15 @@ analyze_function_body (struct cgraph_node *node, bool 
early)
                      es2->call_stmt_time = 0;
                    }
                }
+             /* Internal calls are not in the callgraph, so edges pointing to
+                .ASSUME bodies are not covered by the above branch, as the
+                dispatching edge doesn't exist.  */
+             else if (edge->callback)
+               {
+                 gcc_checking_assert (edge->callee->assume_function);
+                 es->call_stmt_size = 0;
+                 es->call_stmt_time = 0;
+               }
            }
 
          /* TODO: When conditional jump or switch is known to be constant, but
-- 
2.55.0

Reply via email to