https://gcc.gnu.org/g:4af59432346b30541ac3142b6df968e34b8f2a5b

commit 4af59432346b30541ac3142b6df968e34b8f2a5b
Author: Josef Melcr <melcr...@fit.cvut.cz>
Date:   Fri Oct 18 14:40:46 2024 +0200

    omp-cp: add callback attribute, wip callback edges
    
    gcc/c-family/ChangeLog:
    
            * c-attribs.cc: add callback attribute
    
    gcc/ChangeLog:
    
            * cgraph.cc (symbol_table::create_edge): allow multiple stmts to
              edges for callback edges
            (cgraph_edge::make_callback): add make_callback method
            * cgraph.h: add make_callback signature
            * gimple.h (GCC_GIMPLE_H):
            (gimple_omp_parallel_set_child_fn): add callback attribute when
            setting new child fn
            * ipa-inline.cc (can_inline_edge_p): disable inlining of
              callback edges
            * ipa-prop.cc (ipa_analyze_node): add callback edge creation
    
    yeah it's segfaulting atm
    
    Signed-off-by: Josef Melcr <melcr...@fit.cvut.cz>

Diff:
---
 gcc/c-family/c-attribs.cc |  3 ++-
 gcc/cgraph.cc             | 26 +++++++++++++++++++++++++-
 gcc/cgraph.h              |  7 +++++++
 gcc/gimple.h              | 12 +++++++++++-
 gcc/ipa-inline.cc         |  6 ++++++
 gcc/ipa-prop.cc           | 24 ++++++++++++++++++++++++
 6 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
index 5b64805f97de..c342e7a1e55f 100644
--- a/gcc/c-family/c-attribs.cc
+++ b/gcc/c-family/c-attribs.cc
@@ -642,7 +642,8 @@ const struct attribute_spec c_common_gnu_attributes[] =
   { "flag_enum",             0, 0, false, true, false, false,
                              handle_flag_enum_attribute, NULL },
   { "null_terminated_string_arg", 1, 1, false, true, true, false,
-                             handle_null_terminated_string_arg_attribute, NULL}
+                             handle_null_terminated_string_arg_attribute, 
NULL},
+  { "callback", 0, 0, true, false, false, false, NULL, NULL}
 };
 
 const struct scoped_attribute_specs c_common_gnu_attribute_table =
diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
index 3332ea41ce2d..9310f1b43c20 100644
--- a/gcc/cgraph.cc
+++ b/gcc/cgraph.cc
@@ -885,7 +885,7 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node 
*callee,
         construction of call stmt hashtable.  */
       cgraph_edge *e;
       gcc_checking_assert (!(e = caller->get_edge (call_stmt))
-                          || e->speculative);
+                          || e->speculative || e->has_callback);
 
       gcc_assert (is_gimple_call (call_stmt));
     }
@@ -912,6 +912,8 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node 
*callee,
   edge->indirect_info = NULL;
   edge->indirect_inlining_edge = 0;
   edge->speculative = false;
+  edge->has_callback = false;
+  edge->callback = false;
   edge->indirect_unknown_callee = indir_unknown_callee;
   if (call_stmt && caller->call_site_hash)
     cgraph_add_edge_to_call_site_hash (edge);
@@ -1137,6 +1139,28 @@ cgraph_edge::make_speculative (cgraph_node *n2, 
profile_count direct_count,
   return e2;
 }
 
+cgraph_edge *
+cgraph_edge::make_callback (cgraph_node *n2)
+{
+  cgraph_node *n = caller;
+  cgraph_edge *e2;
+
+  if (dump_file)
+    fprintf (dump_file, "Indirect call -> callback call %s => %s\n",
+            n->dump_name (), n2->dump_name ());
+  has_callback = true;
+  e2 = n->create_edge (n2, call_stmt, count);
+  initialize_inline_failed (e2);
+  e2->callback = true;
+  if (TREE_NOTHROW (n2->decl))
+    e2->can_throw_external = false;
+  else
+    e2->can_throw_external = can_throw_external;
+  e2->lto_stmt_uid = lto_stmt_uid;
+  n2->mark_address_taken ();
+  return e2;
+}
+
 /* Speculative call consists of an indirect edge and one or more
    direct edge+ref pairs.
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 50bae96de4cf..4d937b1cde24 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1735,6 +1735,9 @@ public:
   cgraph_edge *make_speculative (cgraph_node *n2, profile_count direct_count,
                                 unsigned int speculative_id = 0);
 
+  /* TODO DOCS */
+  cgraph_edge *make_callback (cgraph_node *n2);
+
   /* Speculative call consists of an indirect edge and one or more
      direct edge+ref pairs.  Speculative will expand to the following sequence:
 
@@ -1951,6 +1954,10 @@ public:
      Optimizers may later redirect direct call to clone, so 1) and 3)
      do not need to necessarily agree with destination.  */
   unsigned int speculative : 1;
+  /* TODO DOCS */
+  unsigned int callback : 1;
+  /* TODO DOCS */
+  unsigned int has_callback : 1;
   /* Set to true when caller is a constructor or destructor of polymorphic
      type.  */
   unsigned in_polymorphic_cdtor : 1;
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 039ed66eab5d..faae38491fea 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -22,8 +22,11 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_GIMPLE_H
 #define GCC_GIMPLE_H
 
+#include "stringpool.h"
+#include "attribs.h"
 #include "tree-ssa-alias.h"
 #include "gimple-expr.h"
+#include "tree.h"
 
 typedef gimple *gimple_seq_node;
 
@@ -5814,10 +5817,17 @@ inline void
 gimple_omp_parallel_set_child_fn (gomp_parallel *omp_parallel_stmt,
                                  tree child_fn)
 {
+  if (child_fn != NULL_TREE
+      && !lookup_attribute ("callback", DECL_ATTRIBUTES (child_fn)))
+    {
+      tree attrs = tree_cons (get_identifier ("callback"), NULL,
+                             DECL_ATTRIBUTES (child_fn));
+      decl_attributes (&child_fn, attrs, 0);
+    }
+
   omp_parallel_stmt->child_fn = child_fn;
 }
 
-
 /* Return the artificial argument used to send variables and values
    from the parent to the children threads in OMP_PARALLEL_STMT.  */
 
diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc
index 8c423af42d1c..b31c028eca2b 100644
--- a/gcc/ipa-inline.cc
+++ b/gcc/ipa-inline.cc
@@ -452,6 +452,12 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
     }
   if (!inlinable && report)
     report_inline_failed_reason (e);
+
+  if(e->callback) {
+    printf("skipping inline - tried to inline: %d\n", inlinable);
+    inlinable = false;
+  }
+
   return inlinable;
 }
 
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 9070a45f6835..ffd6555d2e56 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -59,6 +59,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "attr-fnspec.h"
 #include "gimple-range.h"
 #include "value-range-storage.h"
+#include "attribs.h"
+#include "ipa-ref.h"
+#include "is-a.h"
 
 /* Function summary where the parameter infos are actually stored. */
 ipa_node_params_t *ipa_node_params_sum = NULL;
@@ -3194,6 +3197,27 @@ ipa_analyze_node (struct cgraph_node *node)
   fbi.param_count = ipa_get_param_count (info);
   fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
 
+  if (lookup_attribute ("callback", DECL_ATTRIBUTES (node->decl)))
+    {
+      printf ("callback ahoj %s\n", node->name ());
+      gcc_checking_assert (node->referred_to_p ());
+
+      ipa_ref *ref = NULL;
+      for (int i = 0; node->iterate_referring (i, ref); i++)
+       {
+           if (ref->use == IPA_REF_ADDR) {
+             gcc_checking_assert(dyn_cast<gcall*>(ref->stmt));
+             gcall * call_stmt = dyn_cast<gcall *>(ref->stmt);
+             cgraph_node * reffering_node = dyn_cast<cgraph_node 
*>(ref->referring);
+             gcc_checking_assert(call_stmt);
+             gcc_checking_assert(reffering_node);
+        cgraph_edge * e = reffering_node->get_edge(ref->stmt);
+        e->make_callback(node);
+        ipa_analyze_node(e->caller);
+           }
+       }
+    }
+
   for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
     {
       ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));

Reply via email to