1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
|
/* Internal functions.
Copyright (C) 2011-2017 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];
}
/* 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. */
unsigned int vectorizable : 1;
/* True if VECTORIZABLE, and if the first argument is a mask that
predicates the operation. */
unsigned int conditional : 1;
unsigned int unused : 14;
};
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 true if FN is a vectorizable conditional function, i.e. if:
R = IFN_FOO (COND, A1, A2...);
is equivalent to:
R = COND ? FOO (A1, A2, ...) : A1;
for scalars and:
for (int i = 0; i < nunits; ++i)
R[i] = COND[i] ? FOO (A1[i], A2[i], ...) : A1[i];
for vectors. */
inline bool
vectorizable_conditional_fn_p (internal_fn fn)
{
return direct_internal_fn_array[fn].conditional;
}
/* 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);
/* 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 bool set_edom_supported_p (void);
extern internal_fn get_conditional_internal_fn (tree_code, 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, machine_mode);
#endif
|