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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [tree-if-conv.c] - Blame information for rev 20

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

Line No. Rev Author Line
1 12 jlechner
/* If-conversion for vectorizer.
2
   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
3
   Contributed by Devang Patel <dpatel@apple.com>
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 2, or (at your option) any later
10
version.
11
 
12
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15
for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING.  If not, write to the Free
19
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301, USA.  */
21
 
22
/* This pass implements tree level if-conversion transformation of loops.
23
   Initial goal is to help vectorizer vectorize loops with conditions.
24
 
25
   A short description of if-conversion:
26
 
27
     o Decide if a loop is if-convertible or not.
28
     o Walk all loop basic blocks in breadth first order (BFS order).
29
       o Remove conditional statements (at the end of basic block)
30
         and propagate condition into destination basic blocks'
31
         predicate list.
32
       o Replace modify expression with conditional modify expression
33
         using current basic block's condition.
34
     o Merge all basic blocks
35
       o Replace phi nodes with conditional modify expr
36
       o Merge all basic blocks into header
37
 
38
     Sample transformation:
39
 
40
     INPUT
41
     -----
42
 
43
     # i_23 = PHI <0(0), i_18(10)>;
44
     <L0>:;
45
     j_15 = A[i_23];
46
     if (j_15 > 41) goto <L1>; else goto <L17>;
47
 
48
     <L17>:;
49
     goto <bb 3> (<L3>);
50
 
51
     <L1>:;
52
 
53
     # iftmp.2_4 = PHI <0(8), 42(2)>;
54
     <L3>:;
55
     A[i_23] = iftmp.2_4;
56
     i_18 = i_23 + 1;
57
     if (i_18 <= 15) goto <L19>; else goto <L18>;
58
 
59
     <L19>:;
60
     goto <bb 1> (<L0>);
61
 
62
     <L18>:;
63
 
64
     OUTPUT
65
     ------
66
 
67
     # i_23 = PHI <0(0), i_18(10)>;
68
     <L0>:;
69
     j_15 = A[i_23];
70
 
71
     <L3>:;
72
     iftmp.2_4 = j_15 > 41 ? 42 : 0;
73
     A[i_23] = iftmp.2_4;
74
     i_18 = i_23 + 1;
75
     if (i_18 <= 15) goto <L19>; else goto <L18>;
76
 
77
     <L19>:;
78
     goto <bb 1> (<L0>);
79
 
80
     <L18>:;
81
*/
82
 
83
#include "config.h"
84
#include "system.h"
85
#include "coretypes.h"
86
#include "tm.h"
87
#include "tree.h"
88
#include "c-common.h"
89
#include "flags.h"
90
#include "timevar.h"
91
#include "varray.h"
92
#include "rtl.h"
93
#include "basic-block.h"
94
#include "diagnostic.h"
95
#include "tree-flow.h"
96
#include "tree-dump.h"
97
#include "cfgloop.h"
98
#include "tree-chrec.h"
99
#include "tree-data-ref.h"
100
#include "tree-scalar-evolution.h"
101
#include "tree-pass.h"
102
#include "target.h"
103
 
104
/* local function prototypes */
105
static void main_tree_if_conversion (void);
106
static tree tree_if_convert_stmt (struct loop *loop, tree, tree,
107
                                  block_stmt_iterator *);
108
static void tree_if_convert_cond_expr (struct loop *, tree, tree,
109
                                       block_stmt_iterator *);
110
static bool if_convertible_phi_p (struct loop *, basic_block, tree);
111
static bool if_convertible_modify_expr_p (struct loop *, basic_block, tree);
112
static bool if_convertible_stmt_p (struct loop *, basic_block, tree);
113
static bool if_convertible_bb_p (struct loop *, basic_block, basic_block);
114
static bool if_convertible_loop_p (struct loop *, bool);
115
static void add_to_predicate_list (basic_block, tree);
116
static tree add_to_dst_predicate_list (struct loop * loop, basic_block, tree, tree,
117
                                       block_stmt_iterator *);
118
static void clean_predicate_lists (struct loop *loop);
119
static basic_block find_phi_replacement_condition (struct loop *loop,
120
                                                   basic_block, tree *,
121
                                                   block_stmt_iterator *);
122
static void replace_phi_with_cond_modify_expr (tree, tree, basic_block,
123
                                               block_stmt_iterator *);
124
static void process_phi_nodes (struct loop *);
125
static void combine_blocks (struct loop *);
126
static tree ifc_temp_var (tree, tree);
127
static bool pred_blocks_visited_p (basic_block, bitmap *);
128
static basic_block * get_loop_body_in_if_conv_order (const struct loop *loop);
129
static bool bb_with_exit_edge_p (struct loop *, basic_block);
130
 
131
/* List of basic blocks in if-conversion-suitable order.  */
132
static basic_block *ifc_bbs;
133
 
134
/* Main entry point.
135
   Apply if-conversion to the LOOP. Return true if successful otherwise return
136
   false. If false is returned then loop remains unchanged.
137
   FOR_VECTORIZER is a boolean flag. It indicates whether if-conversion is used
138
   for vectorizer or not. If it is used for vectorizer, additional checks are
139
   used. (Vectorization checks are not yet implemented).  */
140
 
141
static bool
142
tree_if_conversion (struct loop *loop, bool for_vectorizer)
143
{
144
  basic_block bb;
145
  block_stmt_iterator itr;
146
  tree cond;
147
  unsigned int i;
148
 
149
  ifc_bbs = NULL;
150
 
151
  /* if-conversion is not appropriate for all loops. First, check if loop  is
152
     if-convertible or not.  */
153
  if (!if_convertible_loop_p (loop, for_vectorizer))
154
    {
155
      if (dump_file && (dump_flags & TDF_DETAILS))
156
        fprintf (dump_file,"-------------------------\n");
157
      if (ifc_bbs)
158
        {
159
          free (ifc_bbs);
160
          ifc_bbs = NULL;
161
        }
162
      free_dominance_info (CDI_POST_DOMINATORS);
163
      return false;
164
    }
165
 
166
  cond = NULL_TREE;
167
 
168
  /* Do actual work now.  */
169
  for (i = 0; i < loop->num_nodes; i++)
170
    {
171
      bb = ifc_bbs [i];
172
 
173
      /* Update condition using predicate list.  */
174
      cond = bb->aux;
175
 
176
      /* Process all statements in this basic block.
177
         Remove conditional expression, if any, and annotate
178
         destination basic block(s) appropriately.  */
179
      for (itr = bsi_start (bb); !bsi_end_p (itr); /* empty */)
180
        {
181
          tree t = bsi_stmt (itr);
182
          cond = tree_if_convert_stmt (loop, t, cond, &itr);
183
          if (!bsi_end_p (itr))
184
            bsi_next (&itr);
185
        }
186
 
187
      /* If current bb has only one successor, then consider it as an
188
         unconditional goto.  */
189
      if (single_succ_p (bb))
190
        {
191
          basic_block bb_n = single_succ (bb);
192
          if (cond != NULL_TREE)
193
            add_to_predicate_list (bb_n, cond);
194
          cond = NULL_TREE;
195
        }
196
    }
197
 
198
  /* Now, all statements are if-converted and basic blocks are
199
     annotated appropriately. Combine all basic block into one huge
200
     basic block.  */
201
  combine_blocks (loop);
202
 
203
  /* clean up */
204
  clean_predicate_lists (loop);
205
  free (ifc_bbs);
206
  ifc_bbs = NULL;
207
 
208
  return true;
209
}
210
 
211
/* if-convert stmt T which is part of LOOP.
212
   If T is a MODIFY_EXPR than it is converted into conditional modify
213
   expression using COND.  For conditional expressions, add condition in the
214
   destination basic block's predicate list and remove conditional
215
   expression itself. BSI is the iterator used to traverse statements of
216
   loop. It is used here when it is required to delete current statement.  */
217
 
218
static tree
219
tree_if_convert_stmt (struct loop *  loop, tree t, tree cond,
220
                      block_stmt_iterator *bsi)
221
{
222
  if (dump_file && (dump_flags & TDF_DETAILS))
223
    {
224
      fprintf (dump_file, "------if-convert stmt\n");
225
      print_generic_stmt (dump_file, t, TDF_SLIM);
226
      print_generic_stmt (dump_file, cond, TDF_SLIM);
227
    }
228
 
229
  switch (TREE_CODE (t))
230
    {
231
      /* Labels are harmless here.  */
232
    case LABEL_EXPR:
233
      break;
234
 
235
    case MODIFY_EXPR:
236
      /* This modify_expr is killing previous value of LHS. Appropriate value will
237
         be selected by PHI node based on condition. It is possible that before
238
         this transformation, PHI nodes was selecting default value and now it will
239
         use this new value. This is OK because it does not change validity the
240
         program.  */
241
      break;
242
 
243
    case COND_EXPR:
244
      /* Update destination blocks' predicate list and remove this
245
         condition expression.  */
246
      tree_if_convert_cond_expr (loop, t, cond, bsi);
247
      cond = NULL_TREE;
248
      break;
249
 
250
    default:
251
      gcc_unreachable ();
252
    }
253
  return cond;
254
}
255
 
256
/* STMT is COND_EXPR. Update two destination's predicate list.
257
   Remove COND_EXPR, if it is not the loop exit condition. Otherwise
258
   update loop exit condition appropriately.  BSI is the iterator
259
   used to traverse statement list. STMT is part of loop LOOP.  */
260
 
261
static void
262
tree_if_convert_cond_expr (struct loop *loop, tree stmt, tree cond,
263
                           block_stmt_iterator *bsi)
264
{
265
  tree c, c2;
266
  edge true_edge, false_edge;
267
 
268
  gcc_assert (TREE_CODE (stmt) == COND_EXPR);
269
 
270
  c = COND_EXPR_COND (stmt);
271
 
272
  extract_true_false_edges_from_block (bb_for_stmt (stmt),
273
                                       &true_edge, &false_edge);
274
 
275
  /* Add new condition into destination's predicate list.  */
276
 
277
  /* If 'c' is true then TRUE_EDGE is taken.  */
278
  add_to_dst_predicate_list (loop, true_edge->dest, cond,
279
                             unshare_expr (c), bsi);
280
 
281
  /* If 'c' is false then FALSE_EDGE is taken.  */
282
  c2 = invert_truthvalue (unshare_expr (c));
283
  add_to_dst_predicate_list (loop, false_edge->dest, cond, c2, bsi);
284
 
285
  /* Now this conditional statement is redundant. Remove it.
286
     But, do not remove exit condition! Update exit condition
287
     using new condition.  */
288
  if (!bb_with_exit_edge_p (loop, bb_for_stmt (stmt)))
289
    {
290
      bsi_remove (bsi);
291
      cond = NULL_TREE;
292
    }
293
  return;
294
}
295
 
296
/* Return true, iff PHI is if-convertible. PHI is part of loop LOOP
297
   and it belongs to basic block BB.
298
   PHI is not if-convertible
299
   - if it has more than 2 arguments.
300
   - Virtual PHI is immediately used in another PHI node.  */
301
 
302
static bool
303
if_convertible_phi_p (struct loop *loop, basic_block bb, tree phi)
304
{
305
  if (dump_file && (dump_flags & TDF_DETAILS))
306
    {
307
      fprintf (dump_file, "-------------------------\n");
308
      print_generic_stmt (dump_file, phi, TDF_SLIM);
309
    }
310
 
311
  if (bb != loop->header && PHI_NUM_ARGS (phi) != 2)
312
    {
313
      if (dump_file && (dump_flags & TDF_DETAILS))
314
        fprintf (dump_file, "More than two phi node args.\n");
315
      return false;
316
    }
317
 
318
  if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
319
    {
320
      imm_use_iterator imm_iter;
321
      use_operand_p use_p;
322
      FOR_EACH_IMM_USE_FAST (use_p, imm_iter, PHI_RESULT (phi))
323
        {
324
          if (TREE_CODE (USE_STMT (use_p)) == PHI_NODE)
325
            {
326
              if (dump_file && (dump_flags & TDF_DETAILS))
327
                fprintf (dump_file, "Difficult to handle this virtual phi.\n");
328
              return false;
329
            }
330
        }
331
    }
332
 
333
  return true;
334
}
335
 
336
/* Return true, if M_EXPR is if-convertible.
337
   MODIFY_EXPR is not if-convertible if,
338
   - It is not movable.
339
   - It could trap.
340
   - LHS is not var decl.
341
  MODIFY_EXPR is part of block BB, which is inside loop LOOP.
342
*/
343
 
344
static bool
345
if_convertible_modify_expr_p (struct loop *loop, basic_block bb, tree m_expr)
346
{
347
  if (dump_file && (dump_flags & TDF_DETAILS))
348
    {
349
      fprintf (dump_file, "-------------------------\n");
350
      print_generic_stmt (dump_file, m_expr, TDF_SLIM);
351
    }
352
 
353
  /* Be conservative and do not handle immovable expressions.  */
354
  if (movement_possibility (m_expr) == MOVE_IMPOSSIBLE)
355
    {
356
      if (dump_file && (dump_flags & TDF_DETAILS))
357
        fprintf (dump_file, "stmt is movable. Don't take risk\n");
358
      return false;
359
    }
360
 
361
  /* See if it needs speculative loading or not.  */
362
  if (bb != loop->header
363
      && tree_could_trap_p (TREE_OPERAND (m_expr, 1)))
364
    {
365
      if (dump_file && (dump_flags & TDF_DETAILS))
366
        fprintf (dump_file, "tree could trap...\n");
367
      return false;
368
    }
369
 
370
  if (TREE_CODE (TREE_OPERAND (m_expr, 1)) == CALL_EXPR)
371
    {
372
      if (dump_file && (dump_flags & TDF_DETAILS))
373
        fprintf (dump_file, "CALL_EXPR \n");
374
      return false;
375
    }
376
 
377
  if (TREE_CODE (TREE_OPERAND (m_expr, 0)) != SSA_NAME
378
      && bb != loop->header
379
      && !bb_with_exit_edge_p (loop, bb))
380
    {
381
      if (dump_file && (dump_flags & TDF_DETAILS))
382
        {
383
          fprintf (dump_file, "LHS is not var\n");
384
          print_generic_stmt (dump_file, m_expr, TDF_SLIM);
385
        }
386
      return false;
387
    }
388
 
389
 
390
  return true;
391
}
392
 
393
/* Return true, iff STMT is if-convertible.
394
   Statement is if-convertible if,
395
   - It is if-convertible MODIFY_EXPR
396
   - IT is LABEL_EXPR or COND_EXPR.
397
   STMT is inside block BB, which is inside loop LOOP.  */
398
 
399
static bool
400
if_convertible_stmt_p (struct loop *loop, basic_block bb, tree stmt)
401
{
402
  switch (TREE_CODE (stmt))
403
    {
404
    case LABEL_EXPR:
405
      break;
406
 
407
    case MODIFY_EXPR:
408
 
409
      if (!if_convertible_modify_expr_p (loop, bb, stmt))
410
        return false;
411
      break;
412
 
413
    case COND_EXPR:
414
      break;
415
 
416
    default:
417
      /* Don't know what to do with 'em so don't do anything.  */
418
      if (dump_file && (dump_flags & TDF_DETAILS))
419
        {
420
          fprintf (dump_file, "don't know what to do\n");
421
          print_generic_stmt (dump_file, stmt, TDF_SLIM);
422
        }
423
      return false;
424
      break;
425
    }
426
 
427
  return true;
428
}
429
 
430
/* Return true, iff BB is if-convertible.
431
   Note: This routine does _not_ check basic block statements and phis.
432
   Basic block is not if-convertible if,
433
   - Basic block is non-empty and it is after exit block (in BFS order).
434
   - Basic block is after exit block but before latch.
435
   - Basic block edge(s) is not normal.
436
   EXIT_BB_SEEN is true if basic block with exit edge is already seen.
437
   BB is inside loop LOOP.  */
438
 
439
static bool
440
if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
441
{
442
  edge e;
443
  edge_iterator ei;
444
 
445
  if (dump_file && (dump_flags & TDF_DETAILS))
446
    fprintf (dump_file, "----------[%d]-------------\n", bb->index);
447
 
448
  if (exit_bb)
449
    {
450
      if (bb != loop->latch)
451
        {
452
          if (dump_file && (dump_flags & TDF_DETAILS))
453
            fprintf (dump_file, "basic block after exit bb but before latch\n");
454
          return false;
455
        }
456
      else if (!empty_block_p (bb))
457
        {
458
          if (dump_file && (dump_flags & TDF_DETAILS))
459
            fprintf (dump_file, "non empty basic block after exit bb\n");
460
          return false;
461
        }
462
      else if (bb == loop->latch
463
               && bb != exit_bb
464
               && !dominated_by_p (CDI_DOMINATORS, bb, exit_bb))
465
          {
466
            if (dump_file && (dump_flags & TDF_DETAILS))
467
              fprintf (dump_file, "latch is not dominated by exit_block\n");
468
            return false;
469
          }
470
    }
471
 
472
  /* Be less adventurous and handle only normal edges.  */
473
  FOR_EACH_EDGE (e, ei, bb->succs)
474
    if (e->flags &
475
        (EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_ABNORMAL | EDGE_IRREDUCIBLE_LOOP))
476
      {
477
        if (dump_file && (dump_flags & TDF_DETAILS))
478
          fprintf (dump_file,"Difficult to handle edges\n");
479
        return false;
480
      }
481
 
482
  return true;
483
}
484
 
485
/* Return true, iff LOOP is if-convertible.
486
   LOOP is if-convertible if,
487
   - It is innermost.
488
   - It has two or more basic blocks.
489
   - It has only one exit.
490
   - Loop header is not the exit edge.
491
   - If its basic blocks and phi nodes are if convertible. See above for
492
     more info.
493
   FOR_VECTORIZER enables vectorizer specific checks. For example, support
494
   for vector conditions, data dependency checks etc.. (Not implemented yet).  */
495
 
496
static bool
497
if_convertible_loop_p (struct loop *loop, bool for_vectorizer ATTRIBUTE_UNUSED)
498
{
499
  tree phi;
500
  basic_block bb;
501
  block_stmt_iterator itr;
502
  unsigned int i;
503
  edge e;
504
  edge_iterator ei;
505
  basic_block exit_bb = NULL;
506
 
507
  /* Handle only inner most loop.  */
508
  if (!loop || loop->inner)
509
    {
510
      if (dump_file && (dump_flags & TDF_DETAILS))
511
        fprintf (dump_file, "not inner most loop\n");
512
      return false;
513
    }
514
 
515
  /* If only one block, no need for if-conversion.  */
516
  if (loop->num_nodes <= 2)
517
    {
518
      if (dump_file && (dump_flags & TDF_DETAILS))
519
        fprintf (dump_file, "less than 2 basic blocks\n");
520
      return false;
521
    }
522
 
523
  /* More than one loop exit is too much to handle.  */
524
  if (!loop->single_exit)
525
    {
526
      if (dump_file && (dump_flags & TDF_DETAILS))
527
        fprintf (dump_file, "multiple exits\n");
528
      return false;
529
    }
530
 
531
  /* ??? Check target's vector conditional operation support for vectorizer.  */
532
 
533
  /* If one of the loop header's edge is exit edge then do not apply
534
     if-conversion.  */
535
  FOR_EACH_EDGE (e, ei, loop->header->succs)
536
    {
537
      if (loop_exit_edge_p (loop, e))
538
        return false;
539
    }
540
 
541
  calculate_dominance_info (CDI_DOMINATORS);
542
  calculate_dominance_info (CDI_POST_DOMINATORS);
543
 
544
  /* Allow statements that can be handled during if-conversion.  */
545
  ifc_bbs = get_loop_body_in_if_conv_order (loop);
546
  if (!ifc_bbs)
547
    {
548
      if (dump_file && (dump_flags & TDF_DETAILS))
549
        fprintf (dump_file,"Irreducible loop\n");
550
      free_dominance_info (CDI_POST_DOMINATORS);
551
      return false;
552
    }
553
 
554
  for (i = 0; i < loop->num_nodes; i++)
555
    {
556
      bb = ifc_bbs[i];
557
 
558
      if (!if_convertible_bb_p (loop, bb, exit_bb))
559
        return false;
560
 
561
      /* Check statements.  */
562
      for (itr = bsi_start (bb); !bsi_end_p (itr); bsi_next (&itr))
563
        if (!if_convertible_stmt_p (loop, bb, bsi_stmt (itr)))
564
          return false;
565
      /* ??? Check data dependency for vectorizer.  */
566
 
567
      /* What about phi nodes ? */
568
      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
569
        if (!if_convertible_phi_p (loop, bb, phi))
570
          return false;
571
 
572
      if (bb_with_exit_edge_p (loop, bb))
573
        exit_bb = bb;
574
    }
575
 
576
  /* OK. Did not find any potential issues so go ahead in if-convert
577
     this loop. Now there is no looking back.  */
578
  if (dump_file)
579
    fprintf (dump_file,"Applying if-conversion\n");
580
 
581
  free_dominance_info (CDI_POST_DOMINATORS);
582
  return true;
583
}
584
 
585
/* Add condition COND into predicate list of basic block BB.  */
586
 
587
static void
588
add_to_predicate_list (basic_block bb, tree new_cond)
589
{
590
  tree cond = bb->aux;
591
 
592
  if (cond)
593
    cond = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
594
                        unshare_expr (cond), new_cond);
595
  else
596
    cond = new_cond;
597
 
598
  bb->aux = cond;
599
}
600
 
601
/* Add condition COND into BB's predicate list.  PREV_COND is
602
   existing condition.  */
603
 
604
static tree
605
add_to_dst_predicate_list (struct loop * loop, basic_block bb,
606
                           tree prev_cond, tree cond,
607
                           block_stmt_iterator *bsi)
608
{
609
  tree new_cond = NULL_TREE;
610
 
611
  if (!flow_bb_inside_loop_p (loop, bb))
612
    return NULL_TREE;
613
 
614
  if (prev_cond == boolean_true_node || !prev_cond)
615
    new_cond = unshare_expr (cond);
616
  else
617
    {
618
      tree tmp;
619
      tree tmp_stmt = NULL_TREE;
620
      tree tmp_stmts1 = NULL_TREE;
621
      tree tmp_stmts2 = NULL_TREE;
622
      prev_cond = force_gimple_operand (unshare_expr (prev_cond),
623
                                        &tmp_stmts1, true, NULL);
624
      if (tmp_stmts1)
625
        bsi_insert_before (bsi, tmp_stmts1, BSI_SAME_STMT);
626
 
627
      cond = force_gimple_operand (unshare_expr (cond),
628
                                   &tmp_stmts2, true, NULL);
629
      if (tmp_stmts2)
630
        bsi_insert_before (bsi, tmp_stmts2, BSI_SAME_STMT);
631
 
632
      /* new_cond == prev_cond AND cond */
633
      tmp = build (TRUTH_AND_EXPR, boolean_type_node,
634
                   unshare_expr (prev_cond), cond);
635
      tmp_stmt = ifc_temp_var (boolean_type_node, tmp);
636
      bsi_insert_before (bsi, tmp_stmt, BSI_SAME_STMT);
637
      new_cond = TREE_OPERAND (tmp_stmt, 0);
638
    }
639
  add_to_predicate_list (bb, new_cond);
640
  return new_cond;
641
}
642
 
643
/* During if-conversion aux field from basic block is used to hold predicate
644
   list. Clean each basic block's predicate list for the given LOOP.  */
645
 
646
static void
647
clean_predicate_lists (struct loop *loop)
648
{
649
  basic_block *bb;
650
  unsigned int i;
651
  bb = get_loop_body (loop);
652
  for (i = 0; i < loop->num_nodes; i++)
653
    bb[i]->aux = NULL;
654
 
655
  free (bb);
656
}
657
 
658
/* Basic block BB has two predecessors. Using predecessor's aux field, set
659
   appropriate condition COND for the PHI node replacement. Return true block
660
   whose phi arguments are selected when cond is true.  */
661
 
662
static basic_block
663
find_phi_replacement_condition (struct loop *loop,
664
                                basic_block bb, tree *cond,
665
                                block_stmt_iterator *bsi)
666
{
667
  basic_block first_bb = NULL;
668
  basic_block second_bb = NULL;
669
  tree tmp_cond;
670
 
671
  gcc_assert (EDGE_COUNT (bb->preds) == 2);
672
  first_bb = (EDGE_PRED (bb, 0))->src;
673
  second_bb = (EDGE_PRED (bb, 1))->src;
674
 
675
  /* Use condition based on following criteria:
676
     1)
677
       S1: x = !c ? a : b;
678
 
679
       S2: x = c ? b : a;
680
 
681
       S2 is preferred over S1. Make 'b' first_bb and use its condition.
682
 
683
     2) Do not make loop header first_bb.
684
 
685
     3)
686
       S1: x = !(c == d)? a : b;
687
 
688
       S21: t1 = c == d;
689
       S22: x = t1 ? b : a;
690
 
691
       S3: x = (c == d) ? b : a;
692
 
693
       S3 is preferred over S1 and S2*, Make 'b' first_bb and use
694
       its condition.
695
 
696
     4) If  pred B is dominated by pred A then use pred B's condition.
697
        See PR23115.  */
698
 
699
  /* Select condition that is not TRUTH_NOT_EXPR.  */
700
  tmp_cond = first_bb->aux;
701
  if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
702
    {
703
      basic_block tmp_bb;
704
      tmp_bb = first_bb;
705
      first_bb = second_bb;
706
      second_bb = tmp_bb;
707
    }
708
 
709
  /* Check if FIRST_BB is loop header or not and make sure that
710
     FIRST_BB does not dominate SECOND_BB.  */
711
  if (first_bb == loop->header
712
      || dominated_by_p (CDI_DOMINATORS, second_bb, first_bb))
713
    {
714
      tmp_cond = second_bb->aux;
715
      if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
716
        {
717
          /* Select non loop header condition but do not switch basic blocks.  */
718
          *cond = invert_truthvalue (unshare_expr (tmp_cond));
719
        }
720
      else
721
        {
722
          /* Select non loop header condition.  */
723
          first_bb = second_bb;
724
          *cond = first_bb->aux;
725
        }
726
    }
727
  else
728
    /* FIRST_BB is not loop header */
729
    *cond = first_bb->aux;
730
 
731
  /* Create temp. for the condition. Vectorizer prefers to have gimple
732
     value as condition. Various targets use different means to communicate
733
     condition in vector compare operation. Using gimple value allows compiler
734
     to emit vector compare and select RTL without exposing compare's result.  */
735
  if (!is_gimple_reg (*cond) && !is_gimple_condexpr (*cond))
736
    {
737
      tree new_stmt;
738
 
739
      new_stmt = ifc_temp_var (TREE_TYPE (*cond), unshare_expr (*cond));
740
      bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
741
      *cond = TREE_OPERAND (new_stmt, 0);
742
    }
743
 
744
  gcc_assert (*cond);
745
 
746
  return first_bb;
747
}
748
 
749
 
750
/* Replace PHI node with conditional modify expr using COND.
751
   This routine does not handle PHI nodes with more than two arguments.
752
   For example,
753
     S1: A = PHI <x1(1), x2(5)
754
   is converted into,
755
     S2: A = cond ? x1 : x2;
756
   S2 is inserted at the top of basic block's statement list.
757
   When COND is true, phi arg from TRUE_BB is selected.
758
*/
759
 
760
static void
761
replace_phi_with_cond_modify_expr (tree phi, tree cond, basic_block true_bb,
762
                                   block_stmt_iterator *bsi)
763
{
764
  tree new_stmt;
765
  basic_block bb;
766
  tree rhs;
767
  tree arg_0, arg_1;
768
 
769
  gcc_assert (TREE_CODE (phi) == PHI_NODE);
770
 
771
  /* If this is not filtered earlier, then now it is too late.  */
772
  gcc_assert (PHI_NUM_ARGS (phi) == 2);
773
 
774
  /* Find basic block and initialize iterator.  */
775
  bb = bb_for_stmt (phi);
776
 
777
  new_stmt = NULL_TREE;
778
  arg_0 = NULL_TREE;
779
  arg_1 = NULL_TREE;
780
 
781
  /* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr.  */
782
  if (EDGE_PRED (bb, 1)->src == true_bb)
783
    {
784
      arg_0 = PHI_ARG_DEF (phi, 1);
785
      arg_1 = PHI_ARG_DEF (phi, 0);
786
    }
787
  else
788
    {
789
      arg_0 = PHI_ARG_DEF (phi, 0);
790
      arg_1 = PHI_ARG_DEF (phi, 1);
791
    }
792
 
793
  /* Build new RHS using selected condition and arguments.  */
794
  rhs = build (COND_EXPR, TREE_TYPE (PHI_RESULT (phi)),
795
               unshare_expr (cond), unshare_expr (arg_0),
796
               unshare_expr (arg_1));
797
 
798
  /* Create new MODIFY expression using RHS.  */
799
  new_stmt = build (MODIFY_EXPR, TREE_TYPE (PHI_RESULT (phi)),
800
                    unshare_expr (PHI_RESULT (phi)), rhs);
801
 
802
  /* Make new statement definition of the original phi result.  */
803
  SSA_NAME_DEF_STMT (PHI_RESULT (phi)) = new_stmt;
804
 
805
  /* Insert using iterator.  */
806
  bsi_insert_before (bsi, new_stmt, BSI_SAME_STMT);
807
  update_stmt (new_stmt);
808
 
809
  if (dump_file && (dump_flags & TDF_DETAILS))
810
    {
811
      fprintf (dump_file, "new phi replacement stmt\n");
812
      print_generic_stmt (dump_file, new_stmt, TDF_SLIM);
813
    }
814
}
815
 
816
/* Process phi nodes for the given  LOOP.  Replace phi nodes with cond
817
   modify expr.  */
818
 
819
static void
820
process_phi_nodes (struct loop *loop)
821
{
822
  basic_block bb;
823
  unsigned int orig_loop_num_nodes = loop->num_nodes;
824
  unsigned int i;
825
 
826
  /* Replace phi nodes with cond. modify expr.  */
827
  for (i = 1; i < orig_loop_num_nodes; i++)
828
    {
829
      tree phi, cond;
830
      block_stmt_iterator bsi;
831
      basic_block true_bb = NULL;
832
      bb = ifc_bbs[i];
833
 
834
      if (bb == loop->header)
835
        continue;
836
 
837
      phi = phi_nodes (bb);
838
      bsi = bsi_after_labels (bb);
839
 
840
      /* BB has two predecessors. Using predecessor's aux field, set
841
         appropriate condition for the PHI node replacement.  */
842
      if (phi)
843
        true_bb = find_phi_replacement_condition (loop, bb, &cond, &bsi);
844
 
845
      while (phi)
846
        {
847
          tree next = PHI_CHAIN (phi);
848
          replace_phi_with_cond_modify_expr (phi, cond, true_bb, &bsi);
849
          release_phi_node (phi);
850
          phi = next;
851
        }
852
      bb->phi_nodes = NULL;
853
    }
854
  return;
855
}
856
 
857
/* Combine all basic block from the given LOOP into one or two super
858
   basic block.  Replace PHI nodes with conditional modify expression.  */
859
 
860
static void
861
combine_blocks (struct loop *loop)
862
{
863
  basic_block bb, exit_bb, merge_target_bb;
864
  unsigned int orig_loop_num_nodes = loop->num_nodes;
865
  unsigned int i;
866
  unsigned int n_exits;
867
 
868
  get_loop_exit_edges (loop, &n_exits);
869
  /* Process phi nodes to prepare blocks for merge.  */
870
  process_phi_nodes (loop);
871
 
872
  exit_bb = NULL;
873
 
874
  /* Merge basic blocks */
875
  merge_target_bb = loop->header;
876
  for (i = 1; i < orig_loop_num_nodes; i++)
877
    {
878
      edge e;
879
      block_stmt_iterator bsi;
880
      tree_stmt_iterator last;
881
 
882
      bb = ifc_bbs[i];
883
 
884
      if (!exit_bb && bb_with_exit_edge_p (loop, bb))
885
          exit_bb = bb;
886
 
887
      if (bb == exit_bb)
888
        {
889
          edge_iterator ei;
890
 
891
          /* Connect this node with loop header.  */
892
          make_edge (ifc_bbs[0], bb, EDGE_FALLTHRU);
893
          set_immediate_dominator (CDI_DOMINATORS, bb, ifc_bbs[0]);
894
 
895
          if (exit_bb != loop->latch)
896
            {
897
              /* Redirect non-exit edge to loop->latch.  */
898
              FOR_EACH_EDGE (e, ei, bb->succs)
899
                {
900
                  if (!loop_exit_edge_p (loop, e))
901
                    {
902
                      redirect_edge_and_branch (e, loop->latch);
903
                      set_immediate_dominator (CDI_DOMINATORS, loop->latch, bb);
904
                    }
905
                }
906
            }
907
          continue;
908
        }
909
 
910
      if (bb == loop->latch && empty_block_p (bb))
911
        continue;
912
 
913
      /* It is time to remove this basic block.  First remove edges.  */
914
      while (EDGE_COUNT (bb->preds) > 0)
915
        remove_edge (EDGE_PRED (bb, 0));
916
 
917
      /* This is loop latch and loop does not have exit then do not
918
         delete this basic block. Just remove its PREDS and reconnect
919
         loop->header and loop->latch blocks.  */
920
      if (bb == loop->latch && n_exits == 0)
921
        {
922
          make_edge (loop->header, loop->latch, EDGE_FALLTHRU);
923
          set_immediate_dominator (CDI_DOMINATORS, loop->latch, loop->header);
924
          continue;
925
        }
926
 
927
      while (EDGE_COUNT (bb->succs) > 0)
928
        remove_edge (EDGE_SUCC (bb, 0));
929
 
930
      /* Remove labels and make stmts member of loop->header.  */
931
      for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
932
        {
933
          if (TREE_CODE (bsi_stmt (bsi)) == LABEL_EXPR)
934
            bsi_remove (&bsi);
935
          else
936
            {
937
              set_bb_for_stmt (bsi_stmt (bsi), merge_target_bb);
938
              bsi_next (&bsi);
939
            }
940
        }
941
 
942
      /* Update stmt list.  */
943
      last = tsi_last (merge_target_bb->stmt_list);
944
      tsi_link_after (&last, bb->stmt_list, TSI_NEW_STMT);
945
      bb->stmt_list = NULL;
946
 
947
      /* Update dominator info.  */
948
      if (dom_computed[CDI_DOMINATORS])
949
        delete_from_dominance_info (CDI_DOMINATORS, bb);
950
      if (dom_computed[CDI_POST_DOMINATORS])
951
        delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
952
 
953
      /* Remove basic block.  */
954
      if (bb == loop->latch)
955
        loop->latch = merge_target_bb;
956
      remove_bb_from_loops (bb);
957
      expunge_block (bb);
958
    }
959
 
960
  /* Now if possible, merge loop header and block with exit edge.
961
     This reduces number of basic blocks to 2. Auto vectorizer addresses
962
     loops with two nodes only.  FIXME: Use cleanup_tree_cfg().  */
963
  if (exit_bb
964
      && loop->header != loop->latch
965
      && exit_bb != loop->latch
966
      && empty_block_p (loop->latch))
967
    {
968
      if (can_merge_blocks_p (loop->header, exit_bb))
969
        {
970
          remove_bb_from_loops (exit_bb);
971
          merge_blocks (loop->header, exit_bb);
972
        }
973
    }
974
}
975
 
976
/* Make new  temp variable of type TYPE. Add MODIFY_EXPR to assign EXP
977
   to the new variable.  */
978
 
979
static tree
980
ifc_temp_var (tree type, tree exp)
981
{
982
  const char *name = "_ifc_";
983
  tree var, stmt, new_name;
984
 
985
  if (is_gimple_reg (exp))
986
    return exp;
987
 
988
  /* Create new temporary variable.  */
989
  var = create_tmp_var (type, name);
990
  add_referenced_tmp_var (var);
991
 
992
  /* Build new statement to assign EXP to new variable.  */
993
  stmt = build (MODIFY_EXPR, type, var, exp);
994
 
995
  /* Get SSA name for the new variable and set make new statement
996
     its definition statement.  */
997
  new_name = make_ssa_name (var, stmt);
998
  TREE_OPERAND (stmt, 0) = new_name;
999
  SSA_NAME_DEF_STMT (new_name) = stmt;
1000
 
1001
  return stmt;
1002
}
1003
 
1004
 
1005
/* Return TRUE iff, all pred blocks of BB are visited.
1006
   Bitmap VISITED keeps history of visited blocks.  */
1007
 
1008
static bool
1009
pred_blocks_visited_p (basic_block bb, bitmap *visited)
1010
{
1011
  edge e;
1012
  edge_iterator ei;
1013
  FOR_EACH_EDGE (e, ei, bb->preds)
1014
    if (!bitmap_bit_p (*visited, e->src->index))
1015
      return false;
1016
 
1017
  return true;
1018
}
1019
 
1020
/* Get body of a LOOP in suitable order for if-conversion.
1021
   It is caller's responsibility to deallocate basic block
1022
   list.  If-conversion suitable order is, BFS order with one
1023
   additional constraint. Select block in BFS block, if all
1024
   pred are already selected.  */
1025
 
1026
static basic_block *
1027
get_loop_body_in_if_conv_order (const struct loop *loop)
1028
{
1029
  basic_block *blocks, *blocks_in_bfs_order;
1030
  basic_block bb;
1031
  bitmap visited;
1032
  unsigned int index = 0;
1033
  unsigned int visited_count = 0;
1034
 
1035
  gcc_assert (loop->num_nodes);
1036
  gcc_assert (loop->latch != EXIT_BLOCK_PTR);
1037
 
1038
  blocks = xcalloc (loop->num_nodes, sizeof (basic_block));
1039
  visited = BITMAP_ALLOC (NULL);
1040
 
1041
  blocks_in_bfs_order = get_loop_body_in_bfs_order (loop);
1042
 
1043
  index = 0;
1044
  while (index < loop->num_nodes)
1045
    {
1046
      bb = blocks_in_bfs_order [index];
1047
 
1048
      if (bb->flags & BB_IRREDUCIBLE_LOOP)
1049
        {
1050
          free (blocks_in_bfs_order);
1051
          BITMAP_FREE (visited);
1052
          free (blocks);
1053
          return NULL;
1054
        }
1055
      if (!bitmap_bit_p (visited, bb->index))
1056
        {
1057
          if (pred_blocks_visited_p (bb, &visited)
1058
              || bb == loop->header)
1059
            {
1060
              /* This block is now visited.  */
1061
              bitmap_set_bit (visited, bb->index);
1062
              blocks[visited_count++] = bb;
1063
            }
1064
        }
1065
      index++;
1066
      if (index == loop->num_nodes
1067
          && visited_count != loop->num_nodes)
1068
        {
1069
          /* Not done yet.  */
1070
          index = 0;
1071
        }
1072
    }
1073
  free (blocks_in_bfs_order);
1074
  BITMAP_FREE (visited);
1075
  return blocks;
1076
}
1077
 
1078
/* Return true if one of the basic block BB edge is exit of LOOP.  */
1079
 
1080
static bool
1081
bb_with_exit_edge_p (struct loop *loop, basic_block bb)
1082
{
1083
  edge e;
1084
  edge_iterator ei;
1085
  bool exit_edge_found = false;
1086
 
1087
  FOR_EACH_EDGE (e, ei, bb->succs)
1088
    if (loop_exit_edge_p (loop, e))
1089
      {
1090
        exit_edge_found = true;
1091
        break;
1092
      }
1093
 
1094
  return exit_edge_found;
1095
}
1096
 
1097
/* Tree if-conversion pass management.  */
1098
 
1099
static void
1100
main_tree_if_conversion (void)
1101
{
1102
  unsigned i, loop_num;
1103
  struct loop *loop;
1104
 
1105
  if (!current_loops)
1106
    return;
1107
 
1108
  loop_num = current_loops->num;
1109
  for (i = 0; i < loop_num; i++)
1110
    {
1111
      loop =  current_loops->parray[i];
1112
      if (!loop)
1113
      continue;
1114
 
1115
      tree_if_conversion (loop, true);
1116
    }
1117
 
1118
}
1119
 
1120
static bool
1121
gate_tree_if_conversion (void)
1122
{
1123
  return flag_tree_vectorize != 0;
1124
}
1125
 
1126
struct tree_opt_pass pass_if_conversion =
1127
{
1128
  "ifcvt",                              /* name */
1129
  gate_tree_if_conversion,              /* gate */
1130
  main_tree_if_conversion,              /* execute */
1131
  NULL,                                 /* sub */
1132
  NULL,                                 /* next */
1133
  0,                                     /* static_pass_number */
1134
  0,                                     /* tv_id */
1135
  PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
1136
  0,                                     /* properties_provided */
1137
  0,                                     /* properties_destroyed */
1138
  0,                                     /* todo_flags_start */
1139
  TODO_dump_func | TODO_verify_loops | TODO_verify_stmts | TODO_verify_flow,
1140
                                        /* todo_flags_finish */
1141
 
1142
};

powered by: WebSVN 2.1.0

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