xref: /netbsd-src/external/gpl3/gcc/dist/gcc/internal-fn.h (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 /* Internal functions.
2    Copyright (C) 2011-2022 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10 
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19 
20 #ifndef GCC_INTERNAL_FN_H
21 #define GCC_INTERNAL_FN_H
22 
23 /* INTEGER_CST values for IFN_UNIQUE function arg-0.
24 
25    UNSPEC: Undifferentiated UNIQUE.
26 
27    FORK and JOIN mark the points at which OpenACC partitioned
28    execution is entered or exited.
29       DEP_VAR = UNIQUE ({FORK,JOIN}, DEP_VAR, AXIS)
30 
31    HEAD_MARK and TAIL_MARK are used to demark the sequence entering
32    or leaving partitioned execution.
33       DEP_VAR = UNIQUE ({HEAD,TAIL}_MARK, REMAINING_MARKS, ...PRIMARY_FLAGS)
34 
35    The PRIMARY_FLAGS only occur on the first HEAD_MARK of a sequence.
36 
37    PRIVATE captures variables to be made private at the surrounding parallelism
38    level.  */
39 #define IFN_UNIQUE_CODES				  \
40   DEF(UNSPEC),	\
41     DEF(OACC_FORK), DEF(OACC_JOIN),		\
42     DEF(OACC_HEAD_MARK), DEF(OACC_TAIL_MARK),	\
43     DEF(OACC_PRIVATE)
44 
45 enum ifn_unique_kind {
46 #define DEF(X) IFN_UNIQUE_##X
47   IFN_UNIQUE_CODES
48 #undef DEF
49 };
50 
51 /* INTEGER_CST values for IFN_GOACC_LOOP arg-0.  Allows the precise
52    stepping of the compute geometry over the loop iterations to be
53    deferred until it is known which compiler is generating the code.
54    The action is encoded in a constant first argument.
55 
56      CHUNK_MAX = LOOP (CODE_CHUNKS, DIR, RANGE, STEP, CHUNK_SIZE, MASK)
57      STEP = LOOP (CODE_STEP, DIR, RANGE, STEP, CHUNK_SIZE, MASK)
58      OFFSET = LOOP (CODE_OFFSET, DIR, RANGE, STEP, CHUNK_SIZE, MASK, CHUNK_NO)
59      BOUND = LOOP (CODE_BOUND, DIR, RANGE, STEP, CHUNK_SIZE, MASK, OFFSET)
60 
61      DIR - +1 for up loop, -1 for down loop
62      RANGE - Range of loop (END - BASE)
63      STEP - iteration step size
64      CHUNKING - size of chunking, (constant zero for no chunking)
65      CHUNK_NO - chunk number
66      MASK - partitioning mask.  */
67 
68 #define IFN_GOACC_LOOP_CODES \
69   DEF(CHUNKS), DEF(STEP), DEF(OFFSET), DEF(BOUND)
70 enum ifn_goacc_loop_kind {
71 #define DEF(X) IFN_GOACC_LOOP_##X
72   IFN_GOACC_LOOP_CODES
73 #undef DEF
74 };
75 
76 /* The GOACC_REDUCTION function defines a generic interface to support
77    gang, worker and vector reductions.  All calls are of the following
78    form:
79 
80      V = REDUCTION (CODE, REF_TO_RES, LOCAL_VAR, LEVEL, OP, OFFSET)
81 
82    REF_TO_RES - is a reference to the original reduction varl, may be NULL
83    LOCAL_VAR is the intermediate reduction variable
84    LEVEL corresponds to the GOMP_DIM of the reduction
85    OP is the tree code of the reduction operation
86    OFFSET may be used as an offset into a reduction array for the
87           reductions occuring at this level.
88    In general the return value is LOCAL_VAR, which creates a data
89    dependency between calls operating on the same reduction.  */
90 
91 #define IFN_GOACC_REDUCTION_CODES \
92   DEF(SETUP), DEF(INIT), DEF(FINI), DEF(TEARDOWN)
93 enum ifn_goacc_reduction_kind {
94 #define DEF(X) IFN_GOACC_REDUCTION_##X
95   IFN_GOACC_REDUCTION_CODES
96 #undef DEF
97 };
98 
99 /* Initialize internal function tables.  */
100 
101 extern void init_internal_fns ();
102 
103 /* Return the name of internal function FN.  The name is only meaningful
104    for dumps; it has no linkage.  */
105 
106 extern const char *const internal_fn_name_array[];
107 
108 static inline const char *
internal_fn_name(enum internal_fn fn)109 internal_fn_name (enum internal_fn fn)
110 {
111   return internal_fn_name_array[(int) fn];
112 }
113 
114 extern internal_fn lookup_internal_fn (const char *);
115 
116 /* Return the ECF_* flags for function FN.  */
117 
118 extern const int internal_fn_flags_array[];
119 
120 static inline int
internal_fn_flags(enum internal_fn fn)121 internal_fn_flags (enum internal_fn fn)
122 {
123   return internal_fn_flags_array[(int) fn];
124 }
125 
126 /* Return fnspec for function FN.  */
127 
128 extern GTY(()) const_tree internal_fn_fnspec_array[IFN_LAST + 1];
129 
130 static inline const_tree
internal_fn_fnspec(enum internal_fn fn)131 internal_fn_fnspec (enum internal_fn fn)
132 {
133   return internal_fn_fnspec_array[(int) fn];
134 }
135 
136 /* Describes an internal function that maps directly to an optab.  */
137 struct direct_internal_fn_info
138 {
139   /* optabs can be parameterized by one or two modes.  These fields describe
140      how to select those modes from the types of the return value and
141      arguments.  A value of -1 says that the mode is determined by the
142      return type while a value N >= 0 says that the mode is determined by
143      the type of argument N.  A value of -2 says that this internal
144      function isn't directly mapped to an optab.  */
145   signed int type0 : 8;
146   signed int type1 : 8;
147   /* True if the function is pointwise, so that it can be vectorized by
148      converting the return type and all argument types to vectors of the
149      same number of elements.  E.g. we can vectorize an IFN_SQRT on
150      floats as an IFN_SQRT on vectors of N floats.
151 
152      This only needs 1 bit, but occupies the full 16 to ensure a nice
153      layout.  */
154   unsigned int vectorizable : 16;
155 };
156 
157 extern const direct_internal_fn_info direct_internal_fn_array[IFN_LAST + 1];
158 
159 /* Return true if FN is mapped directly to an optab.  */
160 
161 inline bool
direct_internal_fn_p(internal_fn fn)162 direct_internal_fn_p (internal_fn fn)
163 {
164   return direct_internal_fn_array[fn].type0 >= -1;
165 }
166 
167 /* Return true if FN is a direct internal function that can be vectorized by
168    converting the return type and all argument types to vectors of the same
169    number of elements.  E.g. we can vectorize an IFN_SQRT on floats as an
170    IFN_SQRT on vectors of N floats.  */
171 
172 inline bool
vectorizable_internal_fn_p(internal_fn fn)173 vectorizable_internal_fn_p (internal_fn fn)
174 {
175   return direct_internal_fn_array[fn].vectorizable;
176 }
177 
178 /* Return optab information about internal function FN.  Only meaningful
179    if direct_internal_fn_p (FN).  */
180 
181 inline const direct_internal_fn_info &
direct_internal_fn(internal_fn fn)182 direct_internal_fn (internal_fn fn)
183 {
184   gcc_checking_assert (direct_internal_fn_p (fn));
185   return direct_internal_fn_array[fn];
186 }
187 
188 extern tree_pair direct_internal_fn_types (internal_fn, tree, tree *);
189 extern tree_pair direct_internal_fn_types (internal_fn, gcall *);
190 extern bool direct_internal_fn_supported_p (internal_fn, tree_pair,
191 					    optimization_type);
192 extern bool direct_internal_fn_supported_p (internal_fn, tree,
193 					    optimization_type);
194 extern bool direct_internal_fn_supported_p (gcall *, optimization_type);
195 
196 /* Return true if FN is supported for types TYPE0 and TYPE1 when the
197    optimization type is OPT_TYPE.  The types are those associated with
198    the "type0" and "type1" fields of FN's direct_internal_fn_info
199    structure.  */
200 
201 inline bool
direct_internal_fn_supported_p(internal_fn fn,tree type0,tree type1,optimization_type opt_type)202 direct_internal_fn_supported_p (internal_fn fn, tree type0, tree type1,
203 				optimization_type opt_type)
204 {
205   return direct_internal_fn_supported_p (fn, tree_pair (type0, type1),
206 					 opt_type);
207 }
208 
209 extern bool commutative_binary_fn_p (internal_fn);
210 extern bool commutative_ternary_fn_p (internal_fn);
211 extern int first_commutative_argument (internal_fn);
212 extern bool associative_binary_fn_p (internal_fn);
213 
214 extern bool set_edom_supported_p (void);
215 
216 extern internal_fn get_conditional_internal_fn (tree_code);
217 extern internal_fn get_conditional_internal_fn (internal_fn);
218 extern tree_code conditional_internal_fn_code (internal_fn);
219 extern internal_fn get_unconditional_internal_fn (internal_fn);
220 extern bool can_interpret_as_conditional_op_p (gimple *, tree *,
221 					       tree_code *, tree (&)[3],
222 					       tree *);
223 
224 extern bool internal_load_fn_p (internal_fn);
225 extern bool internal_store_fn_p (internal_fn);
226 extern bool internal_gather_scatter_fn_p (internal_fn);
227 extern int internal_fn_mask_index (internal_fn);
228 extern int internal_fn_stored_value_index (internal_fn);
229 extern bool internal_gather_scatter_fn_supported_p (internal_fn, tree,
230 						    tree, tree, int);
231 extern bool internal_check_ptrs_fn_supported_p (internal_fn, tree,
232 						poly_uint64, unsigned int);
233 #define VECT_PARTIAL_BIAS_UNSUPPORTED 127
234 
235 extern signed char internal_len_load_store_bias (internal_fn ifn,
236 						 machine_mode);
237 
238 extern void expand_addsub_overflow (location_t, tree_code, tree, tree, tree,
239 				    bool, bool, bool, bool, tree *);
240 extern void expand_internal_call (gcall *);
241 extern void expand_internal_call (internal_fn, gcall *);
242 extern void expand_PHI (internal_fn, gcall *);
243 extern void expand_SHUFFLEVECTOR (internal_fn, gcall *);
244 extern void expand_SPACESHIP (internal_fn, gcall *);
245 
246 extern bool vectorized_internal_fn_supported_p (internal_fn, tree);
247 
248 enum {
249   ATOMIC_OP_FETCH_CMP_0_EQ = 0,
250   ATOMIC_OP_FETCH_CMP_0_NE = 1,
251   ATOMIC_OP_FETCH_CMP_0_LT = 2,
252   ATOMIC_OP_FETCH_CMP_0_LE = 3,
253   ATOMIC_OP_FETCH_CMP_0_GT = 4,
254   ATOMIC_OP_FETCH_CMP_0_GE = 5
255 };
256 
257 #endif
258