]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cgraph.h
[Ada] Two typo fixes
[thirdparty/gcc.git] / gcc / cgraph.h
index 66a4dae76184433d749c9ebd7d5e75bed2fc31e1..cfae6e91da92bd50474e2925b12311c3dd69c410 100644 (file)
@@ -1,5 +1,5 @@
 /* Callgraph handling code.
-   Copyright (C) 2003-2019 Free Software Foundation, Inc.
+   Copyright (C) 2003-2020 Free Software Foundation, Inc.
    Contributed by Jan Hubicka
 
 This file is part of GCC.
@@ -81,8 +81,9 @@ enum availability
      program.  */
   AVAIL_AVAILABLE,
   /* Function body/variable initializer is known and all it's uses are
-     explicitly visible within current unit (ie it's address is never taken and
-     it is not exported to other units). Currently used only for functions.  */
+     explicitly visible within current unit (i.e. it's address is never taken
+     and it is not exported to other units). Currently used only for
+     functions.  */
   AVAIL_LOCAL
 };
 
@@ -92,7 +93,7 @@ enum symbol_partitioning_class
    /* External declarations are ignored by partitioning algorithms and they are
       added into the boundary later via compute_ltrans_boundary.  */
    SYMBOL_EXTERNAL,
-   /* Partitioned symbols are pur into one of partitions.  */
+   /* Partitioned symbols are put into one of partitions.  */
    SYMBOL_PARTITION,
    /* Duplicated symbols (such as comdat or constant pool references) are
       copied into every node needing them via add_symbol_to_partition.  */
@@ -108,6 +109,23 @@ struct GTY((desc ("%h.type"), tag ("SYMTAB_SYMBOL"),
 public:
   friend class symbol_table;
 
+  /* Constructor.  */
+  explicit symtab_node (symtab_type t)
+    : type (t), resolution (LDPR_UNKNOWN), definition (false), alias (false),
+      transparent_alias (false), weakref (false), cpp_implicit_alias (false),
+      symver (false), analyzed (false), writeonly (false),
+      refuse_visibility_changes (false), externally_visible (false),
+      no_reorder (false), force_output (false), forced_by_abi (false),
+      unique_name (false), implicit_section (false), body_removed (false),
+      used_from_other_partition (false), in_other_partition (false),
+      address_taken (false), in_init_priority_hash (false),
+      need_lto_streaming (false), offloadable (false), ifunc_resolver (false),
+      order (false), next_sharing_asm_name (NULL),
+      previous_sharing_asm_name (NULL), same_comdat_group (NULL), ref_list (),
+      alias_target (NULL), lto_file_data (NULL), aux (NULL),
+      x_comdat_group (NULL_TREE), x_section (NULL)
+  {}
+
   /* Return name.  */
   const char *name () const;
 
@@ -146,13 +164,13 @@ public:
   void DEBUG_FUNCTION verify (void);
 
   /* Return ipa reference from this symtab_node to
-     REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
+     REFERRED_NODE or REFERRED_VARPOOL_NODE. USE_TYPE specify type
      of the use and STMT the statement (if it exists).  */
   ipa_ref *create_reference (symtab_node *referred_node,
                             enum ipa_ref_use use_type);
 
   /* Return ipa reference from this symtab_node to
-     REFERED_NODE or REFERED_VARPOOL_NODE. USE_TYPE specify type
+     REFERRED_NODE or REFERRED_VARPOOL_NODE. USE_TYPE specify type
      of the use and STMT the statement (if it exists).  */
   ipa_ref *create_reference (symtab_node *referred_node,
                             enum ipa_ref_use use_type, gimple *stmt);
@@ -371,7 +389,7 @@ public:
      Assume that symbol is used (so there is no need to take into account
      garbage collecting linkers)
 
-     This can happen for comdats, commons and weaks when they are previaled
+     This can happen for comdats, commons and weaks when they are prevailed
      by other definition at static linking time.  */
   inline bool
   can_be_discarded_p (void)
@@ -406,7 +424,7 @@ public:
 
      If MEMORY_ACCESSED is true, assume that both memory pointer to THIS
      and S2 is going to be accessed.  This eliminates the situations when
-     either THIS or S2 is NULL and is seful for comparing bases when deciding
+     either THIS or S2 is NULL and is useful for comparing bases when deciding
      about memory aliasing.  */
   int equal_address_to (symtab_node *s2, bool memory_accessed = false);
 
@@ -463,7 +481,7 @@ public:
      set via finalize_function or finalize_decl  */
   unsigned definition : 1;
   /* True when symbol is an alias.
-     Set by ssemble_alias.  */
+     Set by assemble_alias.  */
   unsigned alias : 1;
   /* When true the alias is translated into its target symbol either by GCC
      or assembler (it also may just be a duplicate declaration of the same
@@ -477,7 +495,7 @@ public:
         by varasm.c. For those DECL_ASSEMBLER_NAME have
         IDENTIFIER_TRANSPARENT_ALIAS set and thus also their assembler
         name must be unique.
-        Weakrefs belong to this cateogry when we target assembler without
+        Weakrefs belong to this category when we target assembler without
         .weakref directive.
        - weakrefs that are renamed by assembler via .weakref directive.
         In this case the alias may or may not be definition (depending if
@@ -496,6 +514,8 @@ public:
      and their visibility needs to be copied from their "masters" at
      the end of parsing.  */
   unsigned cpp_implicit_alias : 1;
+  /* The alias is a symbol version.  */
+  unsigned symver : 1;
   /* Set once the definition was analyzed.  The list of references and
      other properties are built during analysis.  */
   unsigned analyzed : 1;
@@ -648,8 +668,10 @@ symtab_node::checking_verify_symtab_nodes (void)
 }
 
 /* Walk all aliases for NODE.  */
-#define FOR_EACH_ALIAS(node, alias) \
-  for (unsigned x_i = 0; node->iterate_direct_aliases (x_i, alias); x_i++)
+#define FOR_EACH_ALIAS(NODE, ALIAS)                            \
+  for (unsigned ALIAS##_iter_ = 0;                             \
+       (NODE)->iterate_direct_aliases (ALIAS##_iter_, ALIAS);  \
+       ALIAS##_iter_++)
 
 /* This is the information that is put into the cgraph local structure
    to recover a function.  */
@@ -705,38 +727,6 @@ struct GTY(()) cgraph_thunk_info {
   bool thunk_p;
 };
 
-/* Information about the function collected locally.
-   Available after function is analyzed.  */
-
-struct GTY(()) cgraph_local_info {
-  /* Set when function is visible in current compilation unit only and
-     its address is never taken.  */
-  unsigned local : 1;
-
-  /* False when there is something makes versioning impossible.  */
-  unsigned versionable : 1;
-
-  /* False when function calling convention and signature cannot be changed.
-     This is the case when __builtin_apply_args is used.  */
-  unsigned can_change_signature : 1;
-
-  /* True when the function has been originally extern inline, but it is
-     redefined now.  */
-  unsigned redefined_extern_inline : 1;
-
-  /* True if the function may enter serial irrevocable mode.  */
-  unsigned tm_may_enter_irr : 1;
-};
-
-/* Information about the function that needs to be computed globally
-   once compilation is finished.  Available only with -funit-at-a-time.  */
-
-struct GTY(()) cgraph_global_info {
-  /* For inline clones this points to the function they will be
-     inlined into.  */
-  cgraph_node *inlined_to;
-};
-
 /* Represent which DECL tree (or reference to such tree)
    will be replaced by another tree while versioning.  */
 struct GTY(()) ipa_replace_map
@@ -928,6 +918,29 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
 {
   friend class symbol_table;
 
+  /* Constructor.  */
+  explicit cgraph_node (int uid)
+    : symtab_node (SYMTAB_FUNCTION), callees (NULL), callers (NULL),
+      indirect_calls (NULL), origin (NULL), nested (NULL), next_nested (NULL),
+      next_sibling_clone (NULL), prev_sibling_clone (NULL), clones (NULL),
+      clone_of (NULL), call_site_hash (NULL), former_clone_of (NULL),
+      simdclone (NULL), simd_clones (NULL), ipa_transforms_to_apply (vNULL),
+      inlined_to (NULL), rtl (NULL), clone (), thunk (),
+      count (profile_count::uninitialized ()),
+      count_materialization_scale (REG_BR_PROB_BASE), profile_id (0),
+      unit_id (0), tp_first_run (0), used_as_abstract_origin (false),
+      lowered (false), process (false), frequency (NODE_FREQUENCY_NORMAL),
+      only_called_at_startup (false), only_called_at_exit (false),
+      tm_clone (false), dispatcher_function (false), calls_comdat_local (false),
+      icf_merged (false), nonfreeing_fn (false), merged_comdat (false),
+      merged_extern_inline (false), parallelized_function (false),
+      split_part (false), indirect_call_target (false), local (false),
+      versionable (false), can_change_signature (false),
+      redefined_extern_inline (false), tm_may_enter_irr (false),
+      ipcp_clone (false), declare_variant_alt (false),
+      calls_declare_variant_alt (false), m_uid (uid), m_summary_id (-1)
+  {}
+
   /* Remove the node from cgraph and all inline clones inlined into it.
      Skip however removal of FORBIDDEN_NODE and return true if it needs to be
      removed.  This allows to call the function from outer loop walking clone
@@ -972,12 +985,12 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
      When UPDATE_ORIGINAL is true, the counts are subtracted from the original
      function's profile to reflect the fact that part of execution is handled
      by node.
-     When CALL_DUPLICATOIN_HOOK is true, the ipa passes are acknowledged about
+     When CALL_DUPLICATION_HOOK is true, the ipa passes are acknowledged about
      the new clone. Otherwise the caller is responsible for doing so later.
 
      If the new node is being inlined into another one, NEW_INLINED_TO should be
      the outline function the new one is (even indirectly) inlined to.
-     All hooks will see this in node's global.inlined_to, when invoked.
+     All hooks will see this in node's inlined_to, when invoked.
      Can be NULL if the node is not inlined.  SUFFIX is string that is appended
      to the original name.  */
   cgraph_node *create_clone (tree decl, profile_count count,
@@ -996,6 +1009,10 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
                                     ipa_param_adjustments *param_adjustments,
                                     const char * suffix, unsigned num_suffix);
 
+  /* Remove the node from the tree of virtual and inline clones and make it a
+     standalone node - not a clone any more.  */
+  void remove_from_clone_tree ();
+
   /* cgraph node being removed from symbol table; see if its entry can be
    replaced by other inline clone.  */
   cgraph_node *find_replacement (void);
@@ -1153,7 +1170,7 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
   /* Likewise indicate that a node is having address taken.  */
   void mark_address_taken (void);
 
-  /* Set fialization priority to PRIORITY.  */
+  /* Set finalization priority to PRIORITY.  */
   void set_fini_priority (priority_type priority);
 
   /* Return the finalization priority.  */
@@ -1209,7 +1226,7 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
     If SET_CONST if false, clear the flag.
 
     When setting the flag be careful about possible interposition and
-    do not set the flag for functions that can be interposet and set pure
+    do not set the flag for functions that can be interposed and set pure
     flag for functions that can bind to other definition. 
 
     Return true if any change was done. */
@@ -1310,6 +1327,10 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
   /* Return true if this node represents a former, i.e. an expanded, thunk.  */
   inline bool former_thunk_p (void);
 
+  /* Check if function calls comdat local.  This is used to recompute
+     calls_comdat_local flag after function transformations.  */
+  bool check_calls_comdat_local_p ();
+
   /* Return true if function should be optimized for size.  */
   bool optimize_for_size_p (void);
 
@@ -1377,9 +1398,9 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
   static cgraph_node * get_create (tree);
 
   /* Return local info for the compiled function.  */
-  static cgraph_local_info *local_info (tree decl);
+  static cgraph_node *local_info_node (tree decl);
 
-  /* Return local info for the compiled function.  */
+  /* Return RTL info for the compiled function.  */
   static struct cgraph_rtl_info *rtl_info (const_tree);
 
   /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
@@ -1443,8 +1464,10 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
      per-function in order to allow IPA passes to introduce new functions.  */
   vec<ipa_opt_pass> GTY((skip)) ipa_transforms_to_apply;
 
-  cgraph_local_info local;
-  cgraph_global_info global;
+  /* For inline clones this points to the function they will be
+     inlined into.  */
+  cgraph_node *inlined_to;
+
   struct cgraph_rtl_info *rtl;
   cgraph_clone_info clone;
   cgraph_thunk_info thunk;
@@ -1456,6 +1479,8 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
   int count_materialization_scale;
   /* ID assigned by the profiling.  */
   unsigned int profile_id;
+  /* ID of the translation unit.  */
+  int unit_id;
   /* Time profiler: first run of function.  */
   int tp_first_run;
 
@@ -1492,12 +1517,34 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
   unsigned nonfreeing_fn : 1;
   /* True if there was multiple COMDAT bodies merged by lto-symtab.  */
   unsigned merged_comdat : 1;
+  /* True if this def was merged with extern inlines.  */
+  unsigned merged_extern_inline : 1;
   /* True if function was created to be executed in parallel.  */
   unsigned parallelized_function : 1;
   /* True if function is part split out by ipa-split.  */
   unsigned split_part : 1;
   /* True if the function appears as possible target of indirect call.  */
   unsigned indirect_call_target : 1;
+  /* Set when function is visible in current compilation unit only and
+     its address is never taken.  */
+  unsigned local : 1;
+  /* False when there is something makes versioning impossible.  */
+  unsigned versionable : 1;
+  /* False when function calling convention and signature cannot be changed.
+     This is the case when __builtin_apply_args is used.  */
+  unsigned can_change_signature : 1;
+  /* True when the function has been originally extern inline, but it is
+     redefined now.  */
+  unsigned redefined_extern_inline : 1;
+  /* True if the function may enter serial irrevocable mode.  */
+  unsigned tm_may_enter_irr : 1;
+  /* True if this was a clone created by ipa-cp.  */
+  unsigned ipcp_clone : 1;
+  /* True if this is the deferred declare variant resolution artificial
+     function.  */
+  unsigned declare_variant_alt : 1;
+  /* True if the function calls declare_variant_alt functions.  */
+  unsigned calls_declare_variant_alt : 1;
 
 private:
   /* Unique id of the node.  */
@@ -1579,7 +1626,7 @@ public:
   ipa_polymorphic_call_context (cgraph_edge *e);
   /* Build polymorphic call context for IP invariant CST.
      If specified, OTR_TYPE specify the type of polymorphic call
-     that takes CST+OFFSET as a prameter.  */
+     that takes CST+OFFSET as a parameter.  */
   ipa_polymorphic_call_context (tree cst, tree otr_type = NULL,
                                HOST_WIDE_INT offset = 0);
   /* Build context for pointer REF contained in FNDECL at statement STMT.
@@ -1595,7 +1642,7 @@ public:
   /* Make context non-speculative.  */
   void clear_speculation ();
 
-  /* Produce context specifying all derrived types of OTR_TYPE.  If OTR_TYPE is
+  /* Produce context specifying all derived types of OTR_TYPE.  If OTR_TYPE is
      NULL, the context is set to dummy "I know nothing" setting.  */
   void clear_outer_type (tree otr_type = NULL);
 
@@ -1618,8 +1665,8 @@ public:
   /* Use when we cannot track dynamic type change.  This speculatively assume
      type change is not happening.  */
   void possible_dynamic_type_change (bool, tree otr_type = NULL);
-  /* Assume that both THIS and a given context is valid and strenghten THIS
-     if possible.  Return true if any strenghtening was made.
+  /* Assume that both THIS and a given context is valid and strengthen THIS
+     if possible.  Return true if any strengthening was made.
      If actual type the context is being used in is known, OTR_TYPE should be
      set accordingly. This improves quality of combined result.  */
   bool combine_with (ipa_polymorphic_call_context, tree otr_type = NULL);
@@ -1666,10 +1713,9 @@ public:
   int param_index;
   /* ECF flags determined from the caller.  */
   int ecf_flags;
-  /* Profile_id of common target obtrained from profile.  */
-  int common_target_id;
-  /* Probability that call will land in function with COMMON_TARGET_ID.  */
-  int common_target_probability;
+
+  /* Number of speculative call targets, it's less than GCOV_TOPN_VALUES.  */
+  unsigned num_speculative_call_targets : 16;
 
   /* Set when the call is a virtual call with the parameter being the
      associated object pointer rather than a simple direct call.  */
@@ -1699,13 +1745,15 @@ public:
   friend struct cgraph_node;
   friend class symbol_table;
 
-  /* Remove the edge in the cgraph.  */
-  void remove (void);
+  /* Remove EDGE from the cgraph.  */
+  static void remove (cgraph_edge *edge);
 
-  /* 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 (gcall *new_stmt, bool update_speculative = true);
+  /* Change field call_stmt of edge E to NEW_STMT.  If UPDATE_SPECULATIVE and E
+     is any component of speculative edge, then update all components.
+     Speculations can be resolved in the process and EDGE can be removed and
+     deallocated.  Return the edge that now represents the call.  */
+  static cgraph_edge *set_call_stmt (cgraph_edge *e, gcall *new_stmt,
+                                    bool update_speculative = true);
 
   /* Redirect callee of the edge to N.  The function does not update underlying
      call expression.  */
@@ -1718,28 +1766,130 @@ public:
   void redirect_callee_duplicating_thunks (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);
+     CALLEE.  Speculations can be resolved in the process and EDGE can be
+     removed and deallocated.  Return the edge that now represents the
+     call.  */
+  static cgraph_edge *make_direct (cgraph_edge *edge, 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 *make_speculative (cgraph_node *n2, profile_count direct_count);
+     with FREQUENCY.  speculative_id is used to link direct calls with their
+     corresponding IPA_REF_ADDR references when representing speculative calls.
+   */
+  cgraph_edge *make_speculative (cgraph_node *n2, profile_count direct_count,
+                                unsigned int speculative_id = 0);
+
+  /* Speculative call consists of an indirect edge and one or more
+     direct edge+ref pairs.  Speculative will expand to the following sequence:
+
+     if (call_dest == target1)         // reference to target1
+       target1 ();                     // direct call to target1
+     else if (call_dest == target2)    // reference to targt2
+       target2 ();                     // direct call to target2
+     else
+       call_dest ();                   // indirect call
+
+     Before the expansion we will have indirect call and the direct call+ref
+     pairs all linked to single statement.
+
+     Note that ref may point to different symbol than the corresponding call
+     becuase the speculated edge may have been optimized (redirected to
+     a clone) or inlined.
 
-   /* Given speculative call edge, return all three components.  */
-  void speculative_call_info (cgraph_edge *&direct, cgraph_edge *&indirect,
-                             ipa_ref *&reference);
+     Given an edge which is part of speculative call, return the first
+     direct call edge in the speculative call sequence.
 
-  /* 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);
+     In the example above called on any cgraph edge in the sequence it will
+     return direct call to target1.  */
+  cgraph_edge *first_speculative_call_target ();
+
+  /* Return next speculative call target or NULL if there is none.
+     All targets are required to form an interval in the callee list.
+
+     In example above, if called on call to target1 it will return call to
+     target2.  */
+  cgraph_edge *next_speculative_call_target ()
+  {
+    cgraph_edge *e = this;
+    gcc_checking_assert (speculative && callee);
+
+    if (e->next_callee && e->next_callee->speculative
+       && e->next_callee->call_stmt == e->call_stmt
+       && e->next_callee->lto_stmt_uid == e->lto_stmt_uid)
+      return e->next_callee;
+    return NULL;
+  }
+
+  /* When called on any edge in the speculative call return the (unique)
+     indirect call edge in the speculative call sequence.  */
+  cgraph_edge *speculative_call_indirect_edge ()
+  {
+    gcc_checking_assert (speculative);
+    if (!callee)
+      return this;
+    for (cgraph_edge *e2 = caller->indirect_calls;
+        true; e2 = e2->next_callee)
+      if (e2->speculative
+         && call_stmt == e2->call_stmt
+         && lto_stmt_uid == e2->lto_stmt_uid)
+       return e2;
+  }
+
+  /* When called on any edge in speculative call and when given any target
+     of ref which is speculated to it returns the corresponding direct call.
+
+     In example above if called on function target2 it will return call to
+     target2.  */
+  cgraph_edge *speculative_call_for_target (cgraph_node *);
+
+  /* Return REF corresponding to direct call in the specualtive call
+     sequence.  */
+  ipa_ref *speculative_call_target_ref ()
+  {
+    ipa_ref *ref;
+
+    gcc_checking_assert (speculative);
+    for (unsigned int i = 0; caller->iterate_reference (i, ref); i++)
+      if (ref->speculative && ref->speculative_id == speculative_id
+         && ref->stmt == (gimple *)call_stmt
+         && ref->lto_stmt_uid == lto_stmt_uid)
+       return ref;
+    gcc_unreachable ();
+  }
+
+  /* Speculative call edge turned out to be direct call to CALLEE_DECL.  Remove
+     the speculative call sequence and return edge representing the call, the
+     original EDGE can be removed and deallocated.  It is up to caller to
+     redirect the call as appropriate.  Return the edge that now represents the
+     call.
+
+     For "speculative" indirect call that contains multiple "speculative"
+     targets (i.e. edge->indirect_info->num_speculative_call_targets > 1),
+     decrease the count and only remove current direct edge.
+
+     If no speculative direct call left to the speculative indirect call, remove
+     the speculative of both the indirect call and corresponding direct edge.
+
+     It is up to caller to iteratively resolve each "speculative" direct call
+     and redirect the call as appropriate.  */
+  static cgraph_edge *resolve_speculation (cgraph_edge *edge,
+                                          tree callee_decl = NULL);
 
   /* 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);
+     associated with edge E so that it corresponds to the edge callee.
+     Speculations can be resolved in the process and EDGE can be removed and
+     deallocated.
+
+     The edge could be one of speculative direct call generated from speculative
+     indirect call.  In this circumstance, decrease the speculative targets
+     count (i.e. num_speculative_call_targets) and redirect call stmt to the
+     corresponding i-th target.  If no speculative direct call left to the
+     speculative indirect call, remove "speculative" of the indirect call and
+     also redirect stmt to it's final direct target.
+
+     It is up to caller to iteratively transform each "speculative"
+     direct call as appropriate.  */
+  static gimple *redirect_call_stmt_to_callee (cgraph_edge *e);
 
   /* Create clone of edge in the node N represented
      by CALL_EXPR the callgraph.  */
@@ -1785,6 +1935,9 @@ public:
      be internal to the current translation unit.  */
   bool possibly_call_in_translation_unit_p (void);
 
+  /* Return num_speculative_targets of this edge.  */
+  int num_speculative_call_targets_p (void);
+
   /* Expected number of executions: calculated in profile.c.  */
   profile_count count;
   cgraph_node *caller;
@@ -1804,6 +1957,9 @@ public:
   /* The stmt_uid of call_stmt.  This is used by LTO to recover the call_stmt
      when the function is serialized in.  */
   unsigned int lto_stmt_uid;
+  /* speculative id is used to link direct calls with their corresponding
+     IPA_REF_ADDR references when representing speculative calls.  */
+  unsigned int speculative_id : 16;
   /* Whether this edge was made direct by indirect inlining.  */
   unsigned int indirect_inlining_edge : 1;
   /* Whether this edge describes an indirect call with an undetermined
@@ -1827,10 +1983,10 @@ public:
      to a same call statement:
      1) a direct call (to expected_fn)
      2) an indirect call (to call_target)
-     3) a IPA_REF_ADDR refrence to expected_fn.
+     3) a IPA_REF_ADDR reference to expected_fn.
 
      Optimizers may later redirect direct call to clone, so 1) and 3)
-     do not need to necesarily agree with destination.  */
+     do not need to necessarily agree with destination.  */
   unsigned int speculative : 1;
   /* Set to true when caller is a constructor or destructor of polymorphic
      type.  */
@@ -1879,6 +2035,12 @@ private:
 
 struct GTY((tag ("SYMTAB_VARIABLE"))) varpool_node : public symtab_node
 {
+  /* Constructor.  */
+  explicit varpool_node ()
+    : symtab_node (SYMTAB_VARIABLE), output (0), dynamically_initialized (0),
+      tls_model (TLS_MODEL_NONE), used_by_single_function (0)
+  {}
+
   /* Dump given varpool node to F.  */
   void dump (FILE *f);
 
@@ -1923,7 +2085,7 @@ struct GTY((tag ("SYMTAB_VARIABLE"))) varpool_node : public symtab_node
      sections can be resolved.  */
   void finalize_named_section_flags (void);
 
-  /* Call calback on varpool symbol and aliases associated to varpool symbol.
+  /* Call callback on varpool symbol and aliases associated to varpool symbol.
      When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
      skipped. */
   bool call_for_symbol_and_aliases (bool (*callback) (varpool_node *, void *),
@@ -1991,7 +2153,7 @@ struct GTY((tag ("SYMTAB_VARIABLE"))) varpool_node : public symtab_node
   ENUM_BITFIELD(tls_model) tls_model : 3;
 
   /* Set if the variable is known to be used by single function only.
-     This is computed by ipa_signle_use pass and used by late optimizations
+     This is computed by ipa_single_use pass and used by late optimizations
      in places where optimization would be valid for local static variable
      if we did not do any inter-procedural code movement.  */
   unsigned used_by_single_function : 1;
@@ -2029,7 +2191,7 @@ is_a_helper <cgraph_node *>::test (symtab_node *p)
   return p && p->type == SYMTAB_FUNCTION;
 }
 
-/* Report whether or not THIS symtab node is a vriable, aka varpool_node.  */
+/* Report whether or not THIS symtab node is a variable, aka varpool_node.  */
 
 template <>
 template <>
@@ -2093,9 +2255,19 @@ public:
   friend struct cgraph_node;
   friend struct cgraph_edge;
 
-  symbol_table (): cgraph_max_uid (1), cgraph_max_summary_id (0),
-  edges_max_uid (1), edges_max_summary_id (0),
-  cgraph_released_summary_ids (), edge_released_summary_ids ()
+  symbol_table (): 
+  cgraph_count (0), cgraph_max_uid (1), cgraph_max_summary_id (0),
+  edges_count (0), edges_max_uid (1), edges_max_summary_id (0),
+  cgraph_released_summary_ids (), edge_released_summary_ids (),
+  nodes (NULL), asmnodes (NULL), asm_last_node (NULL),
+  order (0), max_unit (0), global_info_ready (false), state (PARSING),
+  function_flags_ready (false), cpp_implicit_aliases_done (false),
+  section_hash (NULL), assembler_name_hash (NULL), init_priority_hash (NULL),
+  dump_file (NULL), ipa_clones_dump_file (NULL), cloned_nodes (),
+  m_first_edge_removal_hook (NULL), m_first_cgraph_removal_hook (NULL),
+  m_first_edge_duplicated_hook (NULL), m_first_cgraph_duplicated_hook (NULL),
+  m_first_cgraph_insertion_hook (NULL), m_first_varpool_insertion_hook (NULL),
+  m_first_varpool_removal_hook (NULL)
   {
   }
 
@@ -2110,9 +2282,9 @@ public:
 
   /* 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.  */
+     in order to do the fixups, but ipa-ref is not PCH safe.  Consequently we
+     first produce aliases without links, but once C++ FE is sure it won't
+     stream PCH we build the links via this function.  */
   void process_same_body_aliases (void);
 
   /* Perform simple optimizations based on callgraph.  */
@@ -2286,7 +2458,7 @@ public:
   /* 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.  */
+  /* Initialize asm name hash unless.  */
   void symtab_initialize_asm_name_hash (void);
 
   /* Set the DECL_ASSEMBLER_NAME and update symtab hashtables.  */
@@ -2341,6 +2513,9 @@ public:
   /* Vector of released summary IDS for cgraph nodes.  */
   vec<int> GTY ((skip)) edge_released_summary_ids;
 
+  /* Return symbol used to separate symbol name from suffix.  */
+  static char symbol_suffix_separator ();
+
   symtab_node* GTY(()) nodes;
   asm_node* GTY(()) asmnodes;
   asm_node* GTY(()) asm_last_node;
@@ -2350,6 +2525,9 @@ public:
      them, to support -fno-toplevel-reorder.  */
   int order;
 
+  /* Maximal unit ID used.  */
+  int max_unit;
+
   /* Set when whole unit has been analyzed so we can access global info.  */
   bool global_info_ready;
   /* What state callgraph is in right now.  */
@@ -2359,7 +2537,7 @@ public:
 
   bool cpp_implicit_aliases_done;
 
-  /* Hash table used to hold sectoons.  */
+  /* Hash table used to hold sections.  */
   hash_table<section_name_hasher> *GTY(()) section_hash;
 
   /* Hash table used to convert assembler names into nodes.  */
@@ -2370,17 +2548,11 @@ public:
 
   FILE* GTY ((skip)) dump_file;
 
-  /* Return symbol used to separate symbol name from suffix.  */
-  static char symbol_suffix_separator ();
-
   FILE* GTY ((skip)) ipa_clones_dump_file;
 
   hash_set <const cgraph_node *> GTY ((skip)) cloned_nodes;
 
 private:
-  /* Allocate new callgraph node.  */
-  inline cgraph_node * allocate_cgraph_symbol (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).  CLONING_P should be set if properties that are copied from an
@@ -2408,7 +2580,7 @@ private:
 
   /* List of hooks triggered when an edge is removed.  */
   cgraph_edge_hook_list * GTY((skip)) m_first_edge_removal_hook;
-  /* List of hooks triggem_red when a cgraph node is removed.  */
+  /* List of hooks trigger_red when a cgraph node is removed.  */
   cgraph_node_hook_list * GTY((skip)) m_first_cgraph_removal_hook;
   /* List of hooks triggered when an edge is duplicated.  */
   cgraph_2edge_hook_list * GTY((skip)) m_first_edge_duplicated_hook;
@@ -2450,10 +2622,9 @@ bool cgraph_function_possibly_inlined_p (tree);
 const char* cgraph_inline_failed_string (cgraph_inline_failed_t);
 cgraph_inline_failed_type_t cgraph_inline_failed_type (cgraph_inline_failed_t);
 
-extern bool gimple_check_call_matching_types (gimple *, tree, bool);
-
 /* In cgraphunit.c  */
 void cgraphunit_c_finalize (void);
+int tp_first_run_node_cmp (const void *pa, const void *pb);
 
 /*  Initialize datastructures so DECL is a function in lowered gimple form.
     IN_SSA is true if the gimple is in SSA.  */
@@ -2507,13 +2678,13 @@ symtab_node::real_symbol_p (void)
   if (!is_a <cgraph_node *> (this))
     return true;
   cnode = dyn_cast <cgraph_node *> (this);
-  if (cnode->global.inlined_to)
+  if (cnode->inlined_to)
     return false;
   return true;
 }
 
 /* Return true if DECL should have entry in symbol table if used.
-   Those are functions and static & external veriables*/
+   Those are functions and static & external variables.  */
 
 static inline bool
 decl_in_symtab_p (const_tree decl)
@@ -2530,13 +2701,13 @@ symtab_node::in_same_comdat_group_p (symtab_node *target)
 
   if (cgraph_node *cn = dyn_cast <cgraph_node *> (target))
     {
-      if (cn->global.inlined_to)
-       source = cn->global.inlined_to;
+      if (cn->inlined_to)
+       source = cn->inlined_to;
     }
   if (cgraph_node *cn = dyn_cast <cgraph_node *> (target))
     {
-      if (cn->global.inlined_to)
-       target = cn->global.inlined_to;
+      if (cn->inlined_to)
+       target = cn->inlined_to;
     }
 
   return source->get_comdat_group () == target->get_comdat_group ();
@@ -2707,21 +2878,6 @@ symbol_table::release_symbol (cgraph_node *node)
   ggc_free (node);
 }
 
-/* Allocate new callgraph node.  */
-
-inline cgraph_node *
-symbol_table::allocate_cgraph_symbol (void)
-{
-  cgraph_node *node;
-
-  node = ggc_cleared_alloc<cgraph_node> ();
-  node->type = SYMTAB_FUNCTION;
-  node->m_summary_id = -1;
-  node->m_uid = cgraph_max_uid++;
-  return node;
-}
-
-
 /* Return first static symbol with definition.  */
 inline symtab_node *
 symbol_table::first_symbol (void)
@@ -2983,7 +3139,7 @@ struct GTY((for_user)) constant_descriptor_tree {
 inline bool
 cgraph_node::only_called_directly_or_aliased_p (void)
 {
-  gcc_assert (!global.inlined_to);
+  gcc_assert (!inlined_to);
   return (!force_output && !address_taken
          && !ifunc_resolver
          && !used_from_other_partition
@@ -3000,7 +3156,7 @@ cgraph_node::only_called_directly_or_aliased_p (void)
 inline bool
 cgraph_node::can_remove_if_no_direct_calls_and_refs_p (void)
 {
-  gcc_checking_assert (!global.inlined_to);
+  gcc_checking_assert (!inlined_to);
   /* Extern inlines can always go, we will use the external definition.  */
   if (DECL_EXTERNAL (decl))
     return true;
@@ -3012,7 +3168,7 @@ cgraph_node::can_remove_if_no_direct_calls_and_refs_p (void)
     return false;
   /* Only COMDAT functions can be removed if externally visible.  */
   if (externally_visible
-      && (!DECL_COMDAT (decl)
+      && ((!DECL_COMDAT (decl) || ifunc_resolver)
          || forced_by_abi
          || used_from_object_file_p ()))
     return false;
@@ -3152,27 +3308,14 @@ cgraph_edge::set_callee (cgraph_node *n)
   callee = n;
 }
 
-/* Redirect callee of the edge to N.  The function does not update underlying
-   call expression.  */
-
-inline void
-cgraph_edge::redirect_callee (cgraph_node *n)
-{
-  /* Remove from callers list of the current callee.  */
-  remove_callee ();
-
-  /* Insert to callers list of the new callee.  */
-  set_callee (n);
-}
-
 /* Return true when the edge represents a direct recursion.  */
 
 inline bool
 cgraph_edge::recursive_p (void)
 {
   cgraph_node *c = callee->ultimate_alias_target ();
-  if (caller->global.inlined_to)
-    return caller->global.inlined_to->decl == c->decl;
+  if (caller->inlined_to)
+    return caller->inlined_to->decl == c->decl;
   else
     return caller->decl == c->decl;
 }
@@ -3209,8 +3352,8 @@ cgraph_edge::binds_to_current_def_p ()
 inline int
 cgraph_edge::frequency ()
 {
-  return count.to_cgraph_frequency (caller->global.inlined_to
-                                   ? caller->global.inlined_to->count
+  return count.to_cgraph_frequency (caller->inlined_to
+                                   ? caller->inlined_to->count
                                    : caller->count);
 }
 
@@ -3232,7 +3375,7 @@ inline void
 cgraph_node::mark_force_output (void)
 {
   force_output = 1;
-  gcc_checking_assert (!global.inlined_to);
+  gcc_checking_assert (!inlined_to);
 }
 
 /* Return true if function should be optimized for size.  */
@@ -3271,7 +3414,7 @@ symtab_node::get_availability (symtab_node *ref)
     return dyn_cast <varpool_node *> (this)->get_availability (ref);
 }
 
-/* Call calback on symtab node and aliases associated to this node.
+/* Call callback on symtab node and aliases associated to this node.
    When INCLUDE_OVERWRITABLE is false, overwritable symbols are skipped. */
 
 inline bool
@@ -3312,7 +3455,7 @@ cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
   return false;
 }
 
-/* Call calback on varpool symbol and aliases associated to varpool symbol.
+/* Call callback on varpool symbol and aliases associated to varpool symbol.
    When INCLUDE_OVERWRITABLE is false, overwritable symbols are
    skipped. */
 
@@ -3333,7 +3476,7 @@ varpool_node::call_for_symbol_and_aliases (bool (*callback) (varpool_node *,
   return false;
 }
 
-/* Return true if refernece may be used in address compare.  */
+/* Return true if reference may be used in address compare.  */
 
 inline bool
 ipa_ref::address_matters_p ()
@@ -3376,7 +3519,7 @@ ipa_polymorphic_call_context::clear_speculation ()
   speculative_maybe_derived_type = false;
 }
 
-/* Produce context specifying all derrived types of OTR_TYPE.  If OTR_TYPE is
+/* Produce context specifying all derived types of OTR_TYPE.  If OTR_TYPE is
    NULL, the context is set to dummy "I know nothing" setting.  */
 
 inline void