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