Pass manager: add support for termination of pass list
authorMartin Liska <mliska@suse.cz>
Wed, 4 Nov 2015 16:50:45 +0000 (17:50 +0100)
committerMartin Liska <marxin@gcc.gnu.org>
Wed, 4 Nov 2015 16:50:45 +0000 (16:50 +0000)
* cgraphunit.c (cgraph_node::expand_thunk): Call
allocate_struct_function before init_function_start.
(cgraph_node::expand): Use push_cfun and pop_cfun.
* config/i386/i386.c (ix86_code_end): Call
allocate_struct_function before init_function_start.
* config/rs6000/rs6000.c (rs6000_code_end): Likewise.
* function.c (init_function_start): Move preamble to all
callers.
* passes.c (do_per_function_toporder): Use push_cfun and pop_cfun.
(execute_one_pass): Handle newly added TODO_discard_function.
(execute_pass_list_1): Terminate if cfun equals to NULL.
(execute_pass_list): Do not push and pop cfun, expect that
cfun is set.
* tree-pass.h (TODO_discard_function): Define.

From-SVN: r229764

gcc/ChangeLog
gcc/cgraphunit.c
gcc/config/i386/i386.c
gcc/config/rs6000/rs6000.c
gcc/function.c
gcc/passes.c
gcc/tree-pass.h

index b41693d306bff81928a1c3f910d9f37a7dfa8139..6e7020c1739f13423945a24b4736a76ed00674e5 100644 (file)
@@ -1,3 +1,20 @@
+2015-11-04  Martin Liska  <mliska@suse.cz>
+
+       * cgraphunit.c (cgraph_node::expand_thunk): Call
+       allocate_struct_function before init_function_start.
+       (cgraph_node::expand): Use push_cfun and pop_cfun.
+       * config/i386/i386.c (ix86_code_end): Call
+       allocate_struct_function before init_function_start.
+       * config/rs6000/rs6000.c (rs6000_code_end): Likewise.
+       * function.c (init_function_start): Move preamble to all
+       callers.
+       * passes.c (do_per_function_toporder): Use push_cfun and pop_cfun.
+       (execute_one_pass): Handle newly added TODO_discard_function.
+       (execute_pass_list_1): Terminate if cfun equals to NULL.
+       (execute_pass_list): Do not push and pop cfun, expect that
+       cfun is set.
+       * tree-pass.h (TODO_discard_function): Define.
+
 2015-11-04  Mikhail Maltsev  <maltsevm@gmail.com>
 
        * cfganal.c (inverted_post_order_compute): Remove conditional
index 43d31858eddbe09ef1338f689e33aa1ab49d182c..f73d9a78e0303257afadc9aa10c5a3a7b5588216 100644 (file)
@@ -1618,6 +1618,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
       fn_block = make_node (BLOCK);
       BLOCK_VARS (fn_block) = a;
       DECL_INITIAL (thunk_fndecl) = fn_block;
+      allocate_struct_function (thunk_fndecl, false);
       init_function_start (thunk_fndecl);
       cfun->is_thunk = 1;
       insn_locations_init ();
@@ -1632,7 +1633,6 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk)
       insn_locations_finalize ();
       init_insn_lengths ();
       free_after_compilation (cfun);
-      set_cfun (NULL);
       TREE_ASM_WRITTEN (thunk_fndecl) = 1;
       thunk.thunk_p = false;
       analyzed = false;
@@ -1944,9 +1944,11 @@ cgraph_node::expand (void)
   bitmap_obstack_initialize (NULL);
 
   /* Initialize the RTL code for the function.  */
-  current_function_decl = decl;
   saved_loc = input_location;
   input_location = DECL_SOURCE_LOCATION (decl);
+
+  gcc_assert (DECL_STRUCT_FUNCTION (decl));
+  push_cfun (DECL_STRUCT_FUNCTION (decl));
   init_function_start (decl);
 
   gimple_register_cfg_hooks ();
@@ -2014,8 +2016,8 @@ cgraph_node::expand (void)
 
   /* Make sure that BE didn't give up on compiling.  */
   gcc_assert (TREE_ASM_WRITTEN (decl));
-  set_cfun (NULL);
-  current_function_decl = NULL;
+  if (cfun)
+    pop_cfun ();
 
   /* It would make a lot more sense to output thunks before function body to get more
      forward and lest backwarding jumps.  This however would need solving problem
index 66024e2d74a6d3cf524783467477efea3b84d991..2a965f678a0314df1277125ac5f5b80738c77aad 100644 (file)
@@ -10958,6 +10958,7 @@ ix86_code_end (void)
 
       DECL_INITIAL (decl) = make_node (BLOCK);
       current_function_decl = decl;
+      allocate_struct_function (decl, false);
       init_function_start (decl);
       first_function_block_is_cold = false;
       /* Make sure unwind info is emitted for the thunk if needed.  */
index 271c3f91b4a72a406f1b1adbbdd8bc4772bf75df..8bdd64674bf8ad189676a2026b4a65b23709e656 100644 (file)
@@ -34594,6 +34594,7 @@ rs6000_code_end (void)
 
   DECL_INITIAL (decl) = make_node (BLOCK);
   current_function_decl = decl;
+  allocate_struct_function (decl, false);
   init_function_start (decl);
   first_function_block_is_cold = false;
   /* Make sure unwind info is emitted for the thunk if needed.  */
index aaf49a4bbb922a2cc6021a6d5da8484385fba3b0..0d7cabc1d4cefaa6e50b19b428852db756beccaa 100644 (file)
@@ -4957,11 +4957,6 @@ init_dummy_function_start (void)
 void
 init_function_start (tree subr)
 {
-  if (subr && DECL_STRUCT_FUNCTION (subr))
-    set_cfun (DECL_STRUCT_FUNCTION (subr));
-  else
-    allocate_struct_function (subr, false);
-
   /* Initialize backend, if needed.  */
   initialize_rtl ();
 
index f87dcf4bb184fe54a2a3cd96c03388ea717d9e62..7a10cb6334c2c770ef3f3ab7e646f4b9323cb342 100644 (file)
@@ -1706,7 +1706,12 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data)
          order[i] = NULL;
          node->process = 0;
          if (node->has_gimple_body_p ())
-           callback (DECL_STRUCT_FUNCTION (node->decl), data);
+           {
+             struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
+             push_cfun (fn);
+             callback (fn, data);
+             pop_cfun ();
+           }
        }
       symtab->remove_cgraph_removal_hook (hook);
     }
@@ -2347,6 +2352,23 @@ execute_one_pass (opt_pass *pass)
 
   current_pass = NULL;
 
+  if (todo_after & TODO_discard_function)
+    {
+      gcc_assert (cfun);
+      /* As cgraph_node::release_body expects release dominators info,
+        we have to release it.  */
+      if (dom_info_available_p (CDI_DOMINATORS))
+       free_dominance_info (CDI_DOMINATORS);
+
+      if (dom_info_available_p (CDI_POST_DOMINATORS))
+       free_dominance_info (CDI_POST_DOMINATORS);
+
+      tree fn = cfun->decl;
+      pop_cfun ();
+      gcc_assert (!cfun);
+      cgraph_node::get (fn)->release_body ();
+    }
+
   /* Signal this is a suitable GC collection point.  */
   if (!((todo_after | pass->todo_flags_finish) & TODO_do_not_ggc_collect))
     ggc_collect ();
@@ -2361,6 +2383,9 @@ execute_pass_list_1 (opt_pass *pass)
     {
       gcc_assert (pass->type == GIMPLE_PASS
                  || pass->type == RTL_PASS);
+
+      if (cfun == NULL)
+       return;
       if (execute_one_pass (pass) && pass->sub)
         execute_pass_list_1 (pass->sub);
       pass = pass->next;
@@ -2371,14 +2396,13 @@ execute_pass_list_1 (opt_pass *pass)
 void
 execute_pass_list (function *fn, opt_pass *pass)
 {
-  push_cfun (fn);
+  gcc_assert (fn == cfun);
   execute_pass_list_1 (pass);
-  if (fn->cfg)
+  if (cfun && fn->cfg)
     {
       free_dominance_info (CDI_DOMINATORS);
       free_dominance_info (CDI_POST_DOMINATORS);
     }
-  pop_cfun ();
 }
 
 /* Write out all LTO data.  */
index ba53ccaabcd41f6fcb8e74cf4d7b604cc66ebb24..49e22a9d091247316b7b31074f636c6a87be2dab 100644 (file)
@@ -300,6 +300,9 @@ protected:
 /* Rebuild the callgraph edges.  */
 #define TODO_rebuild_cgraph_edges       (1 << 22)
 
+/* Release function body and stop pass manager.  */
+#define TODO_discard_function          (1 << 23)
+
 /* Internally used in execute_function_todo().  */
 #define TODO_update_ssa_any            \
     (TODO_update_ssa                   \