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