annotate gcc/ipa.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Basic IPA optimizations and utilities.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2003-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "coretypes.h"
111
kono
parents: 67
diff changeset
23 #include "backend.h"
kono
parents: 67
diff changeset
24 #include "target.h"
kono
parents: 67
diff changeset
25 #include "tree.h"
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
26 #include "gimple.h"
111
kono
parents: 67
diff changeset
27 #include "alloc-pool.h"
kono
parents: 67
diff changeset
28 #include "tree-pass.h"
kono
parents: 67
diff changeset
29 #include "stringpool.h"
kono
parents: 67
diff changeset
30 #include "cgraph.h"
kono
parents: 67
diff changeset
31 #include "gimplify.h"
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
32 #include "tree-iterator.h"
111
kono
parents: 67
diff changeset
33 #include "ipa-utils.h"
kono
parents: 67
diff changeset
34 #include "symbol-summary.h"
kono
parents: 67
diff changeset
35 #include "tree-vrp.h"
kono
parents: 67
diff changeset
36 #include "ipa-prop.h"
kono
parents: 67
diff changeset
37 #include "ipa-fnsummary.h"
kono
parents: 67
diff changeset
38 #include "dbgcnt.h"
kono
parents: 67
diff changeset
39 #include "debug.h"
kono
parents: 67
diff changeset
40 #include "stringpool.h"
kono
parents: 67
diff changeset
41 #include "attribs.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42
111
kono
parents: 67
diff changeset
43 /* Return true when NODE has ADDR reference. */
kono
parents: 67
diff changeset
44
kono
parents: 67
diff changeset
45 static bool
kono
parents: 67
diff changeset
46 has_addr_references_p (struct cgraph_node *node,
kono
parents: 67
diff changeset
47 void *)
kono
parents: 67
diff changeset
48 {
kono
parents: 67
diff changeset
49 int i;
kono
parents: 67
diff changeset
50 struct ipa_ref *ref = NULL;
kono
parents: 67
diff changeset
51
kono
parents: 67
diff changeset
52 for (i = 0; node->iterate_referring (i, ref); i++)
kono
parents: 67
diff changeset
53 if (ref->use == IPA_REF_ADDR)
kono
parents: 67
diff changeset
54 return true;
kono
parents: 67
diff changeset
55 return false;
kono
parents: 67
diff changeset
56 }
kono
parents: 67
diff changeset
57
kono
parents: 67
diff changeset
58 /* Return true when NODE can be target of an indirect call. */
kono
parents: 67
diff changeset
59
kono
parents: 67
diff changeset
60 static bool
kono
parents: 67
diff changeset
61 is_indirect_call_target_p (struct cgraph_node *node, void *)
kono
parents: 67
diff changeset
62 {
kono
parents: 67
diff changeset
63 return node->indirect_call_target;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
66 /* Look for all functions inlined to NODE and update their inlined_to pointers
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
67 to INLINED_TO. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
68
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
69 static void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
70 update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
71 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
72 struct cgraph_edge *e;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
73 for (e = node->callees; e; e = e->next_callee)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
74 if (e->callee->inlined_to)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
75 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
76 e->callee->inlined_to = inlined_to;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
77 update_inlined_to_pointer (e->callee, inlined_to);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
78 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
79 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
80
111
kono
parents: 67
diff changeset
81 /* Add symtab NODE to queue starting at FIRST.
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
82
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
83 The queue is linked via AUX pointers and terminated by pointer to 1.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
84 We enqueue nodes at two occasions: when we find them reachable or when we find
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
85 their bodies needed for further clonning. In the second case we mark them
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
86 by pointer to 2 after processing so they are re-queue when they become
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
87 reachable. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
88
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
89 static void
111
kono
parents: 67
diff changeset
90 enqueue_node (symtab_node *node, symtab_node **first,
kono
parents: 67
diff changeset
91 hash_set<symtab_node *> *reachable)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
92 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
93 /* Node is still in queue; do nothing. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
94 if (node->aux && node->aux != (void *) 2)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
95 return;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
96 /* Node was already processed as unreachable, re-enqueue
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
97 only if it became reachable now. */
111
kono
parents: 67
diff changeset
98 if (node->aux == (void *)2 && !reachable->contains (node))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
99 return;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
100 node->aux = *first;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
101 *first = node;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
102 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
103
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
104 /* Return true if NODE may get inlined later.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
105 This is used to keep DECL_EXTERNAL function bodies around long enough
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
106 so inliner can proces them. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
107
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
108 static bool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
109 possible_inline_candidate_p (symtab_node *node)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
110 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
111 if (symtab->state >= IPA_SSA_AFTER_INLINING)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
112 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
113 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
114 if (!cnode)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
115 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
116 if (DECL_UNINLINABLE (cnode->decl))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
117 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
118 if (opt_for_fn (cnode->decl, optimize))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
119 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
120 if (symtab->state >= IPA_SSA)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
121 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
122 return lookup_attribute ("always_inline", DECL_ATTRIBUTES (node->decl));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
123 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
124
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
125 /* Process references. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
126
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
127 static void
111
kono
parents: 67
diff changeset
128 process_references (symtab_node *snode,
kono
parents: 67
diff changeset
129 symtab_node **first,
kono
parents: 67
diff changeset
130 hash_set<symtab_node *> *reachable)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
131 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
132 int i;
111
kono
parents: 67
diff changeset
133 struct ipa_ref *ref = NULL;
kono
parents: 67
diff changeset
134 for (i = 0; snode->iterate_reference (i, ref); i++)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
135 {
111
kono
parents: 67
diff changeset
136 symtab_node *node = ref->referred;
kono
parents: 67
diff changeset
137 symtab_node *body = node->ultimate_alias_target ();
kono
parents: 67
diff changeset
138
kono
parents: 67
diff changeset
139 if (node->definition && !node->in_other_partition
kono
parents: 67
diff changeset
140 && ((!DECL_EXTERNAL (node->decl) || node->alias)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
141 || (possible_inline_candidate_p (node)
111
kono
parents: 67
diff changeset
142 /* We use variable constructors during late compilation for
kono
parents: 67
diff changeset
143 constant folding. Keep references alive so partitioning
kono
parents: 67
diff changeset
144 knows about potential references. */
kono
parents: 67
diff changeset
145 || (VAR_P (node->decl)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
146 && (flag_wpa
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
147 || flag_incremental_link
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
148 == INCREMENTAL_LINK_LTO)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
149 && dyn_cast <varpool_node *> (node)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
150 ->ctor_useable_for_folding_p ()))))
111
kono
parents: 67
diff changeset
151 {
kono
parents: 67
diff changeset
152 /* Be sure that we will not optimize out alias target
kono
parents: 67
diff changeset
153 body. */
kono
parents: 67
diff changeset
154 if (DECL_EXTERNAL (node->decl)
kono
parents: 67
diff changeset
155 && node->alias
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
156 && symtab->state < IPA_SSA_AFTER_INLINING)
111
kono
parents: 67
diff changeset
157 reachable->add (body);
kono
parents: 67
diff changeset
158 reachable->add (node);
kono
parents: 67
diff changeset
159 }
kono
parents: 67
diff changeset
160 enqueue_node (node, first, reachable);
kono
parents: 67
diff changeset
161 }
kono
parents: 67
diff changeset
162 }
kono
parents: 67
diff changeset
163
kono
parents: 67
diff changeset
164 /* EDGE is an polymorphic call. If BEFORE_INLINING_P is set, mark
kono
parents: 67
diff changeset
165 all its potential targets as reachable to permit later inlining if
kono
parents: 67
diff changeset
166 devirtualization happens. After inlining still keep their declarations
kono
parents: 67
diff changeset
167 around, so we can devirtualize to a direct call.
kono
parents: 67
diff changeset
168
kono
parents: 67
diff changeset
169 Also try to make trivial devirutalization when no or only one target is
kono
parents: 67
diff changeset
170 possible. */
kono
parents: 67
diff changeset
171
kono
parents: 67
diff changeset
172 static void
kono
parents: 67
diff changeset
173 walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
kono
parents: 67
diff changeset
174 struct cgraph_edge *edge,
kono
parents: 67
diff changeset
175 symtab_node **first,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
176 hash_set<symtab_node *> *reachable)
111
kono
parents: 67
diff changeset
177 {
kono
parents: 67
diff changeset
178 unsigned int i;
kono
parents: 67
diff changeset
179 void *cache_token;
kono
parents: 67
diff changeset
180 bool final;
kono
parents: 67
diff changeset
181 vec <cgraph_node *>targets
kono
parents: 67
diff changeset
182 = possible_polymorphic_call_targets
kono
parents: 67
diff changeset
183 (edge, &final, &cache_token);
kono
parents: 67
diff changeset
184
kono
parents: 67
diff changeset
185 if (!reachable_call_targets->add (cache_token))
kono
parents: 67
diff changeset
186 {
kono
parents: 67
diff changeset
187 for (i = 0; i < targets.length (); i++)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
188 {
111
kono
parents: 67
diff changeset
189 struct cgraph_node *n = targets[i];
kono
parents: 67
diff changeset
190
kono
parents: 67
diff changeset
191 /* Do not bother to mark virtual methods in anonymous namespace;
kono
parents: 67
diff changeset
192 either we will find use of virtual table defining it, or it is
kono
parents: 67
diff changeset
193 unused. */
kono
parents: 67
diff changeset
194 if (TREE_CODE (TREE_TYPE (n->decl)) == METHOD_TYPE
kono
parents: 67
diff changeset
195 && type_in_anonymous_namespace_p
kono
parents: 67
diff changeset
196 (TYPE_METHOD_BASETYPE (TREE_TYPE (n->decl))))
kono
parents: 67
diff changeset
197 continue;
kono
parents: 67
diff changeset
198
kono
parents: 67
diff changeset
199 n->indirect_call_target = true;
kono
parents: 67
diff changeset
200 symtab_node *body = n->function_symbol ();
kono
parents: 67
diff changeset
201
kono
parents: 67
diff changeset
202 /* Prior inlining, keep alive bodies of possible targets for
kono
parents: 67
diff changeset
203 devirtualization. */
kono
parents: 67
diff changeset
204 if (n->definition
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
205 && (possible_inline_candidate_p (body)
111
kono
parents: 67
diff changeset
206 && opt_for_fn (body->decl, flag_devirtualize)))
kono
parents: 67
diff changeset
207 {
kono
parents: 67
diff changeset
208 /* Be sure that we will not optimize out alias target
kono
parents: 67
diff changeset
209 body. */
kono
parents: 67
diff changeset
210 if (DECL_EXTERNAL (n->decl)
kono
parents: 67
diff changeset
211 && n->alias
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
212 && symtab->state < IPA_SSA_AFTER_INLINING)
111
kono
parents: 67
diff changeset
213 reachable->add (body);
kono
parents: 67
diff changeset
214 reachable->add (n);
kono
parents: 67
diff changeset
215 }
kono
parents: 67
diff changeset
216 /* Even after inlining we want to keep the possible targets in the
kono
parents: 67
diff changeset
217 boundary, so late passes can still produce direct call even if
kono
parents: 67
diff changeset
218 the chance for inlining is lost. */
kono
parents: 67
diff changeset
219 enqueue_node (n, first, reachable);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
220 }
111
kono
parents: 67
diff changeset
221 }
kono
parents: 67
diff changeset
222
kono
parents: 67
diff changeset
223 /* Very trivial devirtualization; when the type is
kono
parents: 67
diff changeset
224 final or anonymous (so we know all its derivation)
kono
parents: 67
diff changeset
225 and there is only one possible virtual call target,
kono
parents: 67
diff changeset
226 make the edge direct. */
kono
parents: 67
diff changeset
227 if (final)
kono
parents: 67
diff changeset
228 {
kono
parents: 67
diff changeset
229 if (targets.length () <= 1 && dbg_cnt (devirt))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
230 {
111
kono
parents: 67
diff changeset
231 cgraph_node *target, *node = edge->caller;
kono
parents: 67
diff changeset
232 if (targets.length () == 1)
kono
parents: 67
diff changeset
233 target = targets[0];
kono
parents: 67
diff changeset
234 else
kono
parents: 67
diff changeset
235 target = cgraph_node::get_create
kono
parents: 67
diff changeset
236 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
kono
parents: 67
diff changeset
237
kono
parents: 67
diff changeset
238 if (dump_enabled_p ())
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
239 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
240 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt,
111
kono
parents: 67
diff changeset
241 "devirtualizing call in %s to %s\n",
kono
parents: 67
diff changeset
242 edge->caller->dump_name (),
kono
parents: 67
diff changeset
243 target->dump_name ());
kono
parents: 67
diff changeset
244 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
245 edge = cgraph_edge::make_direct (edge, target);
111
kono
parents: 67
diff changeset
246 if (ipa_fn_summaries)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
247 ipa_update_overall_fn_summary (node->inlined_to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
248 ? node->inlined_to : node);
111
kono
parents: 67
diff changeset
249 else if (edge->call_stmt)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
250 cgraph_edge::redirect_call_stmt_to_callee (edge);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
251 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
252 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
253 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
254
111
kono
parents: 67
diff changeset
255 /* Perform reachability analysis and reclaim all unreachable nodes.
kono
parents: 67
diff changeset
256
kono
parents: 67
diff changeset
257 The algorithm is basically mark&sweep but with some extra refinements:
kono
parents: 67
diff changeset
258
kono
parents: 67
diff changeset
259 - reachable extern inline functions needs special handling; the bodies needs
kono
parents: 67
diff changeset
260 to stay in memory until inlining in hope that they will be inlined.
kono
parents: 67
diff changeset
261 After inlining we release their bodies and turn them into unanalyzed
kono
parents: 67
diff changeset
262 nodes even when they are reachable.
kono
parents: 67
diff changeset
263
kono
parents: 67
diff changeset
264 - virtual functions are kept in callgraph even if they seem unreachable in
kono
parents: 67
diff changeset
265 hope calls to them will be devirtualized.
kono
parents: 67
diff changeset
266
kono
parents: 67
diff changeset
267 Again we remove them after inlining. In late optimization some
kono
parents: 67
diff changeset
268 devirtualization may happen, but it is not important since we won't inline
kono
parents: 67
diff changeset
269 the call. In theory early opts and IPA should work out all important cases.
kono
parents: 67
diff changeset
270
kono
parents: 67
diff changeset
271 - virtual clones needs bodies of their origins for later materialization;
kono
parents: 67
diff changeset
272 this means that we want to keep the body even if the origin is unreachable
kono
parents: 67
diff changeset
273 otherwise. To avoid origin from sitting in the callgraph and being
kono
parents: 67
diff changeset
274 walked by IPA passes, we turn them into unanalyzed nodes with body
kono
parents: 67
diff changeset
275 defined.
kono
parents: 67
diff changeset
276
kono
parents: 67
diff changeset
277 We maintain set of function declaration where body needs to stay in
kono
parents: 67
diff changeset
278 body_needed_for_clonning
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
279
111
kono
parents: 67
diff changeset
280 Inline clones represent special case: their declaration match the
kono
parents: 67
diff changeset
281 declaration of origin and cgraph_remove_node already knows how to
kono
parents: 67
diff changeset
282 reshape callgraph and preserve body when offline copy of function or
kono
parents: 67
diff changeset
283 inline clone is being removed.
kono
parents: 67
diff changeset
284
kono
parents: 67
diff changeset
285 - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
kono
parents: 67
diff changeset
286 variables with DECL_INITIAL set. We finalize these and keep reachable
kono
parents: 67
diff changeset
287 ones around for constant folding purposes. After inlining we however
kono
parents: 67
diff changeset
288 stop walking their references to let everything static referneced by them
kono
parents: 67
diff changeset
289 to be removed when it is otherwise unreachable.
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
290
111
kono
parents: 67
diff changeset
291 We maintain queue of both reachable symbols (i.e. defined symbols that needs
kono
parents: 67
diff changeset
292 to stay) and symbols that are in boundary (i.e. external symbols referenced
kono
parents: 67
diff changeset
293 by reachable symbols or origins of clones). The queue is represented
kono
parents: 67
diff changeset
294 as linked list by AUX pointer terminated by 1.
kono
parents: 67
diff changeset
295
kono
parents: 67
diff changeset
296 At the end we keep all reachable symbols. For symbols in boundary we always
kono
parents: 67
diff changeset
297 turn definition into a declaration, but we may keep function body around
kono
parents: 67
diff changeset
298 based on body_needed_for_clonning
kono
parents: 67
diff changeset
299
kono
parents: 67
diff changeset
300 All symbols that enter the queue have AUX pointer non-zero and are in the
kono
parents: 67
diff changeset
301 boundary. Pointer set REACHABLE is used to track reachable symbols.
kono
parents: 67
diff changeset
302
kono
parents: 67
diff changeset
303 Every symbol can be visited twice - once as part of boundary and once
kono
parents: 67
diff changeset
304 as real reachable symbol. enqueue_node needs to decide whether the
kono
parents: 67
diff changeset
305 node needs to be re-queued for second processing. For this purpose
kono
parents: 67
diff changeset
306 we set AUX pointer of processed symbols in the boundary to constant 2. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 bool
111
kono
parents: 67
diff changeset
309 symbol_table::remove_unreachable_nodes (FILE *file)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 {
111
kono
parents: 67
diff changeset
311 symtab_node *first = (symtab_node *) (void *) 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 struct cgraph_node *node, *next;
111
kono
parents: 67
diff changeset
313 varpool_node *vnode, *vnext;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 bool changed = false;
111
kono
parents: 67
diff changeset
315 hash_set<symtab_node *> reachable;
kono
parents: 67
diff changeset
316 hash_set<tree> body_needed_for_clonning;
kono
parents: 67
diff changeset
317 hash_set<void *> reachable_call_targets;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318
111
kono
parents: 67
diff changeset
319 timevar_push (TV_IPA_UNREACHABLE);
kono
parents: 67
diff changeset
320 build_type_inheritance_graph ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
321 if (file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 fprintf (file, "\nReclaiming functions:");
111
kono
parents: 67
diff changeset
323 if (flag_checking)
kono
parents: 67
diff changeset
324 {
kono
parents: 67
diff changeset
325 FOR_EACH_FUNCTION (node)
kono
parents: 67
diff changeset
326 gcc_assert (!node->aux);
kono
parents: 67
diff changeset
327 FOR_EACH_VARIABLE (vnode)
kono
parents: 67
diff changeset
328 gcc_assert (!vnode->aux);
kono
parents: 67
diff changeset
329 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
330 /* Mark functions whose bodies are obviously needed.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
331 This is mostly when they can be referenced externally. Inline clones
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
332 are special since their declarations are shared with master clone and thus
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
333 cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */
111
kono
parents: 67
diff changeset
334 FOR_EACH_FUNCTION (node)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
335 {
111
kono
parents: 67
diff changeset
336 node->used_as_abstract_origin = false;
kono
parents: 67
diff changeset
337 node->indirect_call_target = false;
kono
parents: 67
diff changeset
338 if (node->definition
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
339 && !node->inlined_to
111
kono
parents: 67
diff changeset
340 && !node->in_other_partition
kono
parents: 67
diff changeset
341 && !node->can_remove_if_no_direct_calls_and_refs_p ())
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
342 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
343 gcc_assert (!node->inlined_to);
111
kono
parents: 67
diff changeset
344 reachable.add (node);
kono
parents: 67
diff changeset
345 enqueue_node (node, &first, &reachable);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
346 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
347 else
111
kono
parents: 67
diff changeset
348 gcc_assert (!node->aux);
kono
parents: 67
diff changeset
349 }
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
350
111
kono
parents: 67
diff changeset
351 /* Mark variables that are obviously needed. */
kono
parents: 67
diff changeset
352 FOR_EACH_DEFINED_VARIABLE (vnode)
kono
parents: 67
diff changeset
353 if (!vnode->can_remove_if_no_refs_p()
kono
parents: 67
diff changeset
354 && !vnode->in_other_partition)
kono
parents: 67
diff changeset
355 {
kono
parents: 67
diff changeset
356 reachable.add (vnode);
kono
parents: 67
diff changeset
357 enqueue_node (vnode, &first, &reachable);
kono
parents: 67
diff changeset
358 }
kono
parents: 67
diff changeset
359
kono
parents: 67
diff changeset
360 /* Perform reachability analysis. */
kono
parents: 67
diff changeset
361 while (first != (symtab_node *) (void *) 1)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
362 {
111
kono
parents: 67
diff changeset
363 bool in_boundary_p = !reachable.contains (first);
kono
parents: 67
diff changeset
364 symtab_node *node = first;
kono
parents: 67
diff changeset
365
kono
parents: 67
diff changeset
366 first = (symtab_node *)first->aux;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367
111
kono
parents: 67
diff changeset
368 /* If we are processing symbol in boundary, mark its AUX pointer for
kono
parents: 67
diff changeset
369 possible later re-processing in enqueue_node. */
kono
parents: 67
diff changeset
370 if (in_boundary_p)
kono
parents: 67
diff changeset
371 {
kono
parents: 67
diff changeset
372 node->aux = (void *)2;
kono
parents: 67
diff changeset
373 if (node->alias && node->analyzed)
kono
parents: 67
diff changeset
374 enqueue_node (node->get_alias_target (), &first, &reachable);
kono
parents: 67
diff changeset
375 }
kono
parents: 67
diff changeset
376 else
kono
parents: 67
diff changeset
377 {
kono
parents: 67
diff changeset
378 if (TREE_CODE (node->decl) == FUNCTION_DECL
kono
parents: 67
diff changeset
379 && DECL_ABSTRACT_ORIGIN (node->decl))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
380 {
111
kono
parents: 67
diff changeset
381 struct cgraph_node *origin_node
kono
parents: 67
diff changeset
382 = cgraph_node::get (DECL_ABSTRACT_ORIGIN (node->decl));
kono
parents: 67
diff changeset
383 if (origin_node && !origin_node->used_as_abstract_origin)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
384 {
111
kono
parents: 67
diff changeset
385 origin_node->used_as_abstract_origin = true;
kono
parents: 67
diff changeset
386 gcc_assert (!origin_node->prev_sibling_clone);
kono
parents: 67
diff changeset
387 gcc_assert (!origin_node->next_sibling_clone);
kono
parents: 67
diff changeset
388 for (cgraph_node *n = origin_node->clones; n;
kono
parents: 67
diff changeset
389 n = n->next_sibling_clone)
kono
parents: 67
diff changeset
390 if (n->decl == DECL_ABSTRACT_ORIGIN (node->decl))
kono
parents: 67
diff changeset
391 n->used_as_abstract_origin = true;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
392 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
393 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
394 /* If any non-external and non-local symbol in a comdat group is
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
395 reachable, force all externally visible symbols in the same comdat
111
kono
parents: 67
diff changeset
396 group to be reachable as well. Comdat-local symbols
kono
parents: 67
diff changeset
397 can be discarded if all uses were inlined. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
398 if (node->same_comdat_group
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
399 && node->externally_visible
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
400 && !DECL_EXTERNAL (node->decl))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
401 {
111
kono
parents: 67
diff changeset
402 symtab_node *next;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
403 for (next = node->same_comdat_group;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
404 next != node;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
405 next = next->same_comdat_group)
111
kono
parents: 67
diff changeset
406 if (!next->comdat_local_p ()
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
407 && !DECL_EXTERNAL (next->decl)
111
kono
parents: 67
diff changeset
408 && !reachable.add (next))
kono
parents: 67
diff changeset
409 enqueue_node (next, &first, &reachable);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
410 }
111
kono
parents: 67
diff changeset
411 /* Mark references as reachable. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
412 process_references (node, &first, &reachable);
111
kono
parents: 67
diff changeset
413 }
kono
parents: 67
diff changeset
414
kono
parents: 67
diff changeset
415 if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
kono
parents: 67
diff changeset
416 {
kono
parents: 67
diff changeset
417 /* Mark the callees reachable unless they are direct calls to extern
kono
parents: 67
diff changeset
418 inline functions we decided to not inline. */
kono
parents: 67
diff changeset
419 if (!in_boundary_p)
kono
parents: 67
diff changeset
420 {
kono
parents: 67
diff changeset
421 struct cgraph_edge *e;
kono
parents: 67
diff changeset
422 /* Keep alive possible targets for devirtualization. */
kono
parents: 67
diff changeset
423 if (opt_for_fn (cnode->decl, optimize)
kono
parents: 67
diff changeset
424 && opt_for_fn (cnode->decl, flag_devirtualize))
kono
parents: 67
diff changeset
425 {
kono
parents: 67
diff changeset
426 struct cgraph_edge *next;
kono
parents: 67
diff changeset
427 for (e = cnode->indirect_calls; e; e = next)
kono
parents: 67
diff changeset
428 {
kono
parents: 67
diff changeset
429 next = e->next_callee;
kono
parents: 67
diff changeset
430 if (e->indirect_info->polymorphic)
kono
parents: 67
diff changeset
431 walk_polymorphic_call_targets (&reachable_call_targets,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
432 e, &first, &reachable);
111
kono
parents: 67
diff changeset
433 }
kono
parents: 67
diff changeset
434 }
kono
parents: 67
diff changeset
435 for (e = cnode->callees; e; e = e->next_callee)
kono
parents: 67
diff changeset
436 {
kono
parents: 67
diff changeset
437 symtab_node *body = e->callee->function_symbol ();
kono
parents: 67
diff changeset
438 if (e->callee->definition
kono
parents: 67
diff changeset
439 && !e->callee->in_other_partition
kono
parents: 67
diff changeset
440 && (!e->inline_failed
kono
parents: 67
diff changeset
441 || !DECL_EXTERNAL (e->callee->decl)
kono
parents: 67
diff changeset
442 || e->callee->alias
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
443 || possible_inline_candidate_p (e->callee)))
111
kono
parents: 67
diff changeset
444 {
kono
parents: 67
diff changeset
445 /* Be sure that we will not optimize out alias target
kono
parents: 67
diff changeset
446 body. */
kono
parents: 67
diff changeset
447 if (DECL_EXTERNAL (e->callee->decl)
kono
parents: 67
diff changeset
448 && e->callee->alias
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
449 && symtab->state < IPA_SSA_AFTER_INLINING)
111
kono
parents: 67
diff changeset
450 reachable.add (body);
kono
parents: 67
diff changeset
451 reachable.add (e->callee);
kono
parents: 67
diff changeset
452 }
kono
parents: 67
diff changeset
453 enqueue_node (e->callee, &first, &reachable);
kono
parents: 67
diff changeset
454 }
kono
parents: 67
diff changeset
455
kono
parents: 67
diff changeset
456 /* When inline clone exists, mark body to be preserved so when removing
kono
parents: 67
diff changeset
457 offline copy of the function we don't kill it. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
458 if (cnode->inlined_to)
111
kono
parents: 67
diff changeset
459 body_needed_for_clonning.add (cnode->decl);
kono
parents: 67
diff changeset
460
kono
parents: 67
diff changeset
461 /* For non-inline clones, force their origins to the boundary and ensure
kono
parents: 67
diff changeset
462 that body is not removed. */
kono
parents: 67
diff changeset
463 while (cnode->clone_of)
kono
parents: 67
diff changeset
464 {
kono
parents: 67
diff changeset
465 bool noninline = cnode->clone_of->decl != cnode->decl;
kono
parents: 67
diff changeset
466 cnode = cnode->clone_of;
kono
parents: 67
diff changeset
467 if (noninline)
kono
parents: 67
diff changeset
468 {
kono
parents: 67
diff changeset
469 body_needed_for_clonning.add (cnode->decl);
kono
parents: 67
diff changeset
470 enqueue_node (cnode, &first, &reachable);
kono
parents: 67
diff changeset
471 }
kono
parents: 67
diff changeset
472 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
473
111
kono
parents: 67
diff changeset
474 }
kono
parents: 67
diff changeset
475 else if (cnode->thunk.thunk_p)
kono
parents: 67
diff changeset
476 enqueue_node (cnode->callees->callee, &first, &reachable);
kono
parents: 67
diff changeset
477
kono
parents: 67
diff changeset
478 /* If any reachable function has simd clones, mark them as
kono
parents: 67
diff changeset
479 reachable as well. */
kono
parents: 67
diff changeset
480 if (cnode->simd_clones)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
481 {
111
kono
parents: 67
diff changeset
482 cgraph_node *next;
kono
parents: 67
diff changeset
483 for (next = cnode->simd_clones;
kono
parents: 67
diff changeset
484 next;
kono
parents: 67
diff changeset
485 next = next->simdclone->next_clone)
kono
parents: 67
diff changeset
486 if (in_boundary_p
kono
parents: 67
diff changeset
487 || !reachable.add (next))
kono
parents: 67
diff changeset
488 enqueue_node (next, &first, &reachable);
kono
parents: 67
diff changeset
489 }
kono
parents: 67
diff changeset
490 }
kono
parents: 67
diff changeset
491 /* When we see constructor of external variable, keep referred nodes in the
kono
parents: 67
diff changeset
492 boundary. This will also hold initializers of the external vars NODE
kono
parents: 67
diff changeset
493 refers to. */
kono
parents: 67
diff changeset
494 varpool_node *vnode = dyn_cast <varpool_node *> (node);
kono
parents: 67
diff changeset
495 if (vnode
kono
parents: 67
diff changeset
496 && DECL_EXTERNAL (node->decl)
kono
parents: 67
diff changeset
497 && !vnode->alias
kono
parents: 67
diff changeset
498 && in_boundary_p)
kono
parents: 67
diff changeset
499 {
kono
parents: 67
diff changeset
500 struct ipa_ref *ref = NULL;
kono
parents: 67
diff changeset
501 for (int i = 0; node->iterate_reference (i, ref); i++)
kono
parents: 67
diff changeset
502 enqueue_node (ref->referred, &first, &reachable);
kono
parents: 67
diff changeset
503 }
kono
parents: 67
diff changeset
504 }
kono
parents: 67
diff changeset
505
kono
parents: 67
diff changeset
506 /* Remove unreachable functions. */
kono
parents: 67
diff changeset
507 for (node = first_function (); node; node = next)
kono
parents: 67
diff changeset
508 {
kono
parents: 67
diff changeset
509 next = next_function (node);
kono
parents: 67
diff changeset
510
kono
parents: 67
diff changeset
511 /* If node is not needed at all, remove it. */
kono
parents: 67
diff changeset
512 if (!node->aux)
kono
parents: 67
diff changeset
513 {
kono
parents: 67
diff changeset
514 if (file)
kono
parents: 67
diff changeset
515 fprintf (file, " %s", node->dump_name ());
kono
parents: 67
diff changeset
516 node->remove ();
kono
parents: 67
diff changeset
517 changed = true;
kono
parents: 67
diff changeset
518 }
kono
parents: 67
diff changeset
519 /* If node is unreachable, remove its body. */
kono
parents: 67
diff changeset
520 else if (!reachable.contains (node))
kono
parents: 67
diff changeset
521 {
kono
parents: 67
diff changeset
522 /* We keep definitions of thunks and aliases in the boundary so
kono
parents: 67
diff changeset
523 we can walk to the ultimate alias targets and function symbols
kono
parents: 67
diff changeset
524 reliably. */
kono
parents: 67
diff changeset
525 if (node->alias || node->thunk.thunk_p)
kono
parents: 67
diff changeset
526 ;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
527 else if (!body_needed_for_clonning.contains (node->decl))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
528 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
529 /* Make the node a non-clone so that we do not attempt to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
530 materialize it later. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
531 if (node->clone_of)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
532 node->remove_from_clone_tree ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
533 node->release_body ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
534 }
111
kono
parents: 67
diff changeset
535 else if (!node->clone_of)
kono
parents: 67
diff changeset
536 gcc_assert (in_lto_p || DECL_RESULT (node->decl));
kono
parents: 67
diff changeset
537 if (node->definition && !node->alias && !node->thunk.thunk_p)
kono
parents: 67
diff changeset
538 {
kono
parents: 67
diff changeset
539 if (file)
kono
parents: 67
diff changeset
540 fprintf (file, " %s", node->dump_name ());
kono
parents: 67
diff changeset
541 node->body_removed = true;
kono
parents: 67
diff changeset
542 node->analyzed = false;
kono
parents: 67
diff changeset
543 node->definition = false;
kono
parents: 67
diff changeset
544 node->cpp_implicit_alias = false;
kono
parents: 67
diff changeset
545 node->alias = false;
kono
parents: 67
diff changeset
546 node->transparent_alias = false;
kono
parents: 67
diff changeset
547 node->thunk.thunk_p = false;
kono
parents: 67
diff changeset
548 node->weakref = false;
kono
parents: 67
diff changeset
549 /* After early inlining we drop always_inline attributes on
kono
parents: 67
diff changeset
550 bodies of functions that are still referenced (have their
kono
parents: 67
diff changeset
551 address taken). */
kono
parents: 67
diff changeset
552 DECL_ATTRIBUTES (node->decl)
kono
parents: 67
diff changeset
553 = remove_attribute ("always_inline",
kono
parents: 67
diff changeset
554 DECL_ATTRIBUTES (node->decl));
kono
parents: 67
diff changeset
555 if (!node->in_other_partition)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
556 node->local = false;
111
kono
parents: 67
diff changeset
557 node->remove_callees ();
kono
parents: 67
diff changeset
558 node->remove_all_references ();
kono
parents: 67
diff changeset
559 changed = true;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
560 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
561 }
111
kono
parents: 67
diff changeset
562 else
kono
parents: 67
diff changeset
563 gcc_assert (node->clone_of || !node->has_gimple_body_p ()
kono
parents: 67
diff changeset
564 || in_lto_p || DECL_RESULT (node->decl));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566
111
kono
parents: 67
diff changeset
567 /* Inline clones might be kept around so their materializing allows further
kono
parents: 67
diff changeset
568 cloning. If the function the clone is inlined into is removed, we need
kono
parents: 67
diff changeset
569 to turn it into normal cone. */
kono
parents: 67
diff changeset
570 FOR_EACH_FUNCTION (node)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
572 if (node->inlined_to
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
573 && !node->callers)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
574 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
575 gcc_assert (node->clones);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
576 node->inlined_to = NULL;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
577 update_inlined_to_pointer (node, node);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
578 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
579 node->aux = NULL;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
580 }
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
581
111
kono
parents: 67
diff changeset
582 /* Remove unreachable variables. */
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
583 if (file)
111
kono
parents: 67
diff changeset
584 fprintf (file, "\nReclaiming variables:");
kono
parents: 67
diff changeset
585 for (vnode = first_variable (); vnode; vnode = vnext)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
586 {
111
kono
parents: 67
diff changeset
587 vnext = next_variable (vnode);
kono
parents: 67
diff changeset
588 if (!vnode->aux
kono
parents: 67
diff changeset
589 /* For can_refer_decl_in_current_unit_p we want to track for
kono
parents: 67
diff changeset
590 all external variables if they are defined in other partition
kono
parents: 67
diff changeset
591 or not. */
kono
parents: 67
diff changeset
592 && (!flag_ltrans || !DECL_EXTERNAL (vnode->decl)))
kono
parents: 67
diff changeset
593 {
kono
parents: 67
diff changeset
594 struct ipa_ref *ref = NULL;
kono
parents: 67
diff changeset
595
kono
parents: 67
diff changeset
596 /* First remove the aliases, so varpool::remove can possibly lookup
kono
parents: 67
diff changeset
597 the constructor and save it for future use. */
kono
parents: 67
diff changeset
598 while (vnode->iterate_direct_aliases (0, ref))
kono
parents: 67
diff changeset
599 {
kono
parents: 67
diff changeset
600 if (file)
kono
parents: 67
diff changeset
601 fprintf (file, " %s", ref->referred->dump_name ());
kono
parents: 67
diff changeset
602 ref->referring->remove ();
kono
parents: 67
diff changeset
603 }
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
604 if (file)
111
kono
parents: 67
diff changeset
605 fprintf (file, " %s", vnode->dump_name ());
kono
parents: 67
diff changeset
606 vnext = next_variable (vnode);
kono
parents: 67
diff changeset
607 /* Signal removal to the debug machinery. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
608 if (! flag_wpa || flag_incremental_link == INCREMENTAL_LINK_LTO)
111
kono
parents: 67
diff changeset
609 {
kono
parents: 67
diff changeset
610 vnode->definition = false;
kono
parents: 67
diff changeset
611 (*debug_hooks->late_global_decl) (vnode->decl);
kono
parents: 67
diff changeset
612 }
kono
parents: 67
diff changeset
613 vnode->remove ();
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
614 changed = true;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
615 }
111
kono
parents: 67
diff changeset
616 else if (!reachable.contains (vnode) && !vnode->alias)
kono
parents: 67
diff changeset
617 {
kono
parents: 67
diff changeset
618 tree init;
kono
parents: 67
diff changeset
619 if (vnode->definition)
kono
parents: 67
diff changeset
620 {
kono
parents: 67
diff changeset
621 if (file)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
622 fprintf (file, " %s", vnode->dump_name ());
111
kono
parents: 67
diff changeset
623 changed = true;
kono
parents: 67
diff changeset
624 }
kono
parents: 67
diff changeset
625 /* Keep body if it may be useful for constant folding. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
626 if ((flag_wpa || flag_incremental_link == INCREMENTAL_LINK_LTO)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
627 || ((init = ctor_for_folding (vnode->decl)) == error_mark_node))
111
kono
parents: 67
diff changeset
628 vnode->remove_initializer ();
kono
parents: 67
diff changeset
629 else
kono
parents: 67
diff changeset
630 DECL_INITIAL (vnode->decl) = init;
kono
parents: 67
diff changeset
631 vnode->body_removed = true;
kono
parents: 67
diff changeset
632 vnode->definition = false;
kono
parents: 67
diff changeset
633 vnode->analyzed = false;
kono
parents: 67
diff changeset
634 vnode->aux = NULL;
kono
parents: 67
diff changeset
635
kono
parents: 67
diff changeset
636 vnode->remove_from_same_comdat_group ();
kono
parents: 67
diff changeset
637
kono
parents: 67
diff changeset
638 vnode->remove_all_references ();
kono
parents: 67
diff changeset
639 }
kono
parents: 67
diff changeset
640 else
kono
parents: 67
diff changeset
641 vnode->aux = NULL;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
642 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
643
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
644 /* Now update address_taken flags and try to promote functions to be local. */
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
645 if (file)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
646 fprintf (file, "\nClearing address taken flags:");
111
kono
parents: 67
diff changeset
647 FOR_EACH_DEFINED_FUNCTION (node)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
648 if (node->address_taken
111
kono
parents: 67
diff changeset
649 && !node->used_from_other_partition)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
650 {
111
kono
parents: 67
diff changeset
651 if (!node->call_for_symbol_and_aliases
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
652 (has_addr_references_p, NULL, true))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
653 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
654 if (file)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
655 fprintf (file, " %s", node->dump_name ());
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
656 node->address_taken = false;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
657 changed = true;
111
kono
parents: 67
diff changeset
658 if (node->local_p ()
kono
parents: 67
diff changeset
659 /* Virtual functions may be kept in cgraph just because
kono
parents: 67
diff changeset
660 of possible later devirtualization. Do not mark them as
kono
parents: 67
diff changeset
661 local too early so we won't optimize them out before
kono
parents: 67
diff changeset
662 we are done with polymorphic call analysis. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
663 && (symtab->state >= IPA_SSA_AFTER_INLINING
111
kono
parents: 67
diff changeset
664 || !node->call_for_symbol_and_aliases
kono
parents: 67
diff changeset
665 (is_indirect_call_target_p, NULL, true)))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
666 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
667 node->local = true;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
668 if (file)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
669 fprintf (file, " (local)");
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
670 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
671 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
672 }
111
kono
parents: 67
diff changeset
673 if (file)
kono
parents: 67
diff changeset
674 fprintf (file, "\n");
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
675
111
kono
parents: 67
diff changeset
676 symtab_node::checking_verify_symtab_nodes ();
kono
parents: 67
diff changeset
677
kono
parents: 67
diff changeset
678 /* If we removed something, perhaps profile could be improved. */
kono
parents: 67
diff changeset
679 if (changed && (optimize || in_lto_p) && ipa_call_summaries)
kono
parents: 67
diff changeset
680 FOR_EACH_DEFINED_FUNCTION (node)
kono
parents: 67
diff changeset
681 ipa_propagate_frequency (node);
kono
parents: 67
diff changeset
682
kono
parents: 67
diff changeset
683 timevar_pop (TV_IPA_UNREACHABLE);
kono
parents: 67
diff changeset
684 return changed;
kono
parents: 67
diff changeset
685 }
kono
parents: 67
diff changeset
686
kono
parents: 67
diff changeset
687 /* Process references to VNODE and set flags WRITTEN, ADDRESS_TAKEN, READ
kono
parents: 67
diff changeset
688 as needed, also clear EXPLICIT_REFS if the references to given variable
kono
parents: 67
diff changeset
689 do not need to be explicit. */
kono
parents: 67
diff changeset
690
kono
parents: 67
diff changeset
691 void
kono
parents: 67
diff changeset
692 process_references (varpool_node *vnode,
kono
parents: 67
diff changeset
693 bool *written, bool *address_taken,
kono
parents: 67
diff changeset
694 bool *read, bool *explicit_refs)
kono
parents: 67
diff changeset
695 {
kono
parents: 67
diff changeset
696 int i;
kono
parents: 67
diff changeset
697 struct ipa_ref *ref;
kono
parents: 67
diff changeset
698
kono
parents: 67
diff changeset
699 if (!vnode->all_refs_explicit_p ()
kono
parents: 67
diff changeset
700 || TREE_THIS_VOLATILE (vnode->decl))
kono
parents: 67
diff changeset
701 *explicit_refs = false;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
702
111
kono
parents: 67
diff changeset
703 for (i = 0; vnode->iterate_referring (i, ref)
kono
parents: 67
diff changeset
704 && *explicit_refs && (!*written || !*address_taken || !*read); i++)
kono
parents: 67
diff changeset
705 switch (ref->use)
kono
parents: 67
diff changeset
706 {
kono
parents: 67
diff changeset
707 case IPA_REF_ADDR:
kono
parents: 67
diff changeset
708 *address_taken = true;
kono
parents: 67
diff changeset
709 break;
kono
parents: 67
diff changeset
710 case IPA_REF_LOAD:
kono
parents: 67
diff changeset
711 *read = true;
kono
parents: 67
diff changeset
712 break;
kono
parents: 67
diff changeset
713 case IPA_REF_STORE:
kono
parents: 67
diff changeset
714 *written = true;
kono
parents: 67
diff changeset
715 break;
kono
parents: 67
diff changeset
716 case IPA_REF_ALIAS:
kono
parents: 67
diff changeset
717 process_references (dyn_cast<varpool_node *> (ref->referring), written,
kono
parents: 67
diff changeset
718 address_taken, read, explicit_refs);
kono
parents: 67
diff changeset
719 break;
kono
parents: 67
diff changeset
720 }
kono
parents: 67
diff changeset
721 }
kono
parents: 67
diff changeset
722
kono
parents: 67
diff changeset
723 /* Set TREE_READONLY bit. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
724
111
kono
parents: 67
diff changeset
725 bool
kono
parents: 67
diff changeset
726 set_readonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
kono
parents: 67
diff changeset
727 {
kono
parents: 67
diff changeset
728 TREE_READONLY (vnode->decl) = true;
kono
parents: 67
diff changeset
729 return false;
kono
parents: 67
diff changeset
730 }
kono
parents: 67
diff changeset
731
kono
parents: 67
diff changeset
732 /* Set writeonly bit and clear the initalizer, since it will not be needed. */
kono
parents: 67
diff changeset
733
kono
parents: 67
diff changeset
734 bool
kono
parents: 67
diff changeset
735 set_writeonly_bit (varpool_node *vnode, void *data)
kono
parents: 67
diff changeset
736 {
kono
parents: 67
diff changeset
737 vnode->writeonly = true;
kono
parents: 67
diff changeset
738 if (optimize || in_lto_p)
kono
parents: 67
diff changeset
739 {
kono
parents: 67
diff changeset
740 DECL_INITIAL (vnode->decl) = NULL;
kono
parents: 67
diff changeset
741 if (!vnode->alias)
kono
parents: 67
diff changeset
742 {
kono
parents: 67
diff changeset
743 if (vnode->num_references ())
kono
parents: 67
diff changeset
744 *(bool *)data = true;
kono
parents: 67
diff changeset
745 vnode->remove_all_references ();
kono
parents: 67
diff changeset
746 }
kono
parents: 67
diff changeset
747 }
kono
parents: 67
diff changeset
748 return false;
kono
parents: 67
diff changeset
749 }
kono
parents: 67
diff changeset
750
kono
parents: 67
diff changeset
751 /* Clear addressale bit of VNODE. */
kono
parents: 67
diff changeset
752
kono
parents: 67
diff changeset
753 bool
kono
parents: 67
diff changeset
754 clear_addressable_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
kono
parents: 67
diff changeset
755 {
kono
parents: 67
diff changeset
756 vnode->address_taken = false;
kono
parents: 67
diff changeset
757 TREE_ADDRESSABLE (vnode->decl) = 0;
kono
parents: 67
diff changeset
758 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
760
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
761 /* Discover variables that have no longer address taken, are read-only or
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
762 write-only and update their flags.
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
763
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
764 Return true when unreachable symbol removal should be done.
111
kono
parents: 67
diff changeset
765
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
766 FIXME: This cannot be done in between gimplify and omp_expand since
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
767 readonly flag plays role on what is shared and what is not. Currently we do
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
768 this transformation as part of whole program visibility and re-do at
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
769 ipa-reference pass (to take into account clonning), but it would
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
770 make sense to do it before early optimizations. */
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
771
111
kono
parents: 67
diff changeset
772 bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
773 ipa_discover_variable_flags (void)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
774 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
775 if (!flag_ipa_reference_addressable)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
776 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
777
111
kono
parents: 67
diff changeset
778 bool remove_p = false;
kono
parents: 67
diff changeset
779 varpool_node *vnode;
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
780 if (dump_file)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
781 fprintf (dump_file, "Clearing variable flags:");
111
kono
parents: 67
diff changeset
782 FOR_EACH_VARIABLE (vnode)
kono
parents: 67
diff changeset
783 if (!vnode->alias
kono
parents: 67
diff changeset
784 && (TREE_ADDRESSABLE (vnode->decl)
kono
parents: 67
diff changeset
785 || !vnode->writeonly
kono
parents: 67
diff changeset
786 || !TREE_READONLY (vnode->decl)))
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
787 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
788 bool written = false;
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
789 bool address_taken = false;
111
kono
parents: 67
diff changeset
790 bool read = false;
kono
parents: 67
diff changeset
791 bool explicit_refs = true;
kono
parents: 67
diff changeset
792
kono
parents: 67
diff changeset
793 process_references (vnode, &written, &address_taken, &read,
kono
parents: 67
diff changeset
794 &explicit_refs);
kono
parents: 67
diff changeset
795 if (!explicit_refs)
kono
parents: 67
diff changeset
796 continue;
kono
parents: 67
diff changeset
797 if (!address_taken)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
798 {
111
kono
parents: 67
diff changeset
799 if (TREE_ADDRESSABLE (vnode->decl) && dump_file)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
800 fprintf (dump_file, " %s (non-addressable)",
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
801 vnode->dump_name ());
111
kono
parents: 67
diff changeset
802 vnode->call_for_symbol_and_aliases (clear_addressable_bit, NULL,
kono
parents: 67
diff changeset
803 true);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
804 }
111
kono
parents: 67
diff changeset
805 if (!address_taken && !written
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
806 /* Making variable in explicit section readonly can cause section
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
807 type conflict.
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
808 See e.g. gcc.c-torture/compile/pr23237.c */
111
kono
parents: 67
diff changeset
809 && vnode->get_section () == NULL)
kono
parents: 67
diff changeset
810 {
kono
parents: 67
diff changeset
811 if (!TREE_READONLY (vnode->decl) && dump_file)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
812 fprintf (dump_file, " %s (read-only)", vnode->dump_name ());
111
kono
parents: 67
diff changeset
813 vnode->call_for_symbol_and_aliases (set_readonly_bit, NULL, true);
kono
parents: 67
diff changeset
814 }
kono
parents: 67
diff changeset
815 if (!vnode->writeonly && !read && !address_taken && written)
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
816 {
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
817 if (dump_file)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
818 fprintf (dump_file, " %s (write-only)", vnode->dump_name ());
111
kono
parents: 67
diff changeset
819 vnode->call_for_symbol_and_aliases (set_writeonly_bit, &remove_p,
kono
parents: 67
diff changeset
820 true);
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
821 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
822 }
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
823 if (dump_file)
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
824 fprintf (dump_file, "\n");
111
kono
parents: 67
diff changeset
825 return remove_p;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
826 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
827
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
828 /* Generate and emit a static constructor or destructor. WHICH must
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
829 be one of 'I' (for a constructor), 'D' (for a destructor).
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
830 BODY is a STATEMENT_LIST containing GENERIC
111
kono
parents: 67
diff changeset
831 statements. PRIORITY is the initialization priority for this
kono
parents: 67
diff changeset
832 constructor or destructor.
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
833
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
834 FINAL specify whether the externally visible name for collect2 should
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
835 be produced. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
836
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
837 static void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
838 cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
839 tree optimization,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
840 tree target)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
841 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
842 static int counter = 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
843 char which_buf[16];
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
844 tree decl, name, resdecl;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
845
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
846 /* The priority is encoded in the constructor or destructor name.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
847 collect2 will sort the names and arrange that they are called at
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
848 program startup. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
849 if (!targetm.have_ctors_dtors && final)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
850 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
851 sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
852 name = get_file_function_name (which_buf);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
853 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
854 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
855 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
856 /* Proudce sane name but one not recognizable by collect2, just for the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
857 case we fail to inline the function. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
858 sprintf (which_buf, "_sub_%c_%.5d_%d", which, priority, counter++);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
859 name = get_identifier (which_buf);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
860 }
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
861
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
862 decl = build_decl (input_location, FUNCTION_DECL, name,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
863 build_function_type_list (void_type_node, NULL_TREE));
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
864 current_function_decl = decl;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
865
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
866 resdecl = build_decl (input_location,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
867 RESULT_DECL, NULL_TREE, void_type_node);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
868 DECL_ARTIFICIAL (resdecl) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
869 DECL_RESULT (decl) = resdecl;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
870 DECL_CONTEXT (resdecl) = decl;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
871
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
872 allocate_struct_function (decl, false);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
873
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
874 TREE_STATIC (decl) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
875 TREE_USED (decl) = 1;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
876 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl) = optimization;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
877 DECL_FUNCTION_SPECIFIC_TARGET (decl) = target;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
878 DECL_ARTIFICIAL (decl) = 1;
111
kono
parents: 67
diff changeset
879 DECL_IGNORED_P (decl) = 1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
880 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
881 DECL_SAVED_TREE (decl) = body;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
882 if (!targetm.have_ctors_dtors && final)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
883 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
884 TREE_PUBLIC (decl) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
885 DECL_PRESERVE_P (decl) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
886 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
887 DECL_UNINLINABLE (decl) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
888
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
889 DECL_INITIAL (decl) = make_node (BLOCK);
111
kono
parents: 67
diff changeset
890 BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
891 TREE_USED (DECL_INITIAL (decl)) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
892
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
893 DECL_SOURCE_LOCATION (decl) = input_location;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
894 cfun->function_end_locus = input_location;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
895
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
896 switch (which)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
897 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
898 case 'I':
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
899 DECL_STATIC_CONSTRUCTOR (decl) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
900 decl_init_priority_insert (decl, priority);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
901 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
902 case 'D':
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
903 DECL_STATIC_DESTRUCTOR (decl) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
904 decl_fini_priority_insert (decl, priority);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
905 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
906 default:
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
907 gcc_unreachable ();
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
908 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
909
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
910 gimplify_function_tree (decl);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
911
111
kono
parents: 67
diff changeset
912 cgraph_node::add_new_function (decl, false);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
913
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
914 set_cfun (NULL);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
915 current_function_decl = NULL;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
916 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
917
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
918 /* Generate and emit a static constructor or destructor. WHICH must
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
919 be one of 'I' (for a constructor) or 'D' (for a destructor).
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
920 BODY is a STATEMENT_LIST containing GENERIC
111
kono
parents: 67
diff changeset
921 statements. PRIORITY is the initialization priority for this
kono
parents: 67
diff changeset
922 constructor or destructor. */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
923
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
924 void
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
925 cgraph_build_static_cdtor (char which, tree body, int priority)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
926 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
927 /* FIXME: We should be able to
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
928 gcc_assert (!in_lto_p);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
929 because at LTO time the global options are not safe to use.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
930 Unfortunately ASAN finish_file will produce constructors late and they
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
931 may lead to surprises. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
932 cgraph_build_static_cdtor_1 (which, body, priority, false,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
933 optimization_default_node,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
934 target_option_default_node);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
935 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
936
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
937 /* When target does not have ctors and dtors, we call all constructor
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
938 and destructor by special initialization/destruction function
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
939 recognized by collect2.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
940
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
941 When we are going to build this function, collect all constructors and
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
942 destructors and turn them into normal functions. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
943
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
944 static void
111
kono
parents: 67
diff changeset
945 record_cdtor_fn (struct cgraph_node *node, vec<tree> *ctors, vec<tree> *dtors)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
946 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
947 if (DECL_STATIC_CONSTRUCTOR (node->decl))
111
kono
parents: 67
diff changeset
948 ctors->safe_push (node->decl);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
949 if (DECL_STATIC_DESTRUCTOR (node->decl))
111
kono
parents: 67
diff changeset
950 dtors->safe_push (node->decl);
kono
parents: 67
diff changeset
951 node = cgraph_node::get (node->decl);
kono
parents: 67
diff changeset
952 DECL_DISREGARD_INLINE_LIMITS (node->decl) = 1;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
953 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
954
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
955 /* Define global constructors/destructor functions for the CDTORS, of
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
956 which they are LEN. The CDTORS are sorted by initialization
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
957 priority. If CTOR_P is true, these are constructors; otherwise,
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
958 they are destructors. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
959
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
960 static void
111
kono
parents: 67
diff changeset
961 build_cdtor (bool ctor_p, const vec<tree> &cdtors)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
962 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
963 size_t i,j;
111
kono
parents: 67
diff changeset
964 size_t len = cdtors.length ();
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
965
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
966 i = 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
967 while (i < len)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
968 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
969 tree body;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
970 tree fn;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
971 priority_type priority;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
972
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
973 priority = 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
974 body = NULL_TREE;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
975 j = i;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
976 do
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
977 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
978 priority_type p;
111
kono
parents: 67
diff changeset
979 fn = cdtors[j];
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
980 p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
981 if (j == i)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
982 priority = p;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
983 else if (p != priority)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
984 break;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
985 j++;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
986 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
987 while (j < len);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
988
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
989 /* When there is only one cdtor and target supports them, do nothing. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
990 if (j == i + 1
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
991 && targetm.have_ctors_dtors)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
992 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
993 i++;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
994 continue;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
995 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
996 /* Find the next batch of constructors/destructors with the same
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
997 initialization priority. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
998 for (;i < j; i++)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
999 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1000 tree call;
111
kono
parents: 67
diff changeset
1001 fn = cdtors[i];
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1002 call = build_call_expr (fn, 0);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1003 if (ctor_p)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1004 DECL_STATIC_CONSTRUCTOR (fn) = 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1005 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1006 DECL_STATIC_DESTRUCTOR (fn) = 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1007 /* We do not want to optimize away pure/const calls here.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1008 When optimizing, these should be already removed, when not
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1009 optimizing, we want user to be able to breakpoint in them. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1010 TREE_SIDE_EFFECTS (call) = 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1011 append_to_statement_list (call, &body);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1012 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1013 gcc_assert (body != NULL_TREE);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1014 /* Generate a function to call all the function of like
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1015 priority. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1016 cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1017 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (cdtors[0]),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1018 DECL_FUNCTION_SPECIFIC_TARGET (cdtors[0]));
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1019 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1020 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1021
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1022 /* Comparison function for qsort. P1 and P2 are actually of type
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1023 "tree *" and point to static constructors. DECL_INIT_PRIORITY is
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1024 used to determine the sort order. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1025
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1026 static int
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1027 compare_ctor (const void *p1, const void *p2)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1028 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1029 tree f1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1030 tree f2;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1031 int priority1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1032 int priority2;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1033
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1034 f1 = *(const tree *)p1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1035 f2 = *(const tree *)p2;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1036 priority1 = DECL_INIT_PRIORITY (f1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1037 priority2 = DECL_INIT_PRIORITY (f2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1038
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1039 if (priority1 < priority2)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1040 return -1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1041 else if (priority1 > priority2)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1042 return 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1043 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1044 /* Ensure a stable sort. Constructors are executed in backwarding
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1045 order to make LTO initialize braries first. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1046 return DECL_UID (f2) - DECL_UID (f1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1047 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1048
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1049 /* Comparison function for qsort. P1 and P2 are actually of type
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1050 "tree *" and point to static destructors. DECL_FINI_PRIORITY is
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1051 used to determine the sort order. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1052
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1053 static int
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1054 compare_dtor (const void *p1, const void *p2)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1055 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1056 tree f1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1057 tree f2;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1058 int priority1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1059 int priority2;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1060
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1061 f1 = *(const tree *)p1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1062 f2 = *(const tree *)p2;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1063 priority1 = DECL_FINI_PRIORITY (f1);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1064 priority2 = DECL_FINI_PRIORITY (f2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1065
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1066 if (priority1 < priority2)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1067 return -1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1068 else if (priority1 > priority2)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1069 return 1;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1070 else
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1071 /* Ensure a stable sort. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1072 return DECL_UID (f1) - DECL_UID (f2);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1073 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1074
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1075 /* Generate functions to call static constructors and destructors
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1076 for targets that do not support .ctors/.dtors sections. These
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1077 functions have magic names which are detected by collect2. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1078
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1079 static void
111
kono
parents: 67
diff changeset
1080 build_cdtor_fns (vec<tree> *ctors, vec<tree> *dtors)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1081 {
111
kono
parents: 67
diff changeset
1082 if (!ctors->is_empty ())
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1083 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1084 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
111
kono
parents: 67
diff changeset
1085 ctors->qsort (compare_ctor);
kono
parents: 67
diff changeset
1086 build_cdtor (/*ctor_p=*/true, *ctors);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1087 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1088
111
kono
parents: 67
diff changeset
1089 if (!dtors->is_empty ())
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1090 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1091 gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
111
kono
parents: 67
diff changeset
1092 dtors->qsort (compare_dtor);
kono
parents: 67
diff changeset
1093 build_cdtor (/*ctor_p=*/false, *dtors);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1094 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1095 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1096
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1097 /* Look for constructors and destructors and produce function calling them.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1098 This is needed for targets not supporting ctors or dtors, but we perform the
111
kono
parents: 67
diff changeset
1099 transformation also at linktime to merge possibly numerous
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1100 constructors/destructors into single function to improve code locality and
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1101 reduce size. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1102
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1103 static unsigned int
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1104 ipa_cdtor_merge (void)
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1105 {
111
kono
parents: 67
diff changeset
1106 /* A vector of FUNCTION_DECLs declared as static constructors. */
kono
parents: 67
diff changeset
1107 auto_vec<tree, 20> ctors;
kono
parents: 67
diff changeset
1108 /* A vector of FUNCTION_DECLs declared as static destructors. */
kono
parents: 67
diff changeset
1109 auto_vec<tree, 20> dtors;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1110 struct cgraph_node *node;
111
kono
parents: 67
diff changeset
1111 FOR_EACH_DEFINED_FUNCTION (node)
kono
parents: 67
diff changeset
1112 if (DECL_STATIC_CONSTRUCTOR (node->decl)
kono
parents: 67
diff changeset
1113 || DECL_STATIC_DESTRUCTOR (node->decl))
kono
parents: 67
diff changeset
1114 record_cdtor_fn (node, &ctors, &dtors);
kono
parents: 67
diff changeset
1115 build_cdtor_fns (&ctors, &dtors);
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1116 return 0;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1117 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1118
111
kono
parents: 67
diff changeset
1119 namespace {
kono
parents: 67
diff changeset
1120
kono
parents: 67
diff changeset
1121 const pass_data pass_data_ipa_cdtor_merge =
kono
parents: 67
diff changeset
1122 {
kono
parents: 67
diff changeset
1123 IPA_PASS, /* type */
kono
parents: 67
diff changeset
1124 "cdtor", /* name */
kono
parents: 67
diff changeset
1125 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
1126 TV_CGRAPHOPT, /* tv_id */
kono
parents: 67
diff changeset
1127 0, /* properties_required */
kono
parents: 67
diff changeset
1128 0, /* properties_provided */
kono
parents: 67
diff changeset
1129 0, /* properties_destroyed */
kono
parents: 67
diff changeset
1130 0, /* todo_flags_start */
kono
parents: 67
diff changeset
1131 0, /* todo_flags_finish */
kono
parents: 67
diff changeset
1132 };
kono
parents: 67
diff changeset
1133
kono
parents: 67
diff changeset
1134 class pass_ipa_cdtor_merge : public ipa_opt_pass_d
kono
parents: 67
diff changeset
1135 {
kono
parents: 67
diff changeset
1136 public:
kono
parents: 67
diff changeset
1137 pass_ipa_cdtor_merge (gcc::context *ctxt)
kono
parents: 67
diff changeset
1138 : ipa_opt_pass_d (pass_data_ipa_cdtor_merge, ctxt,
kono
parents: 67
diff changeset
1139 NULL, /* generate_summary */
kono
parents: 67
diff changeset
1140 NULL, /* write_summary */
kono
parents: 67
diff changeset
1141 NULL, /* read_summary */
kono
parents: 67
diff changeset
1142 NULL, /* write_optimization_summary */
kono
parents: 67
diff changeset
1143 NULL, /* read_optimization_summary */
kono
parents: 67
diff changeset
1144 NULL, /* stmt_fixup */
kono
parents: 67
diff changeset
1145 0, /* function_transform_todo_flags_start */
kono
parents: 67
diff changeset
1146 NULL, /* function_transform */
kono
parents: 67
diff changeset
1147 NULL) /* variable_transform */
kono
parents: 67
diff changeset
1148 {}
kono
parents: 67
diff changeset
1149
kono
parents: 67
diff changeset
1150 /* opt_pass methods: */
kono
parents: 67
diff changeset
1151 virtual bool gate (function *);
kono
parents: 67
diff changeset
1152 virtual unsigned int execute (function *) { return ipa_cdtor_merge (); }
kono
parents: 67
diff changeset
1153
kono
parents: 67
diff changeset
1154 }; // class pass_ipa_cdtor_merge
kono
parents: 67
diff changeset
1155
kono
parents: 67
diff changeset
1156 bool
kono
parents: 67
diff changeset
1157 pass_ipa_cdtor_merge::gate (function *)
kono
parents: 67
diff changeset
1158 {
kono
parents: 67
diff changeset
1159 /* Perform the pass when we have no ctors/dtors support
kono
parents: 67
diff changeset
1160 or at LTO time to merge multiple constructors into single
kono
parents: 67
diff changeset
1161 function. */
kono
parents: 67
diff changeset
1162 return !targetm.have_ctors_dtors || in_lto_p;
kono
parents: 67
diff changeset
1163 }
kono
parents: 67
diff changeset
1164
kono
parents: 67
diff changeset
1165 } // anon namespace
kono
parents: 67
diff changeset
1166
kono
parents: 67
diff changeset
1167 ipa_opt_pass_d *
kono
parents: 67
diff changeset
1168 make_pass_ipa_cdtor_merge (gcc::context *ctxt)
kono
parents: 67
diff changeset
1169 {
kono
parents: 67
diff changeset
1170 return new pass_ipa_cdtor_merge (ctxt);
kono
parents: 67
diff changeset
1171 }
kono
parents: 67
diff changeset
1172
kono
parents: 67
diff changeset
1173 /* Invalid pointer representing BOTTOM for single user dataflow. */
kono
parents: 67
diff changeset
1174 #define BOTTOM ((cgraph_node *)(size_t) 2)
kono
parents: 67
diff changeset
1175
kono
parents: 67
diff changeset
1176 /* Meet operation for single user dataflow.
kono
parents: 67
diff changeset
1177 Here we want to associate variables with sigle function that may access it.
kono
parents: 67
diff changeset
1178
kono
parents: 67
diff changeset
1179 FUNCTION is current single user of a variable, VAR is variable that uses it.
kono
parents: 67
diff changeset
1180 Latttice is stored in SINGLE_USER_MAP.
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1181
111
kono
parents: 67
diff changeset
1182 We represent:
kono
parents: 67
diff changeset
1183 - TOP by no entry in SIGNLE_USER_MAP
kono
parents: 67
diff changeset
1184 - BOTTOM by BOTTOM in AUX pointer (to save lookups)
kono
parents: 67
diff changeset
1185 - known single user by cgraph pointer in SINGLE_USER_MAP. */
kono
parents: 67
diff changeset
1186
kono
parents: 67
diff changeset
1187 cgraph_node *
kono
parents: 67
diff changeset
1188 meet (cgraph_node *function, varpool_node *var,
kono
parents: 67
diff changeset
1189 hash_map<varpool_node *, cgraph_node *> &single_user_map)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1190 {
111
kono
parents: 67
diff changeset
1191 struct cgraph_node *user, **f;
kono
parents: 67
diff changeset
1192
kono
parents: 67
diff changeset
1193 if (var->aux == BOTTOM)
kono
parents: 67
diff changeset
1194 return BOTTOM;
kono
parents: 67
diff changeset
1195
kono
parents: 67
diff changeset
1196 f = single_user_map.get (var);
kono
parents: 67
diff changeset
1197 if (!f)
kono
parents: 67
diff changeset
1198 return function;
kono
parents: 67
diff changeset
1199 user = *f;
kono
parents: 67
diff changeset
1200 if (!function)
kono
parents: 67
diff changeset
1201 return user;
kono
parents: 67
diff changeset
1202 else if (function != user)
kono
parents: 67
diff changeset
1203 return BOTTOM;
kono
parents: 67
diff changeset
1204 else
kono
parents: 67
diff changeset
1205 return function;
kono
parents: 67
diff changeset
1206 }
kono
parents: 67
diff changeset
1207
kono
parents: 67
diff changeset
1208 /* Propagation step of single-use dataflow.
kono
parents: 67
diff changeset
1209
kono
parents: 67
diff changeset
1210 Check all uses of VNODE and see if they are used by single function FUNCTION.
kono
parents: 67
diff changeset
1211 SINGLE_USER_MAP represents the dataflow lattice. */
kono
parents: 67
diff changeset
1212
kono
parents: 67
diff changeset
1213 cgraph_node *
kono
parents: 67
diff changeset
1214 propagate_single_user (varpool_node *vnode, cgraph_node *function,
kono
parents: 67
diff changeset
1215 hash_map<varpool_node *, cgraph_node *> &single_user_map)
kono
parents: 67
diff changeset
1216 {
kono
parents: 67
diff changeset
1217 int i;
kono
parents: 67
diff changeset
1218 struct ipa_ref *ref;
kono
parents: 67
diff changeset
1219
kono
parents: 67
diff changeset
1220 gcc_assert (!vnode->externally_visible);
kono
parents: 67
diff changeset
1221
kono
parents: 67
diff changeset
1222 /* If node is an alias, first meet with its target. */
kono
parents: 67
diff changeset
1223 if (vnode->alias)
kono
parents: 67
diff changeset
1224 function = meet (function, vnode->get_alias_target (), single_user_map);
kono
parents: 67
diff changeset
1225
kono
parents: 67
diff changeset
1226 /* Check all users and see if they correspond to a single function. */
kono
parents: 67
diff changeset
1227 for (i = 0; vnode->iterate_referring (i, ref) && function != BOTTOM; i++)
kono
parents: 67
diff changeset
1228 {
kono
parents: 67
diff changeset
1229 struct cgraph_node *cnode = dyn_cast <cgraph_node *> (ref->referring);
kono
parents: 67
diff changeset
1230 if (cnode)
kono
parents: 67
diff changeset
1231 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1232 if (cnode->inlined_to)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1233 cnode = cnode->inlined_to;
111
kono
parents: 67
diff changeset
1234 if (!function)
kono
parents: 67
diff changeset
1235 function = cnode;
kono
parents: 67
diff changeset
1236 else if (function != cnode)
kono
parents: 67
diff changeset
1237 function = BOTTOM;
kono
parents: 67
diff changeset
1238 }
kono
parents: 67
diff changeset
1239 else
kono
parents: 67
diff changeset
1240 function = meet (function, dyn_cast <varpool_node *> (ref->referring),
kono
parents: 67
diff changeset
1241 single_user_map);
kono
parents: 67
diff changeset
1242 }
kono
parents: 67
diff changeset
1243 return function;
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1244 }
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1245
111
kono
parents: 67
diff changeset
1246 /* Pass setting used_by_single_function flag.
kono
parents: 67
diff changeset
1247 This flag is set on variable when there is only one function that may
kono
parents: 67
diff changeset
1248 possibly referr to it. */
kono
parents: 67
diff changeset
1249
kono
parents: 67
diff changeset
1250 static unsigned int
kono
parents: 67
diff changeset
1251 ipa_single_use (void)
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1252 {
111
kono
parents: 67
diff changeset
1253 varpool_node *first = (varpool_node *) (void *) 1;
kono
parents: 67
diff changeset
1254 varpool_node *var;
kono
parents: 67
diff changeset
1255 hash_map<varpool_node *, cgraph_node *> single_user_map;
kono
parents: 67
diff changeset
1256
kono
parents: 67
diff changeset
1257 FOR_EACH_DEFINED_VARIABLE (var)
kono
parents: 67
diff changeset
1258 if (!var->all_refs_explicit_p ())
kono
parents: 67
diff changeset
1259 var->aux = BOTTOM;
kono
parents: 67
diff changeset
1260 else
kono
parents: 67
diff changeset
1261 {
kono
parents: 67
diff changeset
1262 /* Enqueue symbol for dataflow. */
kono
parents: 67
diff changeset
1263 var->aux = first;
kono
parents: 67
diff changeset
1264 first = var;
kono
parents: 67
diff changeset
1265 }
kono
parents: 67
diff changeset
1266
kono
parents: 67
diff changeset
1267 /* The actual dataflow. */
kono
parents: 67
diff changeset
1268
kono
parents: 67
diff changeset
1269 while (first != (void *) 1)
kono
parents: 67
diff changeset
1270 {
kono
parents: 67
diff changeset
1271 cgraph_node *user, *orig_user, **f;
kono
parents: 67
diff changeset
1272
kono
parents: 67
diff changeset
1273 var = first;
kono
parents: 67
diff changeset
1274 first = (varpool_node *)first->aux;
kono
parents: 67
diff changeset
1275
kono
parents: 67
diff changeset
1276 f = single_user_map.get (var);
kono
parents: 67
diff changeset
1277 if (f)
kono
parents: 67
diff changeset
1278 orig_user = *f;
kono
parents: 67
diff changeset
1279 else
kono
parents: 67
diff changeset
1280 orig_user = NULL;
kono
parents: 67
diff changeset
1281 user = propagate_single_user (var, orig_user, single_user_map);
kono
parents: 67
diff changeset
1282
kono
parents: 67
diff changeset
1283 gcc_checking_assert (var->aux != BOTTOM);
kono
parents: 67
diff changeset
1284
kono
parents: 67
diff changeset
1285 /* If user differs, enqueue all references. */
kono
parents: 67
diff changeset
1286 if (user != orig_user)
kono
parents: 67
diff changeset
1287 {
kono
parents: 67
diff changeset
1288 unsigned int i;
kono
parents: 67
diff changeset
1289 ipa_ref *ref;
kono
parents: 67
diff changeset
1290
kono
parents: 67
diff changeset
1291 single_user_map.put (var, user);
kono
parents: 67
diff changeset
1292
kono
parents: 67
diff changeset
1293 /* Enqueue all aliases for re-processing. */
kono
parents: 67
diff changeset
1294 for (i = 0; var->iterate_direct_aliases (i, ref); i++)
kono
parents: 67
diff changeset
1295 if (!ref->referring->aux)
kono
parents: 67
diff changeset
1296 {
kono
parents: 67
diff changeset
1297 ref->referring->aux = first;
kono
parents: 67
diff changeset
1298 first = dyn_cast <varpool_node *> (ref->referring);
kono
parents: 67
diff changeset
1299 }
kono
parents: 67
diff changeset
1300 /* Enqueue all users for re-processing. */
kono
parents: 67
diff changeset
1301 for (i = 0; var->iterate_reference (i, ref); i++)
kono
parents: 67
diff changeset
1302 if (!ref->referred->aux
kono
parents: 67
diff changeset
1303 && ref->referred->definition
kono
parents: 67
diff changeset
1304 && is_a <varpool_node *> (ref->referred))
kono
parents: 67
diff changeset
1305 {
kono
parents: 67
diff changeset
1306 ref->referred->aux = first;
kono
parents: 67
diff changeset
1307 first = dyn_cast <varpool_node *> (ref->referred);
kono
parents: 67
diff changeset
1308 }
kono
parents: 67
diff changeset
1309
kono
parents: 67
diff changeset
1310 /* If user is BOTTOM, just punt on this var. */
kono
parents: 67
diff changeset
1311 if (user == BOTTOM)
kono
parents: 67
diff changeset
1312 var->aux = BOTTOM;
kono
parents: 67
diff changeset
1313 else
kono
parents: 67
diff changeset
1314 var->aux = NULL;
kono
parents: 67
diff changeset
1315 }
kono
parents: 67
diff changeset
1316 else
kono
parents: 67
diff changeset
1317 var->aux = NULL;
kono
parents: 67
diff changeset
1318 }
kono
parents: 67
diff changeset
1319
kono
parents: 67
diff changeset
1320 FOR_EACH_DEFINED_VARIABLE (var)
kono
parents: 67
diff changeset
1321 {
kono
parents: 67
diff changeset
1322 if (var->aux != BOTTOM)
kono
parents: 67
diff changeset
1323 {
kono
parents: 67
diff changeset
1324 /* Not having the single user known means that the VAR is
kono
parents: 67
diff changeset
1325 unreachable. Either someone forgot to remove unreachable
kono
parents: 67
diff changeset
1326 variables or the reachability here is wrong. */
kono
parents: 67
diff changeset
1327
kono
parents: 67
diff changeset
1328 gcc_checking_assert (single_user_map.get (var));
kono
parents: 67
diff changeset
1329
kono
parents: 67
diff changeset
1330 if (dump_file)
kono
parents: 67
diff changeset
1331 {
kono
parents: 67
diff changeset
1332 fprintf (dump_file, "Variable %s is used by single function\n",
kono
parents: 67
diff changeset
1333 var->dump_name ());
kono
parents: 67
diff changeset
1334 }
kono
parents: 67
diff changeset
1335 var->used_by_single_function = true;
kono
parents: 67
diff changeset
1336 }
kono
parents: 67
diff changeset
1337 var->aux = NULL;
kono
parents: 67
diff changeset
1338 }
kono
parents: 67
diff changeset
1339 return 0;
kono
parents: 67
diff changeset
1340 }
kono
parents: 67
diff changeset
1341
kono
parents: 67
diff changeset
1342 namespace {
kono
parents: 67
diff changeset
1343
kono
parents: 67
diff changeset
1344 const pass_data pass_data_ipa_single_use =
kono
parents: 67
diff changeset
1345 {
kono
parents: 67
diff changeset
1346 IPA_PASS, /* type */
kono
parents: 67
diff changeset
1347 "single-use", /* name */
kono
parents: 67
diff changeset
1348 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
1349 TV_CGRAPHOPT, /* tv_id */
kono
parents: 67
diff changeset
1350 0, /* properties_required */
kono
parents: 67
diff changeset
1351 0, /* properties_provided */
kono
parents: 67
diff changeset
1352 0, /* properties_destroyed */
kono
parents: 67
diff changeset
1353 0, /* todo_flags_start */
kono
parents: 67
diff changeset
1354 0, /* todo_flags_finish */
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
1355 };
111
kono
parents: 67
diff changeset
1356
kono
parents: 67
diff changeset
1357 class pass_ipa_single_use : public ipa_opt_pass_d
kono
parents: 67
diff changeset
1358 {
kono
parents: 67
diff changeset
1359 public:
kono
parents: 67
diff changeset
1360 pass_ipa_single_use (gcc::context *ctxt)
kono
parents: 67
diff changeset
1361 : ipa_opt_pass_d (pass_data_ipa_single_use, ctxt,
kono
parents: 67
diff changeset
1362 NULL, /* generate_summary */
kono
parents: 67
diff changeset
1363 NULL, /* write_summary */
kono
parents: 67
diff changeset
1364 NULL, /* read_summary */
kono
parents: 67
diff changeset
1365 NULL, /* write_optimization_summary */
kono
parents: 67
diff changeset
1366 NULL, /* read_optimization_summary */
kono
parents: 67
diff changeset
1367 NULL, /* stmt_fixup */
kono
parents: 67
diff changeset
1368 0, /* function_transform_todo_flags_start */
kono
parents: 67
diff changeset
1369 NULL, /* function_transform */
kono
parents: 67
diff changeset
1370 NULL) /* variable_transform */
kono
parents: 67
diff changeset
1371 {}
kono
parents: 67
diff changeset
1372
kono
parents: 67
diff changeset
1373 /* opt_pass methods: */
kono
parents: 67
diff changeset
1374 virtual unsigned int execute (function *) { return ipa_single_use (); }
kono
parents: 67
diff changeset
1375
kono
parents: 67
diff changeset
1376 }; // class pass_ipa_single_use
kono
parents: 67
diff changeset
1377
kono
parents: 67
diff changeset
1378 } // anon namespace
kono
parents: 67
diff changeset
1379
kono
parents: 67
diff changeset
1380 ipa_opt_pass_d *
kono
parents: 67
diff changeset
1381 make_pass_ipa_single_use (gcc::context *ctxt)
kono
parents: 67
diff changeset
1382 {
kono
parents: 67
diff changeset
1383 return new pass_ipa_single_use (ctxt);
kono
parents: 67
diff changeset
1384 }
kono
parents: 67
diff changeset
1385
kono
parents: 67
diff changeset
1386 /* Materialize all clones. */
kono
parents: 67
diff changeset
1387
kono
parents: 67
diff changeset
1388 namespace {
kono
parents: 67
diff changeset
1389
kono
parents: 67
diff changeset
1390 const pass_data pass_data_materialize_all_clones =
kono
parents: 67
diff changeset
1391 {
kono
parents: 67
diff changeset
1392 SIMPLE_IPA_PASS, /* type */
kono
parents: 67
diff changeset
1393 "materialize-all-clones", /* name */
kono
parents: 67
diff changeset
1394 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
1395 TV_IPA_OPT, /* tv_id */
kono
parents: 67
diff changeset
1396 0, /* properties_required */
kono
parents: 67
diff changeset
1397 0, /* properties_provided */
kono
parents: 67
diff changeset
1398 0, /* properties_destroyed */
kono
parents: 67
diff changeset
1399 0, /* todo_flags_start */
kono
parents: 67
diff changeset
1400 0, /* todo_flags_finish */
kono
parents: 67
diff changeset
1401 };
kono
parents: 67
diff changeset
1402
kono
parents: 67
diff changeset
1403 class pass_materialize_all_clones : public simple_ipa_opt_pass
kono
parents: 67
diff changeset
1404 {
kono
parents: 67
diff changeset
1405 public:
kono
parents: 67
diff changeset
1406 pass_materialize_all_clones (gcc::context *ctxt)
kono
parents: 67
diff changeset
1407 : simple_ipa_opt_pass (pass_data_materialize_all_clones, ctxt)
kono
parents: 67
diff changeset
1408 {}
kono
parents: 67
diff changeset
1409
kono
parents: 67
diff changeset
1410 /* opt_pass methods: */
kono
parents: 67
diff changeset
1411 virtual unsigned int execute (function *)
kono
parents: 67
diff changeset
1412 {
kono
parents: 67
diff changeset
1413 symtab->materialize_all_clones ();
kono
parents: 67
diff changeset
1414 return 0;
kono
parents: 67
diff changeset
1415 }
kono
parents: 67
diff changeset
1416
kono
parents: 67
diff changeset
1417 }; // class pass_materialize_all_clones
kono
parents: 67
diff changeset
1418
kono
parents: 67
diff changeset
1419 } // anon namespace
kono
parents: 67
diff changeset
1420
kono
parents: 67
diff changeset
1421 simple_ipa_opt_pass *
kono
parents: 67
diff changeset
1422 make_pass_materialize_all_clones (gcc::context *ctxt)
kono
parents: 67
diff changeset
1423 {
kono
parents: 67
diff changeset
1424 return new pass_materialize_all_clones (ctxt);
kono
parents: 67
diff changeset
1425 }