graphite-poly.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224
  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. #include "config.h"
  18. #ifdef HAVE_isl
  19. #include <isl/set.h>
  20. #include <isl/map.h>
  21. #include <isl/union_map.h>
  22. #include <isl/constraint.h>
  23. #include <isl/ilp.h>
  24. #include <isl/aff.h>
  25. #include <isl/val.h>
  26. /* Since ISL-0.13, the extern is in val_gmp.h. */
  27. #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
  28. extern "C" {
  29. #endif
  30. #include <isl/val_gmp.h>
  31. #if !defined(HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE) && defined(__cplusplus)
  32. }
  33. #endif
  34. #endif
  35. #include "system.h"
  36. #include "coretypes.h"
  37. #include "diagnostic-core.h"
  38. #include "hash-set.h"
  39. #include "machmode.h"
  40. #include "vec.h"
  41. #include "double-int.h"
  42. #include "input.h"
  43. #include "alias.h"
  44. #include "symtab.h"
  45. #include "options.h"
  46. #include "wide-int.h"
  47. #include "inchash.h"
  48. #include "tree.h"
  49. #include "fold-const.h"
  50. #include "predict.h"
  51. #include "tm.h"
  52. #include "hard-reg-set.h"
  53. #include "input.h"
  54. #include "function.h"
  55. #include "dominance.h"
  56. #include "cfg.h"
  57. #include "basic-block.h"
  58. #include "tree-ssa-alias.h"
  59. #include "internal-fn.h"
  60. #include "gimple-expr.h"
  61. #include "is-a.h"
  62. #include "gimple.h"
  63. #include "gimple-iterator.h"
  64. #include "tree-ssa-loop.h"
  65. #include "dumpfile.h"
  66. #include "gimple-pretty-print.h"
  67. #include "cfgloop.h"
  68. #include "tree-chrec.h"
  69. #include "tree-data-ref.h"
  70. #include "tree-scalar-evolution.h"
  71. #include "sese.h"
  72. #ifdef HAVE_isl
  73. #include "graphite-poly.h"
  74. #define OPENSCOP_MAX_STRING 256
  75. /* Print to STDERR the GMP value VAL. */
  76. DEBUG_FUNCTION void
  77. debug_gmp_value (mpz_t val)
  78. {
  79. gmp_fprintf (stderr, "%Zd", val);
  80. }
  81. /* Return the maximal loop depth in SCOP. */
  82. int
  83. scop_max_loop_depth (scop_p scop)
  84. {
  85. int i;
  86. poly_bb_p pbb;
  87. int max_nb_loops = 0;
  88. FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
  89. {
  90. int nb_loops = pbb_dim_iter_domain (pbb);
  91. if (max_nb_loops < nb_loops)
  92. max_nb_loops = nb_loops;
  93. }
  94. return max_nb_loops;
  95. }
  96. /* Prints to FILE the scattering function of PBB, at some VERBOSITY
  97. level. */
  98. static void
  99. print_scattering_function_1 (FILE *file, poly_bb_p pbb, int verbosity)
  100. {
  101. graphite_dim_t i;
  102. if (verbosity > 0)
  103. {
  104. fprintf (file, "# scattering bb_%d (\n", pbb_index (pbb));
  105. fprintf (file, "#eq");
  106. for (i = 0; i < pbb_nb_scattering_transform (pbb); i++)
  107. fprintf (file, " s%d", (int) i);
  108. for (i = 0; i < pbb_nb_local_vars (pbb); i++)
  109. fprintf (file, " lv%d", (int) i);
  110. for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
  111. fprintf (file, " i%d", (int) i);
  112. for (i = 0; i < pbb_nb_params (pbb); i++)
  113. fprintf (file, " p%d", (int) i);
  114. fprintf (file, " cst\n");
  115. }
  116. fprintf (file, "isl\n");
  117. print_isl_map (file, pbb->transformed ? pbb->transformed : pbb->schedule);
  118. if (verbosity > 0)
  119. fprintf (file, "#)\n");
  120. }
  121. /* Prints to FILE the scattering function of PBB, at some VERBOSITY
  122. level. */
  123. void
  124. print_scattering_function (FILE *file, poly_bb_p pbb, int verbosity)
  125. {
  126. if (!PBB_TRANSFORMED (pbb))
  127. return;
  128. if (pbb->schedule || pbb->transformed)
  129. {
  130. if (verbosity > 0)
  131. fprintf (file, "# Scattering function is provided\n");
  132. fprintf (file, "1\n");
  133. }
  134. else
  135. {
  136. if (verbosity > 0)
  137. fprintf (file, "# Scattering function is not provided\n");
  138. fprintf (file, "0\n");
  139. return;
  140. }
  141. print_scattering_function_1 (file, pbb, verbosity);
  142. if (verbosity > 0)
  143. fprintf (file, "# Scattering names are not provided\n");
  144. fprintf (file, "0\n");
  145. }
  146. /* Prints to FILE the iteration domain of PBB, at some VERBOSITY
  147. level. */
  148. void
  149. print_iteration_domain (FILE *file, poly_bb_p pbb, int verbosity)
  150. {
  151. print_pbb_domain (file, pbb, verbosity);
  152. }
  153. /* Prints to FILE the scattering functions of every PBB of SCOP. */
  154. void
  155. print_scattering_functions (FILE *file, scop_p scop, int verbosity)
  156. {
  157. int i;
  158. poly_bb_p pbb;
  159. FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
  160. print_scattering_function (file, pbb, verbosity);
  161. }
  162. /* Prints to FILE the iteration domains of every PBB of SCOP, at some
  163. VERBOSITY level. */
  164. void
  165. print_iteration_domains (FILE *file, scop_p scop, int verbosity)
  166. {
  167. int i;
  168. poly_bb_p pbb;
  169. FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
  170. print_iteration_domain (file, pbb, verbosity);
  171. }
  172. /* Prints to STDERR the scattering function of PBB, at some VERBOSITY
  173. level. */
  174. DEBUG_FUNCTION void
  175. debug_scattering_function (poly_bb_p pbb, int verbosity)
  176. {
  177. print_scattering_function (stderr, pbb, verbosity);
  178. }
  179. /* Prints to STDERR the iteration domain of PBB, at some VERBOSITY
  180. level. */
  181. DEBUG_FUNCTION void
  182. debug_iteration_domain (poly_bb_p pbb, int verbosity)
  183. {
  184. print_iteration_domain (stderr, pbb, verbosity);
  185. }
  186. /* Prints to STDERR the scattering functions of every PBB of SCOP, at
  187. some VERBOSITY level. */
  188. DEBUG_FUNCTION void
  189. debug_scattering_functions (scop_p scop, int verbosity)
  190. {
  191. print_scattering_functions (stderr, scop, verbosity);
  192. }
  193. /* Prints to STDERR the iteration domains of every PBB of SCOP, at
  194. some VERBOSITY level. */
  195. DEBUG_FUNCTION void
  196. debug_iteration_domains (scop_p scop, int verbosity)
  197. {
  198. print_iteration_domains (stderr, scop, verbosity);
  199. }
  200. /* Apply graphite transformations to all the basic blocks of SCOP. */
  201. bool
  202. apply_poly_transforms (scop_p scop)
  203. {
  204. bool transform_done = false;
  205. /* Generate code even if we did not apply any real transformation.
  206. This also allows to check the performance for the identity
  207. transformation: GIMPLE -> GRAPHITE -> GIMPLE
  208. Keep in mind that CLooG optimizes in control, so the loop structure
  209. may change, even if we only use -fgraphite-identity. */
  210. if (flag_graphite_identity)
  211. transform_done = true;
  212. if (flag_loop_parallelize_all)
  213. transform_done = true;
  214. if (flag_loop_block)
  215. transform_done |= scop_do_block (scop);
  216. else
  217. {
  218. if (flag_loop_strip_mine)
  219. transform_done |= scop_do_strip_mine (scop, 0);
  220. if (flag_loop_interchange)
  221. transform_done |= scop_do_interchange (scop);
  222. }
  223. /* This pass needs to be run at the final stage, as it does not
  224. update the lst. */
  225. if (flag_loop_optimize_isl || flag_loop_unroll_jam)
  226. transform_done |= optimize_isl (scop);
  227. return transform_done;
  228. }
  229. /* Create a new polyhedral data reference and add it to PBB. It is
  230. defined by its ACCESSES, its TYPE, and the number of subscripts
  231. NB_SUBSCRIPTS. */
  232. void
  233. new_poly_dr (poly_bb_p pbb, int dr_base_object_set,
  234. enum poly_dr_type type, void *cdr, graphite_dim_t nb_subscripts,
  235. isl_map *acc, isl_set *extent)
  236. {
  237. static int id = 0;
  238. poly_dr_p pdr = XNEW (struct poly_dr);
  239. PDR_ID (pdr) = id++;
  240. PDR_BASE_OBJECT_SET (pdr) = dr_base_object_set;
  241. PDR_NB_REFS (pdr) = 1;
  242. PDR_PBB (pdr) = pbb;
  243. pdr->accesses = acc;
  244. pdr->extent = extent;
  245. PDR_TYPE (pdr) = type;
  246. PDR_CDR (pdr) = cdr;
  247. PDR_NB_SUBSCRIPTS (pdr) = nb_subscripts;
  248. PBB_DRS (pbb).safe_push (pdr);
  249. }
  250. /* Free polyhedral data reference PDR. */
  251. void
  252. free_poly_dr (poly_dr_p pdr)
  253. {
  254. isl_map_free (pdr->accesses);
  255. isl_set_free (pdr->extent);
  256. XDELETE (pdr);
  257. }
  258. /* Create a new polyhedral black box. */
  259. poly_bb_p
  260. new_poly_bb (scop_p scop, void *black_box)
  261. {
  262. poly_bb_p pbb = XNEW (struct poly_bb);
  263. pbb->domain = NULL;
  264. pbb->schedule = NULL;
  265. pbb->transformed = NULL;
  266. pbb->saved = NULL;
  267. pbb->map_sepclass = NULL;
  268. PBB_SCOP (pbb) = scop;
  269. pbb_set_black_box (pbb, black_box);
  270. PBB_TRANSFORMED (pbb) = NULL;
  271. PBB_SAVED (pbb) = NULL;
  272. PBB_ORIGINAL (pbb) = NULL;
  273. PBB_DRS (pbb).create (3);
  274. PBB_IS_REDUCTION (pbb) = false;
  275. GBB_PBB ((gimple_bb_p) black_box) = pbb;
  276. return pbb;
  277. }
  278. /* Free polyhedral black box. */
  279. void
  280. free_poly_bb (poly_bb_p pbb)
  281. {
  282. int i;
  283. poly_dr_p pdr;
  284. isl_set_free (pbb->domain);
  285. isl_map_free (pbb->schedule);
  286. isl_map_free (pbb->transformed);
  287. isl_map_free (pbb->saved);
  288. if (PBB_DRS (pbb).exists ())
  289. FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
  290. free_poly_dr (pdr);
  291. PBB_DRS (pbb).release ();
  292. XDELETE (pbb);
  293. }
  294. static void
  295. print_pdr_access_layout (FILE *file, poly_bb_p pbb, poly_dr_p pdr)
  296. {
  297. graphite_dim_t i;
  298. fprintf (file, "# eq");
  299. fprintf (file, " alias");
  300. for (i = 0; i < PDR_NB_SUBSCRIPTS (pdr); i++)
  301. fprintf (file, " sub%d", (int) i);
  302. for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
  303. fprintf (file, " i%d", (int) i);
  304. for (i = 0; i < pbb_nb_params (pbb); i++)
  305. fprintf (file, " p%d", (int) i);
  306. fprintf (file, " cst\n");
  307. }
  308. /* Prints to FILE the polyhedral data reference PDR, at some VERBOSITY
  309. level. */
  310. void
  311. print_pdr (FILE *file, poly_dr_p pdr, int verbosity)
  312. {
  313. if (verbosity > 1)
  314. {
  315. fprintf (file, "# pdr_%d (", PDR_ID (pdr));
  316. switch (PDR_TYPE (pdr))
  317. {
  318. case PDR_READ:
  319. fprintf (file, "read \n");
  320. break;
  321. case PDR_WRITE:
  322. fprintf (file, "write \n");
  323. break;
  324. case PDR_MAY_WRITE:
  325. fprintf (file, "may_write \n");
  326. break;
  327. default:
  328. gcc_unreachable ();
  329. }
  330. dump_data_reference (file, (data_reference_p) PDR_CDR (pdr));
  331. }
  332. if (verbosity > 0)
  333. {
  334. fprintf (file, "# data accesses (\n");
  335. print_pdr_access_layout (file, PDR_PBB (pdr), pdr);
  336. }
  337. /* XXX isl dump accesses/subscripts */
  338. if (verbosity > 0)
  339. fprintf (file, "#)\n");
  340. if (verbosity > 1)
  341. fprintf (file, "#)\n");
  342. }
  343. /* Prints to STDERR the polyhedral data reference PDR, at some
  344. VERBOSITY level. */
  345. DEBUG_FUNCTION void
  346. debug_pdr (poly_dr_p pdr, int verbosity)
  347. {
  348. print_pdr (stderr, pdr, verbosity);
  349. }
  350. /* Creates a new SCOP containing REGION. */
  351. scop_p
  352. new_scop (void *region)
  353. {
  354. scop_p scop = XNEW (struct scop);
  355. scop->context = NULL;
  356. scop->must_raw = NULL;
  357. scop->may_raw = NULL;
  358. scop->must_raw_no_source = NULL;
  359. scop->may_raw_no_source = NULL;
  360. scop->must_war = NULL;
  361. scop->may_war = NULL;
  362. scop->must_war_no_source = NULL;
  363. scop->may_war_no_source = NULL;
  364. scop->must_waw = NULL;
  365. scop->may_waw = NULL;
  366. scop->must_waw_no_source = NULL;
  367. scop->may_waw_no_source = NULL;
  368. scop_set_region (scop, region);
  369. SCOP_BBS (scop).create (3);
  370. SCOP_ORIGINAL_SCHEDULE (scop) = NULL;
  371. SCOP_TRANSFORMED_SCHEDULE (scop) = NULL;
  372. SCOP_SAVED_SCHEDULE (scop) = NULL;
  373. POLY_SCOP_P (scop) = false;
  374. return scop;
  375. }
  376. /* Deletes SCOP. */
  377. void
  378. free_scop (scop_p scop)
  379. {
  380. int i;
  381. poly_bb_p pbb;
  382. FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
  383. free_poly_bb (pbb);
  384. SCOP_BBS (scop).release ();
  385. isl_set_free (scop->context);
  386. isl_union_map_free (scop->must_raw);
  387. isl_union_map_free (scop->may_raw);
  388. isl_union_map_free (scop->must_raw_no_source);
  389. isl_union_map_free (scop->may_raw_no_source);
  390. isl_union_map_free (scop->must_war);
  391. isl_union_map_free (scop->may_war);
  392. isl_union_map_free (scop->must_war_no_source);
  393. isl_union_map_free (scop->may_war_no_source);
  394. isl_union_map_free (scop->must_waw);
  395. isl_union_map_free (scop->may_waw);
  396. isl_union_map_free (scop->must_waw_no_source);
  397. isl_union_map_free (scop->may_waw_no_source);
  398. free_lst (SCOP_ORIGINAL_SCHEDULE (scop));
  399. free_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
  400. free_lst (SCOP_SAVED_SCHEDULE (scop));
  401. XDELETE (scop);
  402. }
  403. /* Print to FILE the domain of PBB in OpenScop format, at some VERBOSITY
  404. level. */
  405. static void
  406. openscop_print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity)
  407. {
  408. graphite_dim_t i;
  409. gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
  410. if (!pbb->domain)
  411. return;
  412. if (verbosity > 0)
  413. {
  414. fprintf (file, "\n# Iteration domain of bb_%d (\n", GBB_BB (gbb)->index);
  415. fprintf (file, "#eq");
  416. for (i = 0; i < pbb_dim_iter_domain (pbb); i++)
  417. fprintf (file, " i%d", (int) i);
  418. for (i = 0; i < pbb_nb_params (pbb); i++)
  419. fprintf (file, " p%d", (int) i);
  420. fprintf (file, " cst\n");
  421. }
  422. fprintf (file, "XXX isl\n");
  423. if (verbosity > 0)
  424. fprintf (file, "#)\n");
  425. }
  426. /* Print to FILE the domain of PBB, at some VERBOSITY level. */
  427. void
  428. print_pbb_domain (FILE *file, poly_bb_p pbb, int verbosity ATTRIBUTE_UNUSED)
  429. {
  430. print_isl_set (file, pbb->domain);
  431. }
  432. /* Dump the cases of a graphite basic block GBB on FILE. */
  433. static void
  434. dump_gbb_cases (FILE *file, gimple_bb_p gbb)
  435. {
  436. int i;
  437. gimple stmt;
  438. vec<gimple> cases;
  439. if (!gbb)
  440. return;
  441. cases = GBB_CONDITION_CASES (gbb);
  442. if (cases.is_empty ())
  443. return;
  444. fprintf (file, "# cases bb_%d (\n", GBB_BB (gbb)->index);
  445. FOR_EACH_VEC_ELT (cases, i, stmt)
  446. {
  447. fprintf (file, "# ");
  448. print_gimple_stmt (file, stmt, 0, 0);
  449. }
  450. fprintf (file, "#)\n");
  451. }
  452. /* Dump conditions of a graphite basic block GBB on FILE. */
  453. static void
  454. dump_gbb_conditions (FILE *file, gimple_bb_p gbb)
  455. {
  456. int i;
  457. gimple stmt;
  458. vec<gimple> conditions;
  459. if (!gbb)
  460. return;
  461. conditions = GBB_CONDITIONS (gbb);
  462. if (conditions.is_empty ())
  463. return;
  464. fprintf (file, "# conditions bb_%d (\n", GBB_BB (gbb)->index);
  465. FOR_EACH_VEC_ELT (conditions, i, stmt)
  466. {
  467. fprintf (file, "# ");
  468. print_gimple_stmt (file, stmt, 0, 0);
  469. }
  470. fprintf (file, "#)\n");
  471. }
  472. /* Print to FILE all the data references of PBB, at some VERBOSITY
  473. level. */
  474. void
  475. print_pdrs (FILE *file, poly_bb_p pbb, int verbosity)
  476. {
  477. int i;
  478. poly_dr_p pdr;
  479. int nb_reads = 0;
  480. int nb_writes = 0;
  481. if (PBB_DRS (pbb).length () == 0)
  482. {
  483. if (verbosity > 0)
  484. fprintf (file, "# Access informations are not provided\n");\
  485. fprintf (file, "0\n");
  486. return;
  487. }
  488. if (verbosity > 1)
  489. fprintf (file, "# Data references (\n");
  490. if (verbosity > 0)
  491. fprintf (file, "# Access informations are provided\n");
  492. fprintf (file, "1\n");
  493. FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
  494. if (PDR_TYPE (pdr) == PDR_READ)
  495. nb_reads++;
  496. else
  497. nb_writes++;
  498. if (verbosity > 1)
  499. fprintf (file, "# Read data references (\n");
  500. if (verbosity > 0)
  501. fprintf (file, "# Read access informations\n");
  502. fprintf (file, "%d\n", nb_reads);
  503. FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
  504. if (PDR_TYPE (pdr) == PDR_READ)
  505. print_pdr (file, pdr, verbosity);
  506. if (verbosity > 1)
  507. fprintf (file, "#)\n");
  508. if (verbosity > 1)
  509. fprintf (file, "# Write data references (\n");
  510. if (verbosity > 0)
  511. fprintf (file, "# Write access informations\n");
  512. fprintf (file, "%d\n", nb_writes);
  513. FOR_EACH_VEC_ELT (PBB_DRS (pbb), i, pdr)
  514. if (PDR_TYPE (pdr) != PDR_READ)
  515. print_pdr (file, pdr, verbosity);
  516. if (verbosity > 1)
  517. fprintf (file, "#)\n");
  518. if (verbosity > 1)
  519. fprintf (file, "#)\n");
  520. }
  521. /* Print to STDERR all the data references of PBB. */
  522. DEBUG_FUNCTION void
  523. debug_pdrs (poly_bb_p pbb, int verbosity)
  524. {
  525. print_pdrs (stderr, pbb, verbosity);
  526. }
  527. /* Print to FILE the body of PBB, at some VERBOSITY level.
  528. If statement_body_provided is false statement body is not printed. */
  529. static void
  530. print_pbb_body (FILE *file, poly_bb_p pbb, int verbosity,
  531. bool statement_body_provided)
  532. {
  533. if (verbosity > 1)
  534. fprintf (file, "# Body (\n");
  535. if (!statement_body_provided)
  536. {
  537. if (verbosity > 0)
  538. fprintf (file, "# Statement body is not provided\n");
  539. fprintf (file, "0\n");
  540. if (verbosity > 1)
  541. fprintf (file, "#)\n");
  542. return;
  543. }
  544. if (verbosity > 0)
  545. fprintf (file, "# Statement body is provided\n");
  546. fprintf (file, "1\n");
  547. if (verbosity > 0)
  548. fprintf (file, "# Original iterator names\n# Iterator names are not provided yet.\n");
  549. if (verbosity > 0)
  550. fprintf (file, "# Statement body\n");
  551. fprintf (file, "{\n");
  552. dump_bb (file, pbb_bb (pbb), 0, 0);
  553. fprintf (file, "}\n");
  554. if (verbosity > 1)
  555. fprintf (file, "#)\n");
  556. }
  557. /* Print to FILE the domain and scattering function of PBB, at some
  558. VERBOSITY level. */
  559. void
  560. print_pbb (FILE *file, poly_bb_p pbb, int verbosity)
  561. {
  562. if (verbosity > 1)
  563. {
  564. fprintf (file, "# pbb_%d (\n", pbb_index (pbb));
  565. dump_gbb_conditions (file, PBB_BLACK_BOX (pbb));
  566. dump_gbb_cases (file, PBB_BLACK_BOX (pbb));
  567. }
  568. openscop_print_pbb_domain (file, pbb, verbosity);
  569. print_scattering_function (file, pbb, verbosity);
  570. print_pdrs (file, pbb, verbosity);
  571. print_pbb_body (file, pbb, verbosity, false);
  572. if (verbosity > 1)
  573. fprintf (file, "#)\n");
  574. }
  575. /* Print to FILE the parameters of SCOP, at some VERBOSITY level. */
  576. void
  577. print_scop_params (FILE *file, scop_p scop, int verbosity)
  578. {
  579. int i;
  580. tree t;
  581. if (verbosity > 1)
  582. fprintf (file, "# parameters (\n");
  583. if (SESE_PARAMS (SCOP_REGION (scop)).length ())
  584. {
  585. if (verbosity > 0)
  586. fprintf (file, "# Parameter names are provided\n");
  587. fprintf (file, "1\n");
  588. if (verbosity > 0)
  589. fprintf (file, "# Parameter names\n");
  590. }
  591. else
  592. {
  593. if (verbosity > 0)
  594. fprintf (file, "# Parameter names are not provided\n");
  595. fprintf (file, "0\n");
  596. }
  597. FOR_EACH_VEC_ELT (SESE_PARAMS (SCOP_REGION (scop)), i, t)
  598. {
  599. print_generic_expr (file, t, 0);
  600. fprintf (file, " ");
  601. }
  602. fprintf (file, "\n");
  603. if (verbosity > 1)
  604. fprintf (file, "#)\n");
  605. }
  606. /* Print to FILE the context of SCoP in OpenScop format, at some VERBOSITY
  607. level. */
  608. static void
  609. openscop_print_scop_context (FILE *file, scop_p scop, int verbosity)
  610. {
  611. graphite_dim_t i;
  612. if (verbosity > 0)
  613. {
  614. fprintf (file, "# Context (\n");
  615. fprintf (file, "#eq");
  616. for (i = 0; i < scop_nb_params (scop); i++)
  617. fprintf (file, " p%d", (int) i);
  618. fprintf (file, " cst\n");
  619. }
  620. if (scop->context)
  621. /* XXX isl print context */
  622. fprintf (file, "XXX isl\n");
  623. else
  624. fprintf (file, "0 %d 0 0 0 %d\n", (int) scop_nb_params (scop) + 2,
  625. (int) scop_nb_params (scop));
  626. if (verbosity > 0)
  627. fprintf (file, "# )\n");
  628. }
  629. /* Print to FILE the context of SCoP, at some VERBOSITY level. */
  630. void
  631. print_scop_context (FILE *file, scop_p scop, int verbosity)
  632. {
  633. graphite_dim_t i;
  634. if (verbosity > 0)
  635. {
  636. fprintf (file, "# Context (\n");
  637. fprintf (file, "#eq");
  638. for (i = 0; i < scop_nb_params (scop); i++)
  639. fprintf (file, " p%d", (int) i);
  640. fprintf (file, " cst\n");
  641. }
  642. if (scop->context)
  643. print_isl_set (file, scop->context);
  644. else
  645. fprintf (file, "no isl context %d\n", (int) scop_nb_params (scop) + 2);
  646. if (verbosity > 0)
  647. fprintf (file, "# )\n");
  648. }
  649. /* Print to FILE the SCOP, at some VERBOSITY level. */
  650. void
  651. print_scop (FILE *file, scop_p scop, int verbosity)
  652. {
  653. int i;
  654. poly_bb_p pbb;
  655. fprintf (file, "SCoP 1\n#(\n");
  656. fprintf (file, "# Language\nGimple\n");
  657. openscop_print_scop_context (file, scop, verbosity);
  658. print_scop_params (file, scop, verbosity);
  659. if (verbosity > 0)
  660. fprintf (file, "# Number of statements\n");
  661. fprintf (file, "%d\n", SCOP_BBS (scop).length ());
  662. FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
  663. print_pbb (file, pbb, verbosity);
  664. if (verbosity > 1)
  665. {
  666. fprintf (file, "# original_lst (\n");
  667. print_lst (file, SCOP_ORIGINAL_SCHEDULE (scop), 0);
  668. fprintf (file, "\n#)\n");
  669. fprintf (file, "# transformed_lst (\n");
  670. print_lst (file, SCOP_TRANSFORMED_SCHEDULE (scop), 0);
  671. fprintf (file, "\n#)\n");
  672. }
  673. fprintf (file, "#)\n");
  674. }
  675. /* Print to STDERR the domain of PBB, at some VERBOSITY level. */
  676. DEBUG_FUNCTION void
  677. debug_pbb_domain (poly_bb_p pbb, int verbosity)
  678. {
  679. print_pbb_domain (stderr, pbb, verbosity);
  680. }
  681. /* Print to FILE the domain and scattering function of PBB, at some
  682. VERBOSITY level. */
  683. DEBUG_FUNCTION void
  684. debug_pbb (poly_bb_p pbb, int verbosity)
  685. {
  686. print_pbb (stderr, pbb, verbosity);
  687. }
  688. /* Print to STDERR the context of SCOP, at some VERBOSITY level. */
  689. DEBUG_FUNCTION void
  690. debug_scop_context (scop_p scop, int verbosity)
  691. {
  692. print_scop_context (stderr, scop, verbosity);
  693. }
  694. /* Print to STDERR the SCOP, at some VERBOSITY level. */
  695. DEBUG_FUNCTION void
  696. debug_scop (scop_p scop, int verbosity)
  697. {
  698. print_scop (stderr, scop, verbosity);
  699. }
  700. /* Print to STDERR the parameters of SCOP, at some VERBOSITY
  701. level. */
  702. DEBUG_FUNCTION void
  703. debug_scop_params (scop_p scop, int verbosity)
  704. {
  705. print_scop_params (stderr, scop, verbosity);
  706. }
  707. extern isl_ctx *the_isl_ctx;
  708. void
  709. print_isl_set (FILE *f, isl_set *set)
  710. {
  711. isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
  712. p = isl_printer_print_set (p, set);
  713. isl_printer_free (p);
  714. }
  715. DEBUG_FUNCTION void
  716. debug_isl_set (isl_set *set)
  717. {
  718. print_isl_set (stderr, set);
  719. }
  720. void
  721. print_isl_map (FILE *f, isl_map *map)
  722. {
  723. isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
  724. p = isl_printer_print_map (p, map);
  725. isl_printer_free (p);
  726. }
  727. DEBUG_FUNCTION void
  728. debug_isl_map (isl_map *map)
  729. {
  730. print_isl_map (stderr, map);
  731. }
  732. void
  733. print_isl_aff (FILE *f, isl_aff *aff)
  734. {
  735. isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
  736. p = isl_printer_print_aff (p, aff);
  737. isl_printer_free (p);
  738. }
  739. DEBUG_FUNCTION void
  740. debug_isl_aff (isl_aff *aff)
  741. {
  742. print_isl_aff (stderr, aff);
  743. }
  744. void
  745. print_isl_constraint (FILE *f, isl_constraint *c)
  746. {
  747. isl_printer *p = isl_printer_to_file (the_isl_ctx, f);
  748. p = isl_printer_print_constraint (p, c);
  749. isl_printer_free (p);
  750. }
  751. DEBUG_FUNCTION void
  752. debug_isl_constraint (isl_constraint *c)
  753. {
  754. print_isl_constraint (stderr, c);
  755. }
  756. /* Returns the number of iterations RES of the loop around PBB at
  757. time(scattering) dimension TIME_DEPTH. */
  758. void
  759. pbb_number_of_iterations_at_time (poly_bb_p pbb,
  760. graphite_dim_t time_depth,
  761. mpz_t res)
  762. {
  763. isl_set *transdomain;
  764. isl_space *dc;
  765. isl_aff *aff;
  766. isl_val *isllb, *islub;
  767. /* Map the iteration domain through the current scatter, and work
  768. on the resulting set. */
  769. transdomain = isl_set_apply (isl_set_copy (pbb->domain),
  770. isl_map_copy (pbb->transformed));
  771. /* Select the time_depth' dimension via an affine expression. */
  772. dc = isl_set_get_space (transdomain);
  773. aff = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
  774. aff = isl_aff_set_coefficient_si (aff, isl_dim_in, time_depth, 1);
  775. /* And find the min/max for that function. */
  776. /* XXX isl check results? */
  777. isllb = isl_set_min_val (transdomain, aff);
  778. islub = isl_set_max_val (transdomain, aff);
  779. islub = isl_val_sub (islub, isllb);
  780. islub = isl_val_add_ui (islub, 1);
  781. isl_val_get_num_gmp (islub, res);
  782. isl_val_free (islub);
  783. isl_aff_free (aff);
  784. isl_set_free (transdomain);
  785. }
  786. /* Translates LOOP to LST. */
  787. static lst_p
  788. loop_to_lst (loop_p loop, vec<poly_bb_p> bbs, int *i)
  789. {
  790. poly_bb_p pbb;
  791. vec<lst_p> seq;
  792. seq.create (5);
  793. for (; bbs.iterate (*i, &pbb); (*i)++)
  794. {
  795. lst_p stmt;
  796. basic_block bb = GBB_BB (PBB_BLACK_BOX (pbb));
  797. if (bb->loop_father == loop)
  798. stmt = new_lst_stmt (pbb);
  799. else if (flow_bb_inside_loop_p (loop, bb))
  800. {
  801. loop_p next = loop->inner;
  802. while (next && !flow_bb_inside_loop_p (next, bb))
  803. next = next->next;
  804. stmt = loop_to_lst (next, bbs, i);
  805. }
  806. else
  807. {
  808. (*i)--;
  809. return new_lst_loop (seq);
  810. }
  811. seq.safe_push (stmt);
  812. }
  813. return new_lst_loop (seq);
  814. }
  815. /* Reads the original scattering of the SCOP and returns an LST
  816. representing it. */
  817. void
  818. scop_to_lst (scop_p scop)
  819. {
  820. lst_p res;
  821. int i, n = SCOP_BBS (scop).length ();
  822. vec<lst_p> seq;
  823. seq.create (5);
  824. sese region = SCOP_REGION (scop);
  825. for (i = 0; i < n; i++)
  826. {
  827. poly_bb_p pbb = SCOP_BBS (scop)[i];
  828. loop_p loop = outermost_loop_in_sese (region, GBB_BB (PBB_BLACK_BOX (pbb)));
  829. if (loop_in_sese_p (loop, region))
  830. res = loop_to_lst (loop, SCOP_BBS (scop), &i);
  831. else
  832. res = new_lst_stmt (pbb);
  833. seq.safe_push (res);
  834. }
  835. res = new_lst_loop (seq);
  836. SCOP_ORIGINAL_SCHEDULE (scop) = res;
  837. SCOP_TRANSFORMED_SCHEDULE (scop) = copy_lst (res);
  838. }
  839. /* Print to FILE on a new line COLUMN white spaces. */
  840. static void
  841. lst_indent_to (FILE *file, int column)
  842. {
  843. int i;
  844. if (column > 0)
  845. fprintf (file, "\n#");
  846. for (i = 0; i < column; i++)
  847. fprintf (file, " ");
  848. }
  849. /* Print LST to FILE with INDENT spaces of indentation. */
  850. void
  851. print_lst (FILE *file, lst_p lst, int indent)
  852. {
  853. if (!lst)
  854. return;
  855. lst_indent_to (file, indent);
  856. if (LST_LOOP_P (lst))
  857. {
  858. int i;
  859. lst_p l;
  860. if (LST_LOOP_FATHER (lst))
  861. fprintf (file, "%d (loop", lst_dewey_number (lst));
  862. else
  863. fprintf (file, "#(root");
  864. FOR_EACH_VEC_ELT (LST_SEQ (lst), i, l)
  865. print_lst (file, l, indent + 2);
  866. fprintf (file, ")");
  867. }
  868. else
  869. fprintf (file, "%d stmt_%d", lst_dewey_number (lst), pbb_index (LST_PBB (lst)));
  870. }
  871. /* Print LST to STDERR. */
  872. DEBUG_FUNCTION void
  873. debug_lst (lst_p lst)
  874. {
  875. print_lst (stderr, lst, 0);
  876. }
  877. /* Pretty print to FILE the loop statement tree LST in DOT format. */
  878. static void
  879. dot_lst_1 (FILE *file, lst_p lst)
  880. {
  881. if (!lst)
  882. return;
  883. if (LST_LOOP_P (lst))
  884. {
  885. int i;
  886. lst_p l;
  887. if (!LST_LOOP_FATHER (lst))
  888. fprintf (file, "L -> L_%d_%d\n",
  889. lst_depth (lst),
  890. lst_dewey_number (lst));
  891. else
  892. fprintf (file, "L_%d_%d -> L_%d_%d\n",
  893. lst_depth (LST_LOOP_FATHER (lst)),
  894. lst_dewey_number (LST_LOOP_FATHER (lst)),
  895. lst_depth (lst),
  896. lst_dewey_number (lst));
  897. FOR_EACH_VEC_ELT (LST_SEQ (lst), i, l)
  898. dot_lst_1 (file, l);
  899. }
  900. else
  901. fprintf (file, "L_%d_%d -> S_%d\n",
  902. lst_depth (LST_LOOP_FATHER (lst)),
  903. lst_dewey_number (LST_LOOP_FATHER (lst)),
  904. pbb_index (LST_PBB (lst)));
  905. }
  906. /* Display the LST using dotty. */
  907. DEBUG_FUNCTION void
  908. dot_lst (lst_p lst)
  909. {
  910. /* When debugging, enable the following code. This cannot be used
  911. in production compilers because it calls "system". */
  912. #if 0
  913. FILE *stream = fopen ("/tmp/lst.dot", "w");
  914. gcc_assert (stream);
  915. fputs ("digraph all {\n", stream);
  916. dot_lst_1 (stream, lst);
  917. fputs ("}\n\n", stream);
  918. fclose (stream);
  919. system ("dotty /tmp/lst.dot &");
  920. #else
  921. fputs ("digraph all {\n", stderr);
  922. dot_lst_1 (stderr, lst);
  923. fputs ("}\n\n", stderr);
  924. #endif
  925. }
  926. /* Reverse the loop around PBB at level DEPTH. */
  927. isl_map *
  928. reverse_loop_at_level (poly_bb_p pbb, int depth)
  929. {
  930. unsigned i, depth_dim = psct_dynamic_dim (pbb, depth);
  931. isl_space *d = isl_map_get_space (pbb->transformed);
  932. isl_space *d1 = isl_space_range (d);
  933. unsigned n = isl_space_dim (d1, isl_dim_out);
  934. isl_space *d2 = isl_space_add_dims (d1, isl_dim_in, n);
  935. isl_map *x = isl_map_universe (isl_space_copy (d2));
  936. isl_constraint *c = isl_equality_alloc (isl_local_space_from_space (d2));
  937. for (i = 0; i < n; i++)
  938. if (i != depth_dim)
  939. x = isl_map_equate (x, isl_dim_in, i, isl_dim_out, i);
  940. c = isl_constraint_set_coefficient_si (c, isl_dim_in, depth_dim, 1);
  941. c = isl_constraint_set_coefficient_si (c, isl_dim_out, depth_dim, 1);
  942. x = isl_map_add_constraint (x, c);
  943. return x;
  944. }
  945. /* Reverse the loop at level DEPTH for all the PBBS. */
  946. isl_union_map *
  947. reverse_loop_for_pbbs (scop_p scop, vec<poly_bb_p> pbbs, int depth)
  948. {
  949. poly_bb_p pbb;
  950. int i;
  951. isl_space *space = isl_space_from_domain (isl_set_get_space (scop->context));
  952. isl_union_map *res = isl_union_map_empty (space);
  953. for (i = 0; pbbs.iterate (i, &pbb); i++)
  954. res = isl_union_map_add_map (res, reverse_loop_at_level (pbb, depth));
  955. return res;
  956. }
  957. #endif