This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gomp] fix type mismatch problems in num_threads


        * c-parser.c (c_parser_pragma_omp_clause): Tidy.
        (c_parser_pragma_omp_clause_num_threads): Warn for not positive.
        * gimple-low.c (emit_num_threads_setup_code): Fix type problems
        with num_threads computation.

Index: c-parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parser.c,v
retrieving revision 2.17.4.16
diff -u -p -r2.17.4.16 c-parser.c
--- c-parser.c	23 Sep 2005 16:40:29 -0000	2.17.4.16
+++ c-parser.c	24 Sep 2005 17:15:29 -0000
@@ -6795,77 +6795,62 @@ c_parser_omp_directive (c_parser *parser
 static pragma_omp_clause
 c_parser_pragma_omp_clause (c_parser *parser)
 {
-  pragma_omp_clause result;
+  pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
 
   if (c_parser_next_token_is_keyword (parser, RID_IF))
-    {
-      result = PRAGMA_OMP_CLAUSE_IF;
-    }
+    result = PRAGMA_OMP_CLAUSE_IF;
   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
-    {
-      result = PRAGMA_OMP_CLAUSE_DEFAULT;
-    }
-  else if (c_parser_next_token_is_not (parser, CPP_NAME))
-    {
-      result = PRAGMA_OMP_CLAUSE_NONE;
-    }
-  else
+    result = PRAGMA_OMP_CLAUSE_DEFAULT;
+  else if (c_parser_next_token_is (parser, CPP_NAME))
     {
       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
-      if (!strcmp ("copyin", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_COPYIN;
-	}
-      if (!strcmp ("copyprivate", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
-	}
-      else if (!strcmp ("firstprivate", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
-	}
-      else if (!strcmp ("lastprivate", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
-	}
-      else if (!strcmp ("nowait", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_NOWAIT;
-	}
-      else if (!strcmp ("num_threads", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
-	}
-      else if (!strcmp ("ordered", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_ORDERED;
-	}
-      else if (!strcmp ("private", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_PRIVATE;
-	}
-      else if (!strcmp ("reduction", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_REDUCTION;
-	}
-      else if (!strcmp ("schedule", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_SCHEDULE;
-	}
-      else if (!strcmp ("shared", p))
-	{
-	  result = PRAGMA_OMP_CLAUSE_SHARED;
-	}
-      else
+
+      switch (p[0])
 	{
-	  result = PRAGMA_OMP_CLAUSE_NONE;
+	case 'c':
+	  if (!strcmp ("copyin", p))
+	    result = PRAGMA_OMP_CLAUSE_COPYIN;
+          else if (!strcmp ("copyprivate", p))
+	    result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
+	  break;
+	case 'f':
+	  if (!strcmp ("firstprivate", p))
+	    result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
+	  break;
+	case 'l':
+	  if (!strcmp ("lastprivate", p))
+	    result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
+	  break;
+	case 'n':
+	  if (!strcmp ("nowait", p))
+	    result = PRAGMA_OMP_CLAUSE_NOWAIT;
+	  else if (!strcmp ("num_threads", p))
+	    result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
+	  break;
+	case 'o':
+	  if (!strcmp ("ordered", p))
+	    result = PRAGMA_OMP_CLAUSE_ORDERED;
+	  break;
+	case 'p':
+	  if (!strcmp ("private", p))
+	    result = PRAGMA_OMP_CLAUSE_PRIVATE;
+	  break;
+	case 'r':
+	  if (!strcmp ("reduction", p))
+	    result = PRAGMA_OMP_CLAUSE_REDUCTION;
+	  break;
+	case 's':
+	  if (!strcmp ("schedule", p))
+	    result = PRAGMA_OMP_CLAUSE_SCHEDULE;
+	  else if (!strcmp ("shared", p))
+	    result = PRAGMA_OMP_CLAUSE_SHARED;
+	  break;
 	}
     }
 
   if (result != PRAGMA_OMP_CLAUSE_NONE)
-    {
-      c_parser_consume_token (parser);
-    }
+    c_parser_consume_token (parser);
+
   return result;
 }
 
@@ -7042,24 +7027,32 @@ c_parser_pragma_omp_clause_num_threads (
 {
   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     {
-      tree t = c_parser_expression (parser).value;
+      tree c, t = c_parser_expression (parser).value;
+
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
 
       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
-	c_parser_error (parser, "expected integer expression");
-      else
 	{
-	  tree c;
-
-	  /* At most one 'num_threads' clause may appear in the directive.  */
-	  for (c = curr_clause_set; c; c = TREE_CHAIN (c))
-	    if (TREE_CODE (TREE_VALUE (c)) == OMP_CLAUSE_NUM_THREADS)
-	      error ("at most one %<num_threads%> clause may appear "
-		     "in a parallel directive");
+	  c_parser_error (parser, "expected integer expression");
+	  return;
+	}
 
-	  add_new_clause (build (OMP_CLAUSE_NUM_THREADS, TREE_TYPE (t), t));
+      /* Attempt to statically determine when the number isn't positive.  */
+      c = fold_build2 (LE_EXPR, boolean_type_node, t,
+		       build_int_cst (TREE_TYPE (t), 0));
+      if (c == boolean_true_node)
+	{
+	  warning (0, "%<num_threads%> value must be positive");
+	  t = integer_one_node;
 	}
 
-      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+      /* At most one 'num_threads' clause may appear in the directive.  */
+      for (c = curr_clause_set; c; c = TREE_CHAIN (c))
+	if (TREE_CODE (TREE_VALUE (c)) == OMP_CLAUSE_NUM_THREADS)
+	  error ("at most one %<num_threads%> clause may appear "
+		 "in a parallel directive");
+
+      add_new_clause (build (OMP_CLAUSE_NUM_THREADS, TREE_TYPE (t), t));
     }
 }
 
Index: gimple-low.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimple-low.c,v
retrieving revision 2.24.4.12
diff -u -p -r2.24.4.12 gimple-low.c
--- gimple-low.c	23 Sep 2005 16:40:30 -0000	2.24.4.12
+++ gimple-low.c	24 Sep 2005 17:15:29 -0000
@@ -695,16 +695,17 @@ emit_omp_data_setup_code (tree_stmt_iter
    Returns the argument that should be passed to GOMP_parallel_start.  */
 
 static tree
-emit_num_threads_setup_code (tree_stmt_iterator *tsi, struct remap_info_d *ri_p,
+emit_num_threads_setup_code (tree_stmt_iterator *tsi,
+			     struct remap_info_d *ri_p,
 			     struct lower_data *data)
 {
   tree val, cond, c;
   tree clauses = ri_p->clauses;
 
-  /* By default, the value of NUM_THREADS is zero (selected at run
-     time) and there is no conditional.  */
+  /* By default, the value of NUM_THREADS is zero (selected at run time)
+     and there is no conditional.  */
   cond = NULL_TREE;
-  val = integer_zero_node;
+  val = build_int_cst (unsigned_type_node, 0);
 
   for (c = clauses; c; c = TREE_CHAIN (c))
     {
@@ -716,56 +717,50 @@ emit_num_threads_setup_code (tree_stmt_i
 	val = OMP_NUM_THREADS_EXPR (clause);
     }
 
-  /* If we found either of 'if (expr)' or 'num_threads (expr)',
-     create a local variable and prepare a list of statements to be
-     inserted.  */
-  if (cond || val != integer_zero_node)
-    {
-      tree t;
-      tree num_threads = create_tmp_var (unsigned_type_node, ".num_threads");
-      tree stmt_list = alloc_stmt_list ();
+  /* If we found either of 'if (expr)' or 'num_threads (expr)', create a
+     local variable and prepare a list of statements to be inserted.  */
+  if (cond
+      || !is_gimple_val (val)
+      || !lang_hooks.types_compatible_p (unsigned_type_node, TREE_TYPE (val)))
+    {
+      tree stmt_list = NULL, num_threads;
+      enum gimplify_status gs;
 
-      if (cond)
-	{
-	  /* If we found the clause 'if (cond)', build the
-	     conditional:
+      /* Ensure 'val' is of the correct type.  */
+      val = fold_convert (unsigned_type_node, val);
 
-	     	if (cond)
-		  .num_threads = val
-		else
-		  .num_threads = 1  */
-	  t = build (COND_EXPR, void_type_node, cond, 
-		     build (MODIFY_EXPR, void_type_node, num_threads, val),
-		     build (MODIFY_EXPR, void_type_node, num_threads,
-			    integer_one_node));
-	  append_to_statement_list (t, &stmt_list);
-	}
-      else
+      /* If we found the clause 'if (cond)', build either
+	 (unsigned int)(cond) or (cond ? val : 1u).  */
+      if (cond)
 	{
-	  gcc_assert (val != integer_zero_node);
-
-	  /* Otherwise, if we found a num_threads clause with anything
-	     other than zero, assign that value to .num_threads:
-	     .num_threads = val  */
-	  t = build (MODIFY_EXPR, unsigned_type_node, num_threads, val);
-	  append_to_statement_list (t, &stmt_list);
+	  if (integer_zerop (val))
+	    val = fold_convert (unsigned_type_node, cond);
+	  else
+	    val = build3 (COND_EXPR, unsigned_type_node, cond, val,
+			  build_int_cst (unsigned_type_node, 1));
 	}
 
-      /* Gimplify and lower the emitted code.  This is necessary
-	 mostly for COND and VAL, which can be arbitrary expressions.  */
+      /* Gimplify and lower the emitted code.  This is necessary mostly
+	 for COND and VAL, which can be arbitrary expressions.  */
       push_gimplify_context ();
-      gimplify_stmt (&stmt_list);
+      num_threads = val;
+      gs = gimplify_expr (&num_threads, &stmt_list, NULL,
+			  is_gimple_val, fb_rvalue);
       pop_gimplify_context (NULL);
-      lower_stmt_body (stmt_list, data);
 
-      tsi_link_after (tsi, stmt_list, TSI_CONTINUE_LINKING);
+      if (stmt_list)
+	{
+	  lower_stmt_body (stmt_list, data);
+	  tsi_link_after (tsi, stmt_list, TSI_CONTINUE_LINKING);
+	}
 
-      return num_threads;
+      if (gs == GS_ALL_DONE)
+	val = num_threads;
+      else
+	val = build_int_cst (unsigned_type_node, 0);
     }
 
-  /* Otherwise, just return zero to specify that the number of threads
-     should be selected at runtime.  */
-  return integer_zero_node;
+  return val;
 }
 
 
Index: testsuite/gcc.dg/gomp/num-threads-1.c
===================================================================
RCS file: testsuite/gcc.dg/gomp/num-threads-1.c
diff -N testsuite/gcc.dg/gomp/num-threads-1.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.dg/gomp/num-threads-1.c	24 Sep 2005 17:27:02 -0000
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+extern void bar(void);
+void foo(void)
+{
+  #pragma omp parallel num_threads (0)	/* { dg-warning "must be positive" } */
+    {
+      bar ();
+    }
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]