graphite-poly.h 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567
  1. /* Graphite polyhedral representation.
  2. Copyright (C) 2009-2015 Free Software Foundation, Inc.
  3. Contributed by Sebastian Pop <sebastian.pop@amd.com> and
  4. Tobias Grosser <grosser@fim.uni-passau.de>.
  5. This file is part of GCC.
  6. GCC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 3, or (at your option)
  9. any later version.
  10. GCC is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with GCC; see the file COPYING3. If not see
  16. <http://www.gnu.org/licenses/>. */
  17. #ifndef GCC_GRAPHITE_POLY_H
  18. #define GCC_GRAPHITE_POLY_H
  19. #ifndef HAVE_ISL_OPTIONS_SET_SCHEDULE_SERIALIZE_SCCS
  20. # define isl_stat int
  21. # define isl_stat_ok 0
  22. #endif
  23. typedef struct poly_dr *poly_dr_p;
  24. typedef struct poly_bb *poly_bb_p;
  25. typedef struct scop *scop_p;
  26. typedef unsigned graphite_dim_t;
  27. static inline graphite_dim_t pbb_dim_iter_domain (const struct poly_bb *);
  28. static inline graphite_dim_t pbb_nb_params (const struct poly_bb *);
  29. static inline graphite_dim_t scop_nb_params (scop_p);
  30. /* A data reference can write or read some memory or we
  31. just know it may write some memory. */
  32. enum poly_dr_type
  33. {
  34. PDR_READ,
  35. /* PDR_MAY_READs are represented using PDR_READS. This does not
  36. limit the expressiveness. */
  37. PDR_WRITE,
  38. PDR_MAY_WRITE
  39. };
  40. struct poly_dr
  41. {
  42. /* An identifier for this PDR. */
  43. int id;
  44. /* The number of data refs identical to this one in the PBB. */
  45. int nb_refs;
  46. /* A pointer to compiler's data reference description. */
  47. void *compiler_dr;
  48. /* A pointer to the PBB that contains this data reference. */
  49. poly_bb_p pbb;
  50. enum poly_dr_type type;
  51. /* The access polyhedron contains the polyhedral space this data
  52. reference will access.
  53. The polyhedron contains these dimensions:
  54. - The alias set (a):
  55. Every memory access is classified in at least one alias set.
  56. - The subscripts (s_0, ..., s_n):
  57. The memory is accessed using zero or more subscript dimensions.
  58. - The iteration domain (variables and parameters)
  59. Do not hardcode the dimensions. Use the following accessor functions:
  60. - pdr_alias_set_dim
  61. - pdr_subscript_dim
  62. - pdr_iterator_dim
  63. - pdr_parameter_dim
  64. Example:
  65. | int A[1335][123];
  66. | int *p = malloc ();
  67. |
  68. | k = ...
  69. | for i
  70. | {
  71. | if (unknown_function ())
  72. | p = A;
  73. | ... = p[?][?];
  74. | for j
  75. | A[i][j+k] = m;
  76. | }
  77. The data access A[i][j+k] in alias set "5" is described like this:
  78. | i j k a s0 s1 1
  79. | 0 0 0 1 0 0 -5 = 0
  80. |-1 0 0 0 1 0 0 = 0
  81. | 0 -1 -1 0 0 1 0 = 0
  82. | 0 0 0 0 1 0 0 >= 0 # The last four lines describe the
  83. | 0 0 0 0 0 1 0 >= 0 # array size.
  84. | 0 0 0 0 -1 0 1335 >= 0
  85. | 0 0 0 0 0 -1 123 >= 0
  86. The pointer "*p" in alias set "5" and "7" is described as a union of
  87. polyhedron:
  88. | i k a s0 1
  89. | 0 0 1 0 -5 = 0
  90. | 0 0 0 1 0 >= 0
  91. "or"
  92. | i k a s0 1
  93. | 0 0 1 0 -7 = 0
  94. | 0 0 0 1 0 >= 0
  95. "*p" accesses all of the object allocated with 'malloc'.
  96. The scalar data access "m" is represented as an array with zero subscript
  97. dimensions.
  98. | i j k a 1
  99. | 0 0 0 -1 15 = 0
  100. The difference between the graphite internal format for access data and
  101. the OpenSop format is in the order of columns.
  102. Instead of having:
  103. | i j k a s0 s1 1
  104. | 0 0 0 1 0 0 -5 = 0
  105. |-1 0 0 0 1 0 0 = 0
  106. | 0 -1 -1 0 0 1 0 = 0
  107. | 0 0 0 0 1 0 0 >= 0 # The last four lines describe the
  108. | 0 0 0 0 0 1 0 >= 0 # array size.
  109. | 0 0 0 0 -1 0 1335 >= 0
  110. | 0 0 0 0 0 -1 123 >= 0
  111. In OpenScop we have:
  112. | a s0 s1 i j k 1
  113. | 1 0 0 0 0 0 -5 = 0
  114. | 0 1 0 -1 0 0 0 = 0
  115. | 0 0 1 0 -1 -1 0 = 0
  116. | 0 1 0 0 0 0 0 >= 0 # The last four lines describe the
  117. | 0 0 1 0 0 0 0 >= 0 # array size.
  118. | 0 -1 0 0 0 0 1335 >= 0
  119. | 0 0 -1 0 0 0 123 >= 0
  120. The OpenScop access function is printed as follows:
  121. | 1 # The number of disjunct components in a union of access functions.
  122. | R C O I L P # Described bellow.
  123. | a s0 s1 i j k 1
  124. | 1 0 0 0 0 0 -5 = 0
  125. | 0 1 0 -1 0 0 0 = 0
  126. | 0 0 1 0 -1 -1 0 = 0
  127. | 0 1 0 0 0 0 0 >= 0 # The last four lines describe the
  128. | 0 0 1 0 0 0 0 >= 0 # array size.
  129. | 0 -1 0 0 0 0 1335 >= 0
  130. | 0 0 -1 0 0 0 123 >= 0
  131. Where:
  132. - R: Number of rows.
  133. - C: Number of columns.
  134. - O: Number of output dimensions = alias set + number of subscripts.
  135. - I: Number of input dimensions (iterators).
  136. - L: Number of local (existentially quantified) dimensions.
  137. - P: Number of parameters.
  138. In the example, the vector "R C O I L P" is "7 7 3 2 0 1". */
  139. isl_map *accesses;
  140. isl_set *extent;
  141. /* Data reference's base object set number, we must assure 2 pdrs are in the
  142. same base object set before dependency checking. */
  143. int dr_base_object_set;
  144. /* The number of subscripts. */
  145. graphite_dim_t nb_subscripts;
  146. };
  147. #define PDR_ID(PDR) (PDR->id)
  148. #define PDR_NB_REFS(PDR) (PDR->nb_refs)
  149. #define PDR_CDR(PDR) (PDR->compiler_dr)
  150. #define PDR_PBB(PDR) (PDR->pbb)
  151. #define PDR_TYPE(PDR) (PDR->type)
  152. #define PDR_ACCESSES(PDR) (NULL)
  153. #define PDR_BASE_OBJECT_SET(PDR) (PDR->dr_base_object_set)
  154. #define PDR_NB_SUBSCRIPTS(PDR) (PDR->nb_subscripts)
  155. void new_poly_dr (poly_bb_p, int, enum poly_dr_type, void *,
  156. graphite_dim_t, isl_map *, isl_set *);
  157. void free_poly_dr (poly_dr_p);
  158. void debug_pdr (poly_dr_p, int);
  159. void print_pdr (FILE *, poly_dr_p, int);
  160. static inline scop_p pdr_scop (poly_dr_p pdr);
  161. /* The dimension of the iteration domain of the scop of PDR. */
  162. static inline graphite_dim_t
  163. pdr_dim_iter_domain (poly_dr_p pdr)
  164. {
  165. return pbb_dim_iter_domain (PDR_PBB (pdr));
  166. }
  167. /* The number of parameters of the scop of PDR. */
  168. static inline graphite_dim_t
  169. pdr_nb_params (poly_dr_p pdr)
  170. {
  171. return scop_nb_params (pdr_scop (pdr));
  172. }
  173. /* The dimension of the alias set in PDR. */
  174. static inline graphite_dim_t
  175. pdr_alias_set_dim (poly_dr_p pdr)
  176. {
  177. poly_bb_p pbb = PDR_PBB (pdr);
  178. return pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb);
  179. }
  180. /* The dimension in PDR containing subscript S. */
  181. static inline graphite_dim_t
  182. pdr_subscript_dim (poly_dr_p pdr, graphite_dim_t s)
  183. {
  184. poly_bb_p pbb = PDR_PBB (pdr);
  185. return pbb_dim_iter_domain (pbb) + pbb_nb_params (pbb) + 1 + s;
  186. }
  187. /* The dimension in PDR containing the loop iterator ITER. */
  188. static inline graphite_dim_t
  189. pdr_iterator_dim (poly_dr_p pdr ATTRIBUTE_UNUSED, graphite_dim_t iter)
  190. {
  191. return iter;
  192. }
  193. /* The dimension in PDR containing parameter PARAM. */
  194. static inline graphite_dim_t
  195. pdr_parameter_dim (poly_dr_p pdr, graphite_dim_t param)
  196. {
  197. poly_bb_p pbb = PDR_PBB (pdr);
  198. return pbb_dim_iter_domain (pbb) + param;
  199. }
  200. /* Returns true when PDR is a "read". */
  201. static inline bool
  202. pdr_read_p (poly_dr_p pdr)
  203. {
  204. return PDR_TYPE (pdr) == PDR_READ;
  205. }
  206. /* Returns true when PDR is a "write". */
  207. static inline bool
  208. pdr_write_p (poly_dr_p pdr)
  209. {
  210. return PDR_TYPE (pdr) == PDR_WRITE;
  211. }
  212. /* Returns true when PDR is a "may write". */
  213. static inline bool
  214. pdr_may_write_p (poly_dr_p pdr)
  215. {
  216. return PDR_TYPE (pdr) == PDR_MAY_WRITE;
  217. }
  218. /* Return true when PDR1 and PDR2 are similar data accesses: they have
  219. the same base array, and the same access functions. */
  220. static inline bool
  221. same_pdr_p (poly_dr_p pdr1, poly_dr_p pdr2)
  222. {
  223. return PDR_NB_SUBSCRIPTS (pdr1) == PDR_NB_SUBSCRIPTS (pdr2)
  224. && PDR_BASE_OBJECT_SET (pdr1) == PDR_BASE_OBJECT_SET (pdr2);
  225. }
  226. typedef struct poly_scattering *poly_scattering_p;
  227. struct poly_scattering
  228. {
  229. /* The number of local variables. */
  230. int nb_local_variables;
  231. /* The number of scattering dimensions. */
  232. int nb_scattering;
  233. };
  234. /* POLY_BB represents a blackbox in the polyhedral model. */
  235. struct poly_bb
  236. {
  237. /* Pointer to a basic block or a statement in the compiler. */
  238. void *black_box;
  239. /* Pointer to the SCOP containing this PBB. */
  240. scop_p scop;
  241. /* The iteration domain of this bb. The layout of this polyhedron
  242. is I|G with I the iteration domain, G the context parameters.
  243. Example:
  244. for (i = a - 7*b + 8; i <= 3*a + 13*b + 20; i++)
  245. for (j = 2; j <= 2*i + 5; j++)
  246. for (k = 0; k <= 5; k++)
  247. S (i,j,k)
  248. Loop iterators: i, j, k
  249. Parameters: a, b
  250. | i >= a - 7b + 8
  251. | i <= 3a + 13b + 20
  252. | j >= 2
  253. | j <= 2i + 5
  254. | k >= 0
  255. | k <= 5
  256. The number of variables in the DOMAIN may change and is not
  257. related to the number of loops in the original code. */
  258. isl_set *domain;
  259. /* The data references we access. */
  260. vec<poly_dr_p> drs;
  261. /* The original scattering. */
  262. poly_scattering_p _original;
  263. isl_map *schedule;
  264. /* The transformed scattering. */
  265. poly_scattering_p _transformed;
  266. isl_map *transformed;
  267. /* A copy of the transformed scattering. */
  268. poly_scattering_p _saved;
  269. isl_map *saved;
  270. /* For tiling, the map for computing the separating class. */
  271. isl_map *map_sepclass;
  272. /* True when this PBB contains only a reduction statement. */
  273. bool is_reduction;
  274. };
  275. #define PBB_BLACK_BOX(PBB) ((gimple_bb_p) PBB->black_box)
  276. #define PBB_SCOP(PBB) (PBB->scop)
  277. #define PBB_DOMAIN(PBB) (NULL)
  278. #define PBB_DRS(PBB) (PBB->drs)
  279. #define PBB_ORIGINAL(PBB) (PBB->_original)
  280. #define PBB_ORIGINAL_SCATTERING(PBB) (NULL)
  281. #define PBB_TRANSFORMED(PBB) (PBB->_transformed)
  282. #define PBB_TRANSFORMED_SCATTERING(PBB) (NULL)
  283. #define PBB_SAVED(PBB) (PBB->_saved)
  284. /* XXX isl if we ever need local vars in the scatter, we can't use the
  285. out dimension of transformed to count the scatterting transform dimension.
  286. */
  287. #define PBB_NB_LOCAL_VARIABLES(PBB) (0)
  288. #define PBB_NB_SCATTERING_TRANSFORM(PBB) (isl_map_n_out (PBB->transformed))
  289. #define PBB_IS_REDUCTION(PBB) (PBB->is_reduction)
  290. extern poly_bb_p new_poly_bb (scop_p, void *);
  291. extern void free_poly_bb (poly_bb_p);
  292. extern void debug_loop_vec (poly_bb_p);
  293. extern void schedule_to_scattering (poly_bb_p, int);
  294. extern void print_pbb_domain (FILE *, poly_bb_p, int);
  295. extern void print_pbb (FILE *, poly_bb_p, int);
  296. extern void print_scop_context (FILE *, scop_p, int);
  297. extern void print_scop (FILE *, scop_p, int);
  298. extern void debug_pbb_domain (poly_bb_p, int);
  299. extern void debug_pbb (poly_bb_p, int);
  300. extern void print_pdrs (FILE *, poly_bb_p, int);
  301. extern void debug_pdrs (poly_bb_p, int);
  302. extern void debug_scop_context (scop_p, int);
  303. extern void debug_scop (scop_p, int);
  304. extern void print_scop_params (FILE *, scop_p, int);
  305. extern void debug_scop_params (scop_p, int);
  306. extern void print_iteration_domain (FILE *, poly_bb_p, int);
  307. extern void print_iteration_domains (FILE *, scop_p, int);
  308. extern void debug_iteration_domain (poly_bb_p, int);
  309. extern void debug_iteration_domains (scop_p, int);
  310. extern void print_isl_set (FILE *, isl_set *);
  311. extern void print_isl_map (FILE *, isl_map *);
  312. extern void print_isl_aff (FILE *, isl_aff *);
  313. extern void print_isl_constraint (FILE *, isl_constraint *);
  314. extern void debug_isl_set (isl_set *);
  315. extern void debug_isl_map (isl_map *);
  316. extern void debug_isl_aff (isl_aff *);
  317. extern void debug_isl_constraint (isl_constraint *);
  318. extern int scop_do_interchange (scop_p);
  319. extern int scop_do_strip_mine (scop_p, int);
  320. extern bool scop_do_block (scop_p);
  321. extern bool flatten_all_loops (scop_p);
  322. extern bool optimize_isl (scop_p);
  323. extern void pbb_number_of_iterations_at_time (poly_bb_p, graphite_dim_t, mpz_t);
  324. extern void debug_gmp_value (mpz_t);
  325. /* Return the number of write data references in PBB. */
  326. static inline int
  327. number_of_write_pdrs (poly_bb_p pbb)
  328. {
  329. int res = 0;
  330. int i;
  331. poly_dr_p pdr;
  332. for (i = 0; PBB_DRS (pbb).iterate (i, &pdr); i++)
  333. if (PDR_TYPE (pdr) == PDR_WRITE)
  334. res++;
  335. return res;
  336. }
  337. /* Returns a gimple_bb from BB. */
  338. static inline gimple_bb_p
  339. gbb_from_bb (basic_block bb)
  340. {
  341. return (gimple_bb_p) bb->aux;
  342. }
  343. /* The poly_bb of the BB. */
  344. static inline poly_bb_p
  345. pbb_from_bb (basic_block bb)
  346. {
  347. return GBB_PBB (gbb_from_bb (bb));
  348. }
  349. /* The basic block of the PBB. */
  350. static inline basic_block
  351. pbb_bb (poly_bb_p pbb)
  352. {
  353. return GBB_BB (PBB_BLACK_BOX (pbb));
  354. }
  355. /* The index of the PBB. */
  356. static inline int
  357. pbb_index (poly_bb_p pbb)
  358. {
  359. return pbb_bb (pbb)->index;
  360. }
  361. /* The loop of the PBB. */
  362. static inline loop_p
  363. pbb_loop (poly_bb_p pbb)
  364. {
  365. return gbb_loop (PBB_BLACK_BOX (pbb));
  366. }
  367. /* The scop that contains the PDR. */
  368. static inline scop_p
  369. pdr_scop (poly_dr_p pdr)
  370. {
  371. return PBB_SCOP (PDR_PBB (pdr));
  372. }
  373. /* Set black box of PBB to BLACKBOX. */
  374. static inline void
  375. pbb_set_black_box (poly_bb_p pbb, void *black_box)
  376. {
  377. pbb->black_box = black_box;
  378. }
  379. /* The number of loops around PBB: the dimension of the iteration
  380. domain. */
  381. static inline graphite_dim_t
  382. pbb_dim_iter_domain (const struct poly_bb *pbb)
  383. {
  384. return isl_set_dim (pbb->domain, isl_dim_set);
  385. }
  386. /* The number of params defined in PBB. */
  387. static inline graphite_dim_t
  388. pbb_nb_params (const struct poly_bb *pbb)
  389. {
  390. scop_p scop = PBB_SCOP (pbb);
  391. return scop_nb_params (scop);
  392. }
  393. /* The number of scattering dimensions in the SCATTERING polyhedron
  394. of a PBB for a given SCOP. */
  395. static inline graphite_dim_t
  396. pbb_nb_scattering_orig (const struct poly_bb *pbb)
  397. {
  398. return 2 * pbb_dim_iter_domain (pbb) + 1;
  399. }
  400. /* The number of scattering dimensions in PBB. */
  401. static inline graphite_dim_t
  402. pbb_nb_scattering_transform (const struct poly_bb *pbb)
  403. {
  404. return PBB_NB_SCATTERING_TRANSFORM (pbb);
  405. }
  406. /* The number of dynamic scattering dimensions in PBB. */
  407. static inline graphite_dim_t
  408. pbb_nb_dynamic_scattering_transform (const struct poly_bb *pbb)
  409. {
  410. /* This function requires the 2d + 1 scattering format to be
  411. invariant during all transformations. */
  412. gcc_assert (PBB_NB_SCATTERING_TRANSFORM (pbb) % 2);
  413. return PBB_NB_SCATTERING_TRANSFORM (pbb) / 2;
  414. }
  415. /* Returns the number of local variables used in the transformed
  416. scattering polyhedron of PBB. */
  417. static inline graphite_dim_t
  418. pbb_nb_local_vars (const struct poly_bb *pbb ATTRIBUTE_UNUSED)
  419. {
  420. /* For now we do not have any local variables, as we do not do strip
  421. mining for example. */
  422. return PBB_NB_LOCAL_VARIABLES (pbb);
  423. }
  424. /* The dimension in the domain of PBB containing the iterator ITER. */
  425. static inline graphite_dim_t
  426. pbb_iterator_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t iter)
  427. {
  428. return iter;
  429. }
  430. /* The dimension in the domain of PBB containing the iterator ITER. */
  431. static inline graphite_dim_t
  432. pbb_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
  433. {
  434. return param
  435. + pbb_dim_iter_domain (pbb);
  436. }
  437. /* The dimension in the original scattering polyhedron of PBB
  438. containing the scattering iterator SCATTER. */
  439. static inline graphite_dim_t
  440. psco_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t scatter)
  441. {
  442. gcc_assert (scatter < pbb_nb_scattering_orig (pbb));
  443. return scatter;
  444. }
  445. /* The dimension in the transformed scattering polyhedron of PBB
  446. containing the scattering iterator SCATTER. */
  447. static inline graphite_dim_t
  448. psct_scattering_dim (poly_bb_p pbb ATTRIBUTE_UNUSED, graphite_dim_t scatter)
  449. {
  450. gcc_assert (scatter <= pbb_nb_scattering_transform (pbb));
  451. return scatter;
  452. }
  453. /* The dimension in the transformed scattering polyhedron of PBB of
  454. the local variable LV. */
  455. static inline graphite_dim_t
  456. psct_local_var_dim (poly_bb_p pbb, graphite_dim_t lv)
  457. {
  458. gcc_assert (lv <= pbb_nb_local_vars (pbb));
  459. return lv + pbb_nb_scattering_transform (pbb);
  460. }
  461. /* The dimension in the original scattering polyhedron of PBB
  462. containing the loop iterator ITER. */
  463. static inline graphite_dim_t
  464. psco_iterator_dim (poly_bb_p pbb, graphite_dim_t iter)
  465. {
  466. gcc_assert (iter < pbb_dim_iter_domain (pbb));
  467. return iter + pbb_nb_scattering_orig (pbb);
  468. }
  469. /* The dimension in the transformed scattering polyhedron of PBB
  470. containing the loop iterator ITER. */
  471. static inline graphite_dim_t
  472. psct_iterator_dim (poly_bb_p pbb, graphite_dim_t iter)
  473. {
  474. gcc_assert (iter < pbb_dim_iter_domain (pbb));
  475. return iter
  476. + pbb_nb_scattering_transform (pbb)
  477. + pbb_nb_local_vars (pbb);
  478. }
  479. /* The dimension in the original scattering polyhedron of PBB
  480. containing parameter PARAM. */
  481. static inline graphite_dim_t
  482. psco_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
  483. {
  484. gcc_assert (param < pbb_nb_params (pbb));
  485. return param
  486. + pbb_nb_scattering_orig (pbb)
  487. + pbb_dim_iter_domain (pbb);
  488. }
  489. /* The dimension in the transformed scattering polyhedron of PBB
  490. containing parameter PARAM. */
  491. static inline graphite_dim_t
  492. psct_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
  493. {
  494. gcc_assert (param < pbb_nb_params (pbb));
  495. return param
  496. + pbb_nb_scattering_transform (pbb)
  497. + pbb_nb_local_vars (pbb)
  498. + pbb_dim_iter_domain (pbb);
  499. }
  500. /* The scattering dimension of PBB corresponding to the dynamic level
  501. LEVEL. */
  502. static inline graphite_dim_t
  503. psct_dynamic_dim (poly_bb_p pbb, graphite_dim_t level)
  504. {
  505. graphite_dim_t result = 1 + 2 * level;
  506. gcc_assert (result < pbb_nb_scattering_transform (pbb));
  507. return result;
  508. }
  509. /* The scattering dimension of PBB corresponding to the static
  510. sequence of the loop level LEVEL. */
  511. static inline graphite_dim_t
  512. psct_static_dim (poly_bb_p pbb, graphite_dim_t level)
  513. {
  514. graphite_dim_t result = 2 * level;
  515. gcc_assert (result < pbb_nb_scattering_transform (pbb));
  516. return result;
  517. }
  518. /* Adds to the transformed scattering polyhedron of PBB a new local
  519. variable and returns its index. */
  520. static inline graphite_dim_t
  521. psct_add_local_variable (poly_bb_p pbb ATTRIBUTE_UNUSED)
  522. {
  523. gcc_unreachable ();
  524. return 0;
  525. }
  526. typedef struct lst *lst_p;
  527. /* Loops and Statements Tree. */
  528. struct lst {
  529. /* LOOP_P is true when an LST node is a loop. */
  530. bool loop_p;
  531. /* A pointer to the loop that contains this node. */
  532. lst_p loop_father;
  533. /* The sum of all the memory strides for an LST loop. */
  534. mpz_t memory_strides;
  535. /* Loop nodes contain a sequence SEQ of LST nodes, statements
  536. contain a pointer to their polyhedral representation PBB. */
  537. union {
  538. poly_bb_p pbb;
  539. vec<lst_p> seq;
  540. } node;
  541. };
  542. #define LST_LOOP_P(LST) ((LST)->loop_p)
  543. #define LST_LOOP_FATHER(LST) ((LST)->loop_father)
  544. #define LST_PBB(LST) ((LST)->node.pbb)
  545. #define LST_SEQ(LST) ((LST)->node.seq)
  546. #define LST_LOOP_MEMORY_STRIDES(LST) ((LST)->memory_strides)
  547. void scop_to_lst (scop_p);
  548. void print_lst (FILE *, lst_p, int);
  549. void debug_lst (lst_p);
  550. void dot_lst (lst_p);
  551. /* Creates a new LST loop with SEQ. */
  552. static inline lst_p
  553. new_lst_loop (vec<lst_p> seq)
  554. {
  555. lst_p lst = XNEW (struct lst);
  556. int i;
  557. lst_p l;
  558. LST_LOOP_P (lst) = true;
  559. LST_SEQ (lst) = seq;
  560. LST_LOOP_FATHER (lst) = NULL;
  561. mpz_init (LST_LOOP_MEMORY_STRIDES (lst));
  562. mpz_set_si (LST_LOOP_MEMORY_STRIDES (lst), -1);
  563. for (i = 0; seq.iterate (i, &l); i++)
  564. LST_LOOP_FATHER (l) = lst;
  565. return lst;
  566. }
  567. /* Creates a new LST statement with PBB. */
  568. static inline lst_p
  569. new_lst_stmt (poly_bb_p pbb)
  570. {
  571. lst_p lst = XNEW (struct lst);
  572. LST_LOOP_P (lst) = false;
  573. LST_PBB (lst) = pbb;
  574. LST_LOOP_FATHER (lst) = NULL;
  575. return lst;
  576. }
  577. /* Frees the memory used by LST. */
  578. static inline void
  579. free_lst (lst_p lst)
  580. {
  581. if (!lst)
  582. return;
  583. if (LST_LOOP_P (lst))
  584. {
  585. int i;
  586. lst_p l;
  587. for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
  588. free_lst (l);
  589. mpz_clear (LST_LOOP_MEMORY_STRIDES (lst));
  590. LST_SEQ (lst).release ();
  591. }
  592. free (lst);
  593. }
  594. /* Returns a copy of LST. */
  595. static inline lst_p
  596. copy_lst (lst_p lst)
  597. {
  598. if (!lst)
  599. return NULL;
  600. if (LST_LOOP_P (lst))
  601. {
  602. int i;
  603. lst_p l;
  604. vec<lst_p> seq;
  605. seq.create (5);
  606. for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
  607. seq.safe_push (copy_lst (l));
  608. return new_lst_loop (seq);
  609. }
  610. return new_lst_stmt (LST_PBB (lst));
  611. }
  612. /* Adds a new loop under the loop LST. */
  613. static inline void
  614. lst_add_loop_under_loop (lst_p lst)
  615. {
  616. vec<lst_p> seq;
  617. seq.create (1);
  618. lst_p l = new_lst_loop (LST_SEQ (lst));
  619. gcc_assert (LST_LOOP_P (lst));
  620. LST_LOOP_FATHER (l) = lst;
  621. seq.quick_push (l);
  622. LST_SEQ (lst) = seq;
  623. }
  624. /* Returns the loop depth of LST. */
  625. static inline int
  626. lst_depth (lst_p lst)
  627. {
  628. if (!lst)
  629. return -2;
  630. /* The depth of the outermost "fake" loop is -1. This outermost
  631. loop does not have a loop father and it is just a container, as
  632. in the loop representation of GCC. */
  633. if (!LST_LOOP_FATHER (lst))
  634. return -1;
  635. return lst_depth (LST_LOOP_FATHER (lst)) + 1;
  636. }
  637. /* Returns the Dewey number for LST. */
  638. static inline int
  639. lst_dewey_number (lst_p lst)
  640. {
  641. int i;
  642. lst_p l;
  643. if (!lst)
  644. return -1;
  645. if (!LST_LOOP_FATHER (lst))
  646. return 0;
  647. FOR_EACH_VEC_ELT (LST_SEQ (LST_LOOP_FATHER (lst)), i, l)
  648. if (l == lst)
  649. return i;
  650. return -1;
  651. }
  652. /* Returns the Dewey number of LST at depth DEPTH. */
  653. static inline int
  654. lst_dewey_number_at_depth (lst_p lst, int depth)
  655. {
  656. gcc_assert (lst && depth >= 0 && lst_depth (lst) <= depth);
  657. if (lst_depth (lst) == depth)
  658. return lst_dewey_number (lst);
  659. return lst_dewey_number_at_depth (LST_LOOP_FATHER (lst), depth);
  660. }
  661. /* Returns the predecessor of LST in the sequence of its loop father.
  662. Returns NULL if LST is the first statement in the sequence. */
  663. static inline lst_p
  664. lst_pred (lst_p lst)
  665. {
  666. int dewey;
  667. lst_p father;
  668. if (!lst || !LST_LOOP_FATHER (lst))
  669. return NULL;
  670. dewey = lst_dewey_number (lst);
  671. if (dewey == 0)
  672. return NULL;
  673. father = LST_LOOP_FATHER (lst);
  674. return LST_SEQ (father)[dewey - 1];
  675. }
  676. /* Returns the successor of LST in the sequence of its loop father.
  677. Returns NULL if there is none. */
  678. static inline lst_p
  679. lst_succ (lst_p lst)
  680. {
  681. int dewey;
  682. lst_p father;
  683. if (!lst || !LST_LOOP_FATHER (lst))
  684. return NULL;
  685. dewey = lst_dewey_number (lst);
  686. father = LST_LOOP_FATHER (lst);
  687. if (LST_SEQ (father).length () == (unsigned) dewey + 1)
  688. return NULL;
  689. return LST_SEQ (father)[dewey + 1];
  690. }
  691. /* Return the LST node corresponding to PBB. */
  692. static inline lst_p
  693. lst_find_pbb (lst_p lst, poly_bb_p pbb)
  694. {
  695. int i;
  696. lst_p l;
  697. if (!lst)
  698. return NULL;
  699. if (!LST_LOOP_P (lst))
  700. return (pbb == LST_PBB (lst)) ? lst : NULL;
  701. for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
  702. {
  703. lst_p res = lst_find_pbb (l, pbb);
  704. if (res)
  705. return res;
  706. }
  707. return NULL;
  708. }
  709. /* Return the LST node corresponding to the loop around STMT at depth
  710. LOOP_DEPTH. */
  711. static inline lst_p
  712. find_lst_loop (lst_p stmt, int loop_depth)
  713. {
  714. lst_p loop = LST_LOOP_FATHER (stmt);
  715. gcc_assert (loop_depth >= 0);
  716. while (loop_depth < lst_depth (loop))
  717. loop = LST_LOOP_FATHER (loop);
  718. return loop;
  719. }
  720. /* Return the first LST representing a PBB statement in LST. */
  721. static inline lst_p
  722. lst_find_first_pbb (lst_p lst)
  723. {
  724. int i;
  725. lst_p l;
  726. if (!lst)
  727. return NULL;
  728. if (!LST_LOOP_P (lst))
  729. return lst;
  730. for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
  731. {
  732. lst_p res = lst_find_first_pbb (l);
  733. if (res)
  734. return res;
  735. }
  736. return NULL;
  737. }
  738. /* Returns true when LST is a loop that does not contain
  739. statements. */
  740. static inline bool
  741. lst_empty_p (lst_p lst)
  742. {
  743. return !lst_find_first_pbb (lst);
  744. }
  745. /* Return the last LST representing a PBB statement in LST. */
  746. static inline lst_p
  747. lst_find_last_pbb (lst_p lst)
  748. {
  749. int i;
  750. lst_p l, res = NULL;
  751. if (!lst)
  752. return NULL;
  753. if (!LST_LOOP_P (lst))
  754. return lst;
  755. for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
  756. {
  757. lst_p last = lst_find_last_pbb (l);
  758. if (last)
  759. res = last;
  760. }
  761. gcc_assert (res);
  762. return res;
  763. }
  764. /* Returns true if LOOP contains LST, in other words, if LST is nested
  765. in LOOP. */
  766. static inline bool
  767. lst_contains_p (lst_p loop, lst_p lst)
  768. {
  769. if (!loop || !lst || !LST_LOOP_P (loop))
  770. return false;
  771. if (loop == lst)
  772. return true;
  773. return lst_contains_p (loop, LST_LOOP_FATHER (lst));
  774. }
  775. /* Returns true if LOOP contains PBB, in other words, if PBB is nested
  776. in LOOP. */
  777. static inline bool
  778. lst_contains_pbb (lst_p loop, poly_bb_p pbb)
  779. {
  780. return lst_find_pbb (loop, pbb) ? true : false;
  781. }
  782. /* Creates a loop nest of depth NB_LOOPS containing LST. */
  783. static inline lst_p
  784. lst_create_nest (int nb_loops, lst_p lst)
  785. {
  786. lst_p res, loop;
  787. vec<lst_p> seq;
  788. if (nb_loops == 0)
  789. return lst;
  790. seq.create (1);
  791. loop = lst_create_nest (nb_loops - 1, lst);
  792. seq.quick_push (loop);
  793. res = new_lst_loop (seq);
  794. LST_LOOP_FATHER (loop) = res;
  795. return res;
  796. }
  797. /* Removes LST from the sequence of statements of its loop father. */
  798. static inline void
  799. lst_remove_from_sequence (lst_p lst)
  800. {
  801. lst_p father = LST_LOOP_FATHER (lst);
  802. int dewey = lst_dewey_number (lst);
  803. gcc_assert (lst && father && dewey >= 0);
  804. LST_SEQ (father).ordered_remove (dewey);
  805. LST_LOOP_FATHER (lst) = NULL;
  806. }
  807. /* Removes the loop LST and inline its body in the father loop. */
  808. static inline void
  809. lst_remove_loop_and_inline_stmts_in_loop_father (lst_p lst)
  810. {
  811. lst_p l, father = LST_LOOP_FATHER (lst);
  812. int i, dewey = lst_dewey_number (lst);
  813. gcc_assert (lst && father && dewey >= 0);
  814. LST_SEQ (father).ordered_remove (dewey);
  815. LST_LOOP_FATHER (lst) = NULL;
  816. FOR_EACH_VEC_ELT (LST_SEQ (lst), i, l)
  817. {
  818. LST_SEQ (father).safe_insert (dewey + i, l);
  819. LST_LOOP_FATHER (l) = father;
  820. }
  821. }
  822. /* Sets NITER to the upper bound approximation of the number of
  823. iterations of loop LST. */
  824. static inline void
  825. lst_niter_for_loop (lst_p lst, mpz_t niter)
  826. {
  827. int depth = lst_depth (lst);
  828. poly_bb_p pbb = LST_PBB (lst_find_first_pbb (lst));
  829. gcc_assert (LST_LOOP_P (lst));
  830. pbb_number_of_iterations_at_time (pbb, psct_dynamic_dim (pbb, depth), niter);
  831. }
  832. /* Updates the scattering of PBB to be at the DEWEY number in the loop
  833. at depth LEVEL. */
  834. static inline void
  835. pbb_update_scattering (poly_bb_p pbb, graphite_dim_t level, int dewey)
  836. {
  837. graphite_dim_t sched = psct_static_dim (pbb, level);
  838. isl_space *d = isl_map_get_space (pbb->transformed);
  839. isl_space *d1 = isl_space_range (d);
  840. unsigned i, n = isl_space_dim (d1, isl_dim_out);
  841. isl_space *d2 = isl_space_add_dims (d1, isl_dim_in, n);
  842. isl_map *x = isl_map_universe (d2);
  843. x = isl_map_fix_si (x, isl_dim_out, sched, dewey);
  844. for (i = 0; i < n; i++)
  845. if (i != sched)
  846. x = isl_map_equate (x, isl_dim_in, i, isl_dim_out, i);
  847. pbb->transformed = isl_map_apply_range (pbb->transformed, x);
  848. }
  849. /* Updates the scattering of all the PBBs under LST to be at the DEWEY
  850. number in the loop at depth LEVEL. */
  851. static inline void
  852. lst_update_scattering_under (lst_p lst, int level, int dewey)
  853. {
  854. int i;
  855. lst_p l;
  856. gcc_assert (lst && level >= 0 && dewey >= 0);
  857. if (LST_LOOP_P (lst))
  858. for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
  859. lst_update_scattering_under (l, level, dewey);
  860. else
  861. pbb_update_scattering (LST_PBB (lst), level, dewey);
  862. }
  863. /* Updates the all the scattering levels of all the PBBs under
  864. LST. */
  865. static inline void
  866. lst_update_scattering (lst_p lst)
  867. {
  868. int i;
  869. lst_p l;
  870. if (!lst)
  871. return;
  872. if (LST_LOOP_FATHER (lst))
  873. {
  874. lst_p father = LST_LOOP_FATHER (lst);
  875. int dewey = lst_dewey_number (lst);
  876. int level = lst_depth (lst);
  877. gcc_assert (lst && father && dewey >= 0 && level >= 0);
  878. for (i = dewey; LST_SEQ (father).iterate (i, &l); i++)
  879. lst_update_scattering_under (l, level, i);
  880. }
  881. if (LST_LOOP_P (lst))
  882. for (i = 0; LST_SEQ (lst).iterate (i, &l); i++)
  883. lst_update_scattering (l);
  884. }
  885. /* Inserts LST1 before LST2 if BEFORE is true; inserts LST1 after LST2
  886. if BEFORE is false. */
  887. static inline void
  888. lst_insert_in_sequence (lst_p lst1, lst_p lst2, bool before)
  889. {
  890. lst_p father;
  891. int dewey;
  892. /* Do not insert empty loops. */
  893. if (!lst1 || lst_empty_p (lst1))
  894. return;
  895. father = LST_LOOP_FATHER (lst2);
  896. dewey = lst_dewey_number (lst2);
  897. gcc_assert (lst2 && father && dewey >= 0);
  898. LST_SEQ (father).safe_insert (before ? dewey : dewey + 1, lst1);
  899. LST_LOOP_FATHER (lst1) = father;
  900. }
  901. /* Replaces LST1 with LST2. */
  902. static inline void
  903. lst_replace (lst_p lst1, lst_p lst2)
  904. {
  905. lst_p father;
  906. int dewey;
  907. if (!lst2 || lst_empty_p (lst2))
  908. return;
  909. father = LST_LOOP_FATHER (lst1);
  910. dewey = lst_dewey_number (lst1);
  911. LST_LOOP_FATHER (lst2) = father;
  912. LST_SEQ (father)[dewey] = lst2;
  913. }
  914. /* Returns a copy of ROOT where LST has been replaced by a copy of the
  915. LSTs A B C in this sequence. */
  916. static inline lst_p
  917. lst_substitute_3 (lst_p root, lst_p lst, lst_p a, lst_p b, lst_p c)
  918. {
  919. int i;
  920. lst_p l;
  921. vec<lst_p> seq;
  922. if (!root)
  923. return NULL;
  924. gcc_assert (lst && root != lst);
  925. if (!LST_LOOP_P (root))
  926. return new_lst_stmt (LST_PBB (root));
  927. seq.create (5);
  928. for (i = 0; LST_SEQ (root).iterate (i, &l); i++)
  929. if (l != lst)
  930. seq.safe_push (lst_substitute_3 (l, lst, a, b, c));
  931. else
  932. {
  933. if (!lst_empty_p (a))
  934. seq.safe_push (copy_lst (a));
  935. if (!lst_empty_p (b))
  936. seq.safe_push (copy_lst (b));
  937. if (!lst_empty_p (c))
  938. seq.safe_push (copy_lst (c));
  939. }
  940. return new_lst_loop (seq);
  941. }
  942. /* Moves LST before LOOP if BEFORE is true, and after the LOOP if
  943. BEFORE is false. */
  944. static inline void
  945. lst_distribute_lst (lst_p loop, lst_p lst, bool before)
  946. {
  947. int loop_depth = lst_depth (loop);
  948. int depth = lst_depth (lst);
  949. int nb_loops = depth - loop_depth;
  950. gcc_assert (lst && loop && LST_LOOP_P (loop) && nb_loops > 0);
  951. lst_remove_from_sequence (lst);
  952. lst_insert_in_sequence (lst_create_nest (nb_loops, lst), loop, before);
  953. }
  954. /* Removes from LOOP all the statements before/after and including PBB
  955. if BEFORE is true/false. Returns the negation of BEFORE when the
  956. statement PBB has been found. */
  957. static inline bool
  958. lst_remove_all_before_including_pbb (lst_p loop, poly_bb_p pbb, bool before)
  959. {
  960. int i;
  961. lst_p l;
  962. if (!loop || !LST_LOOP_P (loop))
  963. return before;
  964. for (i = 0; LST_SEQ (loop).iterate (i, &l);)
  965. if (LST_LOOP_P (l))
  966. {
  967. before = lst_remove_all_before_including_pbb (l, pbb, before);
  968. if (LST_SEQ (l).length () == 0)
  969. {
  970. LST_SEQ (loop).ordered_remove (i);
  971. free_lst (l);
  972. }
  973. else
  974. i++;
  975. }
  976. else
  977. {
  978. if (before)
  979. {
  980. if (LST_PBB (l) == pbb)
  981. before = false;
  982. LST_SEQ (loop).ordered_remove (i);
  983. free_lst (l);
  984. }
  985. else if (LST_PBB (l) == pbb)
  986. {
  987. before = true;
  988. LST_SEQ (loop).ordered_remove (i);
  989. free_lst (l);
  990. }
  991. else
  992. i++;
  993. }
  994. return before;
  995. }
  996. /* Removes from LOOP all the statements before/after and excluding PBB
  997. if BEFORE is true/false; Returns the negation of BEFORE when the
  998. statement PBB has been found. */
  999. static inline bool
  1000. lst_remove_all_before_excluding_pbb (lst_p loop, poly_bb_p pbb, bool before)
  1001. {
  1002. int i;
  1003. lst_p l;
  1004. if (!loop || !LST_LOOP_P (loop))
  1005. return before;
  1006. for (i = 0; LST_SEQ (loop).iterate (i, &l);)
  1007. if (LST_LOOP_P (l))
  1008. {
  1009. before = lst_remove_all_before_excluding_pbb (l, pbb, before);
  1010. if (LST_SEQ (l).length () == 0)
  1011. {
  1012. LST_SEQ (loop).ordered_remove (i);
  1013. free_lst (l);
  1014. continue;
  1015. }
  1016. i++;
  1017. }
  1018. else
  1019. {
  1020. if (before && LST_PBB (l) != pbb)
  1021. {
  1022. LST_SEQ (loop).ordered_remove (i);
  1023. free_lst (l);
  1024. continue;
  1025. }
  1026. i++;
  1027. if (LST_PBB (l) == pbb)
  1028. before = before ? false : true;
  1029. }
  1030. return before;
  1031. }
  1032. /* A SCOP is a Static Control Part of the program, simple enough to be
  1033. represented in polyhedral form. */
  1034. struct scop
  1035. {
  1036. /* A SCOP is defined as a SESE region. */
  1037. void *region;
  1038. /* Number of parameters in SCoP. */
  1039. graphite_dim_t nb_params;
  1040. /* All the basic blocks in this scop that contain memory references
  1041. and that will be represented as statements in the polyhedral
  1042. representation. */
  1043. vec<poly_bb_p> bbs;
  1044. /* Original, transformed and saved schedules. */
  1045. lst_p original_schedule, transformed_schedule, saved_schedule;
  1046. /* The context describes known restrictions concerning the parameters
  1047. and relations in between the parameters.
  1048. void f (int8_t a, uint_16_t b) {
  1049. c = 2 a + b;
  1050. ...
  1051. }
  1052. Here we can add these restrictions to the context:
  1053. -128 >= a >= 127
  1054. 0 >= b >= 65,535
  1055. c = 2a + b */
  1056. isl_set *context;
  1057. /* The context used internally by ISL. */
  1058. isl_ctx *ctx;
  1059. /* The original dependence relations:
  1060. RAW are read after write dependences,
  1061. WAR are write after read dependences,
  1062. WAW are write after write dependences. */
  1063. isl_union_map *must_raw, *may_raw, *must_raw_no_source, *may_raw_no_source,
  1064. *must_war, *may_war, *must_war_no_source, *may_war_no_source,
  1065. *must_waw, *may_waw, *must_waw_no_source, *may_waw_no_source;
  1066. /* True when the scop has been converted to its polyhedral
  1067. representation. */
  1068. bool poly_scop_p;
  1069. };
  1070. #define SCOP_BBS(S) (S->bbs)
  1071. #define SCOP_REGION(S) ((sese) S->region)
  1072. #define SCOP_CONTEXT(S) (NULL)
  1073. #define SCOP_ORIGINAL_SCHEDULE(S) (S->original_schedule)
  1074. #define SCOP_TRANSFORMED_SCHEDULE(S) (S->transformed_schedule)
  1075. #define SCOP_SAVED_SCHEDULE(S) (S->saved_schedule)
  1076. #define POLY_SCOP_P(S) (S->poly_scop_p)
  1077. extern scop_p new_scop (void *);
  1078. extern void free_scop (scop_p);
  1079. extern void free_scops (vec<scop_p> );
  1080. extern void print_generated_program (FILE *, scop_p);
  1081. extern void debug_generated_program (scop_p);
  1082. extern void print_scattering_function (FILE *, poly_bb_p, int);
  1083. extern void print_scattering_functions (FILE *, scop_p, int);
  1084. extern void debug_scattering_function (poly_bb_p, int);
  1085. extern void debug_scattering_functions (scop_p, int);
  1086. extern int scop_max_loop_depth (scop_p);
  1087. extern int unify_scattering_dimensions (scop_p);
  1088. extern bool apply_poly_transforms (scop_p);
  1089. extern bool graphite_legal_transform (scop_p);
  1090. /* Set the region of SCOP to REGION. */
  1091. static inline void
  1092. scop_set_region (scop_p scop, void *region)
  1093. {
  1094. scop->region = region;
  1095. }
  1096. /* Returns the number of parameters for SCOP. */
  1097. static inline graphite_dim_t
  1098. scop_nb_params (scop_p scop)
  1099. {
  1100. return scop->nb_params;
  1101. }
  1102. /* Set the number of params of SCOP to NB_PARAMS. */
  1103. static inline void
  1104. scop_set_nb_params (scop_p scop, graphite_dim_t nb_params)
  1105. {
  1106. scop->nb_params = nb_params;
  1107. }
  1108. /* Allocates a new empty poly_scattering structure. */
  1109. static inline poly_scattering_p
  1110. poly_scattering_new (void)
  1111. {
  1112. poly_scattering_p res = XNEW (struct poly_scattering);
  1113. res->nb_local_variables = 0;
  1114. res->nb_scattering = 0;
  1115. return res;
  1116. }
  1117. /* Free a poly_scattering structure. */
  1118. static inline void
  1119. poly_scattering_free (poly_scattering_p s)
  1120. {
  1121. free (s);
  1122. }
  1123. /* Copies S and return a new scattering. */
  1124. static inline poly_scattering_p
  1125. poly_scattering_copy (poly_scattering_p s)
  1126. {
  1127. poly_scattering_p res = poly_scattering_new ();
  1128. res->nb_local_variables = s->nb_local_variables;
  1129. res->nb_scattering = s->nb_scattering;
  1130. return res;
  1131. }
  1132. /* Saves the transformed scattering of PBB. */
  1133. static inline void
  1134. store_scattering_pbb (poly_bb_p pbb)
  1135. {
  1136. isl_map_free (pbb->saved);
  1137. pbb->saved = isl_map_copy (pbb->transformed);
  1138. }
  1139. /* Stores the SCOP_TRANSFORMED_SCHEDULE to SCOP_SAVED_SCHEDULE. */
  1140. static inline void
  1141. store_lst_schedule (scop_p scop)
  1142. {
  1143. if (SCOP_SAVED_SCHEDULE (scop))
  1144. free_lst (SCOP_SAVED_SCHEDULE (scop));
  1145. SCOP_SAVED_SCHEDULE (scop) = copy_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
  1146. }
  1147. /* Restores the SCOP_TRANSFORMED_SCHEDULE from SCOP_SAVED_SCHEDULE. */
  1148. static inline void
  1149. restore_lst_schedule (scop_p scop)
  1150. {
  1151. if (SCOP_TRANSFORMED_SCHEDULE (scop))
  1152. free_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
  1153. SCOP_TRANSFORMED_SCHEDULE (scop) = copy_lst (SCOP_SAVED_SCHEDULE (scop));
  1154. }
  1155. /* Saves the scattering for all the pbbs in the SCOP. */
  1156. static inline void
  1157. store_scattering (scop_p scop)
  1158. {
  1159. int i;
  1160. poly_bb_p pbb;
  1161. for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
  1162. store_scattering_pbb (pbb);
  1163. store_lst_schedule (scop);
  1164. }
  1165. /* Restores the scattering of PBB. */
  1166. static inline void
  1167. restore_scattering_pbb (poly_bb_p pbb)
  1168. {
  1169. gcc_assert (pbb->saved);
  1170. isl_map_free (pbb->transformed);
  1171. pbb->transformed = isl_map_copy (pbb->saved);
  1172. }
  1173. /* Restores the scattering for all the pbbs in the SCOP. */
  1174. static inline void
  1175. restore_scattering (scop_p scop)
  1176. {
  1177. int i;
  1178. poly_bb_p pbb;
  1179. for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
  1180. restore_scattering_pbb (pbb);
  1181. restore_lst_schedule (scop);
  1182. }
  1183. bool graphite_legal_transform (scop_p);
  1184. isl_map *reverse_loop_at_level (poly_bb_p, int);
  1185. isl_union_map *reverse_loop_for_pbbs (scop_p, vec<poly_bb_p> , int);
  1186. __isl_give isl_union_map *extend_schedule (__isl_take isl_union_map *);
  1187. void
  1188. compute_deps (scop_p scop, vec<poly_bb_p> pbbs,
  1189. isl_union_map **must_raw,
  1190. isl_union_map **may_raw,
  1191. isl_union_map **must_raw_no_source,
  1192. isl_union_map **may_raw_no_source,
  1193. isl_union_map **must_war,
  1194. isl_union_map **may_war,
  1195. isl_union_map **must_war_no_source,
  1196. isl_union_map **may_war_no_source,
  1197. isl_union_map **must_waw,
  1198. isl_union_map **may_waw,
  1199. isl_union_map **must_waw_no_source,
  1200. isl_union_map **may_waw_no_source);
  1201. isl_union_map *
  1202. scop_get_dependences (scop_p scop);
  1203. bool
  1204. carries_deps (__isl_keep isl_union_map *schedule,
  1205. __isl_keep isl_union_map *deps,
  1206. int depth);
  1207. #endif