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