GCC Middle and Back End API Reference
omp-simd-clone.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "cfganal.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "gimple-walk.h"
#include "langhooks.h"
#include "tree-cfg.h"
#include "tree-into-ssa.h"
#include "tree-dfa.h"
#include "cfgloop.h"
#include "symbol-summary.h"
#include "ipa-param-manipulation.h"
#include "tree-eh.h"
#include "varasm.h"
#include "stringpool.h"
#include "attribs.h"
#include "omp-simd-clone.h"
#include "omp-low.h"
#include "omp-general.h"
Include dependency graph for omp-simd-clone.cc:

Data Structures

struct  modify_stmt_info
 

Functions

static bool auto_simd_fail (tree decl, const char *excuse)
 
static bool auto_simd_check_stmt (gimple *stmt, tree outer)
 
static bool plausible_type_for_simd_clone (tree t)
 
static bool ok_for_auto_simd_clone (struct cgraph_node *node)
 
static struct cgraph_simd_clonesimd_clone_struct_alloc (int nargs)
 
static void simd_clone_struct_copy (struct cgraph_simd_clone *to, struct cgraph_simd_clone *from)
 
static void simd_clone_vector_of_formal_parm_types (vec< tree > *args, tree fndecl)
 
static struct cgraph_simd_clonesimd_clone_clauses_extract (struct cgraph_node *node, tree clauses, bool *inbranch_specified)
 
static tree simd_clone_compute_base_data_type (struct cgraph_node *node, struct cgraph_simd_clone *clone_info)
 
static tree simd_clone_mangle (struct cgraph_node *node, struct cgraph_simd_clone *clone_info)
 
static struct cgraph_nodesimd_clone_create (struct cgraph_node *old_node, bool force_local)
 
static void simd_clone_adjust_return_type (struct cgraph_node *node)
 
static tree create_tmp_simd_array (const char *prefix, tree type, poly_uint64 simdlen)
 
static void simd_clone_adjust_argument_types (struct cgraph_node *node)
 
static gimple_seq simd_clone_init_simd_arrays (struct cgraph_node *node, ipa_param_body_adjustments *adjustments)
 
static tree ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
 
static void ipa_simd_modify_function_body (struct cgraph_node *node, ipa_param_body_adjustments *adjustments, tree retval_array, tree iter)
 
static tree simd_clone_linear_addend (struct cgraph_node *node, unsigned int i, tree addtype, basic_block entry_bb)
 
static void simd_clone_adjust (struct cgraph_node *node)
 
void expand_simd_clones (struct cgraph_node *node)
 
static unsigned int ipa_omp_simd_clone (void)
 
simple_ipa_opt_passmake_pass_omp_simd_clone (gcc::context *ctxt)
 

Function Documentation

◆ auto_simd_check_stmt()

static bool auto_simd_check_stmt ( gimple * stmt,
tree outer )
static
Helper function for ok_for_auto_simd_clone; return false if the statement
violates restrictions for an "omp declare simd" function.  Specifically,
the function must not
- throw or call setjmp/longjmp
- write memory that could alias parallel calls
- read volatile memory
- include openmp directives or calls
- call functions that might do those things  

References auto_simd_fail(), DECL_ATTRIBUTES, ECF_CONST, ECF_PURE, ggc_alloc(), gimple_call_flags(), gimple_call_fndecl(), gimple_call_internal_p(), gimple_has_volatile_ops(), gimple_store_p(), lookup_attribute(), and NULL_TREE.

Referenced by ok_for_auto_simd_clone().

◆ auto_simd_fail()

static bool auto_simd_fail ( tree decl,
const char * excuse )
static
OMP constructs' SIMD clone supporting code.

Copyright (C) 2005-2024 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   
Print debug info for ok_for_auto_simd_clone to the dump file, logging
failure reason EXCUSE for function DECL.  Always returns false.   

References DECL_ASSEMBLER_NAME, dump_file, dump_flags, ggc_alloc(), IDENTIFIER_POINTER, and TDF_DETAILS.

Referenced by auto_simd_check_stmt(), and ok_for_auto_simd_clone().

◆ create_tmp_simd_array()

static tree create_tmp_simd_array ( const char * prefix,
tree type,
poly_uint64 simdlen )
static
Each vector argument has a corresponding array to be used locally
as part of the eventual loop.  Create such temporary array and
return it.

PREFIX is the prefix to be used for the temporary.

TYPE is the inner element type.

SIMDLEN is the number of elements.   

References build_array_type_nelts(), create_tmp_var_raw(), ggc_alloc(), and gimple_add_tmp_var().

Referenced by simd_clone_adjust_argument_types().

◆ expand_simd_clones()

◆ ipa_omp_simd_clone()

static unsigned int ipa_omp_simd_clone ( void )
static
Entry point for IPA simd clone creation pass.   

References expand_simd_clones(), and FOR_EACH_FUNCTION.

◆ ipa_simd_modify_function_body()

static void ipa_simd_modify_function_body ( struct cgraph_node * node,
ipa_param_body_adjustments * adjustments,
tree retval_array,
tree iter )
static
Traverse the function body and perform all modifications as
described in ADJUSTMENTS.  At function return, ADJUSTMENTS will be
modified such that the replacement/reduction value will now be an
offset into the corresponding simd_array.

This function will replace all function argument uses with their
corresponding simd array elements, and ajust the return values
accordingly.   

References modify_stmt_info::adjustments, modify_stmt_info::after_stmt, cgraph_simd_clone::args, build4(), cfun, symtab_node::decl, DECL_P, DECL_STRUCT_FUNCTION, ENTRY_BLOCK_PTR_FOR_FN, EXIT_BLOCK_PTR_FOR_FN, find_edge(), FOR_EACH_BB_FN, FOR_EACH_SSA_NAME, gcc_assert, gcc_checking_assert, ipa_param_body_adjustments::get_replacement_ssa_base(), ggc_alloc(), gimple_bb(), gimple_build_assign(), gimple_debug_bind_get_var(), gimple_debug_bind_p(), gimple_debug_source_bind_get_var(), gimple_debug_source_bind_p(), gimple_phi_arg_def(), gimple_phi_arg_edge(), gimple_phi_num_args(), gimple_purge_dead_eh_edges(), gimple_return_retval(), walk_stmt_info::gsi, gsi_after_labels(), gsi_end_p(), gsi_insert_before(), gsi_next(), gsi_remove(), gsi_replace(), GSI_SAME_STMT, gsi_start_bb(), gsi_start_phis(), gsi_stmt(), i, walk_stmt_info::info, ipa_simd_modify_stmt_ops(), ipa_param_body_adjustments::lookup_replacement(), ipa_param_body_adjustments::m_adj_params, maybe_clean_eh_stmt(), cgraph_simd_clone::nargs, NULL, NULL_TREE, cgraph_simd_clone_arg::orig_arg, r, ipa_param_body_adjustments::register_replacement(), SET_PHI_ARG_DEF, set_ssa_default_def(), SET_SSA_NAME_VAR_OR_IDENTIFIER, cgraph_simd_clone_arg::simd_array, cgraph_node::simdclone, cgraph_simd_clone::simdlen, single_succ(), ipa_param_body_adjustments::sort_replacements(), SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, SSA_NAME_VAR, walk_stmt_info::stmt, modify_stmt_info::stmt, TREE_CODE, TREE_TYPE, TYPE_VECTOR_SUBPARTS(), unshare_expr(), update_stmt(), cgraph_simd_clone_arg::vector_arg, vector_unroll_factor, and walk_gimple_op().

Referenced by simd_clone_adjust().

◆ ipa_simd_modify_stmt_ops()

◆ make_pass_omp_simd_clone()

simple_ipa_opt_pass * make_pass_omp_simd_clone ( gcc::context * ctxt)

References ggc_alloc().

◆ ok_for_auto_simd_clone()

◆ plausible_type_for_simd_clone()

static bool plausible_type_for_simd_clone ( tree t)
static
Helper function for ok_for_auto_simd_clone:  return true if type T is
plausible for a cloneable function argument or return type.   

References ggc_alloc(), RECORD_OR_UNION_TYPE_P, TYPE_ATOMIC, TYPE_MODE, and VOID_TYPE_P.

Referenced by ok_for_auto_simd_clone().

◆ simd_clone_adjust()

static void simd_clone_adjust ( struct cgraph_node * node)
static
Adjust the argument types in NODE to their appropriate vector
counterparts.   

References add_bb_to_loop(), add_loop(), add_phi_arg(), cgraph_simd_clone_arg::alignment, alloc_loop(), cgraph_simd_clone_arg::arg_type, cgraph_simd_clone::args, boolean_type_node, build1(), build4(), build_array_type_nelts(), build_distinct_type_copy(), build_fold_addr_expr, build_int_cst(), build_nonstandard_integer_type(), build_one_cst(), build_simple_mem_ref, build_zero_cst(), builtin_decl_explicit(), calculate_dominance_info(), CDI_DOMINATORS, cfun, basic_block_def::count, cgraph_node::create_edge(), create_empty_bb(), create_phi_node(), create_tmp_var, create_tmp_var_raw(), symtab_node::decl, DECL_BY_REFERENCE, DECL_RESULT, DECL_STRUCT_FUNCTION, EDGE_COUNT, EDGE_PRED, ENTRY_BLOCK_PTR_FOR_FN, exact_log2(), EXIT_BLOCK_PTR_FOR_FN, FALLTHRU_EDGE, find_edge(), FOR_EACH_IMM_USE_ON_STMT, FOR_EACH_IMM_USE_STMT, force_gimple_operand_gsi(), loop::force_vectorize, g, gcc_assert, cgraph_node::get_create(), GET_MODE_BITSIZE(), get_or_create_ssa_default_def(), ggc_alloc(), gimple_add_tmp_var(), gimple_assign_lhs(), gimple_build_assign(), gimple_build_call(), gimple_build_cond(), gimple_build_return(), gimple_call_lhs(), gimple_call_set_lhs(), gimple_get_lhs(), gimple_seq_add_stmt_without_update(), gsi_after_labels(), GSI_CONTINUE_LINKING, gsi_insert_after(), gsi_insert_before(), gsi_insert_seq_before(), gsi_insert_seq_on_edge_immediate(), gsi_last_bb(), GSI_NEW_STMT, GSI_SAME_STMT, gsi_stmt(), profile_probability::guessed(), profile_probability::guessed_never(), has_zero_uses(), loop::header, i, cgraph_simd_clone::inbranch, INTEGRAL_TYPE_P, IPA_PARAM_OP_COPY, IPA_PARAM_OP_NEW, IPA_PARAM_PREFIX_MASK, IPA_PARAM_PREFIX_SIMD, ipa_simd_modify_function_body(), is_gimple_debug(), is_gimple_reg_type(), known_eq, loop::latch, profile_probability::likely(), basic_block_def::loop_father, make_edge(), make_single_succ_edge(), make_ssa_name(), cgraph_simd_clone::mask_mode, ipa_param_body_adjustments::modify_formal_parameters(), cgraph_simd_clone::nargs, NULL, NULL_TREE, cgraph_simd_clone_arg::orig_arg, POINTER_TYPE_P, pop_cfun(), pop_gimplify_context(), ptr_type_node, push_cfun(), push_gimplify_context(), redirect_edge_succ(), relayout_decl(), loop::safelen, sc, SCALAR_TYPE_MODE, SET_USE, cgraph_simd_clone_arg::simd_array, simd_clone_adjust_argument_types(), simd_clone_adjust_return_type(), SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_MASK, SIMD_CLONE_ARG_TYPE_UNIFORM, SIMD_CLONE_ARG_TYPE_VECTOR, simd_clone_init_simd_arrays(), simd_clone_linear_addend(), cgraph_node::simdclone, cgraph_simd_clone::simdlen, single_succ(), single_succ_edge(), size_int, size_zero_node, sizetype, split_block(), split_block_after_labels(), ssa_default_def(), targetm, poly_int< N, C >::to_constant(), TODO_update_ssa, TREE_ADDRESSABLE, TREE_CODE, TREE_OPERAND, tree_to_uhwi(), TREE_TYPE, TYPE_DOMAIN, TYPE_MAX_VALUE, TYPE_READONLY, TYPE_SIZE_UNIT, UNKNOWN_LOCATION, profile_probability::unlikely(), unsigned_type_node, update_ssa(), useless_type_conversion_p(), vec_safe_push(), vec_safe_reserve(), cgraph_simd_clone::vecsize_float, cgraph_simd_clone::vecsize_int, cgraph_simd_clone_arg::vector_arg, vector_unroll_factor, void_type_node, and profile_count::zero().

Referenced by expand_simd_clones().

◆ simd_clone_adjust_argument_types()

static void simd_clone_adjust_argument_types ( struct cgraph_node * node)
static
Modify the function argument types to their corresponding vector
counterparts if appropriate.  Also, create one array for each simd
argument to be used locally when using the function arguments as
part of the loop.

NODE is the function whose arguments are to be adjusted.

If NODE does not represent function definition, returns NULL.  Otherwise
returns an adjustment class that will be filled describing how the argument
declarations will be remapped.  New arguments which are not to be remapped
are marked with USER_FLAG.   

References cgraph_simd_clone::args, boolean_type_node, build_decl(), build_vector_type(), create_tmp_simd_array(), symtab_node::decl, DECL_NAME, symtab_node::definition, gcc_assert, GET_MODE_BITSIZE(), ggc_alloc(), i, IDENTIFIER_POINTER, INTEGRAL_TYPE_P, known_eq, nreverse(), NULL, NULL_TREE, pointer_sized_int_node, POINTER_TYPE_P, push_function_arg_decls(), sc, SCALAR_TYPE_MODE, SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_MASK, SIMD_CLONE_ARG_TYPE_VECTOR, simd_clone_compute_base_data_type(), simd_clone_vector_of_formal_parm_types(), cgraph_node::simdclone, TREE_CHAIN, tree_cons(), TREE_TYPE, TYPE_ARG_TYPES, lang_hooks_for_types::type_for_mode, lang_hooks::types, UNKNOWN_LOCATION, vector_unroll_factor, void_list_node, and void_type_node.

Referenced by expand_simd_clones(), and simd_clone_adjust().

◆ simd_clone_adjust_return_type()

◆ simd_clone_clauses_extract()

static struct cgraph_simd_clone * simd_clone_clauses_extract ( struct cgraph_node * node,
tree clauses,
bool * inbranch_specified )
static
Given a simd function in NODE, extract the simd specific
information from the OMP clauses passed in CLAUSES, and return
the struct cgraph_simd_clone * if it should be cloned.  *INBRANCH_SPECIFIED
is set to TRUE if the `inbranch' or `notinbranch' clause specified,
otherwise set to FALSE.   

References arg_type, cgraph_simd_clone::args, symtab_node::decl, DECL_SOURCE_LOCATION, fold_convert, gcc_assert, gcc_unreachable, ggc_alloc(), integer_zerop(), NULL, NULL_TREE, OMP_CLAUSE_ALIGNED, OMP_CLAUSE_ALIGNED_ALIGNMENT, OMP_CLAUSE_CHAIN, OMP_CLAUSE_CODE, OMP_CLAUSE_DECL, OMP_CLAUSE_INBRANCH, OMP_CLAUSE_LINEAR, OMP_CLAUSE_LINEAR_DEFAULT, OMP_CLAUSE_LINEAR_KIND, OMP_CLAUSE_LINEAR_REF, OMP_CLAUSE_LINEAR_STEP, OMP_CLAUSE_LINEAR_UVAL, OMP_CLAUSE_LINEAR_VAL, OMP_CLAUSE_LINEAR_VARIABLE_STRIDE, OMP_CLAUSE_LOCATION, OMP_CLAUSE_NOTINBRANCH, OMP_CLAUSE_SIMDLEN, OMP_CLAUSE_SIMDLEN_EXPR, OMP_CLAUSE_UNIFORM, POINTER_TYPE_P, SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP, SIMD_CLONE_ARG_TYPE_UNIFORM, simd_clone_struct_alloc(), simd_clone_vector_of_formal_parm_types(), ssizetype, TREE_CODE, tree_fits_shwi_p(), TREE_INT_CST_LOW, tree_to_shwi(), tree_to_uhwi(), TREE_TYPE, TREE_VALUE, TYPE_ATOMIC, void_type_node, and warning_at().

Referenced by expand_simd_clones().

◆ simd_clone_compute_base_data_type()

static tree simd_clone_compute_base_data_type ( struct cgraph_node * node,
struct cgraph_simd_clone * clone_info )
static
Given a SIMD clone in NODE, calculate the characteristic data
type and return the coresponding type.  The characteristic data
type is computed as described in the Intel Vector ABI.   

References aggregate_value_p(), symtab_node::decl, ggc_alloc(), i, integer_type_node, map, NULL, RECORD_OR_UNION_TYPE_P, SIMD_CLONE_ARG_TYPE_VECTOR, simd_clone_vector_of_formal_parm_types(), TREE_CODE, TREE_TYPE, and type().

Referenced by expand_simd_clones(), and simd_clone_adjust_argument_types().

◆ simd_clone_create()

◆ simd_clone_init_simd_arrays()

◆ simd_clone_linear_addend()

◆ simd_clone_mangle()

◆ simd_clone_struct_alloc()

static struct cgraph_simd_clone * simd_clone_struct_alloc ( int nargs)
static
Allocate a fresh `simd_clone' and return it.  NARGS is the number
of arguments to reserve space for.   

References ggc_internal_cleared_alloc(), and cgraph_simd_clone::nargs.

Referenced by expand_simd_clones(), and simd_clone_clauses_extract().

◆ simd_clone_struct_copy()

static void simd_clone_struct_copy ( struct cgraph_simd_clone * to,
struct cgraph_simd_clone * from )
inlinestatic
Make a copy of the `struct cgraph_simd_clone' in FROM to TO.   

References ggc_alloc(), cgraph_simd_clone::inbranch, and cgraph_simd_clone::nargs.

Referenced by expand_simd_clones().

◆ simd_clone_vector_of_formal_parm_types()

static void simd_clone_vector_of_formal_parm_types ( vec< tree > * args,
tree fndecl )
static
Fill an empty vector ARGS with parameter types of function FNDECL.  This
uses TYPE_ARG_TYPES if available, otherwise falls back to types of
DECL_ARGUMENTS types.   

References cgraph_simd_clone::args, FOR_EACH_VEC_ELT, i, push_function_arg_decls(), push_function_arg_types(), TREE_TYPE, and TYPE_ARG_TYPES.

Referenced by simd_clone_adjust_argument_types(), simd_clone_clauses_extract(), and simd_clone_compute_base_data_type().