> Hello,
>    following patch introduces a new symbol_table class, encapsulating 
> functions related to symbol table management. Apart from that, cgraph_edge 
> related functions become members of the class. Finally, a portion of clean-up 
> has been applied to cgraph.h.
> 
> Bootstrapped on x86_64-pc-linux-gnu and majority of BEs have been tested for 
> C and C++, no regression observed.
> 
> Thank you,
> Martin
> 
> -  if (!used_as_abstract_origin && cgraph_state != CGRAPH_STATE_PARSING)
> +  if (!used_as_abstract_origin && symtab->state != CGRAPH_STATE_PARSING)

I would probably rename this CGRAPH_ enum into SYMTAB.  Given it is a symtab 
state now ;)
>  
>  struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) 
> cgraph_edge {
> +  /* Remove the edge in the cgraph.  */
> +  void remove (void);
> +
> +  /* Remove the edge from the list of the callers of the callee.  */
> +  void remove_caller (void);
> +
> +  /* Remove the edge from the list of the callees of the caller.  */
> +  void remove_callee (void);

Perhaps those two can become private?
> +
> +  /* Change field call_stmt of edge to NEW_STMT.
> +     If UPDATE_SPECULATIVE and E is any component of speculative
> +     edge, then update all components.  */
> +  void set_call_stmt (gimple new_stmt, bool update_speculative = true);
> +
> +  /* Redirect callee of the edge to N.  The function does not update 
> underlying
> +     call expression.  */
> +  void redirect_callee (cgraph_node *n);
> +
> +  /* Make an indirect edge with an unknown callee an ordinary edge leading to
> +     CALLEE.  DELTA is an integer constant that is to be added to the this
> +     pointer (first parameter) to compensate for skipping
> +     a thunk adjustment.  */
> +  cgraph_edge *make_direct (cgraph_node *callee);
> +
> +  /* Turn edge into speculative call calling N2. Update
> +     the profile so the direct call is taken COUNT times
> +     with FREQUENCY.  */
> +  cgraph_edge *turn_to_speculative (cgraph_node *n2, gcov_type direct_count,
> +                                 int direct_frequency);

Porably make_speculative (like make_direct).
> +
> +  /* If necessary, change the function declaration in the call statement
> +     associated with the edge so that it corresponds to the edge callee.  */
> +  gimple redirect_call_stmt_to_callee (void);
> +
> +   /* Given speculative call edge, return all three components.  */
> +  void speculative_call_info (cgraph_edge *&direct, cgraph_edge *&indirect,
> +                           ipa_ref *&reference);
> +
> +  /* Create clone of edge in the node N represented
> +     by CALL_EXPR the callgraph.  */
> +  cgraph_edge * clone (cgraph_node *n, gimple call_stmt, unsigned stmt_uid,
> +                    gcov_type count_scale, int freq_scale, bool 
> update_original);
> +
> +  /* Speculative call edge turned out to be direct call to CALLE_DECL.
> +     Remove the speculative call sequence and return edge representing the 
> call.
> +     It is up to caller to redirect the call as appropriate. */
> +  cgraph_edge *resolve_speculation (tree callee_decl = NULL);

Probably better to group speculation into one block.
> +
> +  /* Return true when call of edge can not lead to return from caller
> +     and thus it is safe to ignore its side effects for IPA analysis
> +     when computing side effects of the caller.  */
> +  bool cannot_lead_to_return_p (void);
> +
> +  /* Return true when the edge represents a direct recursion.  */
> +  bool recursive_p (void);
> +
> +  /* Return true if the call can be hot.  */
> +  bool maybe_hot_p (void);
> +


> +
> +  /* Perform reachability analysis and reclaim all unreachable nodes.  */
> +  bool remove_unreachable_nodes (bool before_inlining_p, FILE *file);
> +
> +  /* Optimization of function bodies might've rendered some variables as
> +     unnecessary so we want to avoid these from being compiled.  Re-do
> +     reachability starting from variables that are either externally visible
> +     or was referred from the asm output routines.  */
> +  void remove_unreferenced_decls (void);
> +
> +  /* Process CGRAPH_NEW_FUNCTIONS and perform actions necessary to add these
> +     functions into callgraph in a way so they look like ordinary reachable
> +     functions inserted into callgraph already at construction time.  */
> +  void process_new_functions (void);
> +
> +  /* C++ frontend produce same body aliases all over the place, even before 
> PCH
> +     gets streamed out. It relies on us linking the aliases with their 
> function
> +     in order to do the fixups, but ipa-ref is not PCH safe.  Consequentely 
> we
> +     first produce aliases without links, but once C++ FE is sure he won't 
> sream
> +     PCH we build the links via this function.  */
> +  void process_same_body_aliases (void);
> +
> +  /* Output all variables enqueued to be assembled.  */
> +  bool output_variables (void);
> +
> +  /* Output all asm statements we have stored up to be output.  */
> +  void output_asm_statements (void);
> +
> +  /* Analyze the whole compilation unit once it is parsed completely.  */
> +  void finalize_compilation_unit (void);
> +
> +  /* Perform simple optimizations based on callgraph.  */
> +  void compile (void);

It would make sense to order this in a way compilation flows, that is first
finalize_* stuff (since
that is used by FA) ending by finalize_compilation_unit and
process_same_body_aliases, then compile, add_new* stuff, process_new* and then
output_*/asemble_* stuff.
> +
> +  /* Weakrefs may be associated to external decls and thus not output
> +     at expansion time.  Emit all necessary aliases.  */
> +  void output_weakrefs (void);
> +
> +  /* Unregister a symbol NODE.  */
> +  inline void unregister (symtab_node *node);
> +
> +  /* Allocate new callgraph node and insert it into basic data structures.  
> */
> +  cgraph_node *create_empty (void);
> +
> +  void release_symbol (cgraph_node *node, int uid);

Missing comment.
> +
> +  /* Allocate new callgraph node.  */
> +  inline cgraph_node * allocate_cgraph_symbol (void);
There may be chance to friend those four into symtab_node
making it clear they are internal bookkeping issues?
> +
> +  /* Return first static symbol with definition.  */
> +  inline symtab_node *first_symbol (void);
> +
> +  inline asm_node *
> +  first_asm_symbol (void)
> +  {
> +    return asmnodes;
> +  }
> +
> +  /* Return first static symbol with definition.  */
> +  inline symtab_node *first_defined_symbol (void);
> +
> +  /* Return first variable.  */
> +  inline varpool_node *first_variable (void);
> +
> +  /* Return next variable after NODE.  */
> +  inline varpool_node *next_variable (varpool_node *node);
> +
> +  /* Return first static variable with initializer.  */
> +  inline varpool_node *first_static_initializer (void);
> +
> +  /* Return next static variable with initializer after NODE.  */
> +  inline varpool_node *next_static_initializer (varpool_node *node);
> +
> +  /* Return first static variable with definition.  */
> +  inline varpool_node *first_defined_variable (void);
> +
> +  /* Return next static variable with definition after NODE.  */
> +  inline varpool_node *next_defined_variable (varpool_node *node);
> +
> +  /* Return first function with body defined.  */
> +  inline cgraph_node *first_defined_function (void);
> +
> +  /* Return next function with body defined after NODE.  */
> +  inline cgraph_node *next_defined_function (cgraph_node *node);
> +
> +  /* Return first function.  */
> +  inline cgraph_node *first_function (void);
> +
> +  /* Return next function.  */
> +  inline cgraph_node *next_function (cgraph_node *node);
> +
> +  /* Return first function with body defined.  */
> +  cgraph_node *first_function_with_gimple_body (void);
> +
> +  /* Allocate a cgraph_edge structure and fill it with data according to the
> +     parameters of which only CALLEE can be NULL (when creating an indirect 
> call
> +     edge).  */
> +  cgraph_edge *create_edge (cgraph_node *caller, cgraph_node *callee,
> +                         gimple call_stmt, gcov_type count, int freq,
> +                         bool indir_unknown_callee);

I would expect create_edge to be method of caller....
> +
> +  /* Put the edge onto the free list.  */
> +  void free_edge (cgraph_edge *e);

Also perhaps hidding from general interface with friend.  Definitely put it to 
the end of function list.
> +
> +  /* Return next reachable static variable with initializer after NODE.  */
> +  inline cgraph_node *next_function_with_gimple_body (cgraph_node *node);
> +
> +  cgraph_edge_hook_list *add_edge_removal_hook (cgraph_edge_hook, void *);
> +  void remove_edge_removal_hook (cgraph_edge_hook_list *);
> +
> +  cgraph_node_hook_list *add_cgraph_removal_hook (cgraph_node_hook, void *);
> +  void remove_cgraph_removal_hook (cgraph_node_hook_list *);
> +
> +  varpool_node_hook_list *add_varpool_removal_hook (varpool_node_hook,
> +                                                             void *);
> +  void remove_varpool_removal_hook (varpool_node_hook_list *);
> +  cgraph_node_hook_list *add_cgraph_insertion_hook (cgraph_node_hook,
> +                                                    void *);
> +
> +  void remove_cgraph_insertion_hook (cgraph_node_hook_list *);
> +  varpool_node_hook_list *add_varpool_insertion_hook (varpool_node_hook,
> +                                                                   void *);
> +  void remove_varpool_insertion_hook (varpool_node_hook_list *);
> +  cgraph_2edge_hook_list *add_edge_duplication_hook (cgraph_2edge_hook, void 
> *);
> +  void remove_edge_duplication_hook (cgraph_2edge_hook_list *);
> +
> +  cgraph_2node_hook_list *add_cgraph_duplication_hook (cgraph_2node_hook,
> +                                                    void *);
> +  void remove_cgraph_duplication_hook (cgraph_2node_hook_list *);

Add comments.
> +
> +  /* Call all edge removal hooks.  */
> +  void call_edge_removal_hooks (cgraph_edge *e);
> +
> +  /* Call all node insertion hooks.  */
> +  void call_cgraph_insertion_hooks (cgraph_node *node);
> +
> +  /* Call all node removal hooks.  */
> +  void call_cgraph_removal_hooks (cgraph_node *node);
> +
> +  /* Call all node duplication hooks.  */
> +  void call_cgraph_duplication_hooks (cgraph_node *node, cgraph_node *node2);
> +
> +  /* Call all edge duplication hooks.  */
> +  void call_edge_duplication_hooks (cgraph_edge *cs1, cgraph_edge *cs2);
> +
> +  /* Call all node removal hooks.  */
> +  void call_varpool_removal_hooks (varpool_node *node);
> +
> +  /* Call all node insertion hooks.  */
> +  void call_varpool_insertion_hooks (varpool_node *node);
> +
> +  /* Insert NODE to assembler name hash.  */
> +  void insert_to_assembler_name_hash (symtab_node *node, bool with_clones);
> +
> +  /* Remove NODE from assembler name hash.  */
> +  void unlink_from_assembler_name_hash (symtab_node *node, bool with_clones);

Again internal bookkeeping, should go to end and ideally be friend, but I guess 
this one
is used by lto-symtab. (I amy clean it up incrementally)
> +
> +  /* Arrange node to be first in its entry of assembler_name_hash.  */
> +  void symtab_prevail_in_asm_name_hash (symtab_node *node);
> +
> +  /* Initalize asm name hash unless.  */
> +  void symtab_initialize_asm_name_hash (void);
> +
> +  /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables.  */
> +  void change_decl_assembler_name (tree decl, tree name);
> +
> +  /* Rebuild cgraph edges for current function node.  This needs to be run 
> after
> +     passes that don't update the cgraph.  */
> +  unsigned int rebuild_edges (void);

This ought to be method of cgraph_edge.
> +
> +  /* Rebuild cgraph references for current function node.  This needs to be 
> run
> +     after passes that don't update the cgraph.  */
> +  void rebuild_references (void);

LIke here.
> +
> +  /* Once all functions from compilation unit are in memory, produce all 
> clones
> +     and update all calls.  We might also do this on demand if we don't want 
> to
> +     bring all functions to memory prior compilation, but current WHOPR
> +     implementation does that and it is is bit easier to keep everything 
> right
> +     in this order.  */
> +  void materialize_all_clones (void);
> +
> +  /* Hash asmnames ignoring the user specified marks.  */
> +  static hashval_t decl_assembler_name_hash (const_tree asmname);
> +
> +  /* Compare ASMNAME with the DECL_ASSEMBLER_NAME of DECL.  */
> +  static bool decl_assembler_name_equal (tree decl, const_tree asmname);
> +
> +  /* Returns a hash code for P.  */
> +  static hashval_t hash_node_by_assembler_name (const void *p);
> +
> +  /* Returns nonzero if P1 and P2 are equal.  */
> +  static int eq_assembler_name (const void *p1, const void *p2);

Private?
> +
> +  int cgraph_count;
> +  int cgraph_max_uid;
>  
> -/* In symtab.c  */
> -symtab_node *symtab_node_for_asm (const_tree asmname);
> +  int edges_count;
> +  int edges_max_uid;
> +
> +  symtab_node* GTY(()) nodes;
> +  asm_node* GTY(()) asmnodes;
> +  asm_node* GTY(()) asm_last_node;
> +  cgraph_node* GTY(()) free_nodes;
> +
> +  /* Head of a linked list of unused (freed) call graph edges.
> +     Do not GTY((delete)) this list so UIDs gets reliably recycled.  */
> +  cgraph_edge * GTY(()) free_edges;
> +
> +  /* The order index of the next symtab node to be created.  This is
> +     used so that we can sort the cgraph nodes in order by when we saw
> +     them, to support -fno-toplevel-reorder.  */
> +  int order;
> +
> +  /* Set when whole unit has been analyzed so we can access global info.  */
> +  bool global_info_ready;
> +  /* What state callgraph is in right now.  */
> +  enum cgraph_state state;
> +  /* Set when the cgraph is fully build and the basic flags are computed.  */
> +  bool function_flags_ready;
> +
> +  bool cpp_implicit_aliases_done;

Good they are grouped together. Perhaps they all can be part of STATE (as a 
followup)

Thanks,
Honza

Reply via email to