| /* Internal functions. |
| Copyright (C) 2011-2019 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/>. */ |
| |
| #ifndef GCC_INTERNAL_FN_H |
| #define GCC_INTERNAL_FN_H |
| |
| /* INTEGER_CST values for IFN_UNIQUE function arg-0. |
| |
| UNSPEC: Undifferentiated UNIQUE. |
| |
| FORK and JOIN mark the points at which OpenACC partitioned |
| execution is entered or exited. |
| DEP_VAR = UNIQUE ({FORK,JOIN}, DEP_VAR, AXIS) |
| |
| HEAD_MARK and TAIL_MARK are used to demark the sequence entering |
| or leaving partitioned execution. |
| DEP_VAR = UNIQUE ({HEAD,TAIL}_MARK, REMAINING_MARKS, ...PRIMARY_FLAGS) |
| |
| The PRIMARY_FLAGS only occur on the first HEAD_MARK of a sequence. */ |
| #define IFN_UNIQUE_CODES \ |
| DEF(UNSPEC), \ |
| DEF(OACC_FORK), DEF(OACC_JOIN), \ |
| DEF(OACC_HEAD_MARK), DEF(OACC_TAIL_MARK) |
| |
| enum ifn_unique_kind { |
| #define DEF(X) IFN_UNIQUE_##X |
| IFN_UNIQUE_CODES |
| #undef DEF |
| }; |
| |
| /* INTEGER_CST values for IFN_GOACC_LOOP arg-0. Allows the precise |
| stepping of the compute geometry over the loop iterations to be |
| deferred until it is known which compiler is generating the code. |
| The action is encoded in a constant first argument. |
| |
| CHUNK_MAX = LOOP (CODE_CHUNKS, DIR, RANGE, STEP, CHUNK_SIZE, MASK) |
| STEP = LOOP (CODE_STEP, DIR, RANGE, STEP, CHUNK_SIZE, MASK) |
| OFFSET = LOOP (CODE_OFFSET, DIR, RANGE, STEP, CHUNK_SIZE, MASK, CHUNK_NO) |
| BOUND = LOOP (CODE_BOUND, DIR, RANGE, STEP, CHUNK_SIZE, MASK, OFFSET) |
| |
| DIR - +1 for up loop, -1 for down loop |
| RANGE - Range of loop (END - BASE) |
| STEP - iteration step size |
| CHUNKING - size of chunking, (constant zero for no chunking) |
| CHUNK_NO - chunk number |
| MASK - partitioning mask. */ |
| |
| #define IFN_GOACC_LOOP_CODES \ |
| DEF(CHUNKS), DEF(STEP), DEF(OFFSET), DEF(BOUND) |
| enum ifn_goacc_loop_kind { |
| #define DEF(X) IFN_GOACC_LOOP_##X |
| IFN_GOACC_LOOP_CODES |
| #undef DEF |
| }; |
| |
| /* The GOACC_REDUCTION function defines a generic interface to support |
| gang, worker and vector reductions. All calls are of the following |
| form: |
| |
| V = REDUCTION (CODE, REF_TO_RES, LOCAL_VAR, LEVEL, OP, OFFSET) |
| |
| REF_TO_RES - is a reference to the original reduction varl, may be NULL |
| LOCAL_VAR is the intermediate reduction variable |
| LEVEL corresponds to the GOMP_DIM of the reduction |
| OP is the tree code of the reduction operation |
| OFFSET may be used as an offset into a reduction array for the |
| reductions occuring at this level. |
| In general the return value is LOCAL_VAR, which creates a data |
| dependency between calls operating on the same reduction. */ |
| |
| #define IFN_GOACC_REDUCTION_CODES \ |
| DEF(SETUP), DEF(INIT), DEF(FINI), DEF(TEARDOWN) |
| enum ifn_goacc_reduction_kind { |
| #define DEF(X) IFN_GOACC_REDUCTION_##X |
| IFN_GOACC_REDUCTION_CODES |
| #undef DEF |
| }; |
| |
| /* Initialize internal function tables. */ |
| |
| extern void init_internal_fns (); |
| |
| /* Return the name of internal function FN. The name is only meaningful |
| for dumps; it has no linkage. */ |
| |
| extern const char *const internal_fn_name_array[]; |
| |
| static inline const char * |
| internal_fn_name (enum internal_fn fn) |
| { |
| return internal_fn_name_array[(int) fn]; |
| } |
| |
| extern internal_fn lookup_internal_fn (const char *); |
| |
| /* Return the ECF_* flags for function FN. */ |
| |
| extern const int internal_fn_flags_array[]; |
| |
| static inline int |
| internal_fn_flags (enum internal_fn fn) |
| { |
| return internal_fn_flags_array[(int) fn]; |
| } |
| |
| /* Return fnspec for function FN. */ |
| |
| extern GTY(()) const_tree internal_fn_fnspec_array[IFN_LAST + 1]; |
| |
| static inline const_tree |
| internal_fn_fnspec (enum internal_fn fn) |
| { |
| return internal_fn_fnspec_array[(int) fn]; |
| } |
| |
| /* Describes an internal function that maps directly to an optab. */ |
| struct direct_internal_fn_info |
| { |
| /* optabs can be parameterized by one or two modes. These fields describe |
| how to select those modes from the types of the return value and |
| arguments. A value of -1 says that the mode is determined by the |
| return type while a value N >= 0 says that the mode is determined by |
| the type of argument N. A value of -2 says that this internal |
| function isn't directly mapped to an optab. */ |
| signed int type0 : 8; |
| signed int type1 : 8; |
| /* True if the function is pointwise, so that it can be vectorized by |
| converting the return type and all argument types to vectors of the |
| same number of elements. E.g. we can vectorize an IFN_SQRT on |
| floats as an IFN_SQRT on vectors of N floats. |
| |
| This only needs 1 bit, but occupies the full 16 to ensure a nice |
| layout. */ |
| unsigned int vectorizable : 16; |
| }; |
| |
| extern const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1]; |
| |
| /* Return true if FN is mapped directly to an optab. */ |
| |
| inline bool |
| direct_internal_fn_p (internal_fn fn) |
| { |
| return direct_internal_fn_array[fn].type0 >= -1; |
| } |
| |
| /* Return true if FN is a direct internal function that can be vectorized by |
| converting the return type and all argument types to vectors of the same |
| number of elements. E.g. we can vectorize an IFN_SQRT on floats as an |
| IFN_SQRT on vectors of N floats. */ |
| |
| inline bool |
| vectorizable_internal_fn_p (internal_fn fn) |
| { |
| return direct_internal_fn_array[fn].vectorizable; |
| } |
| |
| /* Return optab information about internal function FN. Only meaningful |
| if direct_internal_fn_p (FN). */ |
| |
| inline const direct_internal_fn_info & |
| direct_internal_fn (internal_fn fn) |
| { |
| gcc_checking_assert (direct_internal_fn_p (fn)); |
| return direct_internal_fn_array[fn]; |
| } |
| |
| extern tree_pair direct_internal_fn_types (internal_fn, tree, tree *); |
| extern tree_pair direct_internal_fn_types (internal_fn, gcall *); |
| extern bool direct_internal_fn_supported_p (internal_fn, tree_pair, |
| optimization_type); |
| extern bool direct_internal_fn_supported_p (internal_fn, tree, |
| optimization_type); |
| extern bool direct_internal_fn_supported_p (gcall *, optimization_type); |
| |
| /* Return true if FN is supported for types TYPE0 and TYPE1 when the |
| optimization type is OPT_TYPE. The types are those associated with |
| the "type0" and "type1" fields of FN's direct_internal_fn_info |
| structure. */ |
| |
| inline bool |
| direct_internal_fn_supported_p (internal_fn fn, tree type0, tree type1, |
| optimization_type opt_type) |
| { |
| return direct_internal_fn_supported_p (fn, tree_pair (type0, type1), |
| opt_type); |
| } |
| |
| extern int first_commutative_argument (internal_fn); |
| |
| extern bool set_edom_supported_p (void); |
| |
| extern internal_fn get_conditional_internal_fn (tree_code); |
| extern internal_fn get_conditional_internal_fn (internal_fn); |
| extern tree_code conditional_internal_fn_code (internal_fn); |
| extern internal_fn get_unconditional_internal_fn (internal_fn); |
| extern bool can_interpret_as_conditional_op_p (gimple *, tree *, |
| tree_code *, tree (&)[3], |
| tree *); |
| |
| extern bool internal_load_fn_p (internal_fn); |
| extern bool internal_store_fn_p (internal_fn); |
| extern bool internal_gather_scatter_fn_p (internal_fn); |
| extern int internal_fn_mask_index (internal_fn); |
| extern int internal_fn_stored_value_index (internal_fn); |
| extern bool internal_gather_scatter_fn_supported_p (internal_fn, tree, |
| tree, signop, int); |
| |
| extern void expand_internal_call (gcall *); |
| extern void expand_internal_call (internal_fn, gcall *); |
| extern void expand_PHI (internal_fn, gcall *); |
| |
| extern bool vectorized_internal_fn_supported_p (internal_fn, tree); |
| |
| #endif |