summaryrefslogtreecommitdiff
path: root/gcc/passes.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-21 22:01:24 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2015-01-21 22:01:24 +0000
commitffde65b31066f17eef243be882bb89a6e19370aa (patch)
treeea876d041c0a63eefccdac5416a8678e75da4cfc /gcc/passes.c
parenta8c7acc4db08ce7c8ac3ddcb943f9219e2893792 (diff)
downloadgcc-ffde65b31066f17eef243be882bb89a6e19370aa.tar.gz
[.]
2015-01-21 Basile Starynkevitch <basile@starynkevitch.net> {{merged with trunk -i.e. GCC5.0 in stage4- using svn merge -r209216:219879 svn+ssh://bstarynk@gcc.gnu.org/svn/gcc/trunk but should probably have used svn merge -r209216:219879 ^/trunk we don't use svnmerge.py anymore since our svn is version 1.8.10 }} VERY UNSTABLE 2015-01-20 Basile Starynkevitch <basile@starynkevitch.net> Move previous topdir ChangeLog.MELT to ChangeLog.MELT.2008-2014 [contrib/] 2015-01-21 Basile Starynkevitch <basile@starynkevitch.net> * MELT-Plugin-Makefile: Able to make upgrade-melt as a plugin. Works for GCC 5.0. Remove GCC 4.7 old stuff. Move previous contrib/ChangeLog.MELT to ChangeLog.MELT.2008-2014 [gcc/] 2015-01-21 Basile Starynkevitch <basile@starynkevitch.net> {{merged with trunk -i.e. GCC5.0 in stage4- using svn merge -r209216:219879 svn+ssh://bstarynk@gcc.gnu.org/svn/gcc/trunk but should probably have used svn merge -r209216:219879 ^/trunk **@@@ UNSTABLE since libmelt-ana-gimple.melt not compiling, but translator painfully bootstrapping!!@@@@ }} * toplev.c: Merged manually by keeping MELT extra stuff. * toplev.h: Likewise. * gengtype.c: Add "melt-runtime.h" in list, but merged with trunk. * melt-runtime.h (MELT_VERSION_STRING): Bump to "1.2-pre-merged". (meltgc_walk_gimple_seq): Remove. (gt_ggc_mx_gimple_statement_d): Same for GCC 4.9 & 5.0 * melt-runtime.cc: Update copyright year. (ggc_alloc_cleared_melt_valuevector_st, melt_resize_scangcvect): Call ggc_internal_cleared_alloc. (melt_val2passflag): Skip TODO_verify_ssa, TODO_verify_flow, TODO_verify_stmts, TODO_verify_rtl_sharing for GCC 5.0. (meltgc_walkstmt_cb, meltgc_walktree_cb) (melt_tree_walk_frame_size, meltgc_walk_gimple_seq): Remove. (melt_gt_ggc_mx_gimple_seq_d): Call gt_ggc_mx_gimple_statement_base. * melt-build-script.tpl: Update copyright year. Don't symlink meltrunsup.h anymore. * melt-build-script.sh: Regenerate. * melt/warmelt-base.melt: Update copyright year. (valdesc_object, valdesc_mapobjects, valdesc_mapstrings) (valdesc_multiple, valdesc_closure, valdesc_routine, valdesc_hook) (valdesc_bucketlongs, valdesc_jsonobject, valdesc_string) (valdesc_strbuf, valdesc_pair, valdesc_list, valdesc_int) (valdesc_double, valdesc_mixint, valdesc_mixloc) (valdesc_mixbigint, valdesc_real, valdesc_special_data): Use ggc_internal_alloc & ggc_internal_cleared_alloc for GCC 5.0. (json_canonical_name): Use ISUPPER, ISALPHA, TOUPPER instead of their standard <ctype.h> lowercase macros. * melt/warmelt-modes.melt: Update copyright year. (generate_runtypesupport_forwcopy_fun): Emit both GCC 4.9 & 5.0 compatible code. * melt/libmelt-ana-base.melt: Update copyright year. * melt/libmelt-ana-gimple.melt: TO BE IMPROVED * melt/generated/*: Painfully regenerated several times thru GCC 4.9 MELT plugin. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@219975 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/passes.c')
-rw-r--r--gcc/passes.c716
1 files changed, 417 insertions, 299 deletions
diff --git a/gcc/passes.c b/gcc/passes.c
index 0904f1b7616..b2027edc45a 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1,5 +1,5 @@
/* Top level of GCC compilers (cc1, cc1plus, etc.)
- Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Copyright (C) 1987-2015 Free Software Foundation, Inc.
This file is part of GCC.
@@ -28,7 +28,16 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "line-map.h"
#include "input.h"
+#include "hash-set.h"
+#include "machmode.h"
+#include "vec.h"
+#include "double-int.h"
+#include "alias.h"
+#include "symtab.h"
+#include "wide-int.h"
+#include "inchash.h"
#include "tree.h"
+#include "fold-const.h"
#include "varasm.h"
#include "rtl.h"
#include "tm_p.h"
@@ -42,7 +51,18 @@ along with GCC; see the file COPYING3. If not see
#include "except.h"
#include "function.h"
#include "toplev.h"
+#include "hashtab.h"
+#include "statistics.h"
+#include "real.h"
+#include "fixed-value.h"
+#include "expmed.h"
+#include "dojump.h"
+#include "explow.h"
+#include "calls.h"
+#include "emit-rtl.h"
+#include "stmt.h"
#include "expr.h"
+#include "predict.h"
#include "basic-block.h"
#include "intl.h"
#include "graph.h"
@@ -75,7 +95,10 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "tree-dump.h"
#include "df.h"
-#include "predict.h"
+#include "hash-map.h"
+#include "plugin-api.h"
+#include "ipa-ref.h"
+#include "cgraph.h"
#include "lto-streamer.h"
#include "plugin.h"
#include "ipa-utils.h"
@@ -108,13 +131,13 @@ opt_pass::clone ()
}
bool
-opt_pass::gate ()
+opt_pass::gate (function *)
{
return true;
}
unsigned int
-opt_pass::execute ()
+opt_pass::execute (function *)
{
return 0;
}
@@ -132,13 +155,15 @@ opt_pass::opt_pass (const pass_data &data, context *ctxt)
void
pass_manager::execute_early_local_passes ()
{
- execute_pass_list (pass_early_local_passes_1->sub);
+ execute_pass_list (cfun, pass_build_ssa_passes_1->sub);
+ execute_pass_list (cfun, pass_chkp_instrumentation_passes_1->sub);
+ execute_pass_list (cfun, pass_local_optimization_passes_1->sub);
}
unsigned int
pass_manager::execute_pass_mode_switching ()
{
- return pass_mode_switching_1->execute ();
+ return pass_mode_switching_1->execute (cfun);
}
@@ -238,7 +263,7 @@ rest_of_decl_compilation (tree decl,
if (in_lto_p && !at_end)
;
else if (finalize && TREE_CODE (decl) != FUNCTION_DECL)
- varpool_finalize_decl (decl);
+ varpool_node::finalize_decl (decl);
}
#ifdef ASM_FINISH_DECLARE_OBJECT
@@ -266,7 +291,7 @@ rest_of_decl_compilation (tree decl,
;
else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)
&& TREE_STATIC (decl))
- varpool_node_for_decl (decl);
+ varpool_node::get_create (decl);
}
/* Called after finishing a record, union or enumeral type. */
@@ -324,7 +349,7 @@ finish_optimization_passes (void)
}
static unsigned int
-execute_all_early_local_passes (void)
+execute_build_ssa_passes (void)
{
/* Once this pass (and its sub-passes) are complete, all functions
will be in SSA form. Technically this state change is happening
@@ -332,66 +357,125 @@ execute_all_early_local_passes (void)
none of the sub-passes are IPA passes and do not create new
functions, this is ok. We're setting this value for the benefit
of IPA passes that follow. */
- if (cgraph_state < CGRAPH_STATE_IPA_SSA)
- cgraph_state = CGRAPH_STATE_IPA_SSA;
+ if (symtab->state < IPA_SSA)
+ symtab->state = IPA_SSA;
return 0;
}
-/* Gate: execute, or not, all of the non-trivial optimizations. */
+namespace {
-static bool
-gate_all_early_local_passes (void)
+const pass_data pass_data_build_ssa_passes =
{
- /* Don't bother doing anything if the program has errors. */
- return (!seen_error () && !in_lto_p);
-}
+ SIMPLE_IPA_PASS, /* type */
+ "build_ssa_passes", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_EARLY_LOCAL, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ /* todo_flags_finish is executed before subpases. For this reason
+ it makes no sense to remove unreachable functions here. */
+ 0, /* todo_flags_finish */
+};
-namespace {
+class pass_build_ssa_passes : public simple_ipa_opt_pass
+{
+public:
+ pass_build_ssa_passes (gcc::context *ctxt)
+ : simple_ipa_opt_pass (pass_data_build_ssa_passes, ctxt)
+ {}
-const pass_data pass_data_early_local_passes =
+ /* opt_pass methods: */
+ virtual bool gate (function *)
+ {
+ /* Don't bother doing anything if the program has errors. */
+ return (!seen_error () && !in_lto_p);
+ }
+
+ virtual unsigned int execute (function *)
+ {
+ return execute_build_ssa_passes ();
+ }
+
+}; // class pass_build_ssa_passes
+
+const pass_data pass_data_chkp_instrumentation_passes =
{
SIMPLE_IPA_PASS, /* type */
- "early_local_cleanups", /* name */
+ "chkp_passes", /* name */
OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_gate */
- true, /* has_execute */
- TV_EARLY_LOCAL, /* tv_id */
+ TV_NONE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_remove_functions, /* todo_flags_finish */
+ 0, /* todo_flags_finish */
};
-class pass_early_local_passes : public simple_ipa_opt_pass
+class pass_chkp_instrumentation_passes : public simple_ipa_opt_pass
{
public:
- pass_early_local_passes (gcc::context *ctxt)
- : simple_ipa_opt_pass (pass_data_early_local_passes, ctxt)
+ pass_chkp_instrumentation_passes (gcc::context *ctxt)
+ : simple_ipa_opt_pass (pass_data_chkp_instrumentation_passes, ctxt)
{}
/* opt_pass methods: */
- bool gate () { return gate_all_early_local_passes (); }
- unsigned int execute () { return execute_all_early_local_passes (); }
+ virtual bool gate (function *)
+ {
+ /* Don't bother doing anything if the program has errors. */
+ return (!seen_error () && !in_lto_p);
+ }
-}; // class pass_early_local_passes
+}; // class pass_chkp_instrumentation_passes
+
+const pass_data pass_data_local_optimization_passes =
+{
+ SIMPLE_IPA_PASS, /* type */
+ "opt_local_passes", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_local_optimization_passes : public simple_ipa_opt_pass
+{
+public:
+ pass_local_optimization_passes (gcc::context *ctxt)
+ : simple_ipa_opt_pass (pass_data_local_optimization_passes, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *)
+ {
+ /* Don't bother doing anything if the program has errors. */
+ return (!seen_error () && !in_lto_p);
+ }
+
+}; // class pass_local_optimization_passes
} // anon namespace
simple_ipa_opt_pass *
-make_pass_early_local_passes (gcc::context *ctxt)
+make_pass_build_ssa_passes (gcc::context *ctxt)
{
- return new pass_early_local_passes (ctxt);
+ return new pass_build_ssa_passes (ctxt);
}
-/* Gate: execute, or not, all of the non-trivial optimizations. */
+simple_ipa_opt_pass *
+make_pass_chkp_instrumentation_passes (gcc::context *ctxt)
+{
+ return new pass_chkp_instrumentation_passes (ctxt);
+}
-static bool
-gate_all_early_optimizations (void)
+simple_ipa_opt_pass *
+make_pass_local_optimization_passes (gcc::context *ctxt)
{
- return (optimize >= 1
- /* Don't bother doing anything if the program has errors. */
- && !seen_error ());
+ return new pass_local_optimization_passes (ctxt);
}
namespace {
@@ -401,8 +485,6 @@ const pass_data pass_data_all_early_optimizations =
GIMPLE_PASS, /* type */
"early_optimizations", /* name */
OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_gate */
- false, /* has_execute */
TV_NONE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
@@ -419,7 +501,12 @@ public:
{}
/* opt_pass methods: */
- bool gate () { return gate_all_early_optimizations (); }
+ virtual bool gate (function *)
+ {
+ return (optimize >= 1
+ /* Don't bother doing anything if the program has errors. */
+ && !seen_error ());
+ }
}; // class pass_all_early_optimizations
@@ -431,14 +518,6 @@ make_pass_all_early_optimizations (gcc::context *ctxt)
return new pass_all_early_optimizations (ctxt);
}
-/* Gate: execute, or not, all of the non-trivial optimizations. */
-
-static bool
-gate_all_optimizations (void)
-{
- return optimize >= 1 && !optimize_debug;
-}
-
namespace {
const pass_data pass_data_all_optimizations =
@@ -446,8 +525,6 @@ const pass_data pass_data_all_optimizations =
GIMPLE_PASS, /* type */
"*all_optimizations", /* name */
OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_gate */
- false, /* has_execute */
TV_OPTIMIZE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
@@ -464,7 +541,7 @@ public:
{}
/* opt_pass methods: */
- bool gate () { return gate_all_optimizations (); }
+ virtual bool gate (function *) { return optimize >= 1 && !optimize_debug; }
}; // class pass_all_optimizations
@@ -476,14 +553,6 @@ make_pass_all_optimizations (gcc::context *ctxt)
return new pass_all_optimizations (ctxt);
}
-/* Gate: execute, or not, all of the non-trivial optimizations. */
-
-static bool
-gate_all_optimizations_g (void)
-{
- return optimize >= 1 && optimize_debug;
-}
-
namespace {
const pass_data pass_data_all_optimizations_g =
@@ -491,8 +560,6 @@ const pass_data pass_data_all_optimizations_g =
GIMPLE_PASS, /* type */
"*all_optimizations_g", /* name */
OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_gate */
- false, /* has_execute */
TV_OPTIMIZE, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
@@ -509,7 +576,7 @@ public:
{}
/* opt_pass methods: */
- bool gate () { return gate_all_optimizations_g (); }
+ virtual bool gate (function *) { return optimize >= 1 && optimize_debug; }
}; // class pass_all_optimizations_g
@@ -521,14 +588,6 @@ make_pass_all_optimizations_g (gcc::context *ctxt)
return new pass_all_optimizations_g (ctxt);
}
-static bool
-gate_rest_of_compilation (void)
-{
- /* Early return if there were errors. We can run afoul of our
- consistency checks, and there's not really much point in fixing them. */
- return !(rtl_dump_and_exit || flag_syntax_only || seen_error ());
-}
-
namespace {
const pass_data pass_data_rest_of_compilation =
@@ -536,8 +595,6 @@ const pass_data pass_data_rest_of_compilation =
RTL_PASS, /* type */
"*rest_of_compilation", /* name */
OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_gate */
- false, /* has_execute */
TV_REST_OF_COMPILATION, /* tv_id */
PROP_rtl, /* properties_required */
0, /* properties_provided */
@@ -554,7 +611,12 @@ public:
{}
/* opt_pass methods: */
- bool gate () { return gate_rest_of_compilation (); }
+ virtual bool gate (function *)
+ {
+ /* Early return if there were errors. We can run afoul of our
+ consistency checks, and there's not really much point in fixing them. */
+ return !(rtl_dump_and_exit || flag_syntax_only || seen_error ());
+ }
}; // class pass_rest_of_compilation
@@ -566,12 +628,6 @@ make_pass_rest_of_compilation (gcc::context *ctxt)
return new pass_rest_of_compilation (ctxt);
}
-static bool
-gate_postreload (void)
-{
- return reload_completed;
-}
-
namespace {
const pass_data pass_data_postreload =
@@ -579,14 +635,12 @@ const pass_data pass_data_postreload =
RTL_PASS, /* type */
"*all-postreload", /* name */
OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_gate */
- false, /* has_execute */
TV_POSTRELOAD, /* tv_id */
PROP_rtl, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
+ 0, /* todo_flags_finish */
};
class pass_postreload : public rtl_opt_pass
@@ -597,7 +651,7 @@ public:
{}
/* opt_pass methods: */
- bool gate () { return gate_postreload (); }
+ virtual bool gate (function *) { return reload_completed; }
}; // class pass_postreload
@@ -609,6 +663,44 @@ make_pass_postreload (gcc::context *ctxt)
return new pass_postreload (ctxt);
}
+namespace {
+
+const pass_data pass_data_late_compilation =
+{
+ RTL_PASS, /* type */
+ "*all-late_compilation", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_LATE_COMPILATION, /* tv_id */
+ PROP_rtl, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_late_compilation : public rtl_opt_pass
+{
+public:
+ pass_late_compilation (gcc::context *ctxt)
+ : rtl_opt_pass (pass_data_late_compilation, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *)
+ {
+ return reload_completed || targetm.no_register_allocation;
+ }
+
+}; // class pass_late_compilation
+
+} // anon namespace
+
+static rtl_opt_pass *
+make_pass_late_compilation (gcc::context *ctxt)
+{
+ return new pass_late_compilation (ctxt);
+}
+
/* Set the static pass number of pass PASS to ID and record that
@@ -699,114 +791,73 @@ pass_manager::register_one_dump_file (opt_pass *pass)
if (optgroup_flags == OPTGROUP_NONE)
optgroup_flags = OPTGROUP_OTHER;
id = dumps->dump_register (dot_name, flag_name, glob_name, flags,
- optgroup_flags);
+ optgroup_flags,
+ true);
set_pass_for_id (id, pass);
full_name = concat (prefix, pass->name, num, NULL);
register_pass_name (pass, full_name);
free (CONST_CAST (char *, full_name));
}
-/* Recursive worker function for register_dump_files. */
+/* Register the dump files for the pass_manager starting at PASS. */
-int
-pass_manager::
-register_dump_files_1 (opt_pass *pass, int properties)
+void
+pass_manager::register_dump_files (opt_pass *pass)
{
do
{
- int new_properties = (properties | pass->properties_provided)
- & ~pass->properties_destroyed;
-
if (pass->name && pass->name[0] != '*')
register_one_dump_file (pass);
if (pass->sub)
- new_properties = register_dump_files_1 (pass->sub, new_properties);
-
- /* If we have a gate, combine the properties that we could have with
- and without the pass being examined. */
- if (pass->has_gate)
- properties &= new_properties;
- else
- properties = new_properties;
+ register_dump_files (pass->sub);
pass = pass->next;
}
while (pass);
-
- return properties;
-}
-
-/* Register the dump files for the pass_manager starting at PASS.
- PROPERTIES reflects the properties that are guaranteed to be available at
- the beginning of the pipeline. */
-
-void
-pass_manager::
-register_dump_files (opt_pass *pass,int properties)
-{
- pass->properties_required |= properties;
- register_dump_files_1 (pass, properties);
}
-struct pass_registry
-{
- const char* unique_name;
- opt_pass *pass;
-};
-
/* Helper for pass_registry hash table. */
-struct pass_registry_hasher : typed_noop_remove <pass_registry>
+struct pass_registry_hasher : default_hashmap_traits
{
- typedef pass_registry value_type;
- typedef pass_registry compare_type;
- static inline hashval_t hash (const value_type *);
- static inline bool equal (const value_type *, const compare_type *);
+ static inline hashval_t hash (const char *);
+ static inline bool equal_keys (const char *, const char *);
};
/* Pass registry hash function. */
inline hashval_t
-pass_registry_hasher::hash (const value_type *s)
+pass_registry_hasher::hash (const char *name)
{
- return htab_hash_string (s->unique_name);
+ return htab_hash_string (name);
}
/* Hash equal function */
inline bool
-pass_registry_hasher::equal (const value_type *s1, const compare_type *s2)
+pass_registry_hasher::equal_keys (const char *s1, const char *s2)
{
- return !strcmp (s1->unique_name, s2->unique_name);
+ return !strcmp (s1, s2);
}
-static hash_table <pass_registry_hasher> name_to_pass_map;
+static hash_map<const char *, opt_pass *, pass_registry_hasher>
+ *name_to_pass_map;
/* Register PASS with NAME. */
static void
register_pass_name (opt_pass *pass, const char *name)
{
- struct pass_registry **slot;
- struct pass_registry pr;
-
- if (!name_to_pass_map.is_created ())
- name_to_pass_map.create (256);
-
- pr.unique_name = name;
- slot = name_to_pass_map.find_slot (&pr, INSERT);
- if (!*slot)
- {
- struct pass_registry *new_pr;
+ if (!name_to_pass_map)
+ name_to_pass_map
+ = new hash_map<const char *, opt_pass *, pass_registry_hasher> (256);
- new_pr = XCNEW (struct pass_registry);
- new_pr->unique_name = xstrdup (name);
- new_pr->pass = pass;
- *slot = new_pr;
- }
- else
+ if (name_to_pass_map->get (name))
return; /* Ignore plugin passes. */
+
+ const char *unique_name = xstrdup (name);
+ name_to_pass_map->put (unique_name, pass);
}
/* Map from pass id to canonicalized pass name. */
@@ -816,15 +867,13 @@ static vec<char_ptr> pass_tab = vNULL;
/* Callback function for traversing NAME_TO_PASS_MAP. */
-int
-passes_pass_traverse (pass_registry **p, void *data ATTRIBUTE_UNUSED)
+bool
+passes_pass_traverse (const char *const &name, opt_pass *const &pass, void *)
{
- opt_pass *pass = (*p)->pass;
-
gcc_assert (pass->static_pass_number > 0);
gcc_assert (pass_tab.exists ());
- pass_tab[pass->static_pass_number] = (*p)->unique_name;
+ pass_tab[pass->static_pass_number] = name;
return 1;
}
@@ -839,7 +888,7 @@ create_pass_tab (void)
return;
pass_tab.safe_grow_cleared (g->get_passes ()->passes_by_id_size + 1);
- name_to_pass_map.traverse <void *, passes_pass_traverse> (NULL);
+ name_to_pass_map->traverse <void *, passes_pass_traverse> (NULL);
}
static bool override_gate_status (opt_pass *, tree, bool);
@@ -854,7 +903,7 @@ dump_one_pass (opt_pass *pass, int pass_indent)
const char *pn;
bool is_on, is_really_on;
- is_on = pass->has_gate ? pass->gate () : true;
+ is_on = pass->gate (cfun);
is_really_on = override_gate_status (pass, current_function_decl, is_on);
if (pass->static_pass_number <= 0)
@@ -926,15 +975,11 @@ pass_manager::dump_passes () const
static opt_pass *
get_pass_by_name (const char *name)
{
- struct pass_registry **slot, pr;
-
- pr.unique_name = name;
- slot = name_to_pass_map.find_slot (&pr, NO_INSERT);
+ opt_pass **p = name_to_pass_map->get (name);
+ if (p)
+ return *p;
- if (!slot || !*slot)
- return NULL;
-
- return (*slot)->pass;
+ return NULL;
}
@@ -1170,7 +1215,7 @@ is_pass_explicitly_enabled_or_disabled (opt_pass *pass,
if (!slot)
return false;
- cgraph_uid = func ? cgraph_get_node (func)->uid : 0;
+ cgraph_uid = func ? cgraph_node::get (func)->uid : 0;
if (func && DECL_ASSEMBLER_NAME_SET_P (func))
aname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func));
@@ -1498,6 +1543,12 @@ pass_manager::operator new (size_t sz)
return xcalloc (1, sz);
}
+void
+pass_manager::operator delete (void *ptr)
+{
+ free (ptr);
+}
+
pass_manager::pass_manager (context *ctxt)
: all_passes (NULL), all_small_ipa_passes (NULL), all_lowering_passes (NULL),
all_regular_ipa_passes (NULL),
@@ -1548,19 +1599,41 @@ pass_manager::pass_manager (context *ctxt)
#undef TERMINATE_PASS_LIST
/* Register the passes with the tree dump code. */
- register_dump_files (all_lowering_passes, PROP_gimple_any);
- register_dump_files (all_small_ipa_passes,
- PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
- | PROP_cfg);
- register_dump_files (all_regular_ipa_passes,
- PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
- | PROP_cfg);
- register_dump_files (all_late_ipa_passes,
- PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
- | PROP_cfg);
- register_dump_files (all_passes,
- PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh
- | PROP_cfg);
+ register_dump_files (all_lowering_passes);
+ register_dump_files (all_small_ipa_passes);
+ register_dump_files (all_regular_ipa_passes);
+ register_dump_files (all_late_ipa_passes);
+ register_dump_files (all_passes);
+}
+
+static void
+delete_pass_tree (opt_pass *pass)
+{
+ while (pass)
+ {
+ /* Recurse into child passes. */
+ delete_pass_tree (pass->sub);
+
+ opt_pass *next = pass->next;
+
+ /* Delete this pass. */
+ delete pass;
+
+ /* Iterate onto sibling passes. */
+ pass = next;
+ }
+}
+
+pass_manager::~pass_manager ()
+{
+ XDELETEVEC (passes_by_id);
+
+ /* Call delete_pass_tree on each of the pass_lists. */
+#define DEF_PASS_LIST(LIST) \
+ delete_pass_tree (*pass_lists[PASS_LIST_NO_##LIST]);
+ GCC_PASS_LISTS
+#undef DEF_PASS_LIST
+
}
/* If we are in IPA mode (i.e., current_function_decl is NULL), call
@@ -1568,27 +1641,17 @@ pass_manager::pass_manager (context *ctxt)
call CALLBACK on the current function. */
static void
-do_per_function (void (*callback) (void *data), void *data)
+do_per_function (void (*callback) (function *, void *data), void *data)
{
if (current_function_decl)
- callback (data);
+ callback (cfun, data);
else
{
struct cgraph_node *node;
FOR_EACH_DEFINED_FUNCTION (node)
- if (node->analyzed && gimple_has_body_p (node->decl)
+ if (node->analyzed && (gimple_has_body_p (node->decl) && !in_lto_p)
&& (!node->clone_of || node->decl != node->clone_of->decl))
- {
- push_cfun (DECL_STRUCT_FUNCTION (node->decl));
- callback (data);
- if (!flag_wpa)
- {
- free_dominance_info (CDI_DOMINATORS);
- free_dominance_info (CDI_POST_DOMINATORS);
- }
- pop_cfun ();
- ggc_collect ();
- }
+ callback (DECL_STRUCT_FUNCTION (node->decl), data);
}
}
@@ -1596,44 +1659,71 @@ do_per_function (void (*callback) (void *data), void *data)
keep the array visible to garbage collector to avoid reading collected
out nodes. */
static int nnodes;
-static GTY ((length ("nnodes"))) cgraph_node_ptr *order;
+static GTY ((length ("nnodes"))) cgraph_node **order;
+
+/* Hook called when NODE is removed and therefore should be
+ excluded from order vector. DATA is an array of integers.
+ DATA[0] holds max index it may be accessed by. For cgraph
+ node DATA[node->uid + 1] holds index of this node in order
+ vector. */
+static void
+remove_cgraph_node_from_order (cgraph_node *node, void *data)
+{
+ int *order_idx = (int *)data;
+
+ if (node->uid >= order_idx[0])
+ return;
+
+ int idx = order_idx[node->uid + 1];
+ if (idx >= 0 && idx < nnodes && order[idx] == node)
+ order[idx] = NULL;
+}
/* If we are in IPA mode (i.e., current_function_decl is NULL), call
function CALLBACK for every function in the call graph. Otherwise,
call CALLBACK on the current function.
This function is global so that plugins can use it. */
void
-do_per_function_toporder (void (*callback) (void *data), void *data)
+do_per_function_toporder (void (*callback) (function *, void *data), void *data)
{
int i;
if (current_function_decl)
- callback (data);
+ callback (cfun, data);
else
{
+ cgraph_node_hook_list *hook;
+ int *order_idx;
gcc_assert (!order);
- order = ggc_alloc_vec_cgraph_node_ptr (cgraph_n_nodes);
+ order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count);
+
+ order_idx = XALLOCAVEC (int, symtab->cgraph_max_uid + 1);
+ memset (order_idx + 1, -1, sizeof (int) * symtab->cgraph_max_uid);
+ order_idx[0] = symtab->cgraph_max_uid;
+
nnodes = ipa_reverse_postorder (order);
for (i = nnodes - 1; i >= 0; i--)
- order[i]->process = 1;
+ {
+ order[i]->process = 1;
+ order_idx[order[i]->uid + 1] = i;
+ }
+ hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
+ order_idx);
for (i = nnodes - 1; i >= 0; i--)
{
+ /* Function could be inlined and removed as unreachable. */
+ if (!order[i])
+ continue;
+
struct cgraph_node *node = order[i];
/* Allow possibly removed nodes to be garbage collected. */
order[i] = NULL;
node->process = 0;
- if (cgraph_function_with_gimple_body_p (node))
- {
- cgraph_get_body (node);
- push_cfun (DECL_STRUCT_FUNCTION (node->decl));
- callback (data);
- free_dominance_info (CDI_DOMINATORS);
- free_dominance_info (CDI_POST_DOMINATORS);
- pop_cfun ();
- ggc_collect ();
- }
+ if (node->has_gimple_body_p ())
+ callback (DECL_STRUCT_FUNCTION (node->decl), data);
}
+ symtab->remove_cgraph_removal_hook (hook);
}
ggc_free (order);
order = NULL;
@@ -1643,14 +1733,16 @@ do_per_function_toporder (void (*callback) (void *data), void *data)
/* Helper function to perform function body dump. */
static void
-execute_function_dump (void *data)
+execute_function_dump (function *fn, void *data)
{
opt_pass *pass = (opt_pass *)data;
- if (dump_file && current_function_decl)
+ if (dump_file)
{
- if (cfun->curr_properties & PROP_trees)
- dump_function_to_file (current_function_decl, dump_file, dump_flags);
+ push_cfun (fn);
+
+ if (fn->curr_properties & PROP_trees)
+ dump_function_to_file (fn->decl, dump_file, dump_flags);
else
print_rtl_with_bb (dump_file, get_insns (), dump_flags);
@@ -1658,7 +1750,7 @@ execute_function_dump (void *data)
close the file before aborting. */
fflush (dump_file);
- if ((cfun->curr_properties & PROP_cfg)
+ if ((fn->curr_properties & PROP_cfg)
&& (dump_flags & TDF_GRAPH))
{
if (!pass->graph_dump_initialized)
@@ -1666,8 +1758,10 @@ execute_function_dump (void *data)
clean_graph_dump_file (dump_file_name);
pass->graph_dump_initialized = true;
}
- print_graph_cfg (dump_file_name, cfun);
+ print_graph_cfg (dump_file_name, fn);
}
+
+ pop_cfun ();
}
}
@@ -1798,13 +1892,16 @@ pass_manager::dump_profile_report () const
/* Perform all TODO actions that ought to be done on each function. */
static void
-execute_function_todo (void *data)
+execute_function_todo (function *fn, void *data)
{
+ bool from_ipa_pass = (cfun == NULL);
unsigned int flags = (size_t)data;
- flags &= ~cfun->last_verified;
+ flags &= ~fn->last_verified;
if (!flags)
return;
+ push_cfun (fn);
+
/* Always cleanup the CFG before trying to update SSA. */
if (flags & TODO_cleanup_cfg)
{
@@ -1824,7 +1921,6 @@ execute_function_todo (void *data)
{
unsigned update_flags = flags & TODO_update_ssa_any;
update_ssa (update_flags);
- cfun->last_verified &= ~TODO_verify_ssa;
}
if (flag_tree_pta && (flags & TODO_rebuild_alias))
@@ -1840,30 +1936,59 @@ execute_function_todo (void *data)
rebuild_frequencies ();
if (flags & TODO_rebuild_cgraph_edges)
- rebuild_cgraph_edges ();
+ cgraph_edge::rebuild_edges ();
/* If we've seen errors do not bother running any verifiers. */
- if (seen_error ())
- return;
-
-#if defined ENABLE_CHECKING
- if (flags & TODO_verify_ssa
- || (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA)))
+ if (!seen_error ())
{
- verify_gimple_in_cfg (cfun);
- verify_ssa (true);
- }
- else if (flags & TODO_verify_stmts)
- verify_gimple_in_cfg (cfun);
- if (flags & TODO_verify_flow)
- verify_flow_info ();
- if (current_loops && loops_state_satisfies_p (LOOP_CLOSED_SSA))
- verify_loop_closed_ssa (false);
- if (flags & TODO_verify_rtl_sharing)
- verify_rtl_sharing ();
+#if defined ENABLE_CHECKING
+ dom_state pre_verify_state = dom_info_state (fn, CDI_DOMINATORS);
+ dom_state pre_verify_pstate = dom_info_state (fn, CDI_POST_DOMINATORS);
+
+ if (flags & TODO_verify_il)
+ {
+ if (cfun->curr_properties & PROP_trees)
+ {
+ if (cfun->curr_properties & PROP_cfg)
+ /* IPA passes leave stmts to be fixed up, so make sure to
+ not verify stmts really throw. */
+ verify_gimple_in_cfg (cfun, !from_ipa_pass);
+ else
+ verify_gimple_in_seq (gimple_body (cfun->decl));
+ }
+ if (cfun->curr_properties & PROP_ssa)
+ /* IPA passes leave stmts to be fixed up, so make sure to
+ not verify SSA operands whose verifier will choke on that. */
+ verify_ssa (true, !from_ipa_pass);
+ /* IPA passes leave basic-blocks unsplit, so make sure to
+ not trip on that. */
+ if ((cfun->curr_properties & PROP_cfg)
+ && !from_ipa_pass)
+ verify_flow_info ();
+ if (current_loops
+ && loops_state_satisfies_p (LOOP_CLOSED_SSA))
+ verify_loop_closed_ssa (false);
+ if (cfun->curr_properties & PROP_rtl)
+ verify_rtl_sharing ();
+ }
+
+ /* Make sure verifiers don't change dominator state. */
+ gcc_assert (dom_info_state (fn, CDI_DOMINATORS) == pre_verify_state);
+ gcc_assert (dom_info_state (fn, CDI_POST_DOMINATORS) == pre_verify_pstate);
#endif
+ }
+
+ fn->last_verified = flags & TODO_verify_all;
- cfun->last_verified = flags & TODO_verify_all;
+ pop_cfun ();
+
+ /* For IPA passes make sure to release dominator info, it can be
+ computed by non-verifying TODOs. */
+ if (from_ipa_pass)
+ {
+ free_dominance_info (fn, CDI_DOMINATORS);
+ free_dominance_info (fn, CDI_POST_DOMINATORS);
+ }
}
/* Perform all TODO actions. */
@@ -1893,13 +2018,13 @@ execute_todo (unsigned int flags)
if (flags & TODO_remove_functions)
{
gcc_assert (!cfun);
- symtab_remove_unreachable_nodes (true, dump_file);
+ symtab->remove_unreachable_nodes (dump_file);
}
if ((flags & TODO_dump_symtab) && dump_file && !current_function_decl)
{
gcc_assert (!cfun);
- dump_symtab (dump_file);
+ symtab_node::dump_table (dump_file);
/* Flush the file. If verification fails, we won't be able to
close the file before aborting. */
fflush (dump_file);
@@ -1925,9 +2050,9 @@ verify_interpass_invariants (void)
/* Clear the last verified flag. */
static void
-clear_last_verified (void *data ATTRIBUTE_UNUSED)
+clear_last_verified (function *fn, void *data ATTRIBUTE_UNUSED)
{
- cfun->last_verified = 0;
+ fn->last_verified = 0;
}
/* Helper function. Verify that the properties has been turn into the
@@ -1935,10 +2060,10 @@ clear_last_verified (void *data ATTRIBUTE_UNUSED)
#ifdef ENABLE_CHECKING
static void
-verify_curr_properties (void *data)
+verify_curr_properties (function *fn, void *data)
{
unsigned int props = (size_t)data;
- gcc_assert ((cfun->curr_properties & props) == props);
+ gcc_assert ((fn->curr_properties & props) == props);
}
#endif
@@ -1948,7 +2073,6 @@ verify_curr_properties (void *data)
bool
pass_init_dump_file (opt_pass *pass)
{
- pass->graph_dump_initialized = false;
/* If a dump file name is present, open it if enabled. */
if (pass->static_pass_number != -1)
{
@@ -1997,11 +2121,11 @@ pass_fini_dump_file (opt_pass *pass)
properties. */
static void
-update_properties_after_pass (void *data)
+update_properties_after_pass (function *fn, void *data)
{
opt_pass *pass = (opt_pass *) data;
- cfun->curr_properties = (cfun->curr_properties | pass->properties_provided)
- & ~pass->properties_destroyed;
+ fn->curr_properties = (fn->curr_properties | pass->properties_provided)
+ & ~pass->properties_destroyed;
}
/* Execute summary generation for all of the passes in IPA_PASS. */
@@ -2015,7 +2139,7 @@ execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass)
/* Execute all of the IPA_PASSes in the list. */
if (ipa_pass->type == IPA_PASS
- && ((!pass->has_gate) || pass->gate ())
+ && pass->gate (cfun)
&& ipa_pass->generate_summary)
{
pass_init_dump_file (pass);
@@ -2024,6 +2148,7 @@ execute_ipa_summary_passes (ipa_opt_pass_d *ipa_pass)
if (pass->tv_id)
timevar_push (pass->tv_id);
+ current_pass = pass;
ipa_pass->generate_summary ();
/* Stop timevar. */
@@ -2097,7 +2222,7 @@ execute_all_ipa_transforms (void)
struct cgraph_node *node;
if (!cfun)
return;
- node = cgraph_get_node (current_function_decl);
+ node = cgraph_node::get (current_function_decl);
if (node->ipa_transforms_to_apply.exists ())
{
@@ -2109,20 +2234,6 @@ execute_all_ipa_transforms (void)
}
}
-/* Callback for do_per_function to apply all IPA transforms. */
-
-static void
-apply_ipa_transforms (void *data)
-{
- struct cgraph_node *node = cgraph_get_node (current_function_decl);
- if (!node->global.inlined_to && node->ipa_transforms_to_apply.exists ())
- {
- *(bool *)data = true;
- execute_all_ipa_transforms ();
- rebuild_cgraph_edges ();
- }
-}
-
/* Check if PASS is explicitly disabled or enabled and return
the gate status. FUNC is the function to be processed, and
GATE_STATUS is the gate status determined by pass manager by
@@ -2167,7 +2278,7 @@ execute_one_pass (opt_pass *pass)
/* Check whether gate check should be avoided.
User controls the value of the gate through the parameter "gate_status". */
- gate_status = pass->has_gate ? pass->gate () : true;
+ gate_status = pass->gate (cfun);
gate_status = override_gate_status (pass, current_function_decl, gate_status);
/* Override gate with plugin. */
@@ -2190,18 +2301,6 @@ execute_one_pass (opt_pass *pass)
executed. */
invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
- /* SIPLE IPA passes do not handle callgraphs with IPA transforms in it.
- Apply all trnasforms first. */
- if (pass->type == SIMPLE_IPA_PASS)
- {
- bool applied = false;
- do_per_function (apply_ipa_transforms, (void *)&applied);
- if (applied)
- symtab_remove_unreachable_nodes (true, dump_file);
- /* Restore current_pass. */
- current_pass = pass;
- }
-
if (!quiet_flag && !cfun)
fprintf (stderr, " <%s/%d%c>", pass->name ? pass->name : "",
pass->static_pass_number,
@@ -2228,11 +2327,8 @@ execute_one_pass (opt_pass *pass)
timevar_push (pass->tv_id);
/* Do it! */
- if (pass->has_execute)
- {
- todo_after = pass->execute ();
- do_per_function (clear_last_verified, NULL);
- }
+ todo_after = pass->execute (cfun);
+ do_per_function (clear_last_verified, NULL);
/* Stop timevar. */
if (pass->tv_id != TV_NONE)
@@ -2244,7 +2340,7 @@ execute_one_pass (opt_pass *pass)
check_profile_consistency (pass->static_pass_number, 0, true);
/* Run post-pass cleanup and verification. */
- execute_todo (todo_after | pass->todo_flags_finish);
+ execute_todo (todo_after | pass->todo_flags_finish | TODO_verify_il);
if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
check_profile_consistency (pass->static_pass_number, 1, true);
@@ -2259,7 +2355,7 @@ execute_one_pass (opt_pass *pass)
}
if (!current_function_decl)
- cgraph_process_new_functions ();
+ symtab->process_new_functions ();
pass_fini_dump_file (pass);
@@ -2276,20 +2372,33 @@ execute_one_pass (opt_pass *pass)
return true;
}
-void
-execute_pass_list (opt_pass *pass)
+static void
+execute_pass_list_1 (opt_pass *pass)
{
do
{
gcc_assert (pass->type == GIMPLE_PASS
|| pass->type == RTL_PASS);
if (execute_one_pass (pass) && pass->sub)
- execute_pass_list (pass->sub);
+ execute_pass_list_1 (pass->sub);
pass = pass->next;
}
while (pass);
}
+void
+execute_pass_list (function *fn, opt_pass *pass)
+{
+ push_cfun (fn);
+ execute_pass_list_1 (pass);
+ if (fn->cfg)
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ free_dominance_info (CDI_POST_DOMINATORS);
+ }
+ pop_cfun ();
+}
+
/* Write out all LTO data. */
static void
write_lto (void)
@@ -2317,7 +2426,7 @@ ipa_write_summaries_2 (opt_pass *pass, struct lto_out_decl_state *state)
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
if (pass->type == IPA_PASS
&& ipa_pass->write_summary
- && ((!pass->has_gate) || pass->gate ()))
+ && pass->gate (cfun))
{
/* If a timevar is present, start it. */
if (pass->tv_id)
@@ -2325,6 +2434,7 @@ ipa_write_summaries_2 (opt_pass *pass, struct lto_out_decl_state *state)
pass_init_dump_file (pass);
+ current_pass = pass;
ipa_pass->write_summary ();
pass_fini_dump_file (pass);
@@ -2375,24 +2485,26 @@ ipa_write_summaries (void)
struct cgraph_node *node;
struct cgraph_node **order;
- if (!flag_generate_lto || seen_error ())
+ if ((!flag_generate_lto && !flag_generate_offload) || seen_error ())
return;
+ select_what_to_stream ();
+
encoder = lto_symtab_encoder_new (false);
/* Create the callgraph set in the same order used in
cgraph_expand_all_functions. This mostly facilitates debugging,
since it causes the gimple file to be processed in the same order
as the source code. */
- order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+ order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
order_pos = ipa_reverse_postorder (order);
- gcc_assert (order_pos == cgraph_n_nodes);
+ gcc_assert (order_pos == symtab->cgraph_count);
for (i = order_pos - 1; i >= 0; i--)
{
struct cgraph_node *node = order[i];
- if (cgraph_function_with_gimple_body_p (node))
+ if (node->has_gimple_body_p ())
{
/* When streaming out references to statements as part of some IPA
pass summary, the statements need to have uids assigned and the
@@ -2404,15 +2516,16 @@ ipa_write_summaries (void)
renumber_gimple_stmt_uids ();
pop_cfun ();
}
- if (node->definition)
+ if (node->definition && node->need_lto_streaming)
lto_set_symtab_encoder_in_partition (encoder, node);
}
FOR_EACH_DEFINED_FUNCTION (node)
- if (node->alias)
+ if (node->alias && node->need_lto_streaming)
lto_set_symtab_encoder_in_partition (encoder, node);
FOR_EACH_DEFINED_VARIABLE (vnode)
- lto_set_symtab_encoder_in_partition (encoder, vnode);
+ if (vnode->need_lto_streaming)
+ lto_set_symtab_encoder_in_partition (encoder, vnode);
ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
@@ -2435,7 +2548,7 @@ ipa_write_optimization_summaries_1 (opt_pass *pass,
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
if (pass->type == IPA_PASS
&& ipa_pass->write_optimization_summary
- && ((!pass->has_gate) || pass->gate ()))
+ && pass->gate (cfun))
{
/* If a timevar is present, start it. */
if (pass->tv_id)
@@ -2443,6 +2556,7 @@ ipa_write_optimization_summaries_1 (opt_pass *pass,
pass_init_dump_file (pass);
+ current_pass = pass;
ipa_pass->write_optimization_summary ();
pass_fini_dump_file (pass);
@@ -2513,7 +2627,7 @@ ipa_read_summaries_1 (opt_pass *pass)
gcc_assert (!cfun);
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
- if ((!pass->has_gate) || pass->gate ())
+ if (pass->gate (cfun))
{
if (pass->type == IPA_PASS && ipa_pass->read_summary)
{
@@ -2523,6 +2637,7 @@ ipa_read_summaries_1 (opt_pass *pass)
pass_init_dump_file (pass);
+ current_pass = pass;
ipa_pass->read_summary ();
pass_fini_dump_file (pass);
@@ -2563,7 +2678,7 @@ ipa_read_optimization_summaries_1 (opt_pass *pass)
gcc_assert (!cfun);
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
- if ((!pass->has_gate) || pass->gate ())
+ if (pass->gate (cfun))
{
if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
{
@@ -2573,6 +2688,7 @@ ipa_read_optimization_summaries_1 (opt_pass *pass)
pass_init_dump_file (pass);
+ current_pass = pass;
ipa_pass->read_optimization_summary ();
pass_fini_dump_file (pass);
@@ -2613,7 +2729,8 @@ execute_ipa_pass_list (opt_pass *pass)
if (pass->sub->type == GIMPLE_PASS)
{
invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
- do_per_function_toporder ((void (*)(void *))execute_pass_list,
+ do_per_function_toporder ((void (*)(function *, void *))
+ execute_pass_list,
pass->sub);
invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
}
@@ -2624,7 +2741,7 @@ execute_ipa_pass_list (opt_pass *pass)
gcc_unreachable ();
}
gcc_assert (!current_function_decl);
- cgraph_process_new_functions ();
+ symtab->process_new_functions ();
pass = pass->next;
}
while (pass);
@@ -2640,7 +2757,7 @@ execute_ipa_stmt_fixups (opt_pass *pass,
{
/* Execute all of the IPA_PASSes in the list. */
if (pass->type == IPA_PASS
- && ((!pass->has_gate) || pass->gate ()))
+ && pass->gate (cfun))
{
ipa_opt_pass_d *ipa_pass = (ipa_opt_pass_d *) pass;
@@ -2651,6 +2768,7 @@ execute_ipa_stmt_fixups (opt_pass *pass,
if (pass->tv_id)
timevar_push (pass->tv_id);
+ current_pass = pass;
ipa_pass->stmt_fixup (node, stmts);
/* Stop timevar. */
@@ -2719,13 +2837,13 @@ bool
function_called_by_processed_nodes_p (void)
{
struct cgraph_edge *e;
- for (e = cgraph_get_node (current_function_decl)->callers;
+ for (e = cgraph_node::get (current_function_decl)->callers;
e;
e = e->next_caller)
{
if (e->caller->decl == current_function_decl)
continue;
- if (!cgraph_function_with_gimple_body_p (e->caller))
+ if (!e->caller->has_gimple_body_p ())
continue;
if (TREE_ASM_WRITTEN (e->caller->decl))
continue;
@@ -2735,7 +2853,7 @@ function_called_by_processed_nodes_p (void)
if (dump_file && e)
{
fprintf (dump_file, "Already processed call to:\n");
- dump_cgraph_node (dump_file, e->caller);
+ e->caller->dump (dump_file);
}
return e != NULL;
}