aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2022-10-05 10:42:07 -0400
committerAndrew MacLeod <amacleod@redhat.com>2022-10-13 11:28:47 -0400
commit6cc3394507a2303a18891d34222c53f679256c37 (patch)
treea5156d31cf1535030a778754cf13acefd261996f
parentd75be7e4343f049176546aa9517d570e5eb67954 (diff)
downloadgcc-6cc3394507a2303a18891d34222c53f679256c37.zip
gcc-6cc3394507a2303a18891d34222c53f679256c37.tar.gz
gcc-6cc3394507a2303a18891d34222c53f679256c37.tar.bz2
propagate partial equivs in the cache.
Adjust on-entry cache propagation to look for and propagate both full and partial equivalences. gcc/ PR tree-optimization/102540 PR tree-optimization/102872 * gimple-range-cache.cc (ranger_cache::fill_block_cache): Handle partial equivs. (ranger_cache::range_from_dom): Cleanup dump output. gcc/testsuite/ * gcc.dg/pr102540.c: New. * gcc.dg/pr102872.c: New.
-rw-r--r--gcc/gimple-range-cache.cc37
-rw-r--r--gcc/testsuite/gcc.dg/pr102540.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr102872.c16
3 files changed, 66 insertions, 6 deletions
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 8c80ba6..0b9aa36 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -1189,8 +1189,9 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
{
edge_iterator ei;
edge e;
- Value_Range block_result (TREE_TYPE (name));
- Value_Range undefined (TREE_TYPE (name));
+ tree type = TREE_TYPE (name);
+ Value_Range block_result (type);
+ Value_Range undefined (type);
// At this point we shouldn't be looking at the def, entry or exit block.
gcc_checking_assert (bb != def_bb && bb != ENTRY_BLOCK_PTR_FOR_FN (cfun) &&
@@ -1221,10 +1222,16 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
if (m_oracle)
{
tree equiv_name;
- FOR_EACH_EQUIVALENCE (m_oracle, bb, name, equiv_name)
+ relation_kind rel;
+ int prec = TYPE_PRECISION (type);
+ FOR_EACH_PARTIAL_AND_FULL_EQUIV (m_oracle, bb, name, equiv_name, rel)
{
basic_block equiv_bb = gimple_bb (SSA_NAME_DEF_STMT (equiv_name));
+ // Ignore partial equivs that are smaller than this object.
+ if (rel != VREL_EQ && prec > pe_to_bits (rel))
+ continue;
+
// Check if the equiv has any ranges calculated.
if (!m_gori.has_edge_range_p (equiv_name))
continue;
@@ -1234,16 +1241,32 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb)
(equiv_bb && !dominated_by_p (CDI_DOMINATORS, bb, equiv_bb)))
continue;
+ if (DEBUG_RANGE_CACHE)
+ {
+ if (rel == VREL_EQ)
+ fprintf (dump_file, "Checking Equivalence (");
+ else
+ fprintf (dump_file, "Checking Partial equiv (");
+ print_relation (dump_file, rel);
+ fprintf (dump_file, ") ");
+ print_generic_expr (dump_file, equiv_name, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
Value_Range equiv_range (TREE_TYPE (equiv_name));
if (range_from_dom (equiv_range, equiv_name, bb, RFD_READ_ONLY))
{
+ if (rel != VREL_EQ)
+ range_cast (equiv_range, type);
if (block_result.intersect (equiv_range))
{
if (DEBUG_RANGE_CACHE)
{
- fprintf (dump_file, "Equivalence update! : ");
+ if (rel == VREL_EQ)
+ fprintf (dump_file, "Equivalence update! : ");
+ else
+ fprintf (dump_file, "Partial equiv update! : ");
print_generic_expr (dump_file, equiv_name, TDF_SLIM);
- fprintf (dump_file, "had range : ");
+ fprintf (dump_file, " has range : ");
equiv_range.dump (dump_file);
fprintf (dump_file, " refining range to :");
block_result.dump (dump_file);
@@ -1458,7 +1481,9 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb,
if (DEBUG_RANGE_CACHE)
{
- fprintf (dump_file, "CACHE: BB %d DOM query, found ", start_bb->index);
+ fprintf (dump_file, "CACHE: BB %d DOM query for ", start_bb->index);
+ print_generic_expr (dump_file, name, TDF_SLIM);
+ fprintf (dump_file, ", found ");
r.dump (dump_file);
if (bb)
fprintf (dump_file, " at BB%d\n", bb->index);
diff --git a/gcc/testsuite/gcc.dg/pr102540.c b/gcc/testsuite/gcc.dg/pr102540.c
new file mode 100644
index 0000000..c12f8fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr102540.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-evrp" } */
+
+
+void kill();
+
+static long a;
+static unsigned b;
+int test1 () {
+ long c, e;
+ c = b = a;
+ e = c ? 2 / (c + 1) : 0;
+ if (e && !b)
+ kill ();
+ a = 0;
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/pr102872.c b/gcc/testsuite/gcc.dg/pr102872.c
new file mode 100644
index 0000000..971bb03
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr102872.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void foo(void);
+
+static int a, b;
+int main() {
+ for (; a; ++a) {
+ unsigned short d = a;
+ if (!(b | d) && d)
+ foo();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "foo" "evrp" } } */
+