+2014-11-16 Jan Hubicka <hubicka@ucw.cz>
+
+ * passes.c (execute_one_pass): Do not apply all transforms prior
+ every simple IPA pass.
+ * cgraphunit.c: Do not include fibheap.h
+ (expand_thunk): Use get_untransformed_body.
+ (cgraph_node::expand): Likewise.
+ * tree-ssa-structalias.c (ipa_pta_execute): Skip inline clones.
+ * cgraph.c (release_function_body): Do not push cfun when CFG is not there.
+ (cgraph_node::get_untransformed_body): Break out from ...
+ (cgraph_node::get_body): ... here; add code to apply all transforms.
+ * cgraph.h (cgraph_node): Add get_untransformed_body.
+ * ipa-icf.c (sem_function::init): Use get_untransformed_body.
+ * cgraphclones.c (duplicate_thunk_for_node): Likewise.
+ * tree-inline.c (expand_call_inline): LIkewise.
+ * i386.c (ix86_reset_to_default_globals): Break out from ...
+ (ix86_set_current_function): ... here;
+ (ix86_reset_previous_fndecl): Use it.
+ (ix86_simd_clone_adjust): Use ix86_reset_previous_fndecl.
+
2014-11-16 Eric Botcazou <ebotcazou@adacore.com>
* doc/tm.texi.in (TARGET_FLAGS_REGNUM): Move around.
{
if (DECL_STRUCT_FUNCTION (decl))
{
- push_cfun (DECL_STRUCT_FUNCTION (decl));
- if (cfun->cfg
- && current_loops)
- {
- cfun->curr_properties &= ~PROP_loops;
- loop_optimizer_finalize ();
- }
- if (cfun->gimple_df)
+ if (DECL_STRUCT_FUNCTION (decl)->cfg
+ || DECL_STRUCT_FUNCTION (decl)->gimple_df)
{
- delete_tree_ssa ();
- delete_tree_cfg_annotations ();
- cfun->eh = NULL;
- }
- if (cfun->cfg)
- {
- gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
- gcc_assert (!dom_info_available_p (CDI_POST_DOMINATORS));
- clear_edges ();
- cfun->cfg = NULL;
+ push_cfun (DECL_STRUCT_FUNCTION (decl));
+ if (cfun->cfg
+ && current_loops)
+ {
+ cfun->curr_properties &= ~PROP_loops;
+ loop_optimizer_finalize ();
+ }
+ if (cfun->gimple_df)
+ {
+ delete_tree_ssa ();
+ delete_tree_cfg_annotations ();
+ cfun->eh = NULL;
+ }
+ if (cfun->cfg)
+ {
+ gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
+ gcc_assert (!dom_info_available_p (CDI_POST_DOMINATORS));
+ clear_edges ();
+ cfun->cfg = NULL;
+ }
+ if (cfun->value_histograms)
+ free_histograms ();
+ pop_cfun ();
}
- if (cfun->value_histograms)
- free_histograms ();
- pop_cfun ();
gimple_set_body (decl, NULL);
/* Struct function hangs a lot of data that would leak if we didn't
removed all pointers to it. */
present. */
bool
-cgraph_node::get_body (void)
+cgraph_node::get_untransformed_body (void)
{
lto_file_decl_data *file_data;
const char *data, *name;
return true;
}
+/* Prepare function body. When doing LTO, read cgraph_node's body from disk
+ if it is not already present. When some IPA transformations are scheduled,
+ apply them. */
+
+bool
+cgraph_node::get_body (void)
+{
+ bool updated;
+
+ updated = get_untransformed_body ();
+
+ /* Getting transformed body makes no sense for inline clones;
+ we should never use this on real clones becuase they are materialized
+ early.
+ TODO: Materializing clones here will likely lead to smaller LTRANS
+ footprint. */
+ gcc_assert (!global.inlined_to && !clone_of);
+ if (ipa_transforms_to_apply.exists ())
+ {
+ opt_pass *saved_current_pass = current_pass;
+ FILE *saved_dump_file = dump_file;
+ int saved_dump_flags = dump_flags;
+
+ push_cfun (DECL_STRUCT_FUNCTION (decl));
+ execute_all_ipa_transforms ();
+ cgraph_edge::rebuild_edges ();
+ free_dominance_info (CDI_DOMINATORS);
+ free_dominance_info (CDI_POST_DOMINATORS);
+ pop_cfun ();
+ updated = true;
+
+ current_pass = saved_current_pass;
+ dump_file = saved_dump_file;
+ dump_flags = saved_dump_flags;
+ }
+ return updated;
+}
+
/* Return the DECL_STRUCT_FUNCTION of the function. */
struct function *
/* When doing LTO, read cgraph_node's body from disk if it is not already
present. */
+ bool get_untransformed_body (void);
+
+ /* Prepare function body. When doing LTO, read cgraph_node's body from disk
+ if it is not already present. When some IPA transformations are scheduled,
+ apply them. */
bool get_body (void);
/* Release memory used to represent body of function.
node = duplicate_thunk_for_node (thunk_of, node);
if (!DECL_ARGUMENTS (thunk->decl))
- thunk->get_body ();
+ thunk->get_untransformed_body ();
cgraph_edge *cs;
for (cs = node->callers; cs; cs = cs->next_caller)
&& !gimple_has_body_p (node->decl))
{
if (!node->clone_of->clone_of)
- node->clone_of->get_body ();
+ node->clone_of->get_untransformed_body ();
if (gimple_has_body_p (node->clone_of->decl))
{
if (symtab->dump_file)
#include "target.h"
#include "diagnostic.h"
#include "params.h"
-#include "fibheap.h"
#include "intl.h"
#include "hash-map.h"
#include "plugin-api.h"
}
if (in_lto_p)
- get_body ();
+ get_untransformed_body ();
a = DECL_ARGUMENTS (thunk_fndecl);
current_function_decl = thunk_fndecl;
gimple ret;
if (in_lto_p)
- get_body ();
+ get_untransformed_body ();
a = DECL_ARGUMENTS (thunk_fndecl);
current_function_decl = thunk_fndecl;
announce_function (decl);
process = 0;
gcc_assert (lowered);
- get_body ();
+ get_untransformed_body ();
/* Generate RTL for the body of DECL. */
/* Remember the last target of ix86_set_current_function. */
static GTY(()) tree ix86_previous_fndecl;
+/* Set target globals to default. */
+
+static void
+ix86_reset_to_default_globals (void)
+{
+ tree old_tree = (ix86_previous_fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl)
+ : NULL_TREE);
+
+ if (old_tree)
+ {
+ tree new_tree = target_option_current_node;
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+}
+
/* Invalidate ix86_previous_fndecl cache. */
void
ix86_reset_previous_fndecl (void)
{
+ ix86_reset_to_default_globals ();
ix86_previous_fndecl = NULL_TREE;
}
? DECL_FUNCTION_SPECIFIC_TARGET (fndecl)
: NULL_TREE);
- ix86_previous_fndecl = fndecl;
if (old_tree == new_tree)
;
}
else if (old_tree)
- {
- new_tree = target_option_current_node;
- cl_target_option_restore (&global_options,
- TREE_TARGET_OPTION (new_tree));
- if (TREE_TARGET_GLOBALS (new_tree))
- restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
- else if (new_tree == target_option_default_node)
- restore_target_globals (&default_target_globals);
- else
- TREE_TARGET_GLOBALS (new_tree)
- = save_target_globals_default_opts ();
- }
+ ix86_reset_to_default_globals ();
+ ix86_previous_fndecl = fndecl;
}
}
bool ok = ix86_valid_target_attribute_p (node->decl, NULL, args, 0);
gcc_assert (ok);
pop_cfun ();
- ix86_previous_fndecl = NULL_TREE;
+ ix86_reset_previous_fndecl ();
ix86_set_current_function (node->decl);
}
sem_function::init (void)
{
if (in_lto_p)
- get_node ()->get_body ();
+ get_node ()->get_untransformed_body ();
tree fndecl = node->decl;
function *func = DECL_STRUCT_FUNCTION (fndecl);
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)
- {
- struct cgraph_node *node;
- bool applied = false;
- FOR_EACH_DEFINED_FUNCTION (node)
- if (node->analyzed
- && node->has_gimple_body_p ()
- && (!node->clone_of || node->decl != node->clone_of->decl))
- {
- if (!node->global.inlined_to
- && node->ipa_transforms_to_apply.exists ())
- {
- node->get_body ();
- push_cfun (DECL_STRUCT_FUNCTION (node->decl));
- execute_all_ipa_transforms ();
- cgraph_edge::rebuild_edges ();
- free_dominance_info (CDI_DOMINATORS);
- free_dominance_info (CDI_POST_DOMINATORS);
- pop_cfun ();
- applied = true;
- }
- }
- if (applied)
- symtab->remove_unreachable_nodes (false, dump_file);
- /* Restore current_pass. */
- current_pass = pass;
- }
-
if (!quiet_flag && !cfun)
fprintf (stderr, " <%s>", pass->name ? pass->name : "");
goto egress;
}
fn = cg_edge->callee->decl;
- cg_edge->callee->get_body ();
+ cg_edge->callee->get_untransformed_body ();
#ifdef ENABLE_CHECKING
if (cg_edge->callee->decl != id->dst_node->decl)
/* Nodes without a body are not interesting. Especially do not
visit clones at this point for now - we get duplicate decls
there for inline clones at least. */
- if (!node->has_gimple_body_p () || node->clone_of)
+ if (!node->has_gimple_body_p () || node->global.inlined_to)
continue;
node->get_body ();