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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [tree-outof-ssa.c] - Blame information for rev 38

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

Line No. Rev Author Line
1 38 julius
/* Convert a program in SSA form into Normal form.
2
   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
3
   Contributed by Andrew Macleod <amacleod@redhat.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 "tree.h"
26
#include "flags.h"
27
#include "rtl.h"
28
#include "tm_p.h"
29
#include "ggc.h"
30
#include "langhooks.h"
31
#include "hard-reg-set.h"
32
#include "basic-block.h"
33
#include "output.h"
34
#include "expr.h"
35
#include "function.h"
36
#include "diagnostic.h"
37
#include "bitmap.h"
38
#include "tree-flow.h"
39
#include "tree-gimple.h"
40
#include "tree-inline.h"
41
#include "varray.h"
42
#include "timevar.h"
43
#include "hashtab.h"
44
#include "tree-dump.h"
45
#include "tree-ssa-live.h"
46
#include "tree-pass.h"
47
#include "toplev.h"
48
#include "vecprim.h"
49
 
50
/* Flags to pass to remove_ssa_form.  */
51
 
52
#define SSANORM_PERFORM_TER             0x1
53
#define SSANORM_COMBINE_TEMPS           0x2
54
#define SSANORM_COALESCE_PARTITIONS     0x4
55
 
56
/* Used to hold all the components required to do SSA PHI elimination.
57
   The node and pred/succ list is a simple linear list of nodes and
58
   edges represented as pairs of nodes.
59
 
60
   The predecessor and successor list:  Nodes are entered in pairs, where
61
   [0] ->PRED, [1]->SUCC.  All the even indexes in the array represent
62
   predecessors, all the odd elements are successors.
63
 
64
   Rationale:
65
   When implemented as bitmaps, very large programs SSA->Normal times were
66
   being dominated by clearing the interference graph.
67
 
68
   Typically this list of edges is extremely small since it only includes
69
   PHI results and uses from a single edge which have not coalesced with
70
   each other.  This means that no virtual PHI nodes are included, and
71
   empirical evidence suggests that the number of edges rarely exceed
72
   3, and in a bootstrap of GCC, the maximum size encountered was 7.
73
   This also limits the number of possible nodes that are involved to
74
   rarely more than 6, and in the bootstrap of gcc, the maximum number
75
   of nodes encountered was 12.  */
76
 
77
typedef struct _elim_graph {
78
  /* Size of the elimination vectors.  */
79
  int size;
80
 
81
  /* List of nodes in the elimination graph.  */
82
  VEC(tree,heap) *nodes;
83
 
84
  /*  The predecessor and successor edge list.  */
85
  VEC(int,heap) *edge_list;
86
 
87
  /* Visited vector.  */
88
  sbitmap visited;
89
 
90
  /* Stack for visited nodes.  */
91
  VEC(int,heap) *stack;
92
 
93
  /* The variable partition map.  */
94
  var_map map;
95
 
96
  /* Edge being eliminated by this graph.  */
97
  edge e;
98
 
99
  /* List of constant copies to emit.  These are pushed on in pairs.  */
100
  VEC(tree,heap) *const_copies;
101
} *elim_graph;
102
 
103
 
104
/* Local functions.  */
105
static tree create_temp (tree);
106
static void insert_copy_on_edge (edge, tree, tree);
107
static elim_graph new_elim_graph (int);
108
static inline void delete_elim_graph (elim_graph);
109
static inline void clear_elim_graph (elim_graph);
110
static inline int elim_graph_size (elim_graph);
111
static inline void elim_graph_add_node (elim_graph, tree);
112
static inline void elim_graph_add_edge (elim_graph, int, int);
113
static inline int elim_graph_remove_succ_edge (elim_graph, int);
114
 
115
static inline void eliminate_name (elim_graph, tree);
116
static void eliminate_build (elim_graph, basic_block);
117
static void elim_forward (elim_graph, int);
118
static int elim_unvisited_predecessor (elim_graph, int);
119
static void elim_backward (elim_graph, int);
120
static void elim_create (elim_graph, int);
121
static void eliminate_phi (edge, elim_graph);
122
static tree_live_info_p coalesce_ssa_name (var_map, int);
123
static void assign_vars (var_map);
124
static bool replace_use_variable (var_map, use_operand_p, tree *);
125
static bool replace_def_variable (var_map, def_operand_p, tree *);
126
static void eliminate_virtual_phis (void);
127
static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p);
128
static void print_exprs (FILE *, const char *, tree, const char *, tree,
129
                         const char *);
130
static void print_exprs_edge (FILE *, edge, const char *, tree, const char *,
131
                              tree);
132
 
133
 
134
/* Create a temporary variable based on the type of variable T.  Use T's name
135
   as the prefix.  */
136
 
137
static tree
138
create_temp (tree t)
139
{
140
  tree tmp;
141
  const char *name = NULL;
142
  tree type;
143
 
144
  if (TREE_CODE (t) == SSA_NAME)
145
    t = SSA_NAME_VAR (t);
146
 
147
  gcc_assert (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL);
148
 
149
  type = TREE_TYPE (t);
150
  tmp = DECL_NAME (t);
151
  if (tmp)
152
    name = IDENTIFIER_POINTER (tmp);
153
 
154
  if (name == NULL)
155
    name = "temp";
156
  tmp = create_tmp_var (type, name);
157
 
158
  if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
159
    {
160
      SET_DECL_DEBUG_EXPR (tmp, DECL_DEBUG_EXPR (t));
161
      DECL_DEBUG_EXPR_IS_FROM (tmp) = 1;
162
    }
163
  else if (!DECL_IGNORED_P (t))
164
    {
165
      SET_DECL_DEBUG_EXPR (tmp, t);
166
      DECL_DEBUG_EXPR_IS_FROM (tmp) = 1;
167
    }
168
  DECL_ARTIFICIAL (tmp) = DECL_ARTIFICIAL (t);
169
  DECL_IGNORED_P (tmp) = DECL_IGNORED_P (t);
170
  add_referenced_var (tmp);
171
 
172
  /* add_referenced_var will create the annotation and set up some
173
     of the flags in the annotation.  However, some flags we need to
174
     inherit from our original variable.  */
175
  var_ann (tmp)->symbol_mem_tag = var_ann (t)->symbol_mem_tag;
176
  if (is_call_clobbered (t))
177
    mark_call_clobbered (tmp, var_ann (t)->escape_mask);
178
 
179
  return tmp;
180
}
181
 
182
 
183
/* This helper function fill insert a copy from a constant or variable SRC to
184
   variable DEST on edge E.  */
185
 
186
static void
187
insert_copy_on_edge (edge e, tree dest, tree src)
188
{
189
  tree copy;
190
 
191
  copy = build2 (MODIFY_EXPR, TREE_TYPE (dest), dest, src);
192
  set_is_used (dest);
193
 
194
  if (TREE_CODE (src) == ADDR_EXPR)
195
    src = TREE_OPERAND (src, 0);
196
  if (TREE_CODE (src) == VAR_DECL || TREE_CODE (src) == PARM_DECL)
197
    set_is_used (src);
198
 
199
  if (dump_file && (dump_flags & TDF_DETAILS))
200
    {
201
      fprintf (dump_file,
202
               "Inserting a copy on edge BB%d->BB%d :",
203
               e->src->index,
204
               e->dest->index);
205
      print_generic_expr (dump_file, copy, dump_flags);
206
      fprintf (dump_file, "\n");
207
    }
208
 
209
  bsi_insert_on_edge (e, copy);
210
}
211
 
212
 
213
/* Create an elimination graph with SIZE nodes and associated data
214
   structures.  */
215
 
216
static elim_graph
217
new_elim_graph (int size)
218
{
219
  elim_graph g = (elim_graph) xmalloc (sizeof (struct _elim_graph));
220
 
221
  g->nodes = VEC_alloc (tree, heap, 30);
222
  g->const_copies = VEC_alloc (tree, heap, 20);
223
  g->edge_list = VEC_alloc (int, heap, 20);
224
  g->stack = VEC_alloc (int, heap, 30);
225
 
226
  g->visited = sbitmap_alloc (size);
227
 
228
  return g;
229
}
230
 
231
 
232
/* Empty elimination graph G.  */
233
 
234
static inline void
235
clear_elim_graph (elim_graph g)
236
{
237
  VEC_truncate (tree, g->nodes, 0);
238
  VEC_truncate (int, g->edge_list, 0);
239
}
240
 
241
 
242
/* Delete elimination graph G.  */
243
 
244
static inline void
245
delete_elim_graph (elim_graph g)
246
{
247
  sbitmap_free (g->visited);
248
  VEC_free (int, heap, g->stack);
249
  VEC_free (int, heap, g->edge_list);
250
  VEC_free (tree, heap, g->const_copies);
251
  VEC_free (tree, heap, g->nodes);
252
  free (g);
253
}
254
 
255
 
256
/* Return the number of nodes in graph G.  */
257
 
258
static inline int
259
elim_graph_size (elim_graph g)
260
{
261
  return VEC_length (tree, g->nodes);
262
}
263
 
264
 
265
/* Add NODE to graph G, if it doesn't exist already.  */
266
 
267
static inline void
268
elim_graph_add_node (elim_graph g, tree node)
269
{
270
  int x;
271
  tree t;
272
 
273
  for (x = 0; VEC_iterate (tree, g->nodes, x, t); x++)
274
    if (t == node)
275
      return;
276
  VEC_safe_push (tree, heap, g->nodes, node);
277
}
278
 
279
 
280
/* Add the edge PRED->SUCC to graph G.  */
281
 
282
static inline void
283
elim_graph_add_edge (elim_graph g, int pred, int succ)
284
{
285
  VEC_safe_push (int, heap, g->edge_list, pred);
286
  VEC_safe_push (int, heap, g->edge_list, succ);
287
}
288
 
289
 
290
/* Remove an edge from graph G for which NODE is the predecessor, and
291
   return the successor node.  -1 is returned if there is no such edge.  */
292
 
293
static inline int
294
elim_graph_remove_succ_edge (elim_graph g, int node)
295
{
296
  int y;
297
  unsigned x;
298
  for (x = 0; x < VEC_length (int, g->edge_list); x += 2)
299
    if (VEC_index (int, g->edge_list, x) == node)
300
      {
301
        VEC_replace (int, g->edge_list, x, -1);
302
        y = VEC_index (int, g->edge_list, x + 1);
303
        VEC_replace (int, g->edge_list, x + 1, -1);
304
        return y;
305
      }
306
  return -1;
307
}
308
 
309
 
310
/* Find all the nodes in GRAPH which are successors to NODE in the
311
   edge list.  VAR will hold the partition number found.  CODE is the
312
   code fragment executed for every node found.  */
313
 
314
#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, CODE)                \
315
do {                                                                    \
316
  unsigned x_;                                                          \
317
  int y_;                                                               \
318
  for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2)       \
319
    {                                                                   \
320
      y_ = VEC_index (int, (GRAPH)->edge_list, x_);                     \
321
      if (y_ != (NODE))                                                 \
322
        continue;                                                       \
323
      (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1);              \
324
      CODE;                                                             \
325
    }                                                                   \
326
} while (0)
327
 
328
 
329
/* Find all the nodes which are predecessors of NODE in the edge list for
330
   GRAPH.  VAR will hold the partition number found.  CODE is the
331
   code fragment executed for every node found.  */
332
 
333
#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, CODE)                \
334
do {                                                                    \
335
  unsigned x_;                                                          \
336
  int y_;                                                               \
337
  for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2)       \
338
    {                                                                   \
339
      y_ = VEC_index (int, (GRAPH)->edge_list, x_ + 1);                 \
340
      if (y_ != (NODE))                                                 \
341
        continue;                                                       \
342
      (VAR) = VEC_index (int, (GRAPH)->edge_list, x_);                  \
343
      CODE;                                                             \
344
    }                                                                   \
345
} while (0)
346
 
347
 
348
/* Add T to elimination graph G.  */
349
 
350
static inline void
351
eliminate_name (elim_graph g, tree T)
352
{
353
  elim_graph_add_node (g, T);
354
}
355
 
356
 
357
/* Build elimination graph G for basic block BB on incoming PHI edge
358
   G->e.  */
359
 
360
static void
361
eliminate_build (elim_graph g, basic_block B)
362
{
363
  tree phi;
364
  tree T0, Ti;
365
  int p0, pi;
366
 
367
  clear_elim_graph (g);
368
 
369
  for (phi = phi_nodes (B); phi; phi = PHI_CHAIN (phi))
370
    {
371
      T0 = var_to_partition_to_var (g->map, PHI_RESULT (phi));
372
 
373
      /* Ignore results which are not in partitions.  */
374
      if (T0 == NULL_TREE)
375
        continue;
376
 
377
      Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
378
 
379
      /* If this argument is a constant, or a SSA_NAME which is being
380
         left in SSA form, just queue a copy to be emitted on this
381
         edge.  */
382
      if (!phi_ssa_name_p (Ti)
383
          || (TREE_CODE (Ti) == SSA_NAME
384
              && var_to_partition (g->map, Ti) == NO_PARTITION))
385
        {
386
          /* Save constant copies until all other copies have been emitted
387
             on this edge.  */
388
          VEC_safe_push (tree, heap, g->const_copies, T0);
389
          VEC_safe_push (tree, heap, g->const_copies, Ti);
390
        }
391
      else
392
        {
393
          Ti = var_to_partition_to_var (g->map, Ti);
394
          if (T0 != Ti)
395
            {
396
              eliminate_name (g, T0);
397
              eliminate_name (g, Ti);
398
              p0 = var_to_partition (g->map, T0);
399
              pi = var_to_partition (g->map, Ti);
400
              elim_graph_add_edge (g, p0, pi);
401
            }
402
        }
403
    }
404
}
405
 
406
 
407
/* Push successors of T onto the elimination stack for G.  */
408
 
409
static void
410
elim_forward (elim_graph g, int T)
411
{
412
  int S;
413
  SET_BIT (g->visited, T);
414
  FOR_EACH_ELIM_GRAPH_SUCC (g, T, S,
415
    {
416
      if (!TEST_BIT (g->visited, S))
417
        elim_forward (g, S);
418
    });
419
  VEC_safe_push (int, heap, g->stack, T);
420
}
421
 
422
 
423
/* Return 1 if there unvisited predecessors of T in graph G.  */
424
 
425
static int
426
elim_unvisited_predecessor (elim_graph g, int T)
427
{
428
  int P;
429
  FOR_EACH_ELIM_GRAPH_PRED (g, T, P,
430
    {
431
      if (!TEST_BIT (g->visited, P))
432
        return 1;
433
    });
434
  return 0;
435
}
436
 
437
/* Process predecessors first, and insert a copy.  */
438
 
439
static void
440
elim_backward (elim_graph g, int T)
441
{
442
  int P;
443
  SET_BIT (g->visited, T);
444
  FOR_EACH_ELIM_GRAPH_PRED (g, T, P,
445
    {
446
      if (!TEST_BIT (g->visited, P))
447
        {
448
          elim_backward (g, P);
449
          insert_copy_on_edge (g->e,
450
                               partition_to_var (g->map, P),
451
                               partition_to_var (g->map, T));
452
        }
453
    });
454
}
455
 
456
/* Insert required copies for T in graph G.  Check for a strongly connected
457
   region, and create a temporary to break the cycle if one is found.  */
458
 
459
static void
460
elim_create (elim_graph g, int T)
461
{
462
  tree U;
463
  int P, S;
464
 
465
  if (elim_unvisited_predecessor (g, T))
466
    {
467
      U = create_temp (partition_to_var (g->map, T));
468
      insert_copy_on_edge (g->e, U, partition_to_var (g->map, T));
469
      FOR_EACH_ELIM_GRAPH_PRED (g, T, P,
470
        {
471
          if (!TEST_BIT (g->visited, P))
472
            {
473
              elim_backward (g, P);
474
              insert_copy_on_edge (g->e, partition_to_var (g->map, P), U);
475
            }
476
        });
477
    }
478
  else
479
    {
480
      S = elim_graph_remove_succ_edge (g, T);
481
      if (S != -1)
482
        {
483
          SET_BIT (g->visited, T);
484
          insert_copy_on_edge (g->e,
485
                               partition_to_var (g->map, T),
486
                               partition_to_var (g->map, S));
487
        }
488
    }
489
 
490
}
491
 
492
/* Eliminate all the phi nodes on edge E in graph G.  */
493
 
494
static void
495
eliminate_phi (edge e, elim_graph g)
496
{
497
  int x;
498
  basic_block B = e->dest;
499
 
500
  gcc_assert (VEC_length (tree, g->const_copies) == 0);
501
 
502
  /* Abnormal edges already have everything coalesced.  */
503
  if (e->flags & EDGE_ABNORMAL)
504
    return;
505
 
506
  g->e = e;
507
 
508
  eliminate_build (g, B);
509
 
510
  if (elim_graph_size (g) != 0)
511
    {
512
      tree var;
513
 
514
      sbitmap_zero (g->visited);
515
      VEC_truncate (int, g->stack, 0);
516
 
517
      for (x = 0; VEC_iterate (tree, g->nodes, x, var); x++)
518
        {
519
          int p = var_to_partition (g->map, var);
520
          if (!TEST_BIT (g->visited, p))
521
            elim_forward (g, p);
522
        }
523
 
524
      sbitmap_zero (g->visited);
525
      while (VEC_length (int, g->stack) > 0)
526
        {
527
          x = VEC_pop (int, g->stack);
528
          if (!TEST_BIT (g->visited, x))
529
            elim_create (g, x);
530
        }
531
    }
532
 
533
  /* If there are any pending constant copies, issue them now.  */
534
  while (VEC_length (tree, g->const_copies) > 0)
535
    {
536
      tree src, dest;
537
      src = VEC_pop (tree, g->const_copies);
538
      dest = VEC_pop (tree, g->const_copies);
539
      insert_copy_on_edge (e, dest, src);
540
    }
541
}
542
 
543
 
544
/* Shortcut routine to print messages to file F of the form:
545
   "STR1 EXPR1 STR2 EXPR2 STR3."  */
546
 
547
static void
548
print_exprs (FILE *f, const char *str1, tree expr1, const char *str2,
549
             tree expr2, const char *str3)
550
{
551
  fprintf (f, "%s", str1);
552
  print_generic_expr (f, expr1, TDF_SLIM);
553
  fprintf (f, "%s", str2);
554
  print_generic_expr (f, expr2, TDF_SLIM);
555
  fprintf (f, "%s", str3);
556
}
557
 
558
 
559
/* Shortcut routine to print abnormal edge messages to file F of the form:
560
   "STR1 EXPR1 STR2 EXPR2 across edge E.  */
561
 
562
static void
563
print_exprs_edge (FILE *f, edge e, const char *str1, tree expr1,
564
                  const char *str2, tree expr2)
565
{
566
  print_exprs (f, str1, expr1, str2, expr2, " across an abnormal edge");
567
  fprintf (f, " from BB%d->BB%d\n", e->src->index,
568
               e->dest->index);
569
}
570
 
571
 
572
/* Coalesce partitions in MAP which are live across abnormal edges in GRAPH.
573
   RV is the root variable groupings of the partitions in MAP.  Since code
574
   cannot be inserted on these edges, failure to coalesce something across
575
   an abnormal edge is an error.  */
576
 
577
static void
578
coalesce_abnormal_edges (var_map map, conflict_graph graph, root_var_p rv)
579
{
580
  basic_block bb;
581
  edge e;
582
  tree phi, var, tmp;
583
  int x, y, z;
584
  edge_iterator ei;
585
 
586
  /* Code cannot be inserted on abnormal edges. Look for all abnormal
587
     edges, and coalesce any PHI results with their arguments across
588
     that edge.  */
589
 
590
  FOR_EACH_BB (bb)
591
    FOR_EACH_EDGE (e, ei, bb->succs)
592
      if (e->dest != EXIT_BLOCK_PTR && e->flags & EDGE_ABNORMAL)
593
        for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
594
          {
595
            /* Visit each PHI on the destination side of this abnormal
596
               edge, and attempt to coalesce the argument with the result.  */
597
            var = PHI_RESULT (phi);
598
            x = var_to_partition (map, var);
599
 
600
            /* Ignore results which are not relevant.  */
601
            if (x == NO_PARTITION)
602
              continue;
603
 
604
            tmp = PHI_ARG_DEF (phi, e->dest_idx);
605
#ifdef ENABLE_CHECKING
606
            if (!phi_ssa_name_p (tmp))
607
              {
608
                print_exprs_edge (stderr, e,
609
                                  "\nConstant argument in PHI. Can't insert :",
610
                                  var, " = ", tmp);
611
                internal_error ("SSA corruption");
612
              }
613
#else
614
            gcc_assert (phi_ssa_name_p (tmp));
615
#endif
616
            y = var_to_partition (map, tmp);
617
            gcc_assert (x != NO_PARTITION);
618
            gcc_assert (y != NO_PARTITION);
619
#ifdef ENABLE_CHECKING
620
            if (root_var_find (rv, x) != root_var_find (rv, y))
621
              {
622
                print_exprs_edge (stderr, e, "\nDifferent root vars: ",
623
                                  root_var (rv, root_var_find (rv, x)),
624
                                  " and ",
625
                                  root_var (rv, root_var_find (rv, y)));
626
                internal_error ("SSA corruption");
627
              }
628
#else
629
            gcc_assert (root_var_find (rv, x) == root_var_find (rv, y));
630
#endif
631
 
632
            if (x != y)
633
              {
634
#ifdef ENABLE_CHECKING
635
                if (conflict_graph_conflict_p (graph, x, y))
636
                  {
637
                    print_exprs_edge (stderr, e, "\n Conflict ",
638
                                      partition_to_var (map, x),
639
                                      " and ", partition_to_var (map, y));
640
                    internal_error ("SSA corruption");
641
                  }
642
#else
643
                gcc_assert (!conflict_graph_conflict_p (graph, x, y));
644
#endif
645
 
646
                /* Now map the partitions back to their real variables.  */
647
                var = partition_to_var (map, x);
648
                tmp = partition_to_var (map, y);
649
                if (dump_file && (dump_flags & TDF_DETAILS))
650
                  {
651
                    print_exprs_edge (dump_file, e,
652
                                      "ABNORMAL: Coalescing ",
653
                                      var, " and ", tmp);
654
                  }
655
                z = var_union (map, var, tmp);
656
#ifdef ENABLE_CHECKING
657
                if (z == NO_PARTITION)
658
                  {
659
                    print_exprs_edge (stderr, e, "\nUnable to coalesce",
660
                                      partition_to_var (map, x), " and ",
661
                                      partition_to_var (map, y));
662
                    internal_error ("SSA corruption");
663
                  }
664
#else
665
                gcc_assert (z != NO_PARTITION);
666
#endif
667
                gcc_assert (z == x || z == y);
668
                if (z == x)
669
                  conflict_graph_merge_regs (graph, x, y);
670
                else
671
                  conflict_graph_merge_regs (graph, y, x);
672
              }
673
          }
674
}
675
 
676
/* Coalesce potential copies via PHI arguments.  */
677
 
678
static void
679
coalesce_phi_operands (var_map map, coalesce_list_p cl)
680
{
681
  basic_block bb;
682
  tree phi;
683
 
684
  FOR_EACH_BB (bb)
685
    {
686
      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
687
        {
688
          tree res = PHI_RESULT (phi);
689
          int p = var_to_partition (map, res);
690
          int x;
691
 
692
          if (p == NO_PARTITION)
693
            continue;
694
 
695
          for (x = 0; x < PHI_NUM_ARGS (phi); x++)
696
            {
697
              tree arg = PHI_ARG_DEF (phi, x);
698
              int p2;
699
 
700
              if (TREE_CODE (arg) != SSA_NAME)
701
                continue;
702
              if (SSA_NAME_VAR (res) != SSA_NAME_VAR (arg))
703
                continue;
704
              p2 = var_to_partition (map, PHI_ARG_DEF (phi, x));
705
              if (p2 != NO_PARTITION)
706
                {
707
                  edge e = PHI_ARG_EDGE (phi, x);
708
                  add_coalesce (cl, p, p2,
709
                                coalesce_cost (EDGE_FREQUENCY (e),
710
                                               maybe_hot_bb_p (bb),
711
                                               EDGE_CRITICAL_P (e)));
712
                }
713
            }
714
        }
715
    }
716
}
717
 
718
/* Coalesce all the result decls together.  */
719
 
720
static void
721
coalesce_result_decls (var_map map, coalesce_list_p cl)
722
{
723
  unsigned int i, x;
724
  tree var = NULL;
725
 
726
  for (i = x = 0; x < num_var_partitions (map); x++)
727
    {
728
      tree p = partition_to_var (map, x);
729
      if (TREE_CODE (SSA_NAME_VAR (p)) == RESULT_DECL)
730
        {
731
          if (var == NULL_TREE)
732
            {
733
              var = p;
734
              i = x;
735
            }
736
          else
737
            add_coalesce (cl, i, x,
738
                          coalesce_cost (EXIT_BLOCK_PTR->frequency,
739
                                         maybe_hot_bb_p (EXIT_BLOCK_PTR),
740
                                         false));
741
        }
742
    }
743
}
744
 
745
/* Coalesce matching constraints in asms.  */
746
 
747
static void
748
coalesce_asm_operands (var_map map, coalesce_list_p cl)
749
{
750
  basic_block bb;
751
 
752
  FOR_EACH_BB (bb)
753
    {
754
      block_stmt_iterator bsi;
755
      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
756
        {
757
          tree stmt = bsi_stmt (bsi);
758
          unsigned long noutputs, i;
759
          tree *outputs, link;
760
 
761
          if (TREE_CODE (stmt) != ASM_EXPR)
762
            continue;
763
 
764
          noutputs = list_length (ASM_OUTPUTS (stmt));
765
          outputs = (tree *) alloca (noutputs * sizeof (tree));
766
          for (i = 0, link = ASM_OUTPUTS (stmt); link;
767
               ++i, link = TREE_CHAIN (link))
768
            outputs[i] = TREE_VALUE (link);
769
 
770
          for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link))
771
            {
772
              const char *constraint
773
                = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link)));
774
              tree input = TREE_VALUE (link);
775
              char *end;
776
              unsigned long match;
777
              int p1, p2;
778
 
779
              if (TREE_CODE (input) != SSA_NAME && !DECL_P (input))
780
                continue;
781
 
782
              match = strtoul (constraint, &end, 10);
783
              if (match >= noutputs || end == constraint)
784
                continue;
785
 
786
              if (TREE_CODE (outputs[match]) != SSA_NAME
787
                  && !DECL_P (outputs[match]))
788
                continue;
789
 
790
              p1 = var_to_partition (map, outputs[match]);
791
              if (p1 == NO_PARTITION)
792
                continue;
793
              p2 = var_to_partition (map, input);
794
              if (p2 == NO_PARTITION)
795
                continue;
796
 
797
              add_coalesce (cl, p1, p2, coalesce_cost (REG_BR_PROB_BASE,
798
                                                       maybe_hot_bb_p (bb),
799
                                                       false));
800
            }
801
        }
802
    }
803
}
804
 
805
/* Reduce the number of live ranges in MAP.  Live range information is
806
   returned if FLAGS indicates that we are combining temporaries, otherwise
807
   NULL is returned.  The only partitions which are associated with actual
808
   variables at this point are those which are forced to be coalesced for
809
   various reason. (live on entry, live across abnormal edges, etc.).  */
810
 
811
static tree_live_info_p
812
coalesce_ssa_name (var_map map, int flags)
813
{
814
  unsigned num, x;
815
  sbitmap live;
816
  root_var_p rv;
817
  tree_live_info_p liveinfo;
818
  conflict_graph graph;
819
  coalesce_list_p cl = NULL;
820
  sbitmap_iterator sbi;
821
 
822
  if (num_var_partitions (map) <= 1)
823
    return NULL;
824
 
825
  liveinfo = calculate_live_on_entry (map);
826
  calculate_live_on_exit (liveinfo);
827
  rv = root_var_init (map);
828
 
829
  /* Remove single element variable from the list.  */
830
  root_var_compact (rv);
831
 
832
  cl = create_coalesce_list (map);
833
 
834
  coalesce_phi_operands (map, cl);
835
  coalesce_result_decls (map, cl);
836
  coalesce_asm_operands (map, cl);
837
 
838
  /* Build a conflict graph.  */
839
  graph = build_tree_conflict_graph (liveinfo, rv, cl);
840
 
841
  if (cl)
842
    {
843
      if (dump_file && (dump_flags & TDF_DETAILS))
844
        {
845
          fprintf (dump_file, "Before sorting:\n");
846
          dump_coalesce_list (dump_file, cl);
847
        }
848
 
849
      sort_coalesce_list (cl);
850
 
851
      if (dump_file && (dump_flags & TDF_DETAILS))
852
        {
853
          fprintf (dump_file, "\nAfter sorting:\n");
854
          dump_coalesce_list (dump_file, cl);
855
        }
856
    }
857
 
858
  /* Put the single element variables back in.  */
859
  root_var_decompact (rv);
860
 
861
  /* First, coalesce all live on entry variables to their root variable.
862
     This will ensure the first use is coming from the correct location.  */
863
 
864
  num = num_var_partitions (map);
865
  live = sbitmap_alloc (num);
866
  sbitmap_zero (live);
867
 
868
  /* Set 'live' vector to indicate live on entry partitions.  */
869
  for (x = 0 ; x < num; x++)
870
    {
871
      tree var = partition_to_var (map, x);
872
      if (default_def (SSA_NAME_VAR (var)) == var)
873
        SET_BIT (live, x);
874
    }
875
 
876
  if ((flags & SSANORM_COMBINE_TEMPS) == 0)
877
    {
878
      delete_tree_live_info (liveinfo);
879
      liveinfo = NULL;
880
    }
881
 
882
  /* Assign root variable as partition representative for each live on entry
883
     partition.  */
884
  EXECUTE_IF_SET_IN_SBITMAP (live, 0, x, sbi)
885
    {
886
      tree var = root_var (rv, root_var_find (rv, x));
887
      var_ann_t ann = var_ann (var);
888
      /* If these aren't already coalesced...  */
889
      if (partition_to_var (map, x) != var)
890
        {
891
          /* This root variable should have not already been assigned
892
             to another partition which is not coalesced with this one.  */
893
          gcc_assert (!ann->out_of_ssa_tag);
894
 
895
          if (dump_file && (dump_flags & TDF_DETAILS))
896
            {
897
              print_exprs (dump_file, "Must coalesce ",
898
                           partition_to_var (map, x),
899
                           " with the root variable ", var, ".\n");
900
            }
901
 
902
          change_partition_var (map, var, x);
903
        }
904
    }
905
 
906
  sbitmap_free (live);
907
 
908
  /* Coalesce partitions live across abnormal edges.  */
909
  coalesce_abnormal_edges (map, graph, rv);
910
 
911
  if (dump_file && (dump_flags & TDF_DETAILS))
912
    dump_var_map (dump_file, map);
913
 
914
  /* Coalesce partitions.  */
915
  coalesce_tpa_members (rv, graph, map, cl,
916
                        ((dump_flags & TDF_DETAILS) ? dump_file
917
                         : NULL));
918
 
919
  if (flags & SSANORM_COALESCE_PARTITIONS)
920
    coalesce_tpa_members (rv, graph, map, NULL,
921
                          ((dump_flags & TDF_DETAILS) ? dump_file
922
                           : NULL));
923
  if (cl)
924
    delete_coalesce_list (cl);
925
  root_var_delete (rv);
926
  conflict_graph_delete (graph);
927
 
928
  return liveinfo;
929
}
930
 
931
 
932
/* Take the ssa-name var_map MAP, and assign real variables to each
933
   partition.  */
934
 
935
static void
936
assign_vars (var_map map)
937
{
938
  int x, i, num, rep;
939
  tree t, var;
940
  var_ann_t ann;
941
  root_var_p rv;
942
 
943
  rv = root_var_init (map);
944
  if (!rv)
945
    return;
946
 
947
  /* Coalescing may already have forced some partitions to their root
948
     variable. Find these and tag them.  */
949
 
950
  num = num_var_partitions (map);
951
  for (x = 0; x < num; x++)
952
    {
953
      var = partition_to_var (map, x);
954
      if (TREE_CODE (var) != SSA_NAME)
955
        {
956
          /* Coalescing will already have verified that more than one
957
             partition doesn't have the same root variable. Simply marked
958
             the variable as assigned.  */
959
          ann = var_ann (var);
960
          ann->out_of_ssa_tag = 1;
961
          if (dump_file && (dump_flags & TDF_DETAILS))
962
            {
963
              fprintf (dump_file, "partition %d has variable ", x);
964
              print_generic_expr (dump_file, var, TDF_SLIM);
965
              fprintf (dump_file, " assigned to it.\n");
966
            }
967
 
968
        }
969
    }
970
 
971
  num = root_var_num (rv);
972
  for (x = 0; x < num; x++)
973
    {
974
      var = root_var (rv, x);
975
      ann = var_ann (var);
976
      for (i = root_var_first_partition (rv, x);
977
           i != ROOT_VAR_NONE;
978
           i = root_var_next_partition (rv, i))
979
        {
980
          t = partition_to_var (map, i);
981
 
982
          if (t == var || TREE_CODE (t) != SSA_NAME)
983
            continue;
984
 
985
          rep = var_to_partition (map, t);
986
 
987
          if (!ann->out_of_ssa_tag)
988
            {
989
              if (dump_file && (dump_flags & TDF_DETAILS))
990
                print_exprs (dump_file, "", t, "  --> ", var, "\n");
991
              change_partition_var (map, var, rep);
992
              continue;
993
            }
994
 
995
          if (dump_file && (dump_flags & TDF_DETAILS))
996
            print_exprs (dump_file, "", t, " not coalesced with ", var,
997
                         "");
998
 
999
          var = create_temp (t);
1000
          change_partition_var (map, var, rep);
1001
          ann = var_ann (var);
1002
 
1003
          if (dump_file && (dump_flags & TDF_DETAILS))
1004
            {
1005
              fprintf (dump_file, " -->  New temp:  '");
1006
              print_generic_expr (dump_file, var, TDF_SLIM);
1007
              fprintf (dump_file, "'\n");
1008
            }
1009
        }
1010
    }
1011
 
1012
  root_var_delete (rv);
1013
}
1014
 
1015
 
1016
/* Replace use operand P with whatever variable it has been rewritten to based
1017
   on the partitions in MAP.  EXPR is an optional expression vector over SSA
1018
   versions which is used to replace P with an expression instead of a variable.
1019
   If the stmt is changed, return true.  */
1020
 
1021
static inline bool
1022
replace_use_variable (var_map map, use_operand_p p, tree *expr)
1023
{
1024
  tree new_var;
1025
  tree var = USE_FROM_PTR (p);
1026
 
1027
  /* Check if we are replacing this variable with an expression.  */
1028
  if (expr)
1029
    {
1030
      int version = SSA_NAME_VERSION (var);
1031
      if (expr[version])
1032
        {
1033
          tree new_expr = TREE_OPERAND (expr[version], 1);
1034
          SET_USE (p, new_expr);
1035
          /* Clear the stmt's RHS, or GC might bite us.  */
1036
          TREE_OPERAND (expr[version], 1) = NULL_TREE;
1037
          return true;
1038
        }
1039
    }
1040
 
1041
  new_var = var_to_partition_to_var (map, var);
1042
  if (new_var)
1043
    {
1044
      SET_USE (p, new_var);
1045
      set_is_used (new_var);
1046
      return true;
1047
    }
1048
  return false;
1049
}
1050
 
1051
 
1052
/* Replace def operand DEF_P with whatever variable it has been rewritten to
1053
   based on the partitions in MAP.  EXPR is an optional expression vector over
1054
   SSA versions which is used to replace DEF_P with an expression instead of a
1055
   variable.  If the stmt is changed, return true.  */
1056
 
1057
static inline bool
1058
replace_def_variable (var_map map, def_operand_p def_p, tree *expr)
1059
{
1060
  tree new_var;
1061
  tree var = DEF_FROM_PTR (def_p);
1062
 
1063
  /* Check if we are replacing this variable with an expression.  */
1064
  if (expr)
1065
    {
1066
      int version = SSA_NAME_VERSION (var);
1067
      if (expr[version])
1068
        {
1069
          tree new_expr = TREE_OPERAND (expr[version], 1);
1070
          SET_DEF (def_p, new_expr);
1071
          /* Clear the stmt's RHS, or GC might bite us.  */
1072
          TREE_OPERAND (expr[version], 1) = NULL_TREE;
1073
          return true;
1074
        }
1075
    }
1076
 
1077
  new_var = var_to_partition_to_var (map, var);
1078
  if (new_var)
1079
    {
1080
      SET_DEF (def_p, new_var);
1081
      set_is_used (new_var);
1082
      return true;
1083
    }
1084
  return false;
1085
}
1086
 
1087
 
1088
/* Remove any PHI node which is a virtual PHI.  */
1089
 
1090
static void
1091
eliminate_virtual_phis (void)
1092
{
1093
  basic_block bb;
1094
  tree phi, next;
1095
 
1096
  FOR_EACH_BB (bb)
1097
    {
1098
      for (phi = phi_nodes (bb); phi; phi = next)
1099
        {
1100
          next = PHI_CHAIN (phi);
1101
          if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
1102
            {
1103
#ifdef ENABLE_CHECKING
1104
              int i;
1105
              /* There should be no arguments of this PHI which are in
1106
                 the partition list, or we get incorrect results.  */
1107
              for (i = 0; i < PHI_NUM_ARGS (phi); i++)
1108
                {
1109
                  tree arg = PHI_ARG_DEF (phi, i);
1110
                  if (TREE_CODE (arg) == SSA_NAME
1111
                      && is_gimple_reg (SSA_NAME_VAR (arg)))
1112
                    {
1113
                      fprintf (stderr, "Argument of PHI is not virtual (");
1114
                      print_generic_expr (stderr, arg, TDF_SLIM);
1115
                      fprintf (stderr, "), but the result is :");
1116
                      print_generic_stmt (stderr, phi, TDF_SLIM);
1117
                      internal_error ("SSA corruption");
1118
                    }
1119
                }
1120
#endif
1121
              remove_phi_node (phi, NULL_TREE);
1122
            }
1123
        }
1124
    }
1125
}
1126
 
1127
 
1128
/* This routine will coalesce variables in MAP of the same type which do not
1129
   interfere with each other. LIVEINFO is the live range info for variables
1130
   of interest.  This will both reduce the memory footprint of the stack, and
1131
   allow us to coalesce together local copies of globals and scalarized
1132
   component refs.  */
1133
 
1134
static void
1135
coalesce_vars (var_map map, tree_live_info_p liveinfo)
1136
{
1137
  basic_block bb;
1138
  type_var_p tv;
1139
  tree var;
1140
  unsigned x, p, p2;
1141
  coalesce_list_p cl;
1142
  conflict_graph graph;
1143
 
1144
  cl = create_coalesce_list (map);
1145
 
1146
  /* Merge all the live on entry vectors for coalesced partitions.  */
1147
  for (x = 0; x < num_var_partitions (map); x++)
1148
    {
1149
      var = partition_to_var (map, x);
1150
      p = var_to_partition (map, var);
1151
      if (p != x)
1152
        live_merge_and_clear (liveinfo, p, x);
1153
    }
1154
 
1155
  /* When PHI nodes are turned into copies, the result of each PHI node
1156
     becomes live on entry to the block. Mark these now.  */
1157
  FOR_EACH_BB (bb)
1158
    {
1159
      tree phi, arg;
1160
      unsigned p;
1161
 
1162
      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
1163
        {
1164
          p = var_to_partition (map, PHI_RESULT (phi));
1165
 
1166
          /* Skip virtual PHI nodes.  */
1167
          if (p == (unsigned)NO_PARTITION)
1168
            continue;
1169
 
1170
          make_live_on_entry (liveinfo, bb, p);
1171
 
1172
          /* Each argument is a potential copy operation. Add any arguments
1173
             which are not coalesced to the result to the coalesce list.  */
1174
          for (x = 0; x < (unsigned)PHI_NUM_ARGS (phi); x++)
1175
            {
1176
              arg = PHI_ARG_DEF (phi, x);
1177
              if (!phi_ssa_name_p (arg))
1178
                continue;
1179
              p2 = var_to_partition (map, arg);
1180
              if (p2 == (unsigned)NO_PARTITION)
1181
                continue;
1182
              if (p != p2)
1183
                {
1184
                  edge e = PHI_ARG_EDGE (phi, x);
1185
 
1186
                  add_coalesce (cl, p, p2,
1187
                                coalesce_cost (EDGE_FREQUENCY (e),
1188
                                               maybe_hot_bb_p (bb),
1189
                                               EDGE_CRITICAL_P (e)));
1190
                }
1191
            }
1192
        }
1193
   }
1194
 
1195
 
1196
  /* Re-calculate live on exit info.  */
1197
  calculate_live_on_exit (liveinfo);
1198
 
1199
  if (dump_file && (dump_flags & TDF_DETAILS))
1200
    {
1201
      fprintf (dump_file, "Live range info for variable memory coalescing.\n");
1202
      dump_live_info (dump_file, liveinfo, LIVEDUMP_ALL);
1203
 
1204
      fprintf (dump_file, "Coalesce list from phi nodes:\n");
1205
      dump_coalesce_list (dump_file, cl);
1206
    }
1207
 
1208
 
1209
  tv = type_var_init (map);
1210
  if (dump_file)
1211
    type_var_dump (dump_file, tv);
1212
  type_var_compact (tv);
1213
  if (dump_file)
1214
    type_var_dump (dump_file, tv);
1215
 
1216
  graph = build_tree_conflict_graph (liveinfo, tv, cl);
1217
 
1218
  type_var_decompact (tv);
1219
  if (dump_file && (dump_flags & TDF_DETAILS))
1220
    {
1221
      fprintf (dump_file, "type var list now looks like:n");
1222
      type_var_dump (dump_file, tv);
1223
 
1224
      fprintf (dump_file, "Coalesce list after conflict graph build:\n");
1225
      dump_coalesce_list (dump_file, cl);
1226
    }
1227
 
1228
  sort_coalesce_list (cl);
1229
  if (dump_file && (dump_flags & TDF_DETAILS))
1230
    {
1231
      fprintf (dump_file, "Coalesce list after sorting:\n");
1232
      dump_coalesce_list (dump_file, cl);
1233
    }
1234
 
1235
  coalesce_tpa_members (tv, graph, map, cl,
1236
                        ((dump_flags & TDF_DETAILS) ? dump_file : NULL));
1237
 
1238
  type_var_delete (tv);
1239
  delete_coalesce_list (cl);
1240
}
1241
 
1242
 
1243
/* Temporary Expression Replacement (TER)
1244
 
1245
   Replace SSA version variables during out-of-ssa with their defining
1246
   expression if there is only one use of the variable.
1247
 
1248
   A pass is made through the function, one block at a time.  No cross block
1249
   information is tracked.
1250
 
1251
   Variables which only have one use, and whose defining stmt is considered
1252
   a replaceable expression (see check_replaceable) are entered into
1253
   consideration by adding a list of dependent partitions to the version_info
1254
   vector for that ssa_name_version.  This information comes from the partition
1255
   mapping for each USE.  At the same time, the partition_dep_list vector for
1256
   these partitions have this version number entered into their lists.
1257
 
1258
   When the use of a replaceable ssa_variable is encountered, the dependence
1259
   list in version_info[] is moved to the "pending_dependence" list in case
1260
   the current expression is also replaceable. (To be determined later in
1261
   processing this stmt.) version_info[] for the version is then updated to
1262
   point to the defining stmt and the 'replaceable' bit is set.
1263
 
1264
   Any partition which is defined by a statement 'kills' any expression which
1265
   is dependent on this partition.  Every ssa version in the partitions'
1266
   dependence list is removed from future consideration.
1267
 
1268
   All virtual references are lumped together.  Any expression which is
1269
   dependent on any virtual variable (via a VUSE) has a dependence added
1270
   to the special partition defined by VIRTUAL_PARTITION.
1271
 
1272
   Whenever a V_MAY_DEF is seen, all expressions dependent this
1273
   VIRTUAL_PARTITION are removed from consideration.
1274
 
1275
   At the end of a basic block, all expression are removed from consideration
1276
   in preparation for the next block.
1277
 
1278
   The end result is a vector over SSA_NAME_VERSION which is passed back to
1279
   rewrite_out_of_ssa.  As the SSA variables are being rewritten, instead of
1280
   replacing the SSA_NAME tree element with the partition it was assigned,
1281
   it is replaced with the RHS of the defining expression.  */
1282
 
1283
 
1284
/* Dependency list element.  This can contain either a partition index or a
1285
   version number, depending on which list it is in.  */
1286
 
1287
typedef struct value_expr_d
1288
{
1289
  int value;
1290
  struct value_expr_d *next;
1291
} *value_expr_p;
1292
 
1293
 
1294
/* Temporary Expression Replacement (TER) table information.  */
1295
 
1296
typedef struct temp_expr_table_d
1297
{
1298
  var_map map;
1299
  void **version_info;
1300
  bitmap *expr_vars;
1301
  value_expr_p *partition_dep_list;
1302
  bitmap replaceable;
1303
  bool saw_replaceable;
1304
  int virtual_partition;
1305
  bitmap partition_in_use;
1306
  value_expr_p free_list;
1307
  value_expr_p pending_dependence;
1308
} *temp_expr_table_p;
1309
 
1310
/* Used to indicate a dependency on V_MAY_DEFs.  */
1311
#define VIRTUAL_PARTITION(table)        (table->virtual_partition)
1312
 
1313
static temp_expr_table_p new_temp_expr_table (var_map);
1314
static tree *free_temp_expr_table (temp_expr_table_p);
1315
static inline value_expr_p new_value_expr (temp_expr_table_p);
1316
static inline void free_value_expr (temp_expr_table_p, value_expr_p);
1317
static inline value_expr_p find_value_in_list (value_expr_p, int,
1318
                                               value_expr_p *);
1319
static inline void add_value_to_list (temp_expr_table_p, value_expr_p *, int);
1320
static inline void add_info_to_list (temp_expr_table_p, value_expr_p *,
1321
                                     value_expr_p);
1322
static value_expr_p remove_value_from_list (value_expr_p *, int);
1323
static void add_dependence (temp_expr_table_p, int, tree);
1324
static bool check_replaceable (temp_expr_table_p, tree);
1325
static void finish_expr (temp_expr_table_p, int, bool);
1326
static void mark_replaceable (temp_expr_table_p, tree);
1327
static inline void kill_expr (temp_expr_table_p, int, bool);
1328
static inline void kill_virtual_exprs (temp_expr_table_p, bool);
1329
static void find_replaceable_in_bb (temp_expr_table_p, basic_block);
1330
static tree *find_replaceable_exprs (var_map);
1331
static void dump_replaceable_exprs (FILE *, tree *);
1332
 
1333
 
1334
/* Create a new TER table for MAP.  */
1335
 
1336
static temp_expr_table_p
1337
new_temp_expr_table (var_map map)
1338
{
1339
  temp_expr_table_p t;
1340
 
1341
  t = XNEW (struct temp_expr_table_d);
1342
  t->map = map;
1343
 
1344
  t->version_info = XCNEWVEC (void *, num_ssa_names + 1);
1345
  t->expr_vars = XCNEWVEC (bitmap, num_ssa_names + 1);
1346
  t->partition_dep_list = XCNEWVEC (value_expr_p,
1347
                                    num_var_partitions (map) + 1);
1348
 
1349
  t->replaceable = BITMAP_ALLOC (NULL);
1350
  t->partition_in_use = BITMAP_ALLOC (NULL);
1351
 
1352
  t->saw_replaceable = false;
1353
  t->virtual_partition = num_var_partitions (map);
1354
  t->free_list = NULL;
1355
  t->pending_dependence = NULL;
1356
 
1357
  return t;
1358
}
1359
 
1360
 
1361
/* Free TER table T.  If there are valid replacements, return the expression
1362
   vector.  */
1363
 
1364
static tree *
1365
free_temp_expr_table (temp_expr_table_p t)
1366
{
1367
  value_expr_p p;
1368
  tree *ret = NULL;
1369
  unsigned i;
1370
 
1371
#ifdef ENABLE_CHECKING
1372
  unsigned x;
1373
  for (x = 0; x <= num_var_partitions (t->map); x++)
1374
    gcc_assert (!t->partition_dep_list[x]);
1375
#endif
1376
 
1377
  while ((p = t->free_list))
1378
    {
1379
      t->free_list = p->next;
1380
      free (p);
1381
    }
1382
 
1383
  BITMAP_FREE (t->partition_in_use);
1384
  BITMAP_FREE (t->replaceable);
1385
 
1386
  for (i = 0; i <= num_ssa_names; i++)
1387
    if (t->expr_vars[i])
1388
      BITMAP_FREE (t->expr_vars[i]);
1389
  free (t->expr_vars);
1390
 
1391
  free (t->partition_dep_list);
1392
  if (t->saw_replaceable)
1393
    ret = (tree *)t->version_info;
1394
  else
1395
    free (t->version_info);
1396
 
1397
  free (t);
1398
  return ret;
1399
}
1400
 
1401
 
1402
/* Allocate a new value list node. Take it from the free list in TABLE if
1403
   possible.  */
1404
 
1405
static inline value_expr_p
1406
new_value_expr (temp_expr_table_p table)
1407
{
1408
  value_expr_p p;
1409
  if (table->free_list)
1410
    {
1411
      p = table->free_list;
1412
      table->free_list = p->next;
1413
    }
1414
  else
1415
    p = (value_expr_p) xmalloc (sizeof (struct value_expr_d));
1416
 
1417
  return p;
1418
}
1419
 
1420
 
1421
/* Add value list node P to the free list in TABLE.  */
1422
 
1423
static inline void
1424
free_value_expr (temp_expr_table_p table, value_expr_p p)
1425
{
1426
  p->next = table->free_list;
1427
  table->free_list = p;
1428
}
1429
 
1430
 
1431
/* Find VALUE if it's in LIST.  Return a pointer to the list object if found,
1432
   else return NULL.  If LAST_PTR is provided, it will point to the previous
1433
   item upon return, or NULL if this is the first item in the list.  */
1434
 
1435
static inline value_expr_p
1436
find_value_in_list (value_expr_p list, int value, value_expr_p *last_ptr)
1437
{
1438
  value_expr_p curr;
1439
  value_expr_p last = NULL;
1440
 
1441
  for (curr = list; curr; last = curr, curr = curr->next)
1442
    {
1443
      if (curr->value == value)
1444
        break;
1445
    }
1446
  if (last_ptr)
1447
    *last_ptr = last;
1448
  return curr;
1449
}
1450
 
1451
 
1452
/* Add VALUE to LIST, if it isn't already present.  TAB is the expression
1453
   table */
1454
 
1455
static inline void
1456
add_value_to_list (temp_expr_table_p tab, value_expr_p *list, int value)
1457
{
1458
  value_expr_p info;
1459
 
1460
  if (!find_value_in_list (*list, value, NULL))
1461
    {
1462
      info = new_value_expr (tab);
1463
      info->value = value;
1464
      info->next = *list;
1465
      *list = info;
1466
    }
1467
}
1468
 
1469
 
1470
/* Add value node INFO if it's value isn't already in LIST.  Free INFO if
1471
   it is already in the list. TAB is the expression table.  */
1472
 
1473
static inline void
1474
add_info_to_list (temp_expr_table_p tab, value_expr_p *list, value_expr_p info)
1475
{
1476
  if (find_value_in_list (*list, info->value, NULL))
1477
    free_value_expr (tab, info);
1478
  else
1479
    {
1480
      info->next = *list;
1481
      *list = info;
1482
    }
1483
}
1484
 
1485
 
1486
/* Look for VALUE in LIST.  If found, remove it from the list and return it's
1487
   pointer.  */
1488
 
1489
static value_expr_p
1490
remove_value_from_list (value_expr_p *list, int value)
1491
{
1492
  value_expr_p info, last;
1493
 
1494
  info = find_value_in_list (*list, value, &last);
1495
  if (!info)
1496
    return NULL;
1497
  if (!last)
1498
    *list = info->next;
1499
  else
1500
    last->next = info->next;
1501
 
1502
  return info;
1503
}
1504
 
1505
 
1506
/* Add a dependency between the def of ssa VERSION and VAR.  If VAR is
1507
   replaceable by an expression, add a dependence each of the elements of the
1508
   expression.  These are contained in the pending list.  TAB is the
1509
   expression table.  */
1510
 
1511
static void
1512
add_dependence (temp_expr_table_p tab, int version, tree var)
1513
{
1514
  int i, x;
1515
  value_expr_p info;
1516
 
1517
  i = SSA_NAME_VERSION (var);
1518
  if (bitmap_bit_p (tab->replaceable, i))
1519
    {
1520
      /* This variable is being substituted, so use whatever dependences
1521
         were queued up when we marked this as replaceable earlier.  */
1522
      while ((info = tab->pending_dependence))
1523
        {
1524
          tab->pending_dependence = info->next;
1525
          /* Get the partition this variable was dependent on. Reuse this
1526
             object to represent the current  expression instead.  */
1527
          x = info->value;
1528
          info->value = version;
1529
          add_info_to_list (tab, &(tab->partition_dep_list[x]), info);
1530
          add_value_to_list (tab,
1531
                             (value_expr_p *)&(tab->version_info[version]), x);
1532
          bitmap_set_bit (tab->partition_in_use, x);
1533
        }
1534
    }
1535
  else
1536
    {
1537
      i = var_to_partition (tab->map, var);
1538
      gcc_assert (i != NO_PARTITION);
1539
      add_value_to_list (tab, &(tab->partition_dep_list[i]), version);
1540
      add_value_to_list (tab,
1541
                         (value_expr_p *)&(tab->version_info[version]), i);
1542
      bitmap_set_bit (tab->partition_in_use, i);
1543
    }
1544
}
1545
 
1546
 
1547
/* Check if expression STMT is suitable for replacement in table TAB.  If so,
1548
   create an expression entry.  Return true if this stmt is replaceable.  */
1549
 
1550
static bool
1551
check_replaceable (temp_expr_table_p tab, tree stmt)
1552
{
1553
  tree var, def, basevar;
1554
  int version;
1555
  var_map map = tab->map;
1556
  ssa_op_iter iter;
1557
  tree call_expr;
1558
  bitmap def_vars, use_vars;
1559
 
1560
  if (TREE_CODE (stmt) != MODIFY_EXPR)
1561
    return false;
1562
 
1563
  /* Punt if there is more than 1 def, or more than 1 use.  */
1564
  def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
1565
  if (!def)
1566
    return false;
1567
 
1568
  if (version_ref_count (map, def) != 1)
1569
    return false;
1570
 
1571
  /* There must be no V_MAY_DEFS or V_MUST_DEFS.  */
1572
  if (!(ZERO_SSA_OPERANDS (stmt, (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF))))
1573
    return false;
1574
 
1575
  /* Float expressions must go through memory if float-store is on.  */
1576
  if (flag_float_store && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (stmt, 1))))
1577
    return false;
1578
 
1579
  /* An assignment with a register variable on the RHS is not
1580
     replaceable.  */
1581
  if (TREE_CODE (TREE_OPERAND (stmt, 1)) == VAR_DECL
1582
     && DECL_HARD_REGISTER (TREE_OPERAND (stmt, 1)))
1583
   return false;
1584
 
1585
  /* Calls to functions with side-effects cannot be replaced.  */
1586
  if ((call_expr = get_call_expr_in (stmt)) != NULL_TREE)
1587
    {
1588
      int call_flags = call_expr_flags (call_expr);
1589
      if (TREE_SIDE_EFFECTS (call_expr)
1590
          && !(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
1591
        return false;
1592
    }
1593
 
1594
  version = SSA_NAME_VERSION (def);
1595
  basevar = SSA_NAME_VAR (def);
1596
  def_vars = BITMAP_ALLOC (NULL);
1597
  bitmap_set_bit (def_vars, DECL_UID (basevar));
1598
 
1599
  /* Add this expression to the dependency list for each use partition.  */
1600
  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
1601
    {
1602
      add_dependence (tab, version, var);
1603
 
1604
      use_vars = tab->expr_vars[SSA_NAME_VERSION (var)];
1605
      if (use_vars)
1606
        bitmap_ior_into (def_vars, use_vars);
1607
    }
1608
  tab->expr_vars[version] = def_vars;
1609
 
1610
  /* If there are VUSES, add a dependence on virtual defs.  */
1611
  if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
1612
    {
1613
      add_value_to_list (tab, (value_expr_p *)&(tab->version_info[version]),
1614
                         VIRTUAL_PARTITION (tab));
1615
      add_value_to_list (tab,
1616
                         &(tab->partition_dep_list[VIRTUAL_PARTITION (tab)]),
1617
                         version);
1618
      bitmap_set_bit (tab->partition_in_use, VIRTUAL_PARTITION (tab));
1619
    }
1620
 
1621
  return true;
1622
}
1623
 
1624
 
1625
/* This function will remove the expression for VERSION from replacement
1626
   consideration.n table TAB  If 'replace' is true, it is marked as
1627
   replaceable, otherwise not.  */
1628
 
1629
static void
1630
finish_expr (temp_expr_table_p tab, int version, bool replace)
1631
{
1632
  value_expr_p info, tmp;
1633
  int partition;
1634
 
1635
  /* Remove this expression from its dependent lists.  The partition dependence
1636
     list is retained and transfered later to whomever uses this version.  */
1637
  for (info = (value_expr_p) tab->version_info[version]; info; info = tmp)
1638
    {
1639
      partition = info->value;
1640
      gcc_assert (tab->partition_dep_list[partition]);
1641
      tmp = remove_value_from_list (&(tab->partition_dep_list[partition]),
1642
                                    version);
1643
      gcc_assert (tmp);
1644
      free_value_expr (tab, tmp);
1645
      /* Only clear the bit when the dependency list is emptied via
1646
         a replacement. Otherwise kill_expr will take care of it.  */
1647
      if (!(tab->partition_dep_list[partition]) && replace)
1648
        bitmap_clear_bit (tab->partition_in_use, partition);
1649
      tmp = info->next;
1650
      if (!replace)
1651
        free_value_expr (tab, info);
1652
    }
1653
 
1654
  if (replace)
1655
    {
1656
      tab->saw_replaceable = true;
1657
      bitmap_set_bit (tab->replaceable, version);
1658
    }
1659
  else
1660
    {
1661
      gcc_assert (!bitmap_bit_p (tab->replaceable, version));
1662
      tab->version_info[version] = NULL;
1663
    }
1664
}
1665
 
1666
 
1667
/* Mark the expression associated with VAR as replaceable, and enter
1668
   the defining stmt into the version_info table TAB.  */
1669
 
1670
static void
1671
mark_replaceable (temp_expr_table_p tab, tree var)
1672
{
1673
  value_expr_p info;
1674
  int version = SSA_NAME_VERSION (var);
1675
  finish_expr (tab, version, true);
1676
 
1677
  /* Move the dependence list to the pending list.  */
1678
  if (tab->version_info[version])
1679
    {
1680
      info = (value_expr_p) tab->version_info[version];
1681
      for ( ; info->next; info = info->next)
1682
        continue;
1683
      info->next = tab->pending_dependence;
1684
      tab->pending_dependence = (value_expr_p)tab->version_info[version];
1685
    }
1686
 
1687
  tab->version_info[version] = SSA_NAME_DEF_STMT (var);
1688
}
1689
 
1690
 
1691
/* This function marks any expression in TAB which is dependent on PARTITION
1692
   as NOT replaceable.  CLEAR_BIT is used to determine whether partition_in_use
1693
   should have its bit cleared.  Since this routine can be called within an
1694
   EXECUTE_IF_SET_IN_BITMAP, the bit can't always be cleared.  */
1695
 
1696
static inline void
1697
kill_expr (temp_expr_table_p tab, int partition, bool clear_bit)
1698
{
1699
  value_expr_p ptr;
1700
 
1701
  /* Mark every active expr dependent on this var as not replaceable.  */
1702
  while ((ptr = tab->partition_dep_list[partition]) != NULL)
1703
    finish_expr (tab, ptr->value, false);
1704
 
1705
  if (clear_bit)
1706
    bitmap_clear_bit (tab->partition_in_use, partition);
1707
}
1708
 
1709
 
1710
/* This function kills all expressions in TAB which are dependent on virtual
1711
   DEFs.  CLEAR_BIT determines whether partition_in_use gets cleared.  */
1712
 
1713
static inline void
1714
kill_virtual_exprs (temp_expr_table_p tab, bool clear_bit)
1715
{
1716
  kill_expr (tab, VIRTUAL_PARTITION (tab), clear_bit);
1717
}
1718
 
1719
 
1720
/* This function processes basic block BB, and looks for variables which can
1721
   be replaced by their expressions.  Results are stored in TAB.  */
1722
 
1723
static void
1724
find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
1725
{
1726
  block_stmt_iterator bsi;
1727
  tree stmt, def, use;
1728
  stmt_ann_t ann;
1729
  int partition;
1730
  var_map map = tab->map;
1731
  value_expr_p p;
1732
  ssa_op_iter iter;
1733
 
1734
  for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1735
    {
1736
      stmt = bsi_stmt (bsi);
1737
      ann = stmt_ann (stmt);
1738
 
1739
      /* Determine if this stmt finishes an existing expression.  */
1740
      FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
1741
        {
1742
          unsigned ver = SSA_NAME_VERSION (use);
1743
 
1744
          if (tab->version_info[ver])
1745
            {
1746
              bool same_root_var = false;
1747
              ssa_op_iter iter2;
1748
              bitmap vars = tab->expr_vars[ver];
1749
 
1750
              /* See if the root variables are the same.  If they are, we
1751
                 do not want to do the replacement to avoid problems with
1752
                 code size, see PR tree-optimization/17549.  */
1753
              FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF)
1754
                {
1755
                  if (bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def))))
1756
                    {
1757
                      same_root_var = true;
1758
                      break;
1759
                    }
1760
                }
1761
 
1762
              /* Mark expression as replaceable unless stmt is volatile
1763
                 or DEF sets the same root variable as STMT.  */
1764
              if (!ann->has_volatile_ops && !same_root_var)
1765
                mark_replaceable (tab, use);
1766
              else
1767
                finish_expr (tab, ver, false);
1768
            }
1769
        }
1770
 
1771
      /* Next, see if this stmt kills off an active expression.  */
1772
      FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
1773
        {
1774
          partition = var_to_partition (map, def);
1775
          if (partition != NO_PARTITION && tab->partition_dep_list[partition])
1776
            kill_expr (tab, partition, true);
1777
        }
1778
 
1779
      /* Now see if we are creating a new expression or not.  */
1780
      if (!ann->has_volatile_ops)
1781
        check_replaceable (tab, stmt);
1782
 
1783
      /* Free any unused dependency lists.  */
1784
      while ((p = tab->pending_dependence))
1785
        {
1786
          tab->pending_dependence = p->next;
1787
          free_value_expr (tab, p);
1788
        }
1789
 
1790
      /* A V_{MAY,MUST}_DEF kills any expression using a virtual operand.  */
1791
      if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
1792
        kill_virtual_exprs (tab, true);
1793
    }
1794
}
1795
 
1796
 
1797
/* This function is the driver routine for replacement of temporary expressions
1798
   in the SSA->normal phase, operating on MAP.  If there are replaceable
1799
   expressions, a table is returned which maps SSA versions to the
1800
   expressions they should be replaced with.  A NULL_TREE indicates no
1801
   replacement should take place.  If there are no replacements at all,
1802
   NULL is returned by the function, otherwise an expression vector indexed
1803
   by SSA_NAME version numbers.  */
1804
 
1805
static tree *
1806
find_replaceable_exprs (var_map map)
1807
{
1808
  basic_block bb;
1809
  unsigned i;
1810
  temp_expr_table_p table;
1811
  tree *ret;
1812
 
1813
  table = new_temp_expr_table (map);
1814
  FOR_EACH_BB (bb)
1815
    {
1816
      bitmap_iterator bi;
1817
 
1818
      find_replaceable_in_bb (table, bb);
1819
      EXECUTE_IF_SET_IN_BITMAP ((table->partition_in_use), 0, i, bi)
1820
        {
1821
          kill_expr (table, i, false);
1822
        }
1823
    }
1824
 
1825
  ret = free_temp_expr_table (table);
1826
  return ret;
1827
}
1828
 
1829
 
1830
/* Dump TER expression table EXPR to file F.  */
1831
 
1832
static void
1833
dump_replaceable_exprs (FILE *f, tree *expr)
1834
{
1835
  tree stmt, var;
1836
  int x;
1837
  fprintf (f, "\nReplacing Expressions\n");
1838
  for (x = 0; x < (int)num_ssa_names + 1; x++)
1839
    if (expr[x])
1840
      {
1841
        stmt = expr[x];
1842
        var = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
1843
        gcc_assert (var != NULL_TREE);
1844
        print_generic_expr (f, var, TDF_SLIM);
1845
        fprintf (f, " replace with --> ");
1846
        print_generic_expr (f, TREE_OPERAND (stmt, 1), TDF_SLIM);
1847
        fprintf (f, "\n");
1848
      }
1849
  fprintf (f, "\n");
1850
}
1851
 
1852
 
1853
/* This function will rewrite the current program using the variable mapping
1854
   found in MAP.  If the replacement vector VALUES is provided, any
1855
   occurrences of partitions with non-null entries in the vector will be
1856
   replaced with the expression in the vector instead of its mapped
1857
   variable.  */
1858
 
1859
static void
1860
rewrite_trees (var_map map, tree *values)
1861
{
1862
  elim_graph g;
1863
  basic_block bb;
1864
  block_stmt_iterator si;
1865
  edge e;
1866
  tree phi;
1867
  bool changed;
1868
 
1869
#ifdef ENABLE_CHECKING
1870
  /* Search for PHIs where the destination has no partition, but one
1871
     or more arguments has a partition.  This should not happen and can
1872
     create incorrect code.  */
1873
  FOR_EACH_BB (bb)
1874
    {
1875
      tree phi;
1876
 
1877
      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
1878
        {
1879
          tree T0 = var_to_partition_to_var (map, PHI_RESULT (phi));
1880
 
1881
          if (T0 == NULL_TREE)
1882
            {
1883
              int i;
1884
 
1885
              for (i = 0; i < PHI_NUM_ARGS (phi); i++)
1886
                {
1887
                  tree arg = PHI_ARG_DEF (phi, i);
1888
 
1889
                  if (TREE_CODE (arg) == SSA_NAME
1890
                      && var_to_partition (map, arg) != NO_PARTITION)
1891
                    {
1892
                      fprintf (stderr, "Argument of PHI is in a partition :(");
1893
                      print_generic_expr (stderr, arg, TDF_SLIM);
1894
                      fprintf (stderr, "), but the result is not :");
1895
                      print_generic_stmt (stderr, phi, TDF_SLIM);
1896
                      internal_error ("SSA corruption");
1897
                    }
1898
                }
1899
            }
1900
        }
1901
    }
1902
#endif
1903
 
1904
  /* Replace PHI nodes with any required copies.  */
1905
  g = new_elim_graph (map->num_partitions);
1906
  g->map = map;
1907
  FOR_EACH_BB (bb)
1908
    {
1909
      for (si = bsi_start (bb); !bsi_end_p (si); )
1910
        {
1911
          tree stmt = bsi_stmt (si);
1912
          use_operand_p use_p, copy_use_p;
1913
          def_operand_p def_p;
1914
          bool remove = false, is_copy = false;
1915
          int num_uses = 0;
1916
          stmt_ann_t ann;
1917
          ssa_op_iter iter;
1918
 
1919
          ann = stmt_ann (stmt);
1920
          changed = false;
1921
 
1922
          if (TREE_CODE (stmt) == MODIFY_EXPR
1923
              && (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME))
1924
            is_copy = true;
1925
 
1926
          copy_use_p = NULL_USE_OPERAND_P;
1927
          FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
1928
            {
1929
              if (replace_use_variable (map, use_p, values))
1930
                changed = true;
1931
              copy_use_p = use_p;
1932
              num_uses++;
1933
            }
1934
 
1935
          if (num_uses != 1)
1936
            is_copy = false;
1937
 
1938
          def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF);
1939
 
1940
          if (def_p != NULL)
1941
            {
1942
              /* Mark this stmt for removal if it is the list of replaceable
1943
                 expressions.  */
1944
              if (values && values[SSA_NAME_VERSION (DEF_FROM_PTR (def_p))])
1945
                remove = true;
1946
              else
1947
                {
1948
                  if (replace_def_variable (map, def_p, NULL))
1949
                    changed = true;
1950
                  /* If both SSA_NAMEs coalesce to the same variable,
1951
                     mark the now redundant copy for removal.  */
1952
                  if (is_copy)
1953
                    {
1954
                      gcc_assert (copy_use_p != NULL_USE_OPERAND_P);
1955
                      if (DEF_FROM_PTR (def_p) == USE_FROM_PTR (copy_use_p))
1956
                        remove = true;
1957
                    }
1958
                }
1959
            }
1960
          else
1961
            FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
1962
              if (replace_def_variable (map, def_p, NULL))
1963
                changed = true;
1964
 
1965
          /* Remove any stmts marked for removal.  */
1966
          if (remove)
1967
            bsi_remove (&si, true);
1968
          else
1969
            bsi_next (&si);
1970
        }
1971
 
1972
      phi = phi_nodes (bb);
1973
      if (phi)
1974
        {
1975
          edge_iterator ei;
1976
          FOR_EACH_EDGE (e, ei, bb->preds)
1977
            eliminate_phi (e, g);
1978
        }
1979
    }
1980
 
1981
  delete_elim_graph (g);
1982
}
1983
 
1984
 
1985
DEF_VEC_ALLOC_P(edge,heap);
1986
 
1987
/* These are the local work structures used to determine the best place to
1988
   insert the copies that were placed on edges by the SSA->normal pass..  */
1989
static VEC(edge,heap) *edge_leader;
1990
static VEC(tree,heap) *stmt_list;
1991
static bitmap leader_has_match = NULL;
1992
static edge leader_match = NULL;
1993
 
1994
 
1995
/* Pass this function to make_forwarder_block so that all the edges with
1996
   matching PENDING_STMT lists to 'curr_stmt_list' get redirected.  */
1997
static bool
1998
same_stmt_list_p (edge e)
1999
{
2000
  return (e->aux == (PTR) leader_match) ? true : false;
2001
}
2002
 
2003
 
2004
/* Return TRUE if S1 and S2 are equivalent copies.  */
2005
static inline bool
2006
identical_copies_p (tree s1, tree s2)
2007
{
2008
#ifdef ENABLE_CHECKING
2009
  gcc_assert (TREE_CODE (s1) == MODIFY_EXPR);
2010
  gcc_assert (TREE_CODE (s2) == MODIFY_EXPR);
2011
  gcc_assert (DECL_P (TREE_OPERAND (s1, 0)));
2012
  gcc_assert (DECL_P (TREE_OPERAND (s2, 0)));
2013
#endif
2014
 
2015
  if (TREE_OPERAND (s1, 0) != TREE_OPERAND (s2, 0))
2016
    return false;
2017
 
2018
  s1 = TREE_OPERAND (s1, 1);
2019
  s2 = TREE_OPERAND (s2, 1);
2020
 
2021
  if (s1 != s2)
2022
    return false;
2023
 
2024
  return true;
2025
}
2026
 
2027
 
2028
/* Compare the PENDING_STMT list for two edges, and return true if the lists
2029
   contain the same sequence of copies.  */
2030
 
2031
static inline bool
2032
identical_stmt_lists_p (edge e1, edge e2)
2033
{
2034
  tree t1 = PENDING_STMT (e1);
2035
  tree t2 = PENDING_STMT (e2);
2036
  tree_stmt_iterator tsi1, tsi2;
2037
 
2038
  gcc_assert (TREE_CODE (t1) == STATEMENT_LIST);
2039
  gcc_assert (TREE_CODE (t2) == STATEMENT_LIST);
2040
 
2041
  for (tsi1 = tsi_start (t1), tsi2 = tsi_start (t2);
2042
       !tsi_end_p (tsi1) && !tsi_end_p (tsi2);
2043
       tsi_next (&tsi1), tsi_next (&tsi2))
2044
    {
2045
      if (!identical_copies_p (tsi_stmt (tsi1), tsi_stmt (tsi2)))
2046
        break;
2047
    }
2048
 
2049
  if (!tsi_end_p (tsi1) || ! tsi_end_p (tsi2))
2050
    return false;
2051
 
2052
  return true;
2053
}
2054
 
2055
 
2056
/* Allocate data structures used in analyze_edges_for_bb.   */
2057
 
2058
static void
2059
init_analyze_edges_for_bb (void)
2060
{
2061
  edge_leader = VEC_alloc (edge, heap, 25);
2062
  stmt_list = VEC_alloc (tree, heap, 25);
2063
  leader_has_match = BITMAP_ALLOC (NULL);
2064
}
2065
 
2066
 
2067
/* Free data structures used in analyze_edges_for_bb.   */
2068
 
2069
static void
2070
fini_analyze_edges_for_bb (void)
2071
{
2072
  VEC_free (edge, heap, edge_leader);
2073
  VEC_free (tree, heap, stmt_list);
2074
  BITMAP_FREE (leader_has_match);
2075
}
2076
 
2077
 
2078
/* Look at all the incoming edges to block BB, and decide where the best place
2079
   to insert the stmts on each edge are, and perform those insertions.  */
2080
 
2081
static void
2082
analyze_edges_for_bb (basic_block bb)
2083
{
2084
  edge e;
2085
  edge_iterator ei;
2086
  int count;
2087
  unsigned int x;
2088
  bool have_opportunity;
2089
  block_stmt_iterator bsi;
2090
  tree stmt;
2091
  edge single_edge = NULL;
2092
  bool is_label;
2093
  edge leader;
2094
 
2095
  count = 0;
2096
 
2097
  /* Blocks which contain at least one abnormal edge cannot use
2098
     make_forwarder_block.  Look for these blocks, and commit any PENDING_STMTs
2099
     found on edges in these block.  */
2100
  have_opportunity = true;
2101
  FOR_EACH_EDGE (e, ei, bb->preds)
2102
    if (e->flags & EDGE_ABNORMAL)
2103
      {
2104
        have_opportunity = false;
2105
        break;
2106
      }
2107
 
2108
  if (!have_opportunity)
2109
    {
2110
      FOR_EACH_EDGE (e, ei, bb->preds)
2111
        if (PENDING_STMT (e))
2112
          bsi_commit_one_edge_insert (e, NULL);
2113
      return;
2114
    }
2115
  /* Find out how many edges there are with interesting pending stmts on them.
2116
     Commit the stmts on edges we are not interested in.  */
2117
  FOR_EACH_EDGE (e, ei, bb->preds)
2118
    {
2119
      if (PENDING_STMT (e))
2120
        {
2121
          gcc_assert (!(e->flags & EDGE_ABNORMAL));
2122
          if (e->flags & EDGE_FALLTHRU)
2123
            {
2124
              bsi = bsi_start (e->src);
2125
              if (!bsi_end_p (bsi))
2126
                {
2127
                  stmt = bsi_stmt (bsi);
2128
                  bsi_next (&bsi);
2129
                  gcc_assert (stmt != NULL_TREE);
2130
                  is_label = (TREE_CODE (stmt) == LABEL_EXPR);
2131
                  /* Punt if it has non-label stmts, or isn't local.  */
2132
                  if (!is_label || DECL_NONLOCAL (TREE_OPERAND (stmt, 0))
2133
                      || !bsi_end_p (bsi))
2134
                    {
2135
                      bsi_commit_one_edge_insert (e, NULL);
2136
                      continue;
2137
                    }
2138
                }
2139
            }
2140
          single_edge = e;
2141
          count++;
2142
        }
2143
    }
2144
 
2145
  /* If there aren't at least 2 edges, no sharing will happen.  */
2146
  if (count < 2)
2147
    {
2148
      if (single_edge)
2149
        bsi_commit_one_edge_insert (single_edge, NULL);
2150
      return;
2151
    }
2152
 
2153
  /* Ensure that we have empty worklists.  */
2154
#ifdef ENABLE_CHECKING
2155
  gcc_assert (VEC_length (edge, edge_leader) == 0);
2156
  gcc_assert (VEC_length (tree, stmt_list) == 0);
2157
  gcc_assert (bitmap_empty_p (leader_has_match));
2158
#endif
2159
 
2160
  /* Find the "leader" block for each set of unique stmt lists.  Preference is
2161
     given to FALLTHRU blocks since they would need a GOTO to arrive at another
2162
     block.  The leader edge destination is the block which all the other edges
2163
     with the same stmt list will be redirected to.  */
2164
  have_opportunity = false;
2165
  FOR_EACH_EDGE (e, ei, bb->preds)
2166
    {
2167
      if (PENDING_STMT (e))
2168
        {
2169
          bool found = false;
2170
 
2171
          /* Look for the same stmt list in edge leaders list.  */
2172
          for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++)
2173
            {
2174
              if (identical_stmt_lists_p (leader, e))
2175
                {
2176
                  /* Give this edge the same stmt list pointer.  */
2177
                  PENDING_STMT (e) = NULL;
2178
                  e->aux = leader;
2179
                  bitmap_set_bit (leader_has_match, x);
2180
                  have_opportunity = found = true;
2181
                  break;
2182
                }
2183
            }
2184
 
2185
          /* If no similar stmt list, add this edge to the leader list.  */
2186
          if (!found)
2187
            {
2188
              VEC_safe_push (edge, heap, edge_leader, e);
2189
              VEC_safe_push (tree, heap, stmt_list, PENDING_STMT (e));
2190
            }
2191
        }
2192
     }
2193
 
2194
  /* If there are no similar lists, just issue the stmts.  */
2195
  if (!have_opportunity)
2196
    {
2197
      for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++)
2198
        bsi_commit_one_edge_insert (leader, NULL);
2199
      VEC_truncate (edge, edge_leader, 0);
2200
      VEC_truncate (tree, stmt_list, 0);
2201
      bitmap_clear (leader_has_match);
2202
      return;
2203
    }
2204
 
2205
 
2206
  if (dump_file)
2207
    fprintf (dump_file, "\nOpportunities in BB %d for stmt/block reduction:\n",
2208
             bb->index);
2209
 
2210
 
2211
  /* For each common list, create a forwarding block and issue the stmt's
2212
     in that block.  */
2213
  for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++)
2214
    if (bitmap_bit_p (leader_has_match, x))
2215
      {
2216
        edge new_edge;
2217
        block_stmt_iterator bsi;
2218
        tree curr_stmt_list;
2219
 
2220
        leader_match = leader;
2221
 
2222
        /* The tree_* cfg manipulation routines use the PENDING_EDGE field
2223
           for various PHI manipulations, so it gets cleared when calls are
2224
           made to make_forwarder_block(). So make sure the edge is clear,
2225
           and use the saved stmt list.  */
2226
        PENDING_STMT (leader) = NULL;
2227
        leader->aux = leader;
2228
        curr_stmt_list = VEC_index (tree, stmt_list, x);
2229
 
2230
        new_edge = make_forwarder_block (leader->dest, same_stmt_list_p,
2231
                                         NULL);
2232
        bb = new_edge->dest;
2233
        if (dump_file)
2234
          {
2235
            fprintf (dump_file, "Splitting BB %d for Common stmt list.  ",
2236
                     leader->dest->index);
2237
            fprintf (dump_file, "Original block is now BB%d.\n", bb->index);
2238
            print_generic_stmt (dump_file, curr_stmt_list, TDF_VOPS);
2239
          }
2240
 
2241
        FOR_EACH_EDGE (e, ei, new_edge->src->preds)
2242
          {
2243
            e->aux = NULL;
2244
            if (dump_file)
2245
              fprintf (dump_file, "  Edge (%d->%d) lands here.\n",
2246
                       e->src->index, e->dest->index);
2247
          }
2248
 
2249
        bsi = bsi_last (leader->dest);
2250
        bsi_insert_after (&bsi, curr_stmt_list, BSI_NEW_STMT);
2251
 
2252
        leader_match = NULL;
2253
        /* We should never get a new block now.  */
2254
      }
2255
    else
2256
      {
2257
        PENDING_STMT (leader) = VEC_index (tree, stmt_list, x);
2258
        bsi_commit_one_edge_insert (leader, NULL);
2259
      }
2260
 
2261
 
2262
  /* Clear the working data structures.  */
2263
  VEC_truncate (edge, edge_leader, 0);
2264
  VEC_truncate (tree, stmt_list, 0);
2265
  bitmap_clear (leader_has_match);
2266
}
2267
 
2268
 
2269
/* This function will analyze the insertions which were performed on edges,
2270
   and decide whether they should be left on that edge, or whether it is more
2271
   efficient to emit some subset of them in a single block.  All stmts are
2272
   inserted somewhere.  */
2273
 
2274
static void
2275
perform_edge_inserts (void)
2276
{
2277
  basic_block bb;
2278
 
2279
  if (dump_file)
2280
    fprintf(dump_file, "Analyzing Edge Insertions.\n");
2281
 
2282
  /* analyze_edges_for_bb calls make_forwarder_block, which tries to
2283
     incrementally update the dominator information.  Since we don't
2284
     need dominator information after this pass, go ahead and free the
2285
     dominator information.  */
2286
  free_dominance_info (CDI_DOMINATORS);
2287
  free_dominance_info (CDI_POST_DOMINATORS);
2288
 
2289
  /* Allocate data structures used in analyze_edges_for_bb.   */
2290
  init_analyze_edges_for_bb ();
2291
 
2292
  FOR_EACH_BB (bb)
2293
    analyze_edges_for_bb (bb);
2294
 
2295
  analyze_edges_for_bb (EXIT_BLOCK_PTR);
2296
 
2297
  /* Free data structures used in analyze_edges_for_bb.   */
2298
  fini_analyze_edges_for_bb ();
2299
 
2300
#ifdef ENABLE_CHECKING
2301
  {
2302
    edge_iterator ei;
2303
    edge e;
2304
    FOR_EACH_BB (bb)
2305
      {
2306
        FOR_EACH_EDGE (e, ei, bb->preds)
2307
          {
2308
            if (PENDING_STMT (e))
2309
              error (" Pending stmts not issued on PRED edge (%d, %d)\n",
2310
                     e->src->index, e->dest->index);
2311
          }
2312
        FOR_EACH_EDGE (e, ei, bb->succs)
2313
          {
2314
            if (PENDING_STMT (e))
2315
              error (" Pending stmts not issued on SUCC edge (%d, %d)\n",
2316
                     e->src->index, e->dest->index);
2317
          }
2318
      }
2319
    FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
2320
      {
2321
        if (PENDING_STMT (e))
2322
          error (" Pending stmts not issued on ENTRY edge (%d, %d)\n",
2323
                 e->src->index, e->dest->index);
2324
      }
2325
    FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
2326
      {
2327
        if (PENDING_STMT (e))
2328
          error (" Pending stmts not issued on EXIT edge (%d, %d)\n",
2329
                 e->src->index, e->dest->index);
2330
      }
2331
  }
2332
#endif
2333
}
2334
 
2335
 
2336
/* Remove the variables specified in MAP from SSA form.  FLAGS indicate what
2337
   options should be used.  */
2338
 
2339
static void
2340
remove_ssa_form (var_map map, int flags)
2341
{
2342
  tree_live_info_p liveinfo;
2343
  basic_block bb;
2344
  tree phi, next;
2345
  tree *values = NULL;
2346
 
2347
  /* If we are not combining temps, don't calculate live ranges for variables
2348
     with only one SSA version.  */
2349
  if ((flags & SSANORM_COMBINE_TEMPS) == 0)
2350
    compact_var_map (map, VARMAP_NO_SINGLE_DEFS);
2351
  else
2352
    compact_var_map (map, VARMAP_NORMAL);
2353
 
2354
  if (dump_file && (dump_flags & TDF_DETAILS))
2355
    dump_var_map (dump_file, map);
2356
 
2357
  liveinfo = coalesce_ssa_name (map, flags);
2358
 
2359
  /* Make sure even single occurrence variables are in the list now.  */
2360
  if ((flags & SSANORM_COMBINE_TEMPS) == 0)
2361
    compact_var_map (map, VARMAP_NORMAL);
2362
 
2363
  if (dump_file && (dump_flags & TDF_DETAILS))
2364
    {
2365
      fprintf (dump_file, "After Coalescing:\n");
2366
      dump_var_map (dump_file, map);
2367
    }
2368
 
2369
  if (flags & SSANORM_PERFORM_TER)
2370
    {
2371
      values = find_replaceable_exprs (map);
2372
      if (values && dump_file && (dump_flags & TDF_DETAILS))
2373
        dump_replaceable_exprs (dump_file, values);
2374
    }
2375
 
2376
  /* Assign real variables to the partitions now.  */
2377
  assign_vars (map);
2378
 
2379
  if (dump_file && (dump_flags & TDF_DETAILS))
2380
    {
2381
      fprintf (dump_file, "After Root variable replacement:\n");
2382
      dump_var_map (dump_file, map);
2383
    }
2384
 
2385
  if ((flags & SSANORM_COMBINE_TEMPS) && liveinfo)
2386
    {
2387
      coalesce_vars (map, liveinfo);
2388
      if (dump_file && (dump_flags & TDF_DETAILS))
2389
        {
2390
          fprintf (dump_file, "After variable memory coalescing:\n");
2391
          dump_var_map (dump_file, map);
2392
        }
2393
    }
2394
 
2395
  if (liveinfo)
2396
    delete_tree_live_info (liveinfo);
2397
 
2398
  rewrite_trees (map, values);
2399
 
2400
  if (values)
2401
    free (values);
2402
 
2403
  /* Remove phi nodes which have been translated back to real variables.  */
2404
  FOR_EACH_BB (bb)
2405
    {
2406
      for (phi = phi_nodes (bb); phi; phi = next)
2407
        {
2408
          next = PHI_CHAIN (phi);
2409
          remove_phi_node (phi, NULL_TREE);
2410
        }
2411
    }
2412
 
2413
  /* we no longer maintain the SSA operand cache at this point.  */
2414
  fini_ssa_operands ();
2415
 
2416
  /* If any copies were inserted on edges, analyze and insert them now.  */
2417
  perform_edge_inserts ();
2418
}
2419
 
2420
/* Search every PHI node for arguments associated with backedges which
2421
   we can trivially determine will need a copy (the argument is either
2422
   not an SSA_NAME or the argument has a different underlying variable
2423
   than the PHI result).
2424
 
2425
   Insert a copy from the PHI argument to a new destination at the
2426
   end of the block with the backedge to the top of the loop.  Update
2427
   the PHI argument to reference this new destination.  */
2428
 
2429
static void
2430
insert_backedge_copies (void)
2431
{
2432
  basic_block bb;
2433
 
2434
  FOR_EACH_BB (bb)
2435
    {
2436
      tree phi;
2437
 
2438
      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
2439
        {
2440
          tree result = PHI_RESULT (phi);
2441
          tree result_var;
2442
          int i;
2443
 
2444
          if (!is_gimple_reg (result))
2445
            continue;
2446
 
2447
          result_var = SSA_NAME_VAR (result);
2448
          for (i = 0; i < PHI_NUM_ARGS (phi); i++)
2449
            {
2450
              tree arg = PHI_ARG_DEF (phi, i);
2451
              edge e = PHI_ARG_EDGE (phi, i);
2452
 
2453
              /* If the argument is not an SSA_NAME, then we will
2454
                 need a constant initialization.  If the argument is
2455
                 an SSA_NAME with a different underlying variable and
2456
                 we are not combining temporaries, then we will
2457
                 need a copy statement.  */
2458
              if ((e->flags & EDGE_DFS_BACK)
2459
                  && (TREE_CODE (arg) != SSA_NAME
2460
                      || (!flag_tree_combine_temps
2461
                          && SSA_NAME_VAR (arg) != result_var)))
2462
                {
2463
                  tree stmt, name, last = NULL;
2464
                  block_stmt_iterator bsi;
2465
 
2466
                  bsi = bsi_last (PHI_ARG_EDGE (phi, i)->src);
2467
                  if (!bsi_end_p (bsi))
2468
                    last = bsi_stmt (bsi);
2469
 
2470
                  /* In theory the only way we ought to get back to the
2471
                     start of a loop should be with a COND_EXPR or GOTO_EXPR.
2472
                     However, better safe than sorry.
2473
 
2474
                     If the block ends with a control statement or
2475
                     something that might throw, then we have to
2476
                     insert this assignment before the last
2477
                     statement.  Else insert it after the last statement.  */
2478
                  if (last && stmt_ends_bb_p (last))
2479
                    {
2480
                      /* If the last statement in the block is the definition
2481
                         site of the PHI argument, then we can't insert
2482
                         anything after it.  */
2483
                      if (TREE_CODE (arg) == SSA_NAME
2484
                          && SSA_NAME_DEF_STMT (arg) == last)
2485
                        continue;
2486
                    }
2487
 
2488
                  /* Create a new instance of the underlying
2489
                     variable of the PHI result.  */
2490
                  stmt = build2 (MODIFY_EXPR, TREE_TYPE (result_var),
2491
                                 NULL_TREE, PHI_ARG_DEF (phi, i));
2492
                  name = make_ssa_name (result_var, stmt);
2493
                  TREE_OPERAND (stmt, 0) = name;
2494
 
2495
                  /* Insert the new statement into the block and update
2496
                     the PHI node.  */
2497
                  if (last && stmt_ends_bb_p (last))
2498
                    bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
2499
                  else
2500
                    bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
2501
                  SET_PHI_ARG_DEF (phi, i, name);
2502
                }
2503
            }
2504
        }
2505
    }
2506
}
2507
 
2508
/* Take the current function out of SSA form, as described in
2509
   R. Morgan, ``Building an Optimizing Compiler'',
2510
   Butterworth-Heinemann, Boston, MA, 1998. pp 176-186.  */
2511
 
2512
static unsigned int
2513
rewrite_out_of_ssa (void)
2514
{
2515
  var_map map;
2516
  int var_flags = 0;
2517
  int ssa_flags = 0;
2518
 
2519
  /* If elimination of a PHI requires inserting a copy on a backedge,
2520
     then we will have to split the backedge which has numerous
2521
     undesirable performance effects.
2522
 
2523
     A significant number of such cases can be handled here by inserting
2524
     copies into the loop itself.  */
2525
  insert_backedge_copies ();
2526
 
2527
  if (!flag_tree_live_range_split)
2528
    ssa_flags |= SSANORM_COALESCE_PARTITIONS;
2529
 
2530
  eliminate_virtual_phis ();
2531
 
2532
  if (dump_file && (dump_flags & TDF_DETAILS))
2533
    dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
2534
 
2535
  /* We cannot allow unssa to un-gimplify trees before we instrument them.  */
2536
  if (flag_tree_ter && !flag_mudflap)
2537
    var_flags = SSA_VAR_MAP_REF_COUNT;
2538
 
2539
  map = create_ssa_var_map (var_flags);
2540
 
2541
  if (flag_tree_combine_temps)
2542
    ssa_flags |= SSANORM_COMBINE_TEMPS;
2543
  if (flag_tree_ter && !flag_mudflap)
2544
    ssa_flags |= SSANORM_PERFORM_TER;
2545
 
2546
  remove_ssa_form (map, ssa_flags);
2547
 
2548
  if (dump_file && (dump_flags & TDF_DETAILS))
2549
    dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
2550
 
2551
  /* Flush out flow graph and SSA data.  */
2552
  delete_var_map (map);
2553
 
2554
  in_ssa_p = false;
2555
  return 0;
2556
}
2557
 
2558
 
2559
/* Define the parameters of the out of SSA pass.  */
2560
 
2561
struct tree_opt_pass pass_del_ssa =
2562
{
2563
  "optimized",                          /* name */
2564
  NULL,                                 /* gate */
2565
  rewrite_out_of_ssa,                   /* execute */
2566
  NULL,                                 /* sub */
2567
  NULL,                                 /* next */
2568
  0,                                     /* static_pass_number */
2569
  TV_TREE_SSA_TO_NORMAL,                /* tv_id */
2570
  PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
2571
  0,                                     /* properties_provided */
2572
  /* ??? If TER is enabled, we also kill gimple.  */
2573
  PROP_ssa,                             /* properties_destroyed */
2574
  TODO_verify_ssa | TODO_verify_flow
2575
    | TODO_verify_stmts,                /* todo_flags_start */
2576
  TODO_dump_func
2577
  | TODO_ggc_collect
2578
  | TODO_remove_unused_locals,          /* todo_flags_finish */
2579
 
2580
};

powered by: WebSVN 2.1.0

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