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