From 6cafc3fb8680611b82faac78b3056b4820d06832 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 17 Dec 2013 10:25:47 -0500
Subject: [PATCH 39/89] Introduce gimple_omp_parallel

gcc/
	* coretypes.h (gimple_omp_parallel): New typedef.
	(const_gimple_omp_parallel): New typedef.

	* cgraphbuild.c (build_cgraph_edges): Convert check of code
	against GIMPLE_OMP_PARALLEL to a dyn_cast_gimple_omp_parallel and
	new local.

	* gimple-pretty-print.c (dump_gimple_omp_parallel): Require a
	gimple_omp_parallel rather than a plain gimple.
	(pp_gimple_stmt_1): Add a checked cast to gimple_omp_parallel
	within GIMPLE_OMP_PARALLEL case of switch statement.

	* gimple-walk.c (walk_gimple_op): Likewise, introducing a local.

	* gimple.c (gimple_build_omp_parallel): Return a
	gimple_omp_parallel rather than a plain gimple.
	(gimple_copy): Add checked casts to gimple_omp_parallel within
	GIMPLE_OMP_PARALLEL case of switch statement, introducing locals.

	* gimple.h (gimple_statement_base::as_a_gimple_omp_parallel): New.
	(gimple_statement_base::dyn_cast_gimple_omp_parallel): New.
	(gimple_build_omp_parallel): Return a gimple_omp_parallel rather
	than a plain gimple.
	(gimple_omp_parallel_clauses_ptr): Require a gimple_omp_parallel
	rather than a plain gimple.
	(gimple_omp_parallel_set_clauses): Likewise.
	(gimple_omp_parallel_data_arg_ptr): Likewise.
	(gimple_omp_parallel_set_data_arg): Likewise.
	(gimple_omp_parallel_child_fn_ptr): Likewise.
	(gimple_omp_parallel_set_child_fn): Likewise.
	(gimple_omp_parallel_child_fn): Require a
	const_gimple_omp_parallel rather than a plain const_gimple.
	(gimple_omp_parallel_data_arg): Likewise.

	* omp-low.c (scan_omp_parallel): Strengthen local "stmt" from
	gimple to gimple_omp_parallel.
	(expand_parallel_call): Require a gimple_omp_parallel for
	"entry_stmt" rather than a plain gimple.
	(remove_exit_barrier):  Strengthen local "parallel_stmt" from
	gimple to gimple_omp_parallel.
	(expand_omp_taskreg): Add checked cast to gimple_omp_parallel.

	* tree-inline.c (remap_gimple_stmt): Add a checked cast to
	gimple_omp_parallel within GIMPLE_OMP_PARALLEL case of switch
	statement, introducing local.
---
 gcc/cgraphbuild.c         | 17 ++++++------
 gcc/coretypes.h           |  4 +++
 gcc/gimple-pretty-print.c |  7 ++---
 gcc/gimple-walk.c         | 27 ++++++++++---------
 gcc/gimple.c              | 23 +++++++++++------
 gcc/gimple.h              | 66 +++++++++++++++++++++++------------------------
 gcc/omp-low.c             | 11 +++++---
 gcc/tree-inline.c         | 16 +++++++-----
 8 files changed, 96 insertions(+), 75 deletions(-)

diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index 19961e2..411214a 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -343,14 +343,15 @@ build_cgraph_edges (void)
 					     bb->count, freq);
 	    }
 	  ipa_record_stmt_references (node, stmt);
-	  if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
-	      && gimple_omp_parallel_child_fn (stmt))
-	    {
-	      tree fn = gimple_omp_parallel_child_fn (stmt);
-	      ipa_record_reference (node,
-				    cgraph_get_create_node (fn),
-				    IPA_REF_ADDR, stmt);
-	    }
+	  if (gimple_omp_parallel omp_par_stmt =
+	      stmt->dyn_cast_gimple_omp_parallel ())
+	    if (gimple_omp_parallel_child_fn (omp_par_stmt))
+	      {
+		tree fn = gimple_omp_parallel_child_fn (omp_par_stmt);
+		ipa_record_reference (node,
+				      cgraph_get_create_node (fn),
+				      IPA_REF_ADDR, stmt);
+	      }
 	  if (gimple_code (stmt) == GIMPLE_OMP_TASK)
 	    {
 	      tree fn = gimple_omp_task_child_fn (stmt);
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 0a797a3..2647189 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -167,6 +167,10 @@ struct gimple_statement_omp_for;
 typedef struct gimple_statement_omp_for *gimple_omp_for;
 typedef const struct gimple_statement_omp_for *const_gimple_omp_for;
 
+struct gimple_statement_omp_parallel;
+typedef struct gimple_statement_omp_parallel *gimple_omp_parallel;
+typedef const struct gimple_statement_omp_parallel *const_gimple_omp_parallel;
+
 union section;
 typedef union section section;
 struct gcc_options;
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 1b70885..bf77f87 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1851,8 +1851,8 @@ dump_gimple_phi (pretty_printer *buffer, gimple_phi phi, int spc, bool comment,
    dumpfile.h).  */
 
 static void
-dump_gimple_omp_parallel (pretty_printer *buffer, gimple gs, int spc,
-                          int flags)
+dump_gimple_omp_parallel (pretty_printer *buffer, gimple_omp_parallel gs,
+			  int spc, int flags)
 {
   if (flags & TDF_RAW)
     {
@@ -2143,7 +2143,8 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
       break;
 
     case GIMPLE_OMP_PARALLEL:
-      dump_gimple_omp_parallel (buffer, gs, spc, flags);
+      dump_gimple_omp_parallel (buffer, gs->as_a_gimple_omp_parallel (), spc,
+				flags);
       break;
 
     case GIMPLE_OMP_TASK:
diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c
index ae43f45..63200a2 100644
--- a/gcc/gimple-walk.c
+++ b/gcc/gimple-walk.c
@@ -347,18 +347,21 @@ walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
       break;
 
     case GIMPLE_OMP_PARALLEL:
-      ret = walk_tree (gimple_omp_parallel_clauses_ptr (stmt), callback_op,
-		       wi, pset);
-      if (ret)
-	return ret;
-      ret = walk_tree (gimple_omp_parallel_child_fn_ptr (stmt), callback_op,
-		       wi, pset);
-      if (ret)
-	return ret;
-      ret = walk_tree (gimple_omp_parallel_data_arg_ptr (stmt), callback_op,
-		       wi, pset);
-      if (ret)
-	return ret;
+      {
+	gimple_omp_parallel omp_par_stmt = stmt->as_a_gimple_omp_parallel ();
+	ret = walk_tree (gimple_omp_parallel_clauses_ptr (omp_par_stmt),
+			 callback_op, wi, pset);
+	if (ret)
+	  return ret;
+	ret = walk_tree (gimple_omp_parallel_child_fn_ptr (omp_par_stmt),
+			 callback_op, wi, pset);
+	if (ret)
+	  return ret;
+	ret = walk_tree (gimple_omp_parallel_data_arg_ptr (omp_par_stmt),
+			 callback_op, wi, pset);
+	if (ret)
+	  return ret;
+      }
       break;
 
     case GIMPLE_OMP_TASK:
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 7f25207..0b35d00 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -864,11 +864,12 @@ gimple_build_omp_for (gimple_seq body, int kind, tree clauses, size_t collapse,
    CHILD_FN is the function created for the parallel threads to execute.
    DATA_ARG are the shared data argument(s).  */
 
-gimple
+gimple_omp_parallel
 gimple_build_omp_parallel (gimple_seq body, tree clauses, tree child_fn,
 			   tree data_arg)
 {
-  gimple p = gimple_alloc (GIMPLE_OMP_PARALLEL, 0);
+  gimple_omp_parallel p =
+    gimple_alloc (GIMPLE_OMP_PARALLEL, 0)->as_a_gimple_omp_parallel ();
   if (body)
     gimple_omp_set_body (p, body);
   gimple_omp_parallel_set_clauses (p, clauses);
@@ -1711,12 +1712,18 @@ gimple_copy (gimple stmt)
 	  goto copy_omp_body;
 
 	case GIMPLE_OMP_PARALLEL:
-	  t = unshare_expr (gimple_omp_parallel_clauses (stmt));
-	  gimple_omp_parallel_set_clauses (copy, t);
-	  t = unshare_expr (gimple_omp_parallel_child_fn (stmt));
-	  gimple_omp_parallel_set_child_fn (copy, t);
-	  t = unshare_expr (gimple_omp_parallel_data_arg (stmt));
-	  gimple_omp_parallel_set_data_arg (copy, t);
+	  {
+	    gimple_omp_parallel omp_par_stmt =
+	      stmt->as_a_gimple_omp_parallel ();
+	    gimple_omp_parallel omp_par_copy =
+	      copy->as_a_gimple_omp_parallel ();
+	    t = unshare_expr (gimple_omp_parallel_clauses (omp_par_stmt));
+	    gimple_omp_parallel_set_clauses (omp_par_copy, t);
+	    t = unshare_expr (gimple_omp_parallel_child_fn (omp_par_stmt));
+	    gimple_omp_parallel_set_child_fn (omp_par_copy, t);
+	    t = unshare_expr (gimple_omp_parallel_data_arg (omp_par_stmt));
+	    gimple_omp_parallel_set_data_arg (omp_par_copy, t);
+	  }
 	  goto copy_omp_body;
 
 	case GIMPLE_OMP_TASK:
diff --git a/gcc/gimple.h b/gcc/gimple.h
index d5e9af8..d391db8 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -366,6 +366,12 @@ public:
     return as_a <gimple_statement_omp_for> (this);
   }
 
+  inline gimple_omp_parallel
+  as_a_gimple_omp_parallel ()
+  {
+    return as_a <gimple_statement_omp_parallel> (this);
+  }
+
   /* Dynamic casting methods, where the cast returns NULL if the
      stmt is not of the required kind.
 
@@ -463,6 +469,12 @@ public:
   {
     return dyn_cast <gimple_statement_omp_for> (this);
   }
+
+  inline gimple_omp_parallel
+  dyn_cast_gimple_omp_parallel ()
+  {
+    return dyn_cast <gimple_statement_omp_parallel> (this);
+  }
 };
 
 
@@ -1607,7 +1619,7 @@ gimple_debug gimple_build_debug_source_bind_stat (tree, tree, gimple MEM_STAT_DE
   gimple_build_debug_source_bind_stat ((var), (val), (stmt) MEM_STAT_INFO)
 gimple_omp_critical gimple_build_omp_critical (gimple_seq, tree);
 gimple_omp_for gimple_build_omp_for (gimple_seq, int, tree, size_t, gimple_seq);
-gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree);
+gimple_omp_parallel gimple_build_omp_parallel (gimple_seq, tree, tree, tree);
 gimple gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree);
 gimple gimple_build_omp_section (gimple_seq);
 gimple gimple_build_omp_master (gimple_seq);
@@ -4912,92 +4924,78 @@ gimple_omp_parallel_clauses (const_gimple gs)
 }
 
 
-/* Return a pointer to the clauses associated with OMP_PARALLEL GS.  */
+/* Return a pointer to the clauses associated with OMP_PARALLEL_STMT.  */
 
 static inline tree *
-gimple_omp_parallel_clauses_ptr (gimple gs)
+gimple_omp_parallel_clauses_ptr (gimple_omp_parallel omp_parallel_stmt)
 {
-  gimple_statement_omp_parallel *omp_parallel_stmt =
-    as_a <gimple_statement_omp_parallel> (gs);
   return &omp_parallel_stmt->clauses;
 }
 
 
-/* Set CLAUSES to be the list of clauses associated with OMP_PARALLEL
-   GS.  */
+/* Set CLAUSES to be the list of clauses associated with OMP_PARALLEL_STMT.  */
 
 static inline void
-gimple_omp_parallel_set_clauses (gimple gs, tree clauses)
+gimple_omp_parallel_set_clauses (gimple_omp_parallel omp_parallel_stmt,
+				 tree clauses)
 {
-  gimple_statement_omp_parallel *omp_parallel_stmt =
-    as_a <gimple_statement_omp_parallel> (gs);
   omp_parallel_stmt->clauses = clauses;
 }
 
 
-/* Return the child function used to hold the body of OMP_PARALLEL GS.  */
+/* Return the child function used to hold the body of OMP_PARALLEL_STMT.  */
 
 static inline tree
-gimple_omp_parallel_child_fn (const_gimple gs)
+gimple_omp_parallel_child_fn (const_gimple_omp_parallel omp_parallel_stmt)
 {
-  const gimple_statement_omp_parallel *omp_parallel_stmt =
-    as_a <const gimple_statement_omp_parallel> (gs);
   return omp_parallel_stmt->child_fn;
 }
 
 /* Return a pointer to the child function used to hold the body of
-   OMP_PARALLEL GS.  */
+   OMP_PARALLEL_STMT.  */
 
 static inline tree *
-gimple_omp_parallel_child_fn_ptr (gimple gs)
+gimple_omp_parallel_child_fn_ptr (gimple_omp_parallel omp_parallel_stmt)
 {
-  gimple_statement_omp_parallel *omp_parallel_stmt =
-    as_a <gimple_statement_omp_parallel> (gs);
   return &omp_parallel_stmt->child_fn;
 }
 
 
-/* Set CHILD_FN to be the child function for OMP_PARALLEL GS.  */
+/* Set CHILD_FN to be the child function for OMP_PARALLEL_STMT.  */
 
 static inline void
-gimple_omp_parallel_set_child_fn (gimple gs, tree child_fn)
+gimple_omp_parallel_set_child_fn (gimple_omp_parallel omp_parallel_stmt,
+				  tree child_fn)
 {
-  gimple_statement_omp_parallel *omp_parallel_stmt =
-    as_a <gimple_statement_omp_parallel> (gs);
   omp_parallel_stmt->child_fn = child_fn;
 }
 
 
 /* Return the artificial argument used to send variables and values
-   from the parent to the children threads in OMP_PARALLEL GS.  */
+   from the parent to the children threads in OMP_PARALLEL_STMT.  */
 
 static inline tree
-gimple_omp_parallel_data_arg (const_gimple gs)
+gimple_omp_parallel_data_arg (const_gimple_omp_parallel omp_parallel_stmt)
 {
-  const gimple_statement_omp_parallel *omp_parallel_stmt =
-    as_a <const gimple_statement_omp_parallel> (gs);
   return omp_parallel_stmt->data_arg;
 }
 
 
-/* Return a pointer to the data argument for OMP_PARALLEL GS.  */
+/* Return a pointer to the data argument for OMP_PARALLEL_STMT.  */
 
 static inline tree *
-gimple_omp_parallel_data_arg_ptr (gimple gs)
+gimple_omp_parallel_data_arg_ptr (gimple_omp_parallel omp_parallel_stmt)
 {
-  gimple_statement_omp_parallel *omp_parallel_stmt =
-    as_a <gimple_statement_omp_parallel> (gs);
   return &omp_parallel_stmt->data_arg;
 }
 
 
-/* Set DATA_ARG to be the data argument for OMP_PARALLEL GS.  */
+/* Set DATA_ARG to be the data argument for OMP_PARALLEL_STMT.  */
 
 static inline void
-gimple_omp_parallel_set_data_arg (gimple gs, tree data_arg)
+gimple_omp_parallel_set_data_arg (gimple_omp_parallel omp_parallel_stmt,
+				  tree data_arg)
 {
-  gimple_statement_omp_parallel *omp_parallel_stmt =
-    as_a <gimple_statement_omp_parallel> (gs);
   omp_parallel_stmt->data_arg = data_arg;
 }
 
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 8a3b2a1..1602857 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1957,7 +1957,7 @@ scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
 {
   omp_context *ctx;
   tree name;
-  gimple stmt = gsi_stmt (*gsi);
+  gimple_omp_parallel stmt = gsi_stmt (*gsi)->as_a_gimple_omp_parallel ();
 
   /* Ignore parallel directives with empty bodies, unless there
      are copyin clauses.  */
@@ -4155,7 +4155,8 @@ gimple_build_cond_empty (tree cond)
 
 static void
 expand_parallel_call (struct omp_region *region, basic_block bb,
-		      gimple entry_stmt, vec<tree, va_gc> *ws_args)
+		      gimple_omp_parallel entry_stmt,
+		      vec<tree, va_gc> *ws_args)
 {
   tree t, t1, t2, val, cond, c, clauses, flags;
   gimple_stmt_iterator gsi;
@@ -4478,7 +4479,8 @@ remove_exit_barrier (struct omp_region *region)
 	     of such a variable.  */
 	  if (any_addressable_vars < 0)
 	    {
-	      gimple parallel_stmt = last_stmt (region->entry);
+	      gimple_omp_parallel parallel_stmt =
+		last_stmt (region->entry)->as_a_gimple_omp_parallel ();
 	      tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
 	      tree local_decls, block, decl;
 	      unsigned ix;
@@ -4869,7 +4871,8 @@ expand_omp_taskreg (struct omp_region *region)
 
   /* Emit a library call to launch the children threads.  */
   if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
-    expand_parallel_call (region, new_bb, entry_stmt, ws_args);
+    expand_parallel_call (region, new_bb,
+			  entry_stmt->as_a_gimple_omp_parallel (), ws_args);
   else
     expand_task_call (new_bb, entry_stmt);
   if (gimple_in_ssa_p (cfun))
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 34c399a..291dbf7 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1320,12 +1320,16 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
 	  break;
 
 	case GIMPLE_OMP_PARALLEL:
-	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
-	  copy = gimple_build_omp_parallel
-	           (s1,
-		    gimple_omp_parallel_clauses (stmt),
-		    gimple_omp_parallel_child_fn (stmt),
-		    gimple_omp_parallel_data_arg (stmt));
+	  {
+	    gimple_omp_parallel omp_par_stmt =
+	      stmt->as_a_gimple_omp_parallel ();
+	    s1 = remap_gimple_seq (gimple_omp_body (omp_par_stmt), id);
+	    copy = gimple_build_omp_parallel
+	             (s1,
+		      gimple_omp_parallel_clauses (omp_par_stmt),
+		      gimple_omp_parallel_child_fn (omp_par_stmt),
+		      gimple_omp_parallel_data_arg (omp_par_stmt));
+	  }
 	  break;
 
 	case GIMPLE_OMP_TASK:
-- 
1.8.5.3

