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/?