aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-unswitch.cc
diff options
context:
space:
mode:
authorJosef Melcr <jmelcr02@gmail.com>2025-10-16 16:25:29 +0200
committerJosef Melcr <jmelcr02@gmail.com>2025-10-17 11:31:38 +0200
commit7cd91c7c42eec894c8c13fa68ccc12ec3a047c9a (patch)
treef701ed3961b8161d57545ee52deec459e4b3c6c9 /gcc/tree-ssa-loop-unswitch.cc
parentcdb08b4bd24912f22c2f41798b3bd1b7395c87c6 (diff)
downloadgcc-master.zip
gcc-master.tar.gz
gcc-master.tar.bz2
ipa, cgraph: Enable constant propagation to OpenMP kernels.HEADtrunkmaster
This patch enables constant propagation to outlined OpenMP kernels. It does so using a new function attribute called ' callback' (note the space). The attribute ' callback' captures the notion of a function calling one of its arguments with some of its parameters as arguments. An OpenMP example of such function is GOMP_parallel. We implement the attribute with new callgraph edges called callback edges. They are imaginary edges pointing from the caller of the function with the attribute (e.g. caller of GOMP_parallel) to the body function itself (e.g. the outlined OpenMP body). They share their call statement with the edge from which they are derived (direct edge caller -> GOMP_parallel in this case). These edges allow passes such as ipa-cp to see the hidden call site to the body function and optimize the function accordingly. To illustrate on an example, the body GOMP_parallel looks something like this: void GOMP_parallel (void (*fn) (void *), void *data, /* ... */) { /* ... */ fn (data); /* ... */ } If we extend it with the attribute ' callback(1, 2)', we express that the function calls its first argument and passes it its second argument. This is represented in the call graph in this manner: direct indirect caller -----------------> GOMP_parallel ---------------> fn | ----------------------> fn callback The direct edge is then the callback-carrying edge, all new edges are the derived callback edges. While constant propagation is the main focus of this patch, callback edges can be useful for different passes (for example, they improve icf for OpenMP kernels), as they allow for address redirection. If the outlined body function gets optimized and cloned, from body_fn to body_fn.optimized, the callback edge allows us to replace the address in the arguments list: GOMP_parallel (body_fn, &data_struct, /* ... */); becomes GOMP_parallel (body_fn.optimized, &data_struct, /* ... */); This redirection is possible for any function with the attribute. This callback attribute implementation is partially compatible with clang's implementation. Its semantics, arguments and argument indexing style are the same, but we represent an unknown argument position with 0 (precedent set by attributes such as 'format'), while clang uses -1 or '?'. We use the index 1 for the 'this' pointer in member functions, clang uses 0. We also allow for multiple callback attributes on the same function, while clang only allows one. The attribute is currently for GCC internal use only, thanks to the space in its name. Originally, it was supposed to be called 'callback' like its clang counterpart, but we cannot use this name, as clang uses non-standard indexing style, leading to inconsistencies. The attribute will be introduced into the public API as 'gnu::callback_only' in a future patch. The attribute allows us to propagate constants into body functions of OpenMP constructs. Currently, GCC won't propagate the value 'c' into the OpenMP body in the following example: int a[100]; void test(int c) { #pragma omp parallel for for (int i = 0; i < c; i++) { if (!__builtin_constant_p(c)) { __builtin_abort(); } a[i] = i; } } int main() { test(100); return a[5] - 5; } With this patch, the body function will get cloned and the constant 'c' will get propagated. Some functions may utilize the attribute's infrastructure without being declared with it, for example GOMP_task. These functions are special cases and use the special case functions found in attr-callback.h. Special cases use the attribute under certain circumstances, for example GOMP_task uses it when the copy function is not being used required. gcc/ChangeLog: * Makefile.in: Add attr-callback.o to OBJS. * builtin-attrs.def (ATTR_CALLBACK): Callback attr identifier. (DEF_CALLBACK_ATTRIBUTE): Macro for callback attr creation. (GOMP): Attr for libgomp functions. (ATTR_CALLBACK_GOMP_LIST): ATTR_NOTHROW_LIST with GOMP callback attr added. * cgraph.cc (cgraph_add_edge_to_call_site_hash): Always hash the callback-carrying edge. (cgraph_node::get_edge): Always return the callback-carrying edge. (cgraph_edge::set_call_stmt): Add cascade for callback edges. (symbol_table::create_edge): Allow callback edges to share call stmts, initialize new flags. (cgraph_edge::make_callback): New method, derives a new callback edge. (cgraph_edge::get_callback_carrying_edge): New method. (cgraph_edge::first_callback_edge): Likewise. (cgraph_edge::next_callback_edge): Likewise. (cgraph_edge::purge_callback_edges): Likewise. (cgraph_edge::redirect_callee): When redirecting a callback edge, redirect its ref as well. (cgraph_edge::redirect_call_stmt_to_callee): Add callback edge redirection logic, set update_derived_edges to true hwne redirecting the carrying edge. (cgraph_node::remove_callers): Add cascade for callback edges. (cgraph_edge::dump_edge_flags): Print callback flags. (cgraph_node::verify_node): Add sanity checks for callback edges. * cgraph.h: Add new 1 bit flags and 16 bit callback_id to cgraph_edge class. * cgraphclones.cc (cgraph_edge::clone): Copy over callback data. * cif-code.def (CALLBACK_EDGE): Add CIF_CALLBACK_EDGE code. * ipa-cp.cc (purge_useless_callback_edges): New function, deletes callback edges when necessary. (ipcp_decision_stage): Call purge_useless_callback_edges. * ipa-fnsummary.cc (ipa_call_summary_t::duplicate): Add an exception for callback edges. (analyze_function_body): Copy over summary from carrying to callback edge. * ipa-inline-analysis.cc (do_estimate_growth_1): Skip callback edges when estimating growth. * ipa-inline-transform.cc (inline_transform): Add redirection cascade for callback edges. * ipa-param-manipulation.cc (drop_decl_attribute_if_params_changed_p): New function. (ipa_param_adjustments::build_new_function_type): Add args_modified out param. (ipa_param_adjustments::adjust_decl): Drop callback attrs when modifying args. * ipa-param-manipulation.h: Adjust decl of build_new_function_type. * ipa-prop.cc (ipa_duplicate_jump_function): Add decl. (init_callback_edge_summary): New function. (ipa_compute_jump_functions_for_edge): Add callback edge creation logic. * lto-cgraph.cc (lto_output_edge): Stream out callback data. (input_edge): Input callback data. * omp-builtins.def (BUILT_IN_GOMP_PARALLEL_LOOP_STATIC): Use new attr list. (BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED): Likewise. (BUILT_IN_GOMP_PARALLEL_LOOP_NONMONOTONIC_DYNAMIC): Likewise. (BUILT_IN_GOMP_PARALLEL_LOOP_NONMONOTONIC_RUNTIME): Likewise. (BUILT_IN_GOMP_PARALLEL): Likewise. (BUILT_IN_GOMP_PARALLEL_SECTIONS): Likewise. (BUILT_IN_GOMP_TEAMS_REG): Likewise. * tree-core.h (ECF_CB_1_2): New constant for callback(1,2). * tree-inline.cc (copy_bb): Copy callback edges when copying the carrying edge. (redirect_all_calls): Redirect callback edges. * tree.cc (set_call_expr_flags): Create callback attr according to the ECF_CB flag. * attr-callback.cc: New file. * attr-callback.h: New file. gcc/c-family/ChangeLog: * c-attribs.cc: Define callback attr. gcc/fortran/ChangeLog: * f95-lang.cc (ATTR_CALLBACK_GOMP_LIST): New attr list corresponding to the list in builtin-attrs.def. gcc/testsuite/ChangeLog: * gcc.dg/ipa/ipcp-cb-spec1.c: New test. * gcc.dg/ipa/ipcp-cb-spec2.c: New test. * gcc.dg/ipa/ipcp-cb1.c: New test. Signed-off-by: Josef Melcr <jmelcr02@gmail.com>
Diffstat (limited to 'gcc/tree-ssa-loop-unswitch.cc')
0 files changed, 0 insertions, 0 deletions