From 78cf0a232ee4314a9d668aab9b4b54f86b308111 Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Thu, 27 Aug 2015 17:11:21 -0500 Subject: port revision 219584 from linaro/gcc-4_9-branch gcc/ 2015-01-14 Yvan Roux Backport from trunk r218451. 2014-12-06 James Greenhalgh Sebastian Pop Brian Rzycki PR tree-optimization/54742 * params.def (max-fsm-thread-path-insns, max-fsm-thread-length, max-fsm-thread-paths): New. * doc/invoke.texi (max-fsm-thread-path-insns, max-fsm-thread-length, max-fsm-thread-paths): Documented. * tree-cfg.c (split_edge_bb_loc): Export. * tree-cfg.h (split_edge_bb_loc): Declared extern. * tree-ssa-threadedge.c (simplify_control_stmt_condition): Restore the original value of cond when simplification fails. (fsm_find_thread_path): New. (fsm_find_control_statement_thread_paths): New. (thread_through_normal_block): Call find_control_statement_thread_paths. * tree-ssa-threadupdate.c (dump_jump_thread_path): Pretty print EDGE_FSM_THREAD. (verify_seme): New. (duplicate_seme_region): New. (thread_through_all_blocks): Generate code for EDGE_FSM_THREAD edges calling duplicate_seme_region. * tree-ssa-threadupdate.h (jump_thread_edge_type): Add EDGE_FSM_THREAD. gcc/testsuite/ 2015-01-14 Yvan Roux Backport from trunk r218451. 2014-12-06 James Greenhalgh Sebastian Pop Brian Rzycki PR tree-optimization/54742 * gcc.dg/tree-ssa/ssa-dom-thread-6.c: New test. * gcc.dg/tree-ssa/ssa-dom-thread-7.c: New test. --- .../testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c | 43 +++++++ .../testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c | 127 +++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c create mode 100644 gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c (limited to 'gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa') diff --git a/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c new file mode 100644 index 000000000..bb34a7432 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom1-details" } */ +/* { dg-final { scan-tree-dump-times "FSM" 6 "dom1" } } */ +/* { dg-final { cleanup-tree-dump "dom1" } } */ + +int sum0, sum1, sum2, sum3; +int foo (char *s, char **ret) +{ + int state=0; + char c; + + for (; *s && state != 4; s++) + { + c = *s; + if (c == '*') + { + s++; + break; + } + switch (state) + { + case 0: + if (c == '+') + state = 1; + else if (c != '-') + sum0+=c; + break; + case 1: + if (c == '+') + state = 2; + else if (c == '-') + state = 0; + else + sum1+=c; + break; + default: + break; + } + + } + *ret = s; + return state; +} diff --git a/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c new file mode 100644 index 000000000..21474f0b4 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -0,0 +1,127 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom1-details" } */ +/* { dg-final { scan-tree-dump-times "FSM" 19 "dom1" } } */ +/* { dg-final { cleanup-tree-dump "dom1" } } */ + +enum STATE { + S0=0, + SI, + S1, + S2, + S3, + S4, + S5, + S6 +}; + +int bar (enum STATE s); + +enum STATE foo (unsigned char **y, unsigned *c) +{ + unsigned char *x = *y; + unsigned char n; + enum STATE s = S0; + + for( ; *x && s != SI; x++ ) + { + n = *x; + if (n == 'x') + { + x++; + break; + } + switch(s) + { + case S0: + if(bar(n)) + s = S3; + else if( n == 'a' || n == 'b' ) + s = S1; + else if( n == 'c' ) + s = S4; + else + { + s = SI; + c[SI]++; + } + c[S0]++; + break; + case S1: + if(bar(n)) + { + s = S3; + c[S1]++; + } + else if( n == 'c' ) + { + s = S4; + c[S1]++; + } + else + { + s = SI; + c[S1]++; + } + break; + case S3: + if( n == 'c' ) + { + s = S4; + c[S3]++; + } + else if(!bar(n)) + { + s = SI; + c[S3]++; + } + break; + case S4: + if( n == 'E' || n == 'e' ) + { + s = S2; + c[S4]++; + } + else if(!bar(n)) + { + s = SI; + c[S4]++; + } + break; + case S2: + if( n == 'a' || n == 'b' ) + { + s = S5; + c[S2]++; + } + else + { + s = SI; + c[S2]++; + } + break; + case S5: + if(bar(n)) + { + s = S6; + c[S5]++; + } + else + { + s = SI; + c[S5]++; + } + break; + case S6: + if(!bar(n)) + { + s = SI; + c[SI]++; + } + break; + default: + break; + } + } + *y=x; + return s; +} -- cgit v1.2.3 From c39d2a2bd89ed7a9ff995f2fc1e2e693fab8ee9f Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Fri, 28 Aug 2015 15:29:57 -0500 Subject: backport patch for PR 64878: do not jump thread across more than one back-edge 2015-02-04 Sebastian Pop Brian Rzycki PR tree-optimization/64878 * tree-ssa-threadedge.c: Include tree-ssa-loop.h. (fsm_find_control_statement_thread_paths): Add parameter seen_loop_phi. Stop recursion at loop phi nodes after having visited a loop phi node. * testsuite/gcc.dg/tree-ssa/ssa-dom-thread-8.c: New. --- .../testsuite/gcc.dg/tree-ssa/ssa-dom-thread-8.c | 440 +++++++++++++++++++++ 1 file changed, 440 insertions(+) create mode 100644 gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-8.c (limited to 'gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa') diff --git a/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-8.c b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-8.c new file mode 100644 index 000000000..9be75aaf2 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-8.c @@ -0,0 +1,440 @@ +/* PR 64878 */ +/* { dg-options "-O2" } */ +/* { dg-do run } */ + +struct A { int a1; }; +struct B { char *b1; int b2; int b3; }; +struct C { char *c1; int c2; struct B *c3; }; +extern struct A *f1 (char *s); +static struct A *f2 (struct C *x); +__attribute__ ((noinline, noclone)) int f3 (struct A *x, struct A *z) { asm volatile ("" : : "g" (x), "g" (z) : "memory"); return 0; } +__attribute__ ((noinline, noclone)) void f4 (struct A *x, char *y, struct A *z) { asm volatile ("" : : "g" (x), "g" (z), "g" (y) : "memory"); } +__attribute__ ((noinline, noclone)) struct B *f5 (void) { static char b[32]; static struct B f3 = { b, 0, 32 }; return &f3; } +__attribute__ ((noinline, noclone)) int f6 (struct B *p, char *w, int z) { asm volatile ("" : : "g" (p), "g" (w), "g" (z) : "memory"); return 0; } +__attribute__ ((noinline, noclone)) void f7 (struct B *p) { asm volatile ("" : : "g" (p) : "memory"); } +__attribute__ ((noinline, noclone)) void f8 (struct B *p) { asm volatile ("" : : "g" (p) : "memory"); } +__attribute__ ((noinline, noclone)) void f9 (struct A *x) { asm volatile ("" : : "g" (x) : "memory"); } +__attribute__ ((noinline, noclone)) struct A *f10 (void) { static struct A j; asm volatile ("" : : : "memory"); return &j; } +__attribute__ ((noinline, noclone)) struct A *f11 (void) { static struct A j; asm volatile ("" : : : "memory"); return &j; } +__attribute__ ((noinline, noclone)) struct A *f12 (int b) { static struct A j; asm volatile ("" : : "g" (b) : "memory"); return &j; } +__attribute__ ((noinline, noclone)) struct A *f13 (int i) { static struct A j; asm volatile ("" : : "g" (i) : "memory"); return &j; } +__attribute__ ((noinline, noclone)) struct A *f14 (double d) { static struct A j; asm volatile ("" : : "g" (&d) : "memory"); return &j; } +__attribute__ ((noinline, noclone)) struct A *f15 (char *s) { static struct A j; asm volatile ("" : : "g" (s) : "memory"); return &j; } +char *t = "0123456789abcdef"; +char *u = "0123456789.+-e"; + +__attribute__ ((noinline, noclone)) struct A * +f1 (char *s) +{ + struct C f; + struct A *o; + f.c1 = s; + f.c2 = 0; + f.c3 = f5 (); + o = f2 (&f); + f8 (f.c3); + return o; +} + +static struct A * +f2 (struct C *x) +{ + int a, b, e = 0; + struct A *f = 0, *o; + char *g = 0; + char h = '\0'; + int i = 0, j = 0; + a = 0; + b = 1; + char c; + do + { + c = x->c1[x->c2]; + switch (a) + { + case 0: + if (c == ' ') + x->c2++; + else if (c == '/') + { + a = 4; + j = x->c2++; + } + else + a = b; + break; + case 1: + switch (c) + { + case '{': + a = 0; + b = 15; + f = f10 (); + x->c2++; + break; + case '[': + a = 0; + b = 13; + f = f11 (); + x->c2++; + break; + case 'N': + case 'n': + a = 3; + j = x->c2++; + break; + case '"': + case '\'': + h = c; + f7 (x->c3); + a = 8; + j = ++x->c2; + break; + case 'T': + case 't': + case 'F': + case 'f': + a = 11; + j = x->c2++; + break; + case '0' ... '9': + case '-': + i = 0; + a = 12; + j = x->c2++; + break; + default: + e = 1; + goto out; + } + break; + case 2: + goto out; + case 3: + if (__builtin_strncmp ("null", x->c1 + j, x->c2 - j)) + { + e = 2; + goto out; + } + if (x->c2 - j == 4) + { + f = 0; + b = 2; + a = 0; + } + else + x->c2++; + break; + case 4: + if (c == '*') + a = 5; + else if (c == '/') + a = 6; + else + { + e = 8; + goto out; + } + x->c2++; + break; + case 5: + if (c == '*') + a = 7; + x->c2++; + break; + case 6: + if (c == '\n') + a = 0; + x->c2++; + break; + case 7: + if (c == '/') + a = 0; + else + a = 5; + x->c2++; + break; + case 8: + if (c == h) + { + f6 (x->c3, x->c1 + j, x->c2 - j); + f = f15 (x->c3->b1); + b = 2; + a = 0; + } + else if (c == '\\') + { + b = 8; + a = 9; + } + x->c2++; + break; + case 9: + switch (c) + { + case '"': + case '\\': + f6 (x->c3, x->c1 + j, x->c2 - j - 1); + j = x->c2++; + a = b; + break; + case 'b': + case 'n': + case 'r': + case 't': + f6 (x->c3, x->c1 + j, x->c2 - j - 1); + if (c == 'b') + f6 (x->c3, "\b", 1); + else if (c == 'n') + f6 (x->c3, "\n", 1); + else if (c == 'r') + f6 (x->c3, "\r", 1); + else if (c == 't') + f6 (x->c3, "\t", 1); + j = ++x->c2; + a = b; + break; + case 'u': + f6 (x->c3, x->c1 + j, x->c2 - j - 1); + j = ++x->c2; + a = 10; + break; + default: + e = 7; + goto out; + } + break; + case 10: + if (__builtin_strchr (t, c)) + { + x->c2++; + if (x->c2 - j == 4) + { + unsigned char w[3]; + unsigned int s = + (((x->c1[j] <= '9') ? x->c1[j] - '0' : (x->c1[j] & 7) + 9) << 12) + + (((x->c1[j + 1] <= '9') ? x->c1[j + 1] - '0' : (x->c1[j + 1] & 7) + 9) << 8) + + (((x->c1[j + 2] <= '9') ? x->c1[j + 2] - '0' : (x->c1[j + 2] & 7) + 9) << 4) + + ((x->c1[j + 3] <= '9') ? x->c1[j + 3] - '0' : (x->c1[j + 3] & 7) + 9); + if (s < 0x80) + { + w[0] = s; + f6 (x->c3, (char *) w, 1); + } + else if (s < 0x800) + { + w[0] = 0xc0 | (s >> 6); + w[1] = 0x80 | (s & 0x3f); + f6 (x->c3, (char *) w, 2); + } + else + { + w[0] = 0x0 | (s >> 12); + w[1] = 0x80 | ((s >> 6) & 0x3f); + w[2] = 0x80 | (s & 0x3f); + f6 (x->c3, (char *) w, 3); + } + j = x->c2; + a = b; + } + } + else + { + e = 7; + goto out; + } + break; + case 11: + if (__builtin_strncmp ("true", x->c1 + j, x->c2 - j) == 0) + { + if (x->c2 - j == 4) + { + f = f12 (1); + b = 2; + a = 0; + } + else + x->c2++; + } + else if (__builtin_strncmp ("false", x->c1 + j, x->c2 - j) == 0) + { + if (x->c2 - j == 5) + { + f = f12 (0); + b = 2; + a = 0; + } + else + x->c2++; + } + else + { + e = 3; + goto out; + } + break; + case 12: + if (!c || !__builtin_strchr (u, c)) + { + if (!i) + f = f13 (0); + else + f = f14 (0.0); + b = 2; + a = 0; + } + else + { + if (c == '.' || c == 'e') + i = 1; + x->c2++; + } + break; + case 13: + if (c == ']') + { + x->c2++; + b = 2; + a = 0; + } + else + { + o = f2 (x); + if (((unsigned long) o > (unsigned long) -4000L)) + { + e = 5; + goto out; + } + f3 (f, o); + b = 14; + a = 0; + } + break; + case 14: + if (c == ']') + { + x->c2++; + b = 2; + a = 0; + } + else if (c == ',') + { + x->c2++; + b = 13; + a = 0; + } + else + { + f9 (f); + e = 5; + goto out; + } + break; + case 15: + a = 16; + j = x->c2; + break; + case 16: + if (c == '}') + { + x->c2++; + b = 2; + a = 0; + } + else if (c == '"' || c == '\'') + { + h = c; + f7 (x->c3); + a = 17; + j = ++x->c2; + } + else + { + e = 6; + goto out; + } + break; + case 17: + if (c == h) + { + f6 (x->c3, x->c1 + j, x->c2 - j); + g = __builtin_strdup (x->c3->b1); + b = 18; + a = 0; + } + else if (c == '\\') + { + b = 17; + a = 9; + } + x->c2++; + break; + case 18: + if (c == ':') + { + x->c2++; + b = 19; + a = 0; + } + else + { + e = -6; + goto out; + } + break; + case 19: + o = f2 (x); + if (((unsigned long) o > (unsigned long) -4000L)) + { + e = 6; + goto out; + } + f4 (f, g, o); + __builtin_free (g); + g = 0; + b = 20; + a = 0; + break; + case 20: + if (c == '}') + { + x->c2++; + b = 2; + a = 0; + } + else if (c == ',') + { + x->c2++; + b = 15; + a = 0; + } + else + { + e = 6; + goto out; + } + break; + } + } + while (c); + if (a != 2 && b != 2) + e = 9; +out: + __builtin_free (g); + if (e == 0) + return f; + f9 (f); + return 0; +} + +int +main () +{ + asm volatile ("" : : : "memory"); + struct A *r = f1 ("{ \"id\": null, \"blahah\": \"foobarbazbar\", \"barbar\": { \"barbarbarba\":" + "\"abcdefgh\", \"ijklmnopqr\": \"stuvwxyzabcdefghijklmnopqrstuv\", \"xyzxyz\":" + " [ \"1\" ] } }"); + if (!r) + __builtin_abort (); + return 0; +} -- cgit v1.2.3 From fa0139c9969e54f37f0add025af87cc21b46ffcb Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Fri, 28 Aug 2015 15:36:58 -0500 Subject: backport patch to fix PR65048 PR tree-optimization/65048 * tree-ssa-threadupdate.c (valid_jump_thread_path): New. (thread_through_all_blocks): Call valid_jump_thread_path. Remove invalid FSM jump-thread paths. PR tree-optimization/65048 * gcc.dg/tree-ssa/ssa-dom-thread-9.c: New. --- .../testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c (limited to 'gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa') diff --git a/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c new file mode 100644 index 000000000..6be42038b --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-9.c @@ -0,0 +1,50 @@ +/* PR 65048 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int a, b, c, d; +void fn (void); + +int +foo (x) +{ + switch (x) + { + case 'A': + return 'T'; + case 'U': + return 'A'; + } +} + +void +bar (int x, int y) +{ + switch (c) + { + case 'U': + switch (x) + { + default: + fn (); + case 'G': + switch (y) + { + case 'A': + d = 7; + } + } + } +} + +void +baz (void) +{ + while (1) + { + a = foo (); + b = foo (); + bar (a, b); + } +} + -- cgit v1.2.3 From aa65e2d1e40e4dd0d936a275683c4aadfe8aa20f Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Fri, 28 Aug 2015 15:43:11 -0500 Subject: backport patch to fix PR65177 PR tree-optimization/65177 * tree-ssa-threadupdate.c (verify_seme): Renamed verify_jump_thread. (bb_in_bbs): New. (duplicate_seme_region): Renamed duplicate_thread_path. Redirect all edges not adjacent on the path to the original code. * gcc.dg/tree-ssa/ssa-dom-thread-10.c: New. --- .../testsuite/gcc.dg/tree-ssa/ssa-dom-thread-10.c | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-10.c (limited to 'gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa') diff --git a/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-10.c b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-10.c new file mode 100644 index 000000000..4acf580e1 --- /dev/null +++ b/gcc-4.9/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-10.c @@ -0,0 +1,24 @@ +/* PR 65177 */ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +typedef struct p7_profile_s {} P7_PROFILE; +enum p7t_statetype_e { + p7T_S = 4, p7T_N = 5, p7T_E = 7, p7T_C = 8, p7T_J = 10, }; +typedef struct p7_trace_s {} P7_TRACE; +typedef struct p7_gmx_s { + int L; +} P7_GMX; +static inline int select_c(const P7_PROFILE *gm, const P7_GMX *pp, const P7_GMX *gx, int i) { + float path[2]; + return ((path[0] > path[1]) ? p7T_C : p7T_E); +} +void p7_GOATrace(const P7_PROFILE *gm, const P7_GMX *pp, const P7_GMX *gx, P7_TRACE *tr) { + int i = gx->L; + int sprv, scur; + while (sprv != p7T_S) { + switch (sprv) { case p7T_C: scur = select_c(gm, pp, gx, i); break; } + if ( (scur == p7T_N || scur == p7T_J || scur == p7T_C) && scur == sprv) i--; + sprv = scur; + } +} -- cgit v1.2.3