aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-range-fold.cc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2023-11-20 19:35:53 +0100
committerJan Hubicka <jh@suse.cz>2023-11-20 19:37:45 +0100
commit53ba8d669550d3a1f809048428b97ca607f95cf5 (patch)
tree1c0da57f4c241b70c38a51fcebab3ff5644f6298 /gcc/gimple-range-fold.cc
parent57c028acbec4f7b594e6b024e02d6c799b51e03d (diff)
downloadgcc-53ba8d669550d3a1f809048428b97ca607f95cf5.zip
gcc-53ba8d669550d3a1f809048428b97ca607f95cf5.tar.gz
gcc-53ba8d669550d3a1f809048428b97ca607f95cf5.tar.bz2
inter-procedural value range propagation
implement very basic propapgation 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. gcc/ChangeLog: * cgraph.cc (add_detected_attribute_1): New function. (cgraph_node::add_detected_attribute): Likewise. * cgraph.h (cgraph_node::add_detected_attribute): Declare. * common.opt: Add -Wsuggest-attribute=returns_nonnull. * doc/invoke.texi: Document new flag. * gimple-range-fold.cc (fold_using_range::range_of_call): Use known reutrn value ranges. * ipa-prop.cc (struct ipa_return_value_summary): New type. (class ipa_return_value_sum_t): New type. (ipa_return_value_sum): 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 funcion. * ipa-utils.h (warn_function_returns_nonnull): Declare. * symbol-summary.h: Fix comment. * tree-vrp.cc (execute_ranger_vrp): Record return values. gcc/testsuite/ChangeLog: * g++.dg/ipa/devirt-2.C: Add noipa attribute to prevent ipa-vrp. * g++.dg/ipa/devirt-7.C: Disable ipa-vrp. * g++.dg/ipa/ipa-icf-2.C: Disable ipa-vrp. * g++.dg/ipa/ipa-icf-3.C: Disable ipa-vrp. * g++.dg/ipa/ivinline-1.C: Disable ipa-vrp. * g++.dg/ipa/ivinline-3.C: Disable ipa-vrp. * g++.dg/ipa/ivinline-5.C: Disable ipa-vrp. * g++.dg/ipa/ivinline-8.C: Disable ipa-vrp. * g++.dg/ipa/nothrow-1.C: Disable ipa-vrp. * g++.dg/ipa/pure-const-1.C: Disable ipa-vrp. * g++.dg/ipa/pure-const-2.C: Disable ipa-vrp. * g++.dg/lto/inline-crossmodule-1_0.C: Disable ipa-vrp. * gcc.c-torture/compile/pr106433.c: Add noipa attribute to prevent ipa-vrp. * gcc.c-torture/execute/frame-address.c: Likewise. * gcc.dg/vla-1.c: Add noipa attribute to prevent ipa-vrp. * gcc.dg/ipa/fopt-info-inline-1.c: Disable ipa-vrp. * gcc.dg/ipa/ipa-icf-25.c: Disable ipa-vrp. * gcc.dg/ipa/ipa-icf-38.c: Disable ipa-vrp. * gcc.dg/ipa/pure-const-1.c: Disable ipa-vrp. * gcc.dg/ipa/remref-0.c: Add noipa attribute to prevent ipa-vrp. * gcc.dg/tree-prof/time-profiler-1.c: Disable ipa-vrp. * gcc.dg/tree-prof/time-profiler-2.c: Disable ipa-vrp. * gcc.dg/tree-ssa/pr110269.c: Disable ipa-vrp. * gcc.dg/tree-ssa/pr20701.c: Disable ipa-vrp. * gcc.dg/tree-ssa/vrp05.c: Disable ipa-vrp. * gcc.dg/tree-ssa/return-value-range-1.c: New test.
Diffstat (limited to 'gcc/gimple-range-fold.cc')
-rw-r--r--gcc/gimple-range-fold.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 6e9530c..998b760 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -44,6 +44,11 @@ along with GCC; see the file COPYING3. If not see
#include "value-query.h"
#include "gimple-range-op.h"
#include "gimple-range.h"
+#include "cgraph.h"
+#include "alloc-pool.h"
+#include "symbol-summary.h"
+#include "ipa-utils.h"
+#include "ipa-prop.h"
// Construct a fur_source, and set the m_query field.
fur_source::fur_source (range_query *q)
@@ -1013,6 +1018,25 @@ fold_using_range::range_of_call (vrange &r, gcall *call, fur_source &)
else
r.set_varying (type);
+ tree callee = gimple_call_fndecl (call);
+ if (callee
+ && useless_type_conversion_p (TREE_TYPE (TREE_TYPE (callee)), type))
+ {
+ Value_Range val;
+ if (ipa_return_value_range (val, callee))
+ {
+ r.intersect (val);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Using return value range of ");
+ print_generic_expr (dump_file, callee, TDF_SLIM);
+ fprintf (dump_file, ": ");
+ val.dump (dump_file);
+ fprintf (dump_file, "\n");
+ }
+ }
+ }
+
// If there is an LHS, intersect that with what is known.
if (lhs)
{