]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/ipa-cp.c
* config/microblaze/microblaze.c (microblaze_expand_block_move): Treat
[thirdparty/gcc.git] / gcc / ipa-cp.c
index 42dd4cc29042300a89ee75e00860d2552484fbbc..59b15fa7362c87de3e063f5b727d1279456b6cd6 100644 (file)
@@ -1,5 +1,5 @@
 /* Interprocedural constant propagation
-   Copyright (C) 2005-2018 Free Software Foundation, Inc.
+   Copyright (C) 2005-2019 Free Software Foundation, Inc.
 
    Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
    <mjambor@suse.cz>
@@ -191,7 +191,7 @@ public:
   /* Depth first search number and low link for topological sorting of
      values.  */
   int dfs, low_link;
-  /* True if this valye is currently on the topo-sort stack.  */
+  /* True if this value is currently on the topo-sort stack.  */
   bool on_stack;
 
   ipcp_value()
@@ -307,18 +307,18 @@ private:
 class ipcp_vr_lattice
 {
 public:
-  value_range m_vr;
+  value_range_base m_vr;
 
   inline bool bottom_p () const;
   inline bool top_p () const;
   inline bool set_to_bottom ();
-  bool meet_with (const value_range *p_vr);
+  bool meet_with (const value_range_base *p_vr);
   bool meet_with (const ipcp_vr_lattice &other);
-  void init () { m_vr.type = VR_UNDEFINED; }
+  void init () { gcc_assert (m_vr.undefined_p ()); }
   void print (FILE * f);
 
 private:
-  bool meet_with_1 (const value_range *other_vr);
+  bool meet_with_1 (const value_range_base *other_vr);
 };
 
 /* Structure containing lattices for a parameter itself and for pieces of
@@ -376,6 +376,9 @@ static profile_count max_count;
 
 static long overall_size, max_new_size;
 
+/* Node name to unique clone suffix number map.  */
+static hash_map<const char *, unsigned> *clone_num_suffixes;
+
 /* Return the param lattices structure corresponding to the Ith formal
    parameter of the function described by INFO.  */
 static inline struct ipcp_param_lattices *
@@ -405,16 +408,6 @@ ipa_get_poly_ctx_lat (struct ipa_node_params *info, int i)
   return &plats->ctxlat;
 }
 
-/* Return the lattice corresponding to the value range of the Ith formal
-   parameter of the function described by INFO.  */
-
-static inline ipcp_vr_lattice *
-ipa_get_vr_lat (struct ipa_node_params *info, int i)
-{
-  struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
-  return &plats->m_value_range;
-}
-
 /* Return whether LAT is a lattice with a single constant and without an
    undefined value.  */
 
@@ -549,6 +542,9 @@ print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
       struct ipa_node_params *info;
 
       info = IPA_NODE_REF (node);
+      /* Skip constprop clones since we don't make lattices for them.  */
+      if (info->ipcp_orig_node)
+       continue;
       fprintf (f, "  Node: %s:\n", node->dump_name ());
       count = ipa_get_param_count (info);
       for (i = 0; i < count; i++)
@@ -638,8 +634,7 @@ determine_versionability (struct cgraph_node *node,
   if (DECL_EXTERNAL (node->decl))
     for (cgraph_edge *edge = node->callees; !reason && edge;
         edge = edge->next_callee)
-      if (DECL_BUILT_IN (edge->callee->decl)
-         && DECL_BUILT_IN_CLASS (edge->callee->decl) == BUILT_IN_NORMAL)
+      if (fndecl_built_in_p (edge->callee->decl, BUILT_IN_NORMAL))
         {
          if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
            reason = "external function which calls va_arg_pack";
@@ -820,7 +815,7 @@ build_toporder_info (struct ipa_topo_info *topo)
   topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
 
   gcc_checking_assert (topo->stack_top == 0);
-  topo->nnodes = ipa_reduced_postorder (topo->order, true, true, NULL);
+  topo->nnodes = ipa_reduced_postorder (topo->order, true, NULL);
 }
 
 /* Free information about strongly connected components and the arrays in
@@ -888,7 +883,7 @@ ipcp_lattice<valtype>::set_contains_variable ()
   return ret;
 }
 
-/* Set all aggegate lattices in PLATS to bottom and return true if they were
+/* Set all aggregate lattices in PLATS to bottom and return true if they were
    not previously set as such.  */
 
 static inline bool
@@ -899,7 +894,7 @@ set_agg_lats_to_bottom (struct ipcp_param_lattices *plats)
   return ret;
 }
 
-/* Mark all aggegate lattices in PLATS as containing an unknown value and
+/* Mark all aggregate lattices in PLATS as containing an unknown value and
    return true if they were not previously marked as such.  */
 
 static inline bool
@@ -916,37 +911,30 @@ ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other)
   return meet_with_1 (&other.m_vr);
 }
 
-/* Meet the current value of the lattice with value ranfge described by VR
+/* Meet the current value of the lattice with value range described by VR
    lattice.  */
 
 bool
-ipcp_vr_lattice::meet_with (const value_range *p_vr)
+ipcp_vr_lattice::meet_with (const value_range_base *p_vr)
 {
   return meet_with_1 (p_vr);
 }
 
-/* Meet the current value of the lattice with value ranfge described by
-   OTHER_VR lattice.  */
+/* Meet the current value of the lattice with value range described by
+   OTHER_VR lattice.  Return TRUE if anything changed.  */
 
 bool
-ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
+ipcp_vr_lattice::meet_with_1 (const value_range_base *other_vr)
 {
-  tree min = m_vr.min, max = m_vr.max;
-  value_range_type type = m_vr.type;
-
   if (bottom_p ())
     return false;
 
-  if (other_vr->type == VR_VARYING)
+  if (other_vr->varying_p ())
     return set_to_bottom ();
 
-  vrp_meet (&m_vr, other_vr);
-  if (type != m_vr.type
-      || min != m_vr.min
-      || max != m_vr.max)
-    return true;
-  else
-    return false;
+  value_range_base save (m_vr);
+  m_vr.union_ (other_vr);
+  return !m_vr.equal_p (save);
 }
 
 /* Return true if value range information in the lattice is yet unknown.  */
@@ -954,7 +942,7 @@ ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
 bool
 ipcp_vr_lattice::top_p () const
 {
-  return m_vr.type == VR_UNDEFINED;
+  return m_vr.undefined_p ();
 }
 
 /* Return true if value range information in the lattice is known to be
@@ -963,7 +951,7 @@ ipcp_vr_lattice::top_p () const
 bool
 ipcp_vr_lattice::bottom_p () const
 {
-  return m_vr.type == VR_VARYING;
+  return m_vr.varying_p ();
 }
 
 /* Set value range information in the lattice to bottom.  Return true if it
@@ -972,9 +960,9 @@ ipcp_vr_lattice::bottom_p () const
 bool
 ipcp_vr_lattice::set_to_bottom ()
 {
-  if (m_vr.type == VR_VARYING)
+  if (m_vr.varying_p ())
     return false;
-  m_vr.type = VR_VARYING;
+  m_vr.set_varying ();
   return true;
 }
 
@@ -1141,7 +1129,7 @@ count_callers (cgraph_node *node, void *data)
   int *caller_count = (int *) data;
 
   for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
-    /* Local thunks can be handled transparently, but if the thunk can not
+    /* Local thunks can be handled transparently, but if the thunk cannot
        be optimized out, count it as a real use.  */
     if (!cs->caller->thunk.thunk_p || !cs->caller->local.local)
       ++*caller_count;
@@ -1345,7 +1333,7 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc,
     return NULL_TREE;
 }
 
-/* Determie whether JFUNC evaluates to single known polymorphic context, given
+/* Determine whether JFUNC evaluates to single known polymorphic context, given
    that INFO describes the caller node or the one it is inlined to, CS is the
    call graph edge corresponding to JFUNC and CSIDX index of the described
    parameter.  */
@@ -1889,16 +1877,16 @@ propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
    the result is a range or an anti-range.  */
 
 static bool
-ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr,
+ipa_vr_operation_and_type_effects (value_range_base *dst_vr,
+                                  value_range_base *src_vr,
                                   enum tree_code operation,
                                   tree dst_type, tree src_type)
 {
-  memset (dst_vr, 0, sizeof (*dst_vr));
-  extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
-  if (dst_vr->type == VR_RANGE || dst_vr->type == VR_ANTI_RANGE)
-    return true;
-  else
+  extract_range_from_unary_expr (dst_vr, operation, dst_type,
+                                src_vr, src_type);
+  if (dst_vr->varying_p () || dst_vr->undefined_p ())
     return false;
+  return true;
 }
 
 /* Propagate value range across jump function JFUNC that is associated with
@@ -1934,7 +1922,7 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
 
          if (src_lats->m_value_range.bottom_p ())
            return dest_lat->set_to_bottom ();
-         value_range vr;
+         value_range_base vr;
          if (ipa_vr_operation_and_type_effects (&vr,
                                                 &src_lats->m_value_range.m_vr,
                                                 operation, param_type,
@@ -1951,20 +1939,16 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
          if (TREE_OVERFLOW_P (val))
            val = drop_tree_overflow (val);
 
-         value_range tmpvr;
-         memset (&tmpvr, 0, sizeof (tmpvr));
-         tmpvr.type = VR_RANGE;
-         tmpvr.min = val;
-         tmpvr.max = val;
+         value_range_base tmpvr (VR_RANGE, val, val);
          return dest_lat->meet_with (&tmpvr);
        }
     }
 
-  value_range vr;
+  value_range_base vr;
   if (jfunc->m_vr
       && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
                                            param_type,
-                                           TREE_TYPE (jfunc->m_vr->min)))
+                                           jfunc->m_vr->type ()))
     return dest_lat->meet_with (&vr);
   else
     return dest_lat->set_to_bottom ();
@@ -2398,7 +2382,7 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
 
   t = NULL;
 
-  /* Try to work out value of virtual table pointer value in replacemnets.  */
+  /* Try to work out value of virtual table pointer value in replacements.  */
   if (!t && agg_reps && !ie->indirect_info->by_ref)
     {
       while (agg_reps)
@@ -2834,11 +2818,18 @@ perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts,
   base_time -= time;
   if (base_time > 65535)
     base_time = 65535;
-  time_benefit = base_time.to_int ()
-    + devirtualization_time_bonus (node, known_csts, known_contexts,
-                                  known_aggs_ptrs)
-    + hint_time_bonus (hints)
-    + removable_params_cost + est_move_cost;
+
+  /* Extern inline functions have no cloning local time benefits because they
+     will be inlined anyway.  The only reason to clone them is if it enables
+     optimization in any of the functions they call.  */
+  if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
+    time_benefit = 0;
+  else
+    time_benefit = base_time.to_int ()
+      + devirtualization_time_bonus (node, known_csts, known_contexts,
+                                    known_aggs_ptrs)
+      + hint_time_bonus (hints)
+      + removable_params_cost + est_move_cost;
 
   gcc_checking_assert (size >=0);
   /* The inliner-heuristics based estimates may think that in certain
@@ -2911,7 +2902,7 @@ estimate_local_effects (struct cgraph_node *node)
                     "known contexts, code not going to grow.\n");
        }
       else if (good_cloning_opportunity_p (node,
-                                          MAX ((base_time - time).to_int (),
+                                          MIN ((base_time - time).to_int (),
                                                65536),
                                           stats.freq_sum, stats.count_sum,
                                           size))
@@ -3738,9 +3729,11 @@ update_profiling_info (struct cgraph_node *orig_node,
   new_sum = orig_node_count.combine_with_ipa_count (new_sum);
   orig_node->count = remainder;
 
+  profile_count::adjust_for_ipa_scaling (&new_sum, &orig_node_count);
   for (cs = new_node->callees; cs; cs = cs->next_callee)
     cs->count = cs->count.apply_scale (new_sum, orig_node_count);
 
+  profile_count::adjust_for_ipa_scaling (&remainder, &orig_node_count);
   for (cs = orig_node->callees; cs; cs = cs->next_callee)
     cs->count = cs->count.apply_scale (remainder, orig_node_count);
 
@@ -3851,8 +3844,13 @@ create_specialized_node (struct cgraph_node *node,
        }
     }
 
+  unsigned &suffix_counter = clone_num_suffixes->get_or_insert (
+                              IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
+                                node->decl)));
   new_node = node->create_virtual_clone (callers, replace_trees,
-                                        args_to_skip, "constprop");
+                                        args_to_skip, "constprop",
+                                        suffix_counter);
+  suffix_counter++;
 
   bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
   for (unsigned j = 0; j < self_recursive_calls.length (); j++)
@@ -4614,7 +4612,7 @@ ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *aggvals,
   return false;
 }
 
-/* Return true if offset is minus one because source of a polymorphic contect
+/* Return true if offset is minus one because source of a polymorphic context
    cannot be an aggregate value.  */
 
 DEBUG_FUNCTION bool
@@ -4625,7 +4623,7 @@ ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *,
   return offset == -1;
 }
 
-/* Decide wheter to create a special version of NODE for value VAL of parameter
+/* Decide whether to create a special version of NODE for value VAL of parameter
    at the given INDEX.  If OFFSET is -1, the value is for the parameter itself,
    otherwise it is stored at the given OFFSET of the parameter.  KNOWN_CSTS,
    KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values.  */
@@ -5039,9 +5037,9 @@ ipcp_store_vr_results (void)
              && !plats->m_value_range.top_p ())
            {
              vr.known = true;
-             vr.type = plats->m_value_range.m_vr.type;
-             vr.min = wi::to_wide (plats->m_value_range.m_vr.min);
-             vr.max = wi::to_wide (plats->m_value_range.m_vr.max);
+             vr.type = plats->m_value_range.m_vr.kind ();
+             vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
+             vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
            }
          else
            {
@@ -5066,6 +5064,7 @@ ipcp_driver (void)
 
   ipa_check_create_node_params ();
   ipa_check_create_edge_args ();
+  clone_num_suffixes = new hash_map<const char *, unsigned>;
 
   if (dump_file)
     {
@@ -5087,6 +5086,7 @@ ipcp_driver (void)
   ipcp_store_vr_results ();
 
   /* Free all IPCP structures.  */
+  delete clone_num_suffixes;
   free_toporder_info (&topo);
   delete edge_clone_summaries;
   edge_clone_summaries = NULL;