]>
Commit | Line | Data |
---|---|---|
46e8c075 | 1 | /* Perform optimizations on tree structure. |
2a8a8f8f | 2 | Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005 |
3c2426b9 | 3 | Free Software Foundation, Inc. |
46e8c075 MM |
4 | Written by Mark Michell (mark@codesourcery.com). |
5 | ||
f5adbb8d | 6 | This file is part of GCC. |
46e8c075 | 7 | |
f5adbb8d | 8 | GCC is free software; you can redistribute it and/or modify it |
06ceef4e RK |
9 | under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 2, or (at your option) | |
11 | any later version. | |
12 | ||
f5adbb8d | 13 | GCC is distributed in the hope that it will be useful, but |
06ceef4e RK |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | General Public License for more details. | |
9c96f3f8 | 17 | |
06ceef4e | 18 | You should have received a copy of the GNU General Public License |
f5adbb8d | 19 | along with GCC; see the file COPYING. If not, write to the Free |
1788952f KC |
20 | Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA |
21 | 02110-1301, USA. */ | |
46e8c075 MM |
22 | |
23 | #include "config.h" | |
24 | #include "system.h" | |
4977bab6 ZW |
25 | #include "coretypes.h" |
26 | #include "tm.h" | |
46e8c075 MM |
27 | #include "tree.h" |
28 | #include "cp-tree.h" | |
29 | #include "rtl.h" | |
30 | #include "insn-config.h" | |
574a0ef5 | 31 | #include "input.h" |
46e8c075 | 32 | #include "integrate.h" |
9c96f3f8 | 33 | #include "toplev.h" |
46e8c075 | 34 | #include "varray.h" |
b850de4f | 35 | #include "params.h" |
11fe225a | 36 | #include "hashtab.h" |
44d10c10 | 37 | #include "target.h" |
2b85879e | 38 | #include "debug.h" |
25af8512 | 39 | #include "tree-inline.h" |
6de9cd9a DN |
40 | #include "flags.h" |
41 | #include "langhooks.h" | |
42 | #include "diagnostic.h" | |
43 | #include "tree-dump.h" | |
eadf906f | 44 | #include "tree-gimple.h" |
46e8c075 | 45 | |
46e8c075 MM |
46 | /* Prototypes. */ |
47 | ||
b8ad8c93 | 48 | static void update_cloned_parm (tree, tree, bool); |
95fabfd3 | 49 | |
d60e5448 MM |
50 | /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor |
51 | or destructor. Update it to ensure that the source-position for | |
52 | the cloned parameter matches that for the original, and that the | |
53 | debugging generation code will be able to find the original PARM. */ | |
54 | ||
55 | static void | |
b8ad8c93 | 56 | update_cloned_parm (tree parm, tree cloned_parm, bool first) |
d60e5448 MM |
57 | { |
58 | DECL_ABSTRACT_ORIGIN (cloned_parm) = parm; | |
d30a825a | 59 | |
c6002625 | 60 | /* We may have taken its address. */ |
d30a825a NS |
61 | TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm); |
62 | ||
c6002625 | 63 | /* The definition might have different constness. */ |
d30a825a | 64 | TREE_READONLY (cloned_parm) = TREE_READONLY (parm); |
c8094d83 | 65 | |
b8ad8c93 | 66 | TREE_USED (cloned_parm) = !first || TREE_USED (parm); |
c8094d83 | 67 | |
c6002625 | 68 | /* The name may have changed from the declaration. */ |
d60e5448 | 69 | DECL_NAME (cloned_parm) = DECL_NAME (parm); |
f31686a3 | 70 | DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm); |
e777303f | 71 | TREE_TYPE (cloned_parm) = TREE_TYPE (parm); |
d60e5448 MM |
72 | } |
73 | ||
db9b2174 | 74 | /* FN is a function that has a complete body. Clone the body as |
838dfd8a | 75 | necessary. Returns nonzero if there's no longer any need to |
db9b2174 MM |
76 | process the main body. */ |
77 | ||
4977bab6 ZW |
78 | bool |
79 | maybe_clone_body (tree fn) | |
db9b2174 | 80 | { |
db9b2174 | 81 | tree clone; |
b8ad8c93 | 82 | bool first = true; |
db9b2174 | 83 | |
db9b2174 MM |
84 | /* We only clone constructors and destructors. */ |
85 | if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn) | |
86 | && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)) | |
87 | return 0; | |
88 | ||
5daf7c0a | 89 | /* Emit the DWARF1 abstract instance. */ |
2b85879e | 90 | (*debug_hooks->deferred_inline_function) (fn); |
5daf7c0a | 91 | |
db9b2174 MM |
92 | /* We know that any clones immediately follow FN in the TYPE_METHODS |
93 | list. */ | |
f44b0c8e | 94 | push_to_top_level (); |
4684cd27 | 95 | FOR_EACH_CLONE (clone, fn) |
db9b2174 MM |
96 | { |
97 | tree parm; | |
98 | tree clone_parm; | |
99 | int parmno; | |
25af8512 | 100 | splay_tree decl_map; |
db9b2174 MM |
101 | |
102 | /* Update CLONE's source position information to match FN's. */ | |
f31686a3 | 103 | DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn); |
99389463 | 104 | DECL_INLINE (clone) = DECL_INLINE (fn); |
79065db2 | 105 | DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn); |
3ec6bad3 MM |
106 | DECL_COMDAT (clone) = DECL_COMDAT (fn); |
107 | DECL_WEAK (clone) = DECL_WEAK (fn); | |
108 | DECL_ONE_ONLY (clone) = DECL_ONE_ONLY (fn); | |
109 | DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn); | |
459c43ad MM |
110 | DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn); |
111 | DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn); | |
112 | DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn); | |
113 | DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn); | |
b96ada87 | 114 | TREE_PUBLIC (clone) = TREE_PUBLIC (fn); |
968b41a1 | 115 | DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn); |
d7afec4b | 116 | DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn); |
db9b2174 | 117 | |
c6002625 | 118 | /* Adjust the parameter names and locations. */ |
02a1a68c NS |
119 | parm = DECL_ARGUMENTS (fn); |
120 | clone_parm = DECL_ARGUMENTS (clone); | |
4a90862e | 121 | /* Update the `this' parameter, which is always first. */ |
b8ad8c93 | 122 | update_cloned_parm (parm, clone_parm, first); |
4a90862e JM |
123 | parm = TREE_CHAIN (parm); |
124 | clone_parm = TREE_CHAIN (clone_parm); | |
02a1a68c NS |
125 | if (DECL_HAS_IN_CHARGE_PARM_P (fn)) |
126 | parm = TREE_CHAIN (parm); | |
127 | if (DECL_HAS_VTT_PARM_P (fn)) | |
128 | parm = TREE_CHAIN (parm); | |
129 | if (DECL_HAS_VTT_PARM_P (clone)) | |
130 | clone_parm = TREE_CHAIN (clone_parm); | |
131 | for (; parm; | |
132 | parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm)) | |
85b22f78 | 133 | /* Update this parameter. */ |
b8ad8c93 | 134 | update_cloned_parm (parm, clone_parm, first); |
02a1a68c | 135 | |
db9b2174 | 136 | /* Start processing the function. */ |
058b15c1 | 137 | start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED); |
db9b2174 | 138 | |
db9b2174 | 139 | /* Remap the parameters. */ |
25af8512 | 140 | decl_map = splay_tree_new (splay_tree_compare_pointers, NULL, NULL); |
db9b2174 MM |
141 | for (parmno = 0, |
142 | parm = DECL_ARGUMENTS (fn), | |
143 | clone_parm = DECL_ARGUMENTS (clone); | |
144 | parm; | |
145 | ++parmno, | |
146 | parm = TREE_CHAIN (parm)) | |
147 | { | |
148 | /* Map the in-charge parameter to an appropriate constant. */ | |
149 | if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1) | |
150 | { | |
151 | tree in_charge; | |
298d6f60 | 152 | in_charge = in_charge_arg_for_name (DECL_NAME (clone)); |
25af8512 | 153 | splay_tree_insert (decl_map, |
db9b2174 | 154 | (splay_tree_key) parm, |
3ec6bad3 | 155 | (splay_tree_value) in_charge); |
e0fff4b3 JM |
156 | } |
157 | else if (DECL_ARTIFICIAL (parm) | |
158 | && DECL_NAME (parm) == vtt_parm_identifier) | |
159 | { | |
3ec6bad3 MM |
160 | /* For a subobject constructor or destructor, the next |
161 | argument is the VTT parameter. Remap the VTT_PARM | |
162 | from the CLONE to this parameter. */ | |
e0fff4b3 | 163 | if (DECL_HAS_VTT_PARM_P (clone)) |
3ec6bad3 | 164 | { |
5daf7c0a | 165 | DECL_ABSTRACT_ORIGIN (clone_parm) = parm; |
25af8512 | 166 | splay_tree_insert (decl_map, |
e0fff4b3 | 167 | (splay_tree_key) parm, |
3ec6bad3 | 168 | (splay_tree_value) clone_parm); |
3ec6bad3 MM |
169 | clone_parm = TREE_CHAIN (clone_parm); |
170 | } | |
171 | /* Otherwise, map the VTT parameter to `NULL'. */ | |
e0fff4b3 | 172 | else |
3ec6bad3 | 173 | { |
25af8512 | 174 | splay_tree_insert (decl_map, |
e0fff4b3 | 175 | (splay_tree_key) parm, |
3ec6bad3 | 176 | (splay_tree_value) null_pointer_node); |
3ec6bad3 | 177 | } |
db9b2174 MM |
178 | } |
179 | /* Map other parameters to their equivalents in the cloned | |
180 | function. */ | |
181 | else | |
182 | { | |
25af8512 | 183 | splay_tree_insert (decl_map, |
db9b2174 MM |
184 | (splay_tree_key) parm, |
185 | (splay_tree_value) clone_parm); | |
186 | clone_parm = TREE_CHAIN (clone_parm); | |
187 | } | |
188 | } | |
189 | ||
44d10c10 PB |
190 | if (targetm.cxx.cdtor_returns_this ()) |
191 | { | |
192 | parm = DECL_RESULT (fn); | |
193 | clone_parm = DECL_RESULT (clone); | |
194 | splay_tree_insert (decl_map, (splay_tree_key) parm, | |
195 | (splay_tree_value) clone_parm); | |
196 | } | |
25af8512 AO |
197 | /* Clone the body. */ |
198 | clone_body (clone, fn, decl_map); | |
db9b2174 MM |
199 | |
200 | /* Clean up. */ | |
25af8512 | 201 | splay_tree_delete (decl_map); |
db9b2174 | 202 | |
b2dd096b MM |
203 | /* The clone can throw iff the original function can throw. */ |
204 | cp_function_chain->can_throw = !TREE_NOTHROW (fn); | |
205 | ||
db9b2174 | 206 | /* Now, expand this function into RTL, if appropriate. */ |
5daf7c0a JM |
207 | finish_function (0); |
208 | BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn); | |
8cd2462c | 209 | expand_or_defer_fn (clone); |
b8ad8c93 | 210 | first = false; |
db9b2174 | 211 | } |
f44b0c8e | 212 | pop_from_top_level (); |
9c96f3f8 | 213 | |
db9b2174 MM |
214 | /* We don't need to process the original function any further. */ |
215 | return 1; | |
216 | } |