* Avoid redundant entries in modref's access lists
@ 2021-08-23 15:58 Jan Hubicka
0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2021-08-23 15:58 UTC (permalink / raw)
To: gcc-patches
Hi,
in PR101296 Richard noticed that modref is giving up on analysis in milc by
hitting --param=modref-max-accesses limit. While cleaning up original modref
patch I removed code that tried to do smart things while merging accesses
because it had bugs and wanted to reimplement it later which I later forgot.
This patch adds logic that avoids adding access and its subaccess to the list
which is just waste of memory and compile time. Incrementally I will add logic
merging the ranges.
Bootstrapped/regtested x86_64-linux, comitted. Current cc1plus stats are
Alias oracle query stats:
refs_may_alias_p: 72546769 disambiguations, 82870545 queries
ref_maybe_used_by_call_p: 497089 disambiguations, 73535250 queries
call_may_clobber_ref_p: 259485 disambiguations, 263258 queries
nonoverlapping_component_refs_p: 0 disambiguations, 38042 queries
nonoverlapping_refs_since_match_p: 21125 disambiguations, 65780 must overlaps, 87810 queries
aliasing_component_refs_p: 63132 disambiguations, 2186210 queries
TBAA oracle: 26058958 disambiguations 61665515 queries
12157742 are in alias set 0
11350680 queries asked about the same object
144 queries asked about the same alias set
0 access volatile
10552147 are dependent in the DAG
1545844 are aritificially in conflict with void *
Modref stats:
modref use: 24018 disambiguations, 713486 queries
modref clobber: 1400403 disambiguations, 17119339 queries
3473726 tbaa queries (0.202912 per modref query)
535259 base compares (0.031266 per modref query)
PTA query stats:
pt_solution_includes: 12436890 disambiguations, 20321783 queries
pt_solutions_intersect: 1390457 disambiguations, 14654884 queries
This is pretty much the same as last time I measured. This is bit of expected
since we do not hit the limit on GCC very often. It is 43 times during cc1plus
LTO build (release checking), however code that does a lot of array/fields
initialization may hit the limit easily.
gcc/ChangeLog:
2021-08-23 Jan Hubicka <hubicka@ucw.cz>
* ipa-modref-tree.h (modref_access_node::range_info_useful_p):
Improve range compare.
(modref_access_node::contains): New member function.
(modref_access_node::search): Remove.
(modref_access_node::insert): Be smarter about subaccesses.
gcc/testsuite/ChangeLog:
2021-08-23 Jan Hubicka <hubicka@ucw.cz>
* gcc.dg/tree-ssa/modref-7.c: New test.
diff --git a/gcc/ipa-modref-tree.h b/gcc/ipa-modref-tree.h
index d36c28c0470..2e26b75e21f 100644
--- a/gcc/ipa-modref-tree.h
+++ b/gcc/ipa-modref-tree.h
@@ -66,7 +66,10 @@ struct GTY(()) modref_access_node
/* Return true if range info is useful. */
bool range_info_useful_p () const
{
- return parm_index != -1 && parm_offset_known;
+ return parm_index != -1 && parm_offset_known
+ && (known_size_p (size)
+ || known_size_p (max_size)
+ || known_ge (offset, 0));
}
/* Return true if both accesses are the same. */
bool operator == (modref_access_node &a) const
@@ -88,6 +91,35 @@ struct GTY(()) modref_access_node
return false;
return true;
}
+ /* Return true A is a subaccess. */
+ bool contains (modref_access_node &a) const
+ {
+ if (parm_index != a.parm_index)
+ return false;
+ if (parm_index >= 0)
+ {
+ if (parm_offset_known
+ && (!a.parm_offset_known
+ || !known_eq (parm_offset, a.parm_offset)))
+ return false;
+ }
+ if (range_info_useful_p ())
+ {
+ if (!a.range_info_useful_p ())
+ return false;
+ /* Sizes of stores are used to check that object is big enough
+ to fit the store, so smaller or unknown sotre is more general
+ than large store. */
+ if (known_size_p (size)
+ && !known_le (size, a.size))
+ return false;
+ if (known_size_p (max_size))
+ return known_subrange_p (a.offset, a.max_size, offset, max_size);
+ else
+ return known_le (offset, a.offset);
+ }
+ return true;
+ }
};
/* Access node specifying no useful info. */
@@ -107,17 +139,6 @@ struct GTY((user)) modref_ref_node
accesses (NULL)
{}
- /* Search REF; return NULL if failed. */
- modref_access_node *search (modref_access_node access)
- {
- size_t i;
- modref_access_node *a;
- FOR_EACH_VEC_SAFE_ELT (accesses, i, a)
- if (*a == access)
- return a;
- return NULL;
- }
-
/* Collapse the tree. */
void collapse ()
{
@@ -136,16 +157,36 @@ struct GTY((user)) modref_ref_node
return false;
/* Otherwise, insert a node for the ref of the access under the base. */
- modref_access_node *access_node = search (a);
- if (access_node)
- return false;
+ size_t i;
+ modref_access_node *a2;
+
+ if (!a.useful_p ())
+ {
+ if (!every_access)
+ {
+ collapse ();
+ return true;
+ }
+ return false;
+ }
+
+ FOR_EACH_VEC_SAFE_ELT (accesses, i, a2)
+ {
+ if (a2->contains (a))
+ return false;
+ if (a.contains (*a2))
+ {
+ *a2 = a;
+ return true;
+ }
+ gcc_checking_assert (!(a == *a2));
+ }
/* If this base->ref pair has too many accesses stored, we will clear
all accesses and bail out. */
- if ((accesses && accesses->length () >= max_accesses)
- || !a.useful_p ())
+ if (accesses && accesses->length () >= max_accesses)
{
- if (dump_file && a.useful_p ())
+ if (dump_file)
fprintf (dump_file,
"--param param=modref-max-accesses limit reached\n");
collapse ();
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c
new file mode 100644
index 00000000000..53ffa1c394c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-7.c
@@ -0,0 +1,13 @@
+/* { dg-options "-O2 --param modref-max-accesses=1 -fdump-tree-modref1" } */
+/* { dg-do compile } */
+struct a {
+ int array[10];
+ int tail;
+};
+int test(struct a *a, int p)
+{
+ a->array[p] = 0;
+ a->array[0] = 1;
+}
+/* All three accesses combine to one bigger access. */
+/* { dg-final { scan-tree-dump-not "param=modref-max-accesses" "modref1" } } */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-08-23 15:58 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-23 15:58 Avoid redundant entries in modref's access lists Jan Hubicka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).