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