On Wed, 16 May 2018, Richard Biener wrote: > On Tue, 15 May 2018, Richard Biener wrote: > > > On Tue, 15 May 2018, Richard Biener wrote: > > > > > On Tue, 15 May 2018, Richard Biener wrote: > > > > > > > On Tue, 15 May 2018, Richard Biener wrote: > > > > > > > > > On Tue, 15 May 2018, Richard Biener wrote: > > > > > > > > > > > On Mon, 14 May 2018, Kugan Vivekanandarajah wrote: > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > Attached patch handles PR63185 when we reach PHI with temp != > > > > > > > NULLL. > > > > > > > We could see the PHI and if there isn't any uses for PHI that is > > > > > > > interesting, we could ignore that ? > > > > > > > > > > > > > > Bootstrapped and regression tested on x86_64-linux-gnu. > > > > > > > Is this OK? > > > > > > > > > > > > No, as Jeff said we can't do it this way. > > > > > > > > > > > > If we end up with multiple VDEFs in the walk of defvar immediate > > > > > > uses we know we are dealing with a CFG fork. We can't really > > > > > > ignore any of the paths but we have to > > > > > > > > > > > > a) find the merge point (and the associated VDEF) > > > > > > b) verify for each each chain of VDEFs with associated VUSEs > > > > > > up to that merge VDEF that we have no uses of the to classify > > > > > > store and collect (partial) kills > > > > > > c) intersect kill info and continue walking from the merge point > > > > > > > > > > > > in b) there's the optional possibility to find sinking opportunities > > > > > > in case we have kills on some paths but uses on others. This is why > > > > > > DSE should be really merged with (store) sinking. > > > > > > > > > > > > So if we want to enhance DSEs handling of branches then we need > > > > > > to refactor the simple dse_classify_store function. Let me take > > > > > > an attempt at this today. > > > > > > > > > > First (baby) step is the following - it arranges to collect the > > > > > defs we need to continue walking from and implements trivial > > > > > reduction by stopping at (full) kills. This allows us to handle > > > > > the new testcase (which was already handled in the very late DSE > > > > > pass with the help of sinking the store). > > > > > > > > > > I took the opportunity to kill the use_stmt parameter of > > > > > dse_classify_store as the only user is only looking for whether > > > > > the kills were all clobbers which I added a new parameter for. > > > > > > > > > > I didn't adjust the byte-tracking case fully (I'm not fully > > > > > understanding > > > > > the code in the case of a use and I'm not sure whether it's worth > > > > > doing the def reduction with byte-tracking). > > > > > > > > > > Your testcase can be handled by reducing the PHI and the call def > > > > > by seeing that the only use of a candidate def is another def > > > > > we have already processed. Not sure if worth special-casing though, > > > > > I'd rather have a go at "recursing". That will be the next > > > > > patch. > > > > > > > > > > Bootstrap & regtest running on x86_64-unknown-linux-gnu. > > > > > > > > Applied. > > > > > > > > Another intermediate one below, fixing the byte-tracking for > > > > stmt with uses. This also re-does the PHI handling by simply > > > > avoiding recursion by means of a visited bitmap and stopping > > > > at the DSE classify stmt when re-visiting it instead of failing. > > > > This covers Pratamesh loop case for which I added ssa-dse-33.c. > > > > For the do-while loop this still runs into the inability to > > > > handle two defs to walk from. > > > > > > > > Bootstrap & regtest running on x86_64-unknown-linux-gnu. > > > > > > Ok, loop handling doesn't work in general since we run into the > > > issue that SSA form across the backedge is not representing the > > > same values. Consider > > > > > > <bb 3> > > > # .MEM_22 = PHI <.MEM_12(D)(2), .MEM_13(4)> > > > # n_20 = PHI <0(2), n_7(4)> > > > # .MEM_13 = VDEF <.MEM_22> > > > bytes[n_20] = _4; > > > if (n_20 > 7) > > > goto <bb 5>; > > > > > > <bb 4> > > > n_7 = n_20 + 1; > > > # .MEM_15 = VDEF <.MEM_13> > > > bytes[n_20] = _5; > > > goto <bb 3>; > > > > > > then when classifying the store in bb4, visiting the PHI node > > > gets us to the store in bb3 which appears to be killing. > > > > > > if (gimple_code (temp) == GIMPLE_PHI) > > > - defvar = PHI_RESULT (temp); > > > + { > > > + /* If we visit this PHI by following a backedge then reset > > > + any info in ref that may refer to SSA names which we'd need > > > + to PHI translate. */ > > > + if (gimple_bb (temp) == gimple_bb (stmt) > > > + || dominated_by_p (CDI_DOMINATORS, gimple_bb (stmt), > > > + gimple_bb (temp))) > > > + /* ??? ref->ref may not refer to SSA names or it may only > > > + refer to SSA names that are invariant with respect to the > > > + loop represented by this PHI node. */ > > > + ref->ref = NULL_TREE; > > > + defvar = PHI_RESULT (temp); > > > + bitmap_set_bit (visited, SSA_NAME_VERSION (defvar)); > > > + } > > > > > > should be a workable solution for that. I'm checking that, but > > > eventually you can think of other things that might prevent us from > > > handling backedges. Note the current code tries to allow > > > looking across loops but not handle backedges of loops the > > > original stmt belongs to. > > > > Just to mention before I leave for the day I think I've identified > > a latent issue where I just fail to produce a testcase right now > > which is that non-return exits from a function are not reliably > > visited given they do not all have virtual operands, like > > for example resx. Thus consider > > > > void foo (int *p, int x) > > { > > *p = 0; > > if (x) > > resx; > > *p = 1; > > return; > > } > > > > where we will never visit any stmts on the resx path and thus think > > the *p = 0 store is dead (all with current trunk of course). > > > > Will continue to dig tomorrow. > > PR85803. > > I am currently re-testing the following on x86_64-unknown-linux-gnu > with --param dse-max-alias-queries-per-store=100000 in BOOT_CFLAGS. > > I'll refrain from doing the separate-walks-for-each-def thing > but will try to fix PR85757 by pattern matching the > def-has-single-virtual-use-that-is-another-def-in-the-vector case > in which case we can remove it from further processing.
After committing I am now testing that fix for PR85757 on x86_64-unknown-linux-gnu. Richard. 2018-05-16 Richard Biener <rguent...@suse.de> PR tree-optimization/85757 * tree-ssa-dse.c (dse_classify_store): Record a PHI def and remove defs that only feed that PHI from further processing. * gcc.dg/tree-ssa/ssa-dse-34.c: New testcase. >From bf8054a966485ba32b1b25ab287312eaf4b763d8 Mon Sep 17 00:00:00 2001 From: Richard Guenther <rguent...@suse.de> Date: Wed, 16 May 2018 13:50:18 +0200 Subject: [PATCH 3/4] dse#3 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-34.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-34.c new file mode 100644 index 00000000000..3016dfecd38 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-34.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-dse1-details" } */ + +void f(int n, char *p0, char *p1, char *p2, char *o) +{ + int t0, t1; + __builtin_memcpy(&t0, p0, 1); + __builtin_memcpy(&t1, p1, 1); + if (n==3) + __builtin_memcpy(o+2, p2, 1); + __builtin_memcpy(o+0, &t0, 1); + __builtin_memcpy(o+1, &t1, 1); +} + +/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1" } } */ diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index 32a25b9eb1e..589cfef5df5 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -577,6 +577,7 @@ dse_classify_store (ao_ref *ref, gimple *stmt, else defvar = gimple_vdef (temp); auto_vec<gimple *, 10> defs; + gimple *phi_def = NULL; FOR_EACH_IMM_USE_STMT (use_stmt, ui, defvar) { /* Limit stmt walking. */ @@ -600,7 +601,10 @@ dse_classify_store (ao_ref *ref, gimple *stmt, processing. */ if (!bitmap_bit_p (visited, SSA_NAME_VERSION (PHI_RESULT (use_stmt)))) - defs.safe_push (use_stmt); + { + defs.safe_push (use_stmt); + phi_def = use_stmt; + } } /* If the statement is a use the store is not dead. */ else if (ref_maybe_used_by_stmt_p (use_stmt, ref)) @@ -657,15 +661,31 @@ dse_classify_store (ao_ref *ref, gimple *stmt, return DSE_STORE_DEAD; } - /* Process defs and remove paths starting with a kill from further - processing. */ + /* Process defs and remove those we need not process further. */ for (unsigned i = 0; i < defs.length (); ++i) - if (stmt_kills_ref_p (defs[i], ref)) - { - if (by_clobber_p && !gimple_clobber_p (defs[i])) - *by_clobber_p = false; + { + gimple *def = defs[i]; + gimple *use_stmt; + use_operand_p use_p; + /* If the path to check starts with a kill we do not need to + process it further. + ??? With byte tracking we need only kill the bytes currently + live. */ + if (stmt_kills_ref_p (def, ref)) + { + if (by_clobber_p && !gimple_clobber_p (def)) + *by_clobber_p = false; + defs.unordered_remove (i); + } + /* In addition to kills we can remove defs whose only use + is another def in defs. That can only ever be PHIs of which + we track a single for simplicity reasons (we fail for multiple + PHIs anyways). */ + else if (gimple_code (def) != GIMPLE_PHI + && single_imm_use (gimple_vdef (def), &use_p, &use_stmt) + && use_stmt == phi_def) defs.unordered_remove (i); - } + } /* If all defs kill the ref we are done. */ if (defs.is_empty ()) -- 2.12.3