Jan Hubicka <hubi...@ucw.cz> writes:

> Hi,
> this patch implements very basic propaation of return value ranges from VRP
> pass.  This helps std::vector's push_back since we work out value range of
> allocated block.  This propagates only within single translation unit.  I 
> hoped
> we will also do the propagation at WPA stage, but that needs more work on
> ipa-cp side.
>
> I also added code auto-detecting return_nonnull and corresponding 
> -Wsuggest-attribute
>
> Variant of this patch bootstrapped/regtested x86_64-linux, testing with
> this version is running.  I plan to commit the patch at Monday provided
> there are no issues.
>
> gcc/ChangeLog:
>
>       * cgraph.cc (add_detected_attribute_1): New function.
>       (cgraph_node::add_detected_attribute): New member function.
>       * cgraph.h (struct cgraph_node): Declare it.
>       * common.opt: Add Wsuggest-attribute=returns_nonnull.
>       * doc/invoke.texi: Document +Wsuggest-attribute=returns_nonnull.
>       * gimple-range-fold.cc: Include ipa-prop and dependencies.
>       (fold_using_range::range_of_call): Look for return value range.
>       * ipa-prop.cc (struct ipa_return_value_summary): New structure.
>       (class ipa_return_value_sum_t): New summary.
>       (ipa_record_return_value_range): New function.
>       (ipa_return_value_range): New function.
>       * ipa-prop.h (ipa_return_value_range): Declare.
>       (ipa_record_return_value_range): Declare.
>       * ipa-pure-const.cc (warn_function_returns_nonnull): New function.
>       * ipa-utils.h (warn_function_returns_nonnull): Declare.
>       * symbol-summary.h: Fix comment typo.
>       * tree-vrp.cc (execute_ranger_vrp): Record return values.
>
> gcc/testsuite/ChangeLog:
>
>       * gcc.dg/tree-ssa/return-value-range-1.c: New test.
>
> diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
> index e41e5ad3ae7..71dacf23ce1 100644
> --- a/gcc/cgraph.cc
> +++ b/gcc/cgraph.cc
> @@ -2629,6 +2629,54 @@ cgraph_node::set_malloc_flag (bool malloc_p)
>    return changed;
>  }
>  
> +/* Worker to set malloc flag.  */
> +static void
> +add_detected_attribute_1 (cgraph_node *node, const char *attr, bool *changed)
> +{
> +  if (!lookup_attribute (attr, DECL_ATTRIBUTES (node->decl)))
> +    {
> +      DECL_ATTRIBUTES (node->decl) = tree_cons (get_identifier (attr),
> +                                      NULL_TREE, DECL_ATTRIBUTES 
> (node->decl));
> +      *changed = true;
> +    }
> +
> +  ipa_ref *ref;
> +  FOR_EACH_ALIAS (node, ref)
> +    {
> +      cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
> +      if (alias->get_availability () > AVAIL_INTERPOSABLE)
> +     add_detected_attribute_1 (alias, attr, changed);
> +    }
> +
> +  for (cgraph_edge *e = node->callers; e; e = e->next_caller)
> +    if (e->caller->thunk
> +     && (e->caller->get_availability () > AVAIL_INTERPOSABLE))
> +      add_detected_attribute_1 (e->caller, attr, changed);
> +}
> +
> +/* Set DECL_IS_MALLOC on NODE's decl and on NODE's aliases if any.  */
> +
> +bool
> +cgraph_node::add_detected_attribute (const char *attr)
> +{
> +  bool changed = false;
> +
> +  if (get_availability () > AVAIL_INTERPOSABLE)
> +    add_detected_attribute_1 (this, attr, &changed);
> +  else
> +    {
> +      ipa_ref *ref;
> +
> +      FOR_EACH_ALIAS (this, ref)
> +     {
> +       cgraph_node *alias = dyn_cast<cgraph_node *> (ref->referring);
> +       if (alias->get_availability () > AVAIL_INTERPOSABLE)
> +         add_detected_attribute_1 (alias, attr, &changed);
> +     }
> +    }
> +  return changed;
> +}
> +
>  /* Worker to set noreturng flag.  */
>  static void
>  set_noreturn_flag_1 (cgraph_node *node, bool noreturn_p, bool *changed)
> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index cedaaac3a45..cfdd9f693a8 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -1190,6 +1190,10 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : 
> public symtab_node
>  
>    bool set_pure_flag (bool pure, bool looping);
>  
> +  /* Add attribute ATTR to cgraph_node's decl and on aliases of the node
> +     if any.  */
> +  bool add_detected_attribute (const char *attr);
> +
>    /* Call callback on function and aliases associated to the function.
>       When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
>       skipped. */
> diff --git a/gcc/common.opt b/gcc/common.opt
> index d21db5d4a20..0be4f02677c 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -781,6 +781,10 @@ Wsuggest-attribute=malloc
>  Common Var(warn_suggest_attribute_malloc) Warning
>  Warn about functions which might be candidates for __attribute__((malloc)).
>  
> +Wsuggest-attribute=returns_nonnull

- or _?

(If changing it, needs adjustment in rest of patch too.)

> +Common Var(warn_suggest_attribute_malloc) Warning
> +Warn about functions which might be candidates for __attribute__((malloc)).
> +

Typo: s/malloc/nonnull/?

Reply via email to