graphite.h 13.1 KB
Newer Older
Sebastian Pop committed
1
/* Graphite polyhedral representation.
2
   Copyright (C) 2009-2016 Free Software Foundation, Inc.
Sebastian Pop committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   Contributed by Sebastian Pop <sebastian.pop@amd.com> and
   Tobias Grosser <grosser@fim.uni-passau.de>.

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_GRAPHITE_POLY_H
#define GCC_GRAPHITE_POLY_H

25
#include "sese.h"
26 27 28 29 30 31 32 33 34 35 36
#include <isl/options.h>
#include <isl/ctx.h>
#include <isl/val_gmp.h>
#include <isl/set.h>
#include <isl/union_set.h>
#include <isl/map.h>
#include <isl/union_map.h>
#include <isl/aff.h>
#include <isl/constraint.h>
#include <isl/flow.h>
#include <isl/ilp.h>
37
#include <isl/schedule.h>
38
#include <isl/ast_build.h>
39

40 41 42 43 44 45
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
/* isl 0.15 or later.  */
#include <isl/schedule_node.h>

#else
/* isl 0.14 or 0.13.  */
46 47 48 49
# define isl_stat int
# define isl_stat_ok 0
#endif

Sebastian Pop committed
50 51 52 53 54 55
typedef struct poly_dr *poly_dr_p;

typedef struct poly_bb *poly_bb_p;

typedef struct scop *scop_p;

56
typedef unsigned graphite_dim_t;
Sebastian Pop committed
57 58 59 60 61

static inline graphite_dim_t scop_nb_params (scop_p);

/* A data reference can write or read some memory or we
   just know it may write some memory.  */
62
enum poly_dr_type
Sebastian Pop committed
63 64
{
  PDR_READ,
65 66
  /* PDR_MAY_READs are represented using PDR_READS.  This does not
     limit the expressiveness.  */
Sebastian Pop committed
67 68 69 70 71 72
  PDR_WRITE,
  PDR_MAY_WRITE
};

struct poly_dr
{
73 74 75
  /* An identifier for this PDR.  */
  int id;

76 77 78
  /* The number of data refs identical to this one in the PBB.  */
  int nb_refs;

79 80
  /* A pointer to the gimple stmt containing this reference.  */
  gimple *stmt;
Sebastian Pop committed
81 82 83 84

  /* A pointer to the PBB that contains this data reference.  */
  poly_bb_p pbb;

85
  enum poly_dr_type type;
Sebastian Pop committed
86 87 88 89 90 91

  /* The access polyhedron contains the polyhedral space this data
     reference will access.

     The polyhedron contains these dimensions:

92 93
     - The alias set (a):
     Every memory access is classified in at least one alias set.
Sebastian Pop committed
94

95 96
     - The subscripts (s_0, ..., s_n):
     The memory is accessed using zero or more subscript dimensions.
Sebastian Pop committed
97

98
     - The iteration domain (variables and parameters)
Sebastian Pop committed
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117

     Do not hardcode the dimensions.  Use the following accessor functions:
     - pdr_alias_set_dim
     - pdr_subscript_dim
     - pdr_iterator_dim
     - pdr_parameter_dim

     Example:

     | int A[1335][123];
     | int *p = malloc ();
     |
     | k = ...
     | for i
     |   {
     |     if (unknown_function ())
     |       p = A;
     |       ... = p[?][?];
     | 	   for j
Sebastian Pop committed
118
     |       A[i][j+k] = m;
Sebastian Pop committed
119 120 121 122
     |   }

     The data access A[i][j+k] in alias set "5" is described like this:

Sebastian Pop committed
123
     | i   j   k   a  s0  s1   1
Sebastian Pop committed
124 125 126
     | 0   0   0   1   0   0  -5     =  0
     |-1   0   0   0   1   0   0     =  0
     | 0  -1  -1   0   0   1   0     =  0
127 128
     | 0   0   0   0   1   0   0     >= 0  # The last four lines describe the
     | 0   0   0   0   0   1   0     >= 0  # array size.
Sebastian Pop committed
129 130 131 132 133 134 135
     | 0   0   0   0  -1   0 1335    >= 0
     | 0   0   0   0   0  -1 123     >= 0

     The pointer "*p" in alias set "5" and "7" is described as a union of
     polyhedron:


Sebastian Pop committed
136
     | i   k   a  s0   1
Sebastian Pop committed
137 138 139 140 141
     | 0   0   1   0  -5   =  0
     | 0   0   0   1   0   >= 0

     "or"

Sebastian Pop committed
142
     | i   k   a  s0   1
Sebastian Pop committed
143 144 145 146 147 148 149 150 151
     | 0   0   1   0  -7   =  0
     | 0   0   0   1   0   >= 0

     "*p" accesses all of the object allocated with 'malloc'.

     The scalar data access "m" is represented as an array with zero subscript
     dimensions.

     | i   j   k   a   1
Riyadh Baghdadi committed
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
     | 0   0   0  -1   15  = 0

     The difference between the graphite internal format for access data and
     the OpenSop format is in the order of columns.
     Instead of having:

     | i   j   k   a  s0  s1   1
     | 0   0   0   1   0   0  -5     =  0
     |-1   0   0   0   1   0   0     =  0
     | 0  -1  -1   0   0   1   0     =  0
     | 0   0   0   0   1   0   0     >= 0  # The last four lines describe the
     | 0   0   0   0   0   1   0     >= 0  # array size.
     | 0   0   0   0  -1   0 1335    >= 0
     | 0   0   0   0   0  -1 123     >= 0

     In OpenScop we have:

     | a  s0  s1   i   j   k   1
     | 1   0   0   0   0   0  -5     =  0
     | 0   1   0  -1   0   0   0     =  0
     | 0   0   1   0  -1  -1   0     =  0
     | 0   1   0   0   0   0   0     >= 0  # The last four lines describe the
     | 0   0   1   0   0   0   0     >= 0  # array size.
     | 0  -1   0   0   0   0 1335    >= 0
     | 0   0  -1   0   0   0 123     >= 0

     The OpenScop access function is printed as follows:

     | 1  # The number of disjunct components in a union of access functions.
     | R C O I L P  # Described bellow.
     | a  s0  s1   i   j   k   1
     | 1   0   0   0   0   0  -5     =  0
     | 0   1   0  -1   0   0   0     =  0
     | 0   0   1   0  -1  -1   0     =  0
     | 0   1   0   0   0   0   0     >= 0  # The last four lines describe the
     | 0   0   1   0   0   0   0     >= 0  # array size.
     | 0  -1   0   0   0   0 1335    >= 0
     | 0   0  -1   0   0   0 123     >= 0

     Where:
     - R: Number of rows.
     - C: Number of columns.
     - O: Number of output dimensions = alias set + number of subscripts.
     - I: Number of input dimensions (iterators).
     - L: Number of local (existentially quantified) dimensions.
     - P: Number of parameters.

     In the example, the vector "R C O I L P" is "7 7 3 2 0 1".  */
200
  isl_map *accesses;
Aditya Kumar committed
201
  isl_set *subscript_sizes;
Sebastian Pop committed
202 203
};

204
#define PDR_ID(PDR) (PDR->id)
205
#define PDR_NB_REFS(PDR) (PDR->nb_refs)
Sebastian Pop committed
206 207
#define PDR_PBB(PDR) (PDR->pbb)
#define PDR_TYPE(PDR) (PDR->type)
208
#define PDR_ACCESSES(PDR) (NULL)
Sebastian Pop committed
209

210 211
void new_poly_dr (poly_bb_p, gimple *, enum poly_dr_type,
		  isl_map *, isl_set *);
212 213
void debug_pdr (poly_dr_p);
void print_pdr (FILE *, poly_dr_p);
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

static inline bool
pdr_read_p (poly_dr_p pdr)
{
  return PDR_TYPE (pdr) == PDR_READ;
}

/* Returns true when PDR is a "write".  */

static inline bool
pdr_write_p (poly_dr_p pdr)
{
  return PDR_TYPE (pdr) == PDR_WRITE;
}

/* Returns true when PDR is a "may write".  */

static inline bool
pdr_may_write_p (poly_dr_p pdr)
{
  return PDR_TYPE (pdr) == PDR_MAY_WRITE;
}

Sebastian Pop committed
237 238 239 240
/* POLY_BB represents a blackbox in the polyhedral model.  */

struct poly_bb
{
241
  /* Pointer to a basic block or a statement in the compiler.  */
242
  gimple_poly_bb_p black_box;
Sebastian Pop committed
243

244
  /* Pointer to the SCOP containing this PBB.  */
Sebastian Pop committed
245 246
  scop_p scop;

247 248 249
  /* The iteration domain of this bb.  The layout of this polyhedron
     is I|G with I the iteration domain, G the context parameters.

Sebastian Pop committed
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
     Example:

     for (i = a - 7*b + 8; i <= 3*a + 13*b + 20; i++)
       for (j = 2; j <= 2*i + 5; j++)
         for (k = 0; k <= 5; k++)
           S (i,j,k)

     Loop iterators: i, j, k
     Parameters: a, b

     | i >=  a -  7b +  8
     | i <= 3a + 13b + 20
     | j >= 2
     | j <= 2i + 5
     | k >= 0
     | k <= 5

     The number of variables in the DOMAIN may change and is not
     related to the number of loops in the original code.  */
269
  isl_set *domain;
270 271 272
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
  isl_set *iterators;
#else
273
  /* The original scattering.  */
274
  isl_map *schedule;
Sebastian Pop committed
275

276
  /* The transformed scattering.  */
277
  isl_map *transformed;
Sebastian Pop committed
278

279
  /* A copy of the transformed scattering.  */
280
  isl_map *saved;
281 282 283 284
#endif

  /* The data references we access.  */
  vec<poly_dr_p> drs;
285

286 287
  /* The last basic block generated for this pbb.  */
  basic_block new_bb;
Sebastian Pop committed
288 289
};

290
#define PBB_BLACK_BOX(PBB) ((gimple_poly_bb_p) PBB->black_box)
Sebastian Pop committed
291 292 293
#define PBB_SCOP(PBB) (PBB->scop)
#define PBB_DRS(PBB) (PBB->drs)

294
extern poly_bb_p new_poly_bb (scop_p, gimple_poly_bb_p);
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
extern void print_pbb_domain (FILE *, poly_bb_p);
extern void print_pbb (FILE *, poly_bb_p);
extern void print_scop_context (FILE *, scop_p);
extern void print_scop (FILE *, scop_p);
extern void debug_pbb_domain (poly_bb_p);
extern void debug_pbb (poly_bb_p);
extern void print_pdrs (FILE *, poly_bb_p);
extern void debug_pdrs (poly_bb_p);
extern void debug_scop_context (scop_p);
extern void debug_scop (scop_p);
extern void print_scop_params (FILE *, scop_p);
extern void debug_scop_params (scop_p);
extern void print_iteration_domain (FILE *, poly_bb_p);
extern void print_iteration_domains (FILE *, scop_p);
extern void debug_iteration_domain (poly_bb_p);
extern void debug_iteration_domains (scop_p);
311 312
extern void print_isl_set (FILE *, isl_set *);
extern void print_isl_map (FILE *, isl_map *);
313
extern void print_isl_union_map (FILE *, isl_union_map *);
314 315
extern void print_isl_aff (FILE *, isl_aff *);
extern void print_isl_constraint (FILE *, isl_constraint *);
316 317 318 319
extern void print_isl_schedule (FILE *, isl_schedule *);
extern void debug_isl_schedule (isl_schedule *);
extern void print_isl_ast (FILE *, isl_ast_node *);
extern void debug_isl_ast (isl_ast_node *);
320 321
extern void debug_isl_set (isl_set *);
extern void debug_isl_map (isl_map *);
322
extern void debug_isl_union_map (isl_union_map *);
323 324 325
extern void debug_isl_aff (isl_aff *);
extern void debug_isl_constraint (isl_constraint *);
extern void debug_gmp_value (mpz_t);
326 327 328
extern void debug_scop_pbb (scop_p scop, int i);
extern void print_schedule_ast (FILE *, __isl_keep isl_schedule *, scop_p);
extern void debug_schedule_ast (__isl_keep isl_schedule *, scop_p);
Sebastian Pop committed
329

330
/* The basic block of the PBB.  */
331

332 333 334 335 336 337
static inline basic_block
pbb_bb (poly_bb_p pbb)
{
  return GBB_BB (PBB_BLACK_BOX (pbb));
}

338 339 340
static inline int
pbb_index (poly_bb_p pbb)
{
341
  return pbb_bb (pbb)->index;
342 343
}

344 345 346 347 348 349 350 351
/* The loop of the PBB.  */

static inline loop_p
pbb_loop (poly_bb_p pbb)
{
  return gbb_loop (PBB_BLACK_BOX (pbb));
}

Sebastian Pop committed
352 353
/* The scop that contains the PDR.  */

354 355
static inline scop_p
pdr_scop (poly_dr_p pdr)
Sebastian Pop committed
356 357 358 359 360 361 362
{
  return PBB_SCOP (PDR_PBB (pdr));
}

/* Set black box of PBB to BLACKBOX.  */

static inline void
363
pbb_set_black_box (poly_bb_p pbb, gimple_poly_bb_p black_box)
Sebastian Pop committed
364 365 366 367
{
  pbb->black_box = black_box;
}

368 369 370 371 372
/* A helper structure to keep track of data references, polyhedral BBs, and
   alias sets.  */

struct dr_info
{
373 374 375
  enum {
    invalid_alias_set = -1
  };
376 377 378 379 380 381
  /* The data reference.  */
  data_reference_p dr;

  /* The polyhedral BB containing this DR.  */
  poly_bb_p pbb;

382 383 384 385
  /* ALIAS_SET is the SCC number assigned by a graph_dfs of the alias graph.
     -1 is an invalid alias set.  */
  int alias_set;

386
  /* Construct a DR_INFO from a data reference DR, an ALIAS_SET, and a PBB.  */
387 388 389
  dr_info (data_reference_p dr, poly_bb_p pbb,
	   int alias_set = invalid_alias_set)
    : dr (dr), pbb (pbb), alias_set (alias_set) {}
390 391
};

Sebastian Pop committed
392 393 394 395 396
/* A SCOP is a Static Control Part of the program, simple enough to be
   represented in polyhedral form.  */
struct scop
{
  /* A SCOP is defined as a SESE region.  */
397
  sese_info_p scop_info;
Sebastian Pop committed
398 399 400 401 402 403 404

  /* Number of parameters in SCoP.  */
  graphite_dim_t nb_params;

  /* All the basic blocks in this scop that contain memory references
     and that will be represented as statements in the polyhedral
     representation.  */
405
  vec<poly_bb_p> pbbs;
Sebastian Pop committed
406

407 408 409
  /* All the data references in this scop.  */
  vec<dr_info> drs;

Sebastian Pop committed
410 411 412 413 414 415 416 417 418 419 420 421 422
  /* The context describes known restrictions concerning the parameters
     and relations in between the parameters.

  void f (int8_t a, uint_16_t b) {
    c = 2 a + b;
    ...
  }

  Here we can add these restrictions to the context:

  -128 >= a >= 127
     0 >= b >= 65,535
     c = 2a + b  */
423
  isl_set *param_context;
424

Sebastian Pop committed
425
  /* The context used internally by isl.  */
426
  isl_ctx *isl_context;
427

428 429 430 431 432 433 434
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
  /* SCoP original schedule.  */
  isl_schedule *original_schedule;

  /* SCoP transformed schedule.  */
  isl_schedule *transformed_schedule;
#else
435 436
  /* SCoP final schedule.  */
  isl_schedule *schedule;
437
#endif
438

439 440
  /* The data dependence relation among the data references in this scop.  */
  isl_union_map *dependence;
Sebastian Pop committed
441 442
};

443
extern scop_p new_scop (edge, edge);
Sebastian Pop committed
444
extern void free_scop (scop_p);
445 446
extern gimple_poly_bb_p new_gimple_poly_bb (basic_block, vec<data_reference_p>,
					    vec<scalar_use>, vec<tree>);
Sebastian Pop committed
447 448 449 450 451
extern bool apply_poly_transforms (scop_p);

/* Set the region of SCOP to REGION.  */

static inline void
452
scop_set_region (scop_p scop, sese_info_p region)
Sebastian Pop committed
453
{
454
  scop->scop_info = region;
Sebastian Pop committed
455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
}

/* Returns the number of parameters for SCOP.  */

static inline graphite_dim_t
scop_nb_params (scop_p scop)
{
  return scop->nb_params;
}

/* Set the number of params of SCOP to NB_PARAMS.  */

static inline void
scop_set_nb_params (scop_p scop, graphite_dim_t nb_params)
{
  scop->nb_params = nb_params;
}

473 474 475 476 477
#ifdef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
extern void scop_get_dependences (scop_p scop);
#else
extern isl_union_map *scop_get_dependences (scop_p scop);
#endif
478 479 480 481 482 483

bool
carries_deps (__isl_keep isl_union_map *schedule,
	      __isl_keep isl_union_map *deps,
	      int depth);

484 485 486
extern bool build_poly_scop (scop_p);
extern bool graphite_regenerate_ast_isl (scop_p);
extern void build_scops (vec<scop_p> *);
487 488 489
extern void dot_all_sese (FILE *, vec<sese_l> &);
extern void dot_sese (sese_l &);
extern void dot_cfg ();
490

Sebastian Pop committed
491
#endif