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