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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [tree-ssa-ifcombine.c] - Blame information for rev 309

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

Line No. Rev Author Line
1 280 jeremybenn
/* Combining of if-expressions on trees.
2
   Copyright (C) 2007, 2008 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 "diagnostic.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_volatile_ops (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
           && operand_equal_p (gimple_cond_lhs (inner_cond),
371
                               gimple_cond_lhs (outer_cond), 0)
372
           && operand_equal_p (gimple_cond_rhs (inner_cond),
373
                               gimple_cond_rhs (outer_cond), 0))
374
    {
375
      enum tree_code code1 = gimple_cond_code (inner_cond);
376
      enum tree_code code2 = gimple_cond_code (outer_cond);
377
      tree t;
378
 
379
      if (!(t = combine_comparisons (UNKNOWN_LOCATION,
380
                                     TRUTH_ANDIF_EXPR, code1, code2,
381
                                     boolean_type_node,
382
                                     gimple_cond_lhs (outer_cond),
383
                                     gimple_cond_rhs (outer_cond))))
384
        return false;
385
      t = canonicalize_cond_expr_cond (t);
386
      if (!t)
387
        return false;
388
      gimple_cond_set_condition_from_tree (inner_cond, t);
389
      update_stmt (inner_cond);
390
 
391
      /* Leave CFG optimization to cfg_cleanup.  */
392
      gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
393
      update_stmt (outer_cond);
394
 
395
      if (dump_file)
396
        {
397
          fprintf (dump_file, "optimizing two comparisons to ");
398
          print_generic_expr (dump_file, t, 0);
399
          fprintf (dump_file, "\n");
400
        }
401
 
402
      return true;
403
    }
404
 
405
  return false;
406
}
407
 
408
/* If-convert on a or pattern with a common then block.  The inner
409
   if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
410
   Returns true, if the edges leading to the common then basic-block
411
   were merged.  */
412
 
413
static bool
414
ifcombine_iforif (basic_block inner_cond_bb, basic_block outer_cond_bb)
415
{
416
  gimple inner_cond, outer_cond;
417
  tree name1, name2, bits1, bits2;
418
 
419
  inner_cond = last_stmt (inner_cond_bb);
420
  if (!inner_cond
421
      || gimple_code (inner_cond) != GIMPLE_COND)
422
    return false;
423
 
424
  outer_cond = last_stmt (outer_cond_bb);
425
  if (!outer_cond
426
      || gimple_code (outer_cond) != GIMPLE_COND)
427
    return false;
428
 
429
  /* See if we have two bit tests of the same name in both tests.
430
     In that case remove the outer test and change the inner one to
431
     test for name & (bits1 | bits2) != 0.  */
432
  if (recognize_bits_test (inner_cond, &name1, &bits1)
433
      && recognize_bits_test (outer_cond, &name2, &bits2))
434
    {
435
      gimple_stmt_iterator gsi;
436
      tree t;
437
 
438
      /* Find the common name which is bit-tested.  */
439
      if (name1 == name2)
440
        ;
441
      else if (bits1 == bits2)
442
        {
443
          t = name2;
444
          name2 = bits2;
445
          bits2 = t;
446
          t = name1;
447
          name1 = bits1;
448
          bits1 = t;
449
        }
450
      else if (name1 == bits2)
451
        {
452
          t = name2;
453
          name2 = bits2;
454
          bits2 = t;
455
        }
456
      else if (bits1 == name2)
457
        {
458
          t = name1;
459
          name1 = bits1;
460
          bits1 = t;
461
        }
462
      else
463
        return false;
464
 
465
      /* As we strip non-widening conversions in finding a common
466
         name that is tested make sure to end up with an integral
467
         type for building the bit operations.  */
468
      if (TYPE_PRECISION (TREE_TYPE (bits1))
469
          >= TYPE_PRECISION (TREE_TYPE (bits2)))
470
        {
471
          bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
472
          name1 = fold_convert (TREE_TYPE (bits1), name1);
473
          bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
474
          bits2 = fold_convert (TREE_TYPE (bits1), bits2);
475
        }
476
      else
477
        {
478
          bits2 = fold_convert (unsigned_type_for (TREE_TYPE (bits2)), bits2);
479
          name1 = fold_convert (TREE_TYPE (bits2), name1);
480
          bits1 = fold_convert (unsigned_type_for (TREE_TYPE (bits1)), bits1);
481
          bits1 = fold_convert (TREE_TYPE (bits2), bits1);
482
        }
483
 
484
      /* Do it.  */
485
      gsi = gsi_for_stmt (inner_cond);
486
      t = fold_build2 (BIT_IOR_EXPR, TREE_TYPE (name1), bits1, bits2);
487
      t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
488
                                    true, GSI_SAME_STMT);
489
      t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (name1), name1, t);
490
      t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
491
                                    true, GSI_SAME_STMT);
492
      t = fold_build2 (NE_EXPR, boolean_type_node, t,
493
                       build_int_cst (TREE_TYPE (t), 0));
494
      t = canonicalize_cond_expr_cond (t);
495
      if (!t)
496
        return false;
497
      gimple_cond_set_condition_from_tree (inner_cond, t);
498
      update_stmt (inner_cond);
499
 
500
      /* Leave CFG optimization to cfg_cleanup.  */
501
      gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
502
      update_stmt (outer_cond);
503
 
504
      if (dump_file)
505
        {
506
          fprintf (dump_file, "optimizing bits or bits test to ");
507
          print_generic_expr (dump_file, name1, 0);
508
          fprintf (dump_file, " & T != 0\nwith temporary T = ");
509
          print_generic_expr (dump_file, bits1, 0);
510
          fprintf (dump_file, " | ");
511
          print_generic_expr (dump_file, bits2, 0);
512
          fprintf (dump_file, "\n");
513
        }
514
 
515
      return true;
516
    }
517
 
518
  /* See if we have two comparisons that we can merge into one.
519
     This happens for C++ operator overloading where for example
520
     GE_EXPR is implemented as GT_EXPR || EQ_EXPR.  */
521
  else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
522
           && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
523
           && operand_equal_p (gimple_cond_lhs (inner_cond),
524
                               gimple_cond_lhs (outer_cond), 0)
525
           && operand_equal_p (gimple_cond_rhs (inner_cond),
526
                               gimple_cond_rhs (outer_cond), 0))
527
    {
528
      enum tree_code code1 = gimple_cond_code (inner_cond);
529
      enum tree_code code2 = gimple_cond_code (outer_cond);
530
      tree t;
531
 
532
      if (!(t = combine_comparisons (UNKNOWN_LOCATION,
533
                                     TRUTH_ORIF_EXPR, code1, code2,
534
                                     boolean_type_node,
535
                                     gimple_cond_lhs (outer_cond),
536
                                     gimple_cond_rhs (outer_cond))))
537
        return false;
538
      t = canonicalize_cond_expr_cond (t);
539
      if (!t)
540
        return false;
541
      gimple_cond_set_condition_from_tree (inner_cond, t);
542
      update_stmt (inner_cond);
543
 
544
      /* Leave CFG optimization to cfg_cleanup.  */
545
      gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
546
      update_stmt (outer_cond);
547
 
548
      if (dump_file)
549
        {
550
          fprintf (dump_file, "optimizing two comparisons to ");
551
          print_generic_expr (dump_file, t, 0);
552
          fprintf (dump_file, "\n");
553
        }
554
 
555
      return true;
556
    }
557
 
558
  return false;
559
}
560
 
561
/* Recognize a CFG pattern and dispatch to the appropriate
562
   if-conversion helper.  We start with BB as the innermost
563
   worker basic-block.  Returns true if a transformation was done.  */
564
 
565
static bool
566
tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
567
{
568
  basic_block then_bb = NULL, else_bb = NULL;
569
 
570
  if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb))
571
    return false;
572
 
573
  /* Recognize && and || of two conditions with a common
574
     then/else block which entry edges we can merge.  That is:
575
       if (a || b)
576
         ;
577
     and
578
       if (a && b)
579
         ;
580
     This requires a single predecessor of the inner cond_bb.  */
581
  if (single_pred_p (inner_cond_bb))
582
    {
583
      basic_block outer_cond_bb = single_pred (inner_cond_bb);
584
 
585
      /* The && form is characterized by a common else_bb with
586
         the two edges leading to it mergable.  The latter is
587
         guaranteed by matching PHI arguments in the else_bb and
588
         the inner cond_bb having no side-effects.  */
589
      if (recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb)
590
          && same_phi_args_p (outer_cond_bb, inner_cond_bb, else_bb)
591
          && bb_no_side_effects_p (inner_cond_bb))
592
        {
593
          /* We have
594
               <outer_cond_bb>
595
                 if (q) goto inner_cond_bb; else goto else_bb;
596
               <inner_cond_bb>
597
                 if (p) goto ...; else goto else_bb;
598
                 ...
599
               <else_bb>
600
                 ...
601
           */
602
          return ifcombine_ifandif (inner_cond_bb, outer_cond_bb);
603
        }
604
 
605
      /* The || form is characterized by a common then_bb with the
606
         two edges leading to it mergable.  The latter is guaranteed
607
         by matching PHI arguments in the then_bb and the inner cond_bb
608
         having no side-effects.  */
609
      if (recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb)
610
          && same_phi_args_p (outer_cond_bb, inner_cond_bb, then_bb)
611
          && bb_no_side_effects_p (inner_cond_bb))
612
        {
613
          /* We have
614
               <outer_cond_bb>
615
                 if (q) goto then_bb; else goto inner_cond_bb;
616
               <inner_cond_bb>
617
                 if (q) goto then_bb; else goto ...;
618
               <then_bb>
619
                 ...
620
           */
621
          return ifcombine_iforif (inner_cond_bb, outer_cond_bb);
622
        }
623
    }
624
 
625
  return false;
626
}
627
 
628
/* Main entry for the tree if-conversion pass.  */
629
 
630
static unsigned int
631
tree_ssa_ifcombine (void)
632
{
633
  basic_block *bbs;
634
  bool cfg_changed = false;
635
  int i;
636
 
637
  bbs = blocks_in_phiopt_order ();
638
 
639
  for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i)
640
    {
641
      basic_block bb = bbs[i];
642
      gimple stmt = last_stmt (bb);
643
 
644
      if (stmt
645
          && gimple_code (stmt) == GIMPLE_COND)
646
        cfg_changed |= tree_ssa_ifcombine_bb (bb);
647
    }
648
 
649
  free (bbs);
650
 
651
  return cfg_changed ? TODO_cleanup_cfg : 0;
652
}
653
 
654
static bool
655
gate_ifcombine (void)
656
{
657
  return 1;
658
}
659
 
660
struct gimple_opt_pass pass_tree_ifcombine =
661
{
662
 {
663
  GIMPLE_PASS,
664
  "ifcombine",                  /* name */
665
  gate_ifcombine,               /* gate */
666
  tree_ssa_ifcombine,           /* execute */
667
  NULL,                         /* sub */
668
  NULL,                         /* next */
669
  0,                             /* static_pass_number */
670
  TV_TREE_IFCOMBINE,            /* tv_id */
671
  PROP_cfg | PROP_ssa,          /* properties_required */
672
  0,                             /* properties_provided */
673
  0,                             /* properties_destroyed */
674
  0,                             /* todo_flags_start */
675
  TODO_dump_func
676
  | TODO_ggc_collect
677
  | TODO_update_ssa
678
  | TODO_verify_ssa             /* todo_flags_finish */
679
 }
680
};

powered by: WebSVN 2.1.0

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