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));