graphite.h revision 1.2.10.2 1 /* Graphite polyhedral representation.
2 Copyright (C) 2009-2016 Free Software Foundation, Inc.
3 Contributed by Sebastian Pop <sebastian.pop (at) amd.com> and
4 Tobias Grosser <grosser (at) fim.uni-passau.de>.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
21
22 #ifndef GCC_GRAPHITE_POLY_H
23 #define GCC_GRAPHITE_POLY_H
24
25 #include "sese.h"
26 #include <isl/options.h>
27 #include <isl/ctx.h>
28 #include <isl/val_gmp.h>
29 #include <isl/set.h>
30 #include <isl/union_set.h>
31 #include <isl/map.h>
32 #include <isl/union_map.h>
33 #include <isl/aff.h>
34 #include <isl/constraint.h>
35 #include <isl/flow.h>
36 #include <isl/ilp.h>
37 #include <isl/schedule.h>
38 #include <isl/ast_build.h>
39
40 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
41 /* isl 0.15 or later. */
42 #include <isl/schedule_node.h>
43 #include <isl/id.h>
44 #include <isl/space.h>
45
46 #else
47 /* isl 0.14 or 0.13. */
48 # define isl_stat int
49 # define isl_stat_ok 0
50 #endif
51
52 typedef struct poly_dr *poly_dr_p;
53
54 typedef struct poly_bb *poly_bb_p;
55
56 typedef struct scop *scop_p;
57
58 typedef unsigned graphite_dim_t;
59
60 static inline graphite_dim_t scop_nb_params (scop_p);
61
62 /* A data reference can write or read some memory or we
63 just know it may write some memory. */
64 enum poly_dr_type
65 {
66 PDR_READ,
67 /* PDR_MAY_READs are represented using PDR_READS. This does not
68 limit the expressiveness. */
69 PDR_WRITE,
70 PDR_MAY_WRITE
71 };
72
73 struct poly_dr
74 {
75 /* An identifier for this PDR. */
76 int id;
77
78 /* The number of data refs identical to this one in the PBB. */
79 int nb_refs;
80
81 /* A pointer to the gimple stmt containing this reference. */
82 gimple *stmt;
83
84 /* A pointer to the PBB that contains this data reference. */
85 poly_bb_p pbb;
86
87 enum poly_dr_type type;
88
89 /* The access polyhedron contains the polyhedral space this data
90 reference will access.
91
92 The polyhedron contains these dimensions:
93
94 - The alias set (a):
95 Every memory access is classified in at least one alias set.
96
97 - The subscripts (s_0, ..., s_n):
98 The memory is accessed using zero or more subscript dimensions.
99
100 - The iteration domain (variables and parameters)
101
102 Do not hardcode the dimensions. Use the following accessor functions:
103 - pdr_alias_set_dim
104 - pdr_subscript_dim
105 - pdr_iterator_dim
106 - pdr_parameter_dim
107
108 Example:
109
110 | int A[1335][123];
111 | int *p = malloc ();
112 |
113 | k = ...
114 | for i
115 | {
116 | if (unknown_function ())
117 | p = A;
118 | ... = p[?][?];
119 | for j
120 | A[i][j+k] = m;
121 | }
122
123 The data access A[i][j+k] in alias set "5" is described like this:
124
125 | i j k a s0 s1 1
126 | 0 0 0 1 0 0 -5 = 0
127 |-1 0 0 0 1 0 0 = 0
128 | 0 -1 -1 0 0 1 0 = 0
129 | 0 0 0 0 1 0 0 >= 0 # The last four lines describe the
130 | 0 0 0 0 0 1 0 >= 0 # array size.
131 | 0 0 0 0 -1 0 1335 >= 0
132 | 0 0 0 0 0 -1 123 >= 0
133
134 The pointer "*p" in alias set "5" and "7" is described as a union of
135 polyhedron:
136
137
138 | i k a s0 1
139 | 0 0 1 0 -5 = 0
140 | 0 0 0 1 0 >= 0
141
142 "or"
143
144 | i k a s0 1
145 | 0 0 1 0 -7 = 0
146 | 0 0 0 1 0 >= 0
147
148 "*p" accesses all of the object allocated with 'malloc'.
149
150 The scalar data access "m" is represented as an array with zero subscript
151 dimensions.
152
153 | i j k a 1
154 | 0 0 0 -1 15 = 0
155
156 The difference between the graphite internal format for access data and
157 the OpenSop format is in the order of columns.
158 Instead of having:
159
160 | i j k a s0 s1 1
161 | 0 0 0 1 0 0 -5 = 0
162 |-1 0 0 0 1 0 0 = 0
163 | 0 -1 -1 0 0 1 0 = 0
164 | 0 0 0 0 1 0 0 >= 0 # The last four lines describe the
165 | 0 0 0 0 0 1 0 >= 0 # array size.
166 | 0 0 0 0 -1 0 1335 >= 0
167 | 0 0 0 0 0 -1 123 >= 0
168
169 In OpenScop we have:
170
171 | a s0 s1 i j k 1
172 | 1 0 0 0 0 0 -5 = 0
173 | 0 1 0 -1 0 0 0 = 0
174 | 0 0 1 0 -1 -1 0 = 0
175 | 0 1 0 0 0 0 0 >= 0 # The last four lines describe the
176 | 0 0 1 0 0 0 0 >= 0 # array size.
177 | 0 -1 0 0 0 0 1335 >= 0
178 | 0 0 -1 0 0 0 123 >= 0
179
180 The OpenScop access function is printed as follows:
181
182 | 1 # The number of disjunct components in a union of access functions.
183 | R C O I L P # Described bellow.
184 | a s0 s1 i j k 1
185 | 1 0 0 0 0 0 -5 = 0
186 | 0 1 0 -1 0 0 0 = 0
187 | 0 0 1 0 -1 -1 0 = 0
188 | 0 1 0 0 0 0 0 >= 0 # The last four lines describe the
189 | 0 0 1 0 0 0 0 >= 0 # array size.
190 | 0 -1 0 0 0 0 1335 >= 0
191 | 0 0 -1 0 0 0 123 >= 0
192
193 Where:
194 - R: Number of rows.
195 - C: Number of columns.
196 - O: Number of output dimensions = alias set + number of subscripts.
197 - I: Number of input dimensions (iterators).
198 - L: Number of local (existentially quantified) dimensions.
199 - P: Number of parameters.
200
201 In the example, the vector "R C O I L P" is "7 7 3 2 0 1". */
202 isl_map *accesses;
203 isl_set *subscript_sizes;
204 };
205
206 #define PDR_ID(PDR) (PDR->id)
207 #define PDR_NB_REFS(PDR) (PDR->nb_refs)
208 #define PDR_PBB(PDR) (PDR->pbb)
209 #define PDR_TYPE(PDR) (PDR->type)
210 #define PDR_ACCESSES(PDR) (NULL)
211
212 void new_poly_dr (poly_bb_p, gimple *, enum poly_dr_type,
213 isl_map *, isl_set *);
214 void debug_pdr (poly_dr_p);
215 void print_pdr (FILE *, poly_dr_p);
216
217 static inline bool
218 pdr_read_p (poly_dr_p pdr)
219 {
220 return PDR_TYPE (pdr) == PDR_READ;
221 }
222
223 /* Returns true when PDR is a "write". */
224
225 static inline bool
226 pdr_write_p (poly_dr_p pdr)
227 {
228 return PDR_TYPE (pdr) == PDR_WRITE;
229 }
230
231 /* Returns true when PDR is a "may write". */
232
233 static inline bool
234 pdr_may_write_p (poly_dr_p pdr)
235 {
236 return PDR_TYPE (pdr) == PDR_MAY_WRITE;
237 }
238
239 /* POLY_BB represents a blackbox in the polyhedral model. */
240
241 struct poly_bb
242 {
243 /* Pointer to a basic block or a statement in the compiler. */
244 gimple_poly_bb_p black_box;
245
246 /* Pointer to the SCOP containing this PBB. */
247 scop_p scop;
248
249 /* The iteration domain of this bb. The layout of this polyhedron
250 is I|G with I the iteration domain, G the context parameters.
251
252 Example:
253
254 for (i = a - 7*b + 8; i <= 3*a + 13*b + 20; i++)
255 for (j = 2; j <= 2*i + 5; j++)
256 for (k = 0; k <= 5; k++)
257 S (i,j,k)
258
259 Loop iterators: i, j, k
260 Parameters: a, b
261
262 | i >= a - 7b + 8
263 | i <= 3a + 13b + 20
264 | j >= 2
265 | j <= 2i + 5
266 | k >= 0
267 | k <= 5
268
269 The number of variables in the DOMAIN may change and is not
270 related to the number of loops in the original code. */
271 isl_set *domain;
272 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
273 isl_set *iterators;
274 #else
275 /* The original scattering. */
276 isl_map *schedule;
277
278 /* The transformed scattering. */
279 isl_map *transformed;
280
281 /* A copy of the transformed scattering. */
282 isl_map *saved;
283 #endif
284
285 /* The data references we access. */
286 vec<poly_dr_p> drs;
287
288 /* The last basic block generated for this pbb. */
289 basic_block new_bb;
290 };
291
292 #define PBB_BLACK_BOX(PBB) ((gimple_poly_bb_p) PBB->black_box)
293 #define PBB_SCOP(PBB) (PBB->scop)
294 #define PBB_DRS(PBB) (PBB->drs)
295
296 extern poly_bb_p new_poly_bb (scop_p, gimple_poly_bb_p);
297 extern void print_pbb_domain (FILE *, poly_bb_p);
298 extern void print_pbb (FILE *, poly_bb_p);
299 extern void print_scop_context (FILE *, scop_p);
300 extern void print_scop (FILE *, scop_p);
301 extern void debug_pbb_domain (poly_bb_p);
302 extern void debug_pbb (poly_bb_p);
303 extern void print_pdrs (FILE *, poly_bb_p);
304 extern void debug_pdrs (poly_bb_p);
305 extern void debug_scop_context (scop_p);
306 extern void debug_scop (scop_p);
307 extern void print_scop_params (FILE *, scop_p);
308 extern void debug_scop_params (scop_p);
309 extern void print_iteration_domain (FILE *, poly_bb_p);
310 extern void print_iteration_domains (FILE *, scop_p);
311 extern void debug_iteration_domain (poly_bb_p);
312 extern void debug_iteration_domains (scop_p);
313 extern void print_isl_set (FILE *, isl_set *);
314 extern void print_isl_map (FILE *, isl_map *);
315 extern void print_isl_union_map (FILE *, isl_union_map *);
316 extern void print_isl_aff (FILE *, isl_aff *);
317 extern void print_isl_constraint (FILE *, isl_constraint *);
318 extern void print_isl_schedule (FILE *, isl_schedule *);
319 extern void debug_isl_schedule (isl_schedule *);
320 extern void print_isl_ast (FILE *, isl_ast_node *);
321 extern void debug_isl_ast (isl_ast_node *);
322 extern void debug_isl_set (isl_set *);
323 extern void debug_isl_map (isl_map *);
324 extern void debug_isl_union_map (isl_union_map *);
325 extern void debug_isl_aff (isl_aff *);
326 extern void debug_isl_constraint (isl_constraint *);
327 extern void debug_gmp_value (mpz_t);
328 extern void debug_scop_pbb (scop_p scop, int i);
329 extern void print_schedule_ast (FILE *, __isl_keep isl_schedule *, scop_p);
330 extern void debug_schedule_ast (__isl_keep isl_schedule *, scop_p);
331
332 /* The basic block of the PBB. */
333
334 static inline basic_block
335 pbb_bb (poly_bb_p pbb)
336 {
337 return GBB_BB (PBB_BLACK_BOX (pbb));
338 }
339
340 static inline int
341 pbb_index (poly_bb_p pbb)
342 {
343 return pbb_bb (pbb)->index;
344 }
345
346 /* The loop of the PBB. */
347
348 static inline loop_p
349 pbb_loop (poly_bb_p pbb)
350 {
351 return gbb_loop (PBB_BLACK_BOX (pbb));
352 }
353
354 /* The scop that contains the PDR. */
355
356 static inline scop_p
357 pdr_scop (poly_dr_p pdr)
358 {
359 return PBB_SCOP (PDR_PBB (pdr));
360 }
361
362 /* Set black box of PBB to BLACKBOX. */
363
364 static inline void
365 pbb_set_black_box (poly_bb_p pbb, gimple_poly_bb_p black_box)
366 {
367 pbb->black_box = black_box;
368 }
369
370 /* A helper structure to keep track of data references, polyhedral BBs, and
371 alias sets. */
372
373 struct dr_info
374 {
375 enum {
376 invalid_alias_set = -1
377 };
378 /* The data reference. */
379 data_reference_p dr;
380
381 /* The polyhedral BB containing this DR. */
382 poly_bb_p pbb;
383
384 /* ALIAS_SET is the SCC number assigned by a graph_dfs of the alias graph.
385 -1 is an invalid alias set. */
386 int alias_set;
387
388 /* Construct a DR_INFO from a data reference DR, an ALIAS_SET, and a PBB. */
389 dr_info (data_reference_p dr, poly_bb_p pbb,
390 int alias_set = invalid_alias_set)
391 : dr (dr), pbb (pbb), alias_set (alias_set) {}
392 };
393
394 /* A SCOP is a Static Control Part of the program, simple enough to be
395 represented in polyhedral form. */
396 struct scop
397 {
398 /* A SCOP is defined as a SESE region. */
399 sese_info_p scop_info;
400
401 /* Number of parameters in SCoP. */
402 graphite_dim_t nb_params;
403
404 /* All the basic blocks in this scop that contain memory references
405 and that will be represented as statements in the polyhedral
406 representation. */
407 vec<poly_bb_p> pbbs;
408
409 /* All the data references in this scop. */
410 vec<dr_info> drs;
411
412 /* The context describes known restrictions concerning the parameters
413 and relations in between the parameters.
414
415 void f (int8_t a, uint_16_t b) {
416 c = 2 a + b;
417 ...
418 }
419
420 Here we can add these restrictions to the context:
421
422 -128 >= a >= 127
423 0 >= b >= 65,535
424 c = 2a + b */
425 isl_set *param_context;
426
427 /* The context used internally by isl. */
428 isl_ctx *isl_context;
429
430 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
431 /* SCoP original schedule. */
432 isl_schedule *original_schedule;
433
434 /* SCoP transformed schedule. */
435 isl_schedule *transformed_schedule;
436 #else
437 /* SCoP final schedule. */
438 isl_schedule *schedule;
439 #endif
440
441 /* The data dependence relation among the data references in this scop. */
442 isl_union_map *dependence;
443 };
444
445 extern scop_p new_scop (edge, edge);
446 extern void free_scop (scop_p);
447 extern gimple_poly_bb_p new_gimple_poly_bb (basic_block, vec<data_reference_p>,
448 vec<scalar_use>, vec<tree>);
449 extern bool apply_poly_transforms (scop_p);
450
451 /* Set the region of SCOP to REGION. */
452
453 static inline void
454 scop_set_region (scop_p scop, sese_info_p region)
455 {
456 scop->scop_info = region;
457 }
458
459 /* Returns the number of parameters for SCOP. */
460
461 static inline graphite_dim_t
462 scop_nb_params (scop_p scop)
463 {
464 return scop->nb_params;
465 }
466
467 /* Set the number of params of SCOP to NB_PARAMS. */
468
469 static inline void
470 scop_set_nb_params (scop_p scop, graphite_dim_t nb_params)
471 {
472 scop->nb_params = nb_params;
473 }
474
475 #ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
476 extern void scop_get_dependences (scop_p scop);
477 #else
478 extern isl_union_map *scop_get_dependences (scop_p scop);
479 #endif
480
481 bool
482 carries_deps (__isl_keep isl_union_map *schedule,
483 __isl_keep isl_union_map *deps,
484 int depth);
485
486 extern bool build_poly_scop (scop_p);
487 extern bool graphite_regenerate_ast_isl (scop_p);
488 extern void build_scops (vec<scop_p> *);
489 extern void dot_all_sese (FILE *, vec<sese_l> &);
490 extern void dot_sese (sese_l &);
491 extern void dot_cfg ();
492
493 #endif
494