#include "coretypes.h"
#include "tm.h"
#include "tree.h"
+#include "rtl.h"
#include "tree-inline.h"
#include "langhooks.h"
#include "hashtab.h"
static bool error_found;
-/* Callbrack of verify_cgraph_node. Check that all call_exprs have cgraph nodes. */
+/* Callbrack of verify_cgraph_node. Check that all call_exprs have cgraph
+ nodes. */
+
static tree
verify_cgraph_node_1 (tree *tp, int *walk_subtrees, void *data)
{
error_found = true;
}
}
+
/* Save some cycles by not walking types and declaration as we
won't find anything useful there anyway. */
if (DECL_P (*tp) || TYPE_P (*tp))
- {
- *walk_subtrees = 0;
- }
+ *walk_subtrees = 0;
+
return NULL_TREE;
}
{
DECL_SAVED_TREE (node->decl) = NULL;
DECL_STRUCT_FUNCTION (node->decl) = NULL;
- DECL_ARGUMENTS (node->decl) = NULL;
DECL_INITIAL (node->decl) = error_mark_node;
}
}
{
DECL_SAVED_TREE (node->decl) = NULL;
DECL_STRUCT_FUNCTION (node->decl) = NULL;
- DECL_ARGUMENTS (node->decl) = NULL;
DECL_INITIAL (node->decl) = error_mark_node;
}
while (node->callees)
/* E is expected to be an edge being inlined. Clone destination node of
the edge and redirect it to the new clone.
- DUPLICATE is used for bookeeping on whether we are actually creating new
+ DUPLICATE is used for bookkeeping on whether we are actually creating new
clones or re-using node originally representing out-of-line function call.
*/
void
e->inline_failed = NULL;
if (!e->callee->global.inlined && flag_unit_at_a_time)
- {
- void **slot;
- if (!cgraph_inline_hash)
- cgraph_inline_hash = htab_create_ggc (42, htab_hash_pointer,
- htab_eq_pointer, NULL);
- slot = htab_find_slot (cgraph_inline_hash,
- DECL_ASSEMBLER_NAME (e->callee->decl), INSERT);
- *slot = DECL_ASSEMBLER_NAME (e->callee->decl);
- }
+ DECL_POSSIBLY_INLINED (e->callee->decl) = true;
e->callee->global.inlined = true;
cgraph_clone_inlined_nodes (e, true);
what = e->callee;
- /* Now update size of caller and all functions caller is inlined into. */
+ /* Now update size of caller and all functions caller is inlined into. */
for (;e && !e->inline_failed; e = e->caller->callers)
{
old_insns = e->caller->global.insns;
recursive = what->decl == to->global.inlined_to->decl;
else
recursive = what->decl == to->decl;
- /* Marking recursive function inlinine has sane semantic and thus we should
+ /* Marking recursive function inline has sane semantic and thus we should
not warn on it. */
if (recursive && reason)
*reason = (what->local.disregard_inline_limits
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
"\nConsidering %s %i insns (always inline)\n",
- cgraph_node_name (e->callee), e->callee->global.insns);
+ cgraph_node_name (node), node->global.insns);
old_insns = overall_insns;
for (e = node->callers; e; e = next)
{
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
" Inlined into %s which now has %i insns.\n",
- cgraph_node_name (node->callees->caller),
- node->callees->caller->global.insns);
+ cgraph_node_name (e->caller),
+ e->caller->global.insns);
}
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
}
#endif
}
+
+/* Generate and emit a static constructor or destructor. WHICH must be
+ one of 'I' or 'D'. BODY should be a STATEMENT_LIST containing
+ GENERIC statements. */
+
+void
+cgraph_build_static_cdtor (char which, tree body, int priority)
+{
+ static int counter = 0;
+ char which_buf[16];
+ tree decl, name;
+
+ sprintf (which_buf, "%c_%d", which, counter++);
+ name = get_file_function_name_long (which_buf);
+
+ decl = build_decl (FUNCTION_DECL, name,
+ build_function_type (void_type_node, void_list_node));
+ current_function_decl = decl;
+
+ DECL_RESULT (decl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ allocate_struct_function (decl);
+
+ TREE_STATIC (decl) = 1;
+ TREE_USED (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
+ DECL_SAVED_TREE (decl) = body;
+ TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors;
+ DECL_UNINLINABLE (decl) = 1;
+
+ DECL_INITIAL (decl) = make_node (BLOCK);
+ TREE_USED (DECL_INITIAL (decl)) = 1;
+
+ DECL_SOURCE_LOCATION (decl) = input_location;
+ cfun->function_end_locus = input_location;
+
+ if (which == 'I')
+ DECL_STATIC_CONSTRUCTOR (decl) = 1;
+ else if (which == 'D')
+ DECL_STATIC_DESTRUCTOR (decl) = 1;
+ else
+ abort ();
+
+ gimplify_function_tree (decl);
+
+ /* ??? We will get called LATE in the compilation process. */
+ if (cgraph_global_info_ready)
+ tree_rest_of_compilation (decl, false);
+ else
+ cgraph_finalize_function (decl, 0);
+
+ if (targetm.have_ctors_dtors)
+ {
+ void (*fn) (rtx, int);
+
+ if (which == 'I')
+ fn = targetm.asm_out.constructor;
+ else
+ fn = targetm.asm_out.destructor;
+ fn (XEXP (DECL_RTL (decl), 0), priority);
+ }
+}