rta.c 16.5 KB
Newer Older
Florian Liekweg's avatar
Florian Liekweg committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* -*- c -*- */

/*
 * Project:     libFIRM
 * File name:   ir/ana/rta.c
 * Purpose:     Intraprozedural analyses to improve the call graph estimate.
 * Author:      Florian
 * Modified by:
 * Created:     09.06.2002
 * CVS-ID:      $$
 * Copyright:   (c) 1999-2004 Universitt Karlsruhe
 * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
 */

/**
16
nn * Intraprozedurale Analyse zur Abschtzung der Aufrufrelation. Es
Florian Liekweg's avatar
Florian Liekweg committed
17
18
19
20
 * die Menge der instantiierten Klassen bestimmt, und daraus existierende Methoden
 * bestimmt.
 */

21
22
23
24
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

Florian Liekweg's avatar
Florian Liekweg committed
25
26
#include "rta.h"

27
#include <stdlib.h>
Florian Liekweg's avatar
Florian Liekweg committed
28

29
30
#include "irnode_t.h"
#include "irprog.h"
Florian Liekweg's avatar
Florian Liekweg committed
31

32
33
#include "eset.h"
#include "irgwalk.h"
34
35
36
#include "irgmod.h"
#include "irvrfy.h"
#include "trvrfy.h"
Florian Liekweg's avatar
Florian Liekweg committed
37

38
39
# define TRUE 1
# define FALSE 0
Florian Liekweg's avatar
Florian Liekweg committed
40

41
42
43
44
/* base data */
static eset *_live_classes   = NULL;
static eset *_live_fields    = NULL;
static eset *_called_methods = NULL;
Florian Liekweg's avatar
Florian Liekweg committed
45
46

/* cache computed results */
47
48
static eset *_live_graphs    = NULL;
static eset *_dead_graphs    = NULL;
Florian Liekweg's avatar
Florian Liekweg committed
49

50
51
52
/**
   Initialise the static data structures.
*/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
53
static void init_tables (void)
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{
  _live_classes   = eset_create ();
  _live_fields    = eset_create ();
  _called_methods = eset_create ();

  _live_graphs = eset_create ();
  _dead_graphs = eset_create ();

  if (get_irp_main_irg ()) {
    eset_insert (_live_graphs, get_irp_main_irg ());
  }

  if (get_glob_type ()) {
    eset_insert (_live_classes, get_glob_type ());
  }
}

Florian Liekweg's avatar
Florian Liekweg committed
71
/**
72
73
   Enter all method and field accesses and all class allocations into
   our tables.
Florian Liekweg's avatar
Florian Liekweg committed
74
*/
Florian Liekweg's avatar
Florian Liekweg committed
75
76
77
78
static void rta_act (ir_node *node, void *env)
{
  opcode op = get_irn_opcode (node);

79
  if (iro_Call == op) {         /* CALL */
Florian Liekweg's avatar
Florian Liekweg committed
80
81
82
83
    entity *ent = NULL;

    ir_node *ptr = get_Call_ptr (node);

84
    if (iro_Sel == get_irn_opcode (ptr)) { /* CALL SEL */
Florian Liekweg's avatar
Florian Liekweg committed
85
      ent = get_Sel_entity (ptr);
86
    } else if (iro_Const == get_irn_opcode (ptr)) { /* CALL CONST */
Florian Liekweg's avatar
Florian Liekweg committed
87
      ent = get_tarval_entity (get_Const_tarval (ptr));
Florian Liekweg's avatar
Florian Liekweg committed
88

89
    } else if (iro_SymConst == get_irn_opcode (ptr)) { /* CALL SYMCONST */
90
91
92
93
      /* If this SymConst refers to a method the method is external_visible
	 and therefore must be considered executed anyways. */
      //dump_ir_block_graph(get_irn_irg(ptr));
      //assert (ent && "couldn't determine entity of call to symConst");
94
    }
Florian Liekweg's avatar
Florian Liekweg committed
95

Florian Liekweg's avatar
Florian Liekweg committed
96
    if (ent) {
97
      eset_insert (_called_methods, ent);
Florian Liekweg's avatar
Florian Liekweg committed
98
    }
99
  } else if (iro_Load  == op) { /* LOAD */
Florian Liekweg's avatar
Florian Liekweg committed
100
101
102
103
104
105
106
    ir_node *ptr = get_Load_ptr (node);
    entity  *ent = NULL;

    if (iro_Sel == get_irn_opcode (ptr)) {
      ent = get_Sel_entity (ptr);
    }
    if (ent) {
107
      eset_insert (_live_fields, ent);
Florian Liekweg's avatar
Florian Liekweg committed
108
    }
109
  } else  if (iro_Store == op) { /* STORE */
Florian Liekweg's avatar
Florian Liekweg committed
110
111
112
113
114
115
116
    ir_node *ptr = get_Store_ptr (node);
    entity  *ent = NULL;

    if (iro_Sel == get_irn_opcode (ptr)) {
      ent = get_Sel_entity (ptr);
    }
    if (ent) {
117
      eset_insert (_live_fields, ent);
Florian Liekweg's avatar
Florian Liekweg committed
118
    }
119
  } else if (iro_Alloc == op) { /* ALLOC */
Florian Liekweg's avatar
Florian Liekweg committed
120
    type *type = get_Alloc_type (node);
Florian Liekweg's avatar
Florian Liekweg committed
121

122
    eset_insert (_live_classes, type);
Florian Liekweg's avatar
Florian Liekweg committed
123
124
125
  }
}

Florian Liekweg's avatar
Florian Liekweg committed
126
/**
127
128
   Traverse the given graph to collect method and field accesses and
   object allocations.
Florian Liekweg's avatar
Florian Liekweg committed
129
*/
Florian Liekweg's avatar
Florian Liekweg committed
130
131
static void rta_fill_graph (ir_graph* graph)
{
132
  if (NULL != graph) {
Götz Lindenmaier's avatar
Götz Lindenmaier committed
133
134
    if (NULL != get_irg_end (graph)) {
      current_ir_graph = graph;
135

Götz Lindenmaier's avatar
Götz Lindenmaier committed
136
      irg_walk (get_irg_end (graph), rta_act, NULL, NULL);
137
138
    }
  }
Florian Liekweg's avatar
Florian Liekweg committed
139
140
}

141
142
143
144
/**
   Check whether the given graph is alive based on the contents of the
   given esets.
*/
145
146
147
148
149
150
151
152
153
154
static int is_alive (ir_graph *graph, eset *live_graphs, eset *dead_graphs)
{
  if (eset_contains (live_graphs, graph)) {
    return (TRUE);
  }

  if (eset_contains (dead_graphs, graph)) {
    return (FALSE);
  }

155
  assert (0 && "graph neither live not dead (shouldn't happen)");
156
157
}

Florian Liekweg's avatar
Florian Liekweg committed
158
/**
159
160
161
   Traverse all graphs to collect method and field accesses and object allocations.

   @param rerun Whether to rely on is_alive in a second run
Florian Liekweg's avatar
Florian Liekweg committed
162
*/
163
static void rta_fill_all (int rerun)
Florian Liekweg's avatar
Florian Liekweg committed
164
165
{
  int i;
166
  int old_ip_view = interprocedural_view;
167
168
  eset *live_graphs = NULL;
  eset *dead_graphs = NULL;
Florian Liekweg's avatar
Florian Liekweg committed
169

170
  interprocedural_view = 0;     /* save this for later */
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191

  if (rerun) {
    int n_graphs = get_irp_n_irgs ();

    /* force all graphs to be entered in either live_graphs or dead_graphs */
    for (i = 0; i < n_graphs; i ++) {
      rta_is_alive_graph (get_irp_irg (i));
    }

    /* remember existing infos for later */
    live_graphs = _live_graphs;
    dead_graphs = _dead_graphs;

    /* ensure that live_graphs and dead_graphs aren't deallocated by rta_cleanup */
    _live_graphs = NULL;
    _dead_graphs = NULL;

    rta_cleanup ();
    init_tables ();
  }

192
  /* Consider all graphs, possibly taking into account existing infos */
Florian Liekweg's avatar
Florian Liekweg committed
193
  for (i = 0; i < get_irp_n_irgs(); i++) {
194
195
    ir_graph *graph = get_irp_irg (i);

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
    /* Need to take care of graphs that are externally
       visible. Pretend that they are called: */
    entity *ent = get_irg_entity (graph);
    if (visibility_local != get_entity_visibility (ent)) {
      eset_insert (_called_methods, ent);

      if (get_entity_irg (ent)) {
        eset_insert (_live_graphs, get_entity_irg (ent));
      }

      eset_insert (_live_classes, get_entity_owner (ent));
    }

    /* now check the graph */
    if (rerun) {
      if (is_alive (graph, live_graphs, dead_graphs)) {
        rta_fill_graph (graph);
      } else {
        /* nothing (except debugging printf's :-) */
      }
    } else {
217
218
      rta_fill_graph (graph);
    }
Florian Liekweg's avatar
Florian Liekweg committed
219
  }
220
221
222
223
224
225
226

  if (rerun) {
    /* clean up the tables that we have retained */
    eset_destroy (live_graphs);
    eset_destroy (dead_graphs);
  }

227
  interprocedural_view = old_ip_view; /* cover up our traces */
Florian Liekweg's avatar
Florian Liekweg committed
228
229
}

Florian Liekweg's avatar
Florian Liekweg committed
230
231
232
233
234
/**
   Find out whether the given method could be the target of a
   polymorphic call.
*/
static int is_call_target (const entity *method)
Florian Liekweg's avatar
Florian Liekweg committed
235
{
236
237
238
239
240
241
242
  int is_target = FALSE;
  int i;
  int n_over;

  /* The method could be the target of a polymorphic call if it is
     called or if it overrides a method that is called. */

Florian Liekweg's avatar
Florian Liekweg committed
243
  if (eset_contains (_called_methods, (entity*) method)) {
244
245
246
    return (TRUE);
  }

Florian Liekweg's avatar
Florian Liekweg committed
247
248
  /* not called?  check methods in superclass(es) */
  n_over = get_entity_n_overwrittenby ((entity*) method);
249
  for (i = 0; !is_target && (i < n_over); i ++) {
Florian Liekweg's avatar
Florian Liekweg committed
250
    entity *over = get_entity_overwrittenby ((entity*) method, i);
251
252
253
254
    is_target |= is_call_target (over);
  }

  return (is_target);
Florian Liekweg's avatar
Florian Liekweg committed
255
256
}

Florian Liekweg's avatar
Florian Liekweg committed
257
258
259
260
/**
   Given a method, find the firm graph that implements that method.
*/
static ir_graph *get_implementing_graph (const entity *method)
Florian Liekweg's avatar
Florian Liekweg committed
261
{
Florian Liekweg's avatar
Florian Liekweg committed
262
  ir_graph *graph = get_entity_irg ((entity*) method);
Florian Liekweg's avatar
Florian Liekweg committed
263
264
265

  if (NULL == graph) {
    int i;
Florian Liekweg's avatar
Florian Liekweg committed
266
    int n_over = get_entity_n_overwrites ((entity*) method);
Florian Liekweg's avatar
Florian Liekweg committed
267
268

    for (i = 0; (NULL == graph) && (i < n_over); i ++) {
Florian Liekweg's avatar
Florian Liekweg committed
269
      entity *over = get_entity_overwrites ((entity*) method, i);
Florian Liekweg's avatar
Florian Liekweg committed
270
271
272
273
      graph = get_implementing_graph (over);
    }
  }

274
275
276
  /* we *must* always return a graph != NULL, *except* when we're used
     inside remove_irg or force_description */
  /* assert (graph && "no graph"); */
Florian Liekweg's avatar
Florian Liekweg committed
277
278
279
280

  return (graph);
}

Florian Liekweg's avatar
Florian Liekweg committed
281
282
283
284
/**
   Determine whether the give method or one of its overwriter have
   been used in a call to the given graph.
*/
Florian Liekweg's avatar
Florian Liekweg committed
285
286
287
288
289
static int has_live_call (entity *method, ir_graph *graph)
{
  int has_call = FALSE;
  int i, n_over;

Florian Liekweg's avatar
Florian Liekweg committed
290
  /* stop searching if a overwriting method comes with a new graph */
291
292
293
294
295
296
297
  /* if (get_irg_ent (graph) != method) *
     { /* shouldn't we compare GRAPHS here????? *
     return (FALSE);
     }
  */

  if (graph != get_entity_irg (method)) {
Florian Liekweg's avatar
Florian Liekweg committed
298
299
300
    return (FALSE);
  }

Florian Liekweg's avatar
Florian Liekweg committed
301
  /* maybe we're called (possibly through polymorphy)? */
Florian Liekweg's avatar
Florian Liekweg committed
302
303
304
305
  if (is_call_target (method)) {
    return (TRUE);
  }

Florian Liekweg's avatar
Florian Liekweg committed
306
307
  /* maybe we're overwritten by a method that is called? */
  n_over = get_entity_n_overwrittenby ((entity*) method);
Florian Liekweg's avatar
Florian Liekweg committed
308
  for (i = 0; !has_call && (i < n_over); i ++) {
Florian Liekweg's avatar
Florian Liekweg committed
309
    entity *over = get_entity_overwrittenby((entity*) method, i);
Florian Liekweg's avatar
Florian Liekweg committed
310
311
312
313
314
315
    has_call |= has_live_call (over, graph);
  }

  return (has_call);
}

Florian Liekweg's avatar
Florian Liekweg committed
316
317
/**
   Determine whether the given class is live *and* uses the given
Florian Liekweg's avatar
Florian Liekweg committed
318
   graph at some point, or has live subclasses that use the graph.
Florian Liekweg's avatar
Florian Liekweg committed
319
*/
Florian Liekweg's avatar
Florian Liekweg committed
320
321
322
323
324
325
static int has_graph (type *clazz, ir_graph *graph)
{
  int has_the_graph = FALSE;
  int i;
  int n_sub;

326
  if (eset_contains (_live_classes, clazz)) {
Florian Liekweg's avatar
Florian Liekweg committed
327
328
329
330
331
332
333
334
335
336
337
338
339
340
    int n_meth = get_class_n_members (clazz);

    for (i = 0; i < n_meth; i ++) {
      entity *member = get_class_member (clazz, i);
      if (is_method_type (get_entity_type (member))) {
        ir_graph *impl = get_entity_irg (member);

        if (impl == graph) {
          return (TRUE);
        }
      } /* is_method */
    } /* all methods */
  } /* _live_classes.contains (clazz) */

Florian Liekweg's avatar
Florian Liekweg committed
341
  /* our subclasses might be using that graph, no? */
Florian Liekweg's avatar
Florian Liekweg committed
342
343
344
345
346
347
348
349
350
351
  n_sub = get_class_n_subtypes (clazz);
  for (i = 0; !has_the_graph && (i < n_sub); i ++) {
    type *sub = get_class_subtype (clazz, i);

    has_the_graph |= has_graph (sub, graph);
  }

  return (has_the_graph);
}

Florian Liekweg's avatar
Florian Liekweg committed
352
/**
Florian Liekweg's avatar
Florian Liekweg committed
353
   Determine whether the given method could be used in a call to the
Florian Liekweg's avatar
Florian Liekweg committed
354
355
   given graph on a live class.
*/
Florian Liekweg's avatar
Florian Liekweg committed
356
357
358
359
360
361
362
static int has_live_class (entity *method, ir_graph *graph)
{
  int has_class = FALSE;
  int i;
  int n_over;
  type *clazz;

Florian Liekweg's avatar
Florian Liekweg committed
363
  /* stop searching when an overwriting method provides a new graph */
Florian Liekweg's avatar
Florian Liekweg committed
364
365
366
367
368
  if (get_implementing_graph (method) != graph) {
    return (FALSE);
  }

  clazz = get_entity_owner (method);
Florian Liekweg's avatar
Florian Liekweg committed
369
370

  if (has_graph (clazz, graph)) { /* this also checks whether clazz is live*/
Florian Liekweg's avatar
Florian Liekweg committed
371
372
373
374
375
376
377
378
379
380
381
382
    return (TRUE);
  }

  n_over = get_entity_n_overwrittenby (method);
  for (i = 0; !has_class && (i < n_over); i ++) {
    entity *over = get_entity_overwrittenby (method, i);
    has_class |= has_live_class (over, graph);
  }

  return (has_class);
}

383
384
385
386
387
388
/*
   Count the number of graphs that we have found to be live.  Since
   this touches every graph of the irp, it also forces that each graph
   is either in _live_graphs xor in _dead_graphs.  This is useful if
   we use is_alive(ir_graph*) internally.
*/
Götz Lindenmaier's avatar
Götz Lindenmaier committed
389
static int stats (void)
Florian Liekweg's avatar
Florian Liekweg committed
390
{
391
392
393
394
395
396
397
  int i;
  int n_live_graphs = 0;
  int n_graphs = get_irp_n_irgs();

  for (i = 0; i < n_graphs; i++) {
    ir_graph *graph = get_irp_irg(i);

398
    if (rta_is_alive_graph (graph)) {
399
      n_live_graphs ++;
400
401
402
403
404
    }
  }

  return (n_live_graphs);
}
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
/* remove a graph, part I */
/*
   We removed the first graph to implement the entity, so we're
   abstract now.  Pretend that it wasn't there at all, and every
   entity that used to inherit this entity's graph is now abstract.
*/
/* Since we *know* that this entity will not be called, this is OK. */
static void force_description (entity *ent, entity *addr)
{
  int i, n_over = get_entity_n_overwrittenby (ent);

  set_entity_peculiarity (ent, peculiarity_description);

  for (i = 0; i < n_over; i ++) {
    entity *over = get_entity_overwrittenby (ent, i);

    if (peculiarity_inherited == get_entity_peculiarity (over)) {
      /* We rely on the fact that cse is performed on the const_code_irg. */
      entity *my_addr =
        tarval_to_entity(get_Const_tarval(get_atomic_ent_value(over)));

      if (addr == my_addr) {
        force_description (over, addr);
      }
    } else if (peculiarity_existent == get_entity_peculiarity (over)) {
Florian Liekweg's avatar
Florian Liekweg committed
431
      /* check whether 'over' forces 'inheritance' of *our* graph: */
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
      ir_node *f_addr = get_atomic_ent_value (over);
      entity *impl_ent = tarval_to_entity (get_Const_tarval (f_addr));

      assert ((get_irn_op(f_addr) == op_Const) && "can't do complex addrs");
      if (impl_ent == addr) {
        assert (0 && "gibt's denn sowas");
        force_description (over, addr);
      }
    }
  }
}

/* remove a graph, part II */
/*
   Note: get_implementing_graph is not well defined here (graph->ent
   could overwrite more than one superclass implementation (graph).
   Since we *know* that this entity will not be called, this is OK.
*/
static void remove_irg (ir_graph *graph)
{
  entity *ent = get_irg_entity (graph);

454
455
  //DDMEO(get_irg_ent(graph));

456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
  /* delete the ir_graph data */
  remove_irp_irg (graph);
  /* remove reference to the graph */
  set_entity_irg (ent, NULL);
  /* find the implementation (graph) from *some* superclass: */
  graph = get_implementing_graph (ent);

  if (TRUE || (NULL == graph)) { /* always pretend to be 'abstract'; let the others figure this out */
    /* nothing to inherit!  pretend we're abstract */
    force_description (ent, ent);
  } else {
  /* pretend that we inherit the implementation (graph) from some superclass: */
    set_entity_peculiarity (ent, peculiarity_inherited);

    exchange (get_atomic_ent_value (ent),
              get_atomic_ent_value (get_irg_ent(graph)));
  }
}

/* Initialise the RTA data structures, and perform RTA.
   @param   verbose Iff != 0, print statistics as we go along
*/
478
479
480
481
482
483
void rta_init (int verbose)
{
  int n_live_graphs = get_irp_n_irgs ();
  int n_graphs = 0;
  int n_runs = 0;

484
485
486
487
488
489
490
491
# ifdef DEBUG_libfirm
  int i;
  for (i = 0; i < get_irp_n_irgs(); i++) {
    irg_vrfy (get_irp_irg(i));
  }
  tr_vrfy ();
# endif /* defined DEBUG_libfirm */

492
493
  init_tables ();

494
495
496
497
  if (verbose) {
    printf ("RTA: run %i (%i graphs to go)\n", n_runs, n_live_graphs);
  }

498
499
500
501
502
503
504
  rta_fill_all (FALSE);

  while (n_graphs != n_live_graphs) {
    n_graphs = n_live_graphs;
    n_runs ++;
    rta_fill_all (TRUE);
    n_live_graphs = stats ();
505

506
507
    if (verbose) {
      printf ("RTA: run %i (%i graphs to go)\n", n_runs, n_live_graphs);
508
509
510
    }
  }

511
512
513
514
515
  if (verbose) {
    printf ("RTA: n_graphs      = %i\n", get_irp_n_irgs ());
    printf ("RTA: n_live_graphs = %i\n", n_live_graphs);
    printf ("RTA: n_runs        = %i\n", n_runs);
  }
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539

# ifdef DEBUG_libfirm
  for (i = 0; i < get_irp_n_irgs(); i++) {
    irg_vrfy (get_irp_irg(i));
  }
  tr_vrfy ();
# endif /* defined DEBUG_libfirm */
}

/* Delete all graphs that we have found to be dead from the program */
void rta_delete_dead_graphs ()
{
  int i;
  int n_graphs = get_irp_n_irgs ();
  ir_graph *graph = NULL;

  eset *dead_graphs = eset_create ();

  for (i = 0; i < n_graphs; i++) {
    graph = get_irp_irg(i);

    if (is_alive (graph, _live_graphs, _dead_graphs)) {
      /* do nothing (except some debugging fprintf`s :-) */
    } else {
Florian Liekweg's avatar
Florian Liekweg committed
540
# ifdef DEBUG_libfirm
541
542
      entity *ent = get_irg_entity (graph);
      assert (visibility_external_visible != get_entity_visibility (ent));
Florian Liekweg's avatar
Florian Liekweg committed
543
# endif /* defined DEBUG_libfirm */
544
545
546
547

      eset_insert (dead_graphs, graph);
    }
  }
548
549
550
551
552
553
554
555
  /*
  for (i = 0; i < get_irp_n_types(); ++i) {
    type *tp = get_irp_type(i);
    if (is_class_type(tp) && !rta_is_alive_class(tp)) {
      printf(" never allocated: "); DDMT(tp);
    }
  }
  */
556
557
558
559
560
561
  /* now delete the graphs. */
  for (graph = eset_first (dead_graphs);
       graph;
       graph = (ir_graph*) eset_next (dead_graphs)) {
    remove_irg (graph);
  }
562
}
563

564
565
/* Clean up the RTA data structures.  Call this after calling rta_init */
void rta_cleanup ()
566
{
567
568
569
570
571
572
573
574
# ifdef DEBUG_libfirm
  int i;
    for (i = 0; i < get_irp_n_irgs(); i++) {
      irg_vrfy (get_irp_irg(i));
    }
    tr_vrfy ();
# endif /* defined DEBUG_libfirm */

Florian Liekweg's avatar
Florian Liekweg committed
575
  if (_live_classes) {
576
    eset_destroy (_live_classes);
Florian Liekweg's avatar
Florian Liekweg committed
577
578
579
580
    _live_classes = NULL;
  }

  if (_live_fields) {
581
    eset_destroy (_live_fields);
Florian Liekweg's avatar
Florian Liekweg committed
582
583
584
585
    _live_fields = NULL;
  }

  if (_called_methods) {
586
    eset_destroy (_called_methods);
Florian Liekweg's avatar
Florian Liekweg committed
587
588
589
590
    _called_methods = NULL;
  }

  if (_live_graphs) {
591
    eset_destroy (_live_graphs);
Florian Liekweg's avatar
Florian Liekweg committed
592
593
594
595
    _live_graphs = NULL;
  }

  if (_dead_graphs) {
596
    eset_destroy (_dead_graphs);
Florian Liekweg's avatar
Florian Liekweg committed
597
598
599
600
    _dead_graphs = NULL;
  }
}

Florian Liekweg's avatar
Florian Liekweg committed
601
/* Say whether this class might be instantiated at any point in the program: */
Florian Liekweg's avatar
Florian Liekweg committed
602
603
int  rta_is_alive_class  (type   *clazz)
{
604
  return (eset_contains (_live_classes, clazz));
Florian Liekweg's avatar
Florian Liekweg committed
605
606
}

Florian Liekweg's avatar
Florian Liekweg committed
607
/* Say whether this graph might be run at any time in the program: */
Florian Liekweg's avatar
Florian Liekweg committed
608
609
int  rta_is_alive_graph (ir_graph *graph)
{
610
  if (eset_contains (_live_graphs, graph)) {
Florian Liekweg's avatar
Florian Liekweg committed
611
612
613
    return (TRUE);
  }

614
  if (eset_contains (_dead_graphs, graph)) {
Florian Liekweg's avatar
Florian Liekweg committed
615
616
617
    return (FALSE);
  }

618
  entity *meth = get_irg_ent (graph);
Florian Liekweg's avatar
Florian Liekweg committed
619
620

  if (has_live_call (meth, graph) && has_live_class (meth, graph)) {
621
    eset_insert (_live_graphs, graph);
Florian Liekweg's avatar
Florian Liekweg committed
622
623
624

    return (TRUE);
  } else {
625
    eset_insert (_dead_graphs, graph);
Florian Liekweg's avatar
Florian Liekweg committed
626
627
628
629
630

    return (FALSE);
  }
}

Florian Liekweg's avatar
Florian Liekweg committed
631
/* Say whether there have been any accesses to this field: */
Florian Liekweg's avatar
Florian Liekweg committed
632
633
int  rta_is_alive_field  (entity *field)
{
634
  return (eset_contains (_live_fields, field));
Florian Liekweg's avatar
Florian Liekweg committed
635
636
637
638
639
640
}



/*
 * $Log$
641
642
643
644
645
 * Revision 1.10  2004/06/17 10:31:41  goetz
 * irscc: bugfix, can now deal with loops not reachable from start
 * cgana: bugfix, skip_Tuple
 * rta: improved
 *
Florian Liekweg's avatar
Florian Liekweg committed
646
647
648
 * Revision 1.9  2004/06/17 08:56:03  liekweg
 * Fixed typos in comments
 *
649
650
 * Revision 1.8  2004/06/17 08:33:01  liekweg
 * Added comments; added remove_irg
651
 *
Götz Lindenmaier's avatar
Götz Lindenmaier committed
652
653
654
 * Revision 1.6  2004/06/14 13:02:03  goetz
 * bugfixesbug
 *
655
656
657
 * Revision 1.5  2004/06/13 15:03:45  liekweg
 * RTA auf Iterative RTA aufgebohrt --flo
 *
Florian Liekweg's avatar
Florian Liekweg committed
658
659
660
 * Revision 1.4  2004/06/12 19:35:04  liekweg
 * Kommentare eingef"ugt --flo
 *
661
662
663
 * Revision 1.3  2004/06/12 17:09:46  liekweg
 * RTA works, outedges breaks.  "Yay." --flo
 *
Florian Liekweg's avatar
Florian Liekweg committed
664
665
666
 * Revision 1.2  2004/06/11 18:25:39  liekweg
 * Added todo
 *
Florian Liekweg's avatar
Florian Liekweg committed
667
668
669
670
 * Revision 1.1  2004/06/11 18:24:18  liekweg
 * Added RTA --flo
 *
 */