tree-into-ssa.c (gate_into_ssa): New.
authorJan Hubicka <jh@suse.cz>
Sat, 14 Sep 2013 15:27:21 +0000 (17:27 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 14 Sep 2013 15:27:21 +0000 (15:27 +0000)
* tree-into-ssa.c (gate_into_ssa): New.
(pass_data_build_ssa): Use it.
* cgraph.h (expand_thunk): Update prototype.
* cgraphunit.c (analyze_function): Expand thunks early.
(expand_thunk): Fix DECL_CONTEXT of reust_decl;
build proper cgraph; set in_ssa_p; clear bogus TREE_ASM_WRITTEN;
set lowered flag; do not add new function.
(assemble_thunks_and_aliases): Update.
* tree-ssa.c (gate_init_datastructures): New gate.
(pass_data_init_datastructures): Use it.

From-SVN: r202592

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphunit.c
gcc/tree-into-ssa.c
gcc/tree-ssa.c

index 5113efd..08a9124 100644 (file)
@@ -1,3 +1,16 @@
+2013-09-14  Jan Hubicka  <jh@suse.cz>
+
+       * tree-into-ssa.c (gate_into_ssa): New.
+       (pass_data_build_ssa): Use it.
+       * cgraph.h (expand_thunk): Update prototype.
+       * cgraphunit.c (analyze_function): Expand thunks early.
+       (expand_thunk): Fix DECL_CONTEXT of reust_decl;
+       build proper cgraph; set in_ssa_p; clear bogus TREE_ASM_WRITTEN;
+       set lowered flag; do not add new function.
+       (assemble_thunks_and_aliases): Update.
+       * tree-ssa.c (gate_init_datastructures): New gate.
+       (pass_data_init_datastructures): Use it.
+
 2013-09-14  Iain Sandoe  <iain@codesourcery.com>
 
        PR target/58269
index a6a0a24..50e8743 100644 (file)
@@ -757,7 +757,7 @@ void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree);
     IN_SSA is true if the gimple is in SSA.  */
 basic_block init_lowered_empty_function (tree, bool);
 void cgraph_reset_node (struct cgraph_node *);
-void expand_thunk (struct cgraph_node *);
+bool expand_thunk (struct cgraph_node *, bool);
 
 /* In cgraphclones.c  */
 
index 8331f2e..1644ca9 100644 (file)
@@ -592,15 +592,21 @@ analyze_function (struct cgraph_node *node)
   location_t saved_loc = input_location;
   input_location = DECL_SOURCE_LOCATION (decl);
 
-  if (node->symbol.alias)
-    symtab_resolve_alias
-       ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target));
-  else if (node->thunk.thunk_p)
+  if (node->thunk.thunk_p)
     {
       cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
-                         NULL, 0, CGRAPH_FREQ_BASE);
+                         NULL, 0, CGRAPH_FREQ_BASE);
+      if (!expand_thunk (node, false))
+       {
+         node->thunk.alias = NULL;
+         node->symbol.analyzed = true;
+         return;
+       }
       node->thunk.alias = NULL;
     }
+  if (node->symbol.alias)
+    symtab_resolve_alias
+       ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target));
   else if (node->dispatcher_function)
     {
       /* Generate the dispatcher body of multi-versioned functions.  */
@@ -1432,10 +1438,12 @@ thunk_adjust (gimple_stmt_iterator * bsi,
   return ret;
 }
 
-/* Produce assembler for thunk NODE.  */
+/* Expand thunk NODE to gimple if possible.
+   When OUTPUT_ASM_THUNK is true, also produce assembler for
+   thunks that are not lowered.  */
 
-void
-expand_thunk (struct cgraph_node *node)
+bool
+expand_thunk (struct cgraph_node *node, bool output_asm_thunks)
 {
   bool this_adjusting = node->thunk.this_adjusting;
   HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
@@ -1445,14 +1453,6 @@ expand_thunk (struct cgraph_node *node)
   tree thunk_fndecl = node->symbol.decl;
   tree a;
 
-  if (in_lto_p)
-    cgraph_get_body (node);
-  a = DECL_ARGUMENTS (thunk_fndecl);
-
-  current_function_decl = thunk_fndecl;
-
-  /* Ensure thunks are emitted in their correct sections.  */
-  resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
 
   if (this_adjusting
       && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
@@ -1461,10 +1461,23 @@ expand_thunk (struct cgraph_node *node)
       const char *fnname;
       tree fn_block;
       tree restype = TREE_TYPE (TREE_TYPE (thunk_fndecl));
+
+      if (!output_asm_thunks)
+       return false;
+
+      if (in_lto_p)
+       cgraph_get_body (node);
+      a = DECL_ARGUMENTS (thunk_fndecl);
       
+      current_function_decl = thunk_fndecl;
+
+      /* Ensure thunks are emitted in their correct sections.  */
+      resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
+
       DECL_RESULT (thunk_fndecl)
        = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
                      RESULT_DECL, 0, restype);
+      DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
       fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
 
       /* The back end expects DECL_INITIAL to contain a BLOCK, so we
@@ -1506,6 +1519,15 @@ expand_thunk (struct cgraph_node *node)
       gimple call;
       gimple ret;
 
+      if (in_lto_p)
+       cgraph_get_body (node);
+      a = DECL_ARGUMENTS (thunk_fndecl);
+      
+      current_function_decl = thunk_fndecl;
+
+      /* Ensure thunks are emitted in their correct sections.  */
+      resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
+
       DECL_IGNORED_P (thunk_fndecl) = 1;
       bitmap_obstack_initialize (NULL);
 
@@ -1520,6 +1542,7 @@ expand_thunk (struct cgraph_node *node)
          DECL_ARTIFICIAL (resdecl) = 1;
          DECL_IGNORED_P (resdecl) = 1;
          DECL_RESULT (thunk_fndecl) = resdecl;
+          DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl;
        }
       else
        resdecl = DECL_RESULT (thunk_fndecl);
@@ -1556,6 +1579,7 @@ expand_thunk (struct cgraph_node *node)
         for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
          vargs.quick_push (arg);
       call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
+      node->callees->call_stmt = call;
       vargs.release ();
       gimple_call_set_from_thunk (call, true);
       if (restmp)
@@ -1624,6 +1648,9 @@ expand_thunk (struct cgraph_node *node)
          remove_edge (single_succ_edge (bb));
        }
 
+      cfun->gimple_df->in_ssa_p = true;
+      /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks.  */
+      TREE_ASM_WRITTEN (thunk_fndecl) = false;
       delete_unreachable_blocks ();
       update_ssa (TODO_update_ssa);
 #ifdef ENABLE_CHECKING
@@ -1633,12 +1660,12 @@ expand_thunk (struct cgraph_node *node)
       /* Since we want to emit the thunk, we explicitly mark its name as
         referenced.  */
       node->thunk.thunk_p = false;
-      rebuild_cgraph_edges ();
-      cgraph_add_new_function (thunk_fndecl, true);
+      node->lowered = true;
       bitmap_obstack_release (NULL);
     }
   current_function_decl = NULL;
   set_cfun (NULL);
+  return true;
 }
 
 /* Assemble thunks and aliases associated to NODE.  */
@@ -1657,7 +1684,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
 
        e = e->next_caller;
        assemble_thunks_and_aliases (thunk);
-        expand_thunk (thunk);
+        expand_thunk (thunk, true);
       }
     else
       e = e->next_caller;
index e6e8a3a..726744d 100644 (file)
@@ -2409,6 +2409,14 @@ rewrite_into_ssa (void)
   return 0;
 }
 
+/* Gate for IPCP optimization.  */
+
+static bool
+gate_into_ssa (void)
+{
+  /* Do nothing for funcions that was produced already in SSA form.  */
+  return !(cfun->curr_properties & PROP_ssa);
+}
 
 namespace {
 
@@ -2417,7 +2425,7 @@ const pass_data pass_data_build_ssa =
   GIMPLE_PASS, /* type */
   "ssa", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
-  false, /* has_gate */
+  true, /* has_gate */
   true, /* has_execute */
   TV_TREE_SSA_OTHER, /* tv_id */
   PROP_cfg, /* properties_required */
@@ -2435,6 +2443,7 @@ public:
   {}
 
   /* opt_pass methods: */
+  bool gate () { return gate_into_ssa (); }
   unsigned int execute () { return rewrite_into_ssa (); }
 
 }; // class pass_build_ssa
index 48c997d..461bb52 100644 (file)
@@ -1084,10 +1084,20 @@ static unsigned int
 execute_init_datastructures (void)
 {
   /* Allocate hash tables, arrays and other structures.  */
+  gcc_assert (!cfun->gimple_df);
   init_tree_ssa (cfun);
   return 0;
 }
 
+/* Gate for IPCP optimization.  */
+
+static bool
+gate_init_datastructures (void)
+{
+  /* Do nothing for funcions that was produced already in SSA form.  */
+  return !(cfun->curr_properties & PROP_ssa);
+}
+
 namespace {
 
 const pass_data pass_data_init_datastructures =
@@ -1095,7 +1105,7 @@ const pass_data pass_data_init_datastructures =
   GIMPLE_PASS, /* type */
   "*init_datastructures", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
-  false, /* has_gate */
+  true, /* has_gate */
   true, /* has_execute */
   TV_NONE, /* tv_id */
   PROP_cfg, /* properties_required */
@@ -1113,6 +1123,7 @@ public:
   {}
 
   /* opt_pass methods: */
+  bool gate () { return gate_init_datastructures (); }
   unsigned int execute () { return execute_init_datastructures (); }
 
 }; // class pass_init_datastructures