diff mbox

[gomp4] Re: [PATCH, 4/16] Implement -foffload-alias

Message ID 877fkdp9jv.fsf@kepler.schwinge.homeip.net
State New
Headers show

Commit Message

Thomas Schwinge Dec. 17, 2015, 12:02 p.m. UTC
Hi!

On Wed, 16 Dec 2015 15:42:55 +0100, Tom de Vries <Tom_deVries@mentor.com> wrote:
> On 16/12/15 14:16, Richard Biener wrote:
> > On Mon, 14 Dec 2015, Tom de Vries wrote:
> >
> >> On 14/12/15 14:26, Richard Biener wrote:
> >>> On Sun, 13 Dec 2015, Tom de Vries wrote:
> >>>> This patch:
> >>>> - moves the kernels pass group to the first position in the pass list
> >>>>     after ealias where we're back in ipa mode
> >>>> - inserts an new ipa pass to contain the gimple pass group called
> >>>>     pass_oacc_ipa
> >>>> - inserts a version of ipa-pta before the pass group.

> Committed as attached [...]

> --- a/gcc/passes.def
> +++ b/gcc/passes.def
> @@ -88,24 +88,7 @@ along with GCC; see the file COPYING3.  If not see
>  	  /* pass_build_ealias is a dummy pass that ensures that we
>  	     execute TODO_rebuild_alias at this point.  */
>  	  NEXT_PASS (pass_build_ealias);
> -	  /* Pass group that runs when the function is an offloaded function
> -	     containing oacc kernels loops.  Part 1.  */
> -	  NEXT_PASS (pass_oacc_kernels);
> -	  PUSH_INSERT_PASSES_WITHIN (pass_oacc_kernels)
> -	      NEXT_PASS (pass_ch);
> -	  POP_INSERT_PASSES ()
>  	  NEXT_PASS (pass_fre);
> -	  /* Pass group that runs when the function is an offloaded function
> -	     containing oacc kernels loops.  Part 2.  */
> -	  NEXT_PASS (pass_oacc_kernels2);
> -	  PUSH_INSERT_PASSES_WITHIN (pass_oacc_kernels2)
> -	      /* We use pass_lim to rewrite in-memory iteration and reduction
> -		 variable accesses in loops into local variables accesses.  */
> -	      NEXT_PASS (pass_lim);
> -	      NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
> -	      NEXT_PASS (pass_dce);
> -	      NEXT_PASS (pass_expand_omp_ssa);
> -	  POP_INSERT_PASSES ()
>  	  NEXT_PASS (pass_merge_phi);
>            NEXT_PASS (pass_dse);
>  	  NEXT_PASS (pass_cd_dce);
> @@ -124,6 +107,30 @@ along with GCC; see the file COPYING3.  If not see
>        NEXT_PASS (pass_rebuild_cgraph_edges);
>        NEXT_PASS (pass_inline_parameters);
>    POP_INSERT_PASSES ()
> +
> +  NEXT_PASS (pass_ipa_oacc);
> +  PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc)
> +      NEXT_PASS (pass_ipa_pta);
> +      /* Pass group that runs when the function is an offloaded function
> +	 containing oacc kernels loops.	 */
> +      NEXT_PASS (pass_ipa_oacc_kernels);
> +      PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc_kernels)
> +	  NEXT_PASS (pass_oacc_kernels);
> +	  PUSH_INSERT_PASSES_WITHIN (pass_oacc_kernels)
> +	      NEXT_PASS (pass_ch);
> +	      NEXT_PASS (pass_fre);
> +	      /* We use pass_lim to rewrite in-memory iteration and reduction
> +		 variable accesses in loops into local variables accesses.  */
> +	      NEXT_PASS (pass_lim);
> +	      NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
> +	      NEXT_PASS (pass_dce);
> +	      /* pass_parallelize_loops_oacc_kernels */
> +	      NEXT_PASS (pass_expand_omp_ssa);
> +	      NEXT_PASS (pass_rebuild_cgraph_edges);
> +	  POP_INSERT_PASSES ()
> +      POP_INSERT_PASSES ()
> +  POP_INSERT_PASSES ()
> +
>    NEXT_PASS (pass_ipa_chkp_produce_thunks);
>    NEXT_PASS (pass_ipa_auto_profile);
>    NEXT_PASS (pass_ipa_free_inline_summary);

Merging this patch into gomp-4_0-branch, as before --
<http://news.gmane.org/find-root.php?message_id=%3C87io4jo0ei.fsf%40kepler.schwinge.homeip.net%3E>
-- I again did not clean up but instead just copied the existing OpenACC
kernels pass structure verbatim, so on gomp-4_0-branch we currently got
these additional passes wired up:

           PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc_kernels)
              NEXT_PASS (pass_oacc_kernels);
              PUSH_INSERT_PASSES_WITHIN (pass_oacc_kernels)
    +             NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
                  NEXT_PASS (pass_ch);
    +             NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
                  NEXT_PASS (pass_fre);
                  /* We use pass_lim to rewrite in-memory iteration and reduction
                     variable accesses in loops into local variables accesses.  */
    +             NEXT_PASS (pass_tree_loop_init);
                  NEXT_PASS (pass_lim);
    +             NEXT_PASS (pass_copy_prop);
    +             NEXT_PASS (pass_lim);
    +             NEXT_PASS (pass_copy_prop);
    +             NEXT_PASS (pass_scev_cprop);
    +             NEXT_PASS (pass_tree_loop_done);
                  NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
                  NEXT_PASS (pass_dce);
    -             /* pass_parallelize_loops_oacc_kernels */
    +             NEXT_PASS (pass_tree_loop_init);
    +             NEXT_PASS (pass_parallelize_loops_oacc_kernels);
                  NEXT_PASS (pass_expand_omp_ssa);
    +             NEXT_PASS (pass_tree_loop_done);
                  NEXT_PASS (pass_rebuild_cgraph_edges);
              POP_INSERT_PASSES ()
           POP_INSERT_PASSES ()

That is, in r231753 I effectively merged trunk r231690 into
gomp-4_0-branch as follows:

commit 6a16087c1ab71a9539f538b90a2d98cecab90e82
Merge: 49a5b61 f71e6ee
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Dec 17 11:43:00 2015 +0000

    svn merge -r 231689:231690 svn+ssh://gcc.gnu.org/svn/gcc/trunk
    
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gomp-4_0-branch@231753 138bc75d-0d04-0410-961f-82ee72b054a4

 gcc/ChangeLog                            | 12 +++++
 gcc/opts.c                               | 10 ++++
 gcc/passes.def                           | 62 +++++++++++++------------
 gcc/testsuite/ChangeLog                  | 18 ++++++++
 gcc/testsuite/g++.dg/ipa/devirt-37.C     | 10 ++--
 gcc/testsuite/g++.dg/ipa/devirt-40.C     |  4 +-
 gcc/testsuite/g++.dg/tree-ssa/pr61034.C  | 10 ++--
 gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c     | 12 ++---
 gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c    |  4 +-
 gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c    | 12 ++---
 gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c    | 14 +++---
 gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c    |  6 +--
 gcc/testsuite/gcc.dg/ipa/ipa-pta-16.c    |  4 +-
 gcc/testsuite/gcc.dg/ipa/ipa-pta-2.c     |  4 +-
 gcc/testsuite/gcc.dg/ipa/ipa-pta-3.c     |  8 ++--
 gcc/testsuite/gcc.dg/ipa/ipa-pta-4.c     |  8 ++--
 gcc/testsuite/gcc.dg/ipa/ipa-pta-5.c     |  2 +-
 gcc/testsuite/gcc.dg/ipa/ipa-pta-6.c     |  4 +-
 gcc/testsuite/gcc.dg/torture/ipa-pta-1.c |  4 +-
 gcc/tree-pass.h                          |  3 +-
 gcc/tree-ssa-loop.c                      | 78 +++++++++++++++++++++++---------
 gcc/tree-ssa-structalias.c               |  2 +
 22 files changed, 187 insertions(+), 104 deletions(-)

[diff --git gcc/ChangeLog gcc/ChangeLog]


Grüße
 Thomas
diff mbox

Patch

diff --git gcc/opts.c gcc/opts.c
index 3d25f98..d46f304 100644
--- gcc/opts.c
+++ gcc/opts.c
@@ -560,6 +560,7 @@  default_options_optimization (struct gcc_options *opts,
 {
   unsigned int i;
   int opt2;
+  bool openacc_mode = false;
 
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
@@ -619,6 +620,11 @@  default_options_optimization (struct gcc_options *opts,
 	  opts->x_optimize_debug = 1;
 	  break;
 
+	case OPT_fopenacc:
+	  if (opt->value)
+	    openacc_mode = true;
+	  break;
+
 	default:
 	  /* Ignore other options in this prescan.  */
 	  break;
@@ -633,6 +639,10 @@  default_options_optimization (struct gcc_options *opts,
   /* -O2 param settings.  */
   opt2 = (opts->x_optimize >= 2);
 
+  if (openacc_mode
+      && !opts_set->x_flag_ipa_pta)
+    opts->x_flag_ipa_pta = true;
+
   /* Track fields in field-sensitive alias analysis.  */
   maybe_set_param_value
     (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
diff --git gcc/passes.def gcc/passes.def
index 9b8fe57..bf7b15e 100644
--- gcc/passes.def
+++ gcc/passes.def
@@ -88,35 +88,7 @@  along with GCC; see the file COPYING3.  If not see
 	  /* pass_build_ealias is a dummy pass that ensures that we
 	     execute TODO_rebuild_alias at this point.  */
 	  NEXT_PASS (pass_build_ealias);
-	  /* Pass group that runs when the function is an offloaded function
-	     containing oacc kernels loops.  Part 1.  */
-	  NEXT_PASS (pass_oacc_kernels);
-	  PUSH_INSERT_PASSES_WITHIN (pass_oacc_kernels)
-	      NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
-	      NEXT_PASS (pass_ch);
-	      NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
-	  POP_INSERT_PASSES ()
 	  NEXT_PASS (pass_fre);
-	  /* Pass group that runs when the function is an offloaded function
-	     containing oacc kernels loops.  Part 2.  */
-	  NEXT_PASS (pass_oacc_kernels2);
-	  PUSH_INSERT_PASSES_WITHIN (pass_oacc_kernels2)
-	      /* We use pass_lim to rewrite in-memory iteration and reduction
-		 variable accesses in loops into local variables accesses.  */
-	      NEXT_PASS (pass_tree_loop_init);
-	      NEXT_PASS (pass_lim);
-	      NEXT_PASS (pass_copy_prop);
-	      NEXT_PASS (pass_lim);
-	      NEXT_PASS (pass_copy_prop);
-	      NEXT_PASS (pass_scev_cprop);
-	      NEXT_PASS (pass_tree_loop_done);
-	      NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
-	      NEXT_PASS (pass_dce);
-	      NEXT_PASS (pass_tree_loop_init);
-      	      NEXT_PASS (pass_parallelize_loops_oacc_kernels);
-	      NEXT_PASS (pass_expand_omp_ssa);
-	      NEXT_PASS (pass_tree_loop_done);
-	  POP_INSERT_PASSES ()
 	  NEXT_PASS (pass_merge_phi);
           NEXT_PASS (pass_dse);
 	  NEXT_PASS (pass_cd_dce);
@@ -135,6 +107,40 @@  along with GCC; see the file COPYING3.  If not see
       NEXT_PASS (pass_rebuild_cgraph_edges);
       NEXT_PASS (pass_inline_parameters);
   POP_INSERT_PASSES ()
+
+  NEXT_PASS (pass_ipa_oacc);
+  PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc)
+      NEXT_PASS (pass_ipa_pta);
+      /* Pass group that runs when the function is an offloaded function
+	 containing oacc kernels loops.	 */
+      NEXT_PASS (pass_ipa_oacc_kernels);
+      PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc_kernels)
+	  NEXT_PASS (pass_oacc_kernels);
+	  PUSH_INSERT_PASSES_WITHIN (pass_oacc_kernels)
+	      NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
+	      NEXT_PASS (pass_ch);
+	      NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
+	      NEXT_PASS (pass_fre);
+	      /* We use pass_lim to rewrite in-memory iteration and reduction
+		 variable accesses in loops into local variables accesses.  */
+	      NEXT_PASS (pass_tree_loop_init);
+	      NEXT_PASS (pass_lim);
+	      NEXT_PASS (pass_copy_prop);
+	      NEXT_PASS (pass_lim);
+	      NEXT_PASS (pass_copy_prop);
+	      NEXT_PASS (pass_scev_cprop);
+	      NEXT_PASS (pass_tree_loop_done);
+	      NEXT_PASS (pass_dominator, false /* may_peel_loop_headers_p */);
+	      NEXT_PASS (pass_dce);
+	      NEXT_PASS (pass_tree_loop_init);
+	      NEXT_PASS (pass_parallelize_loops_oacc_kernels);
+	      NEXT_PASS (pass_expand_omp_ssa);
+	      NEXT_PASS (pass_tree_loop_done);
+	      NEXT_PASS (pass_rebuild_cgraph_edges);
+	  POP_INSERT_PASSES ()
+      POP_INSERT_PASSES ()
+  POP_INSERT_PASSES ()
+
   NEXT_PASS (pass_ipa_chkp_produce_thunks);
   NEXT_PASS (pass_ipa_auto_profile);
   NEXT_PASS (pass_ipa_free_inline_summary);
[diff --git gcc/testsuite/ChangeLog gcc/testsuite/ChangeLog]
index 9c5287e..b7f52a0 100644
--- gcc/testsuite/g++.dg/ipa/devirt-37.C
+++ gcc/testsuite/g++.dg/ipa/devirt-37.C
@@ -1,4 +1,4 @@ 
-/* { dg-options "-fpermissive -O2 -fno-indirect-inlining -fno-devirtualize-speculatively -fdump-tree-fre2-details -fno-early-inlining"  } */
+/* { dg-options "-fpermissive -O2 -fno-indirect-inlining -fno-devirtualize-speculatively -fdump-tree-fre3-details -fno-early-inlining"  } */
 #include <stdlib.h>
 struct A {virtual void test() {abort ();}};
 struct B:A
@@ -30,7 +30,7 @@  t()
 /* After inlining the call within constructor needs to be checked to not go into a basetype.
    We should see the vtbl store and we should notice extcall as possibly clobbering the
    type but ignore it because b is in static storage.  */
-/* { dg-final { scan-tree-dump "No dynamic type change found."  "fre2"  } } */
-/* { dg-final { scan-tree-dump "Checking vtbl store:"  "fre2"  } } */
-/* { dg-final { scan-tree-dump "Function call may change dynamic type:extcall"  "fre2"  } } */
-/* { dg-final { scan-tree-dump "converting indirect call to function virtual void"  "fre2"  } } */
+/* { dg-final { scan-tree-dump "No dynamic type change found."  "fre3"  } } */
+/* { dg-final { scan-tree-dump "Checking vtbl store:"  "fre3"  } } */
+/* { dg-final { scan-tree-dump "Function call may change dynamic type:extcall"  "fre3"  } } */
+/* { dg-final { scan-tree-dump "converting indirect call to function virtual void"  "fre3"  } } */
diff --git gcc/testsuite/g++.dg/ipa/devirt-40.C gcc/testsuite/g++.dg/ipa/devirt-40.C
index 279a228..5107c29 100644
--- gcc/testsuite/g++.dg/ipa/devirt-40.C
+++ gcc/testsuite/g++.dg/ipa/devirt-40.C
@@ -1,4 +1,4 @@ 
-/* { dg-options "-O2 -fdump-tree-fre2-details"  } */
+/* { dg-options "-O2 -fdump-tree-fre3-details"  } */
 typedef enum
 {
 } UErrorCode;
@@ -19,4 +19,4 @@  A::m_fn1 (UnicodeString &, int &p2, UErrorCode &) const
   UnicodeString a[2];
 }
 
-/* { dg-final { scan-tree-dump-not "\\n  OBJ_TYPE_REF" "fre2"  } } */
+/* { dg-final { scan-tree-dump-not "\\n  OBJ_TYPE_REF" "fre3"  } } */
diff --git gcc/testsuite/g++.dg/tree-ssa/pr61034.C gcc/testsuite/g++.dg/tree-ssa/pr61034.C
index cd4ee05..c06c580 100644
--- gcc/testsuite/g++.dg/tree-ssa/pr61034.C
+++ gcc/testsuite/g++.dg/tree-ssa/pr61034.C
@@ -1,5 +1,5 @@ 
 // { dg-do compile }
-// { dg-options "-O2 -fdump-tree-fre2 -fdump-tree-optimized" }
+// { dg-options "-O2 -fdump-tree-fre3 -fdump-tree-optimized" }
 
 #define assume(x) if(!(x))__builtin_unreachable()
 
@@ -42,13 +42,13 @@  bool f(I a, I b, I c, I d) {
 // a bunch of conditional free()s and unreachable()s.
 // This works only if everything is inlined into 'f'.
 
-// { dg-final { scan-tree-dump-times ";; Function" 1 "fre2" } }
-// { dg-final { scan-tree-dump-times "unreachable" 11 "fre2" } }
+// { dg-final { scan-tree-dump-times ";; Function" 1 "fre3" } }
+// { dg-final { scan-tree-dump-times "unreachable" 11 "fre3" } }
 
 // Note that depending on PUSH_ARGS_REVERSED we are presented with
 // a different initial CFG and thus the final outcome is different
 
-// { dg-final { scan-tree-dump-times "free" 10 "fre2" { target x86_64-*-* i?86-*-* } } }
+// { dg-final { scan-tree-dump-times "free" 10 "fre3" { target x86_64-*-* i?86-*-* } } }
 // { dg-final { scan-tree-dump-times "free" 3 "optimized" { target x86_64-*-* i?86-*-* } } }
-// { dg-final { scan-tree-dump-times "free" 14 "fre2" { target aarch64-*-* ia64-*-* arm-*-* hppa*-*-* sparc*-*-* powerpc*-*-* alpha*-*-* } } }
+// { dg-final { scan-tree-dump-times "free" 14 "fre3" { target aarch64-*-* ia64-*-* arm-*-* hppa*-*-* sparc*-*-* powerpc*-*-* alpha*-*-* } } }
 // { dg-final { scan-tree-dump-times "free" 4 "optimized" { target aarch64-*-* ia64-*-* arm-*-* hppa*-*-* sparc*-*-* powerpc*-*-* alpha*-*-* } } }
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c
index c183fcb..bc631f8 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run } */
-/* { dg-options "-O -fipa-pta -fdump-ipa-pta-details" } */
+/* { dg-options "-O -fipa-pta -fdump-ipa-pta2-details" } */
 
 static int __attribute__((noinline))
 foo (int *p, int *q)
@@ -45,8 +45,8 @@  int main()
    not seen by IPA PTA (if the address escapes the unit which we only compute
    during IPA PTA...).  Thus the solution also includes NONLOCAL.  */
 
-/* { dg-final { scan-ipa-dump "fn_1 = { bar foo }" "pta" } } */
-/* { dg-final { scan-ipa-dump "bar.arg0 = { NONLOCAL a }" "pta" } } */
-/* { dg-final { scan-ipa-dump "bar.arg1 = { NONLOCAL a }" "pta" } } */
-/* { dg-final { scan-ipa-dump "foo.arg0 = { NONLOCAL a }" "pta" } } */
-/* { dg-final { scan-ipa-dump "foo.arg1 = { NONLOCAL a }" "pta" } } */
+/* { dg-final { scan-ipa-dump "fn_1 = { bar foo }" "pta2" } } */
+/* { dg-final { scan-ipa-dump "bar.arg0 = { NONLOCAL a }" "pta2" } } */
+/* { dg-final { scan-ipa-dump "bar.arg1 = { NONLOCAL a }" "pta2" } } */
+/* { dg-final { scan-ipa-dump "foo.arg0 = { NONLOCAL a }" "pta2" } } */
+/* { dg-final { scan-ipa-dump "foo.arg1 = { NONLOCAL a }" "pta2" } } */
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c
index 0a6c166..90b7bf8 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-10.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run } */
-/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details" } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details" } */
 
 #include <stdarg.h>
 
@@ -26,4 +26,4 @@  int main()
 /* Verify we properly handle variadic arguments and do not let escape
    stuff through it.  */
 
-/* { dg-final { scan-ipa-dump "ESCAPED = { (ESCAPED )?(NONLOCAL )?}" "pta" } } */
+/* { dg-final { scan-ipa-dump "ESCAPED = { (ESCAPED )?(NONLOCAL )?}" "pta2" } } */
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c
index 84dd254..9857d7b 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-11.c
@@ -1,25 +1,25 @@ 
 /* { dg-do link } */
-/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details" } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details" } */
 
 static int i;
 /* i should not escape here, p should point to i only.  */
-/* { dg-final { scan-ipa-dump "p = { i }" "pta" } } */
+/* { dg-final { scan-ipa-dump "p = { i }" "pta2" } } */
 static int *p = &i;
 
 int j;
 /* q should point to j only.  */
-/* { dg-final { scan-ipa-dump "q = { j }" "pta" } } */
+/* { dg-final { scan-ipa-dump "q = { j }" "pta2" } } */
 static int *q = &j;
 
 static int k;
 /* k should escape here, r should point to NONLOCAL, ESCAPED, k.  */
 int *r = &k;
-/* { dg-final { scan-ipa-dump "r = { ESCAPED NONLOCAL k }" "pta" } } */
+/* { dg-final { scan-ipa-dump "r = { ESCAPED NONLOCAL k }" "pta2" } } */
 
 int l;
 /* s should point to NONLOCAL, ESCAPED, l.  */
 int *s = &l;
-/* { dg-final { scan-ipa-dump "s = { ESCAPED NONLOCAL l }" "pta" } } */
+/* { dg-final { scan-ipa-dump "s = { ESCAPED NONLOCAL l }" "pta2" } } */
 
 /* Make p and q referenced so they do not get optimized out.  */
 int foo() { return &p < &q; }
@@ -32,4 +32,4 @@  int main()
 /* It isn't clear if the escape if l is strictly necessary, if it were
    we should have i, r and s in ESCAPED as well.  */
 
-/* { dg-final { scan-ipa-dump "ESCAPED = { ESCAPED NONLOCAL l k }" "pta" } } */
+/* { dg-final { scan-ipa-dump "ESCAPED = { ESCAPED NONLOCAL l k }" "pta2" } } */
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c
index f558df3..93dd871 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c
@@ -1,5 +1,5 @@ 
 /* { dg-do link } */
-/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details -fdump-tree-fre2 -fno-ipa-icf" } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details -fdump-tree-fre3 -fno-ipa-icf" } */
 
 static int x, y;
 
@@ -19,7 +19,7 @@  void *anyfn_global;
 
 /* Even though not referenced in this TU we should have added constraints
    for the initializer.  */
-/* { dg-final { scan-ipa-dump "ex = &local_address_taken" "pta" } } */
+/* { dg-final { scan-ipa-dump "ex = &local_address_taken" "pta2" } } */
 void (*ex)(int *) = local_address_taken;
 
 extern void link_error (void);
@@ -38,11 +38,11 @@  int main()
      uses to be messed up even further.  */
   /* ???  As we don't expand the ESCAPED solution we either get x printed here
      or not based on the phase of the moon.  */
-  /* { dg-final { scan-ipa-dump "local_address_taken.arg0 = { ESCAPED NONLOCAL y x }" "pta" { xfail *-*-* } } } */
-  /* { dg-final { scan-ipa-dump "local_address_taken.clobber = { ESCAPED NONLOCAL y x }" "pta" { xfail *-*-* } } } */
-  /* { dg-final { scan-ipa-dump "local_address_taken.use = { }" "pta" { xfail *-*-* } } } */
+  /* { dg-final { scan-ipa-dump "local_address_taken.arg0 = { ESCAPED NONLOCAL y x }" "pta2" { xfail *-*-* } } } */
+  /* { dg-final { scan-ipa-dump "local_address_taken.clobber = { ESCAPED NONLOCAL y x }" "pta2" { xfail *-*-* } } } */
+  /* { dg-final { scan-ipa-dump "local_address_taken.use = { }" "pta2" { xfail *-*-* } } } */
   /* ??? But make sure x really escaped.  */
-  /* { dg-final { scan-ipa-dump "ESCAPED = {\[^\n\}\]* x \[^\n\}\]*}" "pta" } } */
+  /* { dg-final { scan-ipa-dump "ESCAPED = {\[^\n\}\]* x \[^\n\}\]*}" "pta2" } } */
   (*anyfn) (&x);
   x = 0;
   local (&y);
@@ -54,7 +54,7 @@  int main()
   local_address_taken (&y);
   /* As we are computing flow- and context-insensitive we may not
      CSE the load of x here.  */
-  /* { dg-final { scan-tree-dump " = x;" "fre2" } } */
+  /* { dg-final { scan-tree-dump " = x;" "fre3" } } */
   return x;
 }
 
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
index e3333fa..cc2b940 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run } */
-/* { dg-options "-O2 -fipa-pta -fno-tree-fre -fno-tree-sra -fdump-ipa-pta-details -fdelete-null-pointer-checks" } */
+/* { dg-options "-O2 -fipa-pta -fno-tree-fre -fno-tree-sra -fdump-ipa-pta2-details -fdelete-null-pointer-checks" } */
 
 struct X {
     int i;
@@ -21,8 +21,8 @@  int main()
   void *p;
   a.p = (void *)&c;
   p = foo(&a, &a);
-  /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* c\[^ \]* }" "pta" { target { ! keeps_null_pointer_checks } } } } */
-  /* { dg-final { scan-ipa-dump "foo.result = { NONLOCAL a\[^ \]* c\[^ \]* }" "pta" { target { keeps_null_pointer_checks } } } } */
+  /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* c\[^ \]* }" "pta2" { target { ! keeps_null_pointer_checks } } } } */
+  /* { dg-final { scan-ipa-dump "foo.result = { NONLOCAL a\[^ \]* c\[^ \]* }" "pta2" { target { keeps_null_pointer_checks } } } } */
   ((struct X *)p)->p = (void *)0;
   if (a.p != (void *)0)
     abort ();
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-16.c gcc/testsuite/gcc.dg/ipa/ipa-pta-16.c
index 5bd6596..83b9cd8 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-16.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-16.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run } */
-/* { dg-options "-O2 -fno-tree-sra -fipa-pta -fdump-ipa-pta" } */
+/* { dg-options "-O2 -fno-tree-sra -fipa-pta -fdump-ipa-pta2" } */
 
 struct X
 {
@@ -29,4 +29,4 @@  int main()
   return 0;
 }
 
-/* { dg-final { scan-ipa-dump "y.\[0-9\]*\\\+\[0-9\]* = { i }" "pta" } } */
+/* { dg-final { scan-ipa-dump "y.\[0-9\]*\\\+\[0-9\]* = { i }" "pta2" } } */
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-2.c gcc/testsuite/gcc.dg/ipa/ipa-pta-2.c
index b77864d..0cf2adf 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-2.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O -fipa-pta -fdump-ipa-pta-details" } */
+/* { dg-options "-O -fipa-pta -fdump-ipa-pta2-details" } */
 
 int (*fn)(int *);
 
@@ -21,4 +21,4 @@  int main()
 /* Make sure that when a local function escapes its argument points-to sets
    are properly adjusted.  */
 
-/* { dg-final { scan-ipa-dump "foo.arg0 = { ESCAPED NONLOCAL }" "pta" } } */
+/* { dg-final { scan-ipa-dump "foo.arg0 = { ESCAPED NONLOCAL }" "pta2" } } */
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-3.c gcc/testsuite/gcc.dg/ipa/ipa-pta-3.c
index ff6fa57..68c2144 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-3.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-3.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run } */
-/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details -fdump-tree-fre2-details" } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details -fdump-tree-fre3-details" } */
 
 static int __attribute__((noinline,noclone))
 foo (int *p, int *q)
@@ -21,6 +21,6 @@  int main()
 
 /* Verify we can disambiguate *p and *q in foo.  */
 
-/* { dg-final { scan-ipa-dump "foo.arg0 = &a" "pta" } } */
-/* { dg-final { scan-ipa-dump "foo.arg1 = &b" "pta" } } */
-/* { dg-final { scan-tree-dump "Replaced \\\*p_2\\\(D\\\) with 1" "fre2" } } */
+/* { dg-final { scan-ipa-dump "foo.arg0 = &a" "pta2" } } */
+/* { dg-final { scan-ipa-dump "foo.arg1 = &b" "pta2" } } */
+/* { dg-final { scan-tree-dump "Replaced \\\*p_2\\\(D\\\) with 1" "fre3" } } */
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-4.c gcc/testsuite/gcc.dg/ipa/ipa-pta-4.c
index 106e325..2fc8ada 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-4.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-4.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run } */
-/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details -fdump-tree-fre2-details" } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details -fdump-tree-fre3-details" } */
 
 int a, b;
 
@@ -26,6 +26,6 @@  int main()
 
 /* Verify we can disambiguate *p and *q in foo.  */
 
-/* { dg-final { scan-ipa-dump "foo.arg0 = &a" "pta" } } */
-/* { dg-final { scan-ipa-dump "foo.arg1 = &b" "pta" } } */
-/* { dg-final { scan-tree-dump "Replaced \\\*p_2\\\(D\\\) with 1" "fre2" } } */
+/* { dg-final { scan-ipa-dump "foo.arg0 = &a" "pta2" } } */
+/* { dg-final { scan-ipa-dump "foo.arg1 = &b" "pta2" } } */
+/* { dg-final { scan-tree-dump "Replaced \\\*p_2\\\(D\\\) with 1" "fre3" } } */
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-5.c gcc/testsuite/gcc.dg/ipa/ipa-pta-5.c
index 625291b..ec12979 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-5.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-5.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run } */
-/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta-details" } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details" } */
 
 int **x;
 
diff --git gcc/testsuite/gcc.dg/ipa/ipa-pta-6.c gcc/testsuite/gcc.dg/ipa/ipa-pta-6.c
index c1c8245..8fd5a43 100644
--- gcc/testsuite/gcc.dg/ipa/ipa-pta-6.c
+++ gcc/testsuite/gcc.dg/ipa/ipa-pta-6.c
@@ -1,5 +1,5 @@ 
 /* { dg-do run } */
-/* { dg-options "-O -fipa-pta -fdump-ipa-pta-details" } */
+/* { dg-options "-O -fipa-pta -fdump-ipa-pta2-details" } */
 
 static void __attribute__((noinline,noclone))
 foo (int *p)
@@ -21,4 +21,4 @@  int main()
 /* Verify we correctly compute the units ESCAPED set as empty but
    still properly account for the store via *p in foo.  */
 
-/* { dg-final { scan-ipa-dump "ESCAPED = { }" "pta" } } */
+/* { dg-final { scan-ipa-dump "ESCAPED = { }" "pta2" } } */
diff --git gcc/testsuite/gcc.dg/torture/ipa-pta-1.c gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
index c31d408..1bf4997 100644
--- gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
+++ gcc/testsuite/gcc.dg/torture/ipa-pta-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile { target { nonpic } } } */
-/* { dg-options "-fipa-pta -fdump-ipa-pta -fno-ipa-icf" } */
+/* { dg-options "-fipa-pta -fdump-ipa-pta2 -fno-ipa-icf" } */
 /* { dg-skip-if "" { *-*-* } { "-O0" "-fno-fat-lto-objects" } { "" } } */
 
 struct X { char x; char y; };
@@ -42,4 +42,4 @@  void test4 (int a4, char b, char c, char d, char e, char f, char g, char h)
   bar (p);
 }
 
-/* { dg-final { scan-ipa-dump "bar.arg0 = { test4.arg0 test3.arg0 test2.arg0 test1.arg0 }" "pta" } } */
+/* { dg-final { scan-ipa-dump "bar.arg0 = { test4.arg0 test3.arg0 test2.arg0 test1.arg0 }" "pta2" } } */
diff --git gcc/tree-pass.h gcc/tree-pass.h
index acb606a..b622f56 100644
--- gcc/tree-pass.h
+++ gcc/tree-pass.h
@@ -471,7 +471,8 @@  extern gimple_opt_pass *make_pass_vtable_verify (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_ubsan (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_sanopt (gcc::context *ctxt);
 extern gimple_opt_pass *make_pass_oacc_kernels (gcc::context *ctxt);
-extern gimple_opt_pass *make_pass_oacc_kernels2 (gcc::context *ctxt);
+extern simple_ipa_opt_pass *make_pass_ipa_oacc (gcc::context *ctxt);
+extern simple_ipa_opt_pass *make_pass_ipa_oacc_kernels (gcc::context *ctxt);
 
 /* IPA Passes */
 extern simple_ipa_opt_pass *make_pass_ipa_lower_emutls (gcc::context *ctxt);
diff --git gcc/tree-ssa-loop.c gcc/tree-ssa-loop.c
index 8a7ef1b..ce2068a 100644
--- gcc/tree-ssa-loop.c
+++ gcc/tree-ssa-loop.c
@@ -36,6 +36,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "tree-scalar-evolution.h"
 #include "tree-vectorizer.h"
 #include "omp-low.h"
+#include "diagnostic-core.h"
 
 
 /* A pass making sure loops are fixed up.  */
@@ -206,12 +207,14 @@  make_pass_oacc_kernels (gcc::context *ctxt)
   return new pass_oacc_kernels (ctxt);
 }
 
+/* The ipa oacc superpass.  */
+
 namespace {
 
-const pass_data pass_data_oacc_kernels2 =
+const pass_data pass_data_ipa_oacc =
 {
-  GIMPLE_PASS, /* type */
-  "oacc_kernels2", /* name */
+  SIMPLE_IPA_PASS, /* type */
+  "ipa_oacc", /* name */
   OPTGROUP_LOOP, /* optinfo_flags */
   TV_TREE_LOOP, /* tv_id */
   PROP_cfg, /* properties_required */
@@ -221,34 +224,65 @@  const pass_data pass_data_oacc_kernels2 =
   0, /* todo_flags_finish */
 };
 
-class pass_oacc_kernels2 : public gimple_opt_pass
+class pass_ipa_oacc : public simple_ipa_opt_pass
 {
 public:
-  pass_oacc_kernels2 (gcc::context *ctxt)
-    : gimple_opt_pass (pass_data_oacc_kernels2, ctxt)
+  pass_ipa_oacc (gcc::context *ctxt)
+    : simple_ipa_opt_pass (pass_data_ipa_oacc, ctxt)
   {}
 
   /* opt_pass methods: */
-  virtual bool gate (function *fn) { return gate_oacc_kernels (fn); }
-  virtual unsigned int execute (function *fn)
-    {
-      /* Rather than having a copy of the previous dump, get some use out of
-	 this dump, and try to minimize differences with the following pass
-	 (pass_lim), which will initizalize the loop optimizer with
-	 LOOPS_NORMAL.  */
-      loop_optimizer_init (LOOPS_NORMAL);
-      loop_optimizer_finalize (fn);
-      return 0;
-    }
-
-}; // class pass_oacc_kernels2
+  virtual bool gate (function *)
+  {
+    return (optimize
+	    /* Don't bother doing anything if the program has errors.  */
+	    && !seen_error ()
+	    && flag_openacc
+	    && flag_tree_parallelize_loops > 1);
+  }
+
+}; // class pass_ipa_oacc
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_ipa_oacc (gcc::context *ctxt)
+{
+  return new pass_ipa_oacc (ctxt);
+}
+
+/* The ipa oacc kernels pass.  */
+
+namespace {
+
+const pass_data pass_data_ipa_oacc_kernels =
+{
+  SIMPLE_IPA_PASS, /* type */
+  "ipa_oacc_kernels", /* name */
+  OPTGROUP_LOOP, /* optinfo_flags */
+  TV_TREE_LOOP, /* tv_id */
+  PROP_cfg, /* properties_required */
+  0, /* properties_provided */
+  0, /* properties_destroyed */
+  0, /* todo_flags_start */
+  0, /* todo_flags_finish */
+};
+
+class pass_ipa_oacc_kernels : public simple_ipa_opt_pass
+{
+public:
+  pass_ipa_oacc_kernels (gcc::context *ctxt)
+    : simple_ipa_opt_pass (pass_data_ipa_oacc_kernels, ctxt)
+  {}
+
+}; // class pass_ipa_oacc_kernels
 
 } // anon namespace
 
-gimple_opt_pass *
-make_pass_oacc_kernels2 (gcc::context *ctxt)
+simple_ipa_opt_pass *
+make_pass_ipa_oacc_kernels (gcc::context *ctxt)
 {
-  return new pass_oacc_kernels2 (ctxt);
+  return new pass_ipa_oacc_kernels (ctxt);
 }
 
 /* The no-loop superpass.  */
diff --git gcc/tree-ssa-structalias.c gcc/tree-ssa-structalias.c
index b34c955..5f8c0b6 100644
--- gcc/tree-ssa-structalias.c
+++ gcc/tree-ssa-structalias.c
@@ -7821,6 +7821,8 @@  public:
 	      && !seen_error ());
     }
 
+  opt_pass * clone () { return new pass_ipa_pta (m_ctxt); }
+
   virtual unsigned int execute (function *) { return ipa_pta_execute (); }
 
 }; // class pass_ipa_pta