public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][1/n] Cleanup global pass execution flow
@ 2012-04-05 13:55 Richard Guenther
  2012-04-05 14:51 ` Jan Hubicka
  2012-04-05 15:23 ` Diego Novillo
  0 siblings, 2 replies; 4+ messages in thread
From: Richard Guenther @ 2012-04-05 13:55 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jan Hubicka


I'm trying to get an idea where and why we execute what part of the
pass pipeline (yeah, a two-line patch doing -Og should be possible
after this series ...).  This patch removes an odd caller of
execute_pass_list (pass_early_local_passes.pass.sub), named
tree_lowering_passes, which is even undocumented.  The two callers
will end up executing distinct parts of the function and the
function performs unnecessary setup.  Thus I inlined the
function into its two callers.

I'm not sure about the history of tree_lowering_passes but
freeing up stuff and compacting blocks is not done consistently
at least ;)  The idea is obviously to save memory.

I'll give this the usual bootstrap & regtest testing.

Honza, does this look ok?  I am going to continue this way
until I can re-architect the toplevel pass structure in a way
that we hand control more to the pass manager.  Well, hopefully ;)

Thanks,
Richard.

2012-04-05  Richard Guenther  <rguenther@suse.de>

	* tree-pass.h (tree_lowering_passes): Remove.
	* tree-optimize.c (tree_lowering_passes): Remove.
	* cgraph.c (cgraph_add_new_function): Inline relevant parts
	of tree_lowering_passes, avoid redundant call of early local
	passes.
	* cgraphunit.c (cgraph_lower_function): Fold into ...
	(cgraph_analyze_function): ... its single caller.  Inline
	relevant parts of tree_lowering_passes.

Index: gcc/tree-pass.h
===================================================================
*** gcc/tree-pass.h	(revision 186163)
--- gcc/tree-pass.h	(working copy)
*************** struct register_pass_info
*** 349,356 ****
    enum pass_positioning_ops pos_op; /* how to insert the new pass.  */
  };
  
- extern void tree_lowering_passes (tree decl);
- 
  extern struct gimple_opt_pass pass_mudflap_1;
  extern struct gimple_opt_pass pass_mudflap_2;
  extern struct gimple_opt_pass pass_lower_cf;
--- 349,354 ----
Index: gcc/tree-optimize.c
===================================================================
*** gcc/tree-optimize.c	(revision 186163)
--- gcc/tree-optimize.c	(working copy)
*************** struct gimple_opt_pass pass_init_datastr
*** 366,391 ****
    0					/* todo_flags_finish */
   }
  };
- 
- void
- tree_lowering_passes (tree fn)
- {
-   tree saved_current_function_decl = current_function_decl;
- 
-   current_function_decl = fn;
-   push_cfun (DECL_STRUCT_FUNCTION (fn));
-   gimple_register_cfg_hooks ();
-   bitmap_obstack_initialize (NULL);
-   execute_pass_list (all_lowering_passes);
-   if (optimize && cgraph_global_info_ready)
-     execute_pass_list (pass_early_local_passes.pass.sub);
-   free_dominance_info (CDI_POST_DOMINATORS);
-   free_dominance_info (CDI_DOMINATORS);
-   compact_blocks ();
-   current_function_decl = saved_current_function_decl;
-   bitmap_obstack_release (NULL);
-   pop_cfun ();
- }
  \f
  /* For functions-as-trees languages, this performs all optimization and
     compilation for FNDECL.  */
--- 366,371 ----
Index: gcc/cgraph.c
===================================================================
*** gcc/cgraph.c	(revision 186163)
--- gcc/cgraph.c	(working copy)
*************** cgraph_add_new_function (tree fndecl, bo
*** 2437,2446 ****
  	    push_cfun (DECL_STRUCT_FUNCTION (fndecl));
  	    current_function_decl = fndecl;
  	    gimple_register_cfg_hooks ();
- 	    tree_lowering_passes (fndecl);
  	    bitmap_obstack_initialize (NULL);
! 	    if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
! 	      execute_pass_list (pass_early_local_passes.pass.sub);
  	    bitmap_obstack_release (NULL);
  	    pop_cfun ();
  	    current_function_decl = NULL;
--- 2437,2445 ----
  	    push_cfun (DECL_STRUCT_FUNCTION (fndecl));
  	    current_function_decl = fndecl;
  	    gimple_register_cfg_hooks ();
  	    bitmap_obstack_initialize (NULL);
! 	    execute_pass_list (all_lowering_passes);
! 	    execute_pass_list (pass_early_local_passes.pass.sub);
  	    bitmap_obstack_release (NULL);
  	    pop_cfun ();
  	    current_function_decl = NULL;
Index: gcc/cgraphunit.c
===================================================================
*** gcc/cgraphunit.c	(revision 186163)
--- gcc/cgraphunit.c	(working copy)
*************** cgraph_reset_node (struct cgraph_node *n
*** 313,332 ****
    cgraph_node_remove_callees (node);
  }
  
- static void
- cgraph_lower_function (struct cgraph_node *node)
- {
-   if (node->lowered)
-     return;
- 
-   if (node->nested)
-     lower_nested_functions (node->decl);
-   gcc_assert (!node->nested);
- 
-   tree_lowering_passes (node->decl);
-   node->lowered = true;
- }
- 
  /* DECL has been parsed.  Take it, queue it, compile it at the whim of the
     logic in effect.  If NESTED is true, then our caller cannot stand to have
     the garbage collector run at the moment.  We would need to either create
--- 313,318 ----
*************** cgraph_analyze_function (struct cgraph_n
*** 915,921 ****
  	gimplify_function_tree (decl);
        dump_function (TDI_generic, decl);
  
!       cgraph_lower_function (node);
        pop_cfun ();
      }
    node->analyzed = true;
--- 901,923 ----
  	gimplify_function_tree (decl);
        dump_function (TDI_generic, decl);
  
!       /* Lower the function.  */
!       if (!node->lowered)
! 	{
! 	  if (node->nested)
! 	    lower_nested_functions (node->decl);
! 	  gcc_assert (!node->nested);
! 
! 	  gimple_register_cfg_hooks ();
! 	  bitmap_obstack_initialize (NULL);
! 	  execute_pass_list (all_lowering_passes);
! 	  free_dominance_info (CDI_POST_DOMINATORS);
! 	  free_dominance_info (CDI_DOMINATORS);
! 	  compact_blocks ();
! 	  bitmap_obstack_release (NULL);
! 	  node->lowered = true;
! 	}
! 
        pop_cfun ();
      }
    node->analyzed = true;

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][1/n] Cleanup global pass execution flow
  2012-04-05 13:55 [PATCH][1/n] Cleanup global pass execution flow Richard Guenther
@ 2012-04-05 14:51 ` Jan Hubicka
  2012-04-05 15:23 ` Diego Novillo
  1 sibling, 0 replies; 4+ messages in thread
From: Jan Hubicka @ 2012-04-05 14:51 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches, Jan Hubicka

> 
> I'm trying to get an idea where and why we execute what part of the
> pass pipeline (yeah, a two-line patch doing -Og should be possible
> after this series ...).  This patch removes an odd caller of
> execute_pass_list (pass_early_local_passes.pass.sub), named
> tree_lowering_passes, which is even undocumented.  The two callers
> will end up executing distinct parts of the function and the
> function performs unnecessary setup.  Thus I inlined the
> function into its two callers.
> 
> I'm not sure about the history of tree_lowering_passes but
> freeing up stuff and compacting blocks is not done consistently
> at least ;)  The idea is obviously to save memory.
> 
> I'll give this the usual bootstrap & regtest testing.
> 
> Honza, does this look ok?  I am going to continue this way
> until I can re-architect the toplevel pass structure in a way
> that we hand control more to the pass manager.  Well, hopefully ;)

Yes, it seems fine.
The original idea was to have limited entry points into the pass
manager and have one function per every action instead of exposing
pass lists as our interface. 

That is 
 - lowering passes that used to be executed during the parsing
   to output lower level warnings early enough and compact function
   body representation to save memory. 
   This was supposed to happen on all functions, even unused, to get
   more consistency of errors/warnings output here.

   So program was at one point represented in the lowered functions.  This the
   reason for compactification/dominator tree destruction.  The idea was to do
   this cleanup always when we ended up having program represented in this form at
   once.  That is after lowering, early opt, IPA and assembling

   This is what tree_lowering_passes used to be.
 - early optimization passes done during the construction of callgraph
   lazilly only for reachable functions. 
   At the end of this stage unused stuff was removed and this stage
   used to happen at the end of each source unit for --combine, so
   we don't blow up memory completely for --combine GCC bootstrap.
 - IPA passes

   This is ipa_passes that sits in cgraphunit.c more or less for
   historical reasons when non-cgraph enabled frontends would not
   link anymore if it was elsewhere.
   (cgraph.c and rest was part of libbackend.a, while cgraphunit.c
   and tree-inline.c was part only of cgraph enabled backend, that
   is not f77, and it was having access to tree walking stuff).
 - rest of optimization executed form final pass over cgraph when
   it is being output and destroyed.

   (tree_rest_of_compilation, that probably should also go)

My longer term plan was to get cgraphunit out of busyness by moving
all the compilation driving logic (i.e. cgraph_optimize) into passes.c
and moving most of stuff done out of pass manager into passes.

Things got more complicated with introduction of LTO/WHOPR and we moved
to unit-at-a-time gimplification that killed original purpose of lowering
pases.  

Honza

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][1/n] Cleanup global pass execution flow
  2012-04-05 13:55 [PATCH][1/n] Cleanup global pass execution flow Richard Guenther
  2012-04-05 14:51 ` Jan Hubicka
@ 2012-04-05 15:23 ` Diego Novillo
  2012-04-05 15:31   ` Jan Hubicka
  1 sibling, 1 reply; 4+ messages in thread
From: Diego Novillo @ 2012-04-05 15:23 UTC (permalink / raw)
  To: Richard Guenther; +Cc: gcc-patches, Jan Hubicka

On 4/5/12 9:54 AM, Richard Guenther wrote:

> Honza, does this look ok?  I am going to continue this way
> until I can re-architect the toplevel pass structure in a way
> that we hand control more to the pass manager.  Well, hopefully ;)

Related to this, have you thought about the handoff points between front 
ends and the middle end?

In LTO (and at some point in the gimple front end branch) we have all 
this code setting up various tidbits like:

- Creating cgraph nodes.
- Creating FUNCTION_DECLs
- Setting their gimple bodies
- Etc.

It would be nice if front ends had a single handoff point into the 
middle-end.

So, for instance, if the FE only needed to call cgraph_create_node() or 
varpool_node() to register new functions and globals.

After doing all that registration, the FE calls cgraph_optimize() (or 
some other unique entry point).

I *think* this is roughly how things work, but there seem to be various 
other cgraph/middle-end calls made from front ends.



Diego.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH][1/n] Cleanup global pass execution flow
  2012-04-05 15:23 ` Diego Novillo
@ 2012-04-05 15:31   ` Jan Hubicka
  0 siblings, 0 replies; 4+ messages in thread
From: Jan Hubicka @ 2012-04-05 15:31 UTC (permalink / raw)
  To: Diego Novillo; +Cc: Richard Guenther, gcc-patches, Jan Hubicka

> On 4/5/12 9:54 AM, Richard Guenther wrote:
> 
> >Honza, does this look ok?  I am going to continue this way
> >until I can re-architect the toplevel pass structure in a way
> >that we hand control more to the pass manager.  Well, hopefully ;)
> 
> Related to this, have you thought about the handoff points between
> front ends and the middle end?
> 
> In LTO (and at some point in the gimple front end branch) we have
> all this code setting up various tidbits like:
> 
> - Creating cgraph nodes.
> - Creating FUNCTION_DECLs
> - Setting their gimple bodies
> - Etc.
> 
> It would be nice if front ends had a single handoff point into the
> middle-end.
> 
> So, for instance, if the FE only needed to call cgraph_create_node()
> or varpool_node() to register new functions and globals.

There are cgraph_finalize_function and varpool equivalent for this.
the actual nodes are then build lazily while constructing cgraph...

Out of date description of the basic FE API is in the beggining of
cgraphunit.c. I guess I should update it.
Have some patches to cleanup FE abuse of cgraph in queue now ad
symtab front - I am getting rid of the needed flag and thus also
all those mark_needed calls done for magical purposes.

Honza
> 
> After doing all that registration, the FE calls cgraph_optimize()
> (or some other unique entry point).
> 
> I *think* this is roughly how things work, but there seem to be
> various other cgraph/middle-end calls made from front ends.
> 
> 
> 
> Diego.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-04-05 15:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-05 13:55 [PATCH][1/n] Cleanup global pass execution flow Richard Guenther
2012-04-05 14:51 ` Jan Hubicka
2012-04-05 15:23 ` Diego Novillo
2012-04-05 15:31   ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).