This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Symbol table 13/many: reachability code rewrite


On Sun, Apr 22, 2012 at 2:16 PM, Jan Hubicka <hubicka@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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]