00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "tree.h"
00025 #include "cp-tree.h"
00026 #include "rtl.h"
00027 #include "insn-config.h"
00028 #include "input.h"
00029 #include "integrate.h"
00030 #include "toplev.h"
00031 #include "varray.h"
00032 #include "ggc.h"
00033 #include "params.h"
00034 #include "hashtab.h"
00035 #include "debug.h"
00036 #include "tree-inline.h"
00037
00038
00039
00040 static tree calls_setjmp_r PARAMS ((tree *, int *, void *));
00041 static void update_cloned_parm PARAMS ((tree, tree));
00042 static void dump_function PARAMS ((enum tree_dump_index, tree));
00043
00044
00045
00046 void
00047 optimize_function (fn)
00048 tree fn;
00049 {
00050 dump_function (TDI_original, fn);
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 ++function_depth;
00062
00063 if (flag_inline_trees
00064
00065
00066
00067
00068 && !DECL_THUNK_P (fn))
00069 {
00070 optimize_inline_calls (fn);
00071
00072 dump_function (TDI_inlined, fn);
00073 }
00074
00075
00076 --function_depth;
00077
00078 dump_function (TDI_optimized, fn);
00079 }
00080
00081
00082
00083 static tree
00084 calls_setjmp_r (tp, walk_subtrees, data)
00085 tree *tp;
00086 int *walk_subtrees ATTRIBUTE_UNUSED;
00087 void *data ATTRIBUTE_UNUSED;
00088 {
00089
00090 if (TREE_CODE (*tp) != FUNCTION_DECL)
00091 return NULL_TREE;
00092
00093 return setjmp_call_p (*tp) ? *tp : NULL_TREE;
00094 }
00095
00096
00097
00098
00099
00100
00101 int
00102 calls_setjmp_p (fn)
00103 tree fn;
00104 {
00105 return walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
00106 calls_setjmp_r,
00107 NULL) != NULL_TREE;
00108 }
00109
00110
00111
00112
00113
00114
00115 static void
00116 update_cloned_parm (parm, cloned_parm)
00117 tree parm;
00118 tree cloned_parm;
00119 {
00120 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
00121
00122
00123 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
00124
00125
00126 TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
00127
00128 TREE_USED (cloned_parm) = TREE_USED (parm);
00129
00130
00131 DECL_NAME (cloned_parm) = DECL_NAME (parm);
00132 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm);
00133 }
00134
00135
00136
00137
00138
00139 int
00140 maybe_clone_body (fn)
00141 tree fn;
00142 {
00143 tree clone;
00144 int first = 1;
00145
00146
00147 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
00148 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
00149 return 0;
00150
00151
00152 (*debug_hooks->deferred_inline_function) (fn);
00153
00154
00155
00156 for (clone = TREE_CHAIN (fn);
00157 clone && DECL_CLONED_FUNCTION_P (clone);
00158 clone = TREE_CHAIN (clone), first = 0)
00159 {
00160 tree parm;
00161 tree clone_parm;
00162 int parmno;
00163 splay_tree decl_map;
00164
00165
00166 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
00167 DECL_INLINE (clone) = DECL_INLINE (fn);
00168 DID_INLINE_FUNC (clone) = DID_INLINE_FUNC (fn);
00169 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
00170 DECL_COMDAT (clone) = DECL_COMDAT (fn);
00171 DECL_WEAK (clone) = DECL_WEAK (fn);
00172 DECL_ONE_ONLY (clone) = DECL_ONE_ONLY (fn);
00173 DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
00174 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
00175 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
00176 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
00177 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
00178 TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
00179
00180
00181 parm = DECL_ARGUMENTS (fn);
00182 clone_parm = DECL_ARGUMENTS (clone);
00183
00184 update_cloned_parm (parm, clone_parm);
00185 parm = TREE_CHAIN (parm);
00186 clone_parm = TREE_CHAIN (clone_parm);
00187 if (DECL_HAS_IN_CHARGE_PARM_P (fn))
00188 parm = TREE_CHAIN (parm);
00189 if (DECL_HAS_VTT_PARM_P (fn))
00190 parm = TREE_CHAIN (parm);
00191 if (DECL_HAS_VTT_PARM_P (clone))
00192 clone_parm = TREE_CHAIN (clone_parm);
00193 for (; parm;
00194 parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm))
00195 {
00196
00197 update_cloned_parm (parm, clone_parm);
00198
00199 if (!first)
00200 TREE_USED (clone_parm) = 1;
00201 }
00202
00203
00204 push_to_top_level ();
00205 start_function (NULL_TREE, clone, NULL_TREE, SF_PRE_PARSED);
00206
00207
00208 decl_map = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
00209 for (parmno = 0,
00210 parm = DECL_ARGUMENTS (fn),
00211 clone_parm = DECL_ARGUMENTS (clone);
00212 parm;
00213 ++parmno,
00214 parm = TREE_CHAIN (parm))
00215 {
00216
00217 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
00218 {
00219 tree in_charge;
00220 in_charge = in_charge_arg_for_name (DECL_NAME (clone));
00221 splay_tree_insert (decl_map,
00222 (splay_tree_key) parm,
00223 (splay_tree_value) in_charge);
00224 }
00225 else if (DECL_ARTIFICIAL (parm)
00226 && DECL_NAME (parm) == vtt_parm_identifier)
00227 {
00228
00229
00230
00231 if (DECL_HAS_VTT_PARM_P (clone))
00232 {
00233 DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
00234 splay_tree_insert (decl_map,
00235 (splay_tree_key) parm,
00236 (splay_tree_value) clone_parm);
00237 clone_parm = TREE_CHAIN (clone_parm);
00238 }
00239
00240 else
00241 {
00242 splay_tree_insert (decl_map,
00243 (splay_tree_key) parm,
00244 (splay_tree_value) null_pointer_node);
00245 }
00246 }
00247
00248
00249 else
00250 {
00251 splay_tree_insert (decl_map,
00252 (splay_tree_key) parm,
00253 (splay_tree_value) clone_parm);
00254 clone_parm = TREE_CHAIN (clone_parm);
00255 }
00256 }
00257
00258
00259 clone_body (clone, fn, decl_map);
00260
00261
00262
00263 DECL_NUM_STMTS (clone) = DECL_NUM_STMTS (fn);
00264
00265
00266 splay_tree_delete (decl_map);
00267
00268
00269 cp_function_chain->can_throw = !TREE_NOTHROW (fn);
00270
00271
00272 finish_function (0);
00273 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
00274 expand_body (clone);
00275 pop_from_top_level ();
00276 }
00277
00278
00279 return 1;
00280 }
00281
00282
00283
00284 static void
00285 dump_function (phase, fn)
00286 enum tree_dump_index phase;
00287 tree fn;
00288 {
00289 FILE *stream;
00290 int flags;
00291
00292 stream = dump_begin (phase, &flags);
00293 if (stream)
00294 {
00295 fprintf (stream, "\n;; Function %s",
00296 decl_as_string (fn, TFF_DECL_SPECIFIERS));
00297 fprintf (stream, " (%s)\n",
00298 decl_as_string (DECL_ASSEMBLER_NAME (fn), 0));
00299 fprintf (stream, ";; enabled by -%s\n", dump_flag_name (phase));
00300 fprintf (stream, "\n");
00301
00302 dump_node (fn, TDF_SLIM | flags, stream);
00303 dump_end (phase, stream);
00304 }
00305 }