]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/69196 (code size regression with jump threading at -O2)
authorJeff Law <law@redhat.com>
Tue, 1 Mar 2016 23:12:10 +0000 (16:12 -0700)
committerJeff Law <law@gcc.gnu.org>
Tue, 1 Mar 2016 23:12:10 +0000 (16:12 -0700)
PR tree-optimization/69196
* tree-ssa-threadbackward.c (fsm_find_control_statement_thread_paths):
Appropriately clamp the number of statements to copy when the
thread path does not traverse a loop backedge.

PR tree-optimization/69196
* gcc.dg/tree-ssa/pr69196.c: New test.

From-SVN: r233870

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c [new file with mode: 0644]
gcc/tree-ssa-threadbackward.c

index 982a7c05284ae99d822f280b9f6bc1d2d8816ccf..88f0806ac52e17be70a55e2505b2d17c2ca7d28c 100644 (file)
@@ -6,6 +6,11 @@
 
 2016-03-01  Jeff Law  <law@redhat.com>
 
+       PR tree-optimization/69196
+       * tree-ssa-threadbackward.c (fsm_find_control_statement_thread_paths):
+       Appropriately clamp the number of statements to copy when the
+       thread path does not traverse a loop backedge.
+
        PR tree-optimization/69196
        * tree-ssa-threadbackward.c (fsm_find_control_statement_thread_paths):
        Do count some PHIs in the thread path against the insn count.  Decrease
index bdc4b1166e6d16882b86e0d29a17e1ce24c439e4..1e6a8500c5120e8819d1f2d6f58d906c048e99eb 100644 (file)
@@ -4,6 +4,9 @@
 
 2016-03-01  Jeff Law  <law@redhat.com>
 
+       PR tree-optimization/69196
+       * gcc.dg/tree-ssa/pr69196.c: New test.
+
        PR tree-optimization/69196
        * gcc.dg/tree-ssa/vrp46.c: Twiddle threading params to keep it from
        duplicating code and spoiling the expected output.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr69196-1.c
new file mode 100644 (file)
index 0000000..11c7cf5
--- /dev/null
@@ -0,0 +1,138 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
+
+/* { dg-final { scan-tree-dump "FSM did not thread around loop and would copy too many statements" "vrp1" } } */
+
+
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+extern void rtems_putc(char c);
+
+void vprintk(
+  const char *fmt,
+  va_list ap
+)
+{
+  for (; *fmt != '\0'; fmt++) {
+    unsigned base = 0;
+    unsigned width = 0;
+    enum {
+      LFLAG_INT,
+      LFLAG_LONG,
+      LFLAG_LONG_LONG
+    } lflag = LFLAG_INT;
+    _Bool minus = 0;
+    _Bool sign = 0;
+    char lead = ' ';
+    char c = *fmt;
+    long long num;
+
+    if (c != '%') {
+      rtems_putc(c);
+      continue;
+    }
+
+    ++fmt; c = *fmt;
+
+    if (c == '0') {
+      lead = '0';
+      ++fmt; c = *fmt;
+    }
+
+    if (c == '-') {
+      minus = 1;
+      ++fmt; c = *fmt;
+    }
+
+    while (c >= '0' && c <= '9' ) {
+      width *= 10;
+      width += ((unsigned) c - '0');
+      ++fmt; c = *fmt;
+    }
+
+    if (c == 'l') {
+      lflag = LFLAG_LONG;
+      ++fmt; c = *fmt;
+
+      if (c == 'l') {
+        lflag = LFLAG_LONG_LONG;
+        ++fmt; c = *fmt;
+      }
+    }
+
+    if ( c == 'c' ) {
+
+      char chr = (char) __builtin_va_arg(ap,int);
+      rtems_putc(chr);
+      continue;
+    }
+
+    if ( c == 's' ) {
+      unsigned i, len;
+      char *s, *str;
+
+      str = __builtin_va_arg(ap,char *);
+
+      if ( str == ((void *)0) ) {
+        str = "";
+      }
+
+
+      for ( len=0, s=str ; *s ; len++, s++ )
+        ;
+
+
+      if ( !minus )
+        for ( i=len ; i<width ; i++ )
+          rtems_putc(' ');
+
+
+      if (width == 0) {
+          width = len;
+      }
+
+
+      for ( i=0 ; i<width && *str ; str++ )
+        rtems_putc(*str);
+
+
+      if ( minus )
+        for ( i=len ; i<width ; i++ )
+          rtems_putc(' ');
+
+      continue;
+    }
+
+
+    if ( c == 'o' || c == 'O' ) {
+      base = 8; sign = 0;
+    } else if ( c == 'i' || c == 'I' ||
+                c == 'd' || c == 'D' ) {
+      base = 10; sign = 1;
+    } else if ( c == 'u' || c == 'U' ) {
+      base = 10; sign = 0;
+    } else if ( c == 'x' || c == 'X' ) {
+      base = 16; sign = 0;
+    } else if ( c == 'p' ) {
+      base = 16; sign = 0; lflag = LFLAG_LONG;
+    } else {
+      rtems_putc(c);
+      continue;
+    }
+
+    switch (lflag) {
+      case LFLAG_LONG:
+        num = sign ? (long long) __builtin_va_arg(ap,long)
+          : (long long) __builtin_va_arg(ap,unsigned long);
+        break;
+      case LFLAG_LONG_LONG:
+        num = __builtin_va_arg(ap,long long);
+        break;
+      case LFLAG_INT:
+      default:
+        num = sign ? (long long) __builtin_va_arg(ap,int)
+          : (long long) __builtin_va_arg(ap,unsigned int);
+        break;
+    }
+  }
+}
index 3028504aefa2c8e9233038f67738335ec26e8ebf..747296bff36415dd02b8bf1cb07e3ce184ffb08b 100644 (file)
@@ -429,6 +429,26 @@ fsm_find_control_statement_thread_paths (tree name,
              continue;
            }
 
+
+         /* If this path does not thread through the loop latch, then we are
+            using the FSM threader to find old style jump threads.  This
+            is good, except the FSM threader does not re-use an existing
+            threading path to reduce code duplication.
+
+            So for that case, drastically reduce the number of statements
+            we are allowed to copy.  */
+         if (!threaded_through_latch
+             && (n_insns * PARAM_VALUE (PARAM_FSM_SCALE_PATH_STMTS)
+                 >= PARAM_VALUE (PARAM_MAX_JUMP_THREAD_DUPLICATION_STMTS)))
+           {
+             if (dump_file && (dump_flags & TDF_DETAILS))
+               fprintf (dump_file,
+                        "FSM did not thread around loop and would copy too "
+                        "many statements.\n");
+             path->pop ();
+             continue;
+           }
+
          /* When there is a multi-way branch on the path, then threading can
             explode the CFG due to duplicating the edges for that multi-way
             branch.  So like above, only allow a multi-way branch on the path