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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [tree-ssa-ifcombine.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* Combining of if-expressions on trees.
2
   Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
3
   Contributed by Richard Guenther <rguenther@suse.de>
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 "basic-block.h"
27
#include "timevar.h"
28
#include "tree-pretty-print.h"
29
#include "tree-flow.h"
30
#include "tree-pass.h"
31
#include "tree-dump.h"
32
 
33
/* This pass combines COND_EXPRs to simplify control flow.  It
34
   currently recognizes bit tests and comparisons in chains that
35
   represent logical and or logical or of two COND_EXPRs.
36
 
37
   It does so by walking basic blocks in a approximate reverse
38
   post-dominator order and trying to match CFG patterns that
39
   represent logical and or logical or of two COND_EXPRs.
40
   Transformations are done if the COND_EXPR conditions match
41
   either
42
 
43
     1. two single bit tests X & (1 << Yn) (for logical and)
44
 
45
     2. two bit tests X & Yn (for logical or)
46
 
47
     3. two comparisons X OPn Y (for logical or)
48
 
49
   To simplify this pass, removing basic blocks and dead code
50
   is left to CFG cleanup and DCE.  */
51
 
52
 
53
/* Recognize a if-then-else CFG pattern starting to match with the
54
   COND_BB basic-block containing the COND_EXPR.  The recognized
55
   then end else blocks are stored to *THEN_BB and *ELSE_BB.  If
56
   *THEN_BB and/or *ELSE_BB are already set, they are required to
57
   match the then and else basic-blocks to make the pattern match.
58
   Returns true if the pattern matched, false otherwise.  */
59
 
60
static bool
61
recognize_if_then_else (basic_block cond_bb,
62
                        basic_block *then_bb, basic_block *else_bb)
63
{
64
  edge t, e;
65
 
66
  if (EDGE_COUNT (cond_bb->succs) != 2)
67
    return false;
68
 
69
  /* Find the then/else edges.  */
70
  t = EDGE_SUCC (cond_bb, 0);
71
  e = EDGE_SUCC (cond_bb, 1);
72
  if (!(t->flags & EDGE_TRUE_VALUE))
73
    {
74
      edge tmp = t;
75
      t = e;
76
      e = tmp;
77
    }
78
  if (!(t->flags & EDGE_TRUE_VALUE)
79
      || !(e->flags & EDGE_FALSE_VALUE))
80
    return false;
81
 
82
  /* Check if the edge destinations point to the required block.  */
83
  if (*then_bb
84
      && t->dest != *then_bb)
85
    return false;
86
  if (*else_bb
87
      && e->dest != *else_bb)
88
    return false;
89
 
90
  if (!*then_bb)
91
    *then_bb = t->dest;
92
  if (!*else_bb)
93
    *else_bb = e->dest;
94
 
95
  return true;
96
}
97
 
98
/* Verify if the basic block BB does not have side-effects.  Return
99
   true in this case, else false.  */
100
 
101
static bool
102
bb_no_side_effects_p (basic_block bb)
103
{
104
  gimple_stmt_iterator gsi;
105
 
106
  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
107
    {
108
      gimple stmt = gsi_stmt (gsi);
109
 
110
      if (gimple_has_side_effects (stmt)
111
          || gimple_vuse (stmt))
112
        return false;
113
    }
114
 
115
  return true;
116
}
117
 
118
/* Verify if all PHI node arguments in DEST for edges from BB1 or
119
   BB2 to DEST are the same.  This makes the CFG merge point
120
   free from side-effects.  Return true in this case, else false.  */
121
 
122
static bool
123
same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest)
124
{
125
  edge e1 = find_edge (bb1, dest);
126
  edge e2 = find_edge (bb2, dest);
127
  gimple_stmt_iterator gsi;
128
  gimple phi;
129
 
130
  for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi))
131
    {
132
      phi = gsi_stmt (gsi);
133
      if (!operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, e1),
134
                            PHI_ARG_DEF_FROM_EDGE (phi, e2), 0))
135
        return false;
136
    }
137
 
138
  return true;
139
}
140
 
141
/* Return the best representative SSA name for CANDIDATE which is used
142
   in a bit test.  */
143
 
144
static tree
145
get_name_for_bit_test (tree candidate)
146
{
147
  /* Skip single-use names in favor of using the name from a
148
     non-widening conversion definition.  */
149
  if (TREE_CODE (candidate) == SSA_NAME
150
      && has_single_use (candidate))
151
    {
152
      gimple def_stmt = SSA_NAME_DEF_STMT (candidate);
153
      if (is_gimple_assign (def_stmt)
154
          && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
155
        {
156
          if (TYPE_PRECISION (TREE_TYPE (candidate))
157
              <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
158
            return gimple_assign_rhs1 (def_stmt);
159
        }
160
    }
161
 
162
  return candidate;
163
}
164
 
165
/* Recognize a single bit test pattern in GIMPLE_COND and its defining
166
   statements.  Store the name being tested in *NAME and the bit
167
   in *BIT.  The GIMPLE_COND computes *NAME & (1 << *BIT).
168
   Returns true if the pattern matched, false otherwise.  */
169
 
170
static bool
171
recognize_single_bit_test (gimple cond, tree *name, tree *bit)
172
{
173
  gimple stmt;
174
 
175
  /* Get at the definition of the result of the bit test.  */
176
  if (gimple_cond_code (cond) != NE_EXPR
177
      || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
178
      || !integer_zerop (gimple_cond_rhs (cond)))
179
    return false;
180
  stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
181
  if (!is_gimple_assign (stmt))
182
    return false;
183
 
184
  /* Look at which bit is tested.  One form to recognize is
185
     D.1985_5 = state_3(D) >> control1_4(D);
186
     D.1986_6 = (int) D.1985_5;
187
     D.1987_7 = op0 & 1;
188
     if (D.1987_7 != 0)  */
189
  if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
190
      && integer_onep (gimple_assign_rhs2 (stmt))
191
      && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
192
    {
193
      tree orig_name = gimple_assign_rhs1 (stmt);
194
 
195
      /* Look through copies and conversions to eventually
196
         find the stmt that computes the shift.  */
197
      stmt = SSA_NAME_DEF_STMT (orig_name);
198
 
199
      while (is_gimple_assign (stmt)
200
             && ((CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
201
                  && (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (stmt)))
202
                      <= TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
203
                 || gimple_assign_ssa_name_copy_p (stmt)))
204
        stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
205
 
206
      /* If we found such, decompose it.  */
207
      if (is_gimple_assign (stmt)
208
          && gimple_assign_rhs_code (stmt) == RSHIFT_EXPR)
209
        {
210
          /* op0 & (1 << op1) */
211
          *bit = gimple_assign_rhs2 (stmt);
212
          *name = gimple_assign_rhs1 (stmt);
213
        }
214
      else
215
        {
216
          /* t & 1 */
217
          *bit = integer_zero_node;
218
          *name = get_name_for_bit_test (orig_name);
219
        }
220
 
221
      return true;
222
    }
223
 
224
  /* Another form is
225
     D.1987_7 = op0 & (1 << CST)
226
     if (D.1987_7 != 0)  */
227
  if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
228
      && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
229
      && integer_pow2p (gimple_assign_rhs2 (stmt)))
230
    {
231
      *name = gimple_assign_rhs1 (stmt);
232
      *bit = build_int_cst (integer_type_node,
233
                            tree_log2 (gimple_assign_rhs2 (stmt)));
234
      return true;
235
    }
236
 
237
  /* Another form is
238
     D.1986_6 = 1 << control1_4(D)
239
     D.1987_7 = op0 & D.1986_6
240
     if (D.1987_7 != 0)  */
241
  if (gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
242
      && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
243
      && TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME)
244
    {
245
      gimple tmp;
246
 
247
      /* Both arguments of the BIT_AND_EXPR can be the single-bit
248
         specifying expression.  */
249
      tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
250
      if (is_gimple_assign (tmp)
251
          && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
252
          && integer_onep (gimple_assign_rhs1 (tmp)))
253
        {
254
          *name = gimple_assign_rhs2 (stmt);
255
          *bit = gimple_assign_rhs2 (tmp);
256
          return true;
257
        }
258
 
259
      tmp = SSA_NAME_DEF_STMT (gimple_assign_rhs2 (stmt));
260
      if (is_gimple_assign (tmp)
261
          && gimple_assign_rhs_code (tmp) == LSHIFT_EXPR
262
          && integer_onep (gimple_assign_rhs1 (tmp)))
263
        {
264
          *name = gimple_assign_rhs1 (stmt);
265
          *bit = gimple_assign_rhs2 (tmp);
266
          return true;
267
        }
268
    }
269
 
270
  return false;
271
}
272
 
273
/* Recognize a bit test pattern in a GIMPLE_COND and its defining
274
   statements.  Store the name being tested in *NAME and the bits
275
   in *BITS.  The COND_EXPR computes *NAME & *BITS.
276
   Returns true if the pattern matched, false otherwise.  */
277
 
278
static bool
279
recognize_bits_test (gimple cond, tree *name, tree *bits)
280
{
281
  gimple stmt;
282
 
283
  /* Get at the definition of the result of the bit test.  */
284
  if (gimple_cond_code (cond) != NE_EXPR
285
      || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
286
      || !integer_zerop (gimple_cond_rhs (cond)))
287
    return false;
288
  stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
289
  if (!is_gimple_assign (stmt)
290
      || gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
291
    return false;
292
 
293
  *name = get_name_for_bit_test (gimple_assign_rhs1 (stmt));
294
  *bits = gimple_assign_rhs2 (stmt);
295
 
296
  return true;
297
}
298
 
299
/* If-convert on a and pattern with a common else block.  The inner
300
   if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
301
   Returns true if the edges to the common else basic-block were merged.  */
302
 
303
static bool
304
ifcombine_ifandif (basic_block inner_cond_bb, basic_block outer_cond_bb)
305
{
306
  gimple_stmt_iterator gsi;
307
  gimple inner_cond, outer_cond;
308
  tree name1, name2, bit1, bit2;
309
 
310
  inner_cond = last_stmt (inner_cond_bb);
311
  if (!inner_cond
312
      || gimple_code (inner_cond) != GIMPLE_COND)
313
    return false;
314
 
315
  outer_cond = last_stmt (outer_cond_bb);
316
  if (!outer_cond
317
      || gimple_code (outer_cond) != GIMPLE_COND)
318
    return false;
319
 
320
  /* See if we test a single bit of the same name in both tests.  In
321
     that case remove the outer test, merging both else edges,
322
     and change the inner one to test for
323
     name & (bit1 | bit2) == (bit1 | bit2).  */
324
  if (recognize_single_bit_test (inner_cond, &name1, &bit1)
325
      && recognize_single_bit_test (outer_cond, &name2, &bit2)
326
      && name1 == name2)
327
    {
328
      tree t, t2;
329
 
330
      /* Do it.  */
331
      gsi = gsi_for_stmt (inner_cond);
332
      t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
333
                       build_int_cst (TREE_TYPE (name1), 1), bit1);
334
      t2 = fold_build2 (LSHIFT_EXPR, TREE_TYPE (name1),
335
                        build_int_cst (TREE_TYPE (name1), 1), bit2);
336
      t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), t, t2);
337
      t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
338
                                    true, GSI_SAME_STMT);
339
      t2 = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
340
      t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
341
                                     true, GSI_SAME_STMT);
342
      t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
343
      t = canonicalize_cond_expr_cond (t);
344
      if (!t)
345
        return false;
346
      gimple_cond_set_condition_from_tree (inner_cond, t);
347
      update_stmt (inner_cond);
348
 
349
      /* Leave CFG optimization to cfg_cleanup.  */
350
      gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
351
      update_stmt (outer_cond);
352
 
353
      if (dump_file)
354
        {
355
          fprintf (dump_file, "optimizing double bit test to ");
356
          print_generic_expr (dump_file, name1, 0);
357
          fprintf (dump_file, " & T == T\nwith temporary T = (1 << ");
358
          print_generic_expr (dump_file, bit1, 0);
359
          fprintf (dump_file, ") | (1 << ");
360
          print_generic_expr (dump_file, bit2, 0);
361
          fprintf (dump_file, ")\n");
362
        }
363
 
364
      return true;
365
    }
366
 
367
  /* See if we have two comparisons that we can merge into one.  */
368
  else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
369
           && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
370
    {
371
      tree t;
372
 
373
      if (!(t = maybe_fold_and_comparisons (gimple_cond_code (inner_cond),
374
                                            gimple_cond_lhs (inner_cond),
375
                                            gimple_cond_rhs (inner_cond),
376
                                            gimple_cond_code (outer_cond),
377
                                            gimple_cond_lhs (outer_cond),
378
                                            gimple_cond_rhs (outer_cond))))
379
        return false;
380
      t = canonicalize_cond_expr_cond (t);
381
      if (!t)
382
        return false;
383
      gimple_cond_set_condition_from_tree (inner_cond, t);
384
      update_stmt (inner_cond);
385
 
386
      /* Leave CFG optimization to cfg_cleanup.  */
387
      gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
388
      update_stmt (outer_cond);
389
 
390
      if (dump_file)
391
        {
392
          fprintf (dump_file, "optimizing two comparisons to ");
393
          print_generic_expr (dump_file, t, 0);
394
          fprintf (dump_file, "\n");
395
        }
396
 
397
      return true;
398
    }
399
 
400
  return false;
401
}
402
 
403
/* If-convert on a or pattern with a common then block.  The inner
404
   if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
405
   Returns true, if the edges leading to the common then basic-block
406
   were merged.  */
407
 
408
static bool
409
ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
410
{
411
  gimple inner_cond, outer_cond;
412
  tree name1, name2, bits1, bits2;
413
 
414
  inner_cond = last_stmt (inner_cond_bb);
415
  if (!inner_cond
416
      || gimple_code (inner_cond) != GIMPLE_COND)
417
    return false;
418
 
419
  outer_cond = last_stmt (outer_cond_bb);
420
  if (!outer_cond
421
      || gimple_code (outer_cond) != GIMPLE_COND)
422
    return false;
423
 
424
  /* See if we have two bit tests of the same name in both tests.
425
     In that case remove the outer test and change the inner one to
426
     test for name & (bits1 | bits2) != 0.  */
427
  if (recognize_bits_test (inner_cond, &name1, &bits1)
428
      && recognize_bits_test (outer_cond, &name2, &bits2))
429
    {
430
      gimple_stmt_iterator gsi;
431
      tree t;
432
 
433
      /* Find the common name which is bit-tested.  */
434
      if (name1 == name2)
435
        ;
436
      else if (bits1 == bits2)
437
        {
438
          t = name2;
439
          name2 = bits2;
440
          bits2 = t;
441
          t = name1;
442
          name1 = bits1;
443
          bits1 = t;
444
        }
445
      else if (name1 == bits2)
446
        {
447
          t = name2;
448
          name2 = bits2;
449
          bits2 = t;
450
        }
451
      else if (bits1 == name2)
452
        {
453
          t = name1;
454
          name1 = bits1;
455
          bits1 = t;
456
        }
457
      else
458
        return false;
459
 
460
      /* As we strip non-widening conversions in finding a common
461
         name that is tested make sure to end up with an integral
462
         type for building the bit operations.  */
463
      if (TYPE_PRECISION (TREE_TYPE (bits1))
464
          >= TYPE_PRECISION (TREE_TYPE (bits2)))
465
        {
466
          bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
467
          name1 = fold_convert (TREE_TYPE (bits1), name1);
468
          bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
469
          bits2 = fold_convert (TREE_TYPE (bits1), bits2);
470
        }
471
      else
472
        {
473
          bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
474
          name1 = fold_convert (TREE_TYPE (bits2), name1);
475
          bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
476
          bits1 = fold_convert (TREE_TYPE (bits2), bits1);
477
        }
478
 
479
      /* Do it.  */
480
      gsi = gsi_for_stmt (inner_cond);
481
      t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
482
      t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
483
                                    true, GSI_SAME_STMT);
484
      t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
485
      t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
486
                                    true, GSI_SAME_STMT);
487
      t = fold_build2 (NE_EXPR, boolean_type_node, t,
488
                       build_int_cst (TREE_TYPE (t), 0));
489
      t = canonicalize_cond_expr_cond (t);
490
      if (!t)
491
        return false;
492
      gimple_cond_set_condition_from_tree (inner_cond, t);
493
      update_stmt (inner_cond);
494
 
495
      /* Leave CFG optimization to cfg_cleanup.  */
496
      gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
497
      update_stmt (outer_cond);
498
 
499
      if (dump_file)
500
        {
501
          fprintf (dump_file, "optimizing bits or bits test to ");
502
          print_generic_expr (dump_file, name1, 0);
503
          fprintf (dump_file, " & T != 0\nwith temporary T = ");
504
          print_generic_expr (dump_file, bits1, 0);
505
          fprintf (dump_file, " | ");
506
          print_generic_expr (dump_file, bits2, 0);
507
          fprintf (dump_file, "\n");
508
        }
509
 
510
      return true;
511
    }
512
 
513
  /* See if we have two comparisons that we can merge into one.
514
     This happens for C++ operator overloading where for example
515
     GE_EXPR is implemented as GT_EXPR || EQ_EXPR.  */
516
    else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
517
           && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
518
    {
519
      tree t;
520
 
521
      if (!(t = maybe_fold_or_comparisons (gimple_cond_code (inner_cond),
522
                                           gimple_cond_lhs (inner_cond),
523
                                           gimple_cond_rhs (inner_cond),
524
                                           gimple_cond_code (outer_cond),
525
                                           gimple_cond_lhs (outer_cond),
526
                                           gimple_cond_rhs (outer_cond))))
527
        return false;
528
      t = canonicalize_cond_expr_cond (t);
529
      if (!t)
530
        return false;
531
      gimple_cond_set_condition_from_tree (inner_cond, t);
532
      update_stmt (inner_cond);
533
 
534
      /* Leave CFG optimization to cfg_cleanup.  */
535
      gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
536
      update_stmt (outer_cond);
537
 
538
      if (dump_file)
539
        {
540
          fprintf (dump_file, "optimizing two comparisons to ");
541
          print_generic_expr (dump_file, t, 0);
542
          fprintf (dump_file, "\n");
543
        }
544
 
545
      return true;
546
    }
547
 
548
  return false;
549
}
550
 
551
/* Recognize a CFG pattern and dispatch to the appropriate
552
   if-conversion helper.  We start with BB as the innermost
553
   worker basic-block.  Returns true if a transformation was done.  */
554
 
555
static bool
556
tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
557
{
558
  basic_block then_bb = NULL, else_bb = NULL;
559
 
560
  if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb))
561
    return false;
562
 
563
  /* Recognize && and || of two conditions with a common
564
     then/else block which entry edges we can merge.  That is:
565
       if (a || b)
566
         ;
567
     and
568
       if (a && b)
569
         ;
570
     This requires a single predecessor of the inner cond_bb.  */
571
  if (single_pred_p (inner_cond_bb))
572
    {
573
      basic_block outer_cond_bb = single_pred (inner_cond_bb);
574
 
575
      /* The && form is characterized by a common else_bb with
576
         the two edges leading to it mergable.  The latter is
577
         guaranteed by matching PHI arguments in the else_bb and
578
         the inner cond_bb having no side-effects.  */
579
      if (recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb)
580
          && same_phi_args_p (outer_cond_bb, inner_cond_bb, else_bb)
581
          && bb_no_side_effects_p (inner_cond_bb))
582
        {
583
          /* We have
584
               <outer_cond_bb>
585
                 if (q) goto inner_cond_bb; else goto else_bb;
586
               <inner_cond_bb>
587
                 if (p) goto ...; else goto else_bb;
588
                 ...
589
               <else_bb>
590
                 ...
591
           */
592
          return ifcombine_ifandif (inner_cond_bb, outer_cond_bb);
593
        }
594
 
595
      /* The || form is characterized by a common then_bb with the
596
         two edges leading to it mergable.  The latter is guaranteed
597
         by matching PHI arguments in the then_bb and the inner cond_bb
598
         having no side-effects.  */
599
      if (recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb)
600
          && same_phi_args_p (outer_cond_bb, inner_cond_bb, then_bb)
601
          && bb_no_side_effects_p (inner_cond_bb))
602
        {
603
          /* We have
604
               <outer_cond_bb>
605
                 if (q) goto then_bb; else goto inner_cond_bb;
606
               <inner_cond_bb>
607
                 if (q) goto then_bb; else goto ...;
608
               <then_bb>
609
                 ...
610
           */
611
          return ifcombine_iforif (inner_cond_bb, outer_cond_bb);
612
        }
613
    }
614
 
615
  return false;
616
}
617
 
618
/* Main entry for the tree if-conversion pass.  */
619
 
620
static unsigned int
621
tree_ssa_ifcombine (void)
622
{
623
  basic_block *bbs;
624
  bool cfg_changed = false;
625
  int i;
626
 
627
  bbs = blocks_in_phiopt_order ();
628
  calculate_dominance_info (CDI_DOMINATORS);
629
 
630
  for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i)
631
    {
632
      basic_block bb = bbs[i];
633
      gimple stmt = last_stmt (bb);
634
 
635
      if (stmt
636
          && gimple_code (stmt) == GIMPLE_COND)
637
        cfg_changed |= tree_ssa_ifcombine_bb (bb);
638
    }
639
 
640
  free (bbs);
641
 
642
  return cfg_changed ? TODO_cleanup_cfg : 0;
643
}
644
 
645
static bool
646
gate_ifcombine (void)
647
{
648
  return 1;
649
}
650
 
651
struct gimple_opt_pass pass_tree_ifcombine =
652
{
653
 {
654
  GIMPLE_PASS,
655
  "ifcombine",                  /* name */
656
  gate_ifcombine,               /* gate */
657
  tree_ssa_ifcombine,           /* execute */
658
  NULL,                         /* sub */
659
  NULL,                         /* next */
660
  0,                             /* static_pass_number */
661
  TV_TREE_IFCOMBINE,            /* tv_id */
662
  PROP_cfg | PROP_ssa,          /* properties_required */
663
  0,                             /* properties_provided */
664
  0,                             /* properties_destroyed */
665
  0,                             /* todo_flags_start */
666
  TODO_ggc_collect
667
  | TODO_update_ssa
668
  | TODO_verify_ssa             /* todo_flags_finish */
669
 }
670
};

powered by: WebSVN 2.1.0

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