On 10/11/2013 04:12 AM, Richard Biener wrote:
On Fri, Oct 11, 2013 at 5:31 AM, Andrew MacLeod <amacl...@redhat.com> wrote:
Missed a bit in tree-flow.h.. I mistakenly assumed omp_region belonged
there :-P
Anyway by moving struct omp_region into omp_low.h, along with the prototypes
from tree-flow.h, gimple.h and tree.h. Everything works great with just a
few files actually requiring omp-low.h.
AS an extra bonus, omp-low.c was *exporting* "struct omp_region
*root_omp_region". tree-cfg.c was checking it for non-null and calling
free_omp_regions(). Well, free_omp_regions works just fine will a NULL
root_omp_region (basically does nothing and returns), so exporting it just
for that one check seems nonsensical. Its now static.
Bootstraps (will really-all languages) on x86_64-unknown-linux-gnu with no
new regressions. also stage 1 cross builds on rs6000 and mips. No more of
that crap :-)
OK?
Here's the new reworked version after Jakub's merge.
Couple of extra things. well, 3 :-)
1 - The entire omp_region structure was being exported for tree-cfg to
use, and it was used in a single routine.. make_edges. I split out the
GIMPLE_OMP clauses from that switch, and put them into a function in
omp-low.c for make_edges to call. Now the structure contents are
private to omp-low.c which I think is better.
2 - A few extra front end files are now using find_omp_clause() and thus
need omp-low.h. A couple of them do not understand gimple (nor should
they). They didn't even know what "enum gimple_code" was and failed to
compile both struct omp_region (which has an enum gimple_code), as well
as one or two of the prototypes. Item 1) solved the struct issue, but I
still needed to avoid 'enum gimple_code' in the prototypes, which is why
make_gimple_omp_edges doesn't pass in the code, rather it picks it up
from the last gimple_stmt of the basic block. pretty easy. I folowed
the naming convention used for make_gimple_asm_edges().
3 - omp-low was also exporting copy_var_decl with tree-cfg.c as the only
current consumer. It is actually a very generic tree routine, but
since its only used in these gimple contexts, I moved it to gimple.c so
I wont have to duplicate it later when I do the wrappers. It will likely
become a method within the gimple_var_decl object, so it seemed
reasonable to put it in gimple.c for now. omp-low.c doesn't seem like
the right place to leave it.
Bootstraps on 86_64-unknown-linux-gnu and no new regressions. OK?
Andrew
* tree-flow.h (struct omp_region): Move to omp-low.c
Remove omp_ prototypes and variables.
* gimple.h (omp_reduction_init): Move prototype to omp-low.h.
(copy_var_decl): Relocate prototype from tree-flow.h.
* gimple.c (copy_var_decl): Relocate from omp-low.c.
* tree.h: Move prototype to omp-low.h.
* omp-low.h: New File. Relocate prototypes here.
* omp-low.c (struct omp_region): Make local here.
(root_omp_region): Make static.
(copy_var_decl) Move to gimple.c.
(new_omp_region): Make static.
(make_gimple_omp_edges): New. Refactored from tree-cfg.c make_edges.
* tree-cfg.c: Include omp-low.h.
(make_edges): Factor out OMP specific bits to make_gimple_omp_edges.
* gimplify.c: Include omp-low.h.
* tree-parloops.c: Include omp-low.h.
c
* c-parser.c: Include omp-low.h.
* c-typeck.c: Include omp-low.h.
cp
* parser.c: Include omp-low.h.
* semantics.c: Include omp-low.h.
fortran
* trans-openmp.c: Include omp-low.h.
Index: tree-flow.h
===================================================================
*** tree-flow.h (revision 203625)
--- tree-flow.h (working copy)
*************** along with GCC; see the file COPYING3.
*** 37,92 ****
#include "tree-into-ssa.h"
#include "tree-ssa-loop.h"
- /*---------------------------------------------------------------------------
- OpenMP Region Tree
- ---------------------------------------------------------------------------*/
-
- /* Parallel region information. Every parallel and workshare
- directive is enclosed between two markers, the OMP_* directive
- and a corresponding OMP_RETURN statement. */
-
- struct omp_region
- {
- /* The enclosing region. */
- struct omp_region *outer;
-
- /* First child region. */
- struct omp_region *inner;
-
- /* Next peer region. */
- struct omp_region *next;
-
- /* Block containing the omp directive as its last stmt. */
- basic_block entry;
-
- /* Block containing the OMP_RETURN as its last stmt. */
- basic_block exit;
-
- /* Block containing the OMP_CONTINUE as its last stmt. */
- basic_block cont;
-
- /* If this is a combined parallel+workshare region, this is a list
- of additional arguments needed by the combined parallel+workshare
- library call. */
- vec<tree, va_gc> *ws_args;
-
- /* The code for the omp directive of this region. */
- enum gimple_code type;
-
- /* Schedule kind, only used for OMP_FOR type regions. */
- enum omp_clause_schedule_kind sched_kind;
-
- /* True if this is a combined parallel+workshare region. */
- bool is_combined_parallel;
- };
-
- extern struct omp_region *root_omp_region;
- extern struct omp_region *new_omp_region (basic_block, enum gimple_code,
- struct omp_region *);
- extern void free_omp_regions (void);
- void omp_expand_local (basic_block);
- tree copy_var_decl (tree, tree, tree);
-
/* Location to track pending stmt for edge insertion. */
#define PENDING_STMT(e) ((e)->insns.g)
--- 37,42 ----
Index: gimple.h
===================================================================
*** gimple.h (revision 203625)
--- gimple.h (working copy)
*************** extern tree canonicalize_cond_expr_cond
*** 1086,1094 ****
extern void dump_decl_set (FILE *, bitmap);
extern bool gimple_can_coalesce_p (tree, tree);
extern bool nonfreeing_call_p (gimple);
!
! /* In omp-low.c. */
! extern tree omp_reduction_init (tree, tree);
/* In trans-mem.c. */
extern void diagnose_tm_safe_errors (tree);
--- 1086,1092 ----
extern void dump_decl_set (FILE *, bitmap);
extern bool gimple_can_coalesce_p (tree, tree);
extern bool nonfreeing_call_p (gimple);
! extern tree copy_var_decl (tree, tree, tree);
/* In trans-mem.c. */
extern void diagnose_tm_safe_errors (tree);
Index: gimple.c
===================================================================
*** gimple.c (revision 203625)
--- gimple.c (working copy)
*************** nonfreeing_call_p (gimple call)
*** 4063,4065 ****
--- 4063,4086 ----
return false;
}
+
+ /* Create a new VAR_DECL and copy information from VAR to it. */
+
+ tree
+ copy_var_decl (tree var, tree name, tree type)
+ {
+ tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
+
+ TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
+ TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
+ DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
+ DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
+ DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
+ DECL_CONTEXT (copy) = DECL_CONTEXT (var);
+ TREE_NO_WARNING (copy) = TREE_NO_WARNING (var);
+ TREE_USED (copy) = 1;
+ DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
+ DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var);
+
+ return copy;
+ }
Index: tree.h
===================================================================
*** tree.h (revision 203625)
--- tree.h (working copy)
*************** extern tree build_translation_unit_decl
*** 3553,3559 ****
extern tree build_block (tree, tree, tree, tree);
extern tree build_empty_stmt (location_t);
extern tree build_omp_clause (location_t, enum omp_clause_code);
- extern tree find_omp_clause (tree, enum omp_clause_code);
extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL);
#define build_vl_exp(c, n) build_vl_exp_stat (c, n MEM_STAT_INFO)
--- 3553,3558 ----
Index: omp-low.h
===================================================================
*** omp-low.h (revision 0)
--- omp-low.h (working copy)
***************
*** 0 ****
--- 1,31 ----
+ /* Header file for openMP lowering directives.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3, or (at your option) any later
+ version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+ #ifndef GCC_OMP_LOW_H
+ #define GCC_OMP_LOW_H
+
+ struct omp_region;
+
+ extern tree find_omp_clause (tree, enum omp_clause_code);
+ extern void omp_expand_local (basic_block);
+ extern void free_omp_regions (void);
+ extern tree omp_reduction_init (tree, tree);
+ extern bool make_gimple_omp_edges (basic_block bb, struct omp_region **region);
+
+ #endif /* GCC_OMP_LOW_H */
Index: omp-low.c
===================================================================
*** omp-low.c (revision 203625)
--- omp-low.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 43,48 ****
--- 43,49 ----
#include "optabs.h"
#include "cfgloop.h"
#include "target.h"
+ #include "omp-low.h"
/* Lowering of OpenMP parallel and workshare constructs proceeds in two
*************** along with GCC; see the file COPYING3.
*** 56,61 ****
--- 57,101 ----
scanned for parallel regions which are then moved to a new
function, to be invoked by the thread library. */
+ /* Parallel region information. Every parallel and workshare
+ directive is enclosed between two markers, the OMP_* directive
+ and a corresponding OMP_RETURN statement. */
+
+ struct omp_region
+ {
+ /* The enclosing region. */
+ struct omp_region *outer;
+
+ /* First child region. */
+ struct omp_region *inner;
+
+ /* Next peer region. */
+ struct omp_region *next;
+
+ /* Block containing the omp directive as its last stmt. */
+ basic_block entry;
+
+ /* Block containing the OMP_RETURN as its last stmt. */
+ basic_block exit;
+
+ /* Block containing the OMP_CONTINUE as its last stmt. */
+ basic_block cont;
+
+ /* If this is a combined parallel+workshare region, this is a list
+ of additional arguments needed by the combined parallel+workshare
+ library call. */
+ vec<tree, va_gc> *ws_args;
+
+ /* The code for the omp directive of this region. */
+ enum gimple_code type;
+
+ /* Schedule kind, only used for OMP_FOR type regions. */
+ enum omp_clause_schedule_kind sched_kind;
+
+ /* True if this is a combined parallel+workshare region. */
+ bool is_combined_parallel;
+ };
+
/* Context structure. Used to store information about each parallel
directive in the code. */
*************** struct omp_for_data
*** 135,141 ****
static splay_tree all_contexts;
static int taskreg_nesting_level;
static int target_nesting_level;
! struct omp_region *root_omp_region;
static bitmap task_shared_vars;
static void scan_omp (gimple_seq *, omp_context *);
--- 175,181 ----
static splay_tree all_contexts;
static int taskreg_nesting_level;
static int target_nesting_level;
! static struct omp_region *root_omp_region;
static bitmap task_shared_vars;
static void scan_omp (gimple_seq *, omp_context *);
*************** use_pointer_for_field (tree decl, omp_co
*** 872,898 ****
return false;
}
- /* Create a new VAR_DECL and copy information from VAR to it. */
-
- tree
- copy_var_decl (tree var, tree name, tree type)
- {
- tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
-
- TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
- TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
- DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
- DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
- DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
- DECL_CONTEXT (copy) = DECL_CONTEXT (var);
- TREE_NO_WARNING (copy) = TREE_NO_WARNING (var);
- TREE_USED (copy) = 1;
- DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
- DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var);
-
- return copy;
- }
-
/* Construct a new automatic decl similar to VAR. */
static tree
--- 912,917 ----
*************** debug_all_omp_regions (void)
*** 1219,1225 ****
/* Create a new parallel region starting at STMT inside region PARENT. */
! struct omp_region *
new_omp_region (basic_block bb, enum gimple_code type,
struct omp_region *parent)
{
--- 1238,1244 ----
/* Create a new parallel region starting at STMT inside region PARENT. */
! static struct omp_region *
new_omp_region (basic_block bb, enum gimple_code type,
struct omp_region *parent)
{
*************** diagnose_sb_2 (gimple_stmt_iterator *gsi
*** 10312,10317 ****
--- 10331,10451 ----
return NULL_TREE;
}
+ /* Called from tree-cfg.c::make_edges to create cfg edges for all GIMPLE_OMP
+ codes. */
+ bool
+ make_gimple_omp_edges (basic_block bb, struct omp_region **region)
+ {
+ gimple last = last_stmt (bb);
+ enum gimple_code code = gimple_code (last);
+ struct omp_region *cur_region = *region;
+ bool fallthru = false;
+
+ switch (code)
+ {
+ case GIMPLE_OMP_PARALLEL:
+ case GIMPLE_OMP_TASK:
+ case GIMPLE_OMP_FOR:
+ case GIMPLE_OMP_SINGLE:
+ case GIMPLE_OMP_TEAMS:
+ case GIMPLE_OMP_MASTER:
+ case GIMPLE_OMP_TASKGROUP:
+ case GIMPLE_OMP_ORDERED:
+ case GIMPLE_OMP_CRITICAL:
+ case GIMPLE_OMP_SECTION:
+ cur_region = new_omp_region (bb, code, cur_region);
+ fallthru = true;
+ break;
+
+ case GIMPLE_OMP_TARGET:
+ cur_region = new_omp_region (bb, code, cur_region);
+ fallthru = true;
+ if (gimple_omp_target_kind (last) == GF_OMP_TARGET_KIND_UPDATE)
+ cur_region = cur_region->outer;
+ break;
+
+ case GIMPLE_OMP_SECTIONS:
+ cur_region = new_omp_region (bb, code, cur_region);
+ fallthru = true;
+ break;
+
+ case GIMPLE_OMP_SECTIONS_SWITCH:
+ fallthru = false;
+ break;
+
+ case GIMPLE_OMP_ATOMIC_LOAD:
+ case GIMPLE_OMP_ATOMIC_STORE:
+ fallthru = true;
+ break;
+
+ case GIMPLE_OMP_RETURN:
+ /* In the case of a GIMPLE_OMP_SECTION, the edge will go
+ somewhere other than the next block. This will be
+ created later. */
+ cur_region->exit = bb;
+ fallthru = cur_region->type != GIMPLE_OMP_SECTION;
+ cur_region = cur_region->outer;
+ break;
+
+ case GIMPLE_OMP_CONTINUE:
+ cur_region->cont = bb;
+ switch (cur_region->type)
+ {
+ case GIMPLE_OMP_FOR:
+ /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
+ succs edges as abnormal to prevent splitting
+ them. */
+ single_succ_edge (cur_region->entry)->flags |= EDGE_ABNORMAL;
+ /* Make the loopback edge. */
+ make_edge (bb, single_succ (cur_region->entry),
+ EDGE_ABNORMAL);
+
+ /* Create an edge from GIMPLE_OMP_FOR to exit, which
+ corresponds to the case that the body of the loop
+ is not executed at all. */
+ make_edge (cur_region->entry, bb->next_bb, EDGE_ABNORMAL);
+ make_edge (bb, bb->next_bb, EDGE_FALLTHRU | EDGE_ABNORMAL);
+ fallthru = false;
+ break;
+
+ case GIMPLE_OMP_SECTIONS:
+ /* Wire up the edges into and out of the nested sections. */
+ {
+ basic_block switch_bb = single_succ (cur_region->entry);
+
+ struct omp_region *i;
+ for (i = cur_region->inner; i ; i = i->next)
+ {
+ gcc_assert (i->type == GIMPLE_OMP_SECTION);
+ make_edge (switch_bb, i->entry, 0);
+ make_edge (i->exit, bb, EDGE_FALLTHRU);
+ }
+
+ /* Make the loopback edge to the block with
+ GIMPLE_OMP_SECTIONS_SWITCH. */
+ make_edge (bb, switch_bb, 0);
+
+ /* Make the edge from the switch to exit. */
+ make_edge (switch_bb, bb->next_bb, 0);
+ fallthru = false;
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (*region != cur_region)
+ *region = cur_region;
+
+ return fallthru;
+ }
+
static unsigned int
diagnose_omp_structured_block_errors (void)
{
Index: tree-cfg.c
===================================================================
*** tree-cfg.c (revision 203625)
--- tree-cfg.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 42,47 ****
--- 42,48 ----
#include "tree-inline.h"
#include "target.h"
#include "tree-ssa-live.h"
+ #include "omp-low.h"
/* This file contains functions for building the Control Flow Graph (CFG)
for a function tree. */
*************** make_edges (void)
*** 607,703 ****
fallthru = true;
break;
! case GIMPLE_OMP_PARALLEL:
! case GIMPLE_OMP_TASK:
! case GIMPLE_OMP_FOR:
! case GIMPLE_OMP_SINGLE:
! case GIMPLE_OMP_TEAMS:
! case GIMPLE_OMP_MASTER:
! case GIMPLE_OMP_TASKGROUP:
! case GIMPLE_OMP_ORDERED:
! case GIMPLE_OMP_CRITICAL:
! case GIMPLE_OMP_SECTION:
! cur_region = new_omp_region (bb, code, cur_region);
! fallthru = true;
! break;
!
! case GIMPLE_OMP_TARGET:
! cur_region = new_omp_region (bb, code, cur_region);
! fallthru = true;
! if (gimple_omp_target_kind (last) == GF_OMP_TARGET_KIND_UPDATE)
! cur_region = cur_region->outer;
! break;
!
! case GIMPLE_OMP_SECTIONS:
! cur_region = new_omp_region (bb, code, cur_region);
! fallthru = true;
! break;
!
! case GIMPLE_OMP_SECTIONS_SWITCH:
! fallthru = false;
! break;
!
! case GIMPLE_OMP_ATOMIC_LOAD:
! case GIMPLE_OMP_ATOMIC_STORE:
! fallthru = true;
! break;
!
! case GIMPLE_OMP_RETURN:
! /* In the case of a GIMPLE_OMP_SECTION, the edge will go
! somewhere other than the next block. This will be
! created later. */
! cur_region->exit = bb;
! fallthru = cur_region->type != GIMPLE_OMP_SECTION;
! cur_region = cur_region->outer;
! break;
!
! case GIMPLE_OMP_CONTINUE:
! cur_region->cont = bb;
! switch (cur_region->type)
! {
! case GIMPLE_OMP_FOR:
! /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
! succs edges as abnormal to prevent splitting
! them. */
! single_succ_edge (cur_region->entry)->flags |= EDGE_ABNORMAL;
! /* Make the loopback edge. */
! make_edge (bb, single_succ (cur_region->entry),
! EDGE_ABNORMAL);
!
! /* Create an edge from GIMPLE_OMP_FOR to exit, which
! corresponds to the case that the body of the loop
! is not executed at all. */
! make_edge (cur_region->entry, bb->next_bb, EDGE_ABNORMAL);
! make_edge (bb, bb->next_bb, EDGE_FALLTHRU | EDGE_ABNORMAL);
! fallthru = false;
! break;
!
! case GIMPLE_OMP_SECTIONS:
! /* Wire up the edges into and out of the nested sections. */
! {
! basic_block switch_bb = single_succ (cur_region->entry);
!
! struct omp_region *i;
! for (i = cur_region->inner; i ; i = i->next)
! {
! gcc_assert (i->type == GIMPLE_OMP_SECTION);
! make_edge (switch_bb, i->entry, 0);
! make_edge (i->exit, bb, EDGE_FALLTHRU);
! }
!
! /* Make the loopback edge to the block with
! GIMPLE_OMP_SECTIONS_SWITCH. */
! make_edge (bb, switch_bb, 0);
!
! /* Make the edge from the switch to exit. */
! make_edge (switch_bb, bb->next_bb, 0);
! fallthru = false;
! }
! break;
!
! default:
! gcc_unreachable ();
! }
break;
case GIMPLE_TRANSACTION:
--- 608,615 ----
fallthru = true;
break;
! CASE_GIMPLE_OMP:
! fallthru = make_gimple_omp_edges (bb, &cur_region);
break;
case GIMPLE_TRANSACTION:
*************** make_edges (void)
*** 721,728 ****
make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
}
! if (root_omp_region)
! free_omp_regions ();
/* Fold COND_EXPR_COND of each COND_EXPR. */
fold_cond_expr_cond ();
--- 633,639 ----
make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
}
! free_omp_regions ();
/* Fold COND_EXPR_COND of each COND_EXPR. */
fold_cond_expr_cond ();
Index: gimplify.c
===================================================================
*** gimplify.c (revision 203625)
--- gimplify.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 42,47 ****
--- 42,48 ----
#include "pointer-set.h"
#include "splay-tree.h"
#include "vec.h"
+ #include "omp-low.h"
#include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
#include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
Index: tree-parloops.c
===================================================================
*** tree-parloops.c (revision 203625)
--- tree-parloops.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 32,37 ****
--- 32,38 ----
#include "tree-vectorizer.h"
#include "tree-hasher.h"
#include "tree-parloops.h"
+ #include "omp-low.h"
/* This pass tries to distribute iterations of loops into several threads.
The implementation is straightforward -- for each loop we test whether its
Index: c/c-parser.c
===================================================================
*** c/c-parser.c (revision 203625)
--- c/c-parser.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 55,60 ****
--- 55,61 ----
#include "target.h"
#include "cgraph.h"
#include "plugin.h"
+ #include "omp-low.h"
/* Initialization routine for this file. */
Index: c/c-typeck.c
===================================================================
*** c/c-typeck.c (revision 203625)
--- c/c-typeck.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 38,43 ****
--- 38,44 ----
#include "bitmap.h"
#include "gimple.h"
#include "tree-inline.h"
+ #include "omp-low.h"
#include "c-family/c-objc.h"
#include "c-family/c-common.h"
#include "c-family/c-ubsan.h"
Index: cp/parser.c
===================================================================
*** cp/parser.c (revision 203625)
--- cp/parser.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 39,44 ****
--- 39,45 ----
#include "tree-pretty-print.h"
#include "parser.h"
#include "type-utils.h"
+ #include "omp-low.h"
/* The lexer. */
Index: cp/semantics.c
===================================================================
*** cp/semantics.c (revision 203625)
--- cp/semantics.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 44,49 ****
--- 44,50 ----
#include "gimple.h"
#include "bitmap.h"
#include "hash-table.h"
+ #include "omp-low.h"
static bool verify_constant (tree, bool, bool *, bool *);
#define VERIFY_CONSTANT(X) \
Index: fortran/trans-openmp.c
===================================================================
*** fortran/trans-openmp.c (revision 203625)
--- fortran/trans-openmp.c (working copy)
*************** along with GCC; see the file COPYING3.
*** 32,37 ****
--- 32,38 ----
#include "trans-array.h"
#include "trans-const.h"
#include "arith.h"
+ #include "omp-low.h"
int ompws_flags;