--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-dse1-details" } */
+
+extern void foo(void);
+static int a, *c, g, **j;
+int b;
+static void e() {
+ int k, *l[5] = {&k, &k, &k, &k, &k};
+ while (g) {
+ j = &l[0];
+ b++;
+ }
+}
+static void d(int m) {
+ int **h[30] = {&c}, ***i[1] = {&h[3]};
+ if (m)
+ foo();
+ e();
+}
+int main() {
+ d(a);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead store" 8 "dse1" } } */
if only clobber statements influenced the classification result.
Returns the classification. */
-dse_store_status
+static dse_store_status
dse_classify_store (ao_ref *ref, gimple *stmt,
bool byte_tracking_enabled, sbitmap live_bytes,
- bool *by_clobber_p, tree stop_at_vuse)
+ bool *by_clobber_p, tree stop_at_vuse, int &cnt,
+ bitmap visited)
{
gimple *temp;
- int cnt = 0;
- auto_bitmap visited;
std::unique_ptr<data_reference, void(*)(data_reference_p)>
dra (nullptr, free_data_ref);
/* If all defs kill the ref we are done. */
if (defs.is_empty ())
return DSE_STORE_DEAD;
+ /* If more than one def survives we have to analyze multiple
+ paths. We can handle this by recursing, sharing 'visited'
+ to avoid redundant work and limiting it by shared 'cnt'.
+ For now do not bother with byte-tracking in this case. */
+ while (defs.length () > 1)
+ {
+ if (dse_classify_store (ref, defs.last (), false, NULL,
+ by_clobber_p, stop_at_vuse, cnt,
+ visited) != DSE_STORE_DEAD)
+ break;
+ byte_tracking_enabled = false;
+ defs.pop ();
+ }
/* If more than one def survives fail. */
if (defs.length () > 1)
{
while (1);
}
+dse_store_status
+dse_classify_store (ao_ref *ref, gimple *stmt,
+ bool byte_tracking_enabled, sbitmap live_bytes,
+ bool *by_clobber_p, tree stop_at_vuse)
+{
+ int cnt = 0;
+ auto_bitmap visited;
+ return dse_classify_store (ref, stmt, byte_tracking_enabled, live_bytes,
+ by_clobber_p, stop_at_vuse, cnt, visited);
+}
+
/* Delete a dead call at GSI, which is mem* call of some kind. */
static void