[gomp] structured blocks, part trey
Richard Henderson
rth@redhat.com
Thu Oct 20 10:03:00 GMT 2005
The C++ part of the OpenMP spec has rules about exceptions and
how they may propagate. While obviously we cannot diagnose these
at compile-time, we can certainly force the program to die if it
violates them.
So I wrap all of the grammar elements that say "structured-block"
with a MUST_NOT_THROW. Which means that violations proceed to
std::terminate, ne'er to return.
r~
* semantics.c (begin_omp_structured_block): New.
(finish_omp_structured_block): New.
(begin_omp_parallel, finish_omp_parallel): Use them.
* parser.c (cp_parser_omp_structured_block): Likewise.
(cp_parser_omp_for): Likewise.
(cp_parser_omp_sections_scope): Likewise.
* cp-tree.h: Declare them.
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1144.4.11
diff -u -p -d -r1.1144.4.11 cp-tree.h
--- cp/cp-tree.h 19 Oct 2005 09:44:07 -0000 1.1144.4.11
+++ cp/cp-tree.h 20 Oct 2005 09:50:08 -0000
@@ -4236,6 +4236,8 @@ extern void finalize_nrv (tree *, tree
extern void note_decl_for_pch (tree);
extern tree finish_omp_clauses (tree);
extern void finish_omp_threadprivate (tree);
+extern tree begin_omp_structured_block (void);
+extern tree finish_omp_structured_block (tree);
extern tree begin_omp_parallel (void);
extern tree finish_omp_parallel (tree, tree);
extern tree finish_omp_for (location_t, tree, tree,
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.340.4.15
diff -u -p -d -r1.340.4.15 parser.c
--- cp/parser.c 20 Oct 2005 09:02:10 -0000 1.340.4.15
+++ cp/parser.c 20 Oct 2005 09:50:11 -0000
@@ -18013,9 +18013,9 @@ cp_parser_omp_all_clauses (cp_parser *pa
static tree
cp_parser_omp_structured_block (cp_parser *parser)
{
- tree stmt = push_stmt_list ();
+ tree stmt = begin_omp_structured_block ();
cp_parser_statement (parser, NULL_TREE, false);
- return pop_stmt_list (stmt);
+ return finish_omp_structured_block (stmt);
}
/* OpenMP 2.5:
@@ -18255,6 +18255,8 @@ cp_parser_omp_for_loop (cp_parser *parse
in_iteration_statement_p = parser->in_iteration_statement_p;
parser->in_iteration_statement_p = true;
+ /* Note that the grammar doesn't call for a structured block here,
+ though the loop as a whole is a structured block. */
body = push_stmt_list ();
cp_parser_statement (parser, NULL_TREE, false);
body = pop_stmt_list (body);
@@ -18281,15 +18283,19 @@ cp_parser_omp_for_loop (cp_parser *parse
static tree
cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok)
{
- tree block, clauses, ret;
+ tree block, clauses, sb, ret;
clauses = cp_parser_omp_all_clauses (parser, OMP_FOR_CLAUSE_MASK,
"#pragma omp for", pragma_tok);
block = begin_compound_stmt (0);
+ sb = begin_omp_structured_block ();
+
ret = cp_parser_omp_for_loop (parser);
if (ret)
OMP_FOR_CLAUSES (ret) = clauses;
+
+ add_stmt (finish_omp_structured_block (sb));
finish_compound_stmt (block);
return ret;
@@ -18342,7 +18348,7 @@ cp_parser_omp_sections_scope (cp_parser
if (cp_lexer_peek_token (parser->lexer)->pragma_kind != PRAGMA_OMP_SECTION)
{
- substmt = push_stmt_list ();
+ substmt = begin_omp_structured_block ();
while (1)
{
@@ -18357,7 +18363,7 @@ cp_parser_omp_sections_scope (cp_parser
break;
}
- substmt = pop_stmt_list (substmt);
+ substmt = finish_omp_structured_block (substmt);
substmt = build1 (OMP_SECTION, void_type_node, substmt);
add_stmt (substmt);
}
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.475.4.11
diff -u -p -d -r1.475.4.11 semantics.c
--- cp/semantics.c 19 Oct 2005 23:33:59 -0000 1.475.4.11
+++ cp/semantics.c 20 Oct 2005 09:50:12 -0000
@@ -3541,36 +3541,58 @@ finish_omp_threadprivate (tree vars)
}
}
+/* Build a structured block. Mostly we just want to wrap the thing
+ in a MUST_NOT_THROW_EXPR, which will enforce the constraint in
+ OpenMP 2.5 section 1.2.2 that throw may not violate the entry/exit
+ criteria of the structured block. That is, an exception thrown
+ within the block must be caught within the block. */
+
+tree
+begin_omp_structured_block (void)
+{
+ return push_stmt_list ();
+}
+
+tree
+finish_omp_structured_block (tree block)
+{
+ return build1 (MUST_NOT_THROW_EXPR, void_type_node, pop_stmt_list (block));
+}
+
/* Like c_begin_compound_stmt, except force the retension of the BLOCK. */
tree
begin_omp_parallel (void)
{
- tree outer, inner;
- outer = push_stmt_list ();
+ tree l1, l2, l3;
+
keep_next_level (true);
- inner = begin_compound_stmt (0);
+ l1 = push_stmt_list ();
+ l2 = begin_compound_stmt (0);
+ l3 = begin_omp_structured_block ();
- /* In order to pass two values to finish_omp_parallel without extra
+ /* In order to pass three values to finish_omp_parallel without extra
complication in the interface here, wrap them in a cons node. */
- return tree_cons (outer, inner, NULL);
+ return tree_cons (l1, l2, l3);
}
tree
finish_omp_parallel (tree clauses, tree cons)
{
- tree stmt, outer, inner;
+ tree stmt, l1, l2, l3;
- outer = TREE_PURPOSE (cons);
- inner = TREE_VALUE (cons);
+ l1 = TREE_PURPOSE (cons);
+ l2 = TREE_VALUE (cons);
+ l3 = TREE_CHAIN (cons);
- finish_compound_stmt (inner);
- outer = pop_stmt_list (outer);
+ add_stmt (finish_omp_structured_block (l3));
+ finish_compound_stmt (l2);
+ l1 = pop_stmt_list (l1);
stmt = make_node (OMP_PARALLEL);
TREE_TYPE (stmt) = void_type_node;
OMP_PARALLEL_CLAUSES (stmt) = clauses;
- OMP_PARALLEL_BODY (stmt) = outer;
+ OMP_PARALLEL_BODY (stmt) = l1;
return add_stmt (stmt);
}
Index: testsuite/g++.dg/gomp/block-1.C
===================================================================
RCS file: testsuite/g++.dg/gomp/block-1.C
diff -N testsuite/g++.dg/gomp/block-1.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/gomp/block-1.C 20 Oct 2005 09:50:12 -0000
@@ -0,0 +1,32 @@
+// { dg-do compile }
+// { dg-options "-fopenmp -fdump-tree-gimple" }
+
+void bar();
+void foo()
+{
+ #pragma omp critical
+ bar ();
+ #pragma omp master
+ bar ();
+ #pragma omp single
+ bar ();
+ #pragma omp for
+ for (int i = 0; i < 10; ++i)
+ bar ();
+ #pragma omp sections
+ { bar(); }
+ #pragma omp parallel
+ bar ();
+ #pragma omp parallel for
+ for (int i = 0; i < 10; ++i)
+ bar ();
+ #pragma omp parallel sections
+ {
+ bar ();
+ bar ();
+ #pragma omp section
+ bar ();
+ }
+}
+
+// { dg-final { scan-tree-dump-times "terminate" 10 "gimple" } }
More information about the Gcc-patches
mailing list