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