OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [graphite-clast-to-gimple.c] - Blame information for rev 847

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* Translation of CLAST (CLooG AST) to Gimple.
2
   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3
   Contributed by Sebastian Pop <sebastian.pop@amd.com>.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3, or (at your option)
10
any later version.
11
 
12
GCC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.  */
20
 
21
#include "config.h"
22
#include "system.h"
23
#include "coretypes.h"
24
#include "tm.h"
25
#include "ggc.h"
26
#include "tree.h"
27
#include "rtl.h"
28
#include "basic-block.h"
29
#include "diagnostic.h"
30
#include "tree-flow.h"
31
#include "toplev.h"
32
#include "tree-dump.h"
33
#include "timevar.h"
34
#include "cfgloop.h"
35
#include "tree-chrec.h"
36
#include "tree-data-ref.h"
37
#include "tree-scalar-evolution.h"
38
#include "tree-pass.h"
39
#include "domwalk.h"
40
#include "value-prof.h"
41
#include "pointer-set.h"
42
#include "gimple.h"
43
#include "sese.h"
44
 
45
#ifdef HAVE_cloog
46
#include "cloog/cloog.h"
47
#include "ppl_c.h"
48
#include "graphite-ppl.h"
49
#include "graphite.h"
50
#include "graphite-poly.h"
51
#include "graphite-scop-detection.h"
52
#include "graphite-clast-to-gimple.h"
53
#include "graphite-dependences.h"
54
 
55
/* This flag is set when an error occurred during the translation of
56
   CLAST to Gimple.  */
57
static bool gloog_error;
58
 
59
/* Verifies properties that GRAPHITE should maintain during translation.  */
60
 
61
static inline void
62
graphite_verify (void)
63
{
64
#ifdef ENABLE_CHECKING
65
  verify_loop_structure ();
66
  verify_dominators (CDI_DOMINATORS);
67
  verify_dominators (CDI_POST_DOMINATORS);
68
  verify_ssa (false);
69
  verify_loop_closed_ssa ();
70
#endif
71
}
72
 
73
/* Stores the INDEX in a vector for a given clast NAME.  */
74
 
75
typedef struct clast_name_index {
76
  int index;
77
  const char *name;
78
} *clast_name_index_p;
79
 
80
/* Returns a pointer to a new element of type clast_name_index_p built
81
   from NAME and INDEX.  */
82
 
83
static inline clast_name_index_p
84
new_clast_name_index (const char *name, int index)
85
{
86
  clast_name_index_p res = XNEW (struct clast_name_index);
87
 
88
  res->name = name;
89
  res->index = index;
90
  return res;
91
}
92
 
93
/* For a given clast NAME, returns -1 if it does not correspond to any
94
   parameter, or otherwise, returns the index in the PARAMS or
95
   SCATTERING_DIMENSIONS vector.  */
96
 
97
static inline int
98
clast_name_to_index (const char *name, htab_t index_table)
99
{
100
  struct clast_name_index tmp;
101
  PTR *slot;
102
 
103
  tmp.name = name;
104
  slot = htab_find_slot (index_table, &tmp, NO_INSERT);
105
 
106
  if (slot && *slot)
107
    return ((struct clast_name_index *) *slot)->index;
108
 
109
  return -1;
110
}
111
 
112
/* Records in INDEX_TABLE the INDEX for NAME.  */
113
 
114
static inline void
115
save_clast_name_index (htab_t index_table, const char *name, int index)
116
{
117
  struct clast_name_index tmp;
118
  PTR *slot;
119
 
120
  tmp.name = name;
121
  slot = htab_find_slot (index_table, &tmp, INSERT);
122
 
123
  if (slot)
124
    {
125
      if (*slot)
126
        free (*slot);
127
 
128
      *slot = new_clast_name_index (name, index);
129
    }
130
}
131
 
132
/* Print to stderr the element ELT.  */
133
 
134
static inline void
135
debug_clast_name_index (clast_name_index_p elt)
136
{
137
  fprintf (stderr, "(index = %d, name = %s)\n", elt->index, elt->name);
138
}
139
 
140
/* Helper function for debug_rename_map.  */
141
 
142
static inline int
143
debug_clast_name_indexes_1 (void **slot, void *s ATTRIBUTE_UNUSED)
144
{
145
  struct clast_name_index *entry = (struct clast_name_index *) *slot;
146
  debug_clast_name_index (entry);
147
  return 1;
148
}
149
 
150
/* Print to stderr all the elements of MAP.  */
151
 
152
void
153
debug_clast_name_indexes (htab_t map)
154
{
155
  htab_traverse (map, debug_clast_name_indexes_1, NULL);
156
}
157
 
158
/* Computes a hash function for database element ELT.  */
159
 
160
static inline hashval_t
161
clast_name_index_elt_info (const void *elt)
162
{
163
  return htab_hash_pointer (((const struct clast_name_index *) elt)->name);
164
}
165
 
166
/* Compares database elements E1 and E2.  */
167
 
168
static inline int
169
eq_clast_name_indexes (const void *e1, const void *e2)
170
{
171
  const struct clast_name_index *elt1 = (const struct clast_name_index *) e1;
172
  const struct clast_name_index *elt2 = (const struct clast_name_index *) e2;
173
 
174
  return (elt1->name == elt2->name);
175
}
176
 
177
 
178
/* For a given loop DEPTH in the loop nest of the original black box
179
   PBB, return the old induction variable associated to that loop.  */
180
 
181
static inline tree
182
pbb_to_depth_to_oldiv (poly_bb_p pbb, int depth)
183
{
184
  gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
185
  sese region = SCOP_REGION (PBB_SCOP (pbb));
186
  loop_p loop = gbb_loop_at_index (gbb, region, depth);
187
 
188
  return loop->single_iv;
189
}
190
 
191
/* For a given scattering dimension, return the new induction variable
192
   associated to it.  */
193
 
194
static inline tree
195
newivs_to_depth_to_newiv (VEC (tree, heap) *newivs, int depth)
196
{
197
  return VEC_index (tree, newivs, depth);
198
}
199
 
200
 
201
 
202
/* Returns the tree variable from the name NAME that was given in
203
   Cloog representation.  */
204
 
205
static tree
206
clast_name_to_gcc (const char *name, sese region, VEC (tree, heap) *newivs,
207
                   htab_t newivs_index, htab_t params_index)
208
{
209
  int index;
210
  VEC (tree, heap) *params = SESE_PARAMS (region);
211
 
212
  if (params && params_index)
213
    {
214
      index = clast_name_to_index (name, params_index);
215
 
216
      if (index >= 0)
217
        return VEC_index (tree, params, index);
218
    }
219
 
220
  gcc_assert (newivs && newivs_index);
221
  index = clast_name_to_index (name, newivs_index);
222
  gcc_assert (index >= 0);
223
 
224
  return newivs_to_depth_to_newiv (newivs, index);
225
}
226
 
227
/* Returns the maximal precision type for expressions E1 and E2.  */
228
 
229
static inline tree
230
max_precision_type (tree e1, tree e2)
231
{
232
  tree type1 = TREE_TYPE (e1);
233
  tree type2 = TREE_TYPE (e2);
234
  return TYPE_PRECISION (type1) > TYPE_PRECISION (type2) ? type1 : type2;
235
}
236
 
237
static tree
238
clast_to_gcc_expression (tree, struct clast_expr *, sese, VEC (tree, heap) *,
239
                         htab_t, htab_t);
240
 
241
/* Converts a Cloog reduction expression R with reduction operation OP
242
   to a GCC expression tree of type TYPE.  */
243
 
244
static tree
245
clast_to_gcc_expression_red (tree type, enum tree_code op,
246
                             struct clast_reduction *r,
247
                             sese region, VEC (tree, heap) *newivs,
248
                             htab_t newivs_index, htab_t params_index)
249
{
250
  int i;
251
  tree res = clast_to_gcc_expression (type, r->elts[0], region, newivs,
252
                                      newivs_index, params_index);
253
  tree operand_type = (op == POINTER_PLUS_EXPR) ? sizetype : type;
254
 
255
  for (i = 1; i < r->n; i++)
256
    {
257
      tree t = clast_to_gcc_expression (operand_type, r->elts[i], region,
258
                                        newivs, newivs_index, params_index);
259
      res = fold_build2 (op, type, res, t);
260
    }
261
 
262
  return res;
263
}
264
 
265
/* Converts a Cloog AST expression E back to a GCC expression tree of
266
   type TYPE.  */
267
 
268
static tree
269
clast_to_gcc_expression (tree type, struct clast_expr *e,
270
                         sese region, VEC (tree, heap) *newivs,
271
                         htab_t newivs_index, htab_t params_index)
272
{
273
  switch (e->type)
274
    {
275
    case expr_term:
276
      {
277
        struct clast_term *t = (struct clast_term *) e;
278
 
279
        if (t->var)
280
          {
281
            if (value_one_p (t->val))
282
              {
283
                tree name = clast_name_to_gcc (t->var, region, newivs,
284
                                               newivs_index, params_index);
285
 
286
                if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
287
                  name = fold_convert (sizetype, name);
288
 
289
                name = fold_convert (type, name);
290
                return name;
291
              }
292
 
293
            else if (value_mone_p (t->val))
294
              {
295
                tree name = clast_name_to_gcc (t->var, region, newivs,
296
                                               newivs_index, params_index);
297
 
298
                if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
299
                  name = fold_convert (sizetype, name);
300
 
301
                name = fold_convert (type, name);
302
 
303
                return fold_build1 (NEGATE_EXPR, type, name);
304
              }
305
            else
306
              {
307
                tree name = clast_name_to_gcc (t->var, region, newivs,
308
                                               newivs_index, params_index);
309
                tree cst = gmp_cst_to_tree (type, t->val);
310
 
311
                if (POINTER_TYPE_P (TREE_TYPE (name)) != POINTER_TYPE_P (type))
312
                  name = fold_convert (sizetype, name);
313
 
314
                name = fold_convert (type, name);
315
 
316
                if (!POINTER_TYPE_P (type))
317
                  return fold_build2 (MULT_EXPR, type, cst, name);
318
 
319
                gloog_error = true;
320
                return cst;
321
              }
322
          }
323
        else
324
          return gmp_cst_to_tree (type, t->val);
325
      }
326
 
327
    case expr_red:
328
      {
329
        struct clast_reduction *r = (struct clast_reduction *) e;
330
 
331
        switch (r->type)
332
          {
333
          case clast_red_sum:
334
            return clast_to_gcc_expression_red
335
              (type, POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR : PLUS_EXPR,
336
               r, region, newivs, newivs_index, params_index);
337
 
338
          case clast_red_min:
339
            return clast_to_gcc_expression_red (type, MIN_EXPR, r, region,
340
                                                newivs, newivs_index,
341
                                                params_index);
342
 
343
          case clast_red_max:
344
            return clast_to_gcc_expression_red (type, MAX_EXPR, r, region,
345
                                                newivs, newivs_index,
346
                                                params_index);
347
 
348
          default:
349
            gcc_unreachable ();
350
          }
351
        break;
352
      }
353
 
354
    case expr_bin:
355
      {
356
        struct clast_binary *b = (struct clast_binary *) e;
357
        struct clast_expr *lhs = (struct clast_expr *) b->LHS;
358
        tree tl = clast_to_gcc_expression (type, lhs, region, newivs,
359
                                           newivs_index, params_index);
360
        tree tr = gmp_cst_to_tree (type, b->RHS);
361
 
362
        switch (b->type)
363
          {
364
          case clast_bin_fdiv:
365
            return fold_build2 (FLOOR_DIV_EXPR, type, tl, tr);
366
 
367
          case clast_bin_cdiv:
368
            return fold_build2 (CEIL_DIV_EXPR, type, tl, tr);
369
 
370
          case clast_bin_div:
371
            return fold_build2 (EXACT_DIV_EXPR, type, tl, tr);
372
 
373
          case clast_bin_mod:
374
            return fold_build2 (TRUNC_MOD_EXPR, type, tl, tr);
375
 
376
          default:
377
            gcc_unreachable ();
378
          }
379
      }
380
 
381
    default:
382
      gcc_unreachable ();
383
    }
384
 
385
  return NULL_TREE;
386
}
387
 
388
/* Returns the type for the expression E.  */
389
 
390
static tree
391
gcc_type_for_clast_expr (struct clast_expr *e,
392
                         sese region, VEC (tree, heap) *newivs,
393
                         htab_t newivs_index, htab_t params_index)
394
{
395
  switch (e->type)
396
    {
397
    case expr_term:
398
      {
399
        struct clast_term *t = (struct clast_term *) e;
400
 
401
        if (t->var)
402
          return TREE_TYPE (clast_name_to_gcc (t->var, region, newivs,
403
                                               newivs_index, params_index));
404
        else
405
          return NULL_TREE;
406
      }
407
 
408
    case expr_red:
409
      {
410
        struct clast_reduction *r = (struct clast_reduction *) e;
411
 
412
        if (r->n == 1)
413
          return gcc_type_for_clast_expr (r->elts[0], region, newivs,
414
                                          newivs_index, params_index);
415
        else
416
          {
417
            int i;
418
            for (i = 0; i < r->n; i++)
419
              {
420
                tree type = gcc_type_for_clast_expr (r->elts[i], region,
421
                                                     newivs, newivs_index,
422
                                                     params_index);
423
                if (type)
424
                  return type;
425
              }
426
            return NULL_TREE;
427
          }
428
      }
429
 
430
    case expr_bin:
431
      {
432
        struct clast_binary *b = (struct clast_binary *) e;
433
        struct clast_expr *lhs = (struct clast_expr *) b->LHS;
434
        return gcc_type_for_clast_expr (lhs, region, newivs,
435
                                        newivs_index, params_index);
436
      }
437
 
438
    default:
439
      gcc_unreachable ();
440
    }
441
 
442
  return NULL_TREE;
443
}
444
 
445
/* Returns the type for the equation CLEQ.  */
446
 
447
static tree
448
gcc_type_for_clast_eq (struct clast_equation *cleq,
449
                       sese region, VEC (tree, heap) *newivs,
450
                       htab_t newivs_index, htab_t params_index)
451
{
452
  tree type = gcc_type_for_clast_expr (cleq->LHS, region, newivs,
453
                                       newivs_index, params_index);
454
  if (type)
455
    return type;
456
 
457
  return gcc_type_for_clast_expr (cleq->RHS, region, newivs, newivs_index,
458
                                  params_index);
459
}
460
 
461
/* Translates a clast equation CLEQ to a tree.  */
462
 
463
static tree
464
graphite_translate_clast_equation (sese region,
465
                                   struct clast_equation *cleq,
466
                                   VEC (tree, heap) *newivs,
467
                                   htab_t newivs_index, htab_t params_index)
468
{
469
  enum tree_code comp;
470
  tree type = gcc_type_for_clast_eq (cleq, region, newivs, newivs_index,
471
                                     params_index);
472
  tree lhs = clast_to_gcc_expression (type, cleq->LHS, region, newivs,
473
                                      newivs_index, params_index);
474
  tree rhs = clast_to_gcc_expression (type, cleq->RHS, region, newivs,
475
                                      newivs_index, params_index);
476
 
477
  if (cleq->sign == 0)
478
    comp = EQ_EXPR;
479
 
480
  else if (cleq->sign > 0)
481
    comp = GE_EXPR;
482
 
483
  else
484
    comp = LE_EXPR;
485
 
486
  return fold_build2 (comp, boolean_type_node, lhs, rhs);
487
}
488
 
489
/* Creates the test for the condition in STMT.  */
490
 
491
static tree
492
graphite_create_guard_cond_expr (sese region, struct clast_guard *stmt,
493
                                 VEC (tree, heap) *newivs,
494
                                 htab_t newivs_index, htab_t params_index)
495
{
496
  tree cond = NULL;
497
  int i;
498
 
499
  for (i = 0; i < stmt->n; i++)
500
    {
501
      tree eq = graphite_translate_clast_equation (region, &stmt->eq[i],
502
                                                   newivs, newivs_index,
503
                                                   params_index);
504
 
505
      if (cond)
506
        cond = fold_build2 (TRUTH_AND_EXPR, TREE_TYPE (eq), cond, eq);
507
      else
508
        cond = eq;
509
    }
510
 
511
  return cond;
512
}
513
 
514
/* Creates a new if region corresponding to Cloog's guard.  */
515
 
516
static edge
517
graphite_create_new_guard (sese region, edge entry_edge,
518
                           struct clast_guard *stmt,
519
                           VEC (tree, heap) *newivs,
520
                           htab_t newivs_index, htab_t params_index)
521
{
522
  tree cond_expr = graphite_create_guard_cond_expr (region, stmt, newivs,
523
                                                    newivs_index, params_index);
524
  edge exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
525
  return exit_edge;
526
}
527
 
528
/* Walks a CLAST and returns the first statement in the body of a
529
   loop.  */
530
 
531
static struct clast_user_stmt *
532
clast_get_body_of_loop (struct clast_stmt *stmt)
533
{
534
  if (!stmt
535
      || CLAST_STMT_IS_A (stmt, stmt_user))
536
    return (struct clast_user_stmt *) stmt;
537
 
538
  if (CLAST_STMT_IS_A (stmt, stmt_for))
539
    return clast_get_body_of_loop (((struct clast_for *) stmt)->body);
540
 
541
  if (CLAST_STMT_IS_A (stmt, stmt_guard))
542
    return clast_get_body_of_loop (((struct clast_guard *) stmt)->then);
543
 
544
  if (CLAST_STMT_IS_A (stmt, stmt_block))
545
    return clast_get_body_of_loop (((struct clast_block *) stmt)->body);
546
 
547
  gcc_unreachable ();
548
}
549
 
550
/* Java does not initialize long_long_integer_type_node.  */
551
#define my_long_long (long_long_integer_type_node ? long_long_integer_type_node : ssizetype)
552
 
553
/* Given a CLOOG_IV, return the type that CLOOG_IV should have in GCC
554
   land.  The selected type is big enough to include the original loop
555
   iteration variable, but signed to work with the subtractions CLooG
556
   may have introduced.  If such a type is not available, we fail.
557
 
558
   TODO: Do not always return long_long, but the smallest possible
559
   type, that still holds the original type.
560
 
561
   TODO: Get the types using CLooG instead.  This enables further
562
   optimizations, but needs CLooG support.  */
563
 
564
static tree
565
gcc_type_for_cloog_iv (const char *cloog_iv, gimple_bb_p gbb)
566
{
567
  struct ivtype_map_elt_s tmp;
568
  PTR *slot;
569
 
570
  tmp.cloog_iv = cloog_iv;
571
  slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, NO_INSERT);
572
 
573
  if (slot && *slot)
574
    {
575
      tree type = ((ivtype_map_elt) *slot)->type;
576
      int type_precision = TYPE_PRECISION (type);
577
 
578
      /* Find the smallest signed type possible.  */
579
      if (!TYPE_UNSIGNED (type))
580
        {
581
          if (type_precision <= TYPE_PRECISION (integer_type_node))
582
            return integer_type_node;
583
 
584
          if (type_precision <= TYPE_PRECISION (long_integer_type_node))
585
            return long_integer_type_node;
586
 
587
          if (type_precision <= TYPE_PRECISION (my_long_long))
588
            return my_long_long;
589
 
590
          gcc_unreachable ();
591
        }
592
 
593
      if (type_precision < TYPE_PRECISION (integer_type_node))
594
        return integer_type_node;
595
 
596
      if (type_precision < TYPE_PRECISION (long_integer_type_node))
597
        return long_integer_type_node;
598
 
599
      if (type_precision < TYPE_PRECISION (my_long_long))
600
        return my_long_long;
601
 
602
      /* There is no signed type available, that is large enough to hold the
603
         original value.  */
604
      gcc_unreachable ();
605
    }
606
 
607
  return my_long_long;
608
}
609
 
610
#undef my_long_long
611
 
612
/* Returns the induction variable for the loop that gets translated to
613
   STMT.  */
614
 
615
static tree
616
gcc_type_for_iv_of_clast_loop (struct clast_for *stmt_for)
617
{
618
  struct clast_stmt *stmt = (struct clast_stmt *) stmt_for;
619
  struct clast_user_stmt *body = clast_get_body_of_loop (stmt);
620
  const char *cloog_iv = stmt_for->iterator;
621
  CloogStatement *cs = body->statement;
622
  poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
623
 
624
  return gcc_type_for_cloog_iv (cloog_iv, PBB_BLACK_BOX (pbb));
625
}
626
 
627
/* Creates a new LOOP corresponding to Cloog's STMT.  Inserts an
628
   induction variable for the new LOOP.  New LOOP is attached to CFG
629
   starting at ENTRY_EDGE.  LOOP is inserted into the loop tree and
630
   becomes the child loop of the OUTER_LOOP.  NEWIVS_INDEX binds
631
   CLooG's scattering name to the induction variable created for the
632
   loop of STMT.  The new induction variable is inserted in the NEWIVS
633
   vector.  */
634
 
635
static struct loop *
636
graphite_create_new_loop (sese region, edge entry_edge,
637
                          struct clast_for *stmt,
638
                          loop_p outer, VEC (tree, heap) **newivs,
639
                          htab_t newivs_index, htab_t params_index)
640
{
641
  tree type = gcc_type_for_iv_of_clast_loop (stmt);
642
  tree lb = clast_to_gcc_expression (type, stmt->LB, region, *newivs,
643
                                     newivs_index, params_index);
644
  tree ub = clast_to_gcc_expression (type, stmt->UB, region, *newivs,
645
                                     newivs_index, params_index);
646
  tree stride = gmp_cst_to_tree (type, stmt->stride);
647
  tree ivvar = create_tmp_var (type, "graphite_IV");
648
  tree iv, iv_after_increment;
649
  loop_p loop = create_empty_loop_on_edge
650
    (entry_edge, lb, stride, ub, ivvar, &iv, &iv_after_increment,
651
     outer ? outer : entry_edge->src->loop_father);
652
 
653
  add_referenced_var (ivvar);
654
 
655
  save_clast_name_index (newivs_index, stmt->iterator,
656
                         VEC_length (tree, *newivs));
657
  VEC_safe_push (tree, heap, *newivs, iv);
658
  return loop;
659
}
660
 
661
/* Inserts in MAP a tuple (OLD_NAME, NEW_NAME) for the induction
662
   variables of the loops around GBB in SESE.  */
663
 
664
static void
665
build_iv_mapping (htab_t map, sese region,
666
                  VEC (tree, heap) *newivs, htab_t newivs_index,
667
                  struct clast_user_stmt *user_stmt,
668
                  htab_t params_index)
669
{
670
  struct clast_stmt *t;
671
  int index = 0;
672
  CloogStatement *cs = user_stmt->statement;
673
  poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
674
 
675
  for (t = user_stmt->substitutions; t; t = t->next, index++)
676
    {
677
      struct clast_expr *expr = (struct clast_expr *)
678
       ((struct clast_assignment *)t)->RHS;
679
      tree type = gcc_type_for_clast_expr (expr, region, newivs,
680
                                           newivs_index, params_index);
681
      tree old_name = pbb_to_depth_to_oldiv (pbb, index);
682
      tree e = clast_to_gcc_expression (type, expr, region, newivs,
683
                                        newivs_index, params_index);
684
      set_rename (map, old_name, e);
685
    }
686
}
687
 
688
/* Helper function for htab_traverse.  */
689
 
690
static int
691
copy_renames (void **slot, void *s)
692
{
693
  struct rename_map_elt_s *entry = (struct rename_map_elt_s *) *slot;
694
  htab_t res = (htab_t) s;
695
  tree old_name = entry->old_name;
696
  tree expr = entry->expr;
697
  struct rename_map_elt_s tmp;
698
  PTR *x;
699
 
700
  tmp.old_name = old_name;
701
  x = htab_find_slot (res, &tmp, INSERT);
702
 
703
  if (x && !*x)
704
    *x = new_rename_map_elt (old_name, expr);
705
 
706
  return 1;
707
}
708
 
709
/* Construct bb_pbb_def with BB and PBB. */
710
 
711
static bb_pbb_def *
712
new_bb_pbb_def (basic_block bb, poly_bb_p pbb)
713
{
714
  bb_pbb_def *bb_pbb_p;
715
 
716
  bb_pbb_p = XNEW (bb_pbb_def);
717
  bb_pbb_p->bb = bb;
718
  bb_pbb_p->pbb = pbb;
719
 
720
  return bb_pbb_p;
721
}
722
 
723
/* Mark BB with it's relevant PBB via hashing table BB_PBB_MAPPING.  */
724
 
725
static void
726
mark_bb_with_pbb (poly_bb_p pbb, basic_block bb, htab_t bb_pbb_mapping)
727
{
728
  bb_pbb_def tmp;
729
  PTR *x;
730
 
731
  tmp.bb = bb;
732
  x = htab_find_slot (bb_pbb_mapping, &tmp, INSERT);
733
 
734
  if (x && !*x)
735
    *x = new_bb_pbb_def (bb, pbb);
736
}
737
 
738
/* Find BB's related poly_bb_p in hash table BB_PBB_MAPPING.  */
739
 
740
static poly_bb_p
741
find_pbb_via_hash (htab_t bb_pbb_mapping, basic_block bb)
742
{
743
  bb_pbb_def tmp;
744
  PTR *slot;
745
 
746
  tmp.bb = bb;
747
  slot = htab_find_slot (bb_pbb_mapping, &tmp, NO_INSERT);
748
 
749
  if (slot && *slot)
750
    return ((bb_pbb_def *) *slot)->pbb;
751
 
752
  return NULL;
753
}
754
 
755
/* Check data dependency in LOOP at scattering level LEVEL.
756
   BB_PBB_MAPPING is a basic_block and it's related poly_bb_p
757
   mapping.  */
758
 
759
static bool
760
dependency_in_loop_p (loop_p loop, htab_t bb_pbb_mapping, int level)
761
{
762
  unsigned i,j;
763
  basic_block *bbs = get_loop_body_in_dom_order (loop);
764
 
765
  for (i = 0; i < loop->num_nodes; i++)
766
    {
767
      poly_bb_p pbb1 = find_pbb_via_hash (bb_pbb_mapping, bbs[i]);
768
 
769
      if (pbb1 == NULL)
770
       continue;
771
 
772
      for (j = 0; j < loop->num_nodes; j++)
773
       {
774
         poly_bb_p pbb2 = find_pbb_via_hash (bb_pbb_mapping, bbs[j]);
775
 
776
         if (pbb2 == NULL)
777
           continue;
778
 
779
         if (dependency_between_pbbs_p (pbb1, pbb2, level))
780
           {
781
             free (bbs);
782
             return true;
783
           }
784
       }
785
    }
786
 
787
  free (bbs);
788
 
789
  return false;
790
}
791
 
792
static edge
793
translate_clast (sese, loop_p, struct clast_stmt *, edge, htab_t,
794
                 VEC (tree, heap) **, htab_t, htab_t, int, htab_t);
795
 
796
/* Translates a clast user statement STMT to gimple.
797
 
798
   - REGION is the sese region we used to generate the scop.
799
   - NEXT_E is the edge where new generated code should be attached.
800
   - CONTEXT_LOOP is the loop in which the generated code will be placed
801
   - RENAME_MAP contains a set of tuples of new names associated to
802
     the original variables names.
803
   - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
804
   - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
805
     the sese region.  */
806
static edge
807
translate_clast_user (sese region, struct clast_user_stmt *stmt, edge next_e,
808
                      htab_t rename_map, VEC (tree, heap) **newivs,
809
                      htab_t newivs_index, htab_t bb_pbb_mapping,
810
                      htab_t params_index)
811
{
812
  gimple_bb_p gbb;
813
  basic_block new_bb;
814
  poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (stmt->statement);
815
  gbb = PBB_BLACK_BOX (pbb);
816
 
817
  if (GBB_BB (gbb) == ENTRY_BLOCK_PTR)
818
    return next_e;
819
 
820
  build_iv_mapping (rename_map, region, *newivs, newivs_index, stmt,
821
                    params_index);
822
  next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), region,
823
                                           next_e, rename_map);
824
  new_bb = next_e->src;
825
  mark_bb_with_pbb (pbb, new_bb, bb_pbb_mapping);
826
  update_ssa (TODO_update_ssa);
827
 
828
  return next_e;
829
}
830
 
831
/* Creates a new if region protecting the loop to be executed, if the execution
832
   count is zero (lb > ub).  */
833
static edge
834
graphite_create_new_loop_guard (sese region, edge entry_edge,
835
                                struct clast_for *stmt,
836
                                VEC (tree, heap) *newivs,
837
                                htab_t newivs_index, htab_t params_index)
838
{
839
  tree cond_expr;
840
  edge exit_edge;
841
  tree type = gcc_type_for_iv_of_clast_loop (stmt);
842
  tree lb = clast_to_gcc_expression (type, stmt->LB, region, newivs,
843
                                     newivs_index, params_index);
844
  tree ub = clast_to_gcc_expression (type, stmt->UB, region, newivs,
845
                                     newivs_index, params_index);
846
 
847
  /* XXX: Adding +1 and using LT_EXPR helps with loop latches that have a
848
     loop iteration count of "PARAMETER - 1".  For PARAMETER == 0 this becomes
849
     2^{32|64}, and the condition lb <= ub is true, even if we do not want this.
850
     However lb < ub + 1 is false, as expected.
851
     There might be a problem with cases where ub is 2^32.  */
852
  tree one;
853
  Value gmp_one;
854
  value_init (gmp_one);
855
  value_set_si (gmp_one, 1);
856
  one = gmp_cst_to_tree (type, gmp_one);
857
  value_clear (gmp_one);
858
 
859
  ub = fold_build2 (PLUS_EXPR, type, ub, one);
860
  cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub);
861
 
862
  exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
863
 
864
  return exit_edge;
865
}
866
 
867
 
868
/* Create the loop for a clast for statement.
869
 
870
   - REGION is the sese region we used to generate the scop.
871
   - NEXT_E is the edge where new generated code should be attached.
872
   - RENAME_MAP contains a set of tuples of new names associated to
873
     the original variables names.
874
   - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
875
   - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
876
     the sese region.  */
877
static edge
878
translate_clast_for_loop (sese region, loop_p context_loop,
879
                          struct clast_for *stmt, edge next_e,
880
                          htab_t rename_map, VEC (tree, heap) **newivs,
881
                          htab_t newivs_index, htab_t bb_pbb_mapping,
882
                          int level, htab_t params_index)
883
{
884
  struct loop *loop = graphite_create_new_loop (region, next_e, stmt,
885
                                                context_loop, newivs,
886
                                                newivs_index, params_index);
887
  edge last_e = single_exit (loop);
888
  edge to_body = single_succ_edge (loop->header);
889
  basic_block after = to_body->dest;
890
 
891
  /* Create a basic block for loop close phi nodes.  */
892
  last_e = single_succ_edge (split_edge (last_e));
893
 
894
  /* Translate the body of the loop.  */
895
  next_e = translate_clast (region, loop, stmt->body, to_body, rename_map,
896
                            newivs, newivs_index, bb_pbb_mapping, level + 1,
897
                            params_index);
898
  redirect_edge_succ_nodup (next_e, after);
899
  set_immediate_dominator (CDI_DOMINATORS, next_e->dest, next_e->src);
900
 
901
   /* Remove from rename_map all the tuples containing variables
902
      defined in loop's body.  */
903
  insert_loop_close_phis (rename_map, loop);
904
 
905
  if (flag_loop_parallelize_all
906
      && !dependency_in_loop_p (loop, bb_pbb_mapping,
907
                                get_scattering_level (level)))
908
    loop->can_be_parallel = true;
909
 
910
  return last_e;
911
}
912
 
913
/* Translates a clast for statement STMT to gimple.  First a guard is created
914
   protecting the loop, if it is executed zero times.  In this guard we create
915
   the real loop structure.
916
 
917
   - REGION is the sese region we used to generate the scop.
918
   - NEXT_E is the edge where new generated code should be attached.
919
   - RENAME_MAP contains a set of tuples of new names associated to
920
     the original variables names.
921
   - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
922
   - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
923
     the sese region.  */
924
static edge
925
translate_clast_for (sese region, loop_p context_loop, struct clast_for *stmt,
926
                     edge next_e, htab_t rename_map, VEC (tree, heap) **newivs,
927
                     htab_t newivs_index, htab_t bb_pbb_mapping, int level,
928
                     htab_t params_index)
929
{
930
  edge last_e = graphite_create_new_loop_guard (region, next_e, stmt, *newivs,
931
                                           newivs_index, params_index);
932
 
933
  edge true_e = get_true_edge_from_guard_bb (next_e->dest);
934
  edge false_e = get_false_edge_from_guard_bb (next_e->dest);
935
  edge exit_true_e = single_succ_edge (true_e->dest);
936
  edge exit_false_e = single_succ_edge (false_e->dest);
937
 
938
  htab_t before_guard = htab_create (10, rename_map_elt_info,
939
                                     eq_rename_map_elts, free);
940
  htab_traverse (rename_map, copy_renames, before_guard);
941
 
942
  next_e = translate_clast_for_loop (region, context_loop, stmt, true_e,
943
                                     rename_map, newivs,
944
                                     newivs_index, bb_pbb_mapping, level,
945
                                     params_index);
946
 
947
  insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
948
                     before_guard, rename_map);
949
 
950
  htab_delete (before_guard);
951
 
952
  return last_e;
953
}
954
 
955
/* Translates a clast guard statement STMT to gimple.
956
 
957
   - REGION is the sese region we used to generate the scop.
958
   - NEXT_E is the edge where new generated code should be attached.
959
   - CONTEXT_LOOP is the loop in which the generated code will be placed
960
   - RENAME_MAP contains a set of tuples of new names associated to
961
     the original variables names.
962
   - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.
963
   - PARAMS_INDEX connects the cloog parameters with the gimple parameters in
964
     the sese region.  */
965
static edge
966
translate_clast_guard (sese region, loop_p context_loop,
967
                       struct clast_guard *stmt, edge next_e,
968
                       htab_t rename_map, VEC (tree, heap) **newivs,
969
                       htab_t newivs_index, htab_t bb_pbb_mapping, int level,
970
                       htab_t params_index)
971
{
972
  edge last_e = graphite_create_new_guard (region, next_e, stmt, *newivs,
973
                                           newivs_index, params_index);
974
 
975
  edge true_e = get_true_edge_from_guard_bb (next_e->dest);
976
  edge false_e = get_false_edge_from_guard_bb (next_e->dest);
977
  edge exit_true_e = single_succ_edge (true_e->dest);
978
  edge exit_false_e = single_succ_edge (false_e->dest);
979
 
980
  htab_t before_guard = htab_create (10, rename_map_elt_info,
981
                                     eq_rename_map_elts, free);
982
  htab_traverse (rename_map, copy_renames, before_guard);
983
 
984
  next_e = translate_clast (region, context_loop, stmt->then, true_e,
985
                            rename_map, newivs, newivs_index, bb_pbb_mapping,
986
                            level, params_index);
987
 
988
  insert_guard_phis (last_e->src, exit_true_e, exit_false_e,
989
                     before_guard, rename_map);
990
 
991
  htab_delete (before_guard);
992
 
993
  return last_e;
994
}
995
 
996
/* Translates a CLAST statement STMT to GCC representation in the
997
   context of a SESE.
998
 
999
   - NEXT_E is the edge where new generated code should be attached.
1000
   - CONTEXT_LOOP is the loop in which the generated code will be placed
1001
   - RENAME_MAP contains a set of tuples of new names associated to
1002
     the original variables names.
1003
   - BB_PBB_MAPPING is is a basic_block and it's related poly_bb_p mapping.  */
1004
static edge
1005
translate_clast (sese region, loop_p context_loop, struct clast_stmt *stmt,
1006
                 edge next_e, htab_t rename_map, VEC (tree, heap) **newivs,
1007
                 htab_t newivs_index, htab_t bb_pbb_mapping, int level,
1008
                 htab_t params_index)
1009
{
1010
  if (!stmt)
1011
    return next_e;
1012
 
1013
  if (CLAST_STMT_IS_A (stmt, stmt_root))
1014
    ; /* Do nothing.  */
1015
 
1016
  else if (CLAST_STMT_IS_A (stmt, stmt_user))
1017
    next_e = translate_clast_user (region, (struct clast_user_stmt *) stmt,
1018
                                   next_e, rename_map, newivs, newivs_index,
1019
                                   bb_pbb_mapping, params_index);
1020
 
1021
  else if (CLAST_STMT_IS_A (stmt, stmt_for))
1022
    next_e = translate_clast_for (region, context_loop,
1023
                                  (struct clast_for *) stmt, next_e,
1024
                                  rename_map, newivs, newivs_index,
1025
                                  bb_pbb_mapping, level, params_index);
1026
 
1027
  else if (CLAST_STMT_IS_A (stmt, stmt_guard))
1028
    next_e = translate_clast_guard (region, context_loop,
1029
                                    (struct clast_guard *) stmt, next_e,
1030
                                    rename_map, newivs, newivs_index,
1031
                                    bb_pbb_mapping, level, params_index);
1032
 
1033
  else if (CLAST_STMT_IS_A (stmt, stmt_block))
1034
    next_e = translate_clast (region, context_loop,
1035
                              ((struct clast_block *) stmt)->body,
1036
                              next_e, rename_map, newivs, newivs_index,
1037
                              bb_pbb_mapping, level, params_index);
1038
  else
1039
    gcc_unreachable();
1040
 
1041
  recompute_all_dominators ();
1042
  graphite_verify ();
1043
 
1044
  return translate_clast (region, context_loop, stmt->next, next_e,
1045
                          rename_map, newivs, newivs_index,
1046
                          bb_pbb_mapping, level, params_index);
1047
}
1048
 
1049
/* Returns the first cloog name used in EXPR.  */
1050
 
1051
static const char *
1052
find_cloog_iv_in_expr (struct clast_expr *expr)
1053
{
1054
  struct clast_term *term = (struct clast_term *) expr;
1055
  struct clast_reduction *red;
1056
  int i;
1057
 
1058
  if (expr->type == expr_term)
1059
    return term->var;
1060
 
1061
  if (expr->type != expr_red)
1062
    return NULL;
1063
 
1064
  red = (struct clast_reduction *) expr;
1065
  for (i = 0; i < red->n; i++)
1066
    {
1067
      const char *res = find_cloog_iv_in_expr (red->elts[i]);
1068
 
1069
      if (res)
1070
        return res;
1071
    }
1072
 
1073
  return NULL;
1074
}
1075
 
1076
/* Build for USER_STMT a map between the CLAST induction variables and
1077
   the corresponding GCC old induction variables.  This information is
1078
   stored on each GRAPHITE_BB.  */
1079
 
1080
static void
1081
compute_cloog_iv_types_1 (poly_bb_p pbb, struct clast_user_stmt *user_stmt)
1082
{
1083
  gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1084
  struct clast_stmt *t;
1085
  int index = 0;
1086
 
1087
  for (t = user_stmt->substitutions; t; t = t->next, index++)
1088
    {
1089
      PTR *slot;
1090
      struct ivtype_map_elt_s tmp;
1091
      struct clast_expr *expr = (struct clast_expr *)
1092
        ((struct clast_assignment *)t)->RHS;
1093
 
1094
      /* Create an entry (clast_var, type).  */
1095
      tmp.cloog_iv = find_cloog_iv_in_expr (expr);
1096
      if (!tmp.cloog_iv)
1097
        continue;
1098
 
1099
      slot = htab_find_slot (GBB_CLOOG_IV_TYPES (gbb), &tmp, INSERT);
1100
 
1101
      if (slot && !*slot)
1102
        {
1103
          tree oldiv = pbb_to_depth_to_oldiv (pbb, index);
1104
          tree type = TREE_TYPE (oldiv);
1105
          *slot = new_ivtype_map_elt (tmp.cloog_iv, type);
1106
        }
1107
    }
1108
}
1109
 
1110
/* Walk the CLAST tree starting from STMT and build for each
1111
   clast_user_stmt a map between the CLAST induction variables and the
1112
   corresponding GCC old induction variables.  This information is
1113
   stored on each GRAPHITE_BB.  */
1114
 
1115
static void
1116
compute_cloog_iv_types (struct clast_stmt *stmt)
1117
{
1118
  if (!stmt)
1119
    return;
1120
 
1121
  if (CLAST_STMT_IS_A (stmt, stmt_root))
1122
    goto next;
1123
 
1124
  if (CLAST_STMT_IS_A (stmt, stmt_user))
1125
    {
1126
      CloogStatement *cs = ((struct clast_user_stmt *) stmt)->statement;
1127
      poly_bb_p pbb = (poly_bb_p) cloog_statement_usr (cs);
1128
      gimple_bb_p gbb = PBB_BLACK_BOX (pbb);
1129
 
1130
      if (!GBB_CLOOG_IV_TYPES (gbb))
1131
        GBB_CLOOG_IV_TYPES (gbb) = htab_create (10, ivtype_map_elt_info,
1132
                                                eq_ivtype_map_elts, free);
1133
 
1134
      compute_cloog_iv_types_1 (pbb, (struct clast_user_stmt *) stmt);
1135
      goto next;
1136
    }
1137
 
1138
  if (CLAST_STMT_IS_A (stmt, stmt_for))
1139
    {
1140
      struct clast_stmt *s = ((struct clast_for *) stmt)->body;
1141
      compute_cloog_iv_types (s);
1142
      goto next;
1143
    }
1144
 
1145
  if (CLAST_STMT_IS_A (stmt, stmt_guard))
1146
    {
1147
      struct clast_stmt *s = ((struct clast_guard *) stmt)->then;
1148
      compute_cloog_iv_types (s);
1149
      goto next;
1150
    }
1151
 
1152
  if (CLAST_STMT_IS_A (stmt, stmt_block))
1153
    {
1154
      struct clast_stmt *s = ((struct clast_block *) stmt)->body;
1155
      compute_cloog_iv_types (s);
1156
      goto next;
1157
    }
1158
 
1159
  gcc_unreachable ();
1160
 
1161
 next:
1162
  compute_cloog_iv_types (stmt->next);
1163
}
1164
 
1165
/* Free the SCATTERING domain list.  */
1166
 
1167
static void
1168
free_scattering (CloogDomainList *scattering)
1169
{
1170
  while (scattering)
1171
    {
1172
      CloogDomain *dom = cloog_domain (scattering);
1173
      CloogDomainList *next = cloog_next_domain (scattering);
1174
 
1175
      cloog_domain_free (dom);
1176
      free (scattering);
1177
      scattering = next;
1178
    }
1179
}
1180
 
1181
/* Initialize Cloog's parameter names from the names used in GIMPLE.
1182
   Initialize Cloog's iterator names, using 'graphite_iterator_%d'
1183
   from 0 to scop_nb_loops (scop).  */
1184
 
1185
static void
1186
initialize_cloog_names (scop_p scop, CloogProgram *prog)
1187
{
1188
  sese region = SCOP_REGION (scop);
1189
  int i;
1190
  int nb_iterators = scop_max_loop_depth (scop);
1191
  int nb_scattering = cloog_program_nb_scattdims (prog);
1192
  int nb_parameters = VEC_length (tree, SESE_PARAMS (region));
1193
  char **iterators = XNEWVEC (char *, nb_iterators * 2);
1194
  char **scattering = XNEWVEC (char *, nb_scattering);
1195
  char **parameters= XNEWVEC (char *, nb_parameters);
1196
 
1197
  cloog_program_set_names (prog, cloog_names_malloc ());
1198
 
1199
  for (i = 0; i < nb_parameters; i++)
1200
    {
1201
      tree param = VEC_index (tree, SESE_PARAMS(region), i);
1202
      const char *name = get_name (param);
1203
      int len;
1204
 
1205
      if (!name)
1206
        name = "T";
1207
 
1208
      len = strlen (name);
1209
      len += 17;
1210
      parameters[i] = XNEWVEC (char, len + 1);
1211
      snprintf (parameters[i], len, "%s_%d", name, SSA_NAME_VERSION (param));
1212
    }
1213
 
1214
  cloog_names_set_nb_parameters (cloog_program_names (prog), nb_parameters);
1215
  cloog_names_set_parameters (cloog_program_names (prog), parameters);
1216
 
1217
  for (i = 0; i < nb_iterators; i++)
1218
    {
1219
      int len = 4 + 16;
1220
      iterators[i] = XNEWVEC (char, len);
1221
      snprintf (iterators[i], len, "git_%d", i);
1222
    }
1223
 
1224
  cloog_names_set_nb_iterators (cloog_program_names (prog),
1225
                                nb_iterators);
1226
  cloog_names_set_iterators (cloog_program_names (prog),
1227
                             iterators);
1228
 
1229
  for (i = 0; i < nb_scattering; i++)
1230
    {
1231
      int len = 5 + 16;
1232
      scattering[i] = XNEWVEC (char, len);
1233
      snprintf (scattering[i], len, "scat_%d", i);
1234
    }
1235
 
1236
  cloog_names_set_nb_scattering (cloog_program_names (prog),
1237
                                 nb_scattering);
1238
  cloog_names_set_scattering (cloog_program_names (prog),
1239
                              scattering);
1240
}
1241
 
1242
/* Build cloog program for SCoP.  */
1243
 
1244
static void
1245
build_cloog_prog (scop_p scop, CloogProgram *prog)
1246
{
1247
  int i;
1248
  int max_nb_loops = scop_max_loop_depth (scop);
1249
  poly_bb_p pbb;
1250
  CloogLoop *loop_list = NULL;
1251
  CloogBlockList *block_list = NULL;
1252
  CloogDomainList *scattering = NULL;
1253
  int nbs = 2 * max_nb_loops + 1;
1254
  int *scaldims;
1255
 
1256
  cloog_program_set_context
1257
    (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop)));
1258
  nbs = unify_scattering_dimensions (scop);
1259
  scaldims = (int *) xmalloc (nbs * (sizeof (int)));
1260
  cloog_program_set_nb_scattdims (prog, nbs);
1261
  initialize_cloog_names (scop, prog);
1262
 
1263
  for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
1264
    {
1265
      CloogStatement *stmt;
1266
      CloogBlock *block;
1267
 
1268
      /* Dead code elimination: when the domain of a PBB is empty,
1269
         don't generate code for the PBB.  */
1270
      if (ppl_Pointset_Powerset_C_Polyhedron_is_empty (PBB_DOMAIN (pbb)))
1271
        continue;
1272
 
1273
      /* Build the new statement and its block.  */
1274
      stmt = cloog_statement_alloc (pbb_index (pbb));
1275
      block = cloog_block_alloc (stmt, 0, NULL, pbb_dim_iter_domain (pbb));
1276
      cloog_statement_set_usr (stmt, pbb);
1277
 
1278
      /* Build loop list.  */
1279
      {
1280
        CloogLoop *new_loop_list = cloog_loop_malloc ();
1281
        cloog_loop_set_next (new_loop_list, loop_list);
1282
        cloog_loop_set_domain
1283
          (new_loop_list,
1284
           new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb)));
1285
        cloog_loop_set_block (new_loop_list, block);
1286
        loop_list = new_loop_list;
1287
      }
1288
 
1289
      /* Build block list.  */
1290
      {
1291
        CloogBlockList *new_block_list = cloog_block_list_malloc ();
1292
 
1293
        cloog_block_list_set_next (new_block_list, block_list);
1294
        cloog_block_list_set_block (new_block_list, block);
1295
        block_list = new_block_list;
1296
      }
1297
 
1298
      /* Build scattering list.  */
1299
      {
1300
        /* XXX: Replace with cloog_domain_list_alloc(), when available.  */
1301
        CloogDomainList *new_scattering
1302
          = (CloogDomainList *) xmalloc (sizeof (CloogDomainList));
1303
        ppl_Polyhedron_t scat;
1304
        CloogDomain *dom;
1305
 
1306
        scat = PBB_TRANSFORMED_SCATTERING (pbb);
1307
        dom = new_Cloog_Domain_from_ppl_Polyhedron (scat);
1308
 
1309
        cloog_set_next_domain (new_scattering, scattering);
1310
        cloog_set_domain (new_scattering, dom);
1311
        scattering = new_scattering;
1312
      }
1313
    }
1314
 
1315
  cloog_program_set_loop (prog, loop_list);
1316
  cloog_program_set_blocklist (prog, block_list);
1317
 
1318
  for (i = 0; i < nbs; i++)
1319
    scaldims[i] = 0 ;
1320
 
1321
  cloog_program_set_scaldims (prog, scaldims);
1322
 
1323
  /* Extract scalar dimensions to simplify the code generation problem.  */
1324
  cloog_program_extract_scalars (prog, scattering);
1325
 
1326
  /* Apply scattering.  */
1327
  cloog_program_scatter (prog, scattering);
1328
  free_scattering (scattering);
1329
 
1330
  /* Iterators corresponding to scalar dimensions have to be extracted.  */
1331
  cloog_names_scalarize (cloog_program_names (prog), nbs,
1332
                         cloog_program_scaldims (prog));
1333
 
1334
  /* Free blocklist.  */
1335
  {
1336
    CloogBlockList *next = cloog_program_blocklist (prog);
1337
 
1338
    while (next)
1339
      {
1340
        CloogBlockList *toDelete = next;
1341
        next = cloog_block_list_next (next);
1342
        cloog_block_list_set_next (toDelete, NULL);
1343
        cloog_block_list_set_block (toDelete, NULL);
1344
        cloog_block_list_free (toDelete);
1345
      }
1346
    cloog_program_set_blocklist (prog, NULL);
1347
  }
1348
}
1349
 
1350
/* Return the options that will be used in GLOOG.  */
1351
 
1352
static CloogOptions *
1353
set_cloog_options (void)
1354
{
1355
  CloogOptions *options = cloog_options_malloc ();
1356
 
1357
  /* Change cloog output language to C.  If we do use FORTRAN instead, cloog
1358
     will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
1359
     we pass an incomplete program to cloog.  */
1360
  options->language = LANGUAGE_C;
1361
 
1362
  /* Enable complex equality spreading: removes dummy statements
1363
     (assignments) in the generated code which repeats the
1364
     substitution equations for statements.  This is useless for
1365
     GLooG.  */
1366
  options->esp = 1;
1367
 
1368
  /* Enable C pretty-printing mode: normalizes the substitution
1369
     equations for statements.  */
1370
  options->cpp = 1;
1371
 
1372
  /* Allow cloog to build strides with a stride width different to one.
1373
     This example has stride = 4:
1374
 
1375
     for (i = 0; i < 20; i += 4)
1376
       A  */
1377
  options->strides = 1;
1378
 
1379
  /* Disable optimizations and make cloog generate source code closer to the
1380
     input.  This is useful for debugging,  but later we want the optimized
1381
     code.
1382
 
1383
     XXX: We can not disable optimizations, as loop blocking is not working
1384
     without them.  */
1385
  if (0)
1386
    {
1387
      options->f = -1;
1388
      options->l = INT_MAX;
1389
    }
1390
 
1391
  return options;
1392
}
1393
 
1394
/* Prints STMT to STDERR.  */
1395
 
1396
void
1397
print_clast_stmt (FILE *file, struct clast_stmt *stmt)
1398
{
1399
  CloogOptions *options = set_cloog_options ();
1400
 
1401
  pprint (file, stmt, 0, options);
1402
  cloog_options_free (options);
1403
}
1404
 
1405
/* Prints STMT to STDERR.  */
1406
 
1407
void
1408
debug_clast_stmt (struct clast_stmt *stmt)
1409
{
1410
  print_clast_stmt (stderr, stmt);
1411
}
1412
 
1413
/* Translate SCOP to a CLooG program and clast.  These two
1414
   representations should be freed together: a clast cannot be used
1415
   without a program.  */
1416
 
1417
cloog_prog_clast
1418
scop_to_clast (scop_p scop)
1419
{
1420
  CloogOptions *options = set_cloog_options ();
1421
  cloog_prog_clast pc;
1422
 
1423
  /* Connect new cloog prog generation to graphite.  */
1424
  pc.prog = cloog_program_malloc ();
1425
  build_cloog_prog (scop, pc.prog);
1426
  pc.prog = cloog_program_generate (pc.prog, options);
1427
  pc.stmt = cloog_clast_create (pc.prog, options);
1428
 
1429
  cloog_options_free (options);
1430
  return pc;
1431
}
1432
 
1433
/* Prints to FILE the code generated by CLooG for SCOP.  */
1434
 
1435
void
1436
print_generated_program (FILE *file, scop_p scop)
1437
{
1438
  CloogOptions *options = set_cloog_options ();
1439
  cloog_prog_clast pc = scop_to_clast (scop);
1440
 
1441
  fprintf (file, "       (prog: \n");
1442
  cloog_program_print (file, pc.prog);
1443
  fprintf (file, "       )\n");
1444
 
1445
  fprintf (file, "       (clast: \n");
1446
  pprint (file, pc.stmt, 0, options);
1447
  fprintf (file, "       )\n");
1448
 
1449
  cloog_options_free (options);
1450
  cloog_clast_free (pc.stmt);
1451
  cloog_program_free (pc.prog);
1452
}
1453
 
1454
/* Prints to STDERR the code generated by CLooG for SCOP.  */
1455
 
1456
void
1457
debug_generated_program (scop_p scop)
1458
{
1459
  print_generated_program (stderr, scop);
1460
}
1461
 
1462
/* Add CLooG names to parameter index.  The index is used to translate
1463
   back from CLooG names to GCC trees.  */
1464
 
1465
static void
1466
create_params_index (htab_t index_table, CloogProgram *prog) {
1467
  CloogNames* names = cloog_program_names (prog);
1468
  int nb_parameters = cloog_names_nb_parameters (names);
1469
  char **parameters = cloog_names_parameters (names);
1470
  int i;
1471
 
1472
  for (i = 0; i < nb_parameters; i++)
1473
    save_clast_name_index (index_table, parameters[i], i);
1474
}
1475
 
1476
/* GIMPLE Loop Generator: generates loops from STMT in GIMPLE form for
1477
   the given SCOP.  Return true if code generation succeeded.
1478
   BB_PBB_MAPPING is a basic_block and it's related poly_bb_p mapping.
1479
*/
1480
 
1481
bool
1482
gloog (scop_p scop, VEC (scop_p, heap) *scops, htab_t bb_pbb_mapping)
1483
{
1484
  VEC (tree, heap) *newivs = VEC_alloc (tree, heap, 10);
1485
  loop_p context_loop;
1486
  sese region = SCOP_REGION (scop);
1487
  ifsese if_region = NULL;
1488
  htab_t rename_map, newivs_index, params_index;
1489
  cloog_prog_clast pc;
1490
  int i;
1491
 
1492
  timevar_push (TV_GRAPHITE_CODE_GEN);
1493
  gloog_error = false;
1494
 
1495
  pc = scop_to_clast (scop);
1496
 
1497
  if (dump_file && (dump_flags & TDF_DETAILS))
1498
    {
1499
      fprintf (dump_file, "\nCLAST generated by CLooG: \n");
1500
      print_clast_stmt (dump_file, pc.stmt);
1501
      fprintf (dump_file, "\n");
1502
    }
1503
 
1504
  recompute_all_dominators ();
1505
  graphite_verify ();
1506
 
1507
  if_region = move_sese_in_condition (region);
1508
  sese_insert_phis_for_liveouts (region,
1509
                                 if_region->region->exit->src,
1510
                                 if_region->false_region->exit,
1511
                                 if_region->true_region->exit);
1512
  recompute_all_dominators ();
1513
  graphite_verify ();
1514
 
1515
  context_loop = SESE_ENTRY (region)->src->loop_father;
1516
  compute_cloog_iv_types (pc.stmt);
1517
  rename_map = htab_create (10, rename_map_elt_info, eq_rename_map_elts, free);
1518
  newivs_index = htab_create (10, clast_name_index_elt_info,
1519
                              eq_clast_name_indexes, free);
1520
  params_index = htab_create (10, clast_name_index_elt_info,
1521
                              eq_clast_name_indexes, free);
1522
 
1523
  create_params_index (params_index, pc.prog);
1524
 
1525
  translate_clast (region, context_loop, pc.stmt,
1526
                   if_region->true_region->entry,
1527
                   rename_map, &newivs, newivs_index,
1528
                   bb_pbb_mapping, 1, params_index);
1529
  graphite_verify ();
1530
  sese_adjust_liveout_phis (region, rename_map,
1531
                            if_region->region->exit->src,
1532
                            if_region->false_region->exit,
1533
                            if_region->true_region->exit);
1534
  scev_reset_htab ();
1535
  rename_nb_iterations (rename_map);
1536
 
1537
  for (i = 0; VEC_iterate (scop_p, scops, i, scop); i++)
1538
    rename_sese_parameters (rename_map, SCOP_REGION (scop));
1539
 
1540
  recompute_all_dominators ();
1541
  graphite_verify ();
1542
 
1543
  if (gloog_error)
1544
    set_ifsese_condition (if_region, integer_zero_node);
1545
 
1546
  free (if_region->true_region);
1547
  free (if_region->region);
1548
  free (if_region);
1549
 
1550
  htab_delete (rename_map);
1551
  htab_delete (newivs_index);
1552
  htab_delete (params_index);
1553
  VEC_free (tree, heap, newivs);
1554
  cloog_clast_free (pc.stmt);
1555
  cloog_program_free (pc.prog);
1556
  timevar_pop (TV_GRAPHITE_CODE_GEN);
1557
 
1558
  if (dump_file && (dump_flags & TDF_DETAILS))
1559
    {
1560
      loop_p loop;
1561
      loop_iterator li;
1562
      int num_no_dependency = 0;
1563
 
1564
      FOR_EACH_LOOP (li, loop, 0)
1565
        if (loop->can_be_parallel)
1566
          num_no_dependency++;
1567
 
1568
      fprintf (dump_file, "\n%d loops carried no dependency.\n",
1569
               num_no_dependency);
1570
    }
1571
 
1572
  return !gloog_error;
1573
}
1574
 
1575
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.