1 /* Basic IPA optimizations and utilities.
2 Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GCC.
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 2, or (at your option) any later
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
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 #include "coretypes.h"
27 /* Fill array order with all nodes with output flag set in the reverse
31 cgraph_postorder (struct cgraph_node
**order
)
33 struct cgraph_node
*node
, *node2
;
36 struct cgraph_edge
*edge
, last
;
38 struct cgraph_node
**stack
=
39 XCNEWVEC (struct cgraph_node
*, cgraph_n_nodes
);
41 /* We have to deal with cycles nicely, so use a depth first traversal
42 output algorithm. Ignore the fact that some functions won't need
43 to be output and put them into order as well, so we get dependencies
44 right through intline functions. */
45 for (node
= cgraph_nodes
; node
; node
= node
->next
)
47 for (node
= cgraph_nodes
; node
; node
= node
->next
)
54 node
->aux
= node
->callers
;
57 while (node2
->aux
!= &last
)
60 if (edge
->next_caller
)
61 node2
->aux
= edge
->next_caller
;
64 if (!edge
->caller
->aux
)
66 if (!edge
->caller
->callers
)
67 edge
->caller
->aux
= &last
;
69 edge
->caller
->aux
= edge
->caller
->callers
;
70 stack
[stack_size
++] = node2
;
75 if (node2
->aux
== &last
)
77 order
[order_pos
++] = node2
;
79 node2
= stack
[--stack_size
];
86 for (node
= cgraph_nodes
; node
; node
= node
->next
)
91 /* Perform reachability analysis and reclaim all unreachable nodes.
92 If BEFORE_INLINING_P is true this function is called before inlining
93 decisions has been made. If BEFORE_INLINING_P is false this function also
94 removes unneeded bodies of extern inline functions. */
97 cgraph_remove_unreachable_nodes (bool before_inlining_p
, FILE *file
)
99 struct cgraph_node
*first
= (void *) 1;
100 struct cgraph_node
*node
, *next
;
101 bool changed
= false;
104 #ifdef ENABLE_CHECKING
108 fprintf (file
, "\nReclaiming functions:");
109 #ifdef ENABLE_CHECKING
110 for (node
= cgraph_nodes
; node
; node
= node
->next
)
111 gcc_assert (!node
->aux
);
113 for (node
= cgraph_nodes
; node
; node
= node
->next
)
114 if (node
->needed
&& !node
->global
.inlined_to
115 && ((!DECL_EXTERNAL (node
->decl
))
117 || before_inlining_p
))
123 gcc_assert (!node
->aux
);
125 /* Perform reachability analysis. As a special case do not consider
126 extern inline functions not inlined as live because we won't output
128 while (first
!= (void *) 1)
130 struct cgraph_edge
*e
;
134 for (e
= node
->callees
; e
; e
= e
->next_callee
)
137 && (!e
->inline_failed
|| !e
->callee
->analyzed
138 || (!DECL_EXTERNAL (e
->callee
->decl
))
139 || before_inlining_p
))
141 e
->callee
->aux
= first
;
146 /* Remove unreachable nodes. Extern inline functions need special care;
147 Unreachable extern inline functions shall be removed.
148 Reachable extern inline functions we never inlined shall get their bodies
150 Reachable extern inline functions we sometimes inlined will be turned into
151 unanalyzed nodes so they look like for true extern functions to the rest
152 of code. Body of such functions is released via remove_node once the
153 inline clones are eliminated. */
154 for (node
= cgraph_nodes
; node
; node
= next
)
160 tree decl
= node
->decl
;
162 node
->global
.inlined_to
= NULL
;
163 if (DECL_STRUCT_FUNCTION (decl
))
164 local_insns
= node
->local
.self_insns
;
168 fprintf (file
, " %s", cgraph_node_name (node
));
169 if (!node
->analyzed
|| !DECL_EXTERNAL (node
->decl
)
170 || before_inlining_p
)
171 cgraph_remove_node (node
);
174 struct cgraph_edge
*e
;
176 for (e
= node
->callers
; e
; e
= e
->next_caller
)
179 if (e
|| node
->needed
)
181 struct cgraph_node
*clone
;
183 for (clone
= node
->next_clone
; clone
;
184 clone
= clone
->next_clone
)
189 DECL_SAVED_TREE (node
->decl
) = NULL
;
190 DECL_STRUCT_FUNCTION (node
->decl
) = NULL
;
191 DECL_INITIAL (node
->decl
) = error_mark_node
;
192 node
->analyzed
= false;
194 cgraph_node_remove_callees (node
);
195 node
->analyzed
= false;
198 cgraph_remove_node (node
);
200 if (!DECL_SAVED_TREE (decl
))
201 insns
+= local_insns
;
205 for (node
= cgraph_nodes
; node
; node
= node
->next
)
208 fprintf (file
, "\nReclaimed %i insns", insns
);