]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/graphite-sese-to-poly.c
2014-10-27 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / graphite-sese-to-poly.c
CommitLineData
c6bb733d 1/* Conversion of SESE regions to Polyhedra.
3aea1f79 2 Copyright (C) 2009-2014 Free Software Foundation, Inc.
c6bb733d 3 Contributed by Sebastian Pop <sebastian.pop@amd.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
87e20041 22
429cca51 23#ifdef HAVE_isl
87e20041 24#include <isl/set.h>
25#include <isl/map.h>
26#include <isl/union_map.h>
27#include <isl/constraint.h>
28#include <isl/aff.h>
ea48ac01 29#include <isl/val.h>
30/* For C++ linkage of C functions.
31 Missing from isl/val_gmp.h in isl 0.12 versions.
32 Appearing in isl/val_gmp.h in isl 0.13.
33 To be removed when passing to isl 0.13. */
34#if defined(__cplusplus)
35extern "C" {
36#endif
37#include <isl/val_gmp.h>
38#if defined(__cplusplus)
39}
40#endif
429cca51 41#ifdef HAVE_cloog
87e20041 42#include <cloog/cloog.h>
43#include <cloog/cloog.h>
44#include <cloog/isl/domain.h>
45#endif
429cca51 46#endif
87e20041 47
c6bb733d 48#include "system.h"
49#include "coretypes.h"
41a8aa41 50#include "tree.h"
94ea8568 51#include "predict.h"
52#include "vec.h"
53#include "hashtab.h"
54#include "hash-set.h"
55#include "machmode.h"
56#include "tm.h"
57#include "hard-reg-set.h"
58#include "input.h"
59#include "function.h"
60#include "dominance.h"
61#include "cfg.h"
bc61cadb 62#include "basic-block.h"
63#include "tree-ssa-alias.h"
64#include "internal-fn.h"
65#include "gimple-expr.h"
66#include "is-a.h"
073c1fd5 67#include "gimple.h"
dcf1a1ec 68#include "gimple-iterator.h"
e795d6e1 69#include "gimplify.h"
70#include "gimplify-me.h"
073c1fd5 71#include "gimple-ssa.h"
72#include "tree-cfg.h"
73#include "tree-phinodes.h"
74#include "ssa-iterators.h"
9ed99284 75#include "stringpool.h"
073c1fd5 76#include "tree-ssanames.h"
05d9c18a 77#include "tree-ssa-loop-manip.h"
78#include "tree-ssa-loop-niter.h"
073c1fd5 79#include "tree-ssa-loop.h"
80#include "tree-into-ssa.h"
f0a18dd2 81#include "tree-pass.h"
c6bb733d 82#include "cfgloop.h"
83#include "tree-chrec.h"
84#include "tree-data-ref.h"
85#include "tree-scalar-evolution.h"
c6bb733d 86#include "domwalk.h"
c6bb733d 87#include "sese.h"
f8ba3083 88#include "tree-ssa-propagate.h"
c6bb733d 89
429cca51 90#ifdef HAVE_isl
3ebca59c 91#include "expr.h"
c6bb733d 92#include "graphite-poly.h"
c6bb733d 93#include "graphite-sese-to-poly.h"
94
87e20041 95
96/* Assigns to RES the value of the INTEGER_CST T. */
97
98static inline void
99tree_int_to_gmp (tree t, mpz_t res)
100{
ab2c1de8 101 wi::to_mpz (t, res, TYPE_SIGN (TREE_TYPE (t)));
87e20041 102}
103
9d828157 104/* Returns the index of the PHI argument defined in the outermost
105 loop. */
c6bb733d 106
107static size_t
9d828157 108phi_arg_in_outermost_loop (gimple phi)
c6bb733d 109{
110 loop_p loop = gimple_bb (phi)->loop_father;
9d828157 111 size_t i, res = 0;
c6bb733d 112
113 for (i = 0; i < gimple_phi_num_args (phi); i++)
114 if (!flow_bb_inside_loop_p (loop, gimple_phi_arg_edge (phi, i)->src))
9d828157 115 {
116 loop = gimple_phi_arg_edge (phi, i)->src->loop_father;
117 res = i;
118 }
c6bb733d 119
9d828157 120 return res;
c6bb733d 121}
122
123/* Removes a simple copy phi node "RES = phi (INIT, RES)" at position
124 PSI by inserting on the loop ENTRY edge assignment "RES = INIT". */
125
126static void
127remove_simple_copy_phi (gimple_stmt_iterator *psi)
128{
129 gimple phi = gsi_stmt (*psi);
130 tree res = gimple_phi_result (phi);
9d828157 131 size_t entry = phi_arg_in_outermost_loop (phi);
c6bb733d 132 tree init = gimple_phi_arg_def (phi, entry);
133 gimple stmt = gimple_build_assign (res, init);
134 edge e = gimple_phi_arg_edge (phi, entry);
135
136 remove_phi_node (psi, false);
137 gsi_insert_on_edge_immediate (e, stmt);
c6bb733d 138}
139
140/* Removes an invariant phi node at position PSI by inserting on the
141 loop ENTRY edge the assignment RES = INIT. */
142
143static void
144remove_invariant_phi (sese region, gimple_stmt_iterator *psi)
145{
146 gimple phi = gsi_stmt (*psi);
147 loop_p loop = loop_containing_stmt (phi);
148 tree res = gimple_phi_result (phi);
149 tree scev = scalar_evolution_in_region (region, loop, res);
9d828157 150 size_t entry = phi_arg_in_outermost_loop (phi);
c6bb733d 151 edge e = gimple_phi_arg_edge (phi, entry);
152 tree var;
153 gimple stmt;
e3a19533 154 gimple_seq stmts = NULL;
c6bb733d 155
156 if (tree_contains_chrecs (scev, NULL))
157 scev = gimple_phi_arg_def (phi, entry);
158
159 var = force_gimple_operand (scev, &stmts, true, NULL_TREE);
160 stmt = gimple_build_assign (res, var);
161 remove_phi_node (psi, false);
162
e3a19533 163 gimple_seq_add_stmt (&stmts, stmt);
c6bb733d 164 gsi_insert_seq_on_edge (e, stmts);
165 gsi_commit_edge_inserts ();
166 SSA_NAME_DEF_STMT (res) = stmt;
167}
168
169/* Returns true when the phi node at PSI is of the form "a = phi (a, x)". */
170
171static inline bool
172simple_copy_phi_p (gimple phi)
173{
174 tree res;
175
176 if (gimple_phi_num_args (phi) != 2)
177 return false;
178
179 res = gimple_phi_result (phi);
180 return (res == gimple_phi_arg_def (phi, 0)
181 || res == gimple_phi_arg_def (phi, 1));
182}
183
184/* Returns true when the phi node at position PSI is a reduction phi
185 node in REGION. Otherwise moves the pointer PSI to the next phi to
186 be considered. */
187
188static bool
189reduction_phi_p (sese region, gimple_stmt_iterator *psi)
190{
191 loop_p loop;
c6bb733d 192 gimple phi = gsi_stmt (*psi);
193 tree res = gimple_phi_result (phi);
194
c6bb733d 195 loop = loop_containing_stmt (phi);
196
197 if (simple_copy_phi_p (phi))
198 {
5d92ac74 199 /* PRE introduces phi nodes like these, for an example,
c6bb733d 200 see id-5.f in the fortran graphite testsuite:
201
202 # prephitmp.85_265 = PHI <prephitmp.85_258(33), prephitmp.85_265(18)>
203 */
204 remove_simple_copy_phi (psi);
205 return false;
206 }
207
15822b8e 208 if (scev_analyzable_p (res, region))
c6bb733d 209 {
15822b8e 210 tree scev = scalar_evolution_in_region (region, loop, res);
211
212 if (evolution_function_is_invariant_p (scev, loop->num))
30105622 213 remove_invariant_phi (region, psi);
214 else
215 gsi_next (psi);
216
c6bb733d 217 return false;
218 }
219
c6bb733d 220 /* All the other cases are considered reductions. */
221 return true;
222}
223
c6bb733d 224/* Store the GRAPHITE representation of BB. */
225
226static gimple_bb_p
f1f41a6c 227new_gimple_bb (basic_block bb, vec<data_reference_p> drs)
c6bb733d 228{
229 struct gimple_bb *gbb;
230
231 gbb = XNEW (struct gimple_bb);
232 bb->aux = gbb;
233 GBB_BB (gbb) = bb;
234 GBB_DATA_REFS (gbb) = drs;
f1f41a6c 235 GBB_CONDITIONS (gbb).create (0);
236 GBB_CONDITION_CASES (gbb).create (0);
c6bb733d 237
238 return gbb;
239}
240
ae11f03b 241static void
f1f41a6c 242free_data_refs_aux (vec<data_reference_p> datarefs)
ae11f03b 243{
244 unsigned int i;
245 struct data_reference *dr;
1a95516e 246
f1f41a6c 247 FOR_EACH_VEC_ELT (datarefs, i, dr)
1a95516e 248 if (dr->aux)
ae11f03b 249 {
e9a3f95f 250 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1a95516e 251
dd045aee 252 free (bap->alias_set);
1a95516e 253
e9a3f95f 254 free (bap);
ae11f03b 255 dr->aux = NULL;
256 }
257}
c6bb733d 258/* Frees GBB. */
259
260static void
261free_gimple_bb (struct gimple_bb *gbb)
262{
ae11f03b 263 free_data_refs_aux (GBB_DATA_REFS (gbb));
c6bb733d 264 free_data_refs (GBB_DATA_REFS (gbb));
265
f1f41a6c 266 GBB_CONDITIONS (gbb).release ();
267 GBB_CONDITION_CASES (gbb).release ();
c6bb733d 268 GBB_BB (gbb)->aux = 0;
269 XDELETE (gbb);
270}
271
272/* Deletes all gimple bbs in SCOP. */
273
274static void
275remove_gbbs_in_scop (scop_p scop)
276{
277 int i;
278 poly_bb_p pbb;
279
f1f41a6c 280 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
c6bb733d 281 free_gimple_bb (PBB_BLACK_BOX (pbb));
282}
283
284/* Deletes all scops in SCOPS. */
285
286void
f1f41a6c 287free_scops (vec<scop_p> scops)
c6bb733d 288{
289 int i;
290 scop_p scop;
291
f1f41a6c 292 FOR_EACH_VEC_ELT (scops, i, scop)
c6bb733d 293 {
294 remove_gbbs_in_scop (scop);
295 free_sese (SCOP_REGION (scop));
296 free_scop (scop);
297 }
298
f1f41a6c 299 scops.release ();
c6bb733d 300}
301
221a697e 302/* Same as outermost_loop_in_sese, returns the outermost loop
303 containing BB in REGION, but makes sure that the returned loop
304 belongs to the REGION, and so this returns the first loop in the
305 REGION when the loop containing BB does not belong to REGION. */
306
307static loop_p
308outermost_loop_in_sese_1 (sese region, basic_block bb)
309{
310 loop_p nest = outermost_loop_in_sese (region, bb);
311
312 if (loop_in_sese_p (nest, region))
313 return nest;
314
315 /* When the basic block BB does not belong to a loop in the region,
316 return the first loop in the region. */
317 nest = nest->inner;
318 while (nest)
319 if (loop_in_sese_p (nest, region))
320 break;
321 else
322 nest = nest->next;
323
324 gcc_assert (nest);
325 return nest;
326}
327
c6bb733d 328/* Generates a polyhedral black box only if the bb contains interesting
329 information. */
330
8c6b3774 331static gimple_bb_p
332try_generate_gimple_bb (scop_p scop, basic_block bb)
c6bb733d 333{
f1f41a6c 334 vec<data_reference_p> drs;
335 drs.create (5);
221a697e 336 sese region = SCOP_REGION (scop);
337 loop_p nest = outermost_loop_in_sese_1 (region, bb);
c6bb733d 338 gimple_stmt_iterator gsi;
339
340 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3f6c0a40 341 {
342 gimple stmt = gsi_stmt (gsi);
221a697e 343 loop_p loop;
344
345 if (is_gimple_debug (stmt))
346 continue;
347
348 loop = loop_containing_stmt (stmt);
349 if (!loop_in_sese_p (loop, region))
350 loop = nest;
351
352 graphite_find_data_references_in_stmt (nest, loop, stmt, &drs);
3f6c0a40 353 }
c6bb733d 354
8c6b3774 355 return new_gimple_bb (bb, drs);
c6bb733d 356}
357
358/* Returns true if all predecessors of BB, that are not dominated by BB, are
359 marked in MAP. The predecessors dominated by BB are loop latches and will
360 be handled after BB. */
361
362static bool
363all_non_dominated_preds_marked_p (basic_block bb, sbitmap map)
364{
365 edge e;
366 edge_iterator ei;
367
368 FOR_EACH_EDGE (e, ei, bb->preds)
08b7917c 369 if (!bitmap_bit_p (map, e->src->index)
c6bb733d 370 && !dominated_by_p (CDI_DOMINATORS, e->src, bb))
371 return false;
372
373 return true;
374}
375
376/* Compare the depth of two basic_block's P1 and P2. */
377
378static int
379compare_bb_depths (const void *p1, const void *p2)
380{
381 const_basic_block const bb1 = *(const_basic_block const*)p1;
382 const_basic_block const bb2 = *(const_basic_block const*)p2;
383 int d1 = loop_depth (bb1->loop_father);
384 int d2 = loop_depth (bb2->loop_father);
385
386 if (d1 < d2)
387 return 1;
388
389 if (d1 > d2)
390 return -1;
391
392 return 0;
393}
394
395/* Sort the basic blocks from DOM such that the first are the ones at
396 a deepest loop level. */
397
398static void
f1f41a6c 399graphite_sort_dominated_info (vec<basic_block> dom)
c6bb733d 400{
f1f41a6c 401 dom.qsort (compare_bb_depths);
c6bb733d 402}
403
404/* Recursive helper function for build_scops_bbs. */
405
406static void
8c6b3774 407build_scop_bbs_1 (scop_p scop, sbitmap visited, basic_block bb)
c6bb733d 408{
409 sese region = SCOP_REGION (scop);
f1f41a6c 410 vec<basic_block> dom;
8c6b3774 411 poly_bb_p pbb;
c6bb733d 412
08b7917c 413 if (bitmap_bit_p (visited, bb->index)
c6bb733d 414 || !bb_in_sese_p (bb, region))
415 return;
416
8c6b3774 417 pbb = new_poly_bb (scop, try_generate_gimple_bb (scop, bb));
f1f41a6c 418 SCOP_BBS (scop).safe_push (pbb);
08b7917c 419 bitmap_set_bit (visited, bb->index);
c6bb733d 420
421 dom = get_dominated_by (CDI_DOMINATORS, bb);
422
f1f41a6c 423 if (!dom.exists ())
c6bb733d 424 return;
425
426 graphite_sort_dominated_info (dom);
427
f1f41a6c 428 while (!dom.is_empty ())
c6bb733d 429 {
430 int i;
431 basic_block dom_bb;
432
f1f41a6c 433 FOR_EACH_VEC_ELT (dom, i, dom_bb)
c6bb733d 434 if (all_non_dominated_preds_marked_p (dom_bb, visited))
435 {
8c6b3774 436 build_scop_bbs_1 (scop, visited, dom_bb);
f1f41a6c 437 dom.unordered_remove (i);
c6bb733d 438 break;
439 }
440 }
441
f1f41a6c 442 dom.release ();
c6bb733d 443}
444
445/* Gather the basic blocks belonging to the SCOP. */
446
8c6b3774 447static void
448build_scop_bbs (scop_p scop)
c6bb733d 449{
fe672ac0 450 sbitmap visited = sbitmap_alloc (last_basic_block_for_fn (cfun));
c6bb733d 451 sese region = SCOP_REGION (scop);
452
53c5d9d4 453 bitmap_clear (visited);
8c6b3774 454 build_scop_bbs_1 (scop, visited, SESE_ENTRY_BB (region));
c6bb733d 455 sbitmap_free (visited);
456}
457
87e20041 458/* Return an ISL identifier for the polyhedral basic block PBB. */
459
460static isl_id *
461isl_id_for_pbb (scop_p s, poly_bb_p pbb)
462{
463 char name[50];
464 snprintf (name, sizeof (name), "S_%d", pbb_index (pbb));
465 return isl_id_alloc (s->ctx, name, pbb);
466}
467
c6bb733d 468/* Converts the STATIC_SCHEDULE of PBB into a scattering polyhedron.
469 We generate SCATTERING_DIMENSIONS scattering dimensions.
470
471 CLooG 0.15.0 and previous versions require, that all
472 scattering functions of one CloogProgram have the same number of
473 scattering dimensions, therefore we allow to specify it. This
474 should be removed in future versions of CLooG.
475
476 The scattering polyhedron consists of these dimensions: scattering,
477 loop_iterators, parameters.
478
479 Example:
480
481 | scattering_dimensions = 5
482 | used_scattering_dimensions = 3
483 | nb_iterators = 1
484 | scop_nb_params = 2
485 |
486 | Schedule:
487 | i
488 | 4 5
489 |
490 | Scattering polyhedron:
491 |
492 | scattering: {s1, s2, s3, s4, s5}
493 | loop_iterators: {i}
494 | parameters: {p1, p2}
495 |
496 | s1 s2 s3 s4 s5 i p1 p2 1
497 | 1 0 0 0 0 0 0 0 -4 = 0
498 | 0 1 0 0 0 -1 0 0 0 = 0
499 | 0 0 1 0 0 0 0 0 -5 = 0 */
500
501static void
87e20041 502build_pbb_scattering_polyhedrons (isl_aff *static_sched,
c6bb733d 503 poly_bb_p pbb, int scattering_dimensions)
504{
505 int i;
c6bb733d 506 int nb_iterators = pbb_dim_iter_domain (pbb);
507 int used_scattering_dimensions = nb_iterators * 2 + 1;
ea48ac01 508 isl_val *val;
87e20041 509 isl_space *dc, *dm;
c6bb733d 510
511 gcc_assert (scattering_dimensions >= used_scattering_dimensions);
512
87e20041 513 dc = isl_set_get_space (pbb->domain);
514 dm = isl_space_add_dims (isl_space_from_domain (dc),
515 isl_dim_out, scattering_dimensions);
516 pbb->schedule = isl_map_universe (dm);
c6bb733d 517
518 for (i = 0; i < scattering_dimensions; i++)
519 {
c6bb733d 520 /* Textual order inside this loop. */
521 if ((i % 2) == 0)
522 {
87e20041 523 isl_constraint *c = isl_equality_alloc
524 (isl_local_space_from_space (isl_map_get_space (pbb->schedule)));
525
ea48ac01 526 val = isl_aff_get_coefficient_val (static_sched, isl_dim_in, i / 2);
87e20041 527
ea48ac01 528 val = isl_val_neg (val);
529 c = isl_constraint_set_constant_val (c, val);
87e20041 530 c = isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1);
531 pbb->schedule = isl_map_add_constraint (pbb->schedule, c);
c6bb733d 532 }
533
534 /* Iterations of this loop. */
535 else /* if ((i % 2) == 1) */
536 {
537 int loop = (i - 1) / 2;
87e20041 538 pbb->schedule = isl_map_equate (pbb->schedule, isl_dim_in, loop,
539 isl_dim_out, i);
c6bb733d 540 }
c6bb733d 541 }
542
87e20041 543 pbb->transformed = isl_map_copy (pbb->schedule);
c6bb733d 544}
545
546/* Build for BB the static schedule.
547
548 The static schedule is a Dewey numbering of the abstract syntax
549 tree: http://en.wikipedia.org/wiki/Dewey_Decimal_Classification
550
551 The following example informally defines the static schedule:
552
553 A
554 for (i: ...)
555 {
556 for (j: ...)
557 {
558 B
559 C
560 }
561
562 for (k: ...)
563 {
564 D
565 E
566 }
567 }
568 F
569
570 Static schedules for A to F:
571
572 DEPTH
573 0 1 2
574 A 0
575 B 1 0 0
576 C 1 0 1
577 D 1 1 0
578 E 1 1 1
579 F 2
580*/
581
582static void
583build_scop_scattering (scop_p scop)
584{
585 int i;
586 poly_bb_p pbb;
587 gimple_bb_p previous_gbb = NULL;
87e20041 588 isl_space *dc = isl_set_get_space (scop->context);
589 isl_aff *static_sched;
c6bb733d 590
41f75a99 591 dc = isl_space_add_dims (dc, isl_dim_set, number_of_loops (cfun));
87e20041 592 static_sched = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
c6bb733d 593
594 /* We have to start schedules at 0 on the first component and
595 because we cannot compare_prefix_loops against a previous loop,
596 prefix will be equal to zero, and that index will be
597 incremented before copying. */
87e20041 598 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in, 0, -1);
c6bb733d 599
f1f41a6c 600 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
c6bb733d 601 {
602 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
c6bb733d 603 int prefix;
604 int nb_scat_dims = pbb_dim_iter_domain (pbb) * 2 + 1;
605
606 if (previous_gbb)
607 prefix = nb_common_loops (SCOP_REGION (scop), previous_gbb, gbb);
608 else
609 prefix = 0;
610
611 previous_gbb = gbb;
c6bb733d 612
87e20041 613 static_sched = isl_aff_add_coefficient_si (static_sched, isl_dim_in,
614 prefix, 1);
615 build_pbb_scattering_polyhedrons (static_sched, pbb, nb_scat_dims);
616 }
617
618 isl_aff_free (static_sched);
619}
620
621static isl_pw_aff *extract_affine (scop_p, tree, __isl_take isl_space *space);
622
623/* Extract an affine expression from the chain of recurrence E. */
c6bb733d 624
87e20041 625static isl_pw_aff *
626extract_affine_chrec (scop_p s, tree e, __isl_take isl_space *space)
627{
628 isl_pw_aff *lhs = extract_affine (s, CHREC_LEFT (e), isl_space_copy (space));
629 isl_pw_aff *rhs = extract_affine (s, CHREC_RIGHT (e), isl_space_copy (space));
630 isl_local_space *ls = isl_local_space_from_space (space);
41f75a99 631 unsigned pos = sese_loop_depth ((sese) s->region, get_chrec_loop (e)) - 1;
87e20041 632 isl_aff *loop = isl_aff_set_coefficient_si
633 (isl_aff_zero_on_domain (ls), isl_dim_in, pos, 1);
634 isl_pw_aff *l = isl_pw_aff_from_aff (loop);
635
636 /* Before multiplying, make sure that the result is affine. */
637 gcc_assert (isl_pw_aff_is_cst (rhs)
638 || isl_pw_aff_is_cst (l));
639
640 return isl_pw_aff_add (lhs, isl_pw_aff_mul (rhs, l));
641}
642
643/* Extract an affine expression from the mult_expr E. */
644
645static isl_pw_aff *
646extract_affine_mul (scop_p s, tree e, __isl_take isl_space *space)
647{
648 isl_pw_aff *lhs = extract_affine (s, TREE_OPERAND (e, 0),
649 isl_space_copy (space));
650 isl_pw_aff *rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
c6bb733d 651
87e20041 652 if (!isl_pw_aff_is_cst (lhs)
653 && !isl_pw_aff_is_cst (rhs))
654 {
655 isl_pw_aff_free (lhs);
656 isl_pw_aff_free (rhs);
657 return NULL;
c6bb733d 658 }
659
87e20041 660 return isl_pw_aff_mul (lhs, rhs);
c6bb733d 661}
662
87e20041 663/* Return an ISL identifier from the name of the ssa_name E. */
c6bb733d 664
87e20041 665static isl_id *
666isl_id_for_ssa_name (scop_p s, tree e)
c6bb733d 667{
87e20041 668 const char *name = get_name (e);
669 isl_id *id;
670
671 if (name)
672 id = isl_id_alloc (s->ctx, name, e);
673 else
674 {
675 char name1[50];
676 snprintf (name1, sizeof (name1), "P_%d", SSA_NAME_VERSION (e));
677 id = isl_id_alloc (s->ctx, name1, e);
678 }
c6bb733d 679
87e20041 680 return id;
681}
c6bb733d 682
87e20041 683/* Return an ISL identifier for the data reference DR. */
c6bb733d 684
87e20041 685static isl_id *
686isl_id_for_dr (scop_p s, data_reference_p dr ATTRIBUTE_UNUSED)
687{
688 /* Data references all get the same isl_id. They need to be comparable
689 and are distinguished through the first dimension, which contains the
690 alias set number. */
691 return isl_id_alloc (s->ctx, "", 0);
c6bb733d 692}
693
87e20041 694/* Extract an affine expression from the ssa_name E. */
c6bb733d 695
87e20041 696static isl_pw_aff *
697extract_affine_name (scop_p s, tree e, __isl_take isl_space *space)
c6bb733d 698{
87e20041 699 isl_aff *aff;
700 isl_set *dom;
701 isl_id *id;
702 int dimension;
703
704 id = isl_id_for_ssa_name (s, e);
705 dimension = isl_space_find_dim_by_id (space, isl_dim_param, id);
9af5ce0c 706 isl_id_free (id);
87e20041 707 dom = isl_set_universe (isl_space_copy (space));
708 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
709 aff = isl_aff_add_coefficient_si (aff, isl_dim_param, dimension, 1);
710 return isl_pw_aff_alloc (dom, aff);
711}
c6bb733d 712
87e20041 713/* Extract an affine expression from the gmp constant G. */
c6bb733d 714
87e20041 715static isl_pw_aff *
716extract_affine_gmp (mpz_t g, __isl_take isl_space *space)
717{
718 isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
719 isl_aff *aff = isl_aff_zero_on_domain (ls);
720 isl_set *dom = isl_set_universe (space);
ea48ac01 721 isl_val *v;
722 isl_ctx *ct;
c6bb733d 723
ea48ac01 724 ct = isl_aff_get_ctx (aff);
725 v = isl_val_int_from_gmp (ct, g);
726 aff = isl_aff_add_constant_val (aff, v);
c6bb733d 727
87e20041 728 return isl_pw_aff_alloc (dom, aff);
c6bb733d 729}
730
87e20041 731/* Extract an affine expression from the integer_cst E. */
c6bb733d 732
87e20041 733static isl_pw_aff *
734extract_affine_int (tree e, __isl_take isl_space *space)
735{
736 isl_pw_aff *res;
737 mpz_t g;
738
739 mpz_init (g);
740 tree_int_to_gmp (e, g);
741 res = extract_affine_gmp (g, space);
742 mpz_clear (g);
743
744 return res;
745}
746
747/* Compute pwaff mod 2^width. */
748
ea48ac01 749extern isl_ctx *the_isl_ctx;
750
87e20041 751static isl_pw_aff *
752wrap (isl_pw_aff *pwaff, unsigned width)
c6bb733d 753{
ea48ac01 754 isl_val *mod;
c6bb733d 755
ea48ac01 756 mod = isl_val_int_from_ui(the_isl_ctx, width);
757 mod = isl_val_2exp (mod);
758 pwaff = isl_pw_aff_mod_val (pwaff, mod);
87e20041 759
760 return pwaff;
c6bb733d 761}
762
c6bb733d 763/* When parameter NAME is in REGION, returns its index in SESE_PARAMS.
764 Otherwise returns -1. */
765
766static inline int
767parameter_index_in_region_1 (tree name, sese region)
768{
769 int i;
770 tree p;
771
772 gcc_assert (TREE_CODE (name) == SSA_NAME);
773
f1f41a6c 774 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, p)
c6bb733d 775 if (p == name)
776 return i;
777
778 return -1;
779}
780
781/* When the parameter NAME is in REGION, returns its index in
782 SESE_PARAMS. Otherwise this function inserts NAME in SESE_PARAMS
783 and returns the index of NAME. */
784
785static int
786parameter_index_in_region (tree name, sese region)
787{
788 int i;
789
790 gcc_assert (TREE_CODE (name) == SSA_NAME);
791
792 i = parameter_index_in_region_1 (name, region);
793 if (i != -1)
794 return i;
795
796 gcc_assert (SESE_ADD_PARAMS (region));
797
f1f41a6c 798 i = SESE_PARAMS (region).length ();
799 SESE_PARAMS (region).safe_push (name);
c6bb733d 800 return i;
801}
802
87e20041 803/* Extract an affine expression from the tree E in the scop S. */
c6bb733d 804
87e20041 805static isl_pw_aff *
806extract_affine (scop_p s, tree e, __isl_take isl_space *space)
c6bb733d 807{
87e20041 808 isl_pw_aff *lhs, *rhs, *res;
809 tree type;
810
811 if (e == chrec_dont_know) {
812 isl_space_free (space);
813 return NULL;
814 }
c6bb733d 815
816 switch (TREE_CODE (e))
817 {
818 case POLYNOMIAL_CHREC:
87e20041 819 res = extract_affine_chrec (s, e, space);
c6bb733d 820 break;
821
822 case MULT_EXPR:
87e20041 823 res = extract_affine_mul (s, e, space);
c6bb733d 824 break;
825
826 case PLUS_EXPR:
827 case POINTER_PLUS_EXPR:
87e20041 828 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
829 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
830 res = isl_pw_aff_add (lhs, rhs);
c6bb733d 831 break;
832
833 case MINUS_EXPR:
87e20041 834 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
835 rhs = extract_affine (s, TREE_OPERAND (e, 1), space);
836 res = isl_pw_aff_sub (lhs, rhs);
837 break;
c6bb733d 838
839 case NEGATE_EXPR:
87e20041 840 case BIT_NOT_EXPR:
841 lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space));
842 rhs = extract_affine (s, integer_minus_one_node, space);
843 res = isl_pw_aff_mul (lhs, rhs);
844 break;
c6bb733d 845
87e20041 846 case SSA_NAME:
847 gcc_assert (-1 != parameter_index_in_region_1 (e, SCOP_REGION (s)));
848 res = extract_affine_name (s, e, space);
849 break;
c6bb733d 850
87e20041 851 case INTEGER_CST:
852 res = extract_affine_int (e, space);
853 /* No need to wrap a single integer. */
854 return res;
c6bb733d 855
87e20041 856 CASE_CONVERT:
857 case NON_LVALUE_EXPR:
858 res = extract_affine (s, TREE_OPERAND (e, 0), space);
859 break;
c6bb733d 860
87e20041 861 default:
862 gcc_unreachable ();
863 break;
864 }
c6bb733d 865
87e20041 866 type = TREE_TYPE (e);
867 if (TYPE_UNSIGNED (type))
868 res = wrap (res, TYPE_PRECISION (type));
c6bb733d 869
87e20041 870 return res;
871}
c6bb733d 872
87e20041 873/* In the context of sese S, scan the expression E and translate it to
874 a linear expression C. When parsing a symbolic multiplication, K
875 represents the constant multiplier of an expression containing
876 parameters. */
c6bb733d 877
87e20041 878static void
879scan_tree_for_params (sese s, tree e)
880{
881 if (e == chrec_dont_know)
882 return;
c6bb733d 883
87e20041 884 switch (TREE_CODE (e))
885 {
886 case POLYNOMIAL_CHREC:
887 scan_tree_for_params (s, CHREC_LEFT (e));
888 break;
c6bb733d 889
87e20041 890 case MULT_EXPR:
891 if (chrec_contains_symbols (TREE_OPERAND (e, 0)))
892 scan_tree_for_params (s, TREE_OPERAND (e, 0));
893 else
894 scan_tree_for_params (s, TREE_OPERAND (e, 1));
895 break;
c6bb733d 896
87e20041 897 case PLUS_EXPR:
898 case POINTER_PLUS_EXPR:
899 case MINUS_EXPR:
900 scan_tree_for_params (s, TREE_OPERAND (e, 0));
901 scan_tree_for_params (s, TREE_OPERAND (e, 1));
c6bb733d 902 break;
903
87e20041 904 case NEGATE_EXPR:
905 case BIT_NOT_EXPR:
c6bb733d 906 CASE_CONVERT:
907 case NON_LVALUE_EXPR:
87e20041 908 scan_tree_for_params (s, TREE_OPERAND (e, 0));
c6bb733d 909 break;
910
87e20041 911 case SSA_NAME:
912 parameter_index_in_region (e, s);
913 break;
914
915 case INTEGER_CST:
a1b6cd6a 916 case ADDR_EXPR:
917 break;
918
c6bb733d 919 default:
920 gcc_unreachable ();
921 break;
922 }
923}
924
c6bb733d 925/* Find parameters with respect to REGION in BB. We are looking in memory
926 access functions, conditions and loop bounds. */
927
928static void
929find_params_in_bb (sese region, gimple_bb_p gbb)
930{
931 int i;
db899978 932 unsigned j;
c6bb733d 933 data_reference_p dr;
934 gimple stmt;
935 loop_p loop = GBB_BB (gbb)->loop_father;
c6bb733d 936
db899978 937 /* Find parameters in the access functions of data references. */
f1f41a6c 938 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
db899978 939 for (j = 0; j < DR_NUM_DIMENSIONS (dr); j++)
87e20041 940 scan_tree_for_params (region, DR_ACCESS_FN (dr, j));
c6bb733d 941
942 /* Find parameters in conditional statements. */
f1f41a6c 943 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
c6bb733d 944 {
c6bb733d 945 tree lhs = scalar_evolution_in_region (region, loop,
946 gimple_cond_lhs (stmt));
947 tree rhs = scalar_evolution_in_region (region, loop,
948 gimple_cond_rhs (stmt));
949
87e20041 950 scan_tree_for_params (region, lhs);
951 scan_tree_for_params (region, rhs);
c6bb733d 952 }
953}
954
955/* Record the parameters used in the SCOP. A variable is a parameter
956 in a scop if it does not vary during the execution of that scop. */
957
958static void
959find_scop_parameters (scop_p scop)
960{
961 poly_bb_p pbb;
962 unsigned i;
963 sese region = SCOP_REGION (scop);
964 struct loop *loop;
87e20041 965 int nbp;
c6bb733d 966
967 /* Find the parameters used in the loop bounds. */
f1f41a6c 968 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
c6bb733d 969 {
970 tree nb_iters = number_of_latch_executions (loop);
971
972 if (!chrec_contains_symbols (nb_iters))
973 continue;
974
975 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
87e20041 976 scan_tree_for_params (region, nb_iters);
c6bb733d 977 }
978
c6bb733d 979 /* Find the parameters used in data accesses. */
f1f41a6c 980 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
c6bb733d 981 find_params_in_bb (region, PBB_BLACK_BOX (pbb));
982
87e20041 983 nbp = sese_nb_params (region);
984 scop_set_nb_params (scop, nbp);
c6bb733d 985 SESE_ADD_PARAMS (region) = false;
acb3969f 986
5d92ac74 987 {
87e20041 988 tree e;
989 isl_space *space = isl_space_set_alloc (scop->ctx, nbp, 0);
5d92ac74 990
f1f41a6c 991 FOR_EACH_VEC_ELT (SESE_PARAMS (region), i, e)
87e20041 992 space = isl_space_set_dim_id (space, isl_dim_param, i,
993 isl_id_for_ssa_name (scop, e));
5d92ac74 994
87e20041 995 scop->context = isl_set_universe (space);
5d92ac74 996 }
5d92ac74 997}
998
c6bb733d 999/* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
1000 the constraints for the surrounding loops. */
1001
1002static void
1003build_loop_iteration_domains (scop_p scop, struct loop *loop,
87e20041 1004 int nb,
1005 isl_set *outer, isl_set **doms)
c6bb733d 1006{
c6bb733d 1007 tree nb_iters = number_of_latch_executions (loop);
c6bb733d 1008 sese region = SCOP_REGION (scop);
1009
87e20041 1010 isl_set *inner = isl_set_copy (outer);
1011 isl_space *space;
1012 isl_constraint *c;
1013 int pos = isl_set_dim (outer, isl_dim_set);
ea48ac01 1014 isl_val *v;
87e20041 1015 mpz_t g;
1016
1017 mpz_init (g);
87e20041 1018
1019 inner = isl_set_add_dims (inner, isl_dim_set, 1);
1020 space = isl_set_get_space (inner);
c6bb733d 1021
1022 /* 0 <= loop_i */
87e20041 1023 c = isl_inequality_alloc
1024 (isl_local_space_from_space (isl_space_copy (space)));
1025 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, 1);
1026 inner = isl_set_add_constraint (inner, c);
c6bb733d 1027
87e20041 1028 /* loop_i <= cst_nb_iters */
c6bb733d 1029 if (TREE_CODE (nb_iters) == INTEGER_CST)
1030 {
87e20041 1031 c = isl_inequality_alloc
9af5ce0c 1032 (isl_local_space_from_space (isl_space_copy (space)));
87e20041 1033 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
1034 tree_int_to_gmp (nb_iters, g);
ea48ac01 1035 v = isl_val_int_from_gmp (the_isl_ctx, g);
1036 c = isl_constraint_set_constant_val (c, v);
87e20041 1037 inner = isl_set_add_constraint (inner, c);
c6bb733d 1038 }
87e20041 1039
1040 /* loop_i <= expr_nb_iters */
c6bb733d 1041 else if (!chrec_contains_undetermined (nb_iters))
1042 {
5de9d3ed 1043 widest_int nit;
87e20041 1044 isl_pw_aff *aff;
1045 isl_set *valid;
1046 isl_local_space *ls;
1047 isl_aff *al;
1048 isl_set *le;
c6bb733d 1049
c6bb733d 1050 nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
87e20041 1051
1052 aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
1053 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
1054 valid = isl_set_project_out (valid, isl_dim_set, 0,
1055 isl_set_dim (valid, isl_dim_set));
1056 scop->context = isl_set_intersect (scop->context, valid);
1057
1058 ls = isl_local_space_from_space (isl_space_copy (space));
1059 al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
1060 isl_dim_in, pos, 1);
1061 le = isl_pw_aff_le_set (isl_pw_aff_from_aff (al),
1062 isl_pw_aff_copy (aff));
1063 inner = isl_set_intersect (inner, le);
c6bb733d 1064
fee017b3 1065 if (max_stmt_executions (loop, &nit))
87e20041 1066 {
1067 /* Insert in the context the constraints from the
1068 estimation of the number of iterations NIT and the
1069 symbolic number of iterations (involving parameter
1070 names) NB_ITERS. First, build the affine expression
1071 "NIT - NB_ITERS" and then say that it is positive,
1072 i.e., NIT approximates NB_ITERS: "NIT >= NB_ITERS". */
1073 isl_pw_aff *approx;
1074 mpz_t g;
1075 isl_set *x;
1076 isl_constraint *c;
1077
1078 mpz_init (g);
796b6678 1079 wi::to_mpz (nit, g, SIGNED);
87e20041 1080 mpz_sub_ui (g, g, 1);
1081 approx = extract_affine_gmp (g, isl_set_get_space (inner));
1082 x = isl_pw_aff_ge_set (approx, aff);
1083 x = isl_set_project_out (x, isl_dim_set, 0,
1084 isl_set_dim (x, isl_dim_set));
1085 scop->context = isl_set_intersect (scop->context, x);
1086
1087 c = isl_inequality_alloc
1088 (isl_local_space_from_space (isl_space_copy (space)));
1089 c = isl_constraint_set_coefficient_si (c, isl_dim_set, pos, -1);
ea48ac01 1090 v = isl_val_int_from_gmp (the_isl_ctx, g);
87e20041 1091 mpz_clear (g);
ea48ac01 1092 c = isl_constraint_set_constant_val (c, v);
87e20041 1093 inner = isl_set_add_constraint (inner, c);
1094 }
3fb5ff55 1095 else
1096 isl_pw_aff_free (aff);
c6bb733d 1097 }
1098 else
1099 gcc_unreachable ();
1100
1101 if (loop->inner && loop_in_sese_p (loop->inner, region))
87e20041 1102 build_loop_iteration_domains (scop, loop->inner, nb + 1,
1103 isl_set_copy (inner), doms);
c6bb733d 1104
1105 if (nb != 0
1106 && loop->next
1107 && loop_in_sese_p (loop->next, region))
87e20041 1108 build_loop_iteration_domains (scop, loop->next, nb,
1109 isl_set_copy (outer), doms);
c6bb733d 1110
87e20041 1111 doms[loop->num] = inner;
c6bb733d 1112
87e20041 1113 isl_set_free (outer);
1114 isl_space_free (space);
87e20041 1115 mpz_clear (g);
c6bb733d 1116}
1117
1118/* Returns a linear expression for tree T evaluated in PBB. */
1119
87e20041 1120static isl_pw_aff *
1121create_pw_aff_from_tree (poly_bb_p pbb, tree t)
c6bb733d 1122{
87e20041 1123 scop_p scop = PBB_SCOP (pbb);
c6bb733d 1124
87e20041 1125 t = scalar_evolution_in_region (SCOP_REGION (scop), pbb_loop (pbb), t);
c6bb733d 1126 gcc_assert (!automatically_generated_chrec_p (t));
1127
87e20041 1128 return extract_affine (scop, t, isl_set_get_space (pbb->domain));
c6bb733d 1129}
1130
87e20041 1131/* Add conditional statement STMT to pbb. CODE is used as the comparison
1132 operator. This allows us to invert the condition or to handle
1133 inequalities. */
c6bb733d 1134
1135static void
87e20041 1136add_condition_to_pbb (poly_bb_p pbb, gimple stmt, enum tree_code code)
c6bb733d 1137{
87e20041 1138 isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
1139 isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
1140 isl_set *cond;
c6bb733d 1141
87e20041 1142 switch (code)
c6bb733d 1143 {
87e20041 1144 case LT_EXPR:
1145 cond = isl_pw_aff_lt_set (lhs, rhs);
1146 break;
c6bb733d 1147
87e20041 1148 case GT_EXPR:
1149 cond = isl_pw_aff_gt_set (lhs, rhs);
1150 break;
c6bb733d 1151
87e20041 1152 case LE_EXPR:
1153 cond = isl_pw_aff_le_set (lhs, rhs);
1154 break;
c6bb733d 1155
87e20041 1156 case GE_EXPR:
1157 cond = isl_pw_aff_ge_set (lhs, rhs);
1158 break;
c6bb733d 1159
87e20041 1160 case EQ_EXPR:
1161 cond = isl_pw_aff_eq_set (lhs, rhs);
1162 break;
c6bb733d 1163
87e20041 1164 case NE_EXPR:
1165 cond = isl_pw_aff_ne_set (lhs, rhs);
1166 break;
c6bb733d 1167
87e20041 1168 default:
9af5ce0c 1169 isl_pw_aff_free (lhs);
1170 isl_pw_aff_free (rhs);
87e20041 1171 return;
c6bb733d 1172 }
87e20041 1173
1174 cond = isl_set_coalesce (cond);
1175 cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
1176 pbb->domain = isl_set_intersect (pbb->domain, cond);
c6bb733d 1177}
1178
1179/* Add conditions to the domain of PBB. */
1180
1181static void
1182add_conditions_to_domain (poly_bb_p pbb)
1183{
1184 unsigned int i;
1185 gimple stmt;
1186 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
c6bb733d 1187
f1f41a6c 1188 if (GBB_CONDITIONS (gbb).is_empty ())
c6bb733d 1189 return;
1190
f1f41a6c 1191 FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
c6bb733d 1192 switch (gimple_code (stmt))
1193 {
1194 case GIMPLE_COND:
1195 {
1196 enum tree_code code = gimple_cond_code (stmt);
1197
1198 /* The conditions for ELSE-branches are inverted. */
f1f41a6c 1199 if (!GBB_CONDITION_CASES (gbb)[i])
c6bb733d 1200 code = invert_tree_comparison (code, false);
1201
1202 add_condition_to_pbb (pbb, stmt, code);
1203 break;
1204 }
1205
1206 case GIMPLE_SWITCH:
87e20041 1207 /* Switch statements are not supported right now - fall through. */
c6bb733d 1208
1209 default:
1210 gcc_unreachable ();
1211 break;
1212 }
1213}
1214
8c6b3774 1215/* Traverses all the GBBs of the SCOP and add their constraints to the
1216 iteration domains. */
1217
1218static void
1219add_conditions_to_constraints (scop_p scop)
1220{
1221 int i;
1222 poly_bb_p pbb;
1223
f1f41a6c 1224 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
8c6b3774 1225 add_conditions_to_domain (pbb);
1226}
1227
dff64cac 1228/* Returns a COND_EXPR statement when BB has a single predecessor, the
1229 edge between BB and its predecessor is not a loop exit edge, and
1230 the last statement of the single predecessor is a COND_EXPR. */
c6bb733d 1231
1232static gimple
dff64cac 1233single_pred_cond_non_loop_exit (basic_block bb)
c6bb733d 1234{
1235 if (single_pred_p (bb))
1236 {
1237 edge e = single_pred_edge (bb);
1238 basic_block pred = e->src;
dff64cac 1239 gimple stmt;
1240
1241 if (loop_depth (pred->loop_father) > loop_depth (bb->loop_father))
1242 return NULL;
1243
1244 stmt = last_stmt (pred);
c6bb733d 1245
1246 if (stmt && gimple_code (stmt) == GIMPLE_COND)
1247 return stmt;
1248 }
dff64cac 1249
c6bb733d 1250 return NULL;
1251}
1252
54c91640 1253class sese_dom_walker : public dom_walker
1254{
1255public:
1256 sese_dom_walker (cdi_direction, sese);
54c91640 1257
1258 virtual void before_dom_children (basic_block);
1259 virtual void after_dom_children (basic_block);
1260
1261private:
4997014d 1262 auto_vec<gimple, 3> m_conditions, m_cases;
ae84f584 1263 sese m_region;
54c91640 1264};
1265
1266sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
ae84f584 1267 : dom_walker (direction), m_region (region)
54c91640 1268{
54c91640 1269}
1270
c6bb733d 1271/* Call-back for dom_walk executed before visiting the dominated
1272 blocks. */
1273
54c91640 1274void
1275sese_dom_walker::before_dom_children (basic_block bb)
c6bb733d 1276{
d3746d81 1277 gimple_bb_p gbb;
1278 gimple stmt;
c6bb733d 1279
ae84f584 1280 if (!bb_in_sese_p (bb, m_region))
c6bb733d 1281 return;
1282
dff64cac 1283 stmt = single_pred_cond_non_loop_exit (bb);
d3746d81 1284
c6bb733d 1285 if (stmt)
1286 {
1287 edge e = single_pred_edge (bb);
1288
ae84f584 1289 m_conditions.safe_push (stmt);
c6bb733d 1290
1291 if (e->flags & EDGE_TRUE_VALUE)
ae84f584 1292 m_cases.safe_push (stmt);
c6bb733d 1293 else
ae84f584 1294 m_cases.safe_push (NULL);
c6bb733d 1295 }
1296
d3746d81 1297 gbb = gbb_from_bb (bb);
1298
c6bb733d 1299 if (gbb)
1300 {
ae84f584 1301 GBB_CONDITIONS (gbb) = m_conditions.copy ();
1302 GBB_CONDITION_CASES (gbb) = m_cases.copy ();
c6bb733d 1303 }
1304}
1305
1306/* Call-back for dom_walk executed after visiting the dominated
1307 blocks. */
1308
54c91640 1309void
1310sese_dom_walker::after_dom_children (basic_block bb)
c6bb733d 1311{
ae84f584 1312 if (!bb_in_sese_p (bb, m_region))
c6bb733d 1313 return;
1314
dff64cac 1315 if (single_pred_cond_non_loop_exit (bb))
c6bb733d 1316 {
ae84f584 1317 m_conditions.pop ();
1318 m_cases.pop ();
c6bb733d 1319 }
1320}
1321
c6bb733d 1322/* Add constraints on the possible values of parameter P from the type
1323 of P. */
1324
1325static void
87e20041 1326add_param_constraints (scop_p scop, graphite_dim_t p)
c6bb733d 1327{
f1f41a6c 1328 tree parameter = SESE_PARAMS (SCOP_REGION (scop))[p];
c6bb733d 1329 tree type = TREE_TYPE (parameter);
88a62e9b 1330 tree lb = NULL_TREE;
1331 tree ub = NULL_TREE;
c6bb733d 1332
8424df5f 1333 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
1334 lb = lower_bound_in_type (type, type);
1335 else
1336 lb = TYPE_MIN_VALUE (type);
1337
1338 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
1339 ub = upper_bound_in_type (type, type);
1340 else
1341 ub = TYPE_MAX_VALUE (type);
c6bb733d 1342
1343 if (lb)
1344 {
87e20041 1345 isl_space *space = isl_set_get_space (scop->context);
1346 isl_constraint *c;
1347 mpz_t g;
ea48ac01 1348 isl_val *v;
87e20041 1349
1350 c = isl_inequality_alloc (isl_local_space_from_space (space));
1351 mpz_init (g);
87e20041 1352 tree_int_to_gmp (lb, g);
ea48ac01 1353 v = isl_val_int_from_gmp (the_isl_ctx, g);
1354 v = isl_val_neg (v);
87e20041 1355 mpz_clear (g);
ea48ac01 1356 c = isl_constraint_set_constant_val (c, v);
87e20041 1357 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, 1);
1358
1359 scop->context = isl_set_add_constraint (scop->context, c);
c6bb733d 1360 }
1361
1362 if (ub)
1363 {
87e20041 1364 isl_space *space = isl_set_get_space (scop->context);
1365 isl_constraint *c;
1366 mpz_t g;
ea48ac01 1367 isl_val *v;
87e20041 1368
1369 c = isl_inequality_alloc (isl_local_space_from_space (space));
1370
1371 mpz_init (g);
87e20041 1372 tree_int_to_gmp (ub, g);
ea48ac01 1373 v = isl_val_int_from_gmp (the_isl_ctx, g);
87e20041 1374 mpz_clear (g);
ea48ac01 1375 c = isl_constraint_set_constant_val (c, v);
87e20041 1376 c = isl_constraint_set_coefficient_si (c, isl_dim_param, p, -1);
1377
1378 scop->context = isl_set_add_constraint (scop->context, c);
c6bb733d 1379 }
1380}
1381
1382/* Build the context of the SCOP. The context usually contains extra
1383 constraints that are added to the iteration domains that constrain
1384 some parameters. */
1385
1386static void
1387build_scop_context (scop_p scop)
1388{
c6bb733d 1389 graphite_dim_t p, n = scop_nb_params (scop);
1390
c6bb733d 1391 for (p = 0; p < n; p++)
87e20041 1392 add_param_constraints (scop, p);
c6bb733d 1393}
1394
1395/* Build the iteration domains: the loops belonging to the current
1396 SCOP, and that vary for the execution of the current basic block.
1397 Returns false if there is no loop in SCOP. */
1398
1399static void
1400build_scop_iteration_domain (scop_p scop)
1401{
1402 struct loop *loop;
1403 sese region = SCOP_REGION (scop);
1404 int i;
c6bb733d 1405 poly_bb_p pbb;
41f75a99 1406 int nb_loops = number_of_loops (cfun);
87e20041 1407 isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
c6bb733d 1408
f1f41a6c 1409 FOR_EACH_VEC_ELT (SESE_LOOP_NEST (region), i, loop)
c6bb733d 1410 if (!loop_in_sese_p (loop_outer (loop), region))
87e20041 1411 build_loop_iteration_domains (scop, loop, 0,
1412 isl_set_copy (scop->context), doms);
c6bb733d 1413
f1f41a6c 1414 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
87e20041 1415 {
1416 loop = pbb_loop (pbb);
1417
1418 if (doms[loop->num])
1419 pbb->domain = isl_set_copy (doms[loop->num]);
1420 else
1421 pbb->domain = isl_set_copy (scop->context);
1422
1423 pbb->domain = isl_set_set_tuple_id (pbb->domain,
1424 isl_id_for_pbb (scop, pbb));
1425 }
c6bb733d 1426
628eaf60 1427 for (i = 0; i < nb_loops; i++)
87e20041 1428 if (doms[i])
1429 isl_set_free (doms[i]);
c6bb733d 1430
87e20041 1431 free (doms);
c6bb733d 1432}
1433
1434/* Add a constrain to the ACCESSES polyhedron for the alias set of
1435 data reference DR. ACCESSP_NB_DIMS is the dimension of the
1436 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
1437 domain. */
1438
87e20041 1439static isl_map *
1440pdr_add_alias_set (isl_map *acc, data_reference_p dr)
c6bb733d 1441{
87e20041 1442 isl_constraint *c;
c6bb733d 1443 int alias_set_num = 0;
e9a3f95f 1444 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
c6bb733d 1445
1a95516e 1446 if (bap && bap->alias_set)
e9a3f95f 1447 alias_set_num = *(bap->alias_set);
c6bb733d 1448
87e20041 1449 c = isl_equality_alloc
1450 (isl_local_space_from_space (isl_map_get_space (acc)));
1451 c = isl_constraint_set_constant_si (c, -alias_set_num);
1452 c = isl_constraint_set_coefficient_si (c, isl_dim_out, 0, 1);
1453
1454 return isl_map_add_constraint (acc, c);
1455}
1456
1457/* Assign the affine expression INDEX to the output dimension POS of
1458 MAP and return the result. */
1459
1460static isl_map *
1461set_index (isl_map *map, int pos, isl_pw_aff *index)
1462{
1463 isl_map *index_map;
1464 int len = isl_map_dim (map, isl_dim_out);
1465 isl_id *id;
1466
1467 index_map = isl_map_from_pw_aff (index);
1468 index_map = isl_map_insert_dims (index_map, isl_dim_out, 0, pos);
1469 index_map = isl_map_add_dims (index_map, isl_dim_out, len - pos - 1);
c6bb733d 1470
87e20041 1471 id = isl_map_get_tuple_id (map, isl_dim_out);
1472 index_map = isl_map_set_tuple_id (index_map, isl_dim_out, id);
1473 id = isl_map_get_tuple_id (map, isl_dim_in);
1474 index_map = isl_map_set_tuple_id (index_map, isl_dim_in, id);
c6bb733d 1475
87e20041 1476 return isl_map_intersect (map, index_map);
c6bb733d 1477}
1478
1479/* Add to ACCESSES polyhedron equalities defining the access functions
1480 to the memory. ACCESSP_NB_DIMS is the dimension of the ACCESSES
1481 polyhedron, DOM_NB_DIMS is the dimension of the iteration domain.
1482 PBB is the poly_bb_p that contains the data reference DR. */
1483
87e20041 1484static isl_map *
1485pdr_add_memory_accesses (isl_map *acc, data_reference_p dr, poly_bb_p pbb)
c6bb733d 1486{
1487 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
c6bb733d 1488 scop_p scop = PBB_SCOP (pbb);
c6bb733d 1489
1490 for (i = 0; i < nb_subscripts; i++)
1491 {
87e20041 1492 isl_pw_aff *aff;
c6bb733d 1493 tree afn = DR_ACCESS_FN (dr, nb_subscripts - 1 - i);
1494
87e20041 1495 aff = extract_affine (scop, afn,
1496 isl_space_domain (isl_map_get_space (acc)));
1497 acc = set_index (acc, i + 1, aff);
c6bb733d 1498 }
1499
87e20041 1500 return acc;
c6bb733d 1501}
1502
1503/* Add constrains representing the size of the accessed data to the
19b42529 1504 ACCESSES polyhedron. ACCESSP_NB_DIMS is the dimension of the
1505 ACCESSES polyhedron, DOM_NB_DIMS is the dimension of the iteration
c6bb733d 1506 domain. */
1507
87e20041 1508static isl_set *
1509pdr_add_data_dimensions (isl_set *extent, scop_p scop, data_reference_p dr)
c6bb733d 1510{
1511 tree ref = DR_REF (dr);
1512 int i, nb_subscripts = DR_NUM_DIMENSIONS (dr);
c6bb733d 1513
249d544d 1514 for (i = nb_subscripts - 1; i >= 0; i--, ref = TREE_OPERAND (ref, 0))
c6bb733d 1515 {
249d544d 1516 tree low, high;
c6bb733d 1517
249d544d 1518 if (TREE_CODE (ref) != ARRAY_REF)
c6bb733d 1519 break;
1520
249d544d 1521 low = array_ref_low_bound (ref);
249d544d 1522 high = array_ref_up_bound (ref);
1523
87e20041 1524 /* XXX The PPL code dealt separately with
1525 subscript - low >= 0 and high - subscript >= 0 in case one of
1526 the two bounds isn't known. Do the same here? */
1527
e913b5cd 1528 if (tree_fits_shwi_p (low)
87e20041 1529 && high
e913b5cd 1530 && tree_fits_shwi_p (high)
3354e72e 1531 /* 1-element arrays at end of structures may extend over
1532 their declared size. */
1533 && !(array_at_struct_end_p (ref)
1534 && operand_equal_p (low, high, 0)))
249d544d 1535 {
87e20041 1536 isl_id *id;
1537 isl_aff *aff;
1538 isl_set *univ, *lbs, *ubs;
1539 isl_pw_aff *index;
1540 isl_space *space;
1541 isl_set *valid;
1542 isl_pw_aff *lb = extract_affine_int (low, isl_set_get_space (extent));
1543 isl_pw_aff *ub = extract_affine_int (high, isl_set_get_space (extent));
1544
1545 /* high >= 0 */
1546 valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (ub));
1547 valid = isl_set_project_out (valid, isl_dim_set, 0,
1548 isl_set_dim (valid, isl_dim_set));
1549 scop->context = isl_set_intersect (scop->context, valid);
1550
1551 space = isl_set_get_space (extent);
1552 aff = isl_aff_zero_on_domain (isl_local_space_from_space (space));
1553 aff = isl_aff_add_coefficient_si (aff, isl_dim_in, i + 1, 1);
1554 univ = isl_set_universe (isl_space_domain (isl_aff_get_space (aff)));
1555 index = isl_pw_aff_alloc (univ, aff);
1556
1557 id = isl_set_get_tuple_id (extent);
1558 lb = isl_pw_aff_set_tuple_id (lb, isl_dim_in, isl_id_copy (id));
1559 ub = isl_pw_aff_set_tuple_id (ub, isl_dim_in, id);
1560
1561 /* low <= sub_i <= high */
1562 lbs = isl_pw_aff_ge_set (isl_pw_aff_copy (index), lb);
1563 ubs = isl_pw_aff_le_set (index, ub);
1564 extent = isl_set_intersect (extent, lbs);
1565 extent = isl_set_intersect (extent, ubs);
249d544d 1566 }
c6bb733d 1567 }
87e20041 1568
1569 return extent;
c6bb733d 1570}
1571
1572/* Build data accesses for DR in PBB. */
1573
1574static void
1575build_poly_dr (data_reference_p dr, poly_bb_p pbb)
1576{
ae11f03b 1577 int dr_base_object_set;
87e20041 1578 isl_map *acc;
1579 isl_set *extent;
1580 scop_p scop = PBB_SCOP (pbb);
c6bb733d 1581
87e20041 1582 {
1583 isl_space *dc = isl_set_get_space (pbb->domain);
1584 int nb_out = 1 + DR_NUM_DIMENSIONS (dr);
1585 isl_space *space = isl_space_add_dims (isl_space_from_domain (dc),
1586 isl_dim_out, nb_out);
c6bb733d 1587
87e20041 1588 acc = isl_map_universe (space);
1589 acc = isl_map_set_tuple_id (acc, isl_dim_out, isl_id_for_dr (scop, dr));
1590 }
c6bb733d 1591
87e20041 1592 acc = pdr_add_alias_set (acc, dr);
1593 acc = pdr_add_memory_accesses (acc, dr, pbb);
c6bb733d 1594
87e20041 1595 {
1596 isl_id *id = isl_id_for_dr (scop, dr);
1597 int nb = 1 + DR_NUM_DIMENSIONS (dr);
1598 isl_space *space = isl_space_set_alloc (scop->ctx, 0, nb);
1599 int alias_set_num = 0;
1600 base_alias_pair *bap = (base_alias_pair *)(dr->aux);
1601
1602 if (bap && bap->alias_set)
1603 alias_set_num = *(bap->alias_set);
1604
1605 space = isl_space_set_tuple_id (space, isl_dim_set, id);
1606 extent = isl_set_nat_universe (space);
1607 extent = isl_set_fix_si (extent, isl_dim_set, 0, alias_set_num);
1608 extent = pdr_add_data_dimensions (extent, scop, dr);
1609 }
c6bb733d 1610
3ebac17a 1611 gcc_assert (dr->aux);
1612 dr_base_object_set = ((base_alias_pair *)(dr->aux))->base_obj_set;
ae11f03b 1613
87e20041 1614 new_poly_dr (pbb, dr_base_object_set,
3ebac17a 1615 DR_IS_READ (dr) ? PDR_READ : PDR_WRITE,
87e20041 1616 dr, DR_NUM_DIMENSIONS (dr), acc, extent);
ae11f03b 1617}
c6bb733d 1618
96233858 1619/* Write to FILE the alias graph of data references in DIMACS format. */
8dee37ec 1620
1621static inline bool
1622write_alias_graph_to_ascii_dimacs (FILE *file, char *comment,
f1f41a6c 1623 vec<data_reference_p> drs)
8dee37ec 1624{
f1f41a6c 1625 int num_vertex = drs.length ();
8dee37ec 1626 int edge_num = 0;
1627 data_reference_p dr1, dr2;
1628 int i, j;
1629
1630 if (num_vertex == 0)
1631 return true;
1632
f1f41a6c 1633 FOR_EACH_VEC_ELT (drs, i, dr1)
1634 for (j = i + 1; drs.iterate (j, &dr2); j++)
5fc88ffd 1635 if (dr_may_alias_p (dr1, dr2, true))
8dee37ec 1636 edge_num++;
1637
1638 fprintf (file, "$\n");
1639
1640 if (comment)
1641 fprintf (file, "c %s\n", comment);
1642
1643 fprintf (file, "p edge %d %d\n", num_vertex, edge_num);
1644
f1f41a6c 1645 FOR_EACH_VEC_ELT (drs, i, dr1)
1646 for (j = i + 1; drs.iterate (j, &dr2); j++)
5fc88ffd 1647 if (dr_may_alias_p (dr1, dr2, true))
8dee37ec 1648 fprintf (file, "e %d %d\n", i + 1, j + 1);
1649
1650 return true;
1651}
1652
96233858 1653/* Write to FILE the alias graph of data references in DOT format. */
1654
1655static inline bool
1656write_alias_graph_to_ascii_dot (FILE *file, char *comment,
f1f41a6c 1657 vec<data_reference_p> drs)
96233858 1658{
f1f41a6c 1659 int num_vertex = drs.length ();
96233858 1660 data_reference_p dr1, dr2;
1661 int i, j;
1662
1663 if (num_vertex == 0)
1664 return true;
1665
1666 fprintf (file, "$\n");
1667
1668 if (comment)
1669 fprintf (file, "c %s\n", comment);
1670
1671 /* First print all the vertices. */
f1f41a6c 1672 FOR_EACH_VEC_ELT (drs, i, dr1)
96233858 1673 fprintf (file, "n%d;\n", i);
1674
f1f41a6c 1675 FOR_EACH_VEC_ELT (drs, i, dr1)
1676 for (j = i + 1; drs.iterate (j, &dr2); j++)
5fc88ffd 1677 if (dr_may_alias_p (dr1, dr2, true))
96233858 1678 fprintf (file, "n%d n%d\n", i, j);
1679
1680 return true;
1681}
1682
1683/* Write to FILE the alias graph of data references in ECC format. */
1684
1685static inline bool
1686write_alias_graph_to_ascii_ecc (FILE *file, char *comment,
f1f41a6c 1687 vec<data_reference_p> drs)
96233858 1688{
f1f41a6c 1689 int num_vertex = drs.length ();
96233858 1690 data_reference_p dr1, dr2;
1691 int i, j;
1692
1693 if (num_vertex == 0)
1694 return true;
1695
1696 fprintf (file, "$\n");
1697
1698 if (comment)
1699 fprintf (file, "c %s\n", comment);
1700
f1f41a6c 1701 FOR_EACH_VEC_ELT (drs, i, dr1)
1702 for (j = i + 1; drs.iterate (j, &dr2); j++)
5fc88ffd 1703 if (dr_may_alias_p (dr1, dr2, true))
96233858 1704 fprintf (file, "%d %d\n", i, j);
1705
1706 return true;
1707}
1708
e9a3f95f 1709/* Check if DR1 and DR2 are in the same object set. */
1710
1711static bool
1712dr_same_base_object_p (const struct data_reference *dr1,
1713 const struct data_reference *dr2)
1714{
1715 return operand_equal_p (DR_BASE_OBJECT (dr1), DR_BASE_OBJECT (dr2), 0);
1716}
96233858 1717
1718/* Uses DFS component number as representative of alias-sets. Also tests for
1719 optimality by verifying if every connected component is a clique. Returns
1720 true (1) if the above test is true, and false (0) otherwise. */
1721
1722static int
f1f41a6c 1723build_alias_set_optimal_p (vec<data_reference_p> drs)
c6bb733d 1724{
f1f41a6c 1725 int num_vertices = drs.length ();
96233858 1726 struct graph *g = new_graph (num_vertices);
c6bb733d 1727 data_reference_p dr1, dr2;
1728 int i, j;
96233858 1729 int num_connected_components;
1730 int v_indx1, v_indx2, num_vertices_in_component;
1731 int *all_vertices;
1732 int *vertices;
1733 struct graph_edge *e;
f289f81b 1734 int this_component_is_clique;
1735 int all_components_are_cliques = 1;
c6bb733d 1736
f1f41a6c 1737 FOR_EACH_VEC_ELT (drs, i, dr1)
1738 for (j = i+1; drs.iterate (j, &dr2); j++)
5fc88ffd 1739 if (dr_may_alias_p (dr1, dr2, true))
c6bb733d 1740 {
1741 add_edge (g, i, j);
1742 add_edge (g, j, i);
1743 }
1744
96233858 1745 all_vertices = XNEWVEC (int, num_vertices);
1746 vertices = XNEWVEC (int, num_vertices);
1747 for (i = 0; i < num_vertices; i++)
1748 all_vertices[i] = i;
1749
e9a3f95f 1750 num_connected_components = graphds_dfs (g, all_vertices, num_vertices,
1751 NULL, true, NULL);
1752 for (i = 0; i < g->n_vertices; i++)
1753 {
f1f41a6c 1754 data_reference_p dr = drs[i];
e9a3f95f 1755 base_alias_pair *bap;
1a95516e 1756
3ebac17a 1757 gcc_assert (dr->aux);
1758 bap = (base_alias_pair *)(dr->aux);
1a95516e 1759
e9a3f95f 1760 bap->alias_set = XNEW (int);
1761 *(bap->alias_set) = g->vertices[i].component + 1;
1762 }
1763
96233858 1764 /* Verify if the DFS numbering results in optimal solution. */
1765 for (i = 0; i < num_connected_components; i++)
1766 {
1767 num_vertices_in_component = 0;
1768 /* Get all vertices whose DFS component number is the same as i. */
1769 for (j = 0; j < num_vertices; j++)
1770 if (g->vertices[j].component == i)
1771 vertices[num_vertices_in_component++] = j;
1772
1773 /* Now test if the vertices in 'vertices' form a clique, by testing
1774 for edges among each pair. */
1775 this_component_is_clique = 1;
1776 for (v_indx1 = 0; v_indx1 < num_vertices_in_component; v_indx1++)
1777 {
1778 for (v_indx2 = v_indx1+1; v_indx2 < num_vertices_in_component; v_indx2++)
1779 {
1780 /* Check if the two vertices are connected by iterating
1781 through all the edges which have one of these are source. */
1782 e = g->vertices[vertices[v_indx2]].pred;
1783 while (e)
1784 {
1785 if (e->src == vertices[v_indx1])
1786 break;
1787 e = e->pred_next;
1788 }
1789 if (!e)
1790 {
1791 this_component_is_clique = 0;
1792 break;
1793 }
1794 }
1795 if (!this_component_is_clique)
1796 all_components_are_cliques = 0;
1797 }
1798 }
c6bb733d 1799
96233858 1800 free (all_vertices);
1801 free (vertices);
c6bb733d 1802 free_graph (g);
96233858 1803 return all_components_are_cliques;
c6bb733d 1804}
1805
8c6b3774 1806/* Group each data reference in DRS with its base object set num. */
ae11f03b 1807
1808static void
f1f41a6c 1809build_base_obj_set_for_drs (vec<data_reference_p> drs)
ae11f03b 1810{
f1f41a6c 1811 int num_vertex = drs.length ();
e9a3f95f 1812 struct graph *g = new_graph (num_vertex);
1813 data_reference_p dr1, dr2;
1814 int i, j;
e9a3f95f 1815 int *queue;
1816
f1f41a6c 1817 FOR_EACH_VEC_ELT (drs, i, dr1)
1818 for (j = i + 1; drs.iterate (j, &dr2); j++)
e9a3f95f 1819 if (dr_same_base_object_p (dr1, dr2))
1820 {
1821 add_edge (g, i, j);
1822 add_edge (g, j, i);
1823 }
1824
1825 queue = XNEWVEC (int, num_vertex);
1826 for (i = 0; i < num_vertex; i++)
1827 queue[i] = i;
1828
1a95516e 1829 graphds_dfs (g, queue, num_vertex, NULL, true, NULL);
e9a3f95f 1830
1831 for (i = 0; i < g->n_vertices; i++)
1832 {
f1f41a6c 1833 data_reference_p dr = drs[i];
e9a3f95f 1834 base_alias_pair *bap;
1a95516e 1835
3ebac17a 1836 gcc_assert (dr->aux);
1837 bap = (base_alias_pair *)(dr->aux);
1a95516e 1838
e9a3f95f 1839 bap->base_obj_set = g->vertices[i].component + 1;
1840 }
1841
1842 free (queue);
1843 free_graph (g);
ae11f03b 1844}
1845
c6bb733d 1846/* Build the data references for PBB. */
1847
1848static void
1849build_pbb_drs (poly_bb_p pbb)
1850{
1851 int j;
1852 data_reference_p dr;
f1f41a6c 1853 vec<data_reference_p> gbb_drs = GBB_DATA_REFS (PBB_BLACK_BOX (pbb));
c6bb733d 1854
f1f41a6c 1855 FOR_EACH_VEC_ELT (gbb_drs, j, dr)
c6bb733d 1856 build_poly_dr (dr, pbb);
1857}
1858
aa16918e 1859/* Dump to file the alias graphs for the data references in DRS. */
1860
1861static void
f1f41a6c 1862dump_alias_graphs (vec<data_reference_p> drs)
aa16918e 1863{
1864 char comment[100];
1865 FILE *file_dimacs, *file_ecc, *file_dot;
1866
1867 file_dimacs = fopen ("/tmp/dr_alias_graph_dimacs", "ab");
1868 if (file_dimacs)
1869 {
1870 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1871 current_function_name ());
1872 write_alias_graph_to_ascii_dimacs (file_dimacs, comment, drs);
1873 fclose (file_dimacs);
1874 }
1875
1876 file_ecc = fopen ("/tmp/dr_alias_graph_ecc", "ab");
1877 if (file_ecc)
1878 {
1879 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1880 current_function_name ());
1881 write_alias_graph_to_ascii_ecc (file_ecc, comment, drs);
1882 fclose (file_ecc);
1883 }
1884
1885 file_dot = fopen ("/tmp/dr_alias_graph_dot", "ab");
1886 if (file_dot)
1887 {
1888 snprintf (comment, sizeof (comment), "%s %s", main_input_filename,
1889 current_function_name ());
1890 write_alias_graph_to_ascii_dot (file_dot, comment, drs);
1891 fclose (file_dot);
1892 }
1893}
1894
c6bb733d 1895/* Build data references in SCOP. */
1896
1897static void
1898build_scop_drs (scop_p scop)
1899{
da6ec3dd 1900 int i, j;
c6bb733d 1901 poly_bb_p pbb;
da6ec3dd 1902 data_reference_p dr;
4997014d 1903 auto_vec<data_reference_p, 3> drs;
da6ec3dd 1904
8c6b3774 1905 /* Remove all the PBBs that do not have data references: these basic
1906 blocks are not handled in the polyhedral representation. */
f1f41a6c 1907 for (i = 0; SCOP_BBS (scop).iterate (i, &pbb); i++)
1908 if (GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).is_empty ())
1688f172 1909 {
bf0d0e76 1910 free_gimple_bb (PBB_BLACK_BOX (pbb));
479a6d79 1911 free_poly_bb (pbb);
f1f41a6c 1912 SCOP_BBS (scop).ordered_remove (i);
1688f172 1913 i--;
1914 }
8c6b3774 1915
f1f41a6c 1916 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
1917 for (j = 0; GBB_DATA_REFS (PBB_BLACK_BOX (pbb)).iterate (j, &dr); j++)
1918 drs.safe_push (dr);
da6ec3dd 1919
f1f41a6c 1920 FOR_EACH_VEC_ELT (drs, i, dr)
e9a3f95f 1921 dr->aux = XNEW (base_alias_pair);
1922
1923 if (!build_alias_set_optimal_p (drs))
1924 {
1925 /* TODO: Add support when building alias set is not optimal. */
1926 ;
1927 }
1928
9c48819a 1929 build_base_obj_set_for_drs (drs);
ae11f03b 1930
8dee37ec 1931 /* When debugging, enable the following code. This cannot be used
1932 in production compilers. */
aa16918e 1933 if (0)
1934 dump_alias_graphs (drs);
8dee37ec 1935
f1f41a6c 1936 drs.release ();
c6bb733d 1937
f1f41a6c 1938 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
c6bb733d 1939 build_pbb_drs (pbb);
1940}
1941
30f4f4a6 1942/* Return a gsi at the position of the phi node STMT. */
1943
1944static gimple_stmt_iterator
1945gsi_for_phi_node (gimple stmt)
1946{
1947 gimple_stmt_iterator psi;
1948 basic_block bb = gimple_bb (stmt);
1949
1950 for (psi = gsi_start_phis (bb); !gsi_end_p (psi); gsi_next (&psi))
1951 if (stmt == gsi_stmt (psi))
1952 return psi;
1953
1954 gcc_unreachable ();
1955 return psi;
1956}
1957
1688f172 1958/* Analyze all the data references of STMTS and add them to the
1959 GBB_DATA_REFS vector of BB. */
1960
1961static void
f1f41a6c 1962analyze_drs_in_stmts (scop_p scop, basic_block bb, vec<gimple> stmts)
1688f172 1963{
1964 loop_p nest;
1688f172 1965 gimple_bb_p gbb;
1966 gimple stmt;
1967 int i;
221a697e 1968 sese region = SCOP_REGION (scop);
1688f172 1969
221a697e 1970 if (!bb_in_sese_p (bb, region))
1688f172 1971 return;
1972
221a697e 1973 nest = outermost_loop_in_sese_1 (region, bb);
1688f172 1974 gbb = gbb_from_bb (bb);
1975
f1f41a6c 1976 FOR_EACH_VEC_ELT (stmts, i, stmt)
221a697e 1977 {
1978 loop_p loop;
1979
1980 if (is_gimple_debug (stmt))
1981 continue;
1982
1983 loop = loop_containing_stmt (stmt);
1984 if (!loop_in_sese_p (loop, region))
1985 loop = nest;
1986
1987 graphite_find_data_references_in_stmt (nest, loop, stmt,
1688f172 1988 &GBB_DATA_REFS (gbb));
221a697e 1989 }
1688f172 1990}
1991
1992/* Insert STMT at the end of the STMTS sequence and then insert the
1993 statements from STMTS at INSERT_GSI and call analyze_drs_in_stmts
1994 on STMTS. */
1995
1996static void
1997insert_stmts (scop_p scop, gimple stmt, gimple_seq stmts,
1998 gimple_stmt_iterator insert_gsi)
1999{
2000 gimple_stmt_iterator gsi;
4997014d 2001 auto_vec<gimple, 3> x;
1688f172 2002
e3a19533 2003 gimple_seq_add_stmt (&stmts, stmt);
1688f172 2004 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
f1f41a6c 2005 x.safe_push (gsi_stmt (gsi));
1688f172 2006
2007 gsi_insert_seq_before (&insert_gsi, stmts, GSI_SAME_STMT);
2008 analyze_drs_in_stmts (scop, gsi_bb (insert_gsi), x);
1688f172 2009}
2010
8c6b3774 2011/* Insert the assignment "RES := EXPR" just after AFTER_STMT. */
c6bb733d 2012
2013static void
1688f172 2014insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
c6bb733d 2015{
c6bb733d 2016 gimple_seq stmts;
52123e43 2017 gimple_stmt_iterator gsi;
8c6b3774 2018 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
11db727d 2019 gimple stmt = gimple_build_assign (unshare_expr (res), var);
4997014d 2020 auto_vec<gimple, 3> x;
c6bb733d 2021
e3a19533 2022 gimple_seq_add_stmt (&stmts, stmt);
1688f172 2023 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
f1f41a6c 2024 x.safe_push (gsi_stmt (gsi));
52123e43 2025
39a34dd8 2026 if (gimple_code (after_stmt) == GIMPLE_PHI)
52123e43 2027 {
39a34dd8 2028 gsi = gsi_after_labels (gimple_bb (after_stmt));
52123e43 2029 gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
2030 }
2031 else
2032 {
39a34dd8 2033 gsi = gsi_for_stmt (after_stmt);
52123e43 2034 gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
2035 }
1688f172 2036
2037 analyze_drs_in_stmts (scop, gimple_bb (after_stmt), x);
c6bb733d 2038}
2039
8c6b3774 2040/* Creates a poly_bb_p for basic_block BB from the existing PBB. */
2041
2042static void
2043new_pbb_from_pbb (scop_p scop, poly_bb_p pbb, basic_block bb)
2044{
f1f41a6c 2045 vec<data_reference_p> drs;
2046 drs.create (3);
8c6b3774 2047 gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
2048 gimple_bb_p gbb1 = new_gimple_bb (bb, drs);
2049 poly_bb_p pbb1 = new_poly_bb (scop, gbb1);
f1f41a6c 2050 int index, n = SCOP_BBS (scop).length ();
8c6b3774 2051
2052 /* The INDEX of PBB in SCOP_BBS. */
2053 for (index = 0; index < n; index++)
f1f41a6c 2054 if (SCOP_BBS (scop)[index] == pbb)
8c6b3774 2055 break;
2056
87e20041 2057 pbb1->domain = isl_set_copy (pbb->domain);
24bc4589 2058 pbb1->domain = isl_set_set_tuple_id (pbb1->domain,
2059 isl_id_for_pbb (scop, pbb1));
93f9c161 2060
8c6b3774 2061 GBB_PBB (gbb1) = pbb1;
f1f41a6c 2062 GBB_CONDITIONS (gbb1) = GBB_CONDITIONS (gbb).copy ();
2063 GBB_CONDITION_CASES (gbb1) = GBB_CONDITION_CASES (gbb).copy ();
2064 SCOP_BBS (scop).safe_insert (index + 1, pbb1);
8c6b3774 2065}
2066
c6bb733d 2067/* Insert on edge E the assignment "RES := EXPR". */
2068
2069static void
8c6b3774 2070insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
c6bb733d 2071{
2072 gimple_stmt_iterator gsi;
e3a19533 2073 gimple_seq stmts = NULL;
c6bb733d 2074 tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
11db727d 2075 gimple stmt = gimple_build_assign (unshare_expr (res), var);
8c6b3774 2076 basic_block bb;
4997014d 2077 auto_vec<gimple, 3> x;
c6bb733d 2078
e3a19533 2079 gimple_seq_add_stmt (&stmts, stmt);
1688f172 2080 for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
f1f41a6c 2081 x.safe_push (gsi_stmt (gsi));
1688f172 2082
c6bb733d 2083 gsi_insert_seq_on_edge (e, stmts);
2084 gsi_commit_edge_inserts ();
8c6b3774 2085 bb = gimple_bb (stmt);
2086
2087 if (!bb_in_sese_p (bb, SCOP_REGION (scop)))
2088 return;
2089
2090 if (!gbb_from_bb (bb))
2091 new_pbb_from_pbb (scop, pbb_from_bb (e->src), bb);
1688f172 2092
2093 analyze_drs_in_stmts (scop, bb, x);
c6bb733d 2094}
2095
2096/* Creates a zero dimension array of the same type as VAR. */
2097
2098static tree
03c1327b 2099create_zero_dim_array (tree var, const char *base_name)
c6bb733d 2100{
2101 tree index_type = build_index_type (integer_zero_node);
2102 tree elt_type = TREE_TYPE (var);
2103 tree array_type = build_array_type (elt_type, index_type);
03c1327b 2104 tree base = create_tmp_var (array_type, base_name);
c6bb733d 2105
c6bb733d 2106 return build4 (ARRAY_REF, elt_type, base, integer_zero_node, NULL_TREE,
2107 NULL_TREE);
2108}
2109
2110/* Returns true when PHI is a loop close phi node. */
2111
2112static bool
2113scalar_close_phi_node_p (gimple phi)
2114{
30f4f4a6 2115 if (gimple_code (phi) != GIMPLE_PHI
7c782c9b 2116 || virtual_operand_p (gimple_phi_result (phi)))
c6bb733d 2117 return false;
2118
03ce78db 2119 /* Note that loop close phi nodes should have a single argument
2120 because we translated the representation into a canonical form
2121 before Graphite: see canonicalize_loop_closed_ssa_form. */
c6bb733d 2122 return (gimple_phi_num_args (phi) == 1);
2123}
2124
5d21c24a 2125/* For a definition DEF in REGION, propagates the expression EXPR in
2126 all the uses of DEF outside REGION. */
2127
2128static void
2129propagate_expr_outside_region (tree def, tree expr, sese region)
2130{
2131 imm_use_iterator imm_iter;
2132 gimple use_stmt;
2133 gimple_seq stmts;
2134 bool replaced_once = false;
2135
ed455480 2136 gcc_assert (TREE_CODE (def) == SSA_NAME);
5d21c24a 2137
2138 expr = force_gimple_operand (unshare_expr (expr), &stmts, true,
2139 NULL_TREE);
2140
2141 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2142 if (!is_gimple_debug (use_stmt)
2143 && !bb_in_sese_p (gimple_bb (use_stmt), region))
2144 {
2145 ssa_op_iter iter;
2146 use_operand_p use_p;
2147
2148 FOR_EACH_PHI_OR_STMT_USE (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2149 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0)
2150 && (replaced_once = true))
2151 replace_exp (use_p, expr);
2152
2153 update_stmt (use_stmt);
2154 }
2155
2156 if (replaced_once)
2157 {
2158 gsi_insert_seq_on_edge (SESE_ENTRY (region), stmts);
2159 gsi_commit_edge_inserts ();
2160 }
2161}
2162
c6bb733d 2163/* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2164 dimension array for it. */
2165
2166static void
8c6b3774 2167rewrite_close_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
c6bb733d 2168{
8c6b3774 2169 sese region = SCOP_REGION (scop);
c6bb733d 2170 gimple phi = gsi_stmt (*psi);
2171 tree res = gimple_phi_result (phi);
55c89f69 2172 basic_block bb = gimple_bb (phi);
2173 gimple_stmt_iterator gsi = gsi_after_labels (bb);
c6bb733d 2174 tree arg = gimple_phi_arg_def (phi, 0);
55c89f69 2175 gimple stmt;
c6bb733d 2176
03ce78db 2177 /* Note that loop close phi nodes should have a single argument
2178 because we translated the representation into a canonical form
2179 before Graphite: see canonicalize_loop_closed_ssa_form. */
2180 gcc_assert (gimple_phi_num_args (phi) == 1);
2181
55c89f69 2182 /* The phi node can be a non close phi node, when its argument is
51ec8951 2183 invariant, or a default definition. */
55c89f69 2184 if (is_gimple_min_invariant (arg)
51ec8951 2185 || SSA_NAME_IS_DEFAULT_DEF (arg))
ed455480 2186 {
2187 propagate_expr_outside_region (res, arg, region);
2188 gsi_next (psi);
2189 return;
2190 }
5d21c24a 2191
68a6a8ba 2192 else if (gimple_bb (SSA_NAME_DEF_STMT (arg))->loop_father == bb->loop_father)
2193 {
2194 propagate_expr_outside_region (res, arg, region);
2195 stmt = gimple_build_assign (res, arg);
2196 remove_phi_node (psi, false);
2197 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
68a6a8ba 2198 return;
2199 }
2200
5d21c24a 2201 /* If res is scev analyzable and is not a scalar value, it is safe
2202 to ignore the close phi node: it will be code generated in the
2203 out of Graphite pass. */
2204 else if (scev_analyzable_p (res, region))
2205 {
2206 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (res));
2207 tree scev;
2208
2209 if (!loop_in_sese_p (loop, region))
2210 {
2211 loop = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2212 scev = scalar_evolution_in_region (region, loop, arg);
2213 scev = compute_overall_effect_of_inner_loop (loop, scev);
2214 }
2215 else
ed455480 2216 scev = scalar_evolution_in_region (region, loop, res);
5d21c24a 2217
2218 if (tree_does_not_contain_chrecs (scev))
2219 propagate_expr_outside_region (res, scev, region);
2220
2221 gsi_next (psi);
2222 return;
2223 }
5184a05f 2224 else
55c89f69 2225 {
874117c8 2226 tree zero_dim_array = create_zero_dim_array (res, "Close_Phi");
55c89f69 2227
11db727d 2228 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
55c89f69 2229
49253930 2230 if (TREE_CODE (arg) == SSA_NAME)
1688f172 2231 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
8c6b3774 2232 SSA_NAME_DEF_STMT (arg));
55c89f69 2233 else
8c6b3774 2234 insert_out_of_ssa_copy_on_edge (scop, single_pred_edge (bb),
55c89f69 2235 zero_dim_array, arg);
2236 }
c6bb733d 2237
2238 remove_phi_node (psi, false);
c6bb733d 2239 SSA_NAME_DEF_STMT (res) = stmt;
1688f172 2240
2241 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
c6bb733d 2242}
2243
2244/* Rewrite out of SSA the reduction phi node at PSI by creating a zero
2245 dimension array for it. */
2246
2247static void
8c6b3774 2248rewrite_phi_out_of_ssa (scop_p scop, gimple_stmt_iterator *psi)
c6bb733d 2249{
2250 size_t i;
2251 gimple phi = gsi_stmt (*psi);
2252 basic_block bb = gimple_bb (phi);
2253 tree res = gimple_phi_result (phi);
874117c8 2254 tree zero_dim_array = create_zero_dim_array (res, "phi_out_of_ssa");
c6bb733d 2255 gimple stmt;
c6bb733d 2256
2257 for (i = 0; i < gimple_phi_num_args (phi); i++)
2258 {
2259 tree arg = gimple_phi_arg_def (phi, i);
097e870c 2260 edge e = gimple_phi_arg_edge (phi, i);
c6bb733d 2261
097e870c 2262 /* Avoid the insertion of code in the loop latch to please the
2263 pattern matching of the vectorizer. */
a865acd7 2264 if (TREE_CODE (arg) == SSA_NAME
f5f9fa15 2265 && !SSA_NAME_IS_DEFAULT_DEF (arg)
a865acd7 2266 && e->src == bb->loop_father->latch)
1688f172 2267 insert_out_of_ssa_copy (scop, zero_dim_array, arg,
8c6b3774 2268 SSA_NAME_DEF_STMT (arg));
c6bb733d 2269 else
8c6b3774 2270 insert_out_of_ssa_copy_on_edge (scop, e, zero_dim_array, arg);
c6bb733d 2271 }
2272
11db727d 2273 stmt = gimple_build_assign (res, unshare_expr (zero_dim_array));
c6bb733d 2274 remove_phi_node (psi, false);
11db727d 2275 insert_stmts (scop, stmt, NULL, gsi_after_labels (bb));
c6bb733d 2276}
2277
b8046a12 2278/* Rewrite the degenerate phi node at position PSI from the degenerate
2279 form "x = phi (y, y, ..., y)" to "x = y". */
2280
2281static void
2282rewrite_degenerate_phi (gimple_stmt_iterator *psi)
2283{
2284 tree rhs;
2285 gimple stmt;
2286 gimple_stmt_iterator gsi;
2287 gimple phi = gsi_stmt (*psi);
2288 tree res = gimple_phi_result (phi);
2289 basic_block bb;
2290
b8046a12 2291 bb = gimple_bb (phi);
2292 rhs = degenerate_phi_result (phi);
2293 gcc_assert (rhs);
2294
2295 stmt = gimple_build_assign (res, rhs);
2296 remove_phi_node (psi, false);
b8046a12 2297
2298 gsi = gsi_after_labels (bb);
2299 gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
2300}
2301
42ad5d61 2302/* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2303
8c6b3774 2304static void
42ad5d61 2305rewrite_reductions_out_of_ssa (scop_p scop)
2306{
2307 basic_block bb;
2308 gimple_stmt_iterator psi;
2309 sese region = SCOP_REGION (scop);
2310
fc00614f 2311 FOR_EACH_BB_FN (bb, cfun)
42ad5d61 2312 if (bb_in_sese_p (bb, region))
2313 for (psi = gsi_start_phis (bb); !gsi_end_p (psi);)
2314 {
b8046a12 2315 gimple phi = gsi_stmt (psi);
2316
7c782c9b 2317 if (virtual_operand_p (gimple_phi_result (phi)))
7ba04629 2318 {
2319 gsi_next (&psi);
2320 continue;
2321 }
2322
b8046a12 2323 if (gimple_phi_num_args (phi) > 1
2324 && degenerate_phi_result (phi))
2325 rewrite_degenerate_phi (&psi);
2326
2327 else if (scalar_close_phi_node_p (phi))
8c6b3774 2328 rewrite_close_phi_out_of_ssa (scop, &psi);
b8046a12 2329
42ad5d61 2330 else if (reduction_phi_p (region, &psi))
8c6b3774 2331 rewrite_phi_out_of_ssa (scop, &psi);
42ad5d61 2332 }
2333
2334 update_ssa (TODO_update_ssa);
2335#ifdef ENABLE_CHECKING
2336 verify_loop_closed_ssa (true);
2337#endif
2338}
2339
5061777c 2340/* Rewrite the scalar dependence of DEF used in USE_STMT with a memory
2341 read from ZERO_DIM_ARRAY. */
2342
2343static void
1688f172 2344rewrite_cross_bb_scalar_dependence (scop_p scop, tree zero_dim_array,
8c6b3774 2345 tree def, gimple use_stmt)
5061777c 2346{
874117c8 2347 gimple name_stmt;
2348 tree name;
5061777c 2349 ssa_op_iter iter;
2350 use_operand_p use_p;
5061777c 2351
dd27e8aa 2352 gcc_assert (gimple_code (use_stmt) != GIMPLE_PHI);
5061777c 2353
874117c8 2354 name = copy_ssa_name (def, NULL);
2355 name_stmt = gimple_build_assign (name, zero_dim_array);
2356
dd27e8aa 2357 gimple_assign_set_lhs (name_stmt, name);
1688f172 2358 insert_stmts (scop, name_stmt, NULL, gsi_for_stmt (use_stmt));
5061777c 2359
dd27e8aa 2360 FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_ALL_USES)
2361 if (operand_equal_p (def, USE_FROM_PTR (use_p), 0))
2362 replace_exp (use_p, name);
5061777c 2363
2364 update_stmt (use_stmt);
2365}
2366
3ac4f821 2367/* For every definition DEF in the SCOP that is used outside the scop,
2368 insert a closing-scop definition in the basic block just after this
2369 SCOP. */
2370
2371static void
2372handle_scalar_deps_crossing_scop_limits (scop_p scop, tree def, gimple stmt)
2373{
2374 tree var = create_tmp_reg (TREE_TYPE (def), NULL);
2375 tree new_name = make_ssa_name (var, stmt);
2376 bool needs_copy = false;
2377 use_operand_p use_p;
2378 imm_use_iterator imm_iter;
2379 gimple use_stmt;
2380 sese region = SCOP_REGION (scop);
2381
2382 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2383 {
2384 if (!bb_in_sese_p (gimple_bb (use_stmt), region))
2385 {
2386 FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
2387 {
2388 SET_USE (use_p, new_name);
2389 }
2390 update_stmt (use_stmt);
2391 needs_copy = true;
2392 }
2393 }
2394
2395 /* Insert in the empty BB just after the scop a use of DEF such
2396 that the rewrite of cross_bb_scalar_dependences won't insert
2397 arrays everywhere else. */
2398 if (needs_copy)
2399 {
2400 gimple assign = gimple_build_assign (new_name, def);
2401 gimple_stmt_iterator psi = gsi_after_labels (SESE_EXIT (region)->dest);
2402
3ac4f821 2403 update_stmt (assign);
2404 gsi_insert_before (&psi, assign, GSI_SAME_STMT);
2405 }
2406}
2407
42ad5d61 2408/* Rewrite the scalar dependences crossing the boundary of the BB
c9a67530 2409 containing STMT with an array. Return true when something has been
2410 changed. */
42ad5d61 2411
c9a67530 2412static bool
3ac4f821 2413rewrite_cross_bb_scalar_deps (scop_p scop, gimple_stmt_iterator *gsi)
42ad5d61 2414{
3ac4f821 2415 sese region = SCOP_REGION (scop);
42ad5d61 2416 gimple stmt = gsi_stmt (*gsi);
2417 imm_use_iterator imm_iter;
2418 tree def;
2419 basic_block def_bb;
2420 tree zero_dim_array = NULL_TREE;
2421 gimple use_stmt;
c9a67530 2422 bool res = false;
42ad5d61 2423
b19b9f62 2424 switch (gimple_code (stmt))
2425 {
2426 case GIMPLE_ASSIGN:
2427 def = gimple_assign_lhs (stmt);
2428 break;
2429
2430 case GIMPLE_CALL:
2431 def = gimple_call_lhs (stmt);
2432 break;
2433
2434 default:
c9a67530 2435 return false;
b19b9f62 2436 }
42ad5d61 2437
a4a4b66a 2438 if (!def
2439 || !is_gimple_reg (def))
c9a67530 2440 return false;
42ad5d61 2441
5d21c24a 2442 if (scev_analyzable_p (def, region))
2443 {
2444 loop_p loop = loop_containing_stmt (SSA_NAME_DEF_STMT (def));
2445 tree scev = scalar_evolution_in_region (region, loop, def);
2446
c9a67530 2447 if (tree_contains_chrecs (scev, NULL))
2448 return false;
5d21c24a 2449
c9a67530 2450 propagate_expr_outside_region (def, scev, region);
2451 return true;
5d21c24a 2452 }
2453
42ad5d61 2454 def_bb = gimple_bb (stmt);
2455
3ac4f821 2456 handle_scalar_deps_crossing_scop_limits (scop, def, stmt);
2457
42ad5d61 2458 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
c9a67530 2459 if (gimple_code (use_stmt) == GIMPLE_PHI
2460 && (res = true))
5061777c 2461 {
ed455480 2462 gimple_stmt_iterator psi = gsi_for_stmt (use_stmt);
42ad5d61 2463
ed455480 2464 if (scalar_close_phi_node_p (gsi_stmt (psi)))
8c6b3774 2465 rewrite_close_phi_out_of_ssa (scop, &psi);
ed455480 2466 else
8c6b3774 2467 rewrite_phi_out_of_ssa (scop, &psi);
ed455480 2468 }
2469
2470 FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def)
2471 if (gimple_code (use_stmt) != GIMPLE_PHI
2472 && def_bb != gimple_bb (use_stmt)
c9a67530 2473 && !is_gimple_debug (use_stmt)
2474 && (res = true))
ed455480 2475 {
5061777c 2476 if (!zero_dim_array)
2477 {
03c1327b 2478 zero_dim_array = create_zero_dim_array
874117c8 2479 (def, "Cross_BB_scalar_dependence");
1688f172 2480 insert_out_of_ssa_copy (scop, zero_dim_array, def,
39a34dd8 2481 SSA_NAME_DEF_STMT (def));
5061777c 2482 gsi_next (gsi);
2483 }
2484
2bdae241 2485 rewrite_cross_bb_scalar_dependence (scop, unshare_expr (zero_dim_array),
8c6b3774 2486 def, use_stmt);
5061777c 2487 }
c9a67530 2488
2489 return res;
5061777c 2490}
2491
bf8b5699 2492/* Rewrite out of SSA all the reduction phi nodes of SCOP. */
2493
8c6b3774 2494static void
bf8b5699 2495rewrite_cross_bb_scalar_deps_out_of_ssa (scop_p scop)
2496{
2497 basic_block bb;
2498 gimple_stmt_iterator psi;
2499 sese region = SCOP_REGION (scop);
c9a67530 2500 bool changed = false;
5061777c 2501
3ac4f821 2502 /* Create an extra empty BB after the scop. */
7133bc6f 2503 split_edge (SESE_EXIT (region));
3ac4f821 2504
fc00614f 2505 FOR_EACH_BB_FN (bb, cfun)
5061777c 2506 if (bb_in_sese_p (bb, region))
2507 for (psi = gsi_start_bb (bb); !gsi_end_p (psi); gsi_next (&psi))
3ac4f821 2508 changed |= rewrite_cross_bb_scalar_deps (scop, &psi);
5061777c 2509
c9a67530 2510 if (changed)
2511 {
2512 scev_reset_htab ();
2513 update_ssa (TODO_update_ssa);
5061777c 2514#ifdef ENABLE_CHECKING
c9a67530 2515 verify_loop_closed_ssa (true);
5061777c 2516#endif
c9a67530 2517 }
c6bb733d 2518}
2519
2520/* Returns the number of pbbs that are in loops contained in SCOP. */
2521
2522static int
2523nb_pbbs_in_loops (scop_p scop)
2524{
2525 int i;
2526 poly_bb_p pbb;
2527 int res = 0;
2528
f1f41a6c 2529 FOR_EACH_VEC_ELT (SCOP_BBS (scop), i, pbb)
c6bb733d 2530 if (loop_in_sese_p (gbb_loop (PBB_BLACK_BOX (pbb)), SCOP_REGION (scop)))
2531 res++;
2532
2533 return res;
2534}
2535
f007fe97 2536/* Return the number of data references in BB that write in
2537 memory. */
2538
2539static int
2540nb_data_writes_in_bb (basic_block bb)
2541{
2542 int res = 0;
2543 gimple_stmt_iterator gsi;
2544
2545 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2546 if (gimple_vdef (gsi_stmt (gsi)))
2547 res++;
2548
2549 return res;
2550}
2551
8c6b3774 2552/* Splits at STMT the basic block BB represented as PBB in the
2553 polyhedral form. */
2554
2555static edge
2556split_pbb (scop_p scop, poly_bb_p pbb, basic_block bb, gimple stmt)
2557{
2558 edge e1 = split_block (bb, stmt);
2559 new_pbb_from_pbb (scop, pbb, e1->dest);
2560 return e1;
2561}
2562
2563/* Splits STMT out of its current BB. This is done for reduction
2564 statements for which we want to ignore data dependences. */
30f4f4a6 2565
2566static basic_block
8c6b3774 2567split_reduction_stmt (scop_p scop, gimple stmt)
30f4f4a6 2568{
30f4f4a6 2569 basic_block bb = gimple_bb (stmt);
8c6b3774 2570 poly_bb_p pbb = pbb_from_bb (bb);
1688f172 2571 gimple_bb_p gbb = gbb_from_bb (bb);
8c6b3774 2572 edge e1;
1688f172 2573 int i;
2574 data_reference_p dr;
30f4f4a6 2575
f007fe97 2576 /* Do not split basic blocks with no writes to memory: the reduction
2577 will be the only write to memory. */
fc2372d9 2578 if (nb_data_writes_in_bb (bb) == 0
2579 /* Or if we have already marked BB as a reduction. */
2580 || PBB_IS_REDUCTION (pbb_from_bb (bb)))
f007fe97 2581 return bb;
2582
8c6b3774 2583 e1 = split_pbb (scop, pbb, bb, stmt);
30f4f4a6 2584
8c6b3774 2585 /* Split once more only when the reduction stmt is not the only one
2586 left in the original BB. */
2587 if (!gsi_one_before_end_p (gsi_start_nondebug_bb (bb)))
2588 {
2589 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2590 gsi_prev (&gsi);
2591 e1 = split_pbb (scop, pbb, bb, gsi_stmt (gsi));
2592 }
30f4f4a6 2593
1688f172 2594 /* A part of the data references will end in a different basic block
2595 after the split: move the DRs from the original GBB to the newly
2596 created GBB1. */
f1f41a6c 2597 FOR_EACH_VEC_ELT (GBB_DATA_REFS (gbb), i, dr)
1688f172 2598 {
2599 basic_block bb1 = gimple_bb (DR_STMT (dr));
2600
2601 if (bb1 != bb)
2602 {
2603 gimple_bb_p gbb1 = gbb_from_bb (bb1);
f1f41a6c 2604 GBB_DATA_REFS (gbb1).safe_push (dr);
2605 GBB_DATA_REFS (gbb).ordered_remove (i);
1688f172 2606 i--;
2607 }
2608 }
2609
8c6b3774 2610 return e1->dest;
30f4f4a6 2611}
2612
2613/* Return true when stmt is a reduction operation. */
2614
2615static inline bool
2616is_reduction_operation_p (gimple stmt)
2617{
5daf19b1 2618 enum tree_code code;
2619
2620 gcc_assert (is_gimple_assign (stmt));
2621 code = gimple_assign_rhs_code (stmt);
2622
30f4f4a6 2623 return flag_associative_math
5daf19b1 2624 && commutative_tree_code (code)
2625 && associative_tree_code (code);
30f4f4a6 2626}
2627
2628/* Returns true when PHI contains an argument ARG. */
2629
2630static bool
2631phi_contains_arg (gimple phi, tree arg)
2632{
2633 size_t i;
2634
2635 for (i = 0; i < gimple_phi_num_args (phi); i++)
2636 if (operand_equal_p (arg, gimple_phi_arg_def (phi, i), 0))
2637 return true;
2638
2639 return false;
2640}
2641
2642/* Return a loop phi node that corresponds to a reduction containing LHS. */
2643
2644static gimple
2645follow_ssa_with_commutative_ops (tree arg, tree lhs)
2646{
2647 gimple stmt;
2648
2649 if (TREE_CODE (arg) != SSA_NAME)
2650 return NULL;
2651
2652 stmt = SSA_NAME_DEF_STMT (arg);
2653
7f60ea7e 2654 if (gimple_code (stmt) == GIMPLE_NOP
2655 || gimple_code (stmt) == GIMPLE_CALL)
36f22aa0 2656 return NULL;
2657
30f4f4a6 2658 if (gimple_code (stmt) == GIMPLE_PHI)
2659 {
2660 if (phi_contains_arg (stmt, lhs))
2661 return stmt;
2662 return NULL;
2663 }
2664
5daf19b1 2665 if (!is_gimple_assign (stmt))
2666 return NULL;
2667
30f4f4a6 2668 if (gimple_num_ops (stmt) == 2)
2669 return follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2670
2671 if (is_reduction_operation_p (stmt))
2672 {
2673 gimple res = follow_ssa_with_commutative_ops (gimple_assign_rhs1 (stmt), lhs);
2674
2675 return res ? res :
2676 follow_ssa_with_commutative_ops (gimple_assign_rhs2 (stmt), lhs);
2677 }
2678
2679 return NULL;
2680}
2681
2682/* Detect commutative and associative scalar reductions starting at
5184a05f 2683 the STMT. Return the phi node of the reduction cycle, or NULL. */
30f4f4a6 2684
2685static gimple
2686detect_commutative_reduction_arg (tree lhs, gimple stmt, tree arg,
f1f41a6c 2687 vec<gimple> *in,
2688 vec<gimple> *out)
30f4f4a6 2689{
2690 gimple phi = follow_ssa_with_commutative_ops (arg, lhs);
2691
5184a05f 2692 if (!phi)
2693 return NULL;
30f4f4a6 2694
f1f41a6c 2695 in->safe_push (stmt);
2696 out->safe_push (stmt);
5184a05f 2697 return phi;
30f4f4a6 2698}
2699
2700/* Detect commutative and associative scalar reductions starting at
5d2603f9 2701 STMT. Return the phi node of the reduction cycle, or NULL. */
30f4f4a6 2702
2703static gimple
f1f41a6c 2704detect_commutative_reduction_assign (gimple stmt, vec<gimple> *in,
2705 vec<gimple> *out)
30f4f4a6 2706{
2707 tree lhs = gimple_assign_lhs (stmt);
2708
2709 if (gimple_num_ops (stmt) == 2)
2710 return detect_commutative_reduction_arg (lhs, stmt,
2711 gimple_assign_rhs1 (stmt),
2712 in, out);
2713
2714 if (is_reduction_operation_p (stmt))
2715 {
2716 gimple res = detect_commutative_reduction_arg (lhs, stmt,
2717 gimple_assign_rhs1 (stmt),
2718 in, out);
2719 return res ? res
2720 : detect_commutative_reduction_arg (lhs, stmt,
2721 gimple_assign_rhs2 (stmt),
2722 in, out);
2723 }
2724
2725 return NULL;
2726}
2727
2728/* Return a loop phi node that corresponds to a reduction containing LHS. */
2729
2730static gimple
2731follow_inital_value_to_phi (tree arg, tree lhs)
2732{
2733 gimple stmt;
2734
2735 if (!arg || TREE_CODE (arg) != SSA_NAME)
2736 return NULL;
2737
2738 stmt = SSA_NAME_DEF_STMT (arg);
2739
2740 if (gimple_code (stmt) == GIMPLE_PHI
2741 && phi_contains_arg (stmt, lhs))
2742 return stmt;
2743
2744 return NULL;
2745}
2746
2747
9d75589a 2748/* Return the argument of the loop PHI that is the initial value coming
30f4f4a6 2749 from outside the loop. */
2750
2751static edge
2752edge_initial_value_for_loop_phi (gimple phi)
2753{
2754 size_t i;
2755
2756 for (i = 0; i < gimple_phi_num_args (phi); i++)
2757 {
2758 edge e = gimple_phi_arg_edge (phi, i);
2759
2760 if (loop_depth (e->src->loop_father)
2761 < loop_depth (e->dest->loop_father))
2762 return e;
2763 }
2764
2765 return NULL;
2766}
2767
9d75589a 2768/* Return the argument of the loop PHI that is the initial value coming
30f4f4a6 2769 from outside the loop. */
2770
2771static tree
2772initial_value_for_loop_phi (gimple phi)
2773{
2774 size_t i;
2775
2776 for (i = 0; i < gimple_phi_num_args (phi); i++)
2777 {
2778 edge e = gimple_phi_arg_edge (phi, i);
2779
2780 if (loop_depth (e->src->loop_father)
2781 < loop_depth (e->dest->loop_father))
2782 return gimple_phi_arg_def (phi, i);
2783 }
2784
2785 return NULL_TREE;
2786}
2787
2528d7cf 2788/* Returns true when DEF is used outside the reduction cycle of
2789 LOOP_PHI. */
2790
2791static bool
2792used_outside_reduction (tree def, gimple loop_phi)
2793{
2794 use_operand_p use_p;
2795 imm_use_iterator imm_iter;
2796 loop_p loop = loop_containing_stmt (loop_phi);
2797
2798 /* In LOOP, DEF should be used only in LOOP_PHI. */
2799 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2800 {
2801 gimple stmt = USE_STMT (use_p);
2802
2803 if (stmt != loop_phi
2804 && !is_gimple_debug (stmt)
2805 && flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
2806 return true;
2807 }
2808
2809 return false;
2810}
2811
93514494 2812/* Detect commutative and associative scalar reductions belonging to
2813 the SCOP starting at the loop closed phi node STMT. Return the phi
2814 node of the reduction cycle, or NULL. */
30f4f4a6 2815
2816static gimple
f1f41a6c 2817detect_commutative_reduction (scop_p scop, gimple stmt, vec<gimple> *in,
2818 vec<gimple> *out)
30f4f4a6 2819{
2820 if (scalar_close_phi_node_p (stmt))
2821 {
2528d7cf 2822 gimple def, loop_phi, phi, close_phi = stmt;
2823 tree init, lhs, arg = gimple_phi_arg_def (close_phi, 0);
5184a05f 2824
2825 if (TREE_CODE (arg) != SSA_NAME)
2826 return NULL;
2827
03ce78db 2828 /* Note that loop close phi nodes should have a single argument
2829 because we translated the representation into a canonical form
2830 before Graphite: see canonicalize_loop_closed_ssa_form. */
2528d7cf 2831 gcc_assert (gimple_phi_num_args (close_phi) == 1);
03ce78db 2832
5184a05f 2833 def = SSA_NAME_DEF_STMT (arg);
2528d7cf 2834 if (!stmt_in_sese_p (def, SCOP_REGION (scop))
2835 || !(loop_phi = detect_commutative_reduction (scop, def, in, out)))
93514494 2836 return NULL;
2837
2528d7cf 2838 lhs = gimple_phi_result (close_phi);
2839 init = initial_value_for_loop_phi (loop_phi);
2840 phi = follow_inital_value_to_phi (init, lhs);
30f4f4a6 2841
2528d7cf 2842 if (phi && (used_outside_reduction (lhs, phi)
2843 || !has_single_use (gimple_phi_result (phi))))
30f4f4a6 2844 return NULL;
2528d7cf 2845
f1f41a6c 2846 in->safe_push (loop_phi);
2847 out->safe_push (close_phi);
2528d7cf 2848 return phi;
30f4f4a6 2849 }
2850
2851 if (gimple_code (stmt) == GIMPLE_ASSIGN)
2852 return detect_commutative_reduction_assign (stmt, in, out);
2853
2854 return NULL;
2855}
2856
2857/* Translate the scalar reduction statement STMT to an array RED
2858 knowing that its recursive phi node is LOOP_PHI. */
2859
2860static void
1688f172 2861translate_scalar_reduction_to_array_for_stmt (scop_p scop, tree red,
2862 gimple stmt, gimple loop_phi)
30f4f4a6 2863{
30f4f4a6 2864 tree res = gimple_phi_result (loop_phi);
53b5bc41 2865 gimple assign = gimple_build_assign (res, unshare_expr (red));
1688f172 2866 gimple_stmt_iterator gsi;
30f4f4a6 2867
1688f172 2868 insert_stmts (scop, assign, NULL, gsi_after_labels (gimple_bb (loop_phi)));
30f4f4a6 2869
53b5bc41 2870 assign = gimple_build_assign (unshare_expr (red), gimple_assign_lhs (stmt));
1688f172 2871 gsi = gsi_for_stmt (stmt);
2872 gsi_next (&gsi);
2873 insert_stmts (scop, assign, NULL, gsi);
30f4f4a6 2874}
2875
eae8f2a1 2876/* Removes the PHI node and resets all the debug stmts that are using
2877 the PHI_RESULT. */
2878
2879static void
2880remove_phi (gimple phi)
2881{
2882 imm_use_iterator imm_iter;
2883 tree def;
2884 use_operand_p use_p;
2885 gimple_stmt_iterator gsi;
4997014d 2886 auto_vec<gimple, 3> update;
eae8f2a1 2887 unsigned int i;
2888 gimple stmt;
2889
2890 def = PHI_RESULT (phi);
2891 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2892 {
2893 stmt = USE_STMT (use_p);
2894
2895 if (is_gimple_debug (stmt))
2896 {
2897 gimple_debug_bind_reset_value (stmt);
f1f41a6c 2898 update.safe_push (stmt);
eae8f2a1 2899 }
2900 }
2901
f1f41a6c 2902 FOR_EACH_VEC_ELT (update, i, stmt)
eae8f2a1 2903 update_stmt (stmt);
2904
eae8f2a1 2905 gsi = gsi_for_phi_node (phi);
2906 remove_phi_node (&gsi, false);
2907}
2908
fa6ed0e9 2909/* Helper function for for_each_index. For each INDEX of the data
2910 reference REF, returns true when its indices are valid in the loop
2911 nest LOOP passed in as DATA. */
2912
2913static bool
2914dr_indices_valid_in_loop (tree ref ATTRIBUTE_UNUSED, tree *index, void *data)
2915{
2916 loop_p loop;
2917 basic_block header, def_bb;
2918 gimple stmt;
2919
2920 if (TREE_CODE (*index) != SSA_NAME)
2921 return true;
2922
2923 loop = *((loop_p *) data);
2924 header = loop->header;
2925 stmt = SSA_NAME_DEF_STMT (*index);
2926
2927 if (!stmt)
2928 return true;
2929
2930 def_bb = gimple_bb (stmt);
2931
2932 if (!def_bb)
2933 return true;
2934
2935 return dominated_by_p (CDI_DOMINATORS, header, def_bb);
2936}
2937
53b5bc41 2938/* When the result of a CLOSE_PHI is written to a memory location,
2939 return a pointer to that memory reference, otherwise return
2940 NULL_TREE. */
2941
2942static tree
2943close_phi_written_to_memory (gimple close_phi)
2944{
2945 imm_use_iterator imm_iter;
53b5bc41 2946 use_operand_p use_p;
2947 gimple stmt;
fa6ed0e9 2948 tree res, def = gimple_phi_result (close_phi);
53b5bc41 2949
2950 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
2951 if ((stmt = USE_STMT (use_p))
2952 && gimple_code (stmt) == GIMPLE_ASSIGN
fa6ed0e9 2953 && (res = gimple_assign_lhs (stmt)))
2954 {
2955 switch (TREE_CODE (res))
2956 {
2957 case VAR_DECL:
2958 case PARM_DECL:
2959 case RESULT_DECL:
2960 return res;
2961
2962 case ARRAY_REF:
2963 case MEM_REF:
2964 {
2965 tree arg = gimple_phi_arg_def (close_phi, 0);
2966 loop_p nest = loop_containing_stmt (SSA_NAME_DEF_STMT (arg));
2967
2968 /* FIXME: this restriction is for id-{24,25}.f and
2969 could be handled by duplicating the computation of
2970 array indices before the loop of the close_phi. */
2971 if (for_each_index (&res, dr_indices_valid_in_loop, &nest))
2972 return res;
2973 }
2974 /* Fallthru. */
53b5bc41 2975
fa6ed0e9 2976 default:
2977 continue;
2978 }
2979 }
53b5bc41 2980 return NULL_TREE;
2981}
2982
30f4f4a6 2983/* Rewrite out of SSA the reduction described by the loop phi nodes
2984 IN, and the close phi nodes OUT. IN and OUT are structured by loop
2985 levels like this:
2986
2987 IN: stmt, loop_n, ..., loop_0
2988 OUT: stmt, close_n, ..., close_0
2989
2990 the first element is the reduction statement, and the next elements
2991 are the loop and close phi nodes of each of the outer loops. */
2992
2993static void
8c6b3774 2994translate_scalar_reduction_to_array (scop_p scop,
f1f41a6c 2995 vec<gimple> in,
2996 vec<gimple> out)
30f4f4a6 2997{
30f4f4a6 2998 gimple loop_phi;
f1f41a6c 2999 unsigned int i = out.length () - 1;
3000 tree red = close_phi_written_to_memory (out[i]);
30f4f4a6 3001
f1f41a6c 3002 FOR_EACH_VEC_ELT (in, i, loop_phi)
30f4f4a6 3003 {
f1f41a6c 3004 gimple close_phi = out[i];
30f4f4a6 3005
3006 if (i == 0)
3007 {
3008 gimple stmt = loop_phi;
8c6b3774 3009 basic_block bb = split_reduction_stmt (scop, stmt);
3010 poly_bb_p pbb = pbb_from_bb (bb);
3011 PBB_IS_REDUCTION (pbb) = true;
30f4f4a6 3012 gcc_assert (close_phi == loop_phi);
3013
53b5bc41 3014 if (!red)
3015 red = create_zero_dim_array
3016 (gimple_assign_lhs (stmt), "Commutative_Associative_Reduction");
3017
f1f41a6c 3018 translate_scalar_reduction_to_array_for_stmt (scop, red, stmt, in[1]);
30f4f4a6 3019 continue;
3020 }
3021
f1f41a6c 3022 if (i == in.length () - 1)
30f4f4a6 3023 {
53b5bc41 3024 insert_out_of_ssa_copy (scop, gimple_phi_result (close_phi),
3025 unshare_expr (red), close_phi);
39a34dd8 3026 insert_out_of_ssa_copy_on_edge
8c6b3774 3027 (scop, edge_initial_value_for_loop_phi (loop_phi),
53b5bc41 3028 unshare_expr (red), initial_value_for_loop_phi (loop_phi));
30f4f4a6 3029 }
3030
eae8f2a1 3031 remove_phi (loop_phi);
3032 remove_phi (close_phi);
30f4f4a6 3033 }
3034}
3035
c9a67530 3036/* Rewrites out of SSA a commutative reduction at CLOSE_PHI. Returns
3037 true when something has been changed. */
30f4f4a6 3038
c9a67530 3039static bool
8c6b3774 3040rewrite_commutative_reductions_out_of_ssa_close_phi (scop_p scop,
3041 gimple close_phi)
30f4f4a6 3042{
c9a67530 3043 bool res;
4997014d 3044 auto_vec<gimple, 10> in;
3045 auto_vec<gimple, 10> out;
30f4f4a6 3046
93514494 3047 detect_commutative_reduction (scop, close_phi, &in, &out);
f1f41a6c 3048 res = in.length () > 1;
c9a67530 3049 if (res)
8c6b3774 3050 translate_scalar_reduction_to_array (scop, in, out);
30f4f4a6 3051
c9a67530 3052 return res;
30f4f4a6 3053}
3054
c9a67530 3055/* Rewrites all the commutative reductions from LOOP out of SSA.
3056 Returns true when something has been changed. */
30f4f4a6 3057
c9a67530 3058static bool
8c6b3774 3059rewrite_commutative_reductions_out_of_ssa_loop (scop_p scop,
3060 loop_p loop)
30f4f4a6 3061{
3062 gimple_stmt_iterator gsi;
3063 edge exit = single_exit (loop);
72085fb7 3064 tree res;
c9a67530 3065 bool changed = false;
30f4f4a6 3066
3067 if (!exit)
c9a67530 3068 return false;
30f4f4a6 3069
3070 for (gsi = gsi_start_phis (exit->dest); !gsi_end_p (gsi); gsi_next (&gsi))
72085fb7 3071 if ((res = gimple_phi_result (gsi_stmt (gsi)))
7c782c9b 3072 && !virtual_operand_p (res)
8c6b3774 3073 && !scev_analyzable_p (res, SCOP_REGION (scop)))
c9a67530 3074 changed |= rewrite_commutative_reductions_out_of_ssa_close_phi
8c6b3774 3075 (scop, gsi_stmt (gsi));
c9a67530 3076
3077 return changed;
30f4f4a6 3078}
3079
3080/* Rewrites all the commutative reductions from SCOP out of SSA. */
3081
8c6b3774 3082static void
3083rewrite_commutative_reductions_out_of_ssa (scop_p scop)
30f4f4a6 3084{
30f4f4a6 3085 loop_p loop;
c9a67530 3086 bool changed = false;
8c6b3774 3087 sese region = SCOP_REGION (scop);
8643dd0a 3088
f21d4d00 3089 FOR_EACH_LOOP (loop, 0)
30f4f4a6 3090 if (loop_in_sese_p (loop, region))
8c6b3774 3091 changed |= rewrite_commutative_reductions_out_of_ssa_loop (scop, loop);
ff010926 3092
c9a67530 3093 if (changed)
3094 {
3095 scev_reset_htab ();
3096 gsi_commit_edge_inserts ();
3097 update_ssa (TODO_update_ssa);
ff010926 3098#ifdef ENABLE_CHECKING
c9a67530 3099 verify_loop_closed_ssa (true);
ff010926 3100#endif
c9a67530 3101 }
30f4f4a6 3102}
3103
b43389bd 3104/* Can all ivs be represented by a signed integer?
3105 As CLooG might generate negative values in its expressions, signed loop ivs
3106 are required in the backend. */
d3746d81 3107
b43389bd 3108static bool
3109scop_ivs_can_be_represented (scop_p scop)
3110{
b43389bd 3111 loop_p loop;
18046220 3112 gimple_stmt_iterator psi;
83b709f2 3113 bool result = true;
b43389bd 3114
f21d4d00 3115 FOR_EACH_LOOP (loop, 0)
b43389bd 3116 {
b43389bd 3117 if (!loop_in_sese_p (loop, SCOP_REGION (scop)))
3118 continue;
3119
18046220 3120 for (psi = gsi_start_phis (loop->header);
3121 !gsi_end_p (psi); gsi_next (&psi))
3122 {
3123 gimple phi = gsi_stmt (psi);
3124 tree res = PHI_RESULT (phi);
3125 tree type = TREE_TYPE (res);
b43389bd 3126
18046220 3127 if (TYPE_UNSIGNED (type)
a0553bff 3128 && TYPE_PRECISION (type) >= TYPE_PRECISION (long_long_integer_type_node))
83b709f2 3129 {
3130 result = false;
3131 break;
3132 }
18046220 3133 }
83b709f2 3134 if (!result)
f21d4d00 3135 break;
b43389bd 3136 }
3137
83b709f2 3138 return result;
b43389bd 3139}
3140
c6bb733d 3141/* Builds the polyhedral representation for a SESE region. */
3142
f49215ce 3143void
c6bb733d 3144build_poly_scop (scop_p scop)
3145{
3146 sese region = SCOP_REGION (scop);
c2e502a5 3147 graphite_dim_t max_dim;
30f4f4a6 3148
8c6b3774 3149 build_scop_bbs (scop);
c6bb733d 3150
3151 /* FIXME: This restriction is needed to avoid a problem in CLooG.
3152 Once CLooG is fixed, remove this guard. Anyways, it makes no
3153 sense to optimize a scop containing only PBBs that do not belong
3154 to any loops. */
3155 if (nb_pbbs_in_loops (scop) == 0)
f49215ce 3156 return;
c6bb733d 3157
b43389bd 3158 if (!scop_ivs_can_be_represented (scop))
f49215ce 3159 return;
b43389bd 3160
c5409e1f 3161 if (flag_associative_math)
3162 rewrite_commutative_reductions_out_of_ssa (scop);
3163
c6bb733d 3164 build_sese_loop_nests (region);
54c91640 3165 /* Record all conditions in REGION. */
3166 sese_dom_walker (CDI_DOMINATORS, region).walk (cfun->cfg->x_entry_block_ptr);
c6bb733d 3167 find_scop_parameters (scop);
3168
c2e502a5 3169 max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
3170 if (scop_nb_params (scop) > max_dim)
f49215ce 3171 return;
c2e502a5 3172
c6bb733d 3173 build_scop_iteration_domain (scop);
3174 build_scop_context (scop);
c6bb733d 3175 add_conditions_to_constraints (scop);
8c6b3774 3176
3177 /* Rewrite out of SSA only after having translated the
3178 representation to the polyhedral representation to avoid scev
3179 analysis failures. That means that these functions will insert
3180 new data references that they create in the right place. */
8c6b3774 3181 rewrite_reductions_out_of_ssa (scop);
3182 rewrite_cross_bb_scalar_deps_out_of_ssa (scop);
3183
3184 build_scop_drs (scop);
f77385d3 3185 scop_to_lst (scop);
c6bb733d 3186 build_scop_scattering (scop);
c6bb733d 3187
f49215ce 3188 /* This SCoP has been translated to the polyhedral
3189 representation. */
3190 POLY_SCOP_P (scop) = true;
c6bb733d 3191}
c6bb733d 3192#endif