On Sun, Apr 22, 2012 at 2:16 PM, Jan Hubicka <hubi...@ucw.cz> wrote: > Hi, > this is second part of cleanup of the callgraph/varpool reachability code. > > As I wrote in previous email, the callgraph was originally written with > reachability code built in. This code was used by non-unit-at-a-time (to drop > unnecesary inline functoins), the unit-a-a-time cgraph builder and by pass > removing unreachable functions. > > It was implemented as a queue of functions known to be needed that was > processed by those consumers, plus by the needed flag (removed in previous > patch) for functions that are trivially needed and reachable flag for > functions that are needed by reachablity analysis. > > Similarly varpool code had reachability built in, but the variables was not > removed (it broke drwarf2out), just they was not output when unreachable. > This was done after functions was output and later this reachability code > was re-used for removal of unreferenced variables, too. > > This all was interlacing with cgraph construction code because we did not > track > all references via ipa-ref like we do now. > > This patch removes the shared reachability code and replaces it by 3 > independent implementations. The motivation is that the 3 cases are different > enough to not motivate code reuse for something as simple as an queue + > walk of ipa-references, callees and same comdat group lists. > > 1) at cgraph/varpool construction time in cgraphbuild.c. This code is bit > complicated by fact that new nodes are being discovered and finalized on the > process (such as local statics of functions that are not visible before > function containing them is lowered, or by openMP expansion). > > The code is now also mre contained (see all the varpool_mark_needed_node > calls that has been removed). Because of non-unit-at-a-time we > used to decide that variables are needed at many different places, in > order to bring them into output file as early as possible. > > Now we discover most of the stuff by walking the IL as we build cgraph > and reference lists. There is still feedback from cgraph_finalize, > varpool_finalize and cgraph_add_new_function for functions/vars appearing > during the process. Not as interwinded as before though. > It is made simple by fact that we have only those references and > calls that are needed and thus function is reachable if it has some > referneces to it. > > Newly we now remove unreferenced varpool nodes that should save some memory. > We should also destroy their DECL_INITIAL pointer, but I am still affraid > of dwarf2out breaking, so I will try that inrementally. > 2) unreachable nodes removal in ipa.c. This is just usual rechability walk, > but it has some extra complication to deal with extern inlines (that stay > in code for a while but past inlining their bodies are removed even if > they are reachable), virtual functions (that also stay for a while to > allow devirtualization via type based mechanizm or external constructors) > and it also has to deal with virtual clones (i.e. we can not remove > original function of the clone prior materialization) and inline clones > (when offline version of function is no longer needed, the clone > tree needs to be reshaped). > 3) final pass in varpool that looks what vars are still needed after > all functions was expanded. This is done by DECL_RLT_SET_P test that > is bit kludgy, but works well. > For example, in combine.c we still remove some of __FUNCTION__ vars because > some of aborts are proven to be unnecesary. > > There are a lot of subsequent cleanups left on the table, I tried to separate > this into a lot smaller patch than this one, but it has significant > snowballing > effect. Most irritating part is the wrapup_global_declarations logic that > once > was there to avoid unreferences static vars to be output but it completely > pointless now. Probably should be moved into cgraph construction stage. > > Other problem is that we are creaing new symbols from realy random places, > like > DECL_ASSEMBLER_NAME langhook callback from C++ FE that creates extra name > aliases... > > The code is now also more picky on variable being finalized in order to be > output. > This uncovers latent bug in C++ FE where explicit instantiations are sometimes > not finalized at all. > > Regtested/bootstrapped x86_64-linux and also tested with LTO Mozilla. > Will commit it tonight. > > Honza > > > * lto-symtab.c (lto_varpool_replace_node): Do not merge needed flags. > * cgraphbuild.c (record_reference, record_type_list, mark_address, > mark_load, mark_store): Do not mark varpool nodes as needed. > * cgraph.c (cgraph_new_nodes): Remove. > (cgraph_create_function_alias): Do not mark nodes as reachable. > (cgraph_add_thunk): Likewise. > (cgraph_mark_reachable_node): Do not manage the queue. > * cgraph.h (cgraph_node): Remove next_needed. > (varpool_nodes_queue): Remove next_needed and prev_needed. > (x_cgraph_nodes_queue, x_cgraph_nodes_queue, cgraph_new_nodes): Remove. > (cgraph_new_nodes): Declare. > (x_varpool_nodes_queue, varpool_nodes_queue); Remove. > (varpool_analyze_pending_decls): Remove. > (varpool_analyze_node): New. > (varpool_mark_needed_node): Remove. > (varpool_first_variable, varpool_next_variable): New inlines. > (varpool_first_static_initializer, varpool_next_static_initializer): > Update. > (FOR_EACH_STATIC_VARIABLE): Remove unused walker. > (varpool_first_defined_variable): New inline. > (varpool_next_defined_variable): New inline > (FOR_EACH_VARIABLE): Reimplement. > (FOR_EACH_DEFINED_VARIABLE): Reimplement. > * toplev.c (wrapup_global_declaration_2): Use analyzed instead of > needed flag. > * cgraphunit.c (cgraph_new_nodes): Declare here. > (enqueue_node): New function. > (cgraph_process_new_functions): update for new > node set; when constructing cgraph enqueue node for processing. > (cgraph_add_new_function): Use new node set. > (process_function_and_variable_attributes): Do not set varpool needed > flags. > (referred_to_p): New function. > (varpool_finalize_decl): Move here from varpool.c; enqueue needed node > when varpool is in construction. > (cgraph_analyze_functions): Rewrite. > (cgraph_expand_all_functions): Update. > (cgraph_output_in_order): Do not analyze pending decls; do not set > needed flags. > (cgraph_optimize): Do not analyze pending decls. > * lto-cgraph.c (input_varpool_node): Clear analyzed flag for objects > in other > partition; do not mark node as needed. > * dwarf2out.c (reference_to_unused): Use analyzed flag. > (premark_types_used_by_global_vars_helper): Likewise. > * ipa.c (process_references): Do not call varpool_mark_needed_node. > (cgraph_remove_unreachable_nodes): Do not rely on varpool and > cgrpah queues. > (function_and_variable_visibility): Do not mark node as needed. > (whole_program_function_and_variable_visibility): Likewise. > * Makefile.in (gt-varpool.h): No longer needed. > * passes.c (execute_one_pass, execute_ipa_pass_list): Update. > (ipa_write_summaries): Do not use needed flag. > * varpool.c: Do not include gt-varpool.h > (x_varpool_nodes_queue, x_varpool_last_needed_node, > x_varpool_last_needed_node, x_varpool_first_unanalyzed_node, > x_varpool_first_unanalyzed_node, varpool_assembled_nodes_queue): > Remove. > (varpool_remove_node): Do not update the lists. > (dump_varpool_node): Do not dump needed flag. > (varpool_enqueue_needed_node): Remove. > (varpool_mark_needed_node): Remove. > (varpool_reset_queue): Remove. > (varpool_finalize_decl): Move to cgraphunit.c > (varpool_analyze_node): New functions based on former > varpool_analyze_pending_decls. > (varpool_analyze_pending_decls): Remove. > (varpool_assemble_decl): Do not update the lists. > (enqueue_node): New function. > (varpool_remove_unreferenced_decls): Rewrite. > (varpool_empty_needed_queue): Remove. > (add_new_static_var): Do not mark node as needed. > (varpool_create_variable_alias): Handle expansion state > creation. > * except.c (output_ttype): Do not mark node as needed. > * varasm.c (mark_decl_referenced): Do not use mark_needed_node. > * tree-profile.c (init_ic_make_global_vars, init_ic_make_global_vars): > Likewise. > * tree-switch-conversion.c (build_one_array): Likewise. > > * class.c (build_utf8_ref): Do not mark varpool node as needed. > > * gcc-interface/utils.c (gnat_write_global_declarations): Do not mark > needed node. > > * lto-partition.c (partition_varpool_node_p): Do not use needed flag. > > * decl2.c (maybe_make_one_only): Mark keyed COMDATs as USED so they > gets finalized.
This caused: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53088 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53089 -- H.J.