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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.2.2/] [gcc/] [ipa.c] - Blame information for rev 438

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

Line No. Rev Author Line
1 38 julius
/* Basic IPA optimizations and utilities.
2
   Copyright (C) 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 it under
7
the terms of the GNU General Public License as published by the Free
8
Software Foundation; either version 3, or (at your option) any later
9
version.
10
 
11
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12
WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
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 "cgraph.h"
25
 
26
/* Fill array order with all nodes with output flag set in the reverse
27
   topological order.  */
28
 
29
int
30
cgraph_postorder (struct cgraph_node **order)
31
{
32
  struct cgraph_node *node, *node2;
33
  int stack_size = 0;
34
  int order_pos = 0;
35
  struct cgraph_edge *edge, last;
36
 
37
  struct cgraph_node **stack =
38
    XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
39
 
40
  /* We have to deal with cycles nicely, so use a depth first traversal
41
     output algorithm.  Ignore the fact that some functions won't need
42
     to be output and put them into order as well, so we get dependencies
43
     right through intline functions.  */
44
  for (node = cgraph_nodes; node; node = node->next)
45
    node->aux = NULL;
46
  for (node = cgraph_nodes; node; node = node->next)
47
    if (!node->aux)
48
      {
49
        node2 = node;
50
        if (!node->callers)
51
          node->aux = &last;
52
        else
53
          node->aux = node->callers;
54
        while (node2)
55
          {
56
            while (node2->aux != &last)
57
              {
58
                edge = node2->aux;
59
                if (edge->next_caller)
60
                  node2->aux = edge->next_caller;
61
                else
62
                  node2->aux = &last;
63
                if (!edge->caller->aux)
64
                  {
65
                    if (!edge->caller->callers)
66
                      edge->caller->aux = &last;
67
                    else
68
                      edge->caller->aux = edge->caller->callers;
69
                    stack[stack_size++] = node2;
70
                    node2 = edge->caller;
71
                    break;
72
                  }
73
              }
74
            if (node2->aux == &last)
75
              {
76
                order[order_pos++] = node2;
77
                if (stack_size)
78
                  node2 = stack[--stack_size];
79
                else
80
                  node2 = NULL;
81
              }
82
          }
83
      }
84
  free (stack);
85
  for (node = cgraph_nodes; node; node = node->next)
86
    node->aux = NULL;
87
  return order_pos;
88
}
89
 
90
/* Perform reachability analysis and reclaim all unreachable nodes.
91
   If BEFORE_INLINING_P is true this function is called before inlining
92
   decisions has been made.  If BEFORE_INLINING_P is false this function also
93
   removes unneeded bodies of extern inline functions.  */
94
 
95
bool
96
cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
97
{
98
  struct cgraph_node *first = (void *) 1;
99
  struct cgraph_node *node, *next;
100
  bool changed = false;
101
  int insns = 0;
102
 
103
#ifdef ENABLE_CHECKING
104
  verify_cgraph ();
105
#endif
106
  if (file)
107
    fprintf (file, "\nReclaiming functions:");
108
#ifdef ENABLE_CHECKING
109
  for (node = cgraph_nodes; node; node = node->next)
110
    gcc_assert (!node->aux);
111
#endif
112
  for (node = cgraph_nodes; node; node = node->next)
113
    if (node->needed && !node->global.inlined_to
114
        && ((!DECL_EXTERNAL (node->decl))
115
            || !node->analyzed
116
            || before_inlining_p))
117
      {
118
        node->aux = first;
119
        first = node;
120
      }
121
    else
122
      gcc_assert (!node->aux);
123
 
124
  /* Perform reachability analysis.  As a special case do not consider
125
     extern inline functions not inlined as live because we won't output
126
     them at all.  */
127
  while (first != (void *) 1)
128
    {
129
      struct cgraph_edge *e;
130
      node = first;
131
      first = first->aux;
132
 
133
      for (e = node->callees; e; e = e->next_callee)
134
        if (!e->callee->aux
135
            && node->analyzed
136
            && (!e->inline_failed || !e->callee->analyzed
137
                || (!DECL_EXTERNAL (e->callee->decl))
138
                || before_inlining_p))
139
          {
140
            e->callee->aux = first;
141
            first = e->callee;
142
          }
143
    }
144
 
145
  /* Remove unreachable nodes.  Extern inline functions need special care;
146
     Unreachable extern inline functions shall be removed.
147
     Reachable extern inline functions we never inlined shall get their bodies
148
     eliminated.
149
     Reachable extern inline functions we sometimes inlined will be turned into
150
     unanalyzed nodes so they look like for true extern functions to the rest
151
     of code.  Body of such functions is released via remove_node once the
152
     inline clones are eliminated.  */
153
  for (node = cgraph_nodes; node; node = next)
154
    {
155
      next = node->next;
156
      if (!node->aux)
157
        {
158
          int local_insns;
159
          tree decl = node->decl;
160
 
161
          node->global.inlined_to = NULL;
162
          if (DECL_STRUCT_FUNCTION (decl))
163
            local_insns = node->local.self_insns;
164
          else
165
            local_insns = 0;
166
          if (file)
167
            fprintf (file, " %s", cgraph_node_name (node));
168
          if (!node->analyzed || !DECL_EXTERNAL (node->decl)
169
              || before_inlining_p)
170
            cgraph_remove_node (node);
171
          else
172
            {
173
              struct cgraph_edge *e;
174
 
175
              for (e = node->callers; e; e = e->next_caller)
176
                if (e->caller->aux)
177
                  break;
178
              if (e || node->needed)
179
                {
180
                  struct cgraph_node *clone;
181
 
182
                  for (clone = node->next_clone; clone;
183
                       clone = clone->next_clone)
184
                    if (clone->aux)
185
                      break;
186
                  if (!clone)
187
                    {
188
                      DECL_SAVED_TREE (node->decl) = NULL;
189
                      DECL_STRUCT_FUNCTION (node->decl) = NULL;
190
                      DECL_INITIAL (node->decl) = error_mark_node;
191
                      node->analyzed = false;
192
                    }
193
                  cgraph_node_remove_callees (node);
194
                  node->analyzed = false;
195
                }
196
              else
197
                cgraph_remove_node (node);
198
            }
199
          if (!DECL_SAVED_TREE (decl))
200
            insns += local_insns;
201
          changed = true;
202
        }
203
    }
204
  for (node = cgraph_nodes; node; node = node->next)
205
    node->aux = NULL;
206
  if (file)
207
    fprintf (file, "\nReclaimed %i insns", insns);
208
  return changed;
209
}

powered by: WebSVN 2.1.0

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