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

Subversion Repositories openrisc

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

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

Line No. Rev Author Line
1 38 julius
/* Miscellaneous SSA utility functions.
2
   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
3
 
4
This file is part of GCC.
5
 
6
GCC is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 3, or (at your option)
9
any later version.
10
 
11
GCC is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GCC; see the file COPYING3.  If not see
18
<http://www.gnu.org/licenses/>.  */
19
 
20
#include "config.h"
21
#include "system.h"
22
#include "coretypes.h"
23
#include "tm.h"
24
#include "tree.h"
25
#include "flags.h"
26
#include "rtl.h"
27
#include "tm_p.h"
28
#include "ggc.h"
29
#include "langhooks.h"
30
#include "hard-reg-set.h"
31
#include "basic-block.h"
32
#include "output.h"
33
#include "expr.h"
34
#include "function.h"
35
#include "diagnostic.h"
36
#include "bitmap.h"
37
#include "pointer-set.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-pass.h"
46
#include "toplev.h"
47
 
48
/* Remove the corresponding arguments from the PHI nodes in E's
49
   destination block and redirect it to DEST.  Return redirected edge.
50
   The list of removed arguments is stored in PENDING_STMT (e).  */
51
 
52
edge
53
ssa_redirect_edge (edge e, basic_block dest)
54
{
55
  tree phi;
56
  tree list = NULL, *last = &list;
57
  tree src, dst, node;
58
 
59
  /* Remove the appropriate PHI arguments in E's destination block.  */
60
  for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
61
    {
62
      if (PHI_ARG_DEF (phi, e->dest_idx) == NULL_TREE)
63
        continue;
64
 
65
      src = PHI_ARG_DEF (phi, e->dest_idx);
66
      dst = PHI_RESULT (phi);
67
      node = build_tree_list (dst, src);
68
      *last = node;
69
      last = &TREE_CHAIN (node);
70
    }
71
 
72
  e = redirect_edge_succ_nodup (e, dest);
73
  PENDING_STMT (e) = list;
74
 
75
  return e;
76
}
77
 
78
/* Add PHI arguments queued in PENDINT_STMT list on edge E to edge
79
   E->dest.  */
80
 
81
void
82
flush_pending_stmts (edge e)
83
{
84
  tree phi, arg;
85
 
86
  if (!PENDING_STMT (e))
87
    return;
88
 
89
  for (phi = phi_nodes (e->dest), arg = PENDING_STMT (e);
90
       phi;
91
       phi = PHI_CHAIN (phi), arg = TREE_CHAIN (arg))
92
    {
93
      tree def = TREE_VALUE (arg);
94
      add_phi_arg (phi, def, e);
95
    }
96
 
97
  PENDING_STMT (e) = NULL;
98
}
99
 
100
/* Return true if SSA_NAME is malformed and mark it visited.
101
 
102
   IS_VIRTUAL is true if this SSA_NAME was found inside a virtual
103
      operand.  */
104
 
105
static bool
106
verify_ssa_name (tree ssa_name, bool is_virtual)
107
{
108
  if (TREE_CODE (ssa_name) != SSA_NAME)
109
    {
110
      error ("expected an SSA_NAME object");
111
      return true;
112
    }
113
 
114
  if (TREE_TYPE (ssa_name) != TREE_TYPE (SSA_NAME_VAR (ssa_name)))
115
    {
116
      error ("type mismatch between an SSA_NAME and its symbol");
117
      return true;
118
    }
119
 
120
  if (SSA_NAME_IN_FREE_LIST (ssa_name))
121
    {
122
      error ("found an SSA_NAME that had been released into the free pool");
123
      return true;
124
    }
125
 
126
  if (is_virtual && is_gimple_reg (ssa_name))
127
    {
128
      error ("found a virtual definition for a GIMPLE register");
129
      return true;
130
    }
131
 
132
  if (!is_virtual && !is_gimple_reg (ssa_name))
133
    {
134
      error ("found a real definition for a non-register");
135
      return true;
136
    }
137
 
138
  if (is_virtual && var_ann (SSA_NAME_VAR (ssa_name))
139
      && get_subvars_for_var (SSA_NAME_VAR (ssa_name)) != NULL)
140
    {
141
      error ("found real variable when subvariables should have appeared");
142
      return true;
143
    }
144
 
145
  return false;
146
}
147
 
148
 
149
/* Return true if the definition of SSA_NAME at block BB is malformed.
150
 
151
   STMT is the statement where SSA_NAME is created.
152
 
153
   DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME
154
      version numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set,
155
      it means that the block in that array slot contains the
156
      definition of SSA_NAME.
157
 
158
   IS_VIRTUAL is true if SSA_NAME is created by a V_MAY_DEF or a
159
      V_MUST_DEF.  */
160
 
161
static bool
162
verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
163
            tree stmt, bool is_virtual)
164
{
165
  if (verify_ssa_name (ssa_name, is_virtual))
166
    goto err;
167
 
168
  if (definition_block[SSA_NAME_VERSION (ssa_name)])
169
    {
170
      error ("SSA_NAME created in two different blocks %i and %i",
171
             definition_block[SSA_NAME_VERSION (ssa_name)]->index, bb->index);
172
      goto err;
173
    }
174
 
175
  definition_block[SSA_NAME_VERSION (ssa_name)] = bb;
176
 
177
  if (SSA_NAME_DEF_STMT (ssa_name) != stmt)
178
    {
179
      error ("SSA_NAME_DEF_STMT is wrong");
180
      fprintf (stderr, "Expected definition statement:\n");
181
      print_generic_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), TDF_VOPS);
182
      fprintf (stderr, "\nActual definition statement:\n");
183
      print_generic_stmt (stderr, stmt, TDF_VOPS);
184
      goto err;
185
    }
186
 
187
  return false;
188
 
189
err:
190
  fprintf (stderr, "while verifying SSA_NAME ");
191
  print_generic_expr (stderr, ssa_name, 0);
192
  fprintf (stderr, " in statement\n");
193
  print_generic_stmt (stderr, stmt, TDF_VOPS);
194
 
195
  return true;
196
}
197
 
198
 
199
/* Return true if the use of SSA_NAME at statement STMT in block BB is
200
   malformed.
201
 
202
   DEF_BB is the block where SSA_NAME was found to be created.
203
 
204
   IDOM contains immediate dominator information for the flowgraph.
205
 
206
   CHECK_ABNORMAL is true if the caller wants to check whether this use
207
      is flowing through an abnormal edge (only used when checking PHI
208
      arguments).
209
 
210
   IS_VIRTUAL is true if SSA_NAME is created by a V_MAY_DEF or a
211
      V_MUST_DEF.
212
 
213
   If NAMES_DEFINED_IN_BB is not NULL, it contains a bitmap of ssa names
214
     that are defined before STMT in basic block BB.  */
215
 
216
static bool
217
verify_use (basic_block bb, basic_block def_bb, use_operand_p use_p,
218
            tree stmt, bool check_abnormal, bool is_virtual,
219
            bitmap names_defined_in_bb)
220
{
221
  bool err = false;
222
  tree ssa_name = USE_FROM_PTR (use_p);
223
 
224
  err = verify_ssa_name (ssa_name, is_virtual);
225
 
226
  if (!TREE_VISITED (ssa_name))
227
    if (verify_imm_links (stderr, ssa_name))
228
      err = true;
229
 
230
  TREE_VISITED (ssa_name) = 1;
231
 
232
  if (IS_EMPTY_STMT (SSA_NAME_DEF_STMT (ssa_name))
233
      && default_def (SSA_NAME_VAR (ssa_name)) == ssa_name)
234
    ; /* Default definitions have empty statements.  Nothing to do.  */
235
  else if (!def_bb)
236
    {
237
      error ("missing definition");
238
      err = true;
239
    }
240
  else if (bb != def_bb
241
           && !dominated_by_p (CDI_DOMINATORS, bb, def_bb))
242
    {
243
      error ("definition in block %i does not dominate use in block %i",
244
             def_bb->index, bb->index);
245
      err = true;
246
    }
247
  else if (bb == def_bb
248
           && names_defined_in_bb != NULL
249
           && !bitmap_bit_p (names_defined_in_bb, SSA_NAME_VERSION (ssa_name)))
250
    {
251
      error ("definition in block %i follows the use", def_bb->index);
252
      err = true;
253
    }
254
 
255
  if (check_abnormal
256
      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssa_name))
257
    {
258
      error ("SSA_NAME_OCCURS_IN_ABNORMAL_PHI should be set");
259
      err = true;
260
    }
261
 
262
  /* Make sure the use is in an appropriate list by checking the previous
263
     element to make sure it's the same.  */
264
  if (use_p->prev == NULL)
265
    {
266
      error ("no immediate_use list");
267
      err = true;
268
    }
269
  else
270
    {
271
      tree listvar ;
272
      if (use_p->prev->use == NULL)
273
        listvar = use_p->prev->stmt;
274
      else
275
        listvar = USE_FROM_PTR (use_p->prev);
276
      if (listvar != ssa_name)
277
        {
278
          error ("wrong immediate use list");
279
          err = true;
280
        }
281
    }
282
 
283
  if (err)
284
    {
285
      fprintf (stderr, "for SSA_NAME: ");
286
      print_generic_expr (stderr, ssa_name, TDF_VOPS);
287
      fprintf (stderr, " in statement:\n");
288
      print_generic_stmt (stderr, stmt, TDF_VOPS);
289
    }
290
 
291
  return err;
292
}
293
 
294
 
295
/* Return true if any of the arguments for PHI node PHI at block BB is
296
   malformed.
297
 
298
   DEFINITION_BLOCK is an array of basic blocks indexed by SSA_NAME version
299
      numbers.  If DEFINITION_BLOCK[SSA_NAME_VERSION] is set, it means that the
300
      block in that array slot contains the definition of SSA_NAME.  */
301
 
302
static bool
303
verify_phi_args (tree phi, basic_block bb, basic_block *definition_block)
304
{
305
  edge e;
306
  bool err = false;
307
  unsigned i, phi_num_args = PHI_NUM_ARGS (phi);
308
 
309
  if (EDGE_COUNT (bb->preds) != phi_num_args)
310
    {
311
      error ("incoming edge count does not match number of PHI arguments");
312
      err = true;
313
      goto error;
314
    }
315
 
316
  for (i = 0; i < phi_num_args; i++)
317
    {
318
      use_operand_p op_p = PHI_ARG_DEF_PTR (phi, i);
319
      tree op = USE_FROM_PTR (op_p);
320
 
321
 
322
      e = EDGE_PRED (bb, i);
323
 
324
      if (op == NULL_TREE)
325
        {
326
          error ("PHI argument is missing for edge %d->%d",
327
                 e->src->index,
328
                 e->dest->index);
329
          err = true;
330
          goto error;
331
        }
332
 
333
      if (TREE_CODE (op) != SSA_NAME && !is_gimple_min_invariant (op))
334
        {
335
          error ("PHI argument is not SSA_NAME, or invariant");
336
          err = true;
337
        }
338
 
339
      if (TREE_CODE (op) == SSA_NAME)
340
        err = verify_use (e->src, definition_block[SSA_NAME_VERSION (op)], op_p,
341
                          phi, e->flags & EDGE_ABNORMAL,
342
                          !is_gimple_reg (PHI_RESULT (phi)),
343
                          NULL);
344
 
345
      if (e->dest != bb)
346
        {
347
          error ("wrong edge %d->%d for PHI argument",
348
                 e->src->index, e->dest->index);
349
          err = true;
350
        }
351
 
352
      if (err)
353
        {
354
          fprintf (stderr, "PHI argument\n");
355
          print_generic_stmt (stderr, op, TDF_VOPS);
356
          goto error;
357
        }
358
    }
359
 
360
error:
361
  if (err)
362
    {
363
      fprintf (stderr, "for PHI node\n");
364
      print_generic_stmt (stderr, phi, TDF_VOPS);
365
    }
366
 
367
 
368
  return err;
369
}
370
 
371
 
372
static void
373
verify_flow_insensitive_alias_info (void)
374
{
375
  tree var;
376
  bitmap visited = BITMAP_ALLOC (NULL);
377
  referenced_var_iterator rvi;
378
 
379
  FOR_EACH_REFERENCED_VAR (var, rvi)
380
    {
381
      size_t j;
382
      var_ann_t ann;
383
      VEC(tree,gc) *may_aliases;
384
      tree alias;
385
 
386
      ann = var_ann (var);
387
      may_aliases = ann->may_aliases;
388
 
389
      for (j = 0; VEC_iterate (tree, may_aliases, j, alias); j++)
390
        {
391
          bitmap_set_bit (visited, DECL_UID (alias));
392
 
393
          if (!may_be_aliased (alias))
394
            {
395
              error ("non-addressable variable inside an alias set");
396
              debug_variable (alias);
397
              goto err;
398
            }
399
        }
400
    }
401
 
402
  FOR_EACH_REFERENCED_VAR (var, rvi)
403
    {
404
      var_ann_t ann;
405
      ann = var_ann (var);
406
 
407
      if (!MTAG_P (var)
408
          && ann->is_aliased
409
          && !bitmap_bit_p (visited, DECL_UID (var)))
410
        {
411
          error ("addressable variable that is aliased but is not in any alias set");
412
          goto err;
413
        }
414
    }
415
 
416
  BITMAP_FREE (visited);
417
  return;
418
 
419
err:
420
  debug_variable (var);
421
  internal_error ("verify_flow_insensitive_alias_info failed");
422
}
423
 
424
 
425
static void
426
verify_flow_sensitive_alias_info (void)
427
{
428
  size_t i;
429
  tree ptr;
430
 
431
  for (i = 1; i < num_ssa_names; i++)
432
    {
433
      tree var;
434
      var_ann_t ann;
435
      struct ptr_info_def *pi;
436
 
437
 
438
      ptr = ssa_name (i);
439
      if (!ptr)
440
        continue;
441
 
442
      /* We only care for pointers that are actually referenced in the
443
         program.  */
444
      if (!POINTER_TYPE_P (TREE_TYPE (ptr)) || !TREE_VISITED (ptr))
445
        continue;
446
 
447
      /* RESULT_DECL is special.  If it's a GIMPLE register, then it
448
         is only written-to only once in the return statement.
449
         Otherwise, aggregate RESULT_DECLs may be written-to more than
450
         once in virtual operands.  */
451
      var = SSA_NAME_VAR (ptr);
452
      if (TREE_CODE (var) == RESULT_DECL
453
          && is_gimple_reg (ptr))
454
        continue;
455
 
456
      pi = SSA_NAME_PTR_INFO (ptr);
457
      if (pi == NULL)
458
        continue;
459
 
460
      ann = var_ann (var);
461
      if (pi->is_dereferenced && !pi->name_mem_tag && !ann->symbol_mem_tag)
462
        {
463
          error ("dereferenced pointers should have a name or a symbol tag");
464
          goto err;
465
        }
466
 
467
      if (pi->name_mem_tag
468
          && (pi->pt_vars == NULL || bitmap_empty_p (pi->pt_vars)))
469
        {
470
          error ("pointers with a memory tag, should have points-to sets");
471
          goto err;
472
        }
473
 
474
      if (pi->value_escapes_p
475
          && pi->name_mem_tag
476
          && !is_call_clobbered (pi->name_mem_tag))
477
        {
478
          error ("pointer escapes but its name tag is not call-clobbered");
479
          goto err;
480
        }
481
    }
482
 
483
  return;
484
 
485
err:
486
  debug_variable (ptr);
487
  internal_error ("verify_flow_sensitive_alias_info failed");
488
}
489
 
490
DEF_VEC_P (bitmap);
491
DEF_VEC_ALLOC_P (bitmap,heap);
492
 
493
/* Verify that all name tags have different points to sets.
494
   This algorithm takes advantage of the fact that every variable with the
495
   same name tag must have the same points-to set.
496
   So we check a single variable for each name tag, and verify that its
497
   points-to set is different from every other points-to set for other name
498
   tags.
499
 
500
   Additionally, given a pointer P_i with name tag NMT and symbol tag
501
   SMT, this function verified the alias set of SMT is a superset of
502
   the alias set of NMT.  */
503
 
504
static void
505
verify_name_tags (void)
506
{
507
  size_t i;
508
  size_t j;
509
  bitmap first, second;
510
  VEC(tree,heap) *name_tag_reps = NULL;
511
  VEC(bitmap,heap) *pt_vars_for_reps = NULL;
512
  bitmap type_aliases = BITMAP_ALLOC (NULL);
513
 
514
  /* First we compute the name tag representatives and their points-to sets.  */
515
  for (i = 0; i < num_ssa_names; i++)
516
    {
517
      struct ptr_info_def *pi;
518
      tree smt, ptr = ssa_name (i);
519
 
520
      if (ptr == NULL_TREE)
521
        continue;
522
 
523
      pi = SSA_NAME_PTR_INFO (ptr);
524
 
525
      if (!TREE_VISITED (ptr)
526
          || !POINTER_TYPE_P (TREE_TYPE (ptr))
527
          || !pi
528
          || !pi->name_mem_tag
529
          || TREE_VISITED (pi->name_mem_tag))
530
        continue;
531
 
532
      TREE_VISITED (pi->name_mem_tag) = 1;
533
 
534
      if (pi->pt_vars == NULL)
535
        continue;
536
 
537
      VEC_safe_push (tree, heap, name_tag_reps, ptr);
538
      VEC_safe_push (bitmap, heap, pt_vars_for_reps, pi->pt_vars);
539
 
540
      /* Verify that alias set of PTR's symbol tag is a superset of the
541
         alias set of PTR's name tag.  */
542
      smt = var_ann (SSA_NAME_VAR (ptr))->symbol_mem_tag;
543
      if (smt)
544
        {
545
          size_t i;
546
          VEC(tree,gc) *aliases = var_ann (smt)->may_aliases;
547
          tree alias;
548
 
549
          bitmap_clear (type_aliases);
550
          for (i = 0; VEC_iterate (tree, aliases, i, alias); i++)
551
            bitmap_set_bit (type_aliases, DECL_UID (alias));
552
 
553
          /* When grouping, we may have added PTR's symbol tag into the
554
             alias set of PTR's name tag.  To prevent a false
555
             positive, pretend that SMT is in its own alias set.  */
556
          bitmap_set_bit (type_aliases, DECL_UID (smt));
557
 
558
          if (bitmap_equal_p (type_aliases, pi->pt_vars))
559
            continue;
560
 
561
          if (!bitmap_intersect_compl_p (type_aliases, pi->pt_vars))
562
            {
563
              error ("alias set of a pointer's symbol tag should be a superset of the corresponding name tag");
564
              debug_variable (smt);
565
              debug_variable (pi->name_mem_tag);
566
              goto err;
567
            }
568
        }
569
    }
570
 
571
  /* Now compare all the representative bitmaps with all other representative
572
     bitmaps, to verify that they are all different.  */
573
  for (i = 0; VEC_iterate (bitmap, pt_vars_for_reps, i, first); i++)
574
    {
575
       for (j = i + 1; VEC_iterate (bitmap, pt_vars_for_reps, j, second); j++)
576
         {
577
           if (bitmap_equal_p (first, second))
578
             {
579
               error ("two different pointers with identical points-to sets but different name tags");
580
               debug_variable (VEC_index (tree, name_tag_reps, j));
581
               goto err;
582
             }
583
         }
584
    }
585
 
586
  /* Lastly, clear out the visited flags.  */
587
  for (i = 0; i < num_ssa_names; i++)
588
    {
589
      if (ssa_name (i))
590
        {
591
          tree ptr = ssa_name (i);
592
          struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
593
          if (!TREE_VISITED (ptr)
594
              || !POINTER_TYPE_P (TREE_TYPE (ptr))
595
              || !pi
596
              || !pi->name_mem_tag)
597
            continue;
598
          TREE_VISITED (pi->name_mem_tag) = 0;
599
        }
600
    }
601
 
602
  /* We do not have to free the bitmaps or trees in the vectors, as
603
     they are not owned by us.  */
604
  VEC_free (bitmap, heap, pt_vars_for_reps);
605
  VEC_free (tree, heap, name_tag_reps);
606
  BITMAP_FREE (type_aliases);
607
  return;
608
 
609
err:
610
  debug_variable (VEC_index (tree, name_tag_reps, i));
611
  internal_error ("verify_name_tags failed");
612
}
613
 
614
 
615
/* Verify the consistency of call clobbering information.  */
616
static void
617
verify_call_clobbering (void)
618
{
619
  unsigned int i;
620
  bitmap_iterator bi;
621
  tree var;
622
  referenced_var_iterator rvi;
623
 
624
  /* At all times, the result of the DECL_CALL_CLOBBERED flag should
625
     match the result of the call_clobbered_vars bitmap.  Verify both
626
     that everything in call_clobbered_vars is marked
627
     DECL_CALL_CLOBBERED, and that everything marked
628
     DECL_CALL_CLOBBERED is in call_clobbered_vars.  */
629
  EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
630
    {
631
      var = referenced_var (i);
632
      if (!MTAG_P (var) && !DECL_CALL_CLOBBERED (var))
633
        {
634
          error ("variable in call_clobbered_vars but not marked DECL_CALL_CLOBBERED");
635
          debug_variable (var);
636
          goto err;
637
        }
638
    }
639
  FOR_EACH_REFERENCED_VAR (var, rvi)
640
    {
641
      if (!MTAG_P (var) && DECL_CALL_CLOBBERED (var)
642
          && !bitmap_bit_p (call_clobbered_vars, DECL_UID (var)))
643
        {
644
          error ("variable marked DECL_CALL_CLOBBERED but not in call_clobbered_vars bitmap.");
645
          debug_variable (var);
646
          goto err;
647
        }
648
    }
649
  return;
650
 
651
 err:
652
    internal_error ("verify_call_clobbering failed");
653
}
654
 
655
/* Verify the consistency of aliasing information.  */
656
 
657
static void
658
verify_alias_info (void)
659
{
660
  verify_flow_sensitive_alias_info ();
661
  verify_name_tags ();
662
  verify_call_clobbering ();
663
  verify_flow_insensitive_alias_info ();
664
}
665
 
666
 
667
/* Verify common invariants in the SSA web.
668
   TODO: verify the variable annotations.  */
669
 
670
void
671
verify_ssa (bool check_modified_stmt)
672
{
673
  size_t i;
674
  basic_block bb;
675
  basic_block *definition_block = XCNEWVEC (basic_block, num_ssa_names);
676
  ssa_op_iter iter;
677
  tree op;
678
  enum dom_state orig_dom_state = dom_computed[CDI_DOMINATORS];
679
  bitmap names_defined_in_bb = BITMAP_ALLOC (NULL);
680
 
681
  gcc_assert (!need_ssa_update_p ());
682
 
683
  verify_stmts ();
684
 
685
  timevar_push (TV_TREE_SSA_VERIFY);
686
 
687
  /* Keep track of SSA names present in the IL.  */
688
  for (i = 1; i < num_ssa_names; i++)
689
    {
690
      tree name = ssa_name (i);
691
      if (name)
692
        {
693
          tree stmt;
694
          TREE_VISITED (name) = 0;
695
 
696
          stmt = SSA_NAME_DEF_STMT (name);
697
          if (!IS_EMPTY_STMT (stmt))
698
            {
699
              basic_block bb = bb_for_stmt (stmt);
700
              verify_def (bb, definition_block,
701
                          name, stmt, !is_gimple_reg (name));
702
 
703
            }
704
        }
705
    }
706
 
707
  calculate_dominance_info (CDI_DOMINATORS);
708
 
709
  /* Now verify all the uses and make sure they agree with the definitions
710
     found in the previous pass.  */
711
  FOR_EACH_BB (bb)
712
    {
713
      edge e;
714
      tree phi;
715
      edge_iterator ei;
716
      block_stmt_iterator bsi;
717
 
718
      /* Make sure that all edges have a clear 'aux' field.  */
719
      FOR_EACH_EDGE (e, ei, bb->preds)
720
        {
721
          if (e->aux)
722
            {
723
              error ("AUX pointer initialized for edge %d->%d", e->src->index,
724
                      e->dest->index);
725
              goto err;
726
            }
727
        }
728
 
729
      /* Verify the arguments for every PHI node in the block.  */
730
      for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
731
        {
732
          if (verify_phi_args (phi, bb, definition_block))
733
            goto err;
734
          bitmap_set_bit (names_defined_in_bb,
735
                          SSA_NAME_VERSION (PHI_RESULT (phi)));
736
        }
737
 
738
      /* Now verify all the uses and vuses in every statement of the block.  */
739
      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
740
        {
741
          tree stmt = bsi_stmt (bsi);
742
          use_operand_p use_p;
743
 
744
          if (check_modified_stmt && stmt_modified_p (stmt))
745
            {
746
              error ("stmt (%p) marked modified after optimization pass : ",
747
                     (void *)stmt);
748
              print_generic_stmt (stderr, stmt, TDF_VOPS);
749
              goto err;
750
            }
751
 
752
          if (TREE_CODE (stmt) == MODIFY_EXPR
753
              && TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
754
            {
755
              tree lhs, base_address;
756
 
757
              lhs = TREE_OPERAND (stmt, 0);
758
              base_address = get_base_address (lhs);
759
 
760
              if (base_address
761
                  && SSA_VAR_P (base_address)
762
                  && ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF))
763
                {
764
                  error ("statement makes a memory store, but has no "
765
                         "V_MAY_DEFS nor V_MUST_DEFS");
766
                  print_generic_stmt (stderr, stmt, TDF_VOPS);
767
                  goto err;
768
                }
769
            }
770
 
771
          FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
772
                                    SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
773
            {
774
              op = USE_FROM_PTR (use_p);
775
              if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
776
                              use_p, stmt, false, !is_gimple_reg (op),
777
                              names_defined_in_bb))
778
                goto err;
779
            }
780
 
781
          FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
782
            bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
783
        }
784
 
785
      bitmap_clear (names_defined_in_bb);
786
    }
787
 
788
  /* Finally, verify alias information.  */
789
  verify_alias_info ();
790
 
791
  free (definition_block);
792
 
793
  /* Restore the dominance information to its prior known state, so
794
     that we do not perturb the compiler's subsequent behavior.  */
795
  if (orig_dom_state == DOM_NONE)
796
    free_dominance_info (CDI_DOMINATORS);
797
  else
798
    dom_computed[CDI_DOMINATORS] = orig_dom_state;
799
 
800
  BITMAP_FREE (names_defined_in_bb);
801
  timevar_pop (TV_TREE_SSA_VERIFY);
802
  return;
803
 
804
err:
805
  internal_error ("verify_ssa failed");
806
}
807
 
808
/* Return true if the uid in both int tree maps are equal.  */
809
 
810
int
811
int_tree_map_eq (const void *va, const void *vb)
812
{
813
  const struct int_tree_map *a = (const struct int_tree_map *) va;
814
  const struct int_tree_map *b = (const struct int_tree_map *) vb;
815
  return (a->uid == b->uid);
816
}
817
 
818
/* Hash a UID in a int_tree_map.  */
819
 
820
unsigned int
821
int_tree_map_hash (const void *item)
822
{
823
  return ((const struct int_tree_map *)item)->uid;
824
}
825
 
826
 
827
/* Initialize global DFA and SSA structures.  */
828
 
829
void
830
init_tree_ssa (void)
831
{
832
  referenced_vars = htab_create_ggc (20, int_tree_map_hash,
833
                                     int_tree_map_eq, NULL);
834
  default_defs = htab_create_ggc (20, int_tree_map_hash, int_tree_map_eq, NULL);
835
  call_clobbered_vars = BITMAP_ALLOC (NULL);
836
  addressable_vars = BITMAP_ALLOC (NULL);
837
  init_alias_heapvars ();
838
  init_ssanames ();
839
  init_phinodes ();
840
  global_var = NULL_TREE;
841
  aliases_computed_p = false;
842
}
843
 
844
 
845
/* Deallocate memory associated with SSA data structures for FNDECL.  */
846
 
847
void
848
delete_tree_ssa (void)
849
{
850
  size_t i;
851
  basic_block bb;
852
  block_stmt_iterator bsi;
853
  referenced_var_iterator rvi;
854
  tree var;
855
 
856
  /* Release any ssa_names still in use.  */
857
  for (i = 0; i < num_ssa_names; i++)
858
    {
859
      tree var = ssa_name (i);
860
      if (var && TREE_CODE (var) == SSA_NAME)
861
        {
862
          SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
863
          SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
864
        }
865
      release_ssa_name (var);
866
    }
867
 
868
  /* Remove annotations from every tree in the function.  */
869
  FOR_EACH_BB (bb)
870
    {
871
      for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
872
        {
873
          tree stmt = bsi_stmt (bsi);
874
          stmt_ann_t ann = get_stmt_ann (stmt);
875
 
876
          free_ssa_operands (&ann->operands);
877
          ann->addresses_taken = 0;
878
          mark_stmt_modified (stmt);
879
        }
880
      set_phi_nodes (bb, NULL);
881
    }
882
 
883
  /* Remove annotations from every referenced variable.  */
884
  FOR_EACH_REFERENCED_VAR (var, rvi)
885
    {
886
      ggc_free (var->common.ann);
887
      var->common.ann = NULL;
888
    }
889
  htab_delete (referenced_vars);
890
  referenced_vars = NULL;
891
 
892
  fini_ssanames ();
893
  fini_phinodes ();
894
 
895
  global_var = NULL_TREE;
896
 
897
  htab_delete (default_defs);
898
  BITMAP_FREE (call_clobbered_vars);
899
  call_clobbered_vars = NULL;
900
  BITMAP_FREE (addressable_vars);
901
  addressable_vars = NULL;
902
  modified_noreturn_calls = NULL;
903
  aliases_computed_p = false;
904
  delete_alias_heapvars ();
905
  gcc_assert (!need_ssa_update_p ());
906
}
907
 
908
 
909
/* Return true if the conversion from INNER_TYPE to OUTER_TYPE is a
910
   useless type conversion, otherwise return false.  */
911
 
912
bool
913
tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
914
{
915
  if (inner_type == outer_type)
916
    return true;
917
 
918
  /* Changes in machine mode are never useless conversions.  */
919
  if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type))
920
    return false;
921
 
922
  /* If the inner and outer types are effectively the same, then
923
     strip the type conversion and enter the equivalence into
924
     the table.  */
925
  if (lang_hooks.types_compatible_p (inner_type, outer_type))
926
    return true;
927
 
928
  /* If both types are pointers and the outer type is a (void *), then
929
     the conversion is not necessary.  The opposite is not true since
930
     that conversion would result in a loss of information if the
931
     equivalence was used.  Consider an indirect function call where
932
     we need to know the exact type of the function to correctly
933
     implement the ABI.  */
934
  else if (POINTER_TYPE_P (inner_type)
935
           && POINTER_TYPE_P (outer_type)
936
           && TYPE_REF_CAN_ALIAS_ALL (inner_type)
937
              == TYPE_REF_CAN_ALIAS_ALL (outer_type)
938
           && TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
939
    return true;
940
 
941
  /* Don't lose casts between pointers to volatile and non-volatile
942
     qualified types.  Doing so would result in changing the semantics
943
     of later accesses.  */
944
  else if (POINTER_TYPE_P (inner_type)
945
           && POINTER_TYPE_P (outer_type)
946
           && TYPE_VOLATILE (TREE_TYPE (outer_type))
947
              != TYPE_VOLATILE (TREE_TYPE (inner_type)))
948
    return false;
949
 
950
  /* Pointers/references are equivalent if their pointed to types
951
     are effectively the same.  This allows to strip conversions between
952
     pointer types with different type qualifiers.  */
953
  else if (POINTER_TYPE_P (inner_type)
954
           && POINTER_TYPE_P (outer_type)
955
           && TYPE_REF_CAN_ALIAS_ALL (inner_type)
956
              == TYPE_REF_CAN_ALIAS_ALL (outer_type)
957
           && lang_hooks.types_compatible_p (TREE_TYPE (inner_type),
958
                                             TREE_TYPE (outer_type)))
959
    return true;
960
 
961
  /* If both the inner and outer types are integral types, then the
962
     conversion is not necessary if they have the same mode and
963
     signedness and precision, and both or neither are boolean.  Some
964
     code assumes an invariant that boolean types stay boolean and do
965
     not become 1-bit bit-field types.  Note that types with precision
966
     not using all bits of the mode (such as bit-field types in C)
967
     mean that testing of precision is necessary.  */
968
  else if (INTEGRAL_TYPE_P (inner_type)
969
           && INTEGRAL_TYPE_P (outer_type)
970
           && TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
971
           && TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type)
972
           && simple_cst_equal (TYPE_MAX_VALUE (inner_type), TYPE_MAX_VALUE (outer_type))
973
           && simple_cst_equal (TYPE_MIN_VALUE (inner_type), TYPE_MIN_VALUE (outer_type)))
974
    {
975
      bool first_boolean = (TREE_CODE (inner_type) == BOOLEAN_TYPE);
976
      bool second_boolean = (TREE_CODE (outer_type) == BOOLEAN_TYPE);
977
      if (first_boolean == second_boolean)
978
        return true;
979
    }
980
 
981
  /* Recurse for complex types.  */
982
  else if (TREE_CODE (inner_type) == COMPLEX_TYPE
983
           && TREE_CODE (outer_type) == COMPLEX_TYPE
984
           && tree_ssa_useless_type_conversion_1 (TREE_TYPE (outer_type),
985
                                                  TREE_TYPE (inner_type)))
986
    return true;
987
 
988
  return false;
989
}
990
 
991
/* Return true if EXPR is a useless type conversion, otherwise return
992
   false.  */
993
 
994
bool
995
tree_ssa_useless_type_conversion (tree expr)
996
{
997
  /* If we have an assignment that merely uses a NOP_EXPR to change
998
     the top of the RHS to the type of the LHS and the type conversion
999
     is "safe", then strip away the type conversion so that we can
1000
     enter LHS = RHS into the const_and_copies table.  */
1001
  if (TREE_CODE (expr) == NOP_EXPR || TREE_CODE (expr) == CONVERT_EXPR
1002
      || TREE_CODE (expr) == VIEW_CONVERT_EXPR
1003
      || TREE_CODE (expr) == NON_LVALUE_EXPR)
1004
    return tree_ssa_useless_type_conversion_1 (TREE_TYPE (expr),
1005
                                               TREE_TYPE (TREE_OPERAND (expr,
1006
                                                                        0)));
1007
 
1008
 
1009
  return false;
1010
}
1011
 
1012
/* Returns true if statement STMT may read memory.  */
1013
 
1014
bool
1015
stmt_references_memory_p (tree stmt)
1016
{
1017
  stmt_ann_t ann = stmt_ann (stmt);
1018
 
1019
  if (ann->has_volatile_ops)
1020
    return true;
1021
 
1022
  return (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS));
1023
}
1024
 
1025
/* Internal helper for walk_use_def_chains.  VAR, FN and DATA are as
1026
   described in walk_use_def_chains.
1027
 
1028
   VISITED is a pointer set used to mark visited SSA_NAMEs to avoid
1029
      infinite loops.  We used to have a bitmap for this to just mark
1030
      SSA versions we had visited.  But non-sparse bitmaps are way too
1031
      expensive, while sparse bitmaps may cause quadratic behavior.
1032
 
1033
   IS_DFS is true if the caller wants to perform a depth-first search
1034
      when visiting PHI nodes.  A DFS will visit each PHI argument and
1035
      call FN after each one.  Otherwise, all the arguments are
1036
      visited first and then FN is called with each of the visited
1037
      arguments in a separate pass.  */
1038
 
1039
static bool
1040
walk_use_def_chains_1 (tree var, walk_use_def_chains_fn fn, void *data,
1041
                       struct pointer_set_t *visited, bool is_dfs)
1042
{
1043
  tree def_stmt;
1044
 
1045
  if (pointer_set_insert (visited, var))
1046
    return false;
1047
 
1048
  def_stmt = SSA_NAME_DEF_STMT (var);
1049
 
1050
  if (TREE_CODE (def_stmt) != PHI_NODE)
1051
    {
1052
      /* If we reached the end of the use-def chain, call FN.  */
1053
      return fn (var, def_stmt, data);
1054
    }
1055
  else
1056
    {
1057
      int i;
1058
 
1059
      /* When doing a breadth-first search, call FN before following the
1060
         use-def links for each argument.  */
1061
      if (!is_dfs)
1062
        for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
1063
          if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
1064
            return true;
1065
 
1066
      /* Follow use-def links out of each PHI argument.  */
1067
      for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
1068
        {
1069
          tree arg = PHI_ARG_DEF (def_stmt, i);
1070
          if (TREE_CODE (arg) == SSA_NAME
1071
              && walk_use_def_chains_1 (arg, fn, data, visited, is_dfs))
1072
            return true;
1073
        }
1074
 
1075
      /* When doing a depth-first search, call FN after following the
1076
         use-def links for each argument.  */
1077
      if (is_dfs)
1078
        for (i = 0; i < PHI_NUM_ARGS (def_stmt); i++)
1079
          if (fn (PHI_ARG_DEF (def_stmt, i), def_stmt, data))
1080
            return true;
1081
    }
1082
 
1083
  return false;
1084
}
1085
 
1086
 
1087
 
1088
/* Walk use-def chains starting at the SSA variable VAR.  Call
1089
   function FN at each reaching definition found.  FN takes three
1090
   arguments: VAR, its defining statement (DEF_STMT) and a generic
1091
   pointer to whatever state information that FN may want to maintain
1092
   (DATA).  FN is able to stop the walk by returning true, otherwise
1093
   in order to continue the walk, FN should return false.
1094
 
1095
   Note, that if DEF_STMT is a PHI node, the semantics are slightly
1096
   different.  The first argument to FN is no longer the original
1097
   variable VAR, but the PHI argument currently being examined.  If FN
1098
   wants to get at VAR, it should call PHI_RESULT (PHI).
1099
 
1100
   If IS_DFS is true, this function will:
1101
 
1102
        1- walk the use-def chains for all the PHI arguments, and,
1103
        2- call (*FN) (ARG, PHI, DATA) on all the PHI arguments.
1104
 
1105
   If IS_DFS is false, the two steps above are done in reverse order
1106
   (i.e., a breadth-first search).  */
1107
 
1108
 
1109
void
1110
walk_use_def_chains (tree var, walk_use_def_chains_fn fn, void *data,
1111
                     bool is_dfs)
1112
{
1113
  tree def_stmt;
1114
 
1115
  gcc_assert (TREE_CODE (var) == SSA_NAME);
1116
 
1117
  def_stmt = SSA_NAME_DEF_STMT (var);
1118
 
1119
  /* We only need to recurse if the reaching definition comes from a PHI
1120
     node.  */
1121
  if (TREE_CODE (def_stmt) != PHI_NODE)
1122
    (*fn) (var, def_stmt, data);
1123
  else
1124
    {
1125
      struct pointer_set_t *visited = pointer_set_create ();
1126
      walk_use_def_chains_1 (var, fn, data, visited, is_dfs);
1127
      pointer_set_destroy (visited);
1128
    }
1129
}
1130
 
1131
 
1132
/* Emit warnings for uninitialized variables.  This is done in two passes.
1133
 
1134
   The first pass notices real uses of SSA names with default definitions.
1135
   Such uses are unconditionally uninitialized, and we can be certain that
1136
   such a use is a mistake.  This pass is run before most optimizations,
1137
   so that we catch as many as we can.
1138
 
1139
   The second pass follows PHI nodes to find uses that are potentially
1140
   uninitialized.  In this case we can't necessarily prove that the use
1141
   is really uninitialized.  This pass is run after most optimizations,
1142
   so that we thread as many jumps and possible, and delete as much dead
1143
   code as possible, in order to reduce false positives.  We also look
1144
   again for plain uninitialized variables, since optimization may have
1145
   changed conditionally uninitialized to unconditionally uninitialized.  */
1146
 
1147
/* Emit a warning for T, an SSA_NAME, being uninitialized.  The exact
1148
   warning text is in MSGID and LOCUS may contain a location or be null.  */
1149
 
1150
static void
1151
warn_uninit (tree t, const char *gmsgid, void *data)
1152
{
1153
  tree var = SSA_NAME_VAR (t);
1154
  tree def = SSA_NAME_DEF_STMT (t);
1155
  tree context = (tree) data;
1156
  location_t *locus, *fun_locus;
1157
 
1158
  /* Default uses (indicated by an empty definition statement),
1159
     are uninitialized.  */
1160
  if (!IS_EMPTY_STMT (def))
1161
    return;
1162
 
1163
  /* Except for PARMs of course, which are always initialized.  */
1164
  if (TREE_CODE (var) == PARM_DECL)
1165
    return;
1166
 
1167
  /* Hard register variables get their initial value from the ether.  */
1168
  if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var))
1169
    return;
1170
 
1171
  /* TREE_NO_WARNING either means we already warned, or the front end
1172
     wishes to suppress the warning.  */
1173
  if (TREE_NO_WARNING (var))
1174
    return;
1175
 
1176
  locus = (context != NULL && EXPR_HAS_LOCATION (context)
1177
           ? EXPR_LOCUS (context)
1178
           : &DECL_SOURCE_LOCATION (var));
1179
  warning (0, gmsgid, locus, var);
1180
  fun_locus = &DECL_SOURCE_LOCATION (cfun->decl);
1181
  if (locus->file != fun_locus->file
1182
      || locus->line < fun_locus->line
1183
      || locus->line > cfun->function_end_locus.line)
1184
    inform ("%J%qD was declared here", var, var);
1185
 
1186
  TREE_NO_WARNING (var) = 1;
1187
}
1188
 
1189
/* Called via walk_tree, look for SSA_NAMEs that have empty definitions
1190
   and warn about them.  */
1191
 
1192
static tree
1193
warn_uninitialized_var (tree *tp, int *walk_subtrees, void *data)
1194
{
1195
  tree t = *tp;
1196
 
1197
  switch (TREE_CODE (t))
1198
    {
1199
    case SSA_NAME:
1200
      /* We only do data flow with SSA_NAMEs, so that's all we
1201
         can warn about.  */
1202
      warn_uninit (t, "%H%qD is used uninitialized in this function", data);
1203
      *walk_subtrees = 0;
1204
      break;
1205
 
1206
    case REALPART_EXPR:
1207
    case IMAGPART_EXPR:
1208
      /* The total store transformation performed during gimplification
1209
         creates uninitialized variable uses.  If all is well, these will
1210
         be optimized away, so don't warn now.  */
1211
      if (TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME)
1212
        *walk_subtrees = 0;
1213
      break;
1214
 
1215
    default:
1216
      if (IS_TYPE_OR_DECL_P (t))
1217
        *walk_subtrees = 0;
1218
      break;
1219
    }
1220
 
1221
  return NULL_TREE;
1222
}
1223
 
1224
/* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
1225
   and warn about them.  */
1226
 
1227
static void
1228
warn_uninitialized_phi (tree phi)
1229
{
1230
  int i, n = PHI_NUM_ARGS (phi);
1231
 
1232
  /* Don't look at memory tags.  */
1233
  if (!is_gimple_reg (PHI_RESULT (phi)))
1234
    return;
1235
 
1236
  for (i = 0; i < n; ++i)
1237
    {
1238
      tree op = PHI_ARG_DEF (phi, i);
1239
      if (TREE_CODE (op) == SSA_NAME)
1240
        warn_uninit (op, "%H%qD may be used uninitialized in this function",
1241
                     NULL);
1242
    }
1243
}
1244
 
1245
static unsigned int
1246
execute_early_warn_uninitialized (void)
1247
{
1248
  block_stmt_iterator bsi;
1249
  basic_block bb;
1250
 
1251
  FOR_EACH_BB (bb)
1252
    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
1253
      {
1254
        tree context = bsi_stmt (bsi);
1255
        walk_tree (bsi_stmt_ptr (bsi), warn_uninitialized_var,
1256
                   context, NULL);
1257
      }
1258
  return 0;
1259
}
1260
 
1261
static unsigned int
1262
execute_late_warn_uninitialized (void)
1263
{
1264
  basic_block bb;
1265
  tree phi;
1266
 
1267
  /* Re-do the plain uninitialized variable check, as optimization may have
1268
     straightened control flow.  Do this first so that we don't accidentally
1269
     get a "may be" warning when we'd have seen an "is" warning later.  */
1270
  execute_early_warn_uninitialized ();
1271
 
1272
  FOR_EACH_BB (bb)
1273
    for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
1274
      warn_uninitialized_phi (phi);
1275
  return 0;
1276
}
1277
 
1278
static bool
1279
gate_warn_uninitialized (void)
1280
{
1281
  return warn_uninitialized != 0;
1282
}
1283
 
1284
struct tree_opt_pass pass_early_warn_uninitialized =
1285
{
1286
  NULL,                                 /* name */
1287
  gate_warn_uninitialized,              /* gate */
1288
  execute_early_warn_uninitialized,     /* execute */
1289
  NULL,                                 /* sub */
1290
  NULL,                                 /* next */
1291
  0,                                     /* static_pass_number */
1292
  0,                                     /* tv_id */
1293
  PROP_ssa,                             /* properties_required */
1294
  0,                                     /* properties_provided */
1295
  0,                                     /* properties_destroyed */
1296
  0,                                     /* todo_flags_start */
1297
  0,                                    /* todo_flags_finish */
1298
 
1299
};
1300
 
1301
struct tree_opt_pass pass_late_warn_uninitialized =
1302
{
1303
  NULL,                                 /* name */
1304
  gate_warn_uninitialized,              /* gate */
1305
  execute_late_warn_uninitialized,      /* execute */
1306
  NULL,                                 /* sub */
1307
  NULL,                                 /* next */
1308
  0,                                     /* static_pass_number */
1309
  0,                                     /* tv_id */
1310
  PROP_ssa,                             /* properties_required */
1311
  0,                                     /* properties_provided */
1312
  0,                                     /* properties_destroyed */
1313
  0,                                     /* todo_flags_start */
1314
  0,                                    /* todo_flags_finish */
1315
 
1316
};
1317
 

powered by: WebSVN 2.1.0

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