OSDN Git Service

2006-01-18 Richard Henderson <rth@redhat.com>
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 18 Jan 2006 19:21:25 +0000 (19:21 +0000)
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 18 Jan 2006 19:21:25 +0000 (19:21 +0000)
    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

* libgomp: New directory.
* Makefile.def: Add target_module libgomp.
* Makefile.in: Regenerate.
* configure.in (target_libraries): Add target-libgomp.
* configure: Regenerate.

contrib/

2006-01-18  Richard Henderson  <rth@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

* gcc_update (files_and_dependencies): Add libgomp files.

gcc/

2006-01-18  Richard Henderson  <rth@redhat.com>
            Aldy Hernandez  <aldyh@redhat.com>
    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

* omp-low.c: New file.
* c-omp.c: New file.

2006-01-18  Richard Henderson  <rth@redhat.com>
    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

* doc/invoke.texi: Document -fopenmp.
* tree-dump.h (debug_function): Declare.

* hooks.c (hook_bool_tree_bool_false): New function.
(hook_tree_tree_null): Remove.
(hook_tree_tree_tree_null): New.
* hooks.h: Update to match.

* tree-pretty-print.c (debug_tree_chain): New.
(print_generic_expr): Handle TDF_CHAIN.
(dump_generic_node): Handle BLOCK.
Do not abort with incomplete SWITCH_EXPRs.
Do not dump body of an OpenMP directive if TDF_SLIM is given.
<case OMP_PARALLEL, OMP_FOR, OMP_SECTIONS>: Don't
print space after directive name.
<OMP_FOR>: Handle printing OMP_FOR_PRE_BODY.
Handle OMP_MASTER and OMP_ORDERED.
Handle printing of OMP_BODY just in one place, goto
dump_omp_body in the rest of OMP_* nodes that have
OMP_BODY.
Don't handle clause nodes here.  Update omp statements to
use dump_omp_clauses.
Handle OMP_SINGLE, OMP_SECTIONS, OMP_SECTION,
OMP_CLAUSE_ORDERED, OMP_CLAUSE_SCHEDULE, OMP_ATOMIC,
OMP_CRITICAL, OMP_CLAUSE_NOWAIT, GOMP_CLAUSE_IF,
GOMP_CLAUSE_NUM_THREADS, GOMP_FOR, GOMP_CLAUSE_SHARED,
GOMP_CLAUSE_FIRSTPRIVATE, GOMP_CLAUSE_LASTPRIVATE,
GOMP_CLAUSE_COPYIN and GOMP_CLAUSE_COPYPRIVATE.
Adjust output for GOMP_PARALLEL.
(dump_omp_clauses): New.
(print_declaration): Dump DECL_VALUE_EXPR.
(op_symbol_1): Split out of op_symbol.
(dumping_stmts): Remove.  Update all users.

* cgraph.c (cgraph_analyze_queue): New.
(cgraph_add_new_function): New.
* cgraph.h (cgraph_analyze_queue): Declare.
(cgraph_add_new_function): Declare.
(cgraph_lower_function): Remove.

* tree.c (walk_tree): Walk OMP_CLAUSE_CHAIN of OMP_CLAUSE_*
nodes.  Use switch for all nodes, handle most of IS_EXPR_CODE_CLASS
and TYPE_P nodes in its default clause.
(empty_body_p): New.
(tree_range_check_failed): New.
(build5_stat): New.

* tree.h (OMP_CLAUSE_REDUCTION_INIT,
OMP_CLAUSE_REDUCTION_MERGE,
OMP_CLAUSE_REDUCTION_PLACEHOLDER,
OMP_CLAUSE_PRIVATE_DEBUG,
OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE, OMP_FOR_PRE_BODY,
OMP_MASTER_BODY, OMP_ORDERED_BODY OMP_BODY,
OMP_CLAUSES, OMP_CLAUSE_DECL, OMP_CLAUSE_DEFAULT_KIND,
OMP_CLAUSE_CHAIN, OMP_CLAUSE_OUTER_DECL,
OMP_CLAUSE_INNER_DECL, OMP_CLAUSE_NUM_THREADS_EXPR,
OMP_CLAUSE_IF_EXPR, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR,
OMP_CLAUSE_SCHEDULE_CHUNK_SIZE. OMP_PARALLEL_VAR_INIT,
OMP_PARALLEL_VAR_REDUC, OMP_FOR_VAR_INIT,
OMP_FOR_VAR_LAST, OMP_FOR_VAR_REDUC,
OMP_SECTIONS_VAR_INIT, OMP_SECTIONS_VAR_LAST,
OMP_SECTIONS_VAR_REDUC, OMP_CLAUSE_REDUCTION_CODE
OMP_SINGLE_CLAUSES, OMP_SINGLE_BODY,
OMP_CLAUSE_SCHEDULE_CHUNK_SIZE, OMP_SECTION_BODY,
OMP_CRITICAL_NAME, OMP_CRITICAL_BODY): New.
(TREE_RANGE_CHECK): New.
(empty_body_p): Declare.
(enum omp_clause_default_kind): New.
(build_string_literal): Declare.
(enum omp_clause_schedule_kind, OMP_CLAUSE_SCHEDULE_KIND): New.
(build5_stat, build5): Declare.

* tree-pass.h (TDF_CHAIN): Define.
* tree-pass.h (PROP_gimple_lomp): Define.
(pass_lower_omp): Declare.

* diagnostic.h (debug_tree_chain): Declare.

* builtins.c (get_builtin_sync_mode): Use 0 as last argument to
mode_for_size.
(expand_builtin): Handle sync BUILT_IN_*_16 builtins.
* builtins.c (build_string_literal): Make extern.

* gcc.c (include_spec_function): New.
(static_spec_functions): Add it.
(main): Move load of libgomp.spec ...
(LINK_COMMAND_SPEC): ... here.
(link_gomp_spec): New.
(static_specs): Include it.
(LINK_COMMAND_SPEC): Add link_gomp.
(GOMP_SELF_SPECS): New.
(driver_self_specs): Include it.
(switch_matches): Don't mark inline.
(main): Load libgomp.spec.

* tree-gimple.c (is_gimple_stmt): True for OMP_MASTER,
OMP_ORDERED, OMP_CRITICAL, OMP_SECTIONS, OMP_SECTION,
and OMP_SINGLE, OMP_FOR and OMP_PARALLEL.

* tree-gimple.h (enum omp_parallel): Declare.
(determine_parallel_type): Declare.
(omp_firstprivatize_variable): Declare.
(omp_reduction_init): Declare.
(diagnose_omp_structured_block_errors): Declare.
(struct walk_stmt_info): Add want_return_expr.
(struct walk_stmt_info): Add want_bind_expr, want_locations.
(find_omp_clause): Declare.
(insert_field_into_struct): Declare.
(struct walk_stmt_info): Move from tree-nested.c
(walk_stmts): Declare.

* c-cppbuiltin.c (c_cpp_builtins): If -fopenmp, #define _OPENMP
to 200505.

* cgraphunit.c (cgraph_lower_function): Make static.
(cgraph_finalize_pending_functions): New.
(cgraph_finalize_function): Call it.
(cgraph_finalize_compilation_unit): Likewise.

* builtin-types.def (BT_I16, BT_FN_I16_VPTR_I16,
BT_FN_BOOL_VPTR_I16_I16, BT_FN_I16_VPTR_I16_I16): Add.
(BT_FN_UINT_UINT): New.
(DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7,
DEF_FUNCTION_TYPE_VAR_4): Document.
(BT_PTR_LONG, BT_PTR_PTR, BT_FN_BOOL, BT_FN_INT,
BT_FN_VOID_PTRPTR, BT_PTR_FN_VOID_PTR,
BT_FN_BOOL_LONGPTR_LONGPTR, BT_FN_VOID_OMPFN_PTR_UINT,
BT_FN_VOID_OMPFN_PTR_UINT_UINT,
BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG): New.

* builtins.def: Update DEF_BUILTIN comment to include COND argument.
Move all DEF_SYNC_BUILTIN () and DEF_GOMP_BUILTIN () builtins
into separate files.
(DEF_GOMP_BUILTIN): New.
(BUILT_IN_OMP_GET_THREAD_NUM, BUILT_IN_GOMP_BARRIER,
BUILT_IN_GOMP_CRITICAL_START, BUILT_IN_GOMP_CRITICAL_END,
BUILT_IN_GOMP_CRITICAL_NAME_START, BUILT_IN_GOMP_CRITICAL_NAME_END,
BUILT_IN_GOMP_LOOP_STATIC_START, BUILT_IN_GOMP_LOOP_DYNAMIC_START,
BUILT_IN_GOMP_LOOP_GUIDED_START, BUILT_IN_GOMP_LOOP_RUNTIME_START,
BUILT_IN_GOMP_LOOP_ORDERED_STATIC_START,
BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_START,
BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_START,
BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_START,
BUILT_IN_GOMP_LOOP_STATIC_NEXT, BUILT_IN_GOMP_LOOP_DYNAMIC_NEXT,
BUILT_IN_GOMP_LOOP_GUIDED_NEXT, BUILT_IN_GOMP_LOOP_RUNTIME_NEXT,
BUILT_IN_GOMP_LOOP_ORDERED_STATIC_NEXT,
BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_NEXT,
BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_NEXT,
BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_NEXT,
BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START,
BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC_START,
BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED_START,
BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME_START,
BUILT_IN_GOMP_LOOP_END, BUILT_IN_GOMP_LOOP_END_NOWAIT,
BUILT_IN_GOMP_ORDERED_START, BUILT_IN_GOMP_ORDERED_END,
BUILT_IN_GOMP_PARALLEL_START, BUILT_IN_GOMP_PARALLEL_END,
BUILT_IN_GOMP_SECTIONS_START, BUILT_IN_GOMP_SECTIONS_NEXT,
BUILT_IN_GOMP_PARALLEL_SECTIONS_START, BUILT_IN_GOMP_SECTIONS_END,
BUILT_IN_GOMP_SECTIONS_END_NOWAIT, BUILT_IN_GOMP_SINGLE_START,
BUILT_IN_GOMP_SINGLE_COPY_START, BUILT_IN_GOMP_SINGLE_COPY_END): New.
* sync-builtins.def: New file, moved from builtins.def.
* omp-builtins.def: New file, moved from builtins.def.

* c-objc-common.h (LANG_HOOKS_OMP_PREDETERMINED_SHARING): Redefine.

* gimple-low.c (lower_function_body): Clear data.
(lower_stmt): Do not handle COMPOUND_EXPR.
Remove call to print_node_brief.

* c-tree.h (c_finish_omp_clauses): New prototype.
(C_DECL_THREADPRIVATE_P): Define.
(lookup_name_no_remap, c_omp_remap_private): Remove
(c_begin_omp_parallel, c_finish_omp_parallel): Update.
(check_for_loop_decls): Update decl.
(lookup_name_no_remap, c_omp_remap_private): Declare.
(build_indirect_ref, build_modify_expr, pushdecl,
pushdecl_top_level): Move to c-common.h.

* dwarf2out.c (loc_descriptor_from_tree_1): Don't set unsignedp
before the switch, but just in the 2 places that need it.

* c-decl.c (diagnose_mismatched_decls): Do not check for
mismatched thread-local attributes when OLDDECL is marked
threadprivate and NEWDECL has no thread-local attributes.
(merge_decls): Merge C_DECL_THREADPRIVATE_P.
(c_gimple_diagnostics_recursively): Rename from
c_warn_unused_result_recursively.  Invoke
diagnose_omp_structured_block_errors.
(check_for_loop_decls): Return a singular decl found.

* langhooks.c (lhd_omp_predetermined_sharing): Return
OMP_CLAUSE_DEFAULT_SHARED for DECL_ARTIFICIAL decls.
(lhd_omp_firstprivatize_type_sizes): New.
(lhd_omp_assignment): New.
(lhd_omp_predetermined_sharing): New.

* langhooks.h (struct gimplify_omp_ctx): Forward declare.
(struct lang_hooks_for_types): Add
omp_firstprivatize_type_sizes, omp_privatize_by_reference,
omp_predetermined_sharing, omp_disregard_value_expr,
omp_private_debug_clause, omp_clause_default_ctor,
omp_clause_copy_ctor, omp_clause_assign_op, omp_clause_dtor.

(c_finish_omp_clauses): New.
(c_finish_bc_stmt): Diagnose break within omp for.
(c_begin_omp_parallel, c_finish_omp_parallel): New.
(build_unary_op): Return error_mark after reporting
a readonly_error.
(build_modify_expr): Likewise.

* gimplify.c: Include optabs.h and pointer-set.h.
(enum gimplify_omp_var_data): Declare.
(struct gimplify_omp_ctx): Declare.
(struct gimplify_ctx): Add fields prev_context, combined_pre_p
and combined_ctxp.
(gimplify_ctxp, gimplify_omp_ctxp): New local variables.
(push_gimplify_context, pop_gimplify_context): Allow nesting.
(splay_tree_compare_decl_uid): New.
(new_omp_context): New.
(delete_omp_context): New.
(gimple_add_tmp_var): Call omp_add_variable.
(gimplify_bind_expr): Likewise.
(gimplify_var_or_parm_decl): If omp_notice_variable returned
true, disregard DECL_VALUE_EXPR on the decl if any.
(gimplify_expr_in_ctx): New.
(omp_firstprivatize_variable, omp_firstprivatize_type_sizes
omp_add_variable, omp_notice_variable, omp_is_private
gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses_1
gimplify_adjust_omp_clauses, gimplify_omp_parallel
gimplify_omp_for, gimplify_omp_workshare, goa_lhs_expr_p
gimplify_omp_atomic_fetch_op, goa_stabilize_expr
gimplify_omp_atomic_pipeline, gimplify_omp_atomic_mutex
gimplify_omp_atomic): New.
(gimplify_expr): Handle OMP_PARALLEL, OMP_FOR, OMP_SECTIONS,
OMP_SINGLE, OMP_SECTION, OMP_MASTER, OMP_ORDERED,
OMP_CRITICAL and OMP_ATOMIC.
(gimplify_body): Verify gimplify_ctxp is empty after gimplification.

* c-pragma.h (enum pragma_kind): Add
PRAGMA_OMP_ATOMIC, PRAGMA_OMP_BARRIER,
PRAGMA_OMP_CRITICAL, PRAGMA_OMP_FLUSH, PRAGMA_OMP_FOR,
PRAGMA_OMP_MASTER, PRAGMA_OMP_ORDERED,
PRAGMA_OMP_PARALLEL, PRAGMA_OMP_PARALLEL_FOR,
PRAGMA_OMP_PARALLEL_SECTIONS, PRAGMA_OMP_SECTION,
PRAGMA_OMP_SECTIONS, PRAGMA_OMP_SINGLE,
PRAGMA_OMP_THREADPRIVATE.

* tree.def (OMP_PARALLEL, OMP_FOR, OMP_SECTIONS,
OMP_SINGLE, OMP_SECTION, OMP_MASTER, OMP_ORDERED,
OMP_CRITICAL, OMP_ATOMIC, OMP_CLAUSE_PRIVATE,
OMP_CLAUSE_SHARED, OMP_CLAUSE_FIRSTPRIVATE,
OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_REDUCTION,
OMP_CLAUSE_COPYIN, OMP_CLAUSE_COPYPRIVATE,
OMP_CLAUSE_IF, OMP_CLAUSE_NUM_THREADS,
OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_NOWAIT,
OMP_CLAUSE_ORDERED, OMP_CLAUSE_DEFAULT): Define.

* print-tree.c (print_node): Dump DECL_VALUE_EXPR.

* tree-ssa-dce.c (find_control_dependence): Do not assume that
ENTRY_BLOCK_PTR->next_bb == single_succ (ENTRY_BLOCK_PTR).

* tree-nested.c (convert_call_expr): Call walk_body on OMP_BODY for
OpenMP directives.
(struct nesting_info): Add field_map,
suppress_expansion, debug_var_chain.
(create_nesting_tree): Initialize them.
(lookup_field_for_decl): Use field_map.
(get_nonlocal_debug_decl, get_local_debug_decl): New.
(convert_local_omp_clauses): New.
(finalize_nesting_tree_1): Add debug_var_chain to toplevel block.
(walk_body): Split out of walk_function.
(convert_nonlocal_omp_clauses, convert_local_omp_clauses): New.
(convert_nonlocal_reference): Handle omp statements.
(convert_local_reference): Likewise.
(unnest_nesting_tree_1): Split out of finalize_nesting_tree_1.
(unnest_nesting_tree): New.
(lower_nested_functions): Call it.
(insert_field_into_struct): Make extern.
(struct walk_stmt_info): Move to tree-gimple.h.
(walk_stmts): Make extern.

* omp-builtins.def: New file.

* tree-iterator.c (expr_only): Clarify comment.

* c-common.h (pushdecl_top_level, pushdecl,
build_modify_expr, build_indirect_ref,
c_finish_omp_master, c_finish_omp_critical,
c_finish_omp_ordered, c_finish_omp_barrier,
c_finish_omp_atomic, c_finish_omp_flush,
c_finish_omp_for, c_split_parallel_clauses,
omp_clause_default_kind, c_omp_sharing_predetermined,
c_omp_remap_decl): Declare.

* Makefile.in (BUILTINS_DEF): Add omp-builtins.def.
(OBJS-common): Add omp-low.o.
(c-omp.o, omp-low.o): Add.
(gimplify.o): Add dependency on $(OPTABS_H).
(GTFILES): Add omp-low.c.
(gt-stringpool.h): Add.

* tree-cfg.c (set_bb_for_stmt): Do not update the
block-to-labels map if we are currently expanding to RTL.
(tree_node_can_be_shared): Remove unnecessary CONSTANT_CLASS_P
checks.
Handle IDENTIFIER_NODE.
(tree_verify_flow_info): Do not ICE when emitting error
messages about invalid labels.
(dump_function_to_file): Reset CFUN before emitting the body
of the function.
(debug_function): New.

* passes.c (init_optimization_passes): Schedule
pass_lower_omp.

* langhooks-def.h (lhd_omp_predetermined_sharing,
lhd_omp_assignment, lhd_omp_firstprivatize_type_sizes):
Declare.
(LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES): Define.
(LANG_HOOKS_FOR_TYPES_INITIALIZER): Use it.
(LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE,
LANG_HOOKS_OMP_PREDETERMINED_SHARING,
LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR,
LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE,
LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR,
LANG_HOOKS_OMP_CLAUSE_COPY_CTOR,
LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP,
LANG_HOOKS_OMP_CLAUSE_DTOR): Define.
(LANG_HOOK_DECLS): Use them.

2006-01-18  Dmitry Kurochkin <dmitry.kurochkin@gmail.com>
    Richard Henderson  <rth@redhat.com>
    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>

* c-parser.c (pragma_omp_clause): Define.
(c_parser_declaration_or_fndef): Document OpenMP syntax.
(c_parser_compound_statement): Likewise.
(c_parser_statement): Likewise.
(c_parser_pragma): Handle omp pragmas.
(OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK,
OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK): Define.
(c_parser_omp_clause_name, check_no_duplicate_clause,
c_parser_omp_variable_list,
c_parser_omp_var_list_parens, c_parser_omp_clause_copyin,
c_parser_omp_clause_copyprivate,
c_parser_omp_clause_default,
c_parser_omp_clause_firstprivate, c_parser_omp_clause_if,
c_parser_omp_clause_lastprivate,
c_parser_omp_clause_nowait,
c_parser_omp_clause_num_threads,
c_parser_omp_clause_ordered, c_parser_omp_clause_private,
c_parser_omp_clause_reduction,
c_parser_omp_clause_schedule, c_parser_omp_clause_shared,
c_parser_omp_all_clauses, c_parser_omp_structured_block,
c_parser_omp_atomic, c_parser_omp_barrier,
c_parser_omp_critical, c_parser_omp_flush,
c_parser_omp_for_loop, c_parser_omp_for,
c_parser_omp_master, c_parser_omp_ordered,
c_parser_omp_sections_scope, c_parser_omp_sections,
c_parser_omp_parallel, c_parser_omp_single,
c_parser_omp_construct, c_parser_omp_threadprivate): New.
* c-pragma.c (init_pragma): Do omp pragma registration here.
* c.opt (fopenmp): New flag.

2006-01-18  Eric Christopher  <echristo@apple.com>

* gcc.c (GOMP_SELF_SPECS): Bracket in #ifndef/#endif.
* config/darwin.h (GOMP_SELF_SPECS): Define.

testsuite/

2006-01-18  Richard Henderson  <rth@redhat.com>
            Aldy Hernandez  <aldyh@redhat.com>
    Jakub Jelinek  <jakub@redhat.com>
            Diego Novillo  <dnovillo@redhat.com>
            Uros Bizjak  <uros@kss-loka.si>

* testsuite/gcc.dg/gomp: New directory.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109902 138bc75d-0d04-0410-961f-82ee72b054a4

296 files changed:
ChangeLog
Makefile.def
Makefile.in
configure
configure.in
contrib/ChangeLog
contrib/gcc_update
gcc/ChangeLog
gcc/Makefile.in
gcc/builtin-types.def
gcc/builtins.c
gcc/builtins.def
gcc/c-common.h
gcc/c-cppbuiltin.c
gcc/c-decl.c
gcc/c-objc-common.h
gcc/c-omp.c [new file with mode: 0644]
gcc/c-parser.c
gcc/c-pragma.c
gcc/c-pragma.h
gcc/c-tree.h
gcc/c-typeck.c
gcc/c.opt
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphunit.c
gcc/config/darwin.h
gcc/diagnostic.h
gcc/doc/invoke.texi
gcc/dwarf2out.c
gcc/gcc.c
gcc/gimple-low.c
gcc/gimplify.c
gcc/hooks.c
gcc/hooks.h
gcc/langhooks-def.h
gcc/langhooks.c
gcc/langhooks.h
gcc/omp-builtins.def [new file with mode: 0644]
gcc/omp-low.c [new file with mode: 0644]
gcc/passes.c
gcc/print-tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/gomp/appendix-a/a.1.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.10.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.12.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.13.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.14.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.17.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.17.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.20.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.20.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.21.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.21.3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.22.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.22.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.24.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.26.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.27.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.30.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.31.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.31.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.32.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.33.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.33.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.34.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.34.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.35.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.35.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.35.3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.35.4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.35.5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.35.6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.37.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.37.2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.8.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/appendix-a/a.9.1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/atomic-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/barrier-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/barrier-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-10.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/block-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/clause-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/copyin-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/critical-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/critical-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/critical-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/empty.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/flush-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/flush-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-10.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-13.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-15.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-16.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-17.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-18.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-19.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/for-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/gomp.exp [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/macro-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/macro-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/master-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/master-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/master-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/num-threads-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/omp-parallel-if.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/ordered-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/ordered-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/parallel-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/parallel-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/parallel-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/parallel-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/sections-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/sections-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/sections-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/sections-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/sharing-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/sharing-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/sharing-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/static.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/tls-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/tls-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/uninit-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/vla-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/vla-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/vla-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/vla-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/vla-5.c [new file with mode: 0644]
gcc/tree-cfg.c
gcc/tree-dump.h
gcc/tree-gimple.c
gcc/tree-gimple.h
gcc/tree-iterator.c
gcc/tree-nested.c
gcc/tree-pass.h
gcc/tree-pretty-print.c
gcc/tree-ssa-dce.c
gcc/tree.c
gcc/tree.def
gcc/tree.h
libgomp/ChangeLog [new file with mode: 0644]
libgomp/Makefile.am [new file with mode: 0644]
libgomp/Makefile.in [new file with mode: 0644]
libgomp/NOTES [new file with mode: 0644]
libgomp/acinclude.m4 [new file with mode: 0644]
libgomp/aclocal.m4 [new file with mode: 0644]
libgomp/alloc.c [new file with mode: 0644]
libgomp/barrier.c [new file with mode: 0644]
libgomp/config.h.in [new file with mode: 0644]
libgomp/config/linux/alpha/futex.h [new file with mode: 0644]
libgomp/config/linux/bar.c [new file with mode: 0644]
libgomp/config/linux/bar.h [new file with mode: 0644]
libgomp/config/linux/ia64/futex.h [new file with mode: 0644]
libgomp/config/linux/lock.c [new file with mode: 0644]
libgomp/config/linux/mutex.c [new file with mode: 0644]
libgomp/config/linux/mutex.h [new file with mode: 0644]
libgomp/config/linux/omp-lock.h [new file with mode: 0644]
libgomp/config/linux/powerpc/futex.h [new file with mode: 0644]
libgomp/config/linux/s390/futex.h [new file with mode: 0644]
libgomp/config/linux/sem.c [new file with mode: 0644]
libgomp/config/linux/sem.h [new file with mode: 0644]
libgomp/config/linux/sparc/futex.h [new file with mode: 0644]
libgomp/config/linux/x86/futex.h [new file with mode: 0644]
libgomp/config/posix/bar.c [new file with mode: 0644]
libgomp/config/posix/bar.h [new file with mode: 0644]
libgomp/config/posix/lock.c [new file with mode: 0644]
libgomp/config/posix/mutex.c [new file with mode: 0644]
libgomp/config/posix/mutex.h [new file with mode: 0644]
libgomp/config/posix/omp-lock.h [new file with mode: 0644]
libgomp/config/posix/proc.c [new file with mode: 0644]
libgomp/config/posix/sem.c [new file with mode: 0644]
libgomp/config/posix/sem.h [new file with mode: 0644]
libgomp/config/posix/time.c [new file with mode: 0644]
libgomp/configure [new file with mode: 0755]
libgomp/configure.ac [new file with mode: 0644]
libgomp/configure.tgt [new file with mode: 0644]
libgomp/critical.c [new file with mode: 0644]
libgomp/env.c [new file with mode: 0644]
libgomp/error.c [new file with mode: 0644]
libgomp/fortran.c [new file with mode: 0644]
libgomp/iter.c [new file with mode: 0644]
libgomp/libgomp.h [new file with mode: 0644]
libgomp/libgomp.map [new file with mode: 0644]
libgomp/libgomp.spec.in [new file with mode: 0644]
libgomp/libgomp_f.h.in [new file with mode: 0644]
libgomp/libgomp_g.h [new file with mode: 0644]
libgomp/loop.c [new file with mode: 0644]
libgomp/mkomp_h.pl [new file with mode: 0644]
libgomp/omp.h.in [new file with mode: 0644]
libgomp/omp_lib.f90.in [new file with mode: 0644]
libgomp/omp_lib.h.in [new file with mode: 0644]
libgomp/ordered.c [new file with mode: 0644]
libgomp/parallel.c [new file with mode: 0644]
libgomp/sections.c [new file with mode: 0644]
libgomp/single.c [new file with mode: 0644]
libgomp/team.c [new file with mode: 0644]
libgomp/testsuite/Makefile.am [new file with mode: 0644]
libgomp/testsuite/Makefile.in [new file with mode: 0644]
libgomp/testsuite/lib/libgomp-dg.exp [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.15.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.16.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.18.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.19.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.2.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.21.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.26.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.29.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.3.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.33.3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.36.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.39.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.4.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.40.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/appendix-a/a.5.1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/atomic-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/atomic-10.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/atomic-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/barrier-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/c.exp [new file with mode: 0644]
libgomp/testsuite/libgomp.c/copyin-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/copyin-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/copyin-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/critical-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/critical-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/lib-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/loop-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/loop-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/loop-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/nested-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/nested-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/nestedfn-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/nestedfn-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/nestedfn-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp-loop01.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp-loop02.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp-loop03.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp-nested-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp-parallel-for.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp-parallel-if.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp-single-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp-single-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp-single-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp_hello.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp_matvec.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp_orphan.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp_reduction.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp_workshare1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp_workshare2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp_workshare3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/omp_workshare4.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/ordered-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/ordered-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/ordered-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/parallel-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/pr24455-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/pr24455.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/reduction-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/reduction-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/reduction-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/reduction-4.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/sections-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/shared-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/shared-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/shared-3.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/single-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/single-2.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/vla-1.c [new file with mode: 0644]
libgomp/work.c [new file with mode: 0644]

index 6e072d1..c90bddb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2006-01-18  Richard Henderson  <rth@redhat.com>
+           Jakub Jelinek  <jakub@redhat.com>
+           Diego Novillo  <dnovillo@redhat.com>
+
+       * libgomp: New directory.
+       * Makefile.def: Add target_module libgomp.
+       * Makefile.in: Regenerate.
+       * configure.in (target_libraries): Add target-libgomp.
+       * configure: Regenerate.
+
 2006-01-05  Alexandre Oliva  <aoliva@redhat.com>
 
        * Makefile.tpl (clean-stage[+id+]-[+prefix+][+module+]): Remove
        (EXTRA_HOST_FLAGS): Add it.
        (EXTRA_GCC_FLAGS): Remove flags already specified in flags_to_pass.
 
-        * Makefile.tpl (stage[+id+]-start, stage[+id+]-end): Do not try
-        to use symbolic links between directories.  Avoid race conditions
-        or make them harmless.
-        * configure.in: Do not try to use symbolic links between directories.
+       * Makefile.tpl (stage[+id+]-start, stage[+id+]-end): Do not try
+       to use symbolic links between directories.  Avoid race conditions
+       or make them harmless.
+       * configure.in: Do not try to use symbolic links between directories.
 
        * Makefile.def (LEAN): Pass.
        * Makefile.tpl (LEAN): Define.
@@ -33,8 +43,8 @@
        ([+bootstrap-target+]-lean): New.
        * configure.in: Remove lean bootstrap support from here.
 
-        * Makefile.in: Regenerate.
-        * configure: Regenerate.
+       * Makefile.in: Regenerate.
+       * configure: Regenerate.
 
 2006-01-04  Ben Elliston  <bje@au.ibm.com>
 
index acc770d..cdf25d2 100644 (file)
@@ -137,6 +137,7 @@ target_modules = { module= boehm-gc; };
 target_modules = { module= qthreads; };
 target_modules = { module= rda; };
 target_modules = { module= libada; };
+target_modules = { module= libgomp; lib_path=.libs; };
 
 // These are (some of) the make targets to be done in each subdirectory.
 // Not all; these are the ones which don't have special options.
index 78972f0..f8fb047 100644 (file)
@@ -356,7 +356,7 @@ all:
 
 # This is the list of directories that may be needed in RPATH_ENVVAR
 # so that prorgams built for the target machine work.
-TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libmudflap)$(TARGET_LIB_PATH_libssp)$(HOST_LIB_PATH_gcc)
+TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libmudflap)$(TARGET_LIB_PATH_libssp)$(TARGET_LIB_PATH_libgomp)$(HOST_LIB_PATH_gcc)
 
 @if target-libstdc++-v3
 TARGET_LIB_PATH_libstdc++-v3 = $$r/$(TARGET_SUBDIR)/libstdc++-v3/.libs:
@@ -370,6 +370,10 @@ TARGET_LIB_PATH_libmudflap = $$r/$(TARGET_SUBDIR)/libmudflap/.libs:
 TARGET_LIB_PATH_libssp = $$r/$(TARGET_SUBDIR)/libssp/.libs:
 @endif target-libssp
 
+@if target-libgomp
+TARGET_LIB_PATH_libgomp = $$r/$(TARGET_SUBDIR)/libgomp/.libs:
+@endif target-libgomp
+
 
 
 # This is the list of directories that may be needed in RPATH_ENVVAR
@@ -633,7 +637,8 @@ configure-target:  \
     maybe-configure-target-boehm-gc \
     maybe-configure-target-qthreads \
     maybe-configure-target-rda \
-    maybe-configure-target-libada
+    maybe-configure-target-libada \
+    maybe-configure-target-libgomp
 
 # The target built for a native non-bootstrap build.
 .PHONY: all
@@ -752,7 +757,8 @@ all-target:  \
     maybe-all-target-boehm-gc \
     maybe-all-target-qthreads \
     maybe-all-target-rda \
-    maybe-all-target-libada
+    maybe-all-target-libada \
+    maybe-all-target-libgomp
 
 # Do a target for all the subdirectories.  A ``make do-X'' will do a
 # ``make X'' in all subdirectories (because, in general, there is a
@@ -859,7 +865,8 @@ info-target:  \
     maybe-info-target-boehm-gc \
     maybe-info-target-qthreads \
     maybe-info-target-rda \
-    maybe-info-target-libada
+    maybe-info-target-libada \
+    maybe-info-target-libgomp
 
 .PHONY: do-dvi
 do-dvi:
@@ -961,7 +968,8 @@ dvi-target:  \
     maybe-dvi-target-boehm-gc \
     maybe-dvi-target-qthreads \
     maybe-dvi-target-rda \
-    maybe-dvi-target-libada
+    maybe-dvi-target-libada \
+    maybe-dvi-target-libgomp
 
 .PHONY: do-html
 do-html:
@@ -1063,7 +1071,8 @@ html-target:  \
     maybe-html-target-boehm-gc \
     maybe-html-target-qthreads \
     maybe-html-target-rda \
-    maybe-html-target-libada
+    maybe-html-target-libada \
+    maybe-html-target-libgomp
 
 .PHONY: do-TAGS
 do-TAGS:
@@ -1165,7 +1174,8 @@ TAGS-target:  \
     maybe-TAGS-target-boehm-gc \
     maybe-TAGS-target-qthreads \
     maybe-TAGS-target-rda \
-    maybe-TAGS-target-libada
+    maybe-TAGS-target-libada \
+    maybe-TAGS-target-libgomp
 
 .PHONY: do-install-info
 do-install-info:
@@ -1267,7 +1277,8 @@ install-info-target:  \
     maybe-install-info-target-boehm-gc \
     maybe-install-info-target-qthreads \
     maybe-install-info-target-rda \
-    maybe-install-info-target-libada
+    maybe-install-info-target-libada \
+    maybe-install-info-target-libgomp
 
 .PHONY: do-installcheck
 do-installcheck:
@@ -1369,7 +1380,8 @@ installcheck-target:  \
     maybe-installcheck-target-boehm-gc \
     maybe-installcheck-target-qthreads \
     maybe-installcheck-target-rda \
-    maybe-installcheck-target-libada
+    maybe-installcheck-target-libada \
+    maybe-installcheck-target-libgomp
 
 .PHONY: do-mostlyclean
 do-mostlyclean:
@@ -1471,7 +1483,8 @@ mostlyclean-target:  \
     maybe-mostlyclean-target-boehm-gc \
     maybe-mostlyclean-target-qthreads \
     maybe-mostlyclean-target-rda \
-    maybe-mostlyclean-target-libada
+    maybe-mostlyclean-target-libada \
+    maybe-mostlyclean-target-libgomp
 
 .PHONY: do-clean
 do-clean:
@@ -1573,7 +1586,8 @@ clean-target:  \
     maybe-clean-target-boehm-gc \
     maybe-clean-target-qthreads \
     maybe-clean-target-rda \
-    maybe-clean-target-libada
+    maybe-clean-target-libada \
+    maybe-clean-target-libgomp
 
 .PHONY: do-distclean
 do-distclean:
@@ -1675,7 +1689,8 @@ distclean-target:  \
     maybe-distclean-target-boehm-gc \
     maybe-distclean-target-qthreads \
     maybe-distclean-target-rda \
-    maybe-distclean-target-libada
+    maybe-distclean-target-libada \
+    maybe-distclean-target-libgomp
 
 .PHONY: do-maintainer-clean
 do-maintainer-clean:
@@ -1777,7 +1792,8 @@ maintainer-clean-target:  \
     maybe-maintainer-clean-target-boehm-gc \
     maybe-maintainer-clean-target-qthreads \
     maybe-maintainer-clean-target-rda \
-    maybe-maintainer-clean-target-libada
+    maybe-maintainer-clean-target-libada \
+    maybe-maintainer-clean-target-libgomp
 
 
 # Here are the targets which correspond to the do-X targets.
@@ -1932,7 +1948,8 @@ check-target:  \
     maybe-check-target-boehm-gc \
     maybe-check-target-qthreads \
     maybe-check-target-rda \
-    maybe-check-target-libada
+    maybe-check-target-libada \
+    maybe-check-target-libgomp
 
 do-check:
        @: $(MAKE); $(unstage)
@@ -2131,7 +2148,8 @@ install-target:  \
     maybe-install-target-boehm-gc \
     maybe-install-target-qthreads \
     maybe-install-target-rda \
-    maybe-install-target-libada
+    maybe-install-target-libada \
+    maybe-install-target-libgomp
 
 uninstall:
        @echo "the uninstall target is not supported in this tree"
@@ -35545,6 +35563,362 @@ maintainer-clean-target-libada:
 
 
 
+
+
+.PHONY: configure-target-libgomp maybe-configure-target-libgomp
+maybe-configure-target-libgomp:
+@if target-libgomp
+maybe-configure-target-libgomp: configure-target-libgomp
+configure-target-libgomp:
+       @: $(MAKE); $(unstage)
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       echo "Checking multilib configuration for libgomp..."; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libgomp ; \
+       $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libgomp/multilib.tmp 2> /dev/null ; \
+       if test -r $(TARGET_SUBDIR)/libgomp/multilib.out; then \
+         if cmp -s $(TARGET_SUBDIR)/libgomp/multilib.tmp $(TARGET_SUBDIR)/libgomp/multilib.out; then \
+           rm -f $(TARGET_SUBDIR)/libgomp/multilib.tmp; \
+         else \
+           rm -f $(TARGET_SUBDIR)/libgomp/Makefile; \
+           mv $(TARGET_SUBDIR)/libgomp/multilib.tmp $(TARGET_SUBDIR)/libgomp/multilib.out; \
+         fi; \
+       else \
+         mv $(TARGET_SUBDIR)/libgomp/multilib.tmp $(TARGET_SUBDIR)/libgomp/multilib.out; \
+       fi
+       @test ! -f $(TARGET_SUBDIR)/libgomp/Makefile || exit 0; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libgomp ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo Configuring in $(TARGET_SUBDIR)/libgomp; \
+       cd "$(TARGET_SUBDIR)/libgomp" || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(TARGET_SUBDIR)/libgomp/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/libgomp"; \
+       libsrcdir="$$s/libgomp"; \
+       rm -f no-such-file || : ; \
+       CONFIG_SITE=no-such-file $(SHELL) $${libsrcdir}/configure \
+         $(TARGET_CONFIGARGS) $${srcdiroption}  \
+         || exit 1
+@endif target-libgomp
+
+
+
+
+
+.PHONY: all-target-libgomp maybe-all-target-libgomp
+maybe-all-target-libgomp:
+@if target-libgomp
+TARGET-target-libgomp=all
+maybe-all-target-libgomp: all-target-libgomp
+all-target-libgomp: configure-target-libgomp
+       @: $(MAKE); $(unstage)
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(TARGET_FLAGS_TO_PASS)  $(TARGET-target-libgomp))
+@endif target-libgomp
+
+
+
+
+
+.PHONY: check-target-libgomp maybe-check-target-libgomp
+maybe-check-target-libgomp:
+@if target-libgomp
+maybe-check-target-libgomp: check-target-libgomp
+
+check-target-libgomp:
+       @: $(MAKE); $(unstage)
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(TARGET_FLAGS_TO_PASS)   check)
+
+@endif target-libgomp
+
+.PHONY: install-target-libgomp maybe-install-target-libgomp
+maybe-install-target-libgomp:
+@if target-libgomp
+maybe-install-target-libgomp: install-target-libgomp
+
+install-target-libgomp: installdirs
+       @: $(MAKE); $(unstage)
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(TARGET_FLAGS_TO_PASS)  install)
+
+@endif target-libgomp
+
+# Other targets (info, dvi, etc.)
+
+.PHONY: maybe-info-target-libgomp info-target-libgomp
+maybe-info-target-libgomp:
+@if target-libgomp
+maybe-info-target-libgomp: info-target-libgomp
+
+info-target-libgomp: \
+    configure-target-libgomp 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing info in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  info) \
+         || exit 1
+
+@endif target-libgomp
+
+.PHONY: maybe-dvi-target-libgomp dvi-target-libgomp
+maybe-dvi-target-libgomp:
+@if target-libgomp
+maybe-dvi-target-libgomp: dvi-target-libgomp
+
+dvi-target-libgomp: \
+    configure-target-libgomp 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing dvi in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  dvi) \
+         || exit 1
+
+@endif target-libgomp
+
+.PHONY: maybe-html-target-libgomp html-target-libgomp
+maybe-html-target-libgomp:
+@if target-libgomp
+maybe-html-target-libgomp: html-target-libgomp
+
+html-target-libgomp: \
+    configure-target-libgomp 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing html in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  html) \
+         || exit 1
+
+@endif target-libgomp
+
+.PHONY: maybe-TAGS-target-libgomp TAGS-target-libgomp
+maybe-TAGS-target-libgomp:
+@if target-libgomp
+maybe-TAGS-target-libgomp: TAGS-target-libgomp
+
+TAGS-target-libgomp: \
+    configure-target-libgomp 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing TAGS in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  TAGS) \
+         || exit 1
+
+@endif target-libgomp
+
+.PHONY: maybe-install-info-target-libgomp install-info-target-libgomp
+maybe-install-info-target-libgomp:
+@if target-libgomp
+maybe-install-info-target-libgomp: install-info-target-libgomp
+
+install-info-target-libgomp: \
+    configure-target-libgomp \
+    info-target-libgomp 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing install-info in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  install-info) \
+         || exit 1
+
+@endif target-libgomp
+
+.PHONY: maybe-installcheck-target-libgomp installcheck-target-libgomp
+maybe-installcheck-target-libgomp:
+@if target-libgomp
+maybe-installcheck-target-libgomp: installcheck-target-libgomp
+
+installcheck-target-libgomp: \
+    configure-target-libgomp 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing installcheck in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  installcheck) \
+         || exit 1
+
+@endif target-libgomp
+
+.PHONY: maybe-mostlyclean-target-libgomp mostlyclean-target-libgomp
+maybe-mostlyclean-target-libgomp:
+@if target-libgomp
+maybe-mostlyclean-target-libgomp: mostlyclean-target-libgomp
+
+mostlyclean-target-libgomp: 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing mostlyclean in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  mostlyclean) \
+         || exit 1
+
+@endif target-libgomp
+
+.PHONY: maybe-clean-target-libgomp clean-target-libgomp
+maybe-clean-target-libgomp:
+@if target-libgomp
+maybe-clean-target-libgomp: clean-target-libgomp
+
+clean-target-libgomp: 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing clean in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  clean) \
+         || exit 1
+
+@endif target-libgomp
+
+.PHONY: maybe-distclean-target-libgomp distclean-target-libgomp
+maybe-distclean-target-libgomp:
+@if target-libgomp
+maybe-distclean-target-libgomp: distclean-target-libgomp
+
+distclean-target-libgomp: 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing distclean in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  distclean) \
+         || exit 1
+
+@endif target-libgomp
+
+.PHONY: maybe-maintainer-clean-target-libgomp maintainer-clean-target-libgomp
+maybe-maintainer-clean-target-libgomp:
+@if target-libgomp
+maybe-maintainer-clean-target-libgomp: maintainer-clean-target-libgomp
+
+maintainer-clean-target-libgomp: 
+       @: $(MAKE); $(unstage)
+       @[ -f $(TARGET_SUBDIR)/libgomp/Makefile ] || exit 0 ; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(NORMAL_TARGET_EXPORTS) \
+       echo "Doing maintainer-clean in $(TARGET_SUBDIR)/libgomp" ; \
+       for flag in $(EXTRA_TARGET_FLAGS); do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       (cd $(TARGET_SUBDIR)/libgomp && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" \
+                  maintainer-clean) \
+         || exit 1
+
+@endif target-libgomp
+
+
+
 # ----------
 # GCC module
 # ----------
@@ -37054,6 +37428,8 @@ configure-target-rda: maybe-all-gcc
 
 configure-target-libada: maybe-all-gcc
 
+configure-target-libgomp: maybe-all-gcc
+
 
 
 configure-target-boehm-gc: maybe-all-target-newlib maybe-all-target-libgloss
index cf1560b..663a7a5 100755 (executable)
--- a/configure
+++ b/configure
@@ -909,7 +909,8 @@ target_libraries="target-libiberty \
                target-libgfortran \
                ${libgcj} \
                target-libobjc \
-               target-libada"
+               target-libada \
+               target-libgomp"
 
 # these tools are built using the target libraries, and are intended to
 # run only in the target environment
@@ -1146,6 +1147,30 @@ no)
     esac
 esac
 
+# Allow --disable-libgomp to exclude target-libgomp
+case $enable_libgomp in
+yes)
+    ;;
+no)
+    noconfigdirs="$noconfigdirs target-libgomp"
+    ;;
+"")
+    # Enable libgomp by default on hosted POSIX systems.
+    case "${target}" in
+    *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu)
+       ;;
+    *-*-netbsd* | *-*-freebsd* | *-*-openbsd*)
+       ;;
+    *-*-solaris2* | *-*-sysv4* | *-*-irix* | *-*-osf* | *-*-hpux*)
+       ;;
+    *-*-darwin*)
+       ;;
+    *)
+       noconfigdirs="$noconfigdirs target-libgomp"
+       ;;
+    esac
+esac
+
 
 case "${target}" in
   *-*-chorusos)
@@ -1827,7 +1852,7 @@ else
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1831: checking for $ac_word" >&5
+echo "configure:1856: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1857,7 +1882,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1861: checking for $ac_word" >&5
+echo "configure:1886: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1908,7 +1933,7 @@ fi
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1912: checking for $ac_word" >&5
+echo "configure:1937: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1940,7 +1965,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1944: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1969: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1951,12 +1976,12 @@ cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext << EOF
 
-#line 1955 "configure"
+#line 1980 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:1960: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1985: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1982,12 +2007,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1986: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:2011: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1991: checking whether we are using GNU C" >&5
+echo "configure:2016: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1996,7 +2021,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2000: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2025: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -2015,7 +2040,7 @@ ac_test_CFLAGS="${CFLAGS+set}"
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:2019: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:2044: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2082,7 +2107,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}gnatbind", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gnatbind; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2086: checking for $ac_word" >&5
+echo "configure:2111: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2114,7 +2139,7 @@ if test -n "$ac_tool_prefix"; then
   # Extract the first word of "gnatbind", so it can be a program name with args.
 set dummy gnatbind; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2118: checking for $ac_word" >&5
+echo "configure:2143: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2147,7 +2172,7 @@ fi
 fi
 
 echo $ac_n "checking whether compiler driver understands Ada""... $ac_c" 1>&6
-echo "configure:2151: checking whether compiler driver understands Ada" >&5
+echo "configure:2176: checking whether compiler driver understands Ada" >&5
 if eval "test \"`echo '$''{'acx_cv_cc_gcc_supports_ada'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2179,7 +2204,7 @@ else
 fi
 
 echo $ac_n "checking how to compare bootstrapped objects""... $ac_c" 1>&6
-echo "configure:2183: checking how to compare bootstrapped objects" >&5
+echo "configure:2208: checking how to compare bootstrapped objects" >&5
 if eval "test \"`echo '$''{'gcc_cv_prog_cmp_skip'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2277,9 +2302,9 @@ saved_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS $gmpinc"
 # Check GMP actually works
 echo $ac_n "checking for correct version of gmp.h""... $ac_c" 1>&6
-echo "configure:2281: checking for correct version of gmp.h" >&5
+echo "configure:2306: checking for correct version of gmp.h" >&5
 cat > conftest.$ac_ext <<EOF
-#line 2283 "configure"
+#line 2308 "configure"
 #include "confdefs.h"
 #include "gmp.h"
 int main() {
@@ -2290,7 +2315,7 @@ choke me
 
 ; return 0; }
 EOF
-if { (eval echo configure:2294: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2319: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
 else
@@ -2303,12 +2328,12 @@ rm -f conftest*
 
 if test x"$have_gmp" = xyes; then
   echo $ac_n "checking for MPFR""... $ac_c" 1>&6
-echo "configure:2307: checking for MPFR" >&5
+echo "configure:2332: checking for MPFR" >&5
 
   saved_LIBS="$LIBS"
   LIBS="$LIBS $gmplibs"
   cat > conftest.$ac_ext <<EOF
-#line 2312 "configure"
+#line 2337 "configure"
 #include "confdefs.h"
 #include <gmp.h>
 #include <mpfr.h>
@@ -2316,7 +2341,7 @@ int main() {
 mpfr_t n; mpfr_init(n);
 ; return 0; }
 EOF
-if { (eval echo configure:2320: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
 else
@@ -3312,7 +3337,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3316: checking for $ac_word" >&5
+echo "configure:3341: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3352,7 +3377,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3356: checking for $ac_word" >&5
+echo "configure:3381: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_BISON'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3391,7 +3416,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3395: checking for $ac_word" >&5
+echo "configure:3420: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_M4'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3430,7 +3455,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3434: checking for $ac_word" >&5
+echo "configure:3459: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3470,7 +3495,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3474: checking for $ac_word" >&5
+echo "configure:3499: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_FLEX'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3509,7 +3534,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3513: checking for $ac_word" >&5
+echo "configure:3538: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3562,7 +3587,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3566: checking for $ac_word" >&5
+echo "configure:3591: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_EXPECT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3603,7 +3628,7 @@ do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3607: checking for $ac_word" >&5
+echo "configure:3632: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RUNTEST'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3651,7 +3676,7 @@ test -n "$target_alias" && ncn_target_tool_prefix=$target_alias-
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3655: checking for $ac_word" >&5
+echo "configure:3680: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3682,7 +3707,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3686: checking for $ac_word" >&5
+echo "configure:3711: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3726,7 +3751,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3730: checking for $ac_word" >&5
+echo "configure:3755: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3757,7 +3782,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3761: checking for $ac_word" >&5
+echo "configure:3786: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3801,7 +3826,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3805: checking for $ac_word" >&5
+echo "configure:3830: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3832,7 +3857,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3836: checking for $ac_word" >&5
+echo "configure:3861: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3876,7 +3901,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3880: checking for $ac_word" >&5
+echo "configure:3905: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3907,7 +3932,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3911: checking for $ac_word" >&5
+echo "configure:3936: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3951,7 +3976,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3955: checking for $ac_word" >&5
+echo "configure:3980: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LIPO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3982,7 +4007,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3986: checking for $ac_word" >&5
+echo "configure:4011: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LIPO'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4026,7 +4051,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4030: checking for $ac_word" >&5
+echo "configure:4055: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_NM'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4057,7 +4082,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4061: checking for $ac_word" >&5
+echo "configure:4086: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_NM'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4101,7 +4126,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4105: checking for $ac_word" >&5
+echo "configure:4130: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4132,7 +4157,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4136: checking for $ac_word" >&5
+echo "configure:4161: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4171,7 +4196,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4175: checking for $ac_word" >&5
+echo "configure:4200: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4202,7 +4227,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4206: checking for $ac_word" >&5
+echo "configure:4231: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4241,7 +4266,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4245: checking for $ac_word" >&5
+echo "configure:4270: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4272,7 +4297,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4276: checking for $ac_word" >&5
+echo "configure:4301: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_WINDRES'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4316,7 +4341,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4320: checking for $ac_word" >&5
+echo "configure:4345: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4347,7 +4372,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4351: checking for $ac_word" >&5
+echo "configure:4376: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_OBJCOPY'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4391,7 +4416,7 @@ fi
     # Extract the first word of "${ncn_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4395: checking for $ac_word" >&5
+echo "configure:4420: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4422,7 +4447,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4426: checking for $ac_word" >&5
+echo "configure:4451: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4473,7 +4498,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4477: checking for $ac_word" >&5
+echo "configure:4502: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4504,7 +4529,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4508: checking for $ac_word" >&5
+echo "configure:4533: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4548,7 +4573,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4552: checking for $ac_word" >&5
+echo "configure:4577: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AS_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4579,7 +4604,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4583: checking for $ac_word" >&5
+echo "configure:4608: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AS_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4623,7 +4648,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4627: checking for $ac_word" >&5
+echo "configure:4652: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4654,7 +4679,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4658: checking for $ac_word" >&5
+echo "configure:4683: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4698,7 +4723,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4702: checking for $ac_word" >&5
+echo "configure:4727: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CXX_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4729,7 +4754,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4733: checking for $ac_word" >&5
+echo "configure:4758: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CXX_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4773,7 +4798,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4777: checking for $ac_word" >&5
+echo "configure:4802: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4804,7 +4829,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4808: checking for $ac_word" >&5
+echo "configure:4833: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_DLLTOOL_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4848,7 +4873,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4852: checking for $ac_word" >&5
+echo "configure:4877: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GCC_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4879,7 +4904,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4883: checking for $ac_word" >&5
+echo "configure:4908: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GCC_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4918,7 +4943,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4922: checking for $ac_word" >&5
+echo "configure:4947: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GCJ_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4949,7 +4974,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4953: checking for $ac_word" >&5
+echo "configure:4978: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GCJ_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4993,7 +5018,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4997: checking for $ac_word" >&5
+echo "configure:5022: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GFORTRAN_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5024,7 +5049,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5028: checking for $ac_word" >&5
+echo "configure:5053: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_GFORTRAN_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5068,7 +5093,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5072: checking for $ac_word" >&5
+echo "configure:5097: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LD_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5099,7 +5124,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5103: checking for $ac_word" >&5
+echo "configure:5128: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LD_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5143,7 +5168,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5147: checking for $ac_word" >&5
+echo "configure:5172: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LIPO_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5174,7 +5199,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5178: checking for $ac_word" >&5
+echo "configure:5203: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LIPO_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5218,7 +5243,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5222: checking for $ac_word" >&5
+echo "configure:5247: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_NM_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5249,7 +5274,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5253: checking for $ac_word" >&5
+echo "configure:5278: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_NM_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5293,7 +5318,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5297: checking for $ac_word" >&5
+echo "configure:5322: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5324,7 +5349,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5328: checking for $ac_word" >&5
+echo "configure:5353: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_OBJDUMP_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5368,7 +5393,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5372: checking for $ac_word" >&5
+echo "configure:5397: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5399,7 +5424,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5403: checking for $ac_word" >&5
+echo "configure:5428: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5438,7 +5463,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5442: checking for $ac_word" >&5
+echo "configure:5467: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_STRIP_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5469,7 +5494,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5473: checking for $ac_word" >&5
+echo "configure:5498: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_STRIP_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5513,7 +5538,7 @@ fi
     # Extract the first word of "${ncn_target_tool_prefix}${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_target_tool_prefix}${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5517: checking for $ac_word" >&5
+echo "configure:5542: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_WINDRES_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5544,7 +5569,7 @@ fi
     # Extract the first word of "${ncn_progname}", so it can be a program name with args.
 set dummy ${ncn_progname}; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:5548: checking for $ac_word" >&5
+echo "configure:5573: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_WINDRES_FOR_TARGET'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5587,7 +5612,7 @@ fi
 RAW_CXX_FOR_TARGET="$CXX_FOR_TARGET"
 
 echo $ac_n "checking where to find the target ar""... $ac_c" 1>&6
-echo "configure:5591: checking where to find the target ar" >&5
+echo "configure:5616: checking where to find the target ar" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5612,7 +5637,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target as""... $ac_c" 1>&6
-echo "configure:5616: checking where to find the target as" >&5
+echo "configure:5641: checking where to find the target as" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5637,7 +5662,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target cc""... $ac_c" 1>&6
-echo "configure:5641: checking where to find the target cc" >&5
+echo "configure:5666: checking where to find the target cc" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5662,7 +5687,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target c++""... $ac_c" 1>&6
-echo "configure:5666: checking where to find the target c++" >&5
+echo "configure:5691: checking where to find the target c++" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5690,7 +5715,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target c++ for libstdc++""... $ac_c" 1>&6
-echo "configure:5694: checking where to find the target c++ for libstdc++" >&5
+echo "configure:5719: checking where to find the target c++ for libstdc++" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5718,7 +5743,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target dlltool""... $ac_c" 1>&6
-echo "configure:5722: checking where to find the target dlltool" >&5
+echo "configure:5747: checking where to find the target dlltool" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5743,7 +5768,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target gcc""... $ac_c" 1>&6
-echo "configure:5747: checking where to find the target gcc" >&5
+echo "configure:5772: checking where to find the target gcc" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5768,7 +5793,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target gcj""... $ac_c" 1>&6
-echo "configure:5772: checking where to find the target gcj" >&5
+echo "configure:5797: checking where to find the target gcj" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5796,7 +5821,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target gfortran""... $ac_c" 1>&6
-echo "configure:5800: checking where to find the target gfortran" >&5
+echo "configure:5825: checking where to find the target gfortran" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5824,7 +5849,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target ld""... $ac_c" 1>&6
-echo "configure:5828: checking where to find the target ld" >&5
+echo "configure:5853: checking where to find the target ld" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5849,7 +5874,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target lipo""... $ac_c" 1>&6
-echo "configure:5853: checking where to find the target lipo" >&5
+echo "configure:5878: checking where to find the target lipo" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5864,7 +5889,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target nm""... $ac_c" 1>&6
-echo "configure:5868: checking where to find the target nm" >&5
+echo "configure:5893: checking where to find the target nm" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5889,7 +5914,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target objdump""... $ac_c" 1>&6
-echo "configure:5893: checking where to find the target objdump" >&5
+echo "configure:5918: checking where to find the target objdump" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5914,7 +5939,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target ranlib""... $ac_c" 1>&6
-echo "configure:5918: checking where to find the target ranlib" >&5
+echo "configure:5943: checking where to find the target ranlib" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5939,7 +5964,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target strip""... $ac_c" 1>&6
-echo "configure:5943: checking where to find the target strip" >&5
+echo "configure:5968: checking where to find the target strip" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -5964,7 +5989,7 @@ else
   fi
 fi
 echo $ac_n "checking where to find the target windres""... $ac_c" 1>&6
-echo "configure:5968: checking where to find the target windres" >&5
+echo "configure:5993: checking where to find the target windres" >&5
 if test "x${build}" != "x${host}" ; then
   # Canadian cross, just use what we found
   echo "$ac_t""pre-installed" 1>&6
@@ -6017,7 +6042,7 @@ fi
 
 
 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:6021: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:6046: checking whether to enable maintainer-specific portions of Makefiles" >&5
 # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
   enableval="$enable_maintainer_mode"
@@ -6142,15 +6167,34 @@ trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
 # Transform confdefs.h into DEFS.
 # Protect against shell expansion while executing Makefile rules.
 # Protect against Makefile macro expansion.
-cat > conftest.defs <<\EOF
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
-s%[    `~#$^&*(){}\\|;'"<>?]%\\&%g
-s%\[%\\&%g
-s%\]%\\&%g
-s%\$%$$%g
-EOF
-DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
-rm -f conftest.defs
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[   ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[   ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[    `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
 
 
 # Without the "./", some shells look in PATH for config.status.
index b2e8414..401d2dc 100644 (file)
@@ -151,7 +151,8 @@ target_libraries="target-libiberty \
                target-libgfortran \
                ${libgcj} \
                target-libobjc \
-               target-libada"
+               target-libada \
+               target-libgomp"
 
 # these tools are built using the target libraries, and are intended to
 # run only in the target environment
@@ -341,7 +342,7 @@ no)
     ;;
 "")
     case "${target}" in
-    *-*-linux*-gnu | *-*-gnu* | *-*-k*bsd*-gnu)
+    *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu)
         # Enable libmudflap by default in GNU and friends.
        ;;
     *-*-freebsd*)
@@ -354,6 +355,30 @@ no)
     esac
 esac
 
+# Allow --disable-libgomp to exclude target-libgomp
+case $enable_libgomp in
+yes)
+    ;;
+no)
+    noconfigdirs="$noconfigdirs target-libgomp"
+    ;;
+"")
+    # Enable libgomp by default on hosted POSIX systems.
+    case "${target}" in
+    *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu)
+       ;;
+    *-*-netbsd* | *-*-freebsd* | *-*-openbsd*)
+       ;;
+    *-*-solaris2* | *-*-sysv4* | *-*-irix* | *-*-osf* | *-*-hpux*)
+       ;;
+    *-*-darwin*)
+       ;;
+    *)
+       noconfigdirs="$noconfigdirs target-libgomp"
+       ;;
+    esac
+esac
+
 
 case "${target}" in
   *-*-chorusos)
index dd758fc..8b310e1 100644 (file)
@@ -1,3 +1,8 @@
+2006-01-18  Richard Henderson  <rth@redhat.com>
+           Diego Novillo  <dnovillo@redhat.com>
+
+       * gcc_update (files_and_dependencies): Add libgomp files.
+
 2005-12-06  Ben Elliston  <bje@au.ibm.com>
 
        * newcvsroot: Remove.
index 5dfc419..0ec3739 100755 (executable)
@@ -112,6 +112,10 @@ libjava/libltdl/config-h.in: libjava/libltdl/configure.ac libjava/libltdl/acloca
 libcpp/aclocal.m4: libcpp/configure.ac
 libcpp/Makefile.in: libcpp/configure.ac libcpp/aclocal.m4
 libcpp/configure: libcpp/configure.ac libcpp/aclocal.m4
+libgomp/aclocal.m4: libgomp/configure.ac libgomp/acinclude.m4
+libgomp/Makefile.in: libgomp/Makefile.am libgomp/aclocal.m4
+libgomp/configure: libgomp/configure.ac libgomp/aclocal.m4
+libgomp/config.h.in: libgomp/configure.ac libgomp/aclocal.m4
 # Top level
 Makefile.in: Makefile.tpl Makefile.def
 configure: configure.in config/acx.m4
index 1f6041c..b57d517 100644 (file)
@@ -1,3 +1,353 @@
+2006-01-18  Richard Henderson  <rth@redhat.com>
+           Aldy Hernandez  <aldyh@redhat.com>
+           Jakub Jelinek  <jakub@redhat.com>
+           Diego Novillo  <dnovillo@redhat.com>
+
+       * omp-low.c: New file.
+       * c-omp.c: New file.
+
+2006-01-18  Richard Henderson  <rth@redhat.com>
+           Jakub Jelinek  <jakub@redhat.com>
+           Diego Novillo  <dnovillo@redhat.com>
+
+       * doc/invoke.texi: Document -fopenmp.
+       * tree-dump.h (debug_function): Declare.
+       * hooks.c (hook_bool_tree_bool_false): New function.
+       (hook_tree_tree_null): Remove.
+       (hook_tree_tree_tree_null): New.
+       * hooks.h: Update to match.
+       * tree-pretty-print.c (debug_tree_chain): New.
+       (print_generic_expr): Handle TDF_CHAIN.
+       (dump_generic_node): Handle BLOCK.
+       Do not abort with incomplete SWITCH_EXPRs.
+       Do not dump body of an OpenMP directive if TDF_SLIM is given.
+       <case OMP_PARALLEL, OMP_FOR, OMP_SECTIONS>: Don't
+       print space after directive name.
+       <OMP_FOR>: Handle printing OMP_FOR_PRE_BODY.
+       Handle OMP_MASTER and OMP_ORDERED.
+       Handle printing of OMP_BODY just in one place, goto
+       dump_omp_body in the rest of OMP_* nodes that have
+       OMP_BODY.
+       Don't handle clause nodes here.  Update omp statements to
+       use dump_omp_clauses.
+       Handle OMP_SINGLE, OMP_SECTIONS, OMP_SECTION,
+       OMP_CLAUSE_ORDERED, OMP_CLAUSE_SCHEDULE, OMP_ATOMIC,
+       OMP_CRITICAL, OMP_CLAUSE_NOWAIT, GOMP_CLAUSE_IF,
+       GOMP_CLAUSE_NUM_THREADS, GOMP_FOR, GOMP_CLAUSE_SHARED,
+       GOMP_CLAUSE_FIRSTPRIVATE, GOMP_CLAUSE_LASTPRIVATE,
+       GOMP_CLAUSE_COPYIN and GOMP_CLAUSE_COPYPRIVATE.
+       Adjust output for GOMP_PARALLEL.
+       (dump_omp_clauses): New.
+       (print_declaration): Dump DECL_VALUE_EXPR.
+       (op_symbol_1): Split out of op_symbol.
+       (dumping_stmts): Remove.  Update all users.
+       * cgraph.c (cgraph_analyze_queue): New.
+       (cgraph_add_new_function): New.
+       * cgraph.h (cgraph_analyze_queue): Declare.
+       (cgraph_add_new_function): Declare.
+       (cgraph_lower_function): Remove.
+       * tree.c (walk_tree): Walk OMP_CLAUSE_CHAIN of OMP_CLAUSE_*
+       nodes.  Use switch for all nodes, handle most of IS_EXPR_CODE_CLASS
+       and TYPE_P nodes in its default clause.
+       (empty_body_p): New.
+       (tree_range_check_failed): New.
+       (build5_stat): New.
+       * tree.h (OMP_CLAUSE_REDUCTION_INIT,
+       OMP_CLAUSE_REDUCTION_MERGE,
+       OMP_CLAUSE_REDUCTION_PLACEHOLDER,
+       OMP_CLAUSE_PRIVATE_DEBUG,
+       OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE, OMP_FOR_PRE_BODY,
+       OMP_MASTER_BODY, OMP_ORDERED_BODY OMP_BODY,
+       OMP_CLAUSES, OMP_CLAUSE_DECL, OMP_CLAUSE_DEFAULT_KIND,
+       OMP_CLAUSE_CHAIN, OMP_CLAUSE_OUTER_DECL,
+       OMP_CLAUSE_INNER_DECL, OMP_CLAUSE_NUM_THREADS_EXPR,
+       OMP_CLAUSE_IF_EXPR, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR,
+       OMP_CLAUSE_SCHEDULE_CHUNK_SIZE. OMP_PARALLEL_VAR_INIT,
+       OMP_PARALLEL_VAR_REDUC, OMP_FOR_VAR_INIT,
+       OMP_FOR_VAR_LAST, OMP_FOR_VAR_REDUC,
+       OMP_SECTIONS_VAR_INIT, OMP_SECTIONS_VAR_LAST,
+       OMP_SECTIONS_VAR_REDUC, OMP_CLAUSE_REDUCTION_CODE
+       OMP_SINGLE_CLAUSES, OMP_SINGLE_BODY,
+       OMP_CLAUSE_SCHEDULE_CHUNK_SIZE, OMP_SECTION_BODY,
+       OMP_CRITICAL_NAME, OMP_CRITICAL_BODY): New.
+       (TREE_RANGE_CHECK): New.
+       (empty_body_p): Declare.
+       (enum omp_clause_default_kind): New.
+       (build_string_literal): Declare.
+       (enum omp_clause_schedule_kind, OMP_CLAUSE_SCHEDULE_KIND): New.
+       (build5_stat, build5): Declare.
+       * tree-pass.h (TDF_CHAIN): Define.
+       * tree-pass.h (PROP_gimple_lomp): Define.
+       (pass_lower_omp): Declare.
+       * diagnostic.h (debug_tree_chain): Declare.
+       * builtins.c (get_builtin_sync_mode): Use 0 as last argument to
+       mode_for_size.
+       (expand_builtin): Handle sync BUILT_IN_*_16 builtins.
+       * builtins.c (build_string_literal): Make extern.
+       * gcc.c (include_spec_function): New.
+       (static_spec_functions): Add it.
+       (main): Move load of libgomp.spec ...
+       (LINK_COMMAND_SPEC): ... here.
+       (link_gomp_spec): New.
+       (static_specs): Include it.
+       (LINK_COMMAND_SPEC): Add link_gomp.
+       (GOMP_SELF_SPECS): New.
+       (driver_self_specs): Include it.
+       (switch_matches): Don't mark inline.
+       (main): Load libgomp.spec.
+       * tree-gimple.c (is_gimple_stmt): True for OMP_MASTER,
+       OMP_ORDERED, OMP_CRITICAL, OMP_SECTIONS, OMP_SECTION,
+       and OMP_SINGLE, OMP_FOR and OMP_PARALLEL.
+       * tree-gimple.h (enum omp_parallel): Declare.
+       (determine_parallel_type): Declare.
+       (omp_firstprivatize_variable): Declare.
+       (omp_reduction_init): Declare.
+       (diagnose_omp_structured_block_errors): Declare.
+       (struct walk_stmt_info): Add want_return_expr.
+       (struct walk_stmt_info): Add want_bind_expr, want_locations.
+       (find_omp_clause): Declare.
+       (insert_field_into_struct): Declare.
+       (struct walk_stmt_info): Move from tree-nested.c
+       (walk_stmts): Declare.
+       * c-cppbuiltin.c (c_cpp_builtins): If -fopenmp, #define _OPENMP
+       to 200505.
+       * cgraphunit.c (cgraph_lower_function): Make static.
+       (cgraph_finalize_pending_functions): New.
+       (cgraph_finalize_function): Call it.
+       (cgraph_finalize_compilation_unit): Likewise.
+       * builtin-types.def (BT_I16, BT_FN_I16_VPTR_I16,
+       BT_FN_BOOL_VPTR_I16_I16, BT_FN_I16_VPTR_I16_I16): Add.
+       (BT_FN_UINT_UINT): New.
+       (DEF_FUNCTION_TYPE_6, DEF_FUNCTION_TYPE_7,
+       DEF_FUNCTION_TYPE_VAR_4): Document.
+       (BT_PTR_LONG, BT_PTR_PTR, BT_FN_BOOL, BT_FN_INT,
+       BT_FN_VOID_PTRPTR, BT_PTR_FN_VOID_PTR,
+       BT_FN_BOOL_LONGPTR_LONGPTR, BT_FN_VOID_OMPFN_PTR_UINT,
+       BT_FN_VOID_OMPFN_PTR_UINT_UINT,
+       BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
+       BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+       BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
+       BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG): New.
+       * builtins.def: Update DEF_BUILTIN comment to include COND argument.
+       Move all DEF_SYNC_BUILTIN () and DEF_GOMP_BUILTIN () builtins
+       into separate files.
+       (DEF_GOMP_BUILTIN): New.
+       (BUILT_IN_OMP_GET_THREAD_NUM, BUILT_IN_GOMP_BARRIER,
+       BUILT_IN_GOMP_CRITICAL_START, BUILT_IN_GOMP_CRITICAL_END,
+       BUILT_IN_GOMP_CRITICAL_NAME_START, BUILT_IN_GOMP_CRITICAL_NAME_END,
+       BUILT_IN_GOMP_LOOP_STATIC_START, BUILT_IN_GOMP_LOOP_DYNAMIC_START,
+       BUILT_IN_GOMP_LOOP_GUIDED_START, BUILT_IN_GOMP_LOOP_RUNTIME_START,
+       BUILT_IN_GOMP_LOOP_ORDERED_STATIC_START,
+       BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_START,
+       BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_START,
+       BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_START,
+       BUILT_IN_GOMP_LOOP_STATIC_NEXT, BUILT_IN_GOMP_LOOP_DYNAMIC_NEXT,
+       BUILT_IN_GOMP_LOOP_GUIDED_NEXT, BUILT_IN_GOMP_LOOP_RUNTIME_NEXT,
+       BUILT_IN_GOMP_LOOP_ORDERED_STATIC_NEXT,
+       BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_NEXT,
+       BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_NEXT,
+       BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_NEXT,
+       BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START,
+       BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC_START,
+       BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED_START,
+       BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME_START,
+       BUILT_IN_GOMP_LOOP_END, BUILT_IN_GOMP_LOOP_END_NOWAIT,
+       BUILT_IN_GOMP_ORDERED_START, BUILT_IN_GOMP_ORDERED_END,
+       BUILT_IN_GOMP_PARALLEL_START, BUILT_IN_GOMP_PARALLEL_END,
+       BUILT_IN_GOMP_SECTIONS_START, BUILT_IN_GOMP_SECTIONS_NEXT,
+       BUILT_IN_GOMP_PARALLEL_SECTIONS_START, BUILT_IN_GOMP_SECTIONS_END,
+       BUILT_IN_GOMP_SECTIONS_END_NOWAIT, BUILT_IN_GOMP_SINGLE_START,
+       BUILT_IN_GOMP_SINGLE_COPY_START, BUILT_IN_GOMP_SINGLE_COPY_END): New.
+       * sync-builtins.def: New file, moved from builtins.def.
+       * omp-builtins.def: New file, moved from builtins.def.
+       * c-objc-common.h (LANG_HOOKS_OMP_PREDETERMINED_SHARING): Redefine.
+       * gimple-low.c (lower_function_body): Clear data.
+       (lower_stmt): Do not handle COMPOUND_EXPR.
+       Remove call to print_node_brief.
+       * c-tree.h (c_finish_omp_clauses): New prototype.
+       (C_DECL_THREADPRIVATE_P): Define.
+       (lookup_name_no_remap, c_omp_remap_private): Remove
+       (c_begin_omp_parallel, c_finish_omp_parallel): Update.
+       (check_for_loop_decls): Update decl.
+       (lookup_name_no_remap, c_omp_remap_private): Declare.
+       (build_indirect_ref, build_modify_expr, pushdecl,
+       pushdecl_top_level): Move to c-common.h.
+       * dwarf2out.c (loc_descriptor_from_tree_1): Don't set unsignedp
+       before the switch, but just in the 2 places that need it.
+       * c-decl.c (diagnose_mismatched_decls): Do not check for
+       mismatched thread-local attributes when OLDDECL is marked
+       threadprivate and NEWDECL has no thread-local attributes.
+       (merge_decls): Merge C_DECL_THREADPRIVATE_P.
+       (c_gimple_diagnostics_recursively): Rename from
+       c_warn_unused_result_recursively.  Invoke
+       diagnose_omp_structured_block_errors.
+       (check_for_loop_decls): Return a singular decl found.
+       * langhooks.c (lhd_omp_predetermined_sharing): Return
+       OMP_CLAUSE_DEFAULT_SHARED for DECL_ARTIFICIAL decls.
+       (lhd_omp_firstprivatize_type_sizes): New.
+       (lhd_omp_assignment): New.
+       (lhd_omp_predetermined_sharing): New.
+       * langhooks.h (struct gimplify_omp_ctx): Forward declare.
+       (struct lang_hooks_for_types): Add
+       omp_firstprivatize_type_sizes, omp_privatize_by_reference,
+       omp_predetermined_sharing, omp_disregard_value_expr,
+       omp_private_debug_clause, omp_clause_default_ctor,
+       omp_clause_copy_ctor, omp_clause_assign_op, omp_clause_dtor.
+       (c_finish_omp_clauses): New.
+       (c_finish_bc_stmt): Diagnose break within omp for.
+       (c_begin_omp_parallel, c_finish_omp_parallel): New.
+       (build_unary_op): Return error_mark after reporting
+       a readonly_error.
+       (build_modify_expr): Likewise.
+       * gimplify.c: Include optabs.h and pointer-set.h.
+       (enum gimplify_omp_var_data): Declare.
+       (struct gimplify_omp_ctx): Declare.
+       (struct gimplify_ctx): Add fields prev_context, combined_pre_p
+       and combined_ctxp.
+       (gimplify_ctxp, gimplify_omp_ctxp): New local variables.
+       (push_gimplify_context, pop_gimplify_context): Allow nesting.
+       (splay_tree_compare_decl_uid): New.
+       (new_omp_context): New.
+       (delete_omp_context): New.
+       (gimple_add_tmp_var): Call omp_add_variable.
+       (gimplify_bind_expr): Likewise.
+       (gimplify_var_or_parm_decl): If omp_notice_variable returned
+       true, disregard DECL_VALUE_EXPR on the decl if any.
+       (gimplify_expr_in_ctx): New.
+       (omp_firstprivatize_variable, omp_firstprivatize_type_sizes
+       omp_add_variable, omp_notice_variable, omp_is_private
+       gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses_1
+       gimplify_adjust_omp_clauses, gimplify_omp_parallel
+       gimplify_omp_for, gimplify_omp_workshare, goa_lhs_expr_p
+       gimplify_omp_atomic_fetch_op, goa_stabilize_expr
+       gimplify_omp_atomic_pipeline, gimplify_omp_atomic_mutex
+       gimplify_omp_atomic): New.
+       (gimplify_expr): Handle OMP_PARALLEL, OMP_FOR, OMP_SECTIONS,
+       OMP_SINGLE, OMP_SECTION, OMP_MASTER, OMP_ORDERED,
+       OMP_CRITICAL and OMP_ATOMIC.
+       (gimplify_body): Verify gimplify_ctxp is empty after gimplification.
+       * c-pragma.h (enum pragma_kind): Add
+       PRAGMA_OMP_ATOMIC, PRAGMA_OMP_BARRIER,
+       PRAGMA_OMP_CRITICAL, PRAGMA_OMP_FLUSH, PRAGMA_OMP_FOR,
+       PRAGMA_OMP_MASTER, PRAGMA_OMP_ORDERED,
+       PRAGMA_OMP_PARALLEL, PRAGMA_OMP_PARALLEL_FOR,
+       PRAGMA_OMP_PARALLEL_SECTIONS, PRAGMA_OMP_SECTION,
+       PRAGMA_OMP_SECTIONS, PRAGMA_OMP_SINGLE,
+       PRAGMA_OMP_THREADPRIVATE.
+       * tree.def (OMP_PARALLEL, OMP_FOR, OMP_SECTIONS,
+       OMP_SINGLE, OMP_SECTION, OMP_MASTER, OMP_ORDERED,
+       OMP_CRITICAL, OMP_ATOMIC, OMP_CLAUSE_PRIVATE,
+       OMP_CLAUSE_SHARED, OMP_CLAUSE_FIRSTPRIVATE,
+       OMP_CLAUSE_LASTPRIVATE, OMP_CLAUSE_REDUCTION,
+       OMP_CLAUSE_COPYIN, OMP_CLAUSE_COPYPRIVATE,
+       OMP_CLAUSE_IF, OMP_CLAUSE_NUM_THREADS,
+       OMP_CLAUSE_SCHEDULE, OMP_CLAUSE_NOWAIT,
+       OMP_CLAUSE_ORDERED, OMP_CLAUSE_DEFAULT): Define.
+       * print-tree.c (print_node): Dump DECL_VALUE_EXPR.
+       * tree-ssa-dce.c (find_control_dependence): Do not assume that
+       ENTRY_BLOCK_PTR->next_bb == single_succ (ENTRY_BLOCK_PTR).
+       * tree-nested.c (convert_call_expr): Call walk_body on OMP_BODY for
+       OpenMP directives.
+       (struct nesting_info): Add field_map,
+       suppress_expansion, debug_var_chain.
+       (create_nesting_tree): Initialize them.
+       (lookup_field_for_decl): Use field_map.
+       (get_nonlocal_debug_decl, get_local_debug_decl): New.
+       (convert_local_omp_clauses): New.
+       (finalize_nesting_tree_1): Add debug_var_chain to toplevel block.
+       (walk_body): Split out of walk_function.
+       (convert_nonlocal_omp_clauses, convert_local_omp_clauses): New.
+       (convert_nonlocal_reference): Handle omp statements.
+       (convert_local_reference): Likewise.
+       (unnest_nesting_tree_1): Split out of finalize_nesting_tree_1.
+       (unnest_nesting_tree): New.
+       (lower_nested_functions): Call it.
+       (insert_field_into_struct): Make extern.
+       (struct walk_stmt_info): Move to tree-gimple.h.
+       (walk_stmts): Make extern.
+       * omp-builtins.def: New file.
+       * tree-iterator.c (expr_only): Clarify comment.
+       * c-common.h (pushdecl_top_level, pushdecl,
+       build_modify_expr, build_indirect_ref,
+       c_finish_omp_master, c_finish_omp_critical,
+       c_finish_omp_ordered, c_finish_omp_barrier,
+       c_finish_omp_atomic, c_finish_omp_flush,
+       c_finish_omp_for, c_split_parallel_clauses,
+       omp_clause_default_kind, c_omp_sharing_predetermined,
+       c_omp_remap_decl): Declare.
+       * Makefile.in (BUILTINS_DEF): Add omp-builtins.def.
+       (OBJS-common): Add omp-low.o.
+       (c-omp.o, omp-low.o): Add.
+       (gimplify.o): Add dependency on $(OPTABS_H).
+       (GTFILES): Add omp-low.c.
+       (gt-stringpool.h): Add.
+       * tree-cfg.c (set_bb_for_stmt): Do not update the
+       block-to-labels map if we are currently expanding to RTL.
+       (tree_node_can_be_shared): Remove unnecessary CONSTANT_CLASS_P
+       checks.
+       Handle IDENTIFIER_NODE.
+       (tree_verify_flow_info): Do not ICE when emitting error
+       messages about invalid labels.
+       (dump_function_to_file): Reset CFUN before emitting the body
+       of the function.
+       (debug_function): New.
+       * passes.c (init_optimization_passes): Schedule
+       pass_lower_omp.
+       * langhooks-def.h (lhd_omp_predetermined_sharing,
+       lhd_omp_assignment, lhd_omp_firstprivatize_type_sizes):
+       Declare.
+       (LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES): Define.
+       (LANG_HOOKS_FOR_TYPES_INITIALIZER): Use it.
+       (LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE,
+       LANG_HOOKS_OMP_PREDETERMINED_SHARING,
+       LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR,
+       LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE,
+       LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR,
+       LANG_HOOKS_OMP_CLAUSE_COPY_CTOR,
+       LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP,
+       LANG_HOOKS_OMP_CLAUSE_DTOR): Define.
+       (LANG_HOOK_DECLS): Use them.
+
+2006-01-18  Dmitry Kurochkin <dmitry.kurochkin@gmail.com>
+           Richard Henderson  <rth@redhat.com>
+           Jakub Jelinek  <jakub@redhat.com>
+           Diego Novillo  <dnovillo@redhat.com>
+
+       * c-parser.c (pragma_omp_clause): Define.
+       (c_parser_declaration_or_fndef): Document OpenMP syntax.
+       (c_parser_compound_statement): Likewise.
+       (c_parser_statement): Likewise.
+       (c_parser_pragma): Handle omp pragmas.
+       (OMP_FOR_CLAUSE_MASK, OMP_SECTIONS_CLAUSE_MASK,
+       OMP_PARALLEL_CLAUSE_MASK, OMP_SINGLE_CLAUSE_MASK): Define.
+       (c_parser_omp_clause_name, check_no_duplicate_clause,
+       c_parser_omp_variable_list,
+       c_parser_omp_var_list_parens, c_parser_omp_clause_copyin,
+       c_parser_omp_clause_copyprivate,
+       c_parser_omp_clause_default,
+       c_parser_omp_clause_firstprivate, c_parser_omp_clause_if,
+       c_parser_omp_clause_lastprivate,
+       c_parser_omp_clause_nowait,
+       c_parser_omp_clause_num_threads,
+       c_parser_omp_clause_ordered, c_parser_omp_clause_private,
+       c_parser_omp_clause_reduction,
+       c_parser_omp_clause_schedule, c_parser_omp_clause_shared,
+       c_parser_omp_all_clauses, c_parser_omp_structured_block,
+       c_parser_omp_atomic, c_parser_omp_barrier,
+       c_parser_omp_critical, c_parser_omp_flush,
+       c_parser_omp_for_loop, c_parser_omp_for,
+       c_parser_omp_master, c_parser_omp_ordered,
+       c_parser_omp_sections_scope, c_parser_omp_sections,
+       c_parser_omp_parallel, c_parser_omp_single,
+       c_parser_omp_construct, c_parser_omp_threadprivate): New.
+       * c-pragma.c (init_pragma): Do omp pragma registration here.
+       * c.opt (fopenmp): New flag.
+
+2006-01-18  Eric Christopher  <echristo@apple.com>
+
+       * gcc.c (GOMP_SELF_SPECS): Bracket in #ifndef/#endif.
+       * config/darwin.h (GOMP_SELF_SPECS): Define.
+
 2006-01-18  Kazu Hirata  <kazu@codesourcery.com>
 
        * rtl.h: Remove the prototype for reg_alloc.
index a993f97..dd2c845 100644 (file)
@@ -737,7 +737,7 @@ RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H) reg-notes.def insn-notes.def \
   input.h real.h statistics.h
 RTL_H = $(RTL_BASE_H) genrtl.h
 PARAMS_H = params.h params.def
-BUILTINS_DEF = builtins.def sync-builtins.def
+BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def
 TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
           input.h statistics.h vec.h treestruct.def
 BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
@@ -948,7 +948,7 @@ C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
   c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
   c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
   c-objc-common.o c-dump.o c-pch.o c-parser.o $(C_TARGET_OBJS) \
-  c-gimplify.o tree-mudflap.o c-pretty-print.o
+  c-gimplify.o tree-mudflap.o c-pretty-print.o c-omp.o
 
 # Language-specific object files for C.
 C_OBJS = c-lang.o stub-objc.o $(C_AND_OBJC_OBJS)
@@ -963,7 +963,7 @@ OBJS-common = \
  tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o       \
  tree-ssa-phiopt.o tree-ssa-forwprop.o tree-nested.o tree-ssa-dse.o       \
  tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o    \
tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o                \
omp-low.o tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o      \
  tree-vect-generic.o tree-ssa-loop.o tree-ssa-loop-niter.o                \
  tree-ssa-loop-manip.o tree-ssa-threadupdate.o                            \
  tree-vectorizer.o tree-vect-analyze.o tree-vect-transform.o              \
@@ -1671,6 +1671,9 @@ c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) $(TREE_H) \
          -DHOST_MACHINE=\"$(host)\" -DTARGET_MACHINE=\"$(target)\" \
          $< $(OUTPUT_OPTION)
 
+c-omp.o : c-omp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+       $(FUNCTION_H) $(C_COMMON_H) toplev.h $(TREE_GIMPLE_H)
+
 # Language-independent files.
 
 DRIVER_DEFINES = \
@@ -2034,12 +2037,16 @@ gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
    $(DIAGNOSTIC_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \
    $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
    coretypes.h except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \
-   $(GGC_H) gt-gimplify.h $(HASHTAB_H) real.h $(TARGET_H) toplev.h
+   $(GGC_H) gt-gimplify.h $(HASHTAB_H) real.h $(TARGET_H) toplev.h $(OPTABS_H)
 gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
    $(DIAGNOSTIC_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \
    $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
    except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) tree-pass.h \
    $(HASHTAB_H) toplev.h
+omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+   $(RTL_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_H) \
+   $(TREE_FLOW_H) $(TIMEVAR_H) $(FLAGS_H) $(EXPR_H) toplev.h tree-pass.h \
+   $(GGC_H)
 tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) \
    $(TM_H) coretypes.h
@@ -2859,7 +2866,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \
   $(srcdir)/tree-profile.c $(srcdir)/tree-nested.c \
   $(srcdir)/ipa-reference.c $(srcdir)/tree-ssa-structalias.h \
   $(srcdir)/tree-ssa-structalias.c \
-  $(srcdir)/c-pragma.h \
+  $(srcdir)/c-pragma.h $(srcdir)/omp-low.c \
   $(srcdir)/targhooks.c $(out_file) \
   @all_gtfiles@
 
@@ -2893,7 +2900,7 @@ gt-tree-ssanames.h gt-tree-iterator.h gt-gimplify.h \
 gt-tree-phinodes.h gt-tree-nested.h \
 gt-tree-ssa-operands.h gt-tree-ssa-propagate.h \
 gt-tree-ssa-structalias.h \
-gt-stringpool.h gt-targhooks.h : s-gtype ; @true
+gt-stringpool.h gt-targhooks.h gt-omp-low.h : s-gtype ; @true
 
 define echo_quoted_to_gtyp
  echo "\"$(gtyp)\", " >> tmp-gtyp.h
index 9540f3a..1e97d6e 100644 (file)
@@ -33,6 +33,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    DEF_FUNCTION_TYPE_3 (ENUM, RETURN, ARG1, ARG2, ARG3)
    DEF_FUNCTION_TYPE_4 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4)
    DEF_FUNCTION_TYPE_5 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)
+   DEF_FUNCTION_TYPE_6 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6)
+   DEF_FUNCTION_TYPE_7 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7)
 
      These macros describe function types.  ENUM is as above.  The
      RETURN type is one of the enumerals already defined.  ARG1, ARG2,
@@ -43,6 +45,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    DEF_FUNCTION_TYPE_VAR_2 (ENUM, RETURN, ARG1, ARG2)
    DEF_FUNCTION_TYPE_VAR_3 (ENUM, RETURN, ARG1, ARG2, ARG3)
    DEF_FUNCTION_TYPE_VAR_4 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4)
+   DEF_FUNCTION_TYPE_VAR_4 (ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5)
 
      Similar, but for function types that take variable arguments.
      For example:
@@ -115,10 +118,14 @@ DEF_PRIMITIVE_TYPE (BT_I8, builtin_type_for_size (BITS_PER_UNIT*8, 1))
 DEF_PRIMITIVE_TYPE (BT_I16, builtin_type_for_size (BITS_PER_UNIT*16, 1))
 
 DEF_POINTER_TYPE (BT_PTR_CONST_STRING, BT_CONST_STRING)
+DEF_POINTER_TYPE (BT_PTR_LONG, BT_LONG)
+DEF_POINTER_TYPE (BT_PTR_PTR, BT_PTR)
 
 DEF_FUNCTION_TYPE_0 (BT_FN_VOID, BT_VOID)
+DEF_FUNCTION_TYPE_0 (BT_FN_BOOL, BT_BOOL)
 DEF_FUNCTION_TYPE_0 (BT_FN_PTR, BT_PTR)
 DEF_FUNCTION_TYPE_0 (BT_FN_PID, BT_PID)
+DEF_FUNCTION_TYPE_0 (BT_FN_INT, BT_INT)
 DEF_FUNCTION_TYPE_0 (BT_FN_UINT, BT_UINT)
 DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT, BT_FLOAT)
 DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
@@ -194,6 +201,10 @@ DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT32_DFLOAT32, BT_DFLOAT32, BT_DFLOAT32)
 DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64_DFLOAT64, BT_DFLOAT64, BT_DFLOAT64)
 DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT128_DFLOAT128, BT_DFLOAT128, BT_DFLOAT128)
 DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VPTR, BT_VOID, BT_VOLATILE_PTR)
+DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTRPTR, BT_VOID, BT_PTR_PTR)
+DEF_FUNCTION_TYPE_1 (BT_FN_UINT_UINT, BT_UINT, BT_UINT)
+
+DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
 
 DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_INT, BT_VOID, BT_PTR, BT_INT)
 DEF_FUNCTION_TYPE_2 (BT_FN_STRING_STRING_CONST_STRING, 
@@ -281,6 +292,8 @@ DEF_FUNCTION_TYPE_2 (BT_FN_I2_VPTR_I2, BT_I2, BT_VOLATILE_PTR, BT_I2)
 DEF_FUNCTION_TYPE_2 (BT_FN_I4_VPTR_I4, BT_I4, BT_VOLATILE_PTR, BT_I4)
 DEF_FUNCTION_TYPE_2 (BT_FN_I8_VPTR_I8, BT_I8, BT_VOLATILE_PTR, BT_I8)
 DEF_FUNCTION_TYPE_2 (BT_FN_I16_VPTR_I16, BT_I16, BT_VOLATILE_PTR, BT_I16)
+DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_LONGPTR_LONGPTR,
+                    BT_BOOL, BT_PTR_LONG, BT_PTR_LONG)
 
 DEF_FUNCTION_TYPE_3 (BT_FN_STRING_STRING_CONST_STRING_SIZE,
                     BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE)
@@ -343,6 +356,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_I4_VPTR_I4_I4, BT_I4, BT_VOLATILE_PTR, BT_I4, BT_I4)
 DEF_FUNCTION_TYPE_3 (BT_FN_I8_VPTR_I8_I8, BT_I8, BT_VOLATILE_PTR, BT_I8, BT_I8)
 DEF_FUNCTION_TYPE_3 (BT_FN_I16_VPTR_I16_I16, BT_I16, BT_VOLATILE_PTR,
                     BT_I16, BT_I16)
+DEF_FUNCTION_TYPE_3 (BT_FN_VOID_OMPFN_PTR_UINT, BT_VOID, BT_PTR_FN_VOID_PTR,
+                    BT_PTR, BT_UINT)
 
 DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
                     BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
@@ -358,14 +373,29 @@ DEF_FUNCTION_TYPE_4 (BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE,
                     BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE, BT_SIZE)
 DEF_FUNCTION_TYPE_4 (BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG,
                     BT_INT, BT_FILEPTR, BT_INT, BT_CONST_STRING, BT_VALIST_ARG)
+DEF_FUNCTION_TYPE_4 (BT_FN_VOID_OMPFN_PTR_UINT_UINT,
+                    BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT, BT_UINT)
 
 DEF_FUNCTION_TYPE_5 (BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VALIST_ARG,
                     BT_INT, BT_STRING, BT_INT, BT_SIZE, BT_CONST_STRING,
                     BT_VALIST_ARG)
+DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                    BT_BOOL, BT_LONG, BT_LONG, BT_LONG,
+                    BT_PTR_LONG, BT_PTR_LONG)
 
 DEF_FUNCTION_TYPE_6 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG,
                     BT_INT, BT_STRING, BT_SIZE, BT_INT, BT_SIZE,
                     BT_CONST_STRING, BT_VALIST_ARG)
+DEF_FUNCTION_TYPE_6 (BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                    BT_BOOL, BT_LONG, BT_LONG, BT_LONG, BT_LONG,
+                    BT_PTR_LONG, BT_PTR_LONG)
+DEF_FUNCTION_TYPE_6 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
+                    BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
+                    BT_LONG, BT_LONG, BT_LONG)
+
+DEF_FUNCTION_TYPE_7 (BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
+                    BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT,
+                    BT_LONG, BT_LONG, BT_LONG, BT_LONG)
 
 DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
 DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
@@ -404,3 +434,4 @@ DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR,
 DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR)
 DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,
                     BT_PTR, BT_PTR_FN_VOID_VAR, BT_PTR, BT_SIZE)
+
index 657f38b..2d4322f 100644 (file)
@@ -76,7 +76,6 @@ static const char *c_getstr (tree);
 static rtx c_readstr (const char *, enum machine_mode);
 static int target_char_cast (tree, char *);
 static rtx get_memory_rtx (tree, tree);
-static tree build_string_literal (int, const char *);
 static int apply_args_size (void);
 static int apply_result_size (void);
 #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
@@ -4785,7 +4784,7 @@ expand_builtin_copysign (tree arglist, rtx target, rtx subtarget)
 
 /* Create a new constant string literal and return a char* pointer to it.
    The STRING_CST value is the LEN characters at STR.  */
-static tree
+tree
 build_string_literal (int len, const char *str)
 {
   tree t, elem, index, type;
index d356361..b0d54a0 100644 (file)
@@ -23,7 +23,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 /* Before including this file, you should define a macro:
 
      DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P,
-                  FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT)
+                  FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT, COND)
 
    This macro will be called once for each builtin function.  The
    ENUM will be of type `enum built_in_function', and will indicate
@@ -61,8 +61,10 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
    define it's meaning.  When user uses floorf we may assume that the
    floorf has the meaning we expect, but we can't produce floorf by
    simplifying floor((double)float) since the runtime need not implement
-   it.  */
-   
+   it.
+
+   The builtins is registered only if COND is true.  */
+
 /* A GCC builtin (like __builtin_saveregs) is provided by the
    compiler, but does not correspond to a function in the standard
    library.  */
@@ -133,6 +135,13 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
   DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, 0, 0, false, false, \
               false, 0, false, false)
 
+/* Builtin used by the implementation of GNU OpenMP.  None of these are
+   actually implemented in the compiler; they're all in libgomp.  */
+#undef DEF_GOMP_BUILTIN
+#define DEF_GOMP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
+  DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE,    \
+               false, true, true, ATTRS, false, flag_openmp)
+
 /* Define an attribute list for math functions that are normally
    "impure" because some of them may write into global memory for
    `errno'.  If !flag_errno_math they are instead "const".  */
@@ -711,3 +720,6 @@ DEF_BUILTIN_STUB (BUILT_IN_PROFILE_FUNC_EXIT, "profile_func_exit")
 
 /* Synchronization Primitives.  */
 #include "sync-builtins.def"
+
+/* OpenMP builtins.  */
+#include "omp-builtins.def"
index 735250f..6da433c 100644 (file)
@@ -296,6 +296,10 @@ extern tree push_stmt_list (void);
 extern tree pop_stmt_list (tree);
 extern tree add_stmt (tree);
 extern void push_cleanup (tree, tree, bool);
+extern tree pushdecl_top_level (tree);
+extern tree pushdecl (tree);
+extern tree build_modify_expr (tree, enum tree_code, tree);
+extern tree build_indirect_ref (tree, const char *);
 
 extern int c_expand_decl (tree);
 
@@ -934,6 +938,21 @@ extern void pp_file_change (const struct line_map *);
 extern void pp_dir_change (cpp_reader *, const char *);
 extern bool check_missing_format_attribute (tree, tree);
 
+/* In c-omp.c  */
+extern tree c_finish_omp_master (tree);
+extern tree c_finish_omp_critical (tree, tree);
+extern tree c_finish_omp_ordered (tree);
+extern void c_finish_omp_barrier (void);
+extern void c_finish_omp_atomic (enum tree_code, tree, tree);
+extern void c_finish_omp_flush (void);
+extern tree c_finish_omp_for (location_t, tree, tree, tree, tree, tree, tree);
+extern void c_split_parallel_clauses (tree, tree *, tree *);
+extern enum omp_clause_default_kind c_omp_predetermined_sharing (tree);
+
+/* Not in c-omp.c; provided by the front end.  */
+extern bool c_omp_sharing_predetermined (tree);
+extern tree c_omp_remap_decl (tree, bool);
+
 /* In order for the format checking to accept the C frontend
    diagnostic framework extensions, you must include this file before
    toplev.h, not after.  The C front end formats are a subset of those
index e9f60f6..f54d17e 100644 (file)
@@ -544,6 +544,9 @@ c_cpp_builtins (cpp_reader *pfile)
   else if (flag_stack_protect == 1)
     cpp_define (pfile, "__SSP__=1");
 
+  if (flag_openmp)
+    cpp_define (pfile, "_OPENMP=200505");
+
   /* A straightforward target hook doesn't work, because of problems
      linking that hook's body when part of non-C front ends.  */
 # define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
index 4c786b6..a3b56c0 100644 (file)
@@ -1385,7 +1385,14 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
     {
       /* Only variables can be thread-local, and all declarations must
         agree on this property.  */
-      if (DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl))
+      if (C_DECL_THREADPRIVATE_P (olddecl) && !DECL_THREAD_LOCAL_P (newdecl))
+       {
+         /* Nothing to check.  Since OLDDECL is marked threadprivate
+            and NEWDECL does not have a thread-local attribute, we
+            will merge the threadprivate attribute into NEWDECL.  */
+         ;
+       }
+      else if (DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl))
        {
          if (DECL_THREAD_LOCAL_P (newdecl))
            error ("thread-local declaration of %q+D follows "
@@ -1672,6 +1679,13 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
    if (DECL_INITIAL (newdecl) == 0)
     DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
 
+  /* Merge the threadprivate attribute.  */
+  if (TREE_CODE (olddecl) == VAR_DECL && C_DECL_THREADPRIVATE_P (olddecl))
+    {
+      DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl);
+      C_DECL_THREADPRIVATE_P (newdecl) = 1;
+    }
+
    if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS))
      {
        /* Merge the unused-warning information.  */
@@ -6454,21 +6468,25 @@ store_parm_decls (void)
   cfun->x_dont_save_pending_sizes_p = 1;
 }
 \f
-/* Handle attribute((warn_unused_result)) on FNDECL and all its nested
-   functions.  */
+/* Emit diagnostics that require gimple input for detection.  Operate on
+   FNDECL and all its nested functions.  */
 
 static void
-c_warn_unused_result_recursively (tree fndecl)
+c_gimple_diagnostics_recursively (tree fndecl)
 {
   struct cgraph_node *cgn;
 
   /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
   c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
 
+  /* Notice when OpenMP structured block constraints are violated.  */
+  if (flag_openmp)
+    diagnose_omp_structured_block_errors (fndecl);
+
   /* Finalize all nested functions now.  */
   cgn = cgraph_node (fndecl);
   for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
-    c_warn_unused_result_recursively (cgn->decl);
+    c_gimple_diagnostics_recursively (cgn->decl);
 }
 
 /* Finish up a function declaration and compile that function
@@ -6596,7 +6614,7 @@ finish_function (void)
       if (!decl_function_context (fndecl))
         {
           c_genericize (fndecl);
-          c_warn_unused_result_recursively (fndecl);
+          c_gimple_diagnostics_recursively (fndecl);
 
          /* ??? Objc emits functions after finalizing the compilation unit.
             This should be cleaned up later and this conditional removed.  */
@@ -6650,11 +6668,15 @@ c_expand_body (tree fndecl)
 }
 \f
 /* Check the declarations given in a for-loop for satisfying the C99
-   constraints.  */
-void
+   constraints.  If exactly one such decl is found, return it.  */
+
+tree
 check_for_loop_decls (void)
 {
   struct c_binding *b;
+  tree one_decl = NULL_TREE;
+  int n_decls = 0;
+
 
   if (!flag_isoc99)
     {
@@ -6662,7 +6684,7 @@ check_for_loop_decls (void)
         the C99 for loop scope.  This doesn't make much sense, so don't
         allow it.  */
       error ("%<for%> loop initial declaration used outside C99 mode");
-      return;
+      return NULL_TREE;
     }
   /* C99 subclause 6.8.5 paragraph 3:
 
@@ -6713,7 +6735,12 @@ check_for_loop_decls (void)
          error ("declaration of non-variable %q+D in %<for%> loop "
                 "initial declaration", decl);
        }
+
+      n_decls++;
+      one_decl = decl;
     }
+
+  return n_decls == 1 ? one_decl : NULL_TREE;
 }
 \f
 /* Save and reinitialize the variables
index 6921259..136445c 100644 (file)
@@ -134,4 +134,7 @@ extern void c_initialize_diagnostics (diagnostic_context *);
 #undef LANG_HOOKS_GIMPLIFY_EXPR
 #define LANG_HOOKS_GIMPLIFY_EXPR c_gimplify_expr
 
+#undef LANG_HOOKS_OMP_PREDETERMINED_SHARING
+#define LANG_HOOKS_OMP_PREDETERMINED_SHARING c_omp_predetermined_sharing
+
 #endif /* GCC_C_OBJC_COMMON */
diff --git a/gcc/c-omp.c b/gcc/c-omp.c
new file mode 100644 (file)
index 0000000..30e7e64
--- /dev/null
@@ -0,0 +1,429 @@
+/* This file contains routines to construct GNU OpenMP constructs, 
+   called from parsing in the C and C++ front ends.
+
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   Contributed by Richard Henderson <rth@redhat.com>,
+                 Diego Novillo <dnovillo@redhat.com>.
+
+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 2, 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 COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "function.h"
+#include "c-common.h"
+#include "toplev.h"
+#include "tree-gimple.h"
+#include "bitmap.h"
+#include "langhooks.h"
+
+
+/* Complete a #pragma omp master construct.  STMT is the structured-block
+   that follows the pragma.  */
+
+tree
+c_finish_omp_master (tree stmt)
+{
+  return add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
+}
+
+/* Complete a #pragma omp critical construct.  STMT is the structured-block
+   that follows the pragma, NAME is the identifier in the pragma, or null
+   if it was omitted.  */
+
+tree
+c_finish_omp_critical (tree body, tree name)
+{
+  tree stmt = make_node (OMP_CRITICAL);
+  TREE_TYPE (stmt) = void_type_node;
+  OMP_CRITICAL_BODY (stmt) = body;
+  OMP_CRITICAL_NAME (stmt) = name;
+  return add_stmt (stmt);
+}
+
+/* Complete a #pragma omp ordered construct.  STMT is the structured-block
+   that follows the pragma.  */
+
+tree
+c_finish_omp_ordered (tree stmt)
+{
+  return add_stmt (build1 (OMP_ORDERED, void_type_node, stmt));
+}
+
+
+/* Complete a #pragma omp barrier construct.  */
+
+void
+c_finish_omp_barrier (void)
+{
+  tree x;
+
+  x = built_in_decls[BUILT_IN_GOMP_BARRIER];
+  x = build_function_call_expr (x, NULL);
+  add_stmt (x);
+}
+
+
+/* Complete a #pragma omp atomic construct.  The expression to be 
+   implemented atomically is LHS code= RHS.  */
+
+void
+c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
+{
+  tree x, type, addr;
+
+  if (lhs == error_mark_node || rhs == error_mark_node)
+    return;
+
+  /* ??? According to one reading of the OpenMP spec, complex type are
+     supported, but there are no atomic stores for any architecture.
+     But at least icc 9.0 doesn't support complex types here either.
+     And lets not even talk about vector types...  */
+  type = TREE_TYPE (lhs);
+  if (!INTEGRAL_TYPE_P (type)
+      && !POINTER_TYPE_P (type)
+      && !SCALAR_FLOAT_TYPE_P (type))
+    {
+      error ("invalid expression type for %<#pragma omp atomic%>");
+      return;
+    }
+
+  /* ??? Validate that rhs does not overlap lhs.  */
+
+  /* Take and save the address of the lhs.  From then on we'll reference it
+     via indirection.  */
+  addr = build_unary_op (ADDR_EXPR, lhs, 0);
+  if (addr == error_mark_node)
+    return;
+  addr = save_expr (addr);
+  lhs = build_indirect_ref (addr, NULL);
+
+  /* There are lots of warnings, errors, and conversions that need to happen
+     in the course of interpreting a statement.  Use the normal mechanisms
+     to do this, and then take it apart again.  */
+  x = build_modify_expr (lhs, code, rhs);
+  if (x == error_mark_node)
+    return;
+  gcc_assert (TREE_CODE (x) == MODIFY_EXPR);  
+  rhs = TREE_OPERAND (x, 1);
+
+  /* Punt the actual generation of atomic operations to common code.  */
+  add_stmt (build2 (OMP_ATOMIC, void_type_node, addr, rhs));
+}
+
+
+/* Complete a #pragma omp flush construct.  We don't do anything with the
+   variable list that the syntax allows.  */
+
+void
+c_finish_omp_flush (void)
+{
+  tree x;
+
+  x = built_in_decls[BUILT_IN_SYNCHRONIZE];
+  x = build_function_call_expr (x, NULL);
+  add_stmt (x);
+}
+
+
+/* Check and canonicalize #pragma omp for increment expression.
+   Helper function for c_finish_omp_for.  */
+
+static tree
+check_omp_for_incr_expr (tree exp, tree decl)
+{
+  tree t;
+
+  if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
+      || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
+    return error_mark_node;
+
+  if (exp == decl)
+    return build_int_cst (TREE_TYPE (exp), 0);
+
+  switch (TREE_CODE (exp))
+    {
+    case NOP_EXPR:
+      t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
+      if (t != error_mark_node)
+        return fold_convert (TREE_TYPE (exp), t);
+      break;
+    case MINUS_EXPR:
+      t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
+      if (t != error_mark_node)
+        return fold_build2 (MINUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
+      break;
+    case PLUS_EXPR:
+      t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
+      if (t != error_mark_node)
+        return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
+      t = check_omp_for_incr_expr (TREE_OPERAND (exp, 1), decl);
+      if (t != error_mark_node)
+        return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
+      break;
+    default:
+      break;
+    }
+
+  return error_mark_node;
+}
+
+/* Validate and emit code for the OpenMP directive #pragma omp for.
+   INIT, COND, INCR, BODY and PRE_BODY are the five basic elements
+   of the loop (initialization expression, controlling predicate, increment
+   expression, body of the loop and statements to go before the loop).
+   DECL is the iteration variable.  */
+
+tree
+c_finish_omp_for (location_t locus, tree decl, tree init, tree cond,
+                 tree incr, tree body, tree pre_body)
+{
+  location_t elocus = locus;
+  bool fail = false;
+
+  if (EXPR_HAS_LOCATION (init))
+    elocus = EXPR_LOCATION (init);
+
+  /* Validate the iteration variable.  */
+  if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
+    {
+      error ("%Hinvalid type for iteration variable %qE", &elocus, decl);
+      fail = true;
+    }
+  if (TYPE_UNSIGNED (TREE_TYPE (decl)))
+    warning (0, "%Hiteration variable %qE is unsigned", &elocus, decl);
+
+  /* In the case of "for (int i = 0...)", init will be a decl.  It should
+     have a DECL_INITIAL that we can turn into an assignment.  */
+  if (init == decl)
+    {
+      elocus = DECL_SOURCE_LOCATION (decl);
+
+      init = DECL_INITIAL (decl);
+      if (init == NULL)
+       {
+         error ("%H%qE is not initialized", &elocus, decl);
+         init = integer_zero_node;
+         fail = true;
+       }
+
+      init = build_modify_expr (decl, NOP_EXPR, init);
+      SET_EXPR_LOCATION (init, elocus);
+    }
+  gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
+  gcc_assert (TREE_OPERAND (init, 0) == decl);
+  
+  if (cond == NULL_TREE)
+    {
+      error ("%Hmissing controlling predicate", &elocus);
+      fail = true;
+    }
+  else
+    {
+      bool cond_ok = false;
+
+      if (EXPR_HAS_LOCATION (cond))
+       elocus = EXPR_LOCATION (cond);
+
+      if (TREE_CODE (cond) == LT_EXPR
+         || TREE_CODE (cond) == LE_EXPR
+         || TREE_CODE (cond) == GT_EXPR
+         || TREE_CODE (cond) == GE_EXPR)
+       {
+         tree op0 = TREE_OPERAND (cond, 0);
+         tree op1 = TREE_OPERAND (cond, 1);
+
+         /* 2.5.1.  The comparison in the condition is computed in the type
+            of DECL, otherwise the behavior is undefined.
+
+            For example:
+            long n; int i;
+            i < n;
+
+            according to ISO will be evaluated as:
+            (long)i < n;
+
+            We want to force:
+            i < (int)n;  */
+         if (TREE_CODE (op0) == NOP_EXPR
+             && decl == TREE_OPERAND (op0, 0))
+           {
+             TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
+             TREE_OPERAND (cond, 1) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
+                                                   TREE_OPERAND (cond, 1));
+           }
+         else if (TREE_CODE (op1) == NOP_EXPR
+                  && decl == TREE_OPERAND (op1, 0))
+           {
+             TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
+             TREE_OPERAND (cond, 0) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
+                                                   TREE_OPERAND (cond, 0));
+           }
+
+         if (decl == TREE_OPERAND (cond, 0))
+           cond_ok = true;
+         else if (decl == TREE_OPERAND (cond, 1))
+           {
+             TREE_SET_CODE (cond, swap_tree_comparison (TREE_CODE (cond)));
+             TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
+             TREE_OPERAND (cond, 0) = decl;
+             cond_ok = true;
+           }
+       }
+
+      if (!cond_ok)
+       {
+         error ("%Hinvalid controlling predicate", &elocus);
+         fail = true;
+       }
+    }
+
+  if (incr == NULL_TREE)
+    {
+      error ("%Hmissing increment expression", &elocus);
+      fail = true;
+    }
+  else
+    {
+      bool incr_ok = false;
+
+      if (EXPR_HAS_LOCATION (incr))
+       elocus = EXPR_LOCATION (incr);
+
+      /* Check all the valid increment expressions: v++, v--, ++v, --v,
+        v = v + incr, v = incr + v and v = v - incr.  */
+      switch (TREE_CODE (incr))
+       {
+       case POSTINCREMENT_EXPR:
+       case PREINCREMENT_EXPR:
+       case POSTDECREMENT_EXPR:
+       case PREDECREMENT_EXPR:
+         incr_ok = (TREE_OPERAND (incr, 0) == decl);
+         break;
+
+       case MODIFY_EXPR:
+         if (TREE_OPERAND (incr, 0) != decl)
+           break;
+         if (TREE_OPERAND (incr, 1) == decl)
+           break;
+         if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
+             && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
+                 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
+           incr_ok = true;
+         else if (TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
+                  && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
+           incr_ok = true;
+         else
+           {
+             tree t = check_omp_for_incr_expr (TREE_OPERAND (incr, 1), decl);
+             if (t != error_mark_node)
+               {
+                 incr_ok = true;
+                 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
+                 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
+               }
+           }
+         break;
+
+       default:
+         break;
+       }
+      if (!incr_ok)
+       {
+         error ("%Hinvalid increment expression", &elocus);
+         fail = true;
+       }
+    }
+
+  if (fail)
+    return NULL;
+  else
+    {
+      tree t = make_node (OMP_FOR);
+
+      TREE_TYPE (t) = void_type_node;
+      OMP_FOR_INIT (t) = init;
+      OMP_FOR_COND (t) = cond;
+      OMP_FOR_INCR (t) = incr;
+      OMP_FOR_BODY (t) = body;
+      OMP_FOR_PRE_BODY (t) = pre_body;
+
+      SET_EXPR_LOCATION (t, locus);
+      return add_stmt (t);
+    }
+}
+
+
+/* Divide CLAUSES into two lists: those that apply to a parallel construct,
+   and those that apply to a work-sharing construct.  Place the results in
+   *PAR_CLAUSES and *WS_CLAUSES respectively.  In addition, add a nowait
+   clause to the work-sharing list.  */
+
+void
+c_split_parallel_clauses (tree clauses, tree *par_clauses, tree *ws_clauses)
+{
+  tree next;
+
+  *par_clauses = NULL;
+  *ws_clauses = make_node (OMP_CLAUSE_NOWAIT);
+
+  for (; clauses ; clauses = next)
+    {
+      next = OMP_CLAUSE_CHAIN (clauses);
+
+      switch (TREE_CODE (clauses))
+       {
+       case OMP_CLAUSE_PRIVATE:
+       case OMP_CLAUSE_SHARED:
+       case OMP_CLAUSE_FIRSTPRIVATE:
+       case OMP_CLAUSE_LASTPRIVATE:
+       case OMP_CLAUSE_REDUCTION:
+       case OMP_CLAUSE_COPYIN:
+       case OMP_CLAUSE_IF:
+       case OMP_CLAUSE_NUM_THREADS:
+       case OMP_CLAUSE_DEFAULT:
+         OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
+         *par_clauses = clauses;
+         break;
+
+       case OMP_CLAUSE_SCHEDULE:
+       case OMP_CLAUSE_ORDERED:
+         OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
+         *ws_clauses = clauses;
+         break;
+
+       default:
+         gcc_unreachable ();
+       }
+    }
+}
+
+/* True if OpenMP sharing attribute of DECL is predetermined.  */
+
+enum omp_clause_default_kind
+c_omp_predetermined_sharing (tree decl)
+{
+  /* Variables with const-qualified type having no mutable member
+     are predetermined shared.  */
+  if (TREE_READONLY (decl))
+    return OMP_CLAUSE_DEFAULT_SHARED;
+
+  return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
+}
index 522f2d2..e594d1f 100644 (file)
@@ -200,6 +200,26 @@ static const struct resword reswords[] =
 };
 #define N_reswords (sizeof reswords / sizeof (struct resword))
 
+/* All OpenMP clauses.  OpenMP 2.5.  */
+typedef enum pragma_omp_clause {
+  PRAGMA_OMP_CLAUSE_NONE = 0,
+
+  PRAGMA_OMP_CLAUSE_COPYIN,
+  PRAGMA_OMP_CLAUSE_COPYPRIVATE,
+  PRAGMA_OMP_CLAUSE_DEFAULT,
+  PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
+  PRAGMA_OMP_CLAUSE_IF,
+  PRAGMA_OMP_CLAUSE_LASTPRIVATE,
+  PRAGMA_OMP_CLAUSE_NOWAIT,
+  PRAGMA_OMP_CLAUSE_NUM_THREADS,
+  PRAGMA_OMP_CLAUSE_ORDERED,
+  PRAGMA_OMP_CLAUSE_PRIVATE,
+  PRAGMA_OMP_CLAUSE_REDUCTION,
+  PRAGMA_OMP_CLAUSE_SCHEDULE,
+  PRAGMA_OMP_CLAUSE_SHARED
+} pragma_omp_clause;
+
+
 /* Initialization routine for this file.  */
 
 void
@@ -981,6 +1001,10 @@ static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
 static struct c_expr c_parser_expression (c_parser *);
 static struct c_expr c_parser_expression_conv (c_parser *);
 static tree c_parser_expr_list (c_parser *, bool);
+static void c_parser_omp_construct (c_parser *);
+static void c_parser_omp_threadprivate (c_parser *);
+static void c_parser_omp_barrier (c_parser *);
+static void c_parser_omp_flush (c_parser *);
 
 enum pragma_context { pragma_external, pragma_stmt, pragma_compound };
 static bool c_parser_pragma (c_parser *, enum pragma_context);
@@ -1189,7 +1213,12 @@ c_parser_external_declaration (c_parser *parser)
    absence is diagnosed through the diagnosis of implicit int.  In GNU
    C we also allow but diagnose declarations without declaration
    specifiers, but only at top level (elsewhere they conflict with
-   other syntax).  */
+   other syntax).
+   
+   OpenMP:
+   
+   declaration:
+     threadprivate-directive  */
 
 static void
 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
@@ -3256,7 +3285,16 @@ c_parser_initval (c_parser *parser, struct c_expr *after)
    prefix attributes on the declaration.  ??? The syntax follows the
    old parser in requiring something after label declarations.
    Although they are erroneous if the labels declared aren't defined,
-   is it useful for the syntax to be this way?  */
+   is it useful for the syntax to be this way?
+   
+   OpenMP:
+   
+   block-item:
+     openmp-directive
+
+   openmp-directive:
+     barrier-directive
+     flush-directive  */
 
 static tree
 c_parser_compound_statement (c_parser *parser)
@@ -3527,7 +3565,53 @@ c_parser_label (c_parser *parser)
    objc-throw-statement:
      @throw expression ;
      @throw ;
-*/
+
+   OpenMP:
+
+   statement:
+     openmp-construct
+
+   openmp-construct:
+     parallel-construct
+     for-construct
+     sections-construct
+     single-construct
+     parallel-for-construct
+     parallel-sections-construct
+     master-construct
+     critical-construct
+     atomic-construct
+     ordered-construct
+
+   parallel-construct:
+     parallel-directive structured-block
+
+   for-construct:
+     for-directive iteration-statement
+
+   sections-construct:
+     sections-directive section-scope
+
+   single-construct:
+     single-directive structured-block
+
+   parallel-for-construct:
+     parallel-for-directive iteration-statement
+
+   parallel-sections-construct:
+     parallel-sections-directive section-scope
+
+   master-construct:
+     master-directive structured-block
+
+   critical-construct:
+     critical-directive structured-block
+
+   atomic-construct:
+     atomic-directive expression-statement
+
+   ordered-construct:
+     ordered-directive structured-block  */
 
 static void
 c_parser_statement (c_parser *parser)
@@ -6344,12 +6428,13 @@ c_parser_objc_keywordexpr (c_parser *parser)
 }
 
 \f
-/* Handle pragmas.  ALLOW_STMT is true if we're within the context of
-   a function and such pragmas are to be allowed.  Returns true if we
-   actually parsed such a pragma.  */
+/* Handle pragmas.  Some OpenMP pragmas are associated with, and therefore
+   should be considered, statements.  ALLOW_STMT is true if we're within
+   the context of a function and such pragmas are to be allowed.  Returns
+   true if we actually parsed such a pragma.  */
 
 static bool
-c_parser_pragma (c_parser *parser, enum pragma_context context ATTRIBUTE_UNUSED)
+c_parser_pragma (c_parser *parser, enum pragma_context context)
 {
   unsigned int id;
 
@@ -6358,13 +6443,56 @@ c_parser_pragma (c_parser *parser, enum pragma_context context ATTRIBUTE_UNUSED)
 
   switch (id)
     {
+    case PRAGMA_OMP_BARRIER:
+      if (context != pragma_compound)
+       {
+         if (context == pragma_stmt)
+           c_parser_error (parser, "%<#pragma omp barrier%> may only be "
+                           "used in compound statements");
+         goto bad_stmt;
+       }
+      c_parser_omp_barrier (parser);
+      return false;
+
+    case PRAGMA_OMP_FLUSH:
+      if (context != pragma_compound)
+       {
+         if (context == pragma_stmt)
+           c_parser_error (parser, "%<#pragma omp flush%> may only be "
+                           "used in compound statements");
+         goto bad_stmt;
+       }
+      c_parser_omp_flush (parser);
+      return false;
+
+    case PRAGMA_OMP_THREADPRIVATE:
+      c_parser_omp_threadprivate (parser);
+      return false;
+
+    case PRAGMA_OMP_SECTION:
+      error ("%<#pragma omp section%> may only be used in "
+            "%<#pragma omp sections%> construct");
+      c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
+      return false;
+
     case PRAGMA_GCC_PCH_PREPROCESS:
       c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
       return false;
 
     default:
-      gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
+      if (id < PRAGMA_FIRST_EXTERNAL)
+       {
+         if (context == pragma_external)
+           {
+           bad_stmt:
+             c_parser_error (parser, "expected declaration specifiers");
+             c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
+             return false;
+           }
+         c_parser_omp_construct (parser);
+         return true;
+       }
       break;
     }
 
@@ -6420,6 +6548,1213 @@ c_parser_pragma_pch_preprocess (c_parser *parser)
     c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
 }
 \f
+/* OpenMP 2.5 parsing routines.  */
+
+/* Returns name of the next clause.
+   If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
+   the token is not consumed.  Otherwise appropriate pragma_omp_clause is
+   returned and the token is consumed.  */
+
+static pragma_omp_clause
+c_parser_omp_clause_name (c_parser *parser)
+{
+  pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
+
+  if (c_parser_next_token_is_keyword (parser, RID_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 (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+
+      switch (p[0])
+       {
+       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);
+
+  return result;
+}
+
+/* Validate that a clause of the given type does not already exist.  */
+
+static void
+check_no_duplicate_clause (tree clauses, enum tree_code code, const char *name)
+{
+  tree c;
+
+  for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+    if (TREE_CODE (c) == code)
+      {
+       error ("too many %qs clauses", name);
+       break;
+      }
+}
+
+/* OpenMP 2.5:
+   variable-list:
+     identifier
+     variable-list , identifier
+
+   If KIND is nonzero, create the appropriate node and install the decl
+   in OMP_CLAUSE_DECL and add the node to the head of the list.
+
+   If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
+   return the list created.  */
+
+static tree
+c_parser_omp_variable_list (c_parser *parser, enum tree_code kind, tree list)
+{
+  if (c_parser_next_token_is_not (parser, CPP_NAME)
+      || c_parser_peek_token (parser)->id_kind != C_ID_ID)
+    c_parser_error (parser, "expected identifier");
+
+  while (c_parser_next_token_is (parser, CPP_NAME)
+        && c_parser_peek_token (parser)->id_kind == C_ID_ID)
+    {
+      tree t = lookup_name (c_parser_peek_token (parser)->value);
+
+      if (t == NULL_TREE)
+       undeclared_variable (c_parser_peek_token (parser)->value,
+                            c_parser_peek_token (parser)->location);
+      else if (t == error_mark_node)
+       ;
+      else if (kind != 0)
+       {
+         tree u = make_node (kind);
+         OMP_CLAUSE_DECL (u) = t;
+         OMP_CLAUSE_CHAIN (u) = list;
+         list = u;
+       }
+      else
+       list = tree_cons (t, NULL_TREE, list);
+
+      c_parser_consume_token (parser);
+
+      if (c_parser_next_token_is_not (parser, CPP_COMMA))
+       break;
+
+      c_parser_consume_token (parser);
+    }
+
+  return list;
+}
+
+/* Similarly, but expect leading and trailing parenthesis.  This is a very
+   common case for omp clauses.  */
+
+static tree
+c_parser_omp_var_list_parens (c_parser *parser, enum tree_code kind, tree list)
+{
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      list = c_parser_omp_variable_list (parser, kind, list);
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+    }
+  return list;
+}
+
+/* OpenMP 2.5:
+   copyin ( variable-list ) */
+
+static tree
+c_parser_omp_clause_copyin (c_parser *parser, tree list)
+{
+  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
+}
+
+/* OpenMP 2.5:
+   copyprivate ( variable-list ) */
+
+static tree
+c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
+{
+  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
+}
+
+/* OpenMP 2.5:
+   default ( shared | none ) */
+
+static tree
+c_parser_omp_clause_default (c_parser *parser, tree list)
+{
+  enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
+  tree c;
+
+  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    return list;
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+
+      switch (p[0])
+       {
+       case 'n':
+         if (strcmp ("none", p) != 0)
+           goto invalid_kind;
+         kind = OMP_CLAUSE_DEFAULT_NONE;
+         break;
+
+       case 's':
+         if (strcmp ("shared", p) != 0)
+           goto invalid_kind;
+         kind = OMP_CLAUSE_DEFAULT_SHARED;
+         break;
+
+       default:
+         goto invalid_kind;
+       }
+
+      c_parser_consume_token (parser);
+    }
+  else
+    {
+    invalid_kind:
+      c_parser_error (parser, "expected %<none%> or %<shared%>");
+    }
+  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
+  if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
+    return list;
+
+  check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
+  c = make_node (OMP_CLAUSE_DEFAULT);
+  OMP_CLAUSE_CHAIN (c) = list;
+  OMP_CLAUSE_DEFAULT_KIND (c) = kind;
+
+  return c;
+}
+
+/* OpenMP 2.5:
+   firstprivate ( variable-list ) */
+
+static tree
+c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
+{
+  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
+}
+
+/* OpenMP 2.5:
+   if ( expression ) */
+
+static tree
+c_parser_omp_clause_if (c_parser *parser, tree list)
+{
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      tree t = c_parser_paren_condition (parser);
+      tree c;
+
+      check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if");
+
+      c = make_node (OMP_CLAUSE_IF);
+      OMP_CLAUSE_IF_EXPR (c) = t;
+      OMP_CLAUSE_CHAIN (c) = list;
+      list = c;
+    }
+  else
+    c_parser_error (parser, "expected %<(%>");
+
+  return list;
+}
+
+/* OpenMP 2.5:
+   lastprivate ( variable-list ) */
+
+static tree
+c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
+{
+  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LASTPRIVATE, list);
+}
+
+/* OpenMP 2.5:
+   nowait */
+
+static tree
+c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
+{
+  tree c;
+
+  check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
+
+  c = make_node (OMP_CLAUSE_NOWAIT);
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+}
+
+/* OpenMP 2.5:
+   num_threads ( expression ) */
+
+static tree
+c_parser_omp_clause_num_threads (c_parser *parser, tree list)
+{
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      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");
+         return list;
+       }
+
+      /* 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;
+       }
+
+      check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
+
+      c = make_node (OMP_CLAUSE_NUM_THREADS);
+      OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
+      OMP_CLAUSE_CHAIN (c) = list;
+      list = c;
+    }
+
+  return list;
+}
+
+/* OpenMP 2.5:
+   ordered */
+
+static tree
+c_parser_omp_clause_ordered (c_parser *parser ATTRIBUTE_UNUSED, tree list)
+{
+  tree c;
+
+  check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
+
+  c = make_node (OMP_CLAUSE_ORDERED);
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+}
+
+/* OpenMP 2.5:
+   private ( variable-list ) */
+
+static tree
+c_parser_omp_clause_private (c_parser *parser, tree list)
+{
+  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
+}
+
+/* OpenMP 2.5:
+   reduction ( reduction-operator : variable-list )
+
+   reduction-operator:
+     One of: + * - & ^ | && || */
+
+static tree
+c_parser_omp_clause_reduction (c_parser *parser, tree list)
+{
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      enum tree_code code;
+
+      switch (c_parser_peek_token (parser)->type)
+       {
+       case CPP_PLUS:
+         code = PLUS_EXPR;
+         break;
+       case CPP_MULT:
+         code = MULT_EXPR;
+         break;
+       case CPP_MINUS:
+         code = MINUS_EXPR;
+         break;
+       case CPP_AND:
+         code = BIT_AND_EXPR;
+         break;
+       case CPP_XOR:
+         code = BIT_XOR_EXPR;
+         break;
+       case CPP_OR:
+         code = BIT_IOR_EXPR;
+         break;
+       case CPP_AND_AND:
+         code = TRUTH_ANDIF_EXPR;
+         break;
+       case CPP_OR_OR:
+         code = TRUTH_ORIF_EXPR;
+         break;
+       default:
+         c_parser_error (parser,
+                         "expected %<+%>, %<*%>, %<-%>, %<&%>, "
+                         "%<^%>, %<|%>, %<&&%>, or %<||%>");
+         c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
+         return list;
+       }
+      c_parser_consume_token (parser);
+      if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
+       {
+         tree nl, c;
+
+         nl = c_parser_omp_variable_list (parser, OMP_CLAUSE_REDUCTION, list);
+         for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
+           OMP_CLAUSE_REDUCTION_CODE (c) = code;
+
+         list = nl;
+       }
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+    }
+  return list;
+}
+
+/* OpenMP 2.5:
+   schedule ( schedule-kind )
+   schedule ( schedule-kind , expression )
+
+   schedule-kind:
+     static | dynamic | guided | runtime
+*/
+
+static tree
+c_parser_omp_clause_schedule (c_parser *parser, tree list)
+{
+  tree c, t;
+
+  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    return list;
+
+  c = make_node (OMP_CLAUSE_SCHEDULE);
+
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      tree kind = c_parser_peek_token (parser)->value;
+      const char *p = IDENTIFIER_POINTER (kind);
+
+      switch (p[0])
+       {
+       case 'd':
+         if (strcmp ("dynamic", p) != 0)
+           goto invalid_kind;
+         OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
+         break;
+
+        case 'g':
+         if (strcmp ("guided", p) != 0)
+           goto invalid_kind;
+         OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
+         break;
+
+       case 'r':
+         if (strcmp ("runtime", p) != 0)
+           goto invalid_kind;
+         OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
+         break;
+
+       default:
+         goto invalid_kind;
+       }
+    }
+  else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
+    OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
+  else
+    goto invalid_kind;
+
+  c_parser_consume_token (parser);
+  if (c_parser_next_token_is (parser, CPP_COMMA))
+    {
+      c_parser_consume_token (parser);
+
+      t = c_parser_expr_no_commas (parser, NULL).value;
+
+      if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
+       error ("schedule %<runtime%> does not take "
+              "a %<chunk_size%> parameter");
+      else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)
+       OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
+      else
+       c_parser_error (parser, "expected integer expression");
+
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+    }
+  else
+    c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+                              "expected %<,%> or %<)%>");
+
+  check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
+  OMP_CLAUSE_CHAIN (c) = list;
+  return c;
+
+ invalid_kind:
+  c_parser_error (parser, "invalid schedule kind");
+  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
+  return list;
+}
+
+/* OpenMP 2.5:
+   shared ( variable-list ) */
+
+static tree
+c_parser_omp_clause_shared (c_parser *parser, tree list)
+{
+  return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
+}
+
+/* Parse all OpenMP clauses.  The set clauses allowed by the directive
+   is a bitmask in MASK.  Return the list of clauses found; the result
+   of clause default goes in *pdefault.  */
+
+static tree
+c_parser_omp_all_clauses (c_parser *parser, unsigned int mask,
+                         const char *where)
+{
+  tree clauses = NULL;
+
+  while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
+    {
+      const pragma_omp_clause c_kind = c_parser_omp_clause_name (parser);
+      const char *c_name;
+      tree prev = clauses;
+
+      switch (c_kind)
+       {
+       case PRAGMA_OMP_CLAUSE_COPYIN:
+         clauses = c_parser_omp_clause_copyin (parser, clauses);
+         c_name = "copyin";
+         break;
+       case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
+         clauses = c_parser_omp_clause_copyprivate (parser, clauses);
+         c_name = "copyprivate";
+         break;
+       case PRAGMA_OMP_CLAUSE_DEFAULT:
+         clauses = c_parser_omp_clause_default (parser, clauses);
+         c_name = "default";
+         break;
+       case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
+         clauses = c_parser_omp_clause_firstprivate (parser, clauses);
+         c_name = "firstprivate";
+         break;
+       case PRAGMA_OMP_CLAUSE_IF:
+         clauses = c_parser_omp_clause_if (parser, clauses);
+         c_name = "if";
+         break;
+       case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
+         clauses = c_parser_omp_clause_lastprivate (parser, clauses);
+         c_name = "lastprivate";
+         break;
+       case PRAGMA_OMP_CLAUSE_NOWAIT:
+         clauses = c_parser_omp_clause_nowait (parser, clauses);
+         c_name = "nowait";
+         break;
+       case PRAGMA_OMP_CLAUSE_NUM_THREADS:
+         clauses = c_parser_omp_clause_num_threads (parser, clauses);
+         c_name = "num_threads";
+         break;
+       case PRAGMA_OMP_CLAUSE_ORDERED:
+         clauses = c_parser_omp_clause_ordered (parser, clauses);
+         c_name = "ordered";
+         break;
+       case PRAGMA_OMP_CLAUSE_PRIVATE:
+         clauses = c_parser_omp_clause_private (parser, clauses);
+         c_name = "private";
+         break;
+       case PRAGMA_OMP_CLAUSE_REDUCTION:
+         clauses = c_parser_omp_clause_reduction (parser, clauses);
+         c_name = "reduction";
+         break;
+       case PRAGMA_OMP_CLAUSE_SCHEDULE:
+         clauses = c_parser_omp_clause_schedule (parser, clauses);
+         c_name = "schedule";
+         break;
+       case PRAGMA_OMP_CLAUSE_SHARED:
+         clauses = c_parser_omp_clause_shared (parser, clauses);
+         c_name = "shared";
+         break;
+       default:
+         c_parser_error (parser, "expected %<#pragma omp%> clause");
+         goto saw_error;
+       }
+
+      if (((mask >> c_kind) & 1) == 0 && !parser->error)
+       {
+         /* Remove the invalid clause(s) from the list to avoid
+            confusing the rest of the compiler.  */
+         clauses = prev;
+         error ("%qs is not valid for %qs", c_name, where);
+       }
+    }
+
+ saw_error:
+  c_parser_skip_to_pragma_eol (parser);
+
+  return c_finish_omp_clauses (clauses);
+}
+
+/* OpenMP 2.5:
+   structured-block:
+     statement
+
+   In practice, we're also interested in adding the statement to an
+   outer node.  So it is convenient if we work around the fact that
+   c_parser_statement calls add_stmt.  */
+
+static tree
+c_parser_omp_structured_block (c_parser *parser)
+{
+  tree stmt = push_stmt_list ();
+  c_parser_statement (parser);
+  return pop_stmt_list (stmt);
+}
+
+/* OpenMP 2.5:
+   # pragma omp atomic new-line
+     expression-stmt
+
+   expression-stmt:
+     x binop= expr | x++ | ++x | x-- | --x
+   binop:
+     +, *, -, /, &, ^, |, <<, >>
+
+  where x is an lvalue expression with scalar type.  */
+
+static void
+c_parser_omp_atomic (c_parser *parser)
+{
+  tree lhs, rhs;
+  enum tree_code code;
+
+  c_parser_skip_to_pragma_eol (parser);
+
+  lhs = c_parser_unary_expression (parser).value;
+  switch (TREE_CODE (lhs))
+    {
+    case ERROR_MARK:
+    saw_error:
+      c_parser_skip_to_end_of_block_or_statement (parser);
+      return;
+
+    case PREINCREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
+      lhs = TREE_OPERAND (lhs, 0);
+      code = PLUS_EXPR;
+      rhs = integer_one_node;
+      break;
+
+    case PREDECREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
+      lhs = TREE_OPERAND (lhs, 0);
+      code = MINUS_EXPR;
+      rhs = integer_one_node;
+      break;
+
+    default:
+      switch (c_parser_peek_token (parser)->type)
+       {
+       case CPP_MULT_EQ:
+         code = MULT_EXPR;
+         break;
+       case CPP_DIV_EQ:
+         code = TRUNC_DIV_EXPR;
+         break;
+       case CPP_PLUS_EQ:
+         code = PLUS_EXPR;
+         break;
+       case CPP_MINUS_EQ:
+         code = MINUS_EXPR;
+         break;
+       case CPP_LSHIFT_EQ:
+         code = LSHIFT_EXPR;
+         break;
+       case CPP_RSHIFT_EQ:
+         code = RSHIFT_EXPR;
+         break;
+       case CPP_AND_EQ:
+         code = BIT_AND_EXPR;
+         break;
+       case CPP_OR_EQ:
+         code = BIT_IOR_EXPR;
+         break;
+       case CPP_XOR_EQ:
+         code = BIT_XOR_EXPR;
+         break;
+       default:
+         c_parser_error (parser,
+                         "invalid operator for %<#pragma omp atomic%>");
+         goto saw_error;
+       }
+
+      c_parser_consume_token (parser);
+      rhs = c_parser_expression (parser).value;
+      break;
+    }
+  c_finish_omp_atomic (code, lhs, rhs);
+  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
+}
+
+
+/* OpenMP 2.5:
+   # pragma omp barrier new-line
+*/
+
+static void
+c_parser_omp_barrier (c_parser *parser)
+{
+  c_parser_consume_pragma (parser);
+  c_parser_skip_to_pragma_eol (parser);
+
+  c_finish_omp_barrier ();
+}
+
+/* OpenMP 2.5:
+   # pragma omp critical [(name)] new-line
+     structured-block
+*/
+
+static tree
+c_parser_omp_critical (c_parser *parser)
+{
+  tree stmt, name = NULL;
+
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_consume_token (parser);
+      if (c_parser_next_token_is (parser, CPP_NAME))
+       {
+         name = c_parser_peek_token (parser)->value;
+         c_parser_consume_token (parser);
+         c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+       }
+      else
+       c_parser_error (parser, "expected identifier");
+    }
+  else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
+    c_parser_error (parser, "expected %<(%> or end of line");
+  c_parser_skip_to_pragma_eol (parser);
+
+  stmt = c_parser_omp_structured_block (parser);
+  return c_finish_omp_critical (stmt, name);
+}
+
+/* OpenMP 2.5:
+   # pragma omp flush flush-vars[opt] new-line
+
+   flush-vars:
+     ( variable-list ) */
+
+static void
+c_parser_omp_flush (c_parser *parser)
+{
+  c_parser_consume_pragma (parser);
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    c_parser_omp_var_list_parens (parser, 0, NULL);
+  else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
+    c_parser_error (parser, "expected %<(%> or end of line");
+  c_parser_skip_to_pragma_eol (parser);
+
+  c_finish_omp_flush ();
+}
+
+/* Parse the restricted form of the for statment allowed by OpenMP.
+   The real trick here is to determine the loop control variable early
+   so that we can push a new decl if necessary to make it private.  */
+
+static tree
+c_parser_omp_for_loop (c_parser *parser)
+{
+  tree decl, cond, incr, save_break, save_cont, body, init;
+  location_t loc;
+
+  if (!c_parser_next_token_is_keyword (parser, RID_FOR))
+    {
+      c_parser_error (parser, "for statement expected");
+      return NULL;
+    }
+  loc = c_parser_peek_token (parser)->location;
+  c_parser_consume_token (parser);
+
+  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    return NULL;
+
+  /* Parse the initialization declaration or expression.  */
+  if (c_parser_next_token_starts_declspecs (parser))
+    {
+      c_parser_declaration_or_fndef (parser, true, true, true, true);
+      decl = check_for_loop_decls ();
+      if (decl == NULL)
+       goto error_init;
+      init = decl;
+    }
+  else if (c_parser_next_token_is (parser, CPP_NAME)
+          && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
+    {
+      decl = c_parser_postfix_expression (parser).value;
+
+      c_parser_require (parser, CPP_EQ, "expected %<=%>");
+
+      init = c_parser_expr_no_commas (parser, NULL).value;
+      init = build_modify_expr (decl, NOP_EXPR, init);
+      init = c_process_expr_stmt (init);
+
+      c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
+    }
+  else
+    goto error_init;
+
+  /* Parse the loop condition.  */
+  cond = NULL_TREE;
+  if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
+    {
+      cond = c_parser_expression_conv (parser).value;
+      cond = c_objc_common_truthvalue_conversion (cond);
+      if (EXPR_P (cond))
+       SET_EXPR_LOCATION (cond, input_location);
+    }
+  c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
+
+  /* Parse the increment expression.  */
+  incr = NULL_TREE;
+  if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+    incr = c_process_expr_stmt (c_parser_expression (parser).value);
+  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
+ parse_body:
+  save_break = c_break_label;
+  c_break_label = size_one_node;
+  save_cont = c_cont_label;
+  c_cont_label = NULL_TREE;
+  body = push_stmt_list ();
+
+  add_stmt (c_parser_c99_block_statement (parser));
+  if (c_cont_label)
+    add_stmt (build1 (LABEL_EXPR, void_type_node, c_cont_label));
+
+  body = pop_stmt_list (body);
+  c_break_label = save_break;
+  c_cont_label = save_cont;
+
+  /* Only bother calling c_finish_omp_for if we havn't already generated
+     an error from the initialization parsing.  */
+  if (decl != NULL)
+    return c_finish_omp_for (loc, decl, init, cond, incr, body, NULL);
+  return NULL;
+
+ error_init:
+  c_parser_error (parser, "expected iteration declaration or initialization");
+  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+  decl = init = cond = incr = NULL_TREE;
+  goto parse_body;
+}
+
+/* OpenMP 2.5:
+   #pragma omp for for-clause[optseq] new-line
+     for-loop
+*/
+
+#define OMP_FOR_CLAUSE_MASK                            \
+       ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE)             \
+       | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)        \
+       | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE)         \
+       | (1u << PRAGMA_OMP_CLAUSE_REDUCTION)           \
+       | (1u << PRAGMA_OMP_CLAUSE_ORDERED)             \
+       | (1u << PRAGMA_OMP_CLAUSE_SCHEDULE)            \
+       | (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+c_parser_omp_for (c_parser *parser)
+{
+  tree block, clauses, ret;
+
+  clauses = c_parser_omp_all_clauses (parser, OMP_FOR_CLAUSE_MASK,
+                                     "#pragma omp for");
+
+  block = c_begin_compound_stmt (true);
+  ret = c_parser_omp_for_loop (parser);
+  if (ret)
+    OMP_FOR_CLAUSES (ret) = clauses;
+  block = c_end_compound_stmt (block, true);
+  add_stmt (block);
+
+  return ret;
+}
+
+/* OpenMP 2.5:
+   # pragma omp master new-line
+     structured-block
+*/
+
+static tree
+c_parser_omp_master (c_parser *parser)
+{
+  c_parser_skip_to_pragma_eol (parser);
+  return c_finish_omp_master (c_parser_omp_structured_block (parser));
+}
+
+/* OpenMP 2.5:
+   # pragma omp ordered new-line
+     structured-block
+*/
+
+static tree
+c_parser_omp_ordered (c_parser *parser)
+{
+  c_parser_skip_to_pragma_eol (parser);
+  return c_finish_omp_ordered (c_parser_omp_structured_block (parser));
+}
+
+/* OpenMP 2.5:
+
+   section-scope:
+     { section-sequence }
+
+   section-sequence:
+     section-directive[opt] structured-block
+     section-sequence section-directive structured-block  */
+
+static tree
+c_parser_omp_sections_scope (c_parser *parser)
+{
+  tree stmt, substmt;
+  bool error_suppress = false;
+  location_t loc;
+
+  if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
+    {
+      /* Avoid skipping until the end of the block.  */
+      parser->error = false;
+      return NULL_TREE;
+    }
+
+  stmt = push_stmt_list ();
+
+  loc = c_parser_peek_token (parser)->location;
+  if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
+    {
+      substmt = push_stmt_list ();
+
+      while (1)
+       {
+          c_parser_statement (parser);
+
+         if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
+           break;
+         if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
+           break;
+         if (c_parser_next_token_is (parser, CPP_EOF))
+           break;
+       }
+
+      substmt = pop_stmt_list (substmt);
+      substmt = build1 (OMP_SECTION, void_type_node, substmt);
+      SET_EXPR_LOCATION (substmt, loc);
+      add_stmt (substmt);
+    }
+
+  while (1)
+    {
+      if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
+       break;
+      if (c_parser_next_token_is (parser, CPP_EOF))
+       break;
+
+      loc = c_parser_peek_token (parser)->location;
+      if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
+       {
+         c_parser_consume_pragma (parser);
+         c_parser_skip_to_pragma_eol (parser);
+         error_suppress = false;
+       }
+      else if (!error_suppress)
+       {
+         error ("expected %<#pragma omp section%> or %<}%>");
+         error_suppress = true;
+       }
+
+      substmt = c_parser_omp_structured_block (parser);
+      substmt = build1 (OMP_SECTION, void_type_node, substmt);
+      SET_EXPR_LOCATION (substmt, loc);
+      add_stmt (substmt);
+    }
+  c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
+                            "expected %<#pragma omp section%> or %<}%>");
+
+  substmt = pop_stmt_list (stmt);
+
+  stmt = make_node (OMP_SECTIONS);
+  TREE_TYPE (stmt) = void_type_node;
+  OMP_SECTIONS_BODY (stmt) = substmt;
+
+  return add_stmt (stmt);
+}
+
+/* OpenMP 2.5:
+   # pragma omp sections sections-clause[optseq] newline
+     sections-scope
+*/
+
+#define OMP_SECTIONS_CLAUSE_MASK                       \
+       ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE)             \
+       | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)        \
+       | (1u << PRAGMA_OMP_CLAUSE_LASTPRIVATE)         \
+       | (1u << PRAGMA_OMP_CLAUSE_REDUCTION)           \
+       | (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+c_parser_omp_sections (c_parser *parser)
+{
+  tree block, clauses, ret;
+
+  clauses = c_parser_omp_all_clauses (parser, OMP_SECTIONS_CLAUSE_MASK,
+                                     "#pragma omp sections");
+
+  block = c_begin_compound_stmt (true);
+  ret = c_parser_omp_sections_scope (parser);
+  if (ret)
+    OMP_SECTIONS_CLAUSES (ret) = clauses;
+  block = c_end_compound_stmt (block, true);
+  add_stmt (block);
+
+  return ret;
+}
+
+/* OpenMP 2.5:
+   # pragma parallel parallel-clause new-line
+   # pragma parallel for parallel-for-clause new-line
+   # pragma parallel sections parallel-sections-clause new-line
+*/
+
+#define OMP_PARALLEL_CLAUSE_MASK                       \
+       ( (1u << PRAGMA_OMP_CLAUSE_IF)                  \
+       | (1u << PRAGMA_OMP_CLAUSE_PRIVATE)             \
+       | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)        \
+       | (1u << PRAGMA_OMP_CLAUSE_DEFAULT)             \
+       | (1u << PRAGMA_OMP_CLAUSE_SHARED)              \
+       | (1u << PRAGMA_OMP_CLAUSE_COPYIN)              \
+       | (1u << PRAGMA_OMP_CLAUSE_REDUCTION)           \
+       | (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS))
+
+static tree
+c_parser_omp_parallel (c_parser *parser)
+{
+  enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL;
+  const char *p_name = "#pragma omp parallel";
+  tree stmt, clauses, par_clause, ws_clause, block;
+  unsigned int mask = OMP_PARALLEL_CLAUSE_MASK;
+
+  if (c_parser_next_token_is_keyword (parser, RID_FOR))
+    {
+      c_parser_consume_token (parser);
+      p_kind = PRAGMA_OMP_PARALLEL_FOR;
+      p_name = "#pragma omp parallel for";
+      mask |= OMP_FOR_CLAUSE_MASK;
+      mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT);
+    }
+  else if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      if (strcmp (p, "sections") == 0)
+       {
+         c_parser_consume_token (parser);
+         p_kind = PRAGMA_OMP_PARALLEL_SECTIONS;
+         p_name = "#pragma omp parallel sections";
+         mask |= OMP_SECTIONS_CLAUSE_MASK;
+         mask &= ~(1u << PRAGMA_OMP_CLAUSE_NOWAIT);
+       }
+    }
+
+  clauses = c_parser_omp_all_clauses (parser, mask, p_name);
+
+  switch (p_kind)
+    {
+    case PRAGMA_OMP_PARALLEL:
+      block = c_begin_omp_parallel ();
+      c_parser_statement (parser);
+      stmt = c_finish_omp_parallel (clauses, block);
+      break;
+
+    case PRAGMA_OMP_PARALLEL_FOR:
+      block = c_begin_omp_parallel ();
+      c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
+      stmt = c_parser_omp_for_loop (parser);
+      if (stmt)
+       OMP_FOR_CLAUSES (stmt) = ws_clause;
+      stmt = c_finish_omp_parallel (par_clause, block);
+      break;
+
+    case PRAGMA_OMP_PARALLEL_SECTIONS:
+      block = c_begin_omp_parallel ();
+      c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
+      stmt = c_parser_omp_sections_scope (parser);
+      if (stmt)
+       OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
+      stmt = c_finish_omp_parallel (par_clause, block);
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  return stmt;
+}
+
+/* OpenMP 2.5:
+   # pragma omp single single-clause[optseq] new-line
+     structured-block
+*/
+
+#define OMP_SINGLE_CLAUSE_MASK                         \
+       ( (1u << PRAGMA_OMP_CLAUSE_PRIVATE)             \
+       | (1u << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)        \
+       | (1u << PRAGMA_OMP_CLAUSE_COPYPRIVATE)         \
+       | (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
+
+static tree
+c_parser_omp_single (c_parser *parser)
+{
+  tree stmt = make_node (OMP_SINGLE);
+  TREE_TYPE (stmt) = void_type_node;
+
+  OMP_SINGLE_CLAUSES (stmt)
+    = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
+                               "#pragma omp single");
+  OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser);
+
+  return add_stmt (stmt);
+}
+
+
+/* Main entry point to parsing most OpenMP pragmas.  */
+
+static void
+c_parser_omp_construct (c_parser *parser)
+{
+  enum pragma_kind p_kind;
+  location_t loc;
+  tree stmt;
+
+  loc = c_parser_peek_token (parser)->location;
+  p_kind = c_parser_peek_token (parser)->pragma_kind;
+  c_parser_consume_pragma (parser);
+
+  switch (p_kind)
+    {
+    case PRAGMA_OMP_ATOMIC:
+      c_parser_omp_atomic (parser);
+      return;
+    case PRAGMA_OMP_CRITICAL:
+      stmt = c_parser_omp_critical (parser);
+      break;
+    case PRAGMA_OMP_FOR:
+      stmt = c_parser_omp_for (parser);
+      break;
+    case PRAGMA_OMP_MASTER:
+      stmt = c_parser_omp_master (parser);
+      break;
+    case PRAGMA_OMP_ORDERED:
+      stmt = c_parser_omp_ordered (parser);
+      break;
+    case PRAGMA_OMP_PARALLEL:
+      stmt = c_parser_omp_parallel (parser);
+      break;
+    case PRAGMA_OMP_SECTIONS:
+      stmt = c_parser_omp_sections (parser);
+      break;
+    case PRAGMA_OMP_SINGLE:
+      stmt = c_parser_omp_single (parser);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  if (stmt)
+    SET_EXPR_LOCATION (stmt, loc);
+}
+
+
+/* OpenMP 2.5:
+   # pragma omp threadprivate (variable-list) */
+
+static void
+c_parser_omp_threadprivate (c_parser *parser)
+{
+  tree vars, t;
+
+  c_parser_consume_pragma (parser);
+  vars = c_parser_omp_var_list_parens (parser, 0, NULL);
+
+  if (!targetm.have_tls)
+    sorry ("threadprivate variables not supported in this target");
+
+  /* Mark every variable in VARS to be assigned thread local storage.  */
+  for (t = vars; t; t = TREE_CHAIN (t))
+    {
+      tree v = TREE_PURPOSE (t);
+
+      /* If V had already been marked threadprivate, it doesn't matter
+        whether it had been used prior to this point.  */
+      if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
+       error ("%qE declared %<threadprivate%> after first use", v);
+      else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
+       error ("automatic variable %qE cannot be %<threadprivate%>", v);
+      else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
+       error ("%<threadprivate%> %qE has incomplete type", v);
+      else
+       {
+         if (! DECL_THREAD_LOCAL_P (v))
+           {
+             DECL_TLS_MODEL (v) = decl_default_tls_model (v);
+             /* If rtl has been already set for this var, call
+                make_decl_rtl once again, so that encode_section_info
+                has a chance to look at the new decl flags.  */
+             if (DECL_RTL_SET_P (v))
+               make_decl_rtl (v);
+           }
+         C_DECL_THREADPRIVATE_P (v) = 1;
+       }
+    }
+
+  c_parser_skip_to_pragma_eol (parser);
+}
+
+\f
 /* Parse a single source file.  */
 
 void
index e2a4677..554e57f 100644 (file)
@@ -724,6 +724,32 @@ c_invoke_pragma_handler (unsigned int id)
 void
 init_pragma (void)
 {
+  if (flag_openmp && !flag_preprocess_only)
+    {
+      struct omp_pragma_def { const char *name; unsigned int id; };
+      static const struct omp_pragma_def omp_pragmas[] = {
+       { "atomic", PRAGMA_OMP_ATOMIC },
+       { "barrier", PRAGMA_OMP_BARRIER },
+       { "critical", PRAGMA_OMP_CRITICAL },
+       { "flush", PRAGMA_OMP_FLUSH },
+       { "for", PRAGMA_OMP_FOR },
+       { "master", PRAGMA_OMP_MASTER },
+       { "ordered", PRAGMA_OMP_ORDERED },
+       { "parallel", PRAGMA_OMP_PARALLEL },
+       { "section", PRAGMA_OMP_SECTION },
+       { "sections", PRAGMA_OMP_SECTIONS },
+       { "single", PRAGMA_OMP_SINGLE },
+       { "threadprivate", PRAGMA_OMP_THREADPRIVATE }
+      };
+
+      const int n_omp_pragmas = sizeof (omp_pragmas) / sizeof (*omp_pragmas);
+      int i;
+
+      for (i = 0; i < n_omp_pragmas; ++i)
+       cpp_register_deferred_pragma (parse_in, "omp", omp_pragmas[i].name,
+                                     omp_pragmas[i].id, true, true);
+    }
+
   cpp_register_deferred_pragma (parse_in, "GCC", "pch_preprocess",
                                PRAGMA_GCC_PCH_PREPROCESS, false, false);
 
index 9876555..28ef4e8 100644 (file)
@@ -29,6 +29,21 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 typedef enum pragma_kind {
   PRAGMA_NONE = 0,
 
+  PRAGMA_OMP_ATOMIC,
+  PRAGMA_OMP_BARRIER,
+  PRAGMA_OMP_CRITICAL,
+  PRAGMA_OMP_FLUSH,
+  PRAGMA_OMP_FOR,
+  PRAGMA_OMP_MASTER,
+  PRAGMA_OMP_ORDERED,
+  PRAGMA_OMP_PARALLEL,
+  PRAGMA_OMP_PARALLEL_FOR,
+  PRAGMA_OMP_PARALLEL_SECTIONS,
+  PRAGMA_OMP_SECTION,
+  PRAGMA_OMP_SECTIONS,
+  PRAGMA_OMP_SINGLE,
+  PRAGMA_OMP_THREADPRIVATE,
+
   PRAGMA_GCC_PCH_PREPROCESS,
 
   PRAGMA_FIRST_EXTERNAL
index db6c382..f67c4d2 100644 (file)
@@ -129,6 +129,10 @@ struct lang_type GTY(())
 #define C_DECL_UNDEFINABLE_VM(EXP)     \
   DECL_LANG_FLAG_5 (LABEL_DECL_CHECK (EXP))
 
+/* Record whether a variable has been declared threadprivate by
+   #pragma omp threadprivate.  */
+#define C_DECL_THREADPRIVATE_P(DECL) DECL_LANG_FLAG_3 (VAR_DECL_CHECK (DECL))
+
 /* Nonzero for a decl which either doesn't exist or isn't a prototype.
    N.B. Could be simplified if all built-in decls had complete prototypes
    (but this is presently difficult because some of them need FILE*).  */
@@ -431,7 +435,6 @@ extern int global_bindings_p (void);
 extern void push_scope (void);
 extern tree pop_scope (void);
 extern void insert_block (tree);
-extern tree pushdecl (tree);
 extern void c_expand_body (tree);
 
 extern void c_init_decl_processing (void);
@@ -441,7 +444,7 @@ extern int quals_from_declspecs (const struct c_declspecs *);
 extern struct c_declarator *build_array_declarator (tree, struct c_declspecs *,
                                                    bool, bool);
 extern tree build_enumerator (tree, tree);
-extern void check_for_loop_decls (void);
+extern tree check_for_loop_decls (void);
 extern void mark_forward_parm_decls (void);
 extern void declare_parm_level (void);
 extern void undeclared_variable (tree, location_t);
@@ -461,7 +464,6 @@ extern void pending_xref_error (void);
 extern void c_push_function_context (struct function *);
 extern void c_pop_function_context (struct function *);
 extern void push_parm_decl (const struct c_parm *);
-extern tree pushdecl_top_level (tree);
 extern struct c_declarator *set_array_declarator_inner (struct c_declarator *,
                                                        struct c_declarator *,
                                                        bool);
@@ -529,7 +531,6 @@ extern tree default_conversion (tree);
 extern struct c_expr default_function_array_conversion (struct c_expr);
 extern tree composite_type (tree, tree);
 extern tree build_component_ref (tree, tree);
-extern tree build_indirect_ref (tree, const char *);
 extern tree build_array_ref (tree, tree);
 extern tree build_external_ref (tree, int, location_t);
 extern void pop_maybe_used (bool);
@@ -542,7 +543,6 @@ extern tree build_conditional_expr (tree, tree, tree);
 extern tree build_compound_expr (tree, tree);
 extern tree c_cast_expr (struct c_type_name *, tree);
 extern tree build_c_cast (tree, tree);
-extern tree build_modify_expr (tree, enum tree_code, tree);
 extern void store_init_value (tree, tree);
 extern void error_init (const char *);
 extern void pedwarn_init (const char *);
@@ -577,6 +577,9 @@ extern tree c_finish_goto_ptr (tree);
 extern void c_begin_vm_scope (unsigned int);
 extern void c_end_vm_scope (unsigned int);
 extern tree c_expr_to_decl (tree, bool *, bool *, bool *);
+extern tree c_begin_omp_parallel (void);
+extern tree c_finish_omp_parallel (tree, tree);
+extern tree c_finish_omp_clauses (tree);
 
 /* Set to 0 at beginning of a function definition, set to 1 if
    a return statement that specifies a return value is seen.  */
index e442848..06ffefd 100644 (file)
@@ -2931,10 +2931,13 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
 
        /* Report a read-only lvalue.  */
        if (TREE_READONLY (arg))
-         readonly_error (arg,
-                         ((code == PREINCREMENT_EXPR
-                           || code == POSTINCREMENT_EXPR)
-                          ? lv_increment : lv_decrement));
+         {
+           readonly_error (arg,
+                           ((code == PREINCREMENT_EXPR
+                             || code == POSTINCREMENT_EXPR)
+                            ? lv_increment : lv_decrement));
+           return error_mark_node;
+         }
 
        if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
          val = boolean_increment (code, arg);
@@ -3645,7 +3648,10 @@ build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
       || ((TREE_CODE (lhstype) == RECORD_TYPE
           || TREE_CODE (lhstype) == UNION_TYPE)
          && C_TYPE_FIELDS_READONLY (lhstype)))
-    readonly_error (lhs, lv_assign);
+    {
+      readonly_error (lhs, lv_assign);
+      return error_mark_node;
+    }
 
   /* If storing into a structure or union member,
      it has probably been given type `int'.
@@ -7310,13 +7316,24 @@ c_finish_bc_stmt (tree *label_p, bool is_break)
       if (!skip)
        *label_p = label = create_artificial_label ();
     }
-  else if (TREE_CODE (label) != LABEL_DECL)
+  else if (TREE_CODE (label) == LABEL_DECL)
+    ;
+  else switch (TREE_INT_CST_LOW (label))
     {
+    case 0:
       if (is_break)
        error ("break statement not within loop or switch");
       else
         error ("continue statement not within a loop");
       return NULL_TREE;
+
+    case 1:
+      gcc_assert (is_break);
+      error ("break statement used with OpenMP for loop");
+      return NULL_TREE;
+
+    default:
+      gcc_unreachable ();
     }
 
   if (skip)
@@ -8443,3 +8460,248 @@ c_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
   else
     return expr;
 }
+
+\f
+/* Like c_begin_compound_stmt, except force the retension of the BLOCK.  */
+
+tree
+c_begin_omp_parallel (void)
+{
+  tree block;
+
+  keep_next_level ();
+  block = c_begin_compound_stmt (true);
+
+  return block;
+}
+
+tree
+c_finish_omp_parallel (tree clauses, tree block)
+{
+  tree stmt;
+
+  block = c_end_compound_stmt (block, true);
+
+  stmt = make_node (OMP_PARALLEL);
+  TREE_TYPE (stmt) = void_type_node;
+  OMP_PARALLEL_CLAUSES (stmt) = clauses;
+  OMP_PARALLEL_BODY (stmt) = block;
+
+  return add_stmt (stmt);
+}
+
+/* For all elements of CLAUSES, validate them vs OpenMP constraints.
+   Remove any elements from the list that are invalid.  */
+
+tree
+c_finish_omp_clauses (tree clauses)
+{
+  bitmap_head generic_head, firstprivate_head, lastprivate_head;
+  tree c, t, *pc = &clauses;
+  const char *name;
+
+  bitmap_obstack_initialize (NULL);
+  bitmap_initialize (&generic_head, &bitmap_default_obstack);
+  bitmap_initialize (&firstprivate_head, &bitmap_default_obstack);
+  bitmap_initialize (&lastprivate_head, &bitmap_default_obstack);
+
+  for (pc = &clauses, c = clauses; c ; c = *pc)
+    {
+      bool remove = false;
+      bool need_complete = false;
+      bool need_implicitly_determined = false;
+
+      switch (TREE_CODE (c))
+       {
+       case OMP_CLAUSE_SHARED:
+         name = "shared";
+         need_implicitly_determined = true;
+         goto check_dup_generic;
+
+       case OMP_CLAUSE_PRIVATE:
+         name = "private";
+         need_complete = true;
+         need_implicitly_determined = true;
+         goto check_dup_generic;
+
+       case OMP_CLAUSE_REDUCTION:
+         name = "reduction";
+         need_implicitly_determined = true;
+         t = OMP_CLAUSE_DECL (c);
+         if (AGGREGATE_TYPE_P (TREE_TYPE (t))
+             || POINTER_TYPE_P (TREE_TYPE (t)))
+           {
+             error ("%qE has invalid type for %<reduction%>", t);
+             remove = true;
+           }
+         else if (FLOAT_TYPE_P (TREE_TYPE (t)))
+           {
+             enum tree_code r_code = OMP_CLAUSE_REDUCTION_CODE (c);
+             const char *r_name = NULL;
+
+             switch (r_code)
+               {
+               case PLUS_EXPR:
+               case MULT_EXPR:
+               case MINUS_EXPR:
+                 break;
+               case BIT_AND_EXPR:
+                 r_name = "&";
+                 break;
+               case BIT_XOR_EXPR:
+                 r_name = "^";
+                 break;
+               case BIT_IOR_EXPR:
+                 r_name = "|";
+                 break;
+               case TRUTH_ANDIF_EXPR:
+                 r_name = "&&";
+                 break;
+               case TRUTH_ORIF_EXPR:
+                 r_name = "||";
+                 break;
+               default:
+                 gcc_unreachable ();
+               }
+             if (r_name)
+               {
+                 error ("%qE has invalid type for %<reduction(%s)%>",
+                        t, r_name);
+                 remove = true;
+               }
+           }
+         goto check_dup_generic;
+
+       case OMP_CLAUSE_COPYPRIVATE:
+         name = "copyprivate";
+         goto check_dup_generic;
+
+       case OMP_CLAUSE_COPYIN:
+         name = "copyin";
+         t = OMP_CLAUSE_DECL (c);
+         if (TREE_CODE (t) != VAR_DECL || !DECL_THREAD_LOCAL_P (t))
+           {
+             error ("%qE must be %<threadprivate%> for %<copyin%>", t);
+             remove = true;
+           }
+         goto check_dup_generic;
+
+       check_dup_generic:
+         t = OMP_CLAUSE_DECL (c);
+         if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
+           {
+             error ("%qE is not a variable in clause %qs", t, name);
+             remove = true;
+           }
+         else if (bitmap_bit_p (&generic_head, DECL_UID (t))
+                  || bitmap_bit_p (&firstprivate_head, DECL_UID (t))
+                  || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
+           {
+             error ("%qE appears more than once in data clauses", t);
+             remove = true;
+           }
+         else
+           bitmap_set_bit (&generic_head, DECL_UID (t));
+         break;
+
+       case OMP_CLAUSE_FIRSTPRIVATE:
+         name = "firstprivate";
+         t = OMP_CLAUSE_DECL (c);
+         need_complete = true;
+         need_implicitly_determined = true;
+         if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
+           {
+             error ("%qE is not a variable in clause %<firstprivate%>", t);
+             remove = true;
+           }
+         else if (bitmap_bit_p (&generic_head, DECL_UID (t))
+                  || bitmap_bit_p (&firstprivate_head, DECL_UID (t)))
+           {
+             error ("%qE appears more than once in data clauses", t);
+             remove = true;
+           }
+         else
+           bitmap_set_bit (&firstprivate_head, DECL_UID (t));
+         break;
+
+       case OMP_CLAUSE_LASTPRIVATE:
+         name = "lastprivate";
+         t = OMP_CLAUSE_DECL (c);
+         need_complete = true;
+         need_implicitly_determined = true;
+         if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
+           {
+             error ("%qE is not a variable in clause %<lastprivate%>", t);
+             remove = true;
+           }
+         else if (bitmap_bit_p (&generic_head, DECL_UID (t))
+                  || bitmap_bit_p (&lastprivate_head, DECL_UID (t)))
+           {
+             error ("%qE appears more than once in data clauses", t);
+             remove = true;
+           }
+         else
+           bitmap_set_bit (&lastprivate_head, DECL_UID (t));
+         break;
+
+       case OMP_CLAUSE_IF:
+       case OMP_CLAUSE_NUM_THREADS:
+       case OMP_CLAUSE_SCHEDULE:
+       case OMP_CLAUSE_NOWAIT:
+       case OMP_CLAUSE_ORDERED:
+       case OMP_CLAUSE_DEFAULT:
+         pc = &OMP_CLAUSE_CHAIN (c);
+         continue;
+
+       default:
+         gcc_unreachable ();
+       }
+
+      if (!remove)
+       {
+         t = OMP_CLAUSE_DECL (c);
+
+         if (need_complete)
+           {
+             t = require_complete_type (t);
+             if (t == error_mark_node)
+               remove = true;
+           }
+
+         if (need_implicitly_determined)
+           {
+             const char *share_name = NULL;
+
+             if (TREE_CODE (t) == VAR_DECL && DECL_THREAD_LOCAL_P (t))
+               share_name = "threadprivate";
+             else switch (c_omp_predetermined_sharing (t))
+               {
+               case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
+                 break;
+               case OMP_CLAUSE_DEFAULT_SHARED:
+                 share_name = "shared";
+                 break;
+               case OMP_CLAUSE_DEFAULT_PRIVATE:
+                 share_name = "private";
+                 break;
+               default:
+                 gcc_unreachable ();
+               }
+             if (share_name)
+               {
+                 error ("%qE is predetermined %qs for %qs",
+                        t, share_name, name);
+                 remove = true;
+               }
+           }
+       }
+
+      if (remove)
+       *pc = OMP_CLAUSE_CHAIN (c);
+      else
+       pc = &OMP_CLAUSE_CHAIN (c);
+    }
+
+  bitmap_obstack_release (NULL);
+  return clauses;
+}
index 1338b11..9d11ca6 100644 (file)
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -617,6 +617,10 @@ fobjc-sjlj-exceptions
 ObjC ObjC++ Var(flag_objc_sjlj_exceptions) Init(-1)
 Enable Objective-C setjmp exception handling runtime
 
+fopenmp
+C ObjC C++ ObjC++ Var(flag_openmp)
+Enable OpenMP
+
 foperator-names
 C++ ObjC++
 Recognize C++ kewords like \"compl\" and \"xor\"
index 10a2233..4e4add8 100644 (file)
@@ -113,6 +113,9 @@ struct cgraph_node *cgraph_nodes;
 /* Queue of cgraph nodes scheduled to be lowered.  */
 struct cgraph_node *cgraph_nodes_queue;
 
+/* Queue of cgraph nodes scheduled to be analyzed.  */
+struct cgraph_node *cgraph_analyze_queue;
+
 /* Number of nodes in existence.  */
 int cgraph_n_nodes;
 
@@ -1091,4 +1094,20 @@ cgraph_variable_initializer_availability (struct cgraph_varpool_node *node)
   return AVAIL_AVAILABLE;
 }
 
+
+/* Add the function FNDECL to the call graph.  This assumes that the
+   body of FNDECL is in GENERIC form and ready to be processed by
+   cgraph_finalize_function.  */
+
+void
+cgraph_add_new_function (tree fndecl)
+{
+  /* We're called while lowering another function.  We can't do anything
+     at this time without recursing.  Which would cause a GC at an 
+     inappropriate time.  */
+  struct cgraph_node *n = cgraph_node (fndecl);
+  n->next_needed = cgraph_analyze_queue;
+  cgraph_analyze_queue = n;
+}
+
 #include "gt-cgraph.h"
index 82cf2d9..600b00e 100644 (file)
@@ -239,6 +239,7 @@ extern GTY(()) int cgraph_max_uid;
 extern bool cgraph_global_info_ready;
 extern bool cgraph_function_flags_ready;
 extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
+extern GTY(()) struct cgraph_node *cgraph_analyze_queue;
 
 extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_first_unanalyzed_node;
 extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
@@ -288,12 +289,12 @@ enum availability cgraph_function_body_availability (struct cgraph_node *);
 enum availability cgraph_variable_initializer_availability (struct cgraph_varpool_node *);
 bool cgraph_is_master_clone (struct cgraph_node *);
 struct cgraph_node *cgraph_master_clone (struct cgraph_node *);
+void cgraph_add_new_function (tree);
 
 /* In cgraphunit.c  */
 bool cgraph_assemble_pending_functions (void);
 bool cgraph_varpool_assemble_pending_decls (void);
 void cgraph_finalize_function (tree, bool);
-void cgraph_lower_function (struct cgraph_node *);
 void cgraph_finalize_compilation_unit (void);
 void cgraph_optimize (void);
 void cgraph_mark_needed_node (struct cgraph_node *);
@@ -307,6 +308,7 @@ void cgraph_reset_static_var_maps (void);
 void init_cgraph (void);
 struct cgraph_node *cgraph_function_versioning (struct cgraph_node *,
                                                 varray_type, varray_type);
+void cgraph_analyze_function (struct cgraph_node *);
 struct cgraph_node *save_inline_function_body (struct cgraph_node *);
 
 /* In ipa.c  */
index ae9f690..995bcb9 100644 (file)
@@ -171,7 +171,6 @@ static void cgraph_expand_all_functions (void);
 static void cgraph_mark_functions_to_output (void);
 static void cgraph_expand_function (struct cgraph_node *);
 static tree record_reference (tree *, int *, void *);
-static void cgraph_analyze_function (struct cgraph_node *node);
 
 /* Records tree nodes seen in record_reference.  Simply using
    walk_tree_without_duplicates doesn't guarantee each node is visited
@@ -410,6 +409,29 @@ cgraph_reset_node (struct cgraph_node *node)
     }
 }
 
+static void
+cgraph_lower_function (struct cgraph_node *node)
+{
+  if (node->lowered)
+    return;
+  tree_lowering_passes (node->decl);
+  node->lowered = true;
+}
+
+static void
+cgraph_finalize_pending_functions (void)
+{
+  struct cgraph_node *next, *node = cgraph_analyze_queue;
+
+  cgraph_analyze_queue = NULL;
+  for (; node ; node = next)
+    {
+      next = node->next_needed;
+      node->next_needed = NULL;
+      cgraph_finalize_function (node->decl, true);
+    }
+}
+
 /* DECL has been parsed.  Take it, queue it, compile it at the whim of the
    logic in effect.  If NESTED is true, then our caller cannot stand to have
    the garbage collector run at the moment.  We would need to either create
@@ -436,6 +458,7 @@ cgraph_finalize_function (tree decl, bool nested)
   if (!flag_unit_at_a_time)
     {
       cgraph_analyze_function (node);
+      cgraph_finalize_pending_functions ();
       cgraph_decide_inlining_incrementally (node, false);
     }
 
@@ -465,15 +488,6 @@ cgraph_finalize_function (tree decl, bool nested)
     do_warn_unused_parameter (decl);
 }
 
-void
-cgraph_lower_function (struct cgraph_node *node)
-{
-  if (node->lowered)
-    return;
-  tree_lowering_passes (node->decl);
-  node->lowered = true;
-}
-
 /* Walk tree and record all calls.  Called via walk_tree.  */
 static tree
 record_reference (tree *tp, int *walk_subtrees, void *data)
@@ -878,7 +892,7 @@ cgraph_output_pending_asms (void)
 }
 
 /* Analyze the function scheduled to be output.  */
-static void
+void
 cgraph_analyze_function (struct cgraph_node *node)
 {
   tree decl = node->decl;
@@ -968,6 +982,7 @@ cgraph_finalize_compilation_unit (void)
       gcc_assert (DECL_SAVED_TREE (decl));
 
       cgraph_analyze_function (node);
+      cgraph_finalize_pending_functions ();
 
       for (edge = node->callees; edge; edge = edge->next_callee)
        if (!edge->callee->reachable)
index 70481bb..ddd508e 100644 (file)
@@ -834,4 +834,10 @@ void add_framework_path (char *);
 
 #define WINT_TYPE "int"
 
+/* Every program on darwin links against libSystem which contains the pthread
+   routines, so there's no need to explicitly call out when doing threaded
+   work.  */
+#undef GOMP_SELF_SPECS
+#define GOMP_SELF_SPECS ""
+
 #endif /* CONFIG_DARWIN_H */
index 3a3204b..242cf47 100644 (file)
@@ -203,5 +203,6 @@ extern void print_generic_decl (FILE *, tree, int);
 
 extern void debug_generic_expr (tree);
 extern void debug_generic_stmt (tree);
+extern void debug_tree_chain (tree);
 extern void debug_c_tree (tree);
 #endif /* ! GCC_DIAGNOSTIC_H */
index c1c87f2..629e4a9 100644 (file)
@@ -765,7 +765,7 @@ See S/390 and zSeries Options.
 -fargument-noalias-global  -fleading-underscore @gol
 -ftls-model=@var{model} @gol
 -ftrapv  -fwrapv  -fbounds-check @gol
--fvisibility}
+-fvisibility  -fopenmp}
 @end table
 
 @menu
@@ -4701,6 +4701,15 @@ instrumentation (and therefore faster execution) and still provides
 some protection against outright memory corrupting writes, but allows
 erroneously read data to propagate within a program.
 
+@item -fopenmp
+@opindex fopenmp
+@cindex openmp parallel
+Enable handling of OpenMP directives @code{#pragma omp} in C/C++ and
+@code{!$omp} in Fortran.  When @option{-fopenmp} is specified, the
+compiler generates parallel code according to the OpenMP Application
+Program Interface v2.5.  To generate the final exectuable, the runtime
+library @code{libgomp} must be linked in using @option{-lgomp}.
+
 @item -fstrength-reduce
 @opindex fstrength-reduce
 Perform the optimizations of loop strength reduction and
index 572bfc9..87d92e8 100644 (file)
@@ -9015,7 +9015,6 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
 {
   dw_loc_descr_ref ret, ret1;
   int have_address = 0;
-  int unsignedp = TYPE_UNSIGNED (TREE_TYPE (loc));
   enum dwarf_location_atom op;
 
   /* ??? Most of the time we do not take proper care for sign/zero
@@ -9159,6 +9158,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
        HOST_WIDE_INT bitsize, bitpos, bytepos;
        enum machine_mode mode;
        int volatilep;
+       int unsignedp = TYPE_UNSIGNED (TREE_TYPE (loc));
 
        obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode,
                                   &unsignedp, &volatilep, false);
@@ -9257,7 +9257,7 @@ loc_descriptor_from_tree_1 (tree loc, int want_address)
       goto do_binop;
 
     case RSHIFT_EXPR:
-      op = (unsignedp ? DW_OP_shr : DW_OP_shra);
+      op = (TYPE_UNSIGNED (TREE_TYPE (loc)) ? DW_OP_shr : DW_OP_shra);
       goto do_binop;
 
     case PLUS_EXPR:
index 392bac4..bff3ae8 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -352,6 +352,7 @@ static const char *if_exists_spec_function (int, const char **);
 static const char *if_exists_else_spec_function (int, const char **);
 static const char *replace_outfile_spec_function (int, const char **);
 static const char *version_compare_spec_function (int, const char **);
+static const char *include_spec_function (int, const char **);
 \f
 /* The Specs Language
 
@@ -698,7 +699,8 @@ proper position among the other output files.  */
 %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
     %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
-    %{static:} %{L*} %(mfwrap) %(link_libgcc) %o %(mflib)\
+    %{static:} %{L*} %(mfwrap) %{fopenmp:%:include(libgomp.spec)%(link_gomp)}\
+    %(link_libgcc) %o %(mflib)\
     %{fprofile-arcs|fprofile-generate|coverage:-lgcov}\
     %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
     %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
@@ -737,6 +739,7 @@ static const char *link_spec = LINK_SPEC;
 static const char *lib_spec = LIB_SPEC;
 static const char *mfwrap_spec = MFWRAP_SPEC;
 static const char *mflib_spec = MFLIB_SPEC;
+static const char *link_gomp_spec = "";
 static const char *libgcc_spec = LIBGCC_SPEC;
 static const char *endfile_spec = ENDFILE_SPEC;
 static const char *startfile_spec = STARTFILE_SPEC;
@@ -835,7 +838,15 @@ static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
 #define DRIVER_SELF_SPECS ""
 #endif
 
-static const char *const driver_self_specs[] = { DRIVER_SELF_SPECS };
+/* Adding -fopenmp should imply pthreads.  This is particularly important
+   for targets that use different start files and suchlike.  */
+#ifndef GOMP_SELF_SPECS
+#define GOMP_SELF_SPECS "%{fopenmp: -pthread}"
+#endif
+
+static const char *const driver_self_specs[] = {
+  DRIVER_SELF_SPECS, GOMP_SELF_SPECS
+};
 
 #ifndef OPTION_DEFAULT_SPECS
 #define OPTION_DEFAULT_SPECS { "", "" }
@@ -1534,6 +1545,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("lib",                     &lib_spec),
   INIT_STATIC_SPEC ("mfwrap",                  &mfwrap_spec),
   INIT_STATIC_SPEC ("mflib",                   &mflib_spec),
+  INIT_STATIC_SPEC ("link_gomp",               &link_gomp_spec),
   INIT_STATIC_SPEC ("libgcc",                  &libgcc_spec),
   INIT_STATIC_SPEC ("startfile",               &startfile_spec),
   INIT_STATIC_SPEC ("switches_need_spaces",    &switches_need_spaces),
@@ -1581,6 +1593,7 @@ static const struct spec_function static_spec_functions[] =
   { "if-exists-else",          if_exists_else_spec_function },
   { "replace-outfile",         replace_outfile_spec_function },
   { "version-compare",         version_compare_spec_function },
+  { "include",                 include_spec_function },
   { 0, 0 }
 };
 
@@ -3281,11 +3294,11 @@ process_command (int argc, const char **argv)
     }
 
   /* If there is a -V or -b option (or both), process it now, before
-     trying to interpret the rest of the command line. 
+     trying to interpret the rest of the command line.
      Use heuristic that all configuration names must have at least
      one dash '-'. This allows us to pass options starting with -b.  */
   if (argc > 1 && argv[1][0] == '-'
-      && (argv[1][1] == 'V' || 
+      && (argv[1][1] == 'V' ||
         ((argv[1][1] == 'b') && (NULL != strchr(argv[1] + 2,'-')))))
     {
       const char *new_version = DEFAULT_TARGET_VERSION;
@@ -5518,10 +5531,10 @@ input_suffix_matches (const char *atom, const char *end_atom)
          && input_suffix[end_atom - atom] == '\0');
 }
 
-/* Inline subroutine of handle_braces.  Returns true if a switch
+/* Subroutine of handle_braces.  Returns true if a switch
    matching the atom bracketed by ATOM and END_ATOM appeared on the
    command line.  */
-static inline bool
+static bool
 switch_matches (const char *atom, const char *end_atom, int starred)
 {
   int i;
@@ -6458,7 +6471,7 @@ main (int argc, char **argv)
   if (combine_flag)
     combine_inputs = true;
   else
-    combine_inputs = false;  
+    combine_inputs = false;
 
   for (i = 0; (int) i < n_infiles; i++)
     {
@@ -6489,7 +6502,7 @@ main (int argc, char **argv)
       infiles[i].compiled = false;
       infiles[i].preprocessed = false;
     }
-    
+
   if (!combine_inputs && have_c && have_o && lang_n_infiles > 1)
    fatal ("cannot specify -o with -c or -S with multiple files");
 
@@ -7780,3 +7793,22 @@ version_compare_spec_function (int argc, const char **argv)
 
   return argv[nargs + 2];
 }
+
+/* %:include builtin spec function.  This differs from %include in that it
+   can be nested inside a spec, and thus be conditionalized.  It takes
+   one argument, the filename, and looks for it in the startfile path.
+   The result is always NULL, i.e. an empty expansion.  */
+
+static const char *
+include_spec_function (int argc, const char **argv)
+{
+  char *file;
+
+  if (argc != 1)
+    abort ();
+
+  file = find_a_file (&startfile_prefixes, argv[0], R_OK, 0);
+  read_specs (file ? file : argv[0], FALSE);
+
+  return NULL;
+}
index de0f6f2..2a49eed 100644 (file)
@@ -69,13 +69,12 @@ lower_function_body (void)
 
   gcc_assert (TREE_CODE (bind) == BIND_EXPR);
 
+  memset (&data, 0, sizeof (data));
   data.block = DECL_INITIAL (current_function_decl);
   BLOCK_SUBBLOCKS (data.block) = NULL_TREE;
   BLOCK_CHAIN (data.block) = NULL_TREE;
   TREE_ASM_WRITTEN (data.block) = 1;
 
-  data.return_statements = NULL_TREE;
-
   *body_p = alloc_stmt_list ();
   i = tsi_start (*body_p);
   tsi_link_after (&i, bind, TSI_NEW_STMT);
@@ -196,11 +195,6 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data)
       break;
 
     default:
-#ifdef ENABLE_CHECKING
-      print_node_brief (stderr, "", stmt, 0);
-      internal_error ("unexpected node");
-#endif
-    case COMPOUND_EXPR:
       gcc_unreachable ();
     }
 
index 8783dc6..acd0468 100644 (file)
@@ -46,21 +46,67 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "ggc.h"
 #include "toplev.h"
 #include "target.h"
+#include "optabs.h"
+#include "pointer-set.h"
 
-static struct gimplify_ctx
+
+enum gimplify_omp_var_data
+{
+  GOVD_SEEN = 1,
+  GOVD_EXPLICIT = 2,
+  GOVD_SHARED = 4,
+  GOVD_PRIVATE = 8,
+  GOVD_FIRSTPRIVATE = 16,
+  GOVD_LASTPRIVATE = 32,
+  GOVD_REDUCTION = 64,
+  GOVD_LOCAL = 128,
+  GOVD_DEBUG_PRIVATE = 256,
+  GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
+                          | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL)
+};
+
+struct gimplify_omp_ctx
 {
+  struct gimplify_omp_ctx *outer_context;
+  splay_tree variables;
+  struct pointer_set_t *privatized_types;
+  location_t location;
+  enum omp_clause_default_kind default_kind;
+  bool is_parallel;
+};
+
+struct gimplify_ctx
+{
+  struct gimplify_ctx *prev_context;
+
   tree current_bind_expr;
   tree temps;
   tree conditional_cleanups;
   tree exit_label;
   tree return_temp;
+  
   VEC(tree,heap) *case_labels;
   /* The formal temporary table.  Should this be persistent?  */
   htab_t temp_htab;
+
   int conditions;
   bool save_stack;
   bool into_ssa;
-} *gimplify_ctxp;
+
+  /* When gimplifying combined omp parallel directives (omp parallel
+     loop and omp parallel sections), any prefix code needed to setup
+     the associated worksharing construct needs to be emitted in the
+     pre-queue of its parent parallel, otherwise the lowering process
+     will move that code to the child function.  Similarly, we need to
+     move up to the gimplification context of the parent parallel
+     directive so temporaries are declared in the right context.  */
+  tree *combined_pre_p;
+  struct gimplify_ctx *combined_ctxp;
+};
+
+static struct gimplify_ctx *gimplify_ctxp;
+static struct gimplify_omp_ctx *gimplify_omp_ctxp;
+
 
 
 /* Formal (expression) temporary table handling: Multiple occurrences of
@@ -116,14 +162,14 @@ gimple_tree_eq (const void *p1, const void *p2)
 void
 push_gimplify_context (void)
 {
-  gcc_assert (!gimplify_ctxp);
-  gimplify_ctxp
-    = (struct gimplify_ctx *) xcalloc (1, sizeof (struct gimplify_ctx));
+  struct gimplify_ctx *c;
+
+  c = (struct gimplify_ctx *) xcalloc (1, sizeof (struct gimplify_ctx));
+  c->prev_context = gimplify_ctxp;
   if (optimize)
-    gimplify_ctxp->temp_htab
-      = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
-  else
-    gimplify_ctxp->temp_htab = NULL;
+    c->temp_htab = htab_create (1000, gimple_tree_hash, gimple_tree_eq, free);
+
+  gimplify_ctxp = c;
 }
 
 /* Tear down a context for the gimplifier.  If BODY is non-null, then
@@ -133,28 +179,23 @@ push_gimplify_context (void)
 void
 pop_gimplify_context (tree body)
 {
+  struct gimplify_ctx *c = gimplify_ctxp;
   tree t;
 
-  gcc_assert (gimplify_ctxp && !gimplify_ctxp->current_bind_expr);
+  gcc_assert (c && !c->current_bind_expr);
+  gimplify_ctxp = c->prev_context;
 
-  for (t = gimplify_ctxp->temps; t ; t = TREE_CHAIN (t))
+  for (t = c->temps; t ; t = TREE_CHAIN (t))
     DECL_GIMPLE_FORMAL_TEMP_P (t) = 0;
 
   if (body)
-    declare_tmp_vars (gimplify_ctxp->temps, body);
+    declare_tmp_vars (c->temps, body);
   else
-    record_vars (gimplify_ctxp->temps);
-
-#if 0
-  if (!quiet_flag && optimize)
-    fprintf (stderr, " collisions: %f ",
-            htab_collisions (gimplify_ctxp->temp_htab));
-#endif
+    record_vars (c->temps);
 
   if (optimize)
-    htab_delete (gimplify_ctxp->temp_htab);
-  free (gimplify_ctxp);
-  gimplify_ctxp = NULL;
+    htab_delete (c->temp_htab);
+  free (c);
 }
 
 static void
@@ -214,6 +255,48 @@ gimple_pop_condition (tree *pre_p)
     }
 }
 
+/* A stable comparison routine for use with splay trees and DECLs.  */
+
+static int
+splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
+{
+  tree a = (tree) xa;
+  tree b = (tree) xb;
+
+  return DECL_UID (a) - DECL_UID (b);
+}
+
+/* Create a new omp construct that deals with variable remapping.  */
+
+static struct gimplify_omp_ctx *
+new_omp_context (bool is_parallel)
+{
+  struct gimplify_omp_ctx *c;
+
+  c = XCNEW (struct gimplify_omp_ctx);
+  c->outer_context = gimplify_omp_ctxp;
+  c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
+  c->privatized_types = pointer_set_create ();
+  c->location = input_location;
+  c->is_parallel = is_parallel;
+  c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
+
+  return c;
+}
+
+/* Destroy an omp construct that deals with variable remapping.  */
+
+static void
+delete_omp_context (struct gimplify_omp_ctx *c)
+{
+  splay_tree_delete (c->variables);
+  pointer_set_destroy (c->privatized_types);
+  XDELETE (c);
+}
+
+static void omp_add_variable (struct gimplify_omp_ctx *, tree, unsigned int);
+static bool omp_notice_variable (struct gimplify_omp_ctx *, tree, bool);
+
 /* A subroutine of append_to_statement_list{,_force}.  T is not NULL.  */
 
 static void
@@ -601,6 +684,16 @@ gimple_add_tmp_var (tree tmp)
     {
       TREE_CHAIN (tmp) = gimplify_ctxp->temps;
       gimplify_ctxp->temps = tmp;
+
+      /* Mark temporaries local within the nearest enclosing parallel.  */
+      if (gimplify_omp_ctxp)
+       {
+         struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
+         while (ctx && !ctx->is_parallel)
+           ctx = ctx->outer_context;
+         if (ctx)
+           omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
+       }
     }
   else if (cfun)
     record_vars (tmp);
@@ -933,6 +1026,16 @@ gimplify_bind_expr (tree *expr_p, tree temp, tree *pre_p)
        DECL_COMPLEX_GIMPLE_REG_P (t) = 1;
     }
 
+  /* Mark variables seen in this bind expr as locals.  */
+  if (gimplify_omp_ctxp)
+    {
+      struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
+
+      for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
+       if (TREE_CODE (t) == VAR_DECL && !is_global_var (t))
+         omp_add_variable (ctx, t, GOVD_LOCAL | GOVD_SEEN);
+    }
+
   gimple_push_bind_expr (bind_expr);
   gimplify_ctxp->save_stack = false;
 
@@ -1282,9 +1385,16 @@ static enum gimplify_status
 gimplify_case_label_expr (tree *expr_p)
 {
   tree expr = *expr_p;
+  struct gimplify_ctx *ctxp;
+
+  /* Invalid OpenMP programs can play Duff's Device type games with
+     #pragma omp parallel.  At least in the C front end, we don't
+     detect such invalid branches until after gimplification.  */
+  for (ctxp = gimplify_ctxp; ; ctxp = ctxp->prev_context)
+    if (ctxp->case_labels)
+      break;
 
-  gcc_assert (gimplify_ctxp->case_labels);
-  VEC_safe_push (tree, heap, gimplify_ctxp->case_labels, expr);
+  VEC_safe_push (tree, heap, ctxp->case_labels, expr);
   *expr_p = build1 (LABEL_EXPR, void_type_node, CASE_LABEL (expr));
   return GS_ALL_DONE;
 }
@@ -1491,6 +1601,10 @@ gimplify_var_or_parm_decl (tree *expr_p)
       return GS_ERROR;
     }
 
+  /* When within an OpenMP context, notice uses of variables.  */
+  if (gimplify_omp_ctxp && omp_notice_variable (gimplify_omp_ctxp, decl, true))
+    return GS_ALL_DONE;
+
   /* If the decl is an alias for another expression, substitute it now.  */
   if (DECL_HAS_VALUE_EXPR_P (decl))
     {
@@ -4017,6 +4131,1049 @@ gimplify_to_stmt_list (tree *stmt_p)
     }
 }
 
+/* Gimplify *EXPR_P as if it had been used inside the gimplification
+   context CTX_P.  The other arguments are as in gimplify_expr.  */
+
+static enum gimplify_status
+gimplify_expr_in_ctx (tree *expr_p, tree *pre_p, tree *post_p, 
+                     bool (* gimple_test_f) (tree), fallback_t fallback,
+                     struct gimplify_ctx *ctx_p,
+                     struct gimplify_omp_ctx *omp_ctx_p)
+{
+  enum gimplify_status ret;
+  struct gimplify_ctx *prev_ctxp;
+  struct gimplify_omp_ctx *prev_omp_ctxp;
+  
+  prev_ctxp = gimplify_ctxp;
+  gimplify_ctxp = ctx_p;
+  prev_omp_ctxp = gimplify_omp_ctxp;
+  gimplify_omp_ctxp = omp_ctx_p;
+  ret = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fallback);
+  gimplify_ctxp = prev_ctxp;
+  gimplify_omp_ctxp = prev_omp_ctxp;
+
+  return ret;
+}
+
+/* Add FIRSTPRIVATE entries for DECL in the OpenMP the surrounding parallels
+   to CTX.  If entries already exist, force them to be some flavor of private.
+   If there is no enclosing parallel, do nothing.  */
+
+void
+omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
+{
+  splay_tree_node n;
+
+  if (decl == NULL || !DECL_P (decl))
+    return;
+
+  do
+    {
+      n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
+      if (n != NULL)
+       {
+         if (n->value & GOVD_SHARED)
+           n->value = GOVD_FIRSTPRIVATE | (n->value & GOVD_SEEN);
+         else
+           return;
+       }
+      else if (ctx->is_parallel)
+       omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
+
+      ctx = ctx->outer_context;
+    }
+  while (ctx);
+}
+
+/* Similarly for each of the type sizes of TYPE.  */
+
+static void
+omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
+{
+  if (type == NULL || type == error_mark_node)
+    return;
+  type = TYPE_MAIN_VARIANT (type);
+
+  if (pointer_set_insert (ctx->privatized_types, type))
+    return;
+
+  switch (TREE_CODE (type))
+    {
+    case INTEGER_TYPE:
+    case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
+    case CHAR_TYPE:
+    case REAL_TYPE:
+      omp_firstprivatize_variable (ctx, TYPE_MIN_VALUE (type));
+      omp_firstprivatize_variable (ctx, TYPE_MAX_VALUE (type));
+      break;
+
+    case ARRAY_TYPE:
+      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
+      omp_firstprivatize_type_sizes (ctx, TYPE_DOMAIN (type));
+      break;
+
+    case RECORD_TYPE:
+    case UNION_TYPE:
+    case QUAL_UNION_TYPE:
+      {
+       tree field;
+       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+         if (TREE_CODE (field) == FIELD_DECL)
+           {
+             omp_firstprivatize_variable (ctx, DECL_FIELD_OFFSET (field));
+             omp_firstprivatize_type_sizes (ctx, TREE_TYPE (field));
+           }
+      }
+      break;
+
+    case POINTER_TYPE:
+    case REFERENCE_TYPE:
+      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (type));
+      break;
+
+    default:
+      break;
+    }
+
+  omp_firstprivatize_variable (ctx, TYPE_SIZE (type));
+  omp_firstprivatize_variable (ctx, TYPE_SIZE_UNIT (type));
+  lang_hooks.types.omp_firstprivatize_type_sizes (ctx, type);
+}
+
+/* Add an entry for DECL in the OpenMP context CTX with FLAGS.  */
+
+static void
+omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
+{
+  splay_tree_node n;
+  unsigned int nflags;
+  tree t;
+
+  if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
+    return;
+
+  /* Never elide decls whose type has TREE_ADDRESSABLE set.  This means
+     there are constructors involved somewhere.  */
+  if (TREE_ADDRESSABLE (TREE_TYPE (decl))
+      || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
+    flags |= GOVD_SEEN;
+
+  n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
+  if (n != NULL)
+    {
+      /* We shouldn't be re-adding the decl with the same data
+        sharing class.  */
+      gcc_assert ((n->value & GOVD_DATA_SHARE_CLASS & flags) == 0);
+      /* The only combination of data sharing classes we should see is
+        FIRSTPRIVATE and LASTPRIVATE.  */
+      nflags = n->value | flags;
+      gcc_assert ((nflags & GOVD_DATA_SHARE_CLASS)
+                 == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE));
+      n->value = nflags;
+      return;
+    }
+
+  /* When adding a variable-sized variable, we have to handle all sorts
+     of additional bits of data: the pointer replacement variable, and 
+     the parameters of the type.  */
+  if (!TREE_CONSTANT (DECL_SIZE (decl)))
+    {
+      /* Add the pointer replacement variable as PRIVATE if the variable
+        replacement is private, else FIRSTPRIVATE since we'll need the
+        address of the original variable either for SHARED, or for the
+        copy into or out of the context.  */
+      if (!(flags & GOVD_LOCAL))
+       {
+         nflags = flags & GOVD_PRIVATE ? GOVD_PRIVATE : GOVD_FIRSTPRIVATE;
+         nflags |= flags & GOVD_SEEN;
+         t = DECL_VALUE_EXPR (decl);
+         gcc_assert (TREE_CODE (t) == INDIRECT_REF);
+         t = TREE_OPERAND (t, 0);
+         gcc_assert (DECL_P (t));
+         omp_add_variable (ctx, t, nflags);
+       }
+
+      /* Add all of the variable and type parameters (which should have
+        been gimplified to a formal temporary) as FIRSTPRIVATE.  */
+      omp_firstprivatize_variable (ctx, DECL_SIZE_UNIT (decl));
+      omp_firstprivatize_variable (ctx, DECL_SIZE (decl));
+      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
+
+      /* The variable-sized variable itself is never SHARED, only some form
+        of PRIVATE.  The sharing would take place via the pointer variable
+        which we remapped above.  */
+      if (flags & GOVD_SHARED)
+       flags = GOVD_PRIVATE | GOVD_DEBUG_PRIVATE
+               | (flags & (GOVD_SEEN | GOVD_EXPLICIT));
+
+      /* We're going to make use of the TYPE_SIZE_UNIT at least in the 
+        alloca statement we generate for the variable, so make sure it
+        is available.  This isn't automatically needed for the SHARED
+        case, since we won't be allocating local storage then.  */
+      else
+       omp_notice_variable (ctx, TYPE_SIZE_UNIT (TREE_TYPE (decl)), true);
+    }
+  else if (lang_hooks.decls.omp_privatize_by_reference (decl))
+    {
+      gcc_assert ((flags & GOVD_LOCAL) == 0);
+      omp_firstprivatize_type_sizes (ctx, TREE_TYPE (decl));
+
+      /* Similar to the direct variable sized case above, we'll need the
+        size of references being privatized.  */
+      if ((flags & GOVD_SHARED) == 0)
+       {
+         t = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl)));
+         if (!TREE_CONSTANT (t))
+           omp_notice_variable (ctx, t, true);
+       }
+    }
+
+  splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
+}
+
+/* Record the fact that DECL was used within the OpenMP context CTX.
+   IN_CODE is true when real code uses DECL, and false when we should
+   merely emit default(none) errors.  Return true if DECL is going to
+   be remapped and thus DECL shouldn't be gimplified into its
+   DECL_VALUE_EXPR (if any).  */
+
+static bool
+omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
+{
+  splay_tree_node n;
+  unsigned flags = in_code ? GOVD_SEEN : 0;
+  bool ret = false, shared;
+
+  if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
+    return false;
+
+  /* Threadprivate variables are predetermined.  */
+  if (is_global_var (decl))
+    {
+      if (DECL_THREAD_LOCAL_P (decl))
+       return false;
+
+      if (DECL_HAS_VALUE_EXPR_P (decl))
+       {
+         tree value = get_base_address (DECL_VALUE_EXPR (decl));
+
+         if (value && DECL_P (value) && DECL_THREAD_LOCAL_P (value))
+           return false;
+       }
+    }
+
+  n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
+  if (n == NULL)
+    {
+      enum omp_clause_default_kind default_kind, kind;
+
+      if (!ctx->is_parallel)
+       goto do_outer;
+
+      /* ??? Some compiler-generated variables (like SAVE_EXPRs) could be
+        remapped firstprivate instead of shared.  To some extent this is
+        addressed in omp_firstprivatize_type_sizes, but not effectively.  */
+      default_kind = ctx->default_kind;
+      kind = lang_hooks.decls.omp_predetermined_sharing (decl);
+      if (kind != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
+       default_kind = kind;
+
+      switch (default_kind)
+       {
+       case OMP_CLAUSE_DEFAULT_NONE:
+         error ("%qs not specified in enclosing parallel",
+                IDENTIFIER_POINTER (DECL_NAME (decl)));
+         error ("%Henclosing parallel", &ctx->location);
+         /* FALLTHRU */
+       case OMP_CLAUSE_DEFAULT_SHARED:
+         flags |= GOVD_SHARED;
+         break;
+       case OMP_CLAUSE_DEFAULT_PRIVATE:
+         flags |= GOVD_PRIVATE;
+         break;
+       default:
+         gcc_unreachable ();
+       }
+
+      omp_add_variable (ctx, decl, flags);
+
+      shared = (flags & GOVD_SHARED) != 0;
+      ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
+      goto do_outer;
+    }
+
+  shared = ((flags | n->value) & GOVD_SHARED) != 0;
+  ret = lang_hooks.decls.omp_disregard_value_expr (decl, shared);
+
+  /* If nothing changed, there's nothing left to do.  */
+  if ((n->value & flags) == flags)
+    return ret;
+  flags |= n->value;
+  n->value = flags;
+
+ do_outer:
+  /* If the variable is private in the current context, then we don't
+     need to propagate anything to an outer context.  */
+  if (flags & GOVD_PRIVATE)
+    return ret;
+  if (ctx->outer_context
+      && omp_notice_variable (ctx->outer_context, decl, in_code))
+    return true;
+  return ret;
+}
+
+/* Verify that DECL is private within CTX.  If there's specific information
+   to the contrary in the innermost scope, generate an error.  */
+
+static bool
+omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
+{
+  splay_tree_node n;
+
+  n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
+  if (n != NULL)
+    {
+      if (n->value & GOVD_SHARED)
+       {
+         if (ctx == gimplify_omp_ctxp)
+           error ("iteration variable %qs should be private",
+                  IDENTIFIER_POINTER (DECL_NAME (decl)));
+         n->value = GOVD_PRIVATE;
+       }
+      return true;
+    }
+
+  if (ctx->outer_context)
+    return omp_is_private (ctx->outer_context, decl);
+  else if (ctx->is_parallel)
+    return false;
+  else
+    return !is_global_var (decl);
+}
+
+/* Scan the OpenMP clauses in *LIST_P, installing mappings into a new
+   and previous omp contexts.  */
+
+static void
+gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel)
+{
+  struct gimplify_omp_ctx *ctx, *outer_ctx;
+  tree c;
+
+  ctx = new_omp_context (in_parallel);
+  outer_ctx = ctx->outer_context;
+
+  while ((c = *list_p) != NULL)
+    {
+      enum gimplify_status gs;
+      bool remove = false;
+      bool notice_outer = true;
+      unsigned int flags;
+      tree decl;
+
+      switch (TREE_CODE (c))
+       {
+       case OMP_CLAUSE_PRIVATE:
+         flags = GOVD_PRIVATE | GOVD_EXPLICIT;
+         notice_outer = false;
+         goto do_add;
+       case OMP_CLAUSE_SHARED:
+         flags = GOVD_SHARED | GOVD_EXPLICIT;
+         goto do_add;
+       case OMP_CLAUSE_FIRSTPRIVATE:
+         flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
+         goto do_add;
+       case OMP_CLAUSE_LASTPRIVATE:
+         flags = GOVD_LASTPRIVATE | GOVD_SEEN | GOVD_EXPLICIT;
+         goto do_add;
+       case OMP_CLAUSE_REDUCTION:
+         flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
+         goto do_add;
+
+       do_add:
+         decl = OMP_CLAUSE_DECL (c);
+         if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
+           {
+             remove = true;
+             break;
+           }
+         omp_add_variable (ctx, decl, flags);
+         if (TREE_CODE (c) == OMP_CLAUSE_REDUCTION
+             && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
+           {
+             omp_add_variable (ctx, OMP_CLAUSE_REDUCTION_PLACEHOLDER (c),
+                               GOVD_LOCAL);
+             gimplify_omp_ctxp = ctx;
+             push_gimplify_context ();
+             gimplify_stmt (&OMP_CLAUSE_REDUCTION_INIT (c));
+             pop_gimplify_context (OMP_CLAUSE_REDUCTION_INIT (c));
+             push_gimplify_context ();
+             gimplify_stmt (&OMP_CLAUSE_REDUCTION_MERGE (c));
+             pop_gimplify_context (OMP_CLAUSE_REDUCTION_MERGE (c));
+             gimplify_omp_ctxp = outer_ctx;
+           }
+         if (notice_outer)
+           goto do_notice;
+         break;
+
+       case OMP_CLAUSE_COPYIN:
+       case OMP_CLAUSE_COPYPRIVATE:
+         decl = OMP_CLAUSE_DECL (c);
+         if (decl == error_mark_node || TREE_TYPE (decl) == error_mark_node)
+           {
+             remove = true;
+             break;
+           }
+       do_notice:
+         if (outer_ctx)
+           omp_notice_variable (outer_ctx, decl, true);
+         break;
+
+       case OMP_CLAUSE_SCHEDULE:
+         if (gimplify_ctxp->combined_pre_p)
+           {
+             gcc_assert (gimplify_omp_ctxp == outer_ctx);
+             gs = gimplify_expr_in_ctx (&OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c),
+                                        gimplify_ctxp->combined_pre_p, NULL,
+                                        is_gimple_val, fb_rvalue,
+                                        gimplify_ctxp->combined_ctxp,
+                                        outer_ctx->outer_context);
+             if (gs == GS_ERROR)
+               remove = true;
+             break;
+           }
+         /* FALLTHRU */
+       case OMP_CLAUSE_IF:
+       case OMP_CLAUSE_NUM_THREADS:
+         gs = gimplify_expr (&TREE_OPERAND (c, 0), pre_p, NULL,
+                             is_gimple_val, fb_rvalue);
+         if (gs == GS_ERROR)
+           remove = true;
+         break;
+
+       case OMP_CLAUSE_NOWAIT:
+       case OMP_CLAUSE_ORDERED:
+         break;
+
+       case OMP_CLAUSE_DEFAULT:
+         ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
+         break;
+
+       default:
+         gcc_unreachable ();
+       }
+
+      if (remove)
+       *list_p = OMP_CLAUSE_CHAIN (c);
+      else
+       list_p = &OMP_CLAUSE_CHAIN (c);
+    }
+
+  gimplify_omp_ctxp = ctx;
+}
+
+/* For all variables that were not actually used within the context,
+   remove PRIVATE, SHARED, and FIRSTPRIVATE clauses.  */
+
+static int
+gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
+{
+  tree *list_p = (tree *) data;
+  tree decl = (tree) n->key;
+  unsigned flags = n->value;
+  enum tree_code code;
+  tree clause;
+  bool private_debug;
+
+  if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
+    return 0;
+  if ((flags & GOVD_SEEN) == 0)
+    return 0;
+  if (flags & GOVD_DEBUG_PRIVATE)
+    {
+      gcc_assert ((flags & GOVD_DATA_SHARE_CLASS) == GOVD_PRIVATE);
+      private_debug = true;
+    }
+  else
+    private_debug
+      = lang_hooks.decls.omp_private_debug_clause (decl,
+                                                  !!(flags & GOVD_SHARED));
+  if (private_debug)
+    code = OMP_CLAUSE_PRIVATE;
+  else if (flags & GOVD_SHARED)
+    {
+      if (is_global_var (decl))
+       return 0;
+      code = OMP_CLAUSE_SHARED;
+    }
+  else if (flags & GOVD_PRIVATE)
+    code = OMP_CLAUSE_PRIVATE;
+  else if (flags & GOVD_FIRSTPRIVATE)
+    code = OMP_CLAUSE_FIRSTPRIVATE;
+  else
+    gcc_unreachable ();
+
+  clause = build1 (code, void_type_node, decl);
+  OMP_CLAUSE_CHAIN (clause) = *list_p;
+  if (private_debug)
+    OMP_CLAUSE_PRIVATE_DEBUG (clause) = 1;
+  *list_p = clause;
+
+  return 0;
+}
+
+static void
+gimplify_adjust_omp_clauses (tree *list_p)
+{
+  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
+  tree c, decl;
+
+  while ((c = *list_p) != NULL)
+    {
+      splay_tree_node n;
+      bool remove = false;
+
+      switch (TREE_CODE (c))
+       {
+       case OMP_CLAUSE_PRIVATE:
+       case OMP_CLAUSE_SHARED:
+       case OMP_CLAUSE_FIRSTPRIVATE:
+         decl = OMP_CLAUSE_DECL (c);
+         n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
+         remove = !(n->value & GOVD_SEEN);
+         if (! remove)
+           {
+             bool shared = TREE_CODE (c) == OMP_CLAUSE_SHARED;
+             if ((n->value & GOVD_DEBUG_PRIVATE)
+                 || lang_hooks.decls.omp_private_debug_clause (decl, shared))
+               {
+                 gcc_assert ((n->value & GOVD_DEBUG_PRIVATE) == 0
+                             || ((n->value & GOVD_DATA_SHARE_CLASS)
+                                 == GOVD_PRIVATE));
+                 TREE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
+                 OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
+               }
+           }
+         break;
+
+       case OMP_CLAUSE_LASTPRIVATE:
+         /* Make sure OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE is set to
+            accurately reflect the presence of a FIRSTPRIVATE clause.  */
+         decl = OMP_CLAUSE_DECL (c);
+         n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
+         OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c)
+           = (n->value & GOVD_FIRSTPRIVATE) != 0;
+         break;
+         
+       case OMP_CLAUSE_REDUCTION:
+       case OMP_CLAUSE_COPYIN:
+       case OMP_CLAUSE_COPYPRIVATE:
+       case OMP_CLAUSE_IF:
+       case OMP_CLAUSE_NUM_THREADS:
+       case OMP_CLAUSE_SCHEDULE:
+       case OMP_CLAUSE_NOWAIT:
+       case OMP_CLAUSE_ORDERED:
+       case OMP_CLAUSE_DEFAULT:
+         break;
+
+       default:
+         gcc_unreachable ();
+       }
+
+      if (remove)
+       *list_p = OMP_CLAUSE_CHAIN (c);
+      else
+       list_p = &OMP_CLAUSE_CHAIN (c);
+    }
+
+  /* Add in any implicit data sharing.  */
+  splay_tree_foreach (ctx->variables, gimplify_adjust_omp_clauses_1, list_p);
+  
+  gimplify_omp_ctxp = ctx->outer_context;
+  delete_omp_context (ctx);
+}
+
+/* Gimplify the contents of an OMP_PARALLEL statement.  This involves
+   gimplification of the body, as well as scanning the body for used
+   variables.  We need to do this scan now, because variable-sized
+   decls will be decomposed during gimplification.  */
+
+static enum gimplify_status
+gimplify_omp_parallel (tree *expr_p, tree *pre_p)
+{
+  tree expr = *expr_p;
+
+  gimplify_scan_omp_clauses (&OMP_PARALLEL_CLAUSES (expr), pre_p, true);
+
+  push_gimplify_context ();
+
+  if (determine_parallel_type (expr) == IS_COMBINED_PARALLEL)
+    {
+      gimplify_ctxp->combined_pre_p = pre_p;
+      gimplify_ctxp->combined_ctxp = gimplify_ctxp->prev_context;
+    }
+
+  gimplify_stmt (&OMP_PARALLEL_BODY (expr));
+  pop_gimplify_context (OMP_PARALLEL_BODY (expr));
+
+  gimplify_ctxp->combined_pre_p = NULL;
+  gimplify_ctxp->combined_ctxp = NULL;
+
+  gimplify_adjust_omp_clauses (&OMP_PARALLEL_CLAUSES (expr));
+
+  return GS_ALL_DONE;
+}
+
+/* Gimplify the gross structure of an OMP_FOR statement.  */
+
+static enum gimplify_status
+gimplify_omp_for (tree *expr_p, tree *pre_p)
+{
+  tree for_stmt, decl, t;
+  enum gimplify_status ret = 0;
+  struct gimplify_omp_ctx *outer_combined_omp_ctxp = NULL;
+
+  for_stmt = *expr_p;
+
+  if (gimplify_ctxp->combined_pre_p)
+    outer_combined_omp_ctxp = gimplify_omp_ctxp->outer_context;
+
+  gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, false);
+
+  t = OMP_FOR_INIT (for_stmt);
+  gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
+  decl = TREE_OPERAND (t, 0);
+  gcc_assert (DECL_P (decl));
+  gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (decl)));
+  gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (decl)));
+
+  /* Make sure the iteration variable is private.  */
+  if (omp_is_private (gimplify_omp_ctxp, decl))
+    omp_notice_variable (gimplify_omp_ctxp, decl, true);
+  else
+    omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
+
+  /* Gimplify inside our parent's context if this is part of a combined
+     parallel+workshare directive.  */
+  if (gimplify_ctxp->combined_pre_p)
+    ret |= gimplify_expr_in_ctx (&TREE_OPERAND (t, 1),
+                                gimplify_ctxp->combined_pre_p, NULL,
+                                is_gimple_val, fb_rvalue,
+                                gimplify_ctxp->combined_ctxp,
+                                outer_combined_omp_ctxp);
+  else
+    ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
+                         NULL, is_gimple_val, fb_rvalue);
+
+  t = OMP_FOR_COND (for_stmt);
+  gcc_assert (COMPARISON_CLASS_P (t));
+  gcc_assert (TREE_OPERAND (t, 0) == decl);
+
+  /* Gimplify inside our parent's context if this is part of a combined
+     parallel+workshare directive.  */
+  if (gimplify_ctxp->combined_pre_p)
+    ret |= gimplify_expr_in_ctx (&TREE_OPERAND (t, 1),
+                                gimplify_ctxp->combined_pre_p, NULL,
+                                is_gimple_val, fb_rvalue,
+                                gimplify_ctxp->combined_ctxp,
+                                outer_combined_omp_ctxp);
+  else
+    ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
+                         NULL, is_gimple_val, fb_rvalue);
+
+  t = OMP_FOR_INCR (for_stmt);
+  switch (TREE_CODE (t))
+    {
+    case PREINCREMENT_EXPR:
+    case POSTINCREMENT_EXPR:
+      t = build_int_cst (TREE_TYPE (decl), 1);
+      goto build_modify;
+    case PREDECREMENT_EXPR:
+    case POSTDECREMENT_EXPR:
+      t = build_int_cst (TREE_TYPE (decl), -1);
+      goto build_modify;
+    build_modify:
+      t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
+      t = build2 (MODIFY_EXPR, void_type_node, decl, t);
+      OMP_FOR_INCR (for_stmt) = t;
+      break;
+      
+    case MODIFY_EXPR:
+      gcc_assert (TREE_OPERAND (t, 0) == decl);
+      t = TREE_OPERAND (t, 1);
+      switch (TREE_CODE (t))
+       {
+       case PLUS_EXPR:
+         if (TREE_OPERAND (t, 1) == decl)
+           {
+             TREE_OPERAND (t, 1) = TREE_OPERAND (t, 0);
+             TREE_OPERAND (t, 0) = decl;
+             break;
+           }
+       case MINUS_EXPR:
+         gcc_assert (TREE_OPERAND (t, 0) == decl);
+         break;
+       default:
+         gcc_unreachable ();
+       }
+
+      /* Gimplify inside our parent's context if this is part of a
+        combined parallel+workshare directive.  */
+      if (gimplify_ctxp->combined_pre_p)
+       ret |= gimplify_expr_in_ctx (&TREE_OPERAND (t, 1),
+                                    gimplify_ctxp->combined_pre_p, NULL,
+                                    is_gimple_val, fb_rvalue,
+                                    gimplify_ctxp->combined_ctxp,
+                                    outer_combined_omp_ctxp);
+      else
+       ret |= gimplify_expr (&TREE_OPERAND (t, 1),
+                             &OMP_FOR_PRE_BODY (for_stmt), NULL,
+                             is_gimple_val, fb_rvalue);
+      break;
+
+    default:
+      gcc_unreachable ();
+    }
+
+  gimplify_to_stmt_list (&OMP_FOR_BODY (for_stmt));
+  gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
+
+  return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR;
+}
+
+/* Gimplify the gross structure of other OpenMP worksharing constructs.
+   In particular, OMP_SECTIONS and OMP_SINGLE.  */
+
+static enum gimplify_status
+gimplify_omp_workshare (tree *expr_p, tree *pre_p)
+{
+  tree stmt = *expr_p;
+
+  gimplify_scan_omp_clauses (&OMP_CLAUSES (stmt), pre_p, false);
+  gimplify_to_stmt_list (&OMP_BODY (stmt));
+  gimplify_adjust_omp_clauses (&OMP_CLAUSES (stmt));
+
+  return GS_ALL_DONE;
+}
+
+/* A subroutine of gimplify_omp_atomic.  The front end is supposed to have
+   stabilized the lhs of the atomic operation as *ADDR.  Return true if 
+   EXPR is this stabilized form.  */
+
+static bool
+goa_lhs_expr_p (tree expr, tree addr)
+{
+  /* Also include casts to other type variants.  The C front end is fond
+     of adding these for e.g. volatile variables.  This is like 
+     STRIP_TYPE_NOPS but includes the main variant lookup.  */
+  while ((TREE_CODE (expr) == NOP_EXPR
+          || TREE_CODE (expr) == CONVERT_EXPR
+          || TREE_CODE (expr) == NON_LVALUE_EXPR)
+         && TREE_OPERAND (expr, 0) != error_mark_node
+         && (TYPE_MAIN_VARIANT (TREE_TYPE (expr))
+             == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (expr, 0)))))
+    expr = TREE_OPERAND (expr, 0);
+
+  if (TREE_CODE (expr) == INDIRECT_REF && TREE_OPERAND (expr, 0) == addr)
+    return true;
+  if (TREE_CODE (addr) == ADDR_EXPR && expr == TREE_OPERAND (addr, 0))
+    return true;
+  return false;
+}
+
+/* A subroutine of gimplify_omp_atomic.  Attempt to implement the atomic
+   operation as a __sync_fetch_and_op builtin.  INDEX is log2 of the
+   size of the data type, and thus usable to find the index of the builtin
+   decl.  Returns GS_UNHANDLED if the expression is not of the proper form.  */
+
+static enum gimplify_status
+gimplify_omp_atomic_fetch_op (tree *expr_p, tree addr, tree rhs, int index)
+{
+  enum built_in_function base;
+  tree decl, args, itype;
+  enum insn_code *optab;
+
+  /* Check for one of the supported fetch-op operations.  */
+  switch (TREE_CODE (rhs))
+    {
+    case PLUS_EXPR:
+      base = BUILT_IN_FETCH_AND_ADD_N;
+      optab = sync_add_optab;
+      break;
+    case MINUS_EXPR:
+      base = BUILT_IN_FETCH_AND_SUB_N;
+      optab = sync_add_optab;
+      break;
+    case BIT_AND_EXPR:
+      base = BUILT_IN_FETCH_AND_AND_N;
+      optab = sync_and_optab;
+      break;
+    case BIT_IOR_EXPR:
+      base = BUILT_IN_FETCH_AND_OR_N;
+      optab = sync_ior_optab;
+      break;
+    case BIT_XOR_EXPR:
+      base = BUILT_IN_FETCH_AND_XOR_N;
+      optab = sync_xor_optab;
+      break;
+    default:
+      return GS_UNHANDLED;
+    }
+
+  /* Make sure the expression is of the proper form.  */
+  if (goa_lhs_expr_p (TREE_OPERAND (rhs, 0), addr))
+    rhs = TREE_OPERAND (rhs, 1);
+  else if (commutative_tree_code (TREE_CODE (rhs))
+          && goa_lhs_expr_p (TREE_OPERAND (rhs, 1), addr))
+    rhs = TREE_OPERAND (rhs, 0);
+  else
+    return GS_UNHANDLED;
+
+  decl = built_in_decls[base + index + 1];
+  itype = TREE_TYPE (TREE_TYPE (decl));
+
+  if (optab[TYPE_MODE (itype)] == CODE_FOR_nothing)
+    return GS_UNHANDLED;
+
+  args = tree_cons (NULL, fold_convert (itype, rhs), NULL);
+  args = tree_cons (NULL, addr, args);
+  *expr_p = build_function_call_expr (decl, args);
+  return GS_OK;
+}
+
+/* A subroutine of gimplify_omp_atomic_pipeline.  Walk *EXPR_P and replace
+   appearences of *LHS_ADDR with LHS_VAR.  If an expression does not involve
+   the lhs, evaluate it into a temporary.  Return 1 if the lhs appeared as
+   a subexpression, 0 if it did not, or -1 if an error was encountered.  */
+
+static int
+goa_stabilize_expr (tree *expr_p, tree *pre_p, tree lhs_addr, tree lhs_var)
+{
+  tree expr = *expr_p;
+  int saw_lhs;
+
+  if (goa_lhs_expr_p (expr, lhs_addr))
+    {
+      *expr_p = lhs_var;
+      return 1;
+    }
+  if (is_gimple_val (expr))
+    return 0;
+  saw_lhs = 0;
+  switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+    {
+    case tcc_binary:
+      saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 1), pre_p,
+                                    lhs_addr, lhs_var);
+    case tcc_unary:
+      saw_lhs |= goa_stabilize_expr (&TREE_OPERAND (expr, 0), pre_p,
+                                    lhs_addr, lhs_var);
+      break;
+    default:
+      break;
+    }
+
+  if (saw_lhs == 0)
+    {
+      enum gimplify_status gs;
+      gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
+      if (gs != GS_ALL_DONE)
+       saw_lhs = -1;
+    }
+
+  return saw_lhs;
+}
+
+/* A subroutine of gimplify_omp_atomic.  Implement the atomic operation as:
+
+       oldval = *addr;
+      repeat:
+       newval = rhs;   // with oldval replacing *addr in rhs
+       oldval = __sync_val_compare_and_swap (addr, oldval, newval);
+       if (oldval != newval)
+         goto repeat;
+
+   INDEX is log2 of the size of the data type, and thus usable to find the
+   index of the builtin decl.  */
+
+static enum gimplify_status
+gimplify_omp_atomic_pipeline (tree *expr_p, tree *pre_p, tree addr,
+                             tree rhs, int index)
+{
+  tree oldval, oldival, oldival2, newval, newival, label;
+  tree type, itype, cmpxchg, args, x, iaddr;
+
+  cmpxchg = built_in_decls[BUILT_IN_VAL_COMPARE_AND_SWAP_N + index + 1];
+  type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
+  itype = TREE_TYPE (TREE_TYPE (cmpxchg));
+
+  if (sync_compare_and_swap[TYPE_MODE (itype)] == CODE_FOR_nothing)
+    return GS_UNHANDLED;
+
+  oldval = create_tmp_var (type, NULL);
+  newval = create_tmp_var (type, NULL);
+
+  /* Precompute as much of RHS as possible.  In the same walk, replace
+     occurrences of the lhs value with our temporary.  */
+  if (goa_stabilize_expr (&rhs, pre_p, addr, oldval) < 0)
+    return GS_ERROR;
+
+  x = build_fold_indirect_ref (addr);
+  x = build2 (MODIFY_EXPR, void_type_node, oldval, x);
+  gimplify_and_add (x, pre_p);
+
+  /* For floating-point values, we'll need to view-convert them to integers
+     so that we can perform the atomic compare and swap.  Simplify the 
+     following code by always setting up the "i"ntegral variables.  */
+  if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
+    {
+      oldival = oldval;
+      newival = newval;
+      iaddr = addr;
+    }
+  else
+    {
+      oldival = create_tmp_var (itype, NULL);
+      newival = create_tmp_var (itype, NULL);
+
+      x = build1 (VIEW_CONVERT_EXPR, itype, oldval);
+      x = build2 (MODIFY_EXPR, void_type_node, oldival, x);
+      gimplify_and_add (x, pre_p);
+      iaddr = fold_convert (build_pointer_type (itype), addr);
+    }
+
+  oldival2 = create_tmp_var (itype, NULL);
+
+  label = create_artificial_label ();
+  x = build1 (LABEL_EXPR, void_type_node, label);
+  gimplify_and_add (x, pre_p);
+
+  x = build2 (MODIFY_EXPR, void_type_node, newval, rhs);
+  gimplify_and_add (x, pre_p);
+
+  if (newval != newival)
+    {
+      x = build1 (VIEW_CONVERT_EXPR, itype, newval);
+      x = build2 (MODIFY_EXPR, void_type_node, newival, x);
+      gimplify_and_add (x, pre_p);
+    }
+
+  x = build2 (MODIFY_EXPR, void_type_node, oldival2, oldival);
+  gimplify_and_add (x, pre_p);
+
+  args = tree_cons (NULL, fold_convert (itype, newival), NULL);
+  args = tree_cons (NULL, fold_convert (itype, oldival), args);
+  args = tree_cons (NULL, iaddr, args);
+  x = build_function_call_expr (cmpxchg, args);
+  if (oldval == oldival)
+    x = fold_convert (type, x);
+  x = build2 (MODIFY_EXPR, void_type_node, oldival, x);
+  gimplify_and_add (x, pre_p);
+
+  /* For floating point, be prepared for the loop backedge.  */
+  if (oldval != oldival)
+    {
+      x = build1 (VIEW_CONVERT_EXPR, type, oldival);
+      x = build2 (MODIFY_EXPR, void_type_node, oldval, x);
+      gimplify_and_add (x, pre_p);
+    }
+
+  /* Note that we always perform the comparison as an integer, even for
+     floating point.  This allows the atomic operation to properly 
+     succeed even with NaNs and -0.0.  */
+  x = build3 (COND_EXPR, void_type_node,
+             build2 (NE_EXPR, boolean_type_node, oldival, oldival2),
+             build1 (GOTO_EXPR, void_type_node, label), NULL);
+  gimplify_and_add (x, pre_p);
+
+  *expr_p = NULL;
+  return GS_ALL_DONE;
+}
+
+/* A subroutine of gimplify_omp_atomic.  Implement the atomic operation as:
+
+       GOMP_atomic_start ();
+       *addr = rhs;
+       GOMP_atomic_end ();
+
+   The result is not globally atomic, but works so long as all parallel
+   references are within #pragma omp atomic directives.  According to
+   responses received from omp@openmp.org, appears to be within spec.
+   Which makes sense, since that's how several other compilers handle
+   this situation as well.  */
+
+static enum gimplify_status
+gimplify_omp_atomic_mutex (tree *expr_p, tree *pre_p, tree addr, tree rhs)
+{
+  tree t;
+
+  t = built_in_decls[BUILT_IN_GOMP_ATOMIC_START];
+  t = build_function_call_expr (t, NULL);
+  gimplify_and_add (t, pre_p);
+
+  t = build_fold_indirect_ref (addr);
+  t = build2 (MODIFY_EXPR, void_type_node, t, rhs);
+  gimplify_and_add (t, pre_p);
+  
+  t = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
+  t = build_function_call_expr (t, NULL);
+  gimplify_and_add (t, pre_p);
+
+  *expr_p = NULL;
+  return GS_ALL_DONE;
+}
+
+/* Gimplify an OMP_ATOMIC statement.  */
+
+static enum gimplify_status
+gimplify_omp_atomic (tree *expr_p, tree *pre_p)
+{
+  tree addr = TREE_OPERAND (*expr_p, 0);
+  tree rhs = TREE_OPERAND (*expr_p, 1);
+  tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
+  HOST_WIDE_INT index;
+
+  /* Make sure the type is one of the supported sizes.  */
+  index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
+  index = exact_log2 (index);
+  if (index >= 0 && index <= 4)
+    {
+      enum gimplify_status gs;
+      unsigned int align;
+
+      if (DECL_P (TREE_OPERAND (addr, 0)))
+       align = DECL_ALIGN_UNIT (TREE_OPERAND (addr, 0));
+      else if (TREE_CODE (TREE_OPERAND (addr, 0)) == COMPONENT_REF
+              && TREE_CODE (TREE_OPERAND (TREE_OPERAND (addr, 0), 1))
+                 == FIELD_DECL)
+       align = DECL_ALIGN_UNIT (TREE_OPERAND (TREE_OPERAND (addr, 0), 1));
+      else
+       align = TYPE_ALIGN_UNIT (type);
+
+      /* __sync builtins require strict data alignment.  */
+      if (exact_log2 (align) >= index)
+       {
+         /* When possible, use specialized atomic update functions.  */
+         if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
+           {
+             gs = gimplify_omp_atomic_fetch_op (expr_p, addr, rhs, index);
+             if (gs != GS_UNHANDLED)
+               return gs;
+           }
+
+         /* If we don't have specialized __sync builtins, try and implement
+            as a compare and swap loop.  */
+         gs = gimplify_omp_atomic_pipeline (expr_p, pre_p, addr, rhs, index);
+         if (gs != GS_UNHANDLED)
+           return gs;
+       }
+    }
+
+  /* The ultimate fallback is wrapping the operation in a mutex.  */
+  return gimplify_omp_atomic_mutex (expr_p, pre_p, addr, rhs);
+}
 
 /*  Gimplifies the expression tree pointed to by EXPR_P.  Return 0 if
     gimplification failed.
@@ -4441,6 +5598,30 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
          ret = GS_ALL_DONE;
          break;
 
+       case OMP_PARALLEL:
+         ret = gimplify_omp_parallel (expr_p, pre_p);
+         break;
+
+       case OMP_FOR:
+         ret = gimplify_omp_for (expr_p, pre_p);
+         break;
+
+       case OMP_SECTIONS:
+       case OMP_SINGLE:
+         ret = gimplify_omp_workshare (expr_p, pre_p);
+         break;
+
+       case OMP_SECTION:
+       case OMP_MASTER:
+       case OMP_ORDERED:
+       case OMP_CRITICAL:
+         gimplify_to_stmt_list (&OMP_BODY (*expr_p));
+         break;
+
+       case OMP_ATOMIC:
+         ret = gimplify_omp_atomic (expr_p, pre_p);
+         break;
+
        default:
          switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
            {
@@ -4880,6 +6061,8 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
   tree body, parm_stmts;
 
   timevar_push (TV_TREE_GIMPLIFY);
+
+  gcc_assert (gimplify_ctxp == NULL);
   push_gimplify_context ();
 
   /* Unshare most shared trees in the body and in that of any nested functions.
@@ -4933,6 +6116,7 @@ gimplify_body (tree *body_p, tree fndecl, bool do_parms)
   *body_p = body;
 
   pop_gimplify_context (body);
+  gcc_assert (gimplify_ctxp == NULL);
 
 #ifdef ENABLE_CHECKING
   walk_tree (body_p, check_pointer_types_r, NULL, NULL);
index 2ebd071..a5028de 100644 (file)
@@ -186,6 +186,12 @@ hook_bool_tree_tree_false (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
 }
 
 bool
+hook_bool_tree_bool_false (tree a ATTRIBUTE_UNUSED, bool b ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
+bool
 hook_bool_rtx_false (rtx a ATTRIBUTE_UNUSED)
 {
   return false;
@@ -256,6 +262,12 @@ hook_tree_tree_tree_bool_null (tree t0 ATTRIBUTE_UNUSED, tree t1 ATTRIBUTE_UNUSE
   return NULL;
 }
 
+tree
+hook_tree_tree_tree_null (tree t0 ATTRIBUTE_UNUSED, tree t1 ATTRIBUTE_UNUSED)
+{
+  return NULL;
+}
+
 /* Generic hook that takes a rtx and returns a NULL string.  */
 const char *
 hook_constcharptr_rtx_null (rtx r ATTRIBUTE_UNUSED)
index 1ca909a..eab42ab 100644 (file)
@@ -40,6 +40,8 @@ extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *);
 extern bool hook_bool_rtx_int_int_intp_false (rtx, int, int, int *);
 extern bool hook_bool_constcharptr_size_t_false (const char *, size_t);
 extern bool hook_bool_size_t_constcharptr_int_true (size_t, const char *, int);
+extern bool hook_bool_tree_tree_false (tree, tree);
+extern bool hook_bool_tree_bool_false (tree, bool);
 
 extern void hook_void_void (void);
 extern void hook_void_constcharptr (const char *);
@@ -53,19 +55,20 @@ extern int hook_int_rtx_0 (rtx);
 extern int hook_int_size_t_constcharptr_int_0 (size_t, const char *, int);
 extern int hook_int_void_no_regs (void);
 
+extern tree hook_tree_tree_tree_null (tree, tree);
+extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree);
+extern tree hook_tree_tree_tree_bool_null (tree, tree, bool);
+
 extern unsigned hook_uint_uint_constcharptrptr_0 (unsigned, const char **);
 
 extern bool default_can_output_mi_thunk_no_vcall (tree, HOST_WIDE_INT,
                                           HOST_WIDE_INT, tree);
 
-extern bool hook_bool_tree_tree_false (tree, tree);
-
 extern rtx hook_rtx_rtx_identity (rtx);
 extern rtx hook_rtx_rtx_null (rtx);
 extern rtx hook_rtx_tree_int_null (tree, int);
-extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree);
+
 extern const char *hook_constcharptr_tree_null (tree);
-extern tree hook_tree_tree_tree_bool_null (tree, tree, bool);
 extern const char *hook_constcharptr_rtx_null (rtx);
 extern const char *hook_constcharptr_tree_tree_null (tree, tree);
 extern const char *hook_constcharptr_int_tree_null (int, tree);
index a17927a..168220e 100644 (file)
@@ -88,6 +88,11 @@ extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
 
 /* Declarations for tree gimplification hooks.  */
 extern int lhd_gimplify_expr (tree *, tree *, tree *);
+extern enum omp_clause_default_kind lhd_omp_predetermined_sharing (tree);
+extern tree lhd_omp_assignment (tree, tree, tree);
+struct gimplify_omp_ctx;
+extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
+                                              tree);
 
 #define LANG_HOOKS_NAME                        "GNU unknown"
 #define LANG_HOOKS_IDENTIFIER_SIZE     sizeof (struct lang_identifier)
@@ -213,6 +218,8 @@ extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
 #define LANG_HOOKS_TYPE_MAX_SIZE       lhd_return_null_tree
+#define LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES \
+  lhd_omp_firstprivatize_type_sizes
 #define LANG_HOOKS_HASH_TYPES          true
 
 #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
@@ -226,6 +233,7 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
   LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \
   LANG_HOOKS_TYPE_MAX_SIZE, \
+  LANG_HOOKS_OMP_FIRSTPRIVATIZE_TYPE_SIZES, \
   LANG_HOOKS_HASH_TYPES \
 }
 
@@ -239,6 +247,14 @@ extern tree lhd_make_node (enum tree_code);
 #define LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE NULL
 #define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall
 #define LANG_HOOKS_COMDAT_GROUP lhd_comdat_group
+#define LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE hook_bool_tree_false
+#define LANG_HOOKS_OMP_PREDETERMINED_SHARING lhd_omp_predetermined_sharing
+#define LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR hook_bool_tree_bool_false
+#define LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE hook_bool_tree_bool_false
+#define LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR hook_tree_tree_tree_null
+#define LANG_HOOKS_OMP_CLAUSE_COPY_CTOR lhd_omp_assignment
+#define LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP lhd_omp_assignment
+#define LANG_HOOKS_OMP_CLAUSE_DTOR hook_tree_tree_tree_null
 
 #define LANG_HOOKS_DECLS { \
   LANG_HOOKS_GLOBAL_BINDINGS_P, \
@@ -249,7 +265,15 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_WRITE_GLOBALS, \
   LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE, \
   LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
-  LANG_HOOKS_COMDAT_GROUP \
+  LANG_HOOKS_COMDAT_GROUP, \
+  LANG_HOOKS_OMP_PRIVATIZE_BY_REFERENCE, \
+  LANG_HOOKS_OMP_PREDETERMINED_SHARING, \
+  LANG_HOOKS_OMP_DISREGARD_VALUE_EXPR, \
+  LANG_HOOKS_OMP_PRIVATE_DEBUG_CLAUSE, \
+  LANG_HOOKS_OMP_CLAUSE_DEFAULT_CTOR, \
+  LANG_HOOKS_OMP_CLAUSE_COPY_CTOR, \
+  LANG_HOOKS_OMP_CLAUSE_ASSIGN_OP, \
+  LANG_HOOKS_OMP_CLAUSE_DTOR \
 }
 
 /* The whole thing.  The structure is defined in langhooks.h.  */
index d7ed750..69be1f5 100644 (file)
@@ -550,3 +550,31 @@ lhd_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
 {
   return expr;
 }
+
+/* Return sharing kind if OpenMP sharing attribute of DECL is
+   predetermined, OMP_CLAUSE_DEFAULT_UNSPECIFIED otherwise.  */
+
+enum omp_clause_default_kind
+lhd_omp_predetermined_sharing (tree decl ATTRIBUTE_UNUSED)
+{
+  if (DECL_ARTIFICIAL (decl))
+    return OMP_CLAUSE_DEFAULT_SHARED;
+  return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
+}
+
+/* Generate code to copy SRC to DST.  */
+
+tree
+lhd_omp_assignment (tree clause ATTRIBUTE_UNUSED, tree dst, tree src)
+{
+  return build2 (MODIFY_EXPR, void_type_node, dst, src);
+}
+
+/* Register language specific type size variables as potentially OpenMP
+   firstprivate variables.  */
+
+void
+lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *c ATTRIBUTE_UNUSED,
+                                  tree t ATTRIBUTE_UNUSED)
+{
+}
index 3d97c93..eb6aaaf 100644 (file)
@@ -25,6 +25,8 @@ Boston, MA 02110-1301, USA.  */
 
 struct diagnostic_context;
 
+struct gimplify_omp_ctx;
+
 /* A print hook for print_tree ().  */
 typedef void (*lang_print_tree_hook) (FILE *, tree, int indent);
 
@@ -142,6 +144,10 @@ struct lang_hooks_for_types
      for a type.  */
   tree (*max_size) (tree);
 
+  /* Register language specific type size variables as potentially OpenMP
+     firstprivate variables.  */
+  void (*omp_firstprivatize_type_sizes) (struct gimplify_omp_ctx *, tree);
+
   /* Nonzero if types that are identical are to be hashed so that only
      one copy is kept.  If a language requires unique types for each
      user-specified type, such as Ada, this should be set to TRUE.  */
@@ -192,6 +198,38 @@ struct lang_hooks_for_decls
      value will be the string already stored in an
      IDENTIFIER_NODE.)  */
   const char * (*comdat_group) (tree);
+
+  /* True if OpenMP should privatize what this DECL points to rather
+     than the DECL itself.  */
+  bool (*omp_privatize_by_reference) (tree);
+
+  /* Return sharing kind if OpenMP sharing attribute of DECL is
+     predetermined, OMP_CLAUSE_DEFAULT_UNSPECIFIED otherwise.  */
+  enum omp_clause_default_kind (*omp_predetermined_sharing) (tree);
+
+  /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
+     disregarded in OpenMP construct, because it is going to be
+     remapped during OpenMP lowering.  SHARED is true if DECL
+     is going to be shared, false if it is going to be privatized.  */
+  bool (*omp_disregard_value_expr) (tree, bool);
+
+  /* Return true if DECL that is shared iff SHARED is true should
+     be put into OMP_CLAUSE_PRIVATE_DEBUG.  */
+  bool (*omp_private_debug_clause) (tree, bool);
+
+  /* Build and return code for a default constructor for DECL in
+     response to CLAUSE.  Return NULL if nothing to be done.  */
+  tree (*omp_clause_default_ctor) (tree clause, tree decl);
+
+  /* Build and return code for a copy constructor from SRC to DST.  */
+  tree (*omp_clause_copy_ctor) (tree clause, tree dst, tree src);
+
+  /* Similarly, except use an assignment operator instead.  */
+  tree (*omp_clause_assign_op) (tree clause, tree dst, tree src);
+
+  /* Build and return code destructing DECL.  Return NULL if nothing
+     to be done.  */
+  tree (*omp_clause_dtor) (tree clause, tree decl);
 };
 
 /* Language-specific hooks.  See langhooks-def.h for defaults.  */
diff --git a/gcc/omp-builtins.def b/gcc/omp-builtins.def
new file mode 100644 (file)
index 0000000..596beae
--- /dev/null
@@ -0,0 +1,152 @@
+/* This file contains the definitions and documentation for the
+   OpenMP builtins used in the GNU compiler.
+   Copyright (C) 2005 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 2, 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 COPYING.  If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.  */
+
+/* Before including this file, you should define a macro:
+
+     DEF_GOMP_BUILTIN (ENUM, NAME, TYPE, ATTRS)
+
+   See builtins.def for details.  */
+
+DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_THREAD_NUM, "omp_get_thread_num",
+                 BT_FN_INT, ATTR_CONST_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_OMP_GET_NUM_THREADS, "omp_get_num_threads",
+                 BT_FN_INT, ATTR_CONST_NOTHROW_LIST)
+
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ATOMIC_START, "GOMP_atomic_start",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ATOMIC_END, "GOMP_atomic_end",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_BARRIER, "GOMP_barrier",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_START, "GOMP_critical_start",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_END, "GOMP_critical_end",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_NAME_START,
+                 "GOMP_critical_name_start",
+                 BT_FN_VOID_PTRPTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_CRITICAL_NAME_END,
+                 "GOMP_critical_name_end",
+                 BT_FN_VOID_PTRPTR, ATTR_NOTHROW_LIST)
+/* NOTE: Do not change the order of BUILT_IN_GOMP_LOOP_*_START.  They
+   are used in index arithmetic with enum omp_clause_schedule_kind
+   in omp-low.c.  */
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_STATIC_START,
+                 "GOMP_loop_static_start",
+                 BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_DYNAMIC_START,
+                 "GOMP_loop_dynamic_start",
+                 BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_GUIDED_START,
+                 "GOMP_loop_guided_start",
+                 BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_RUNTIME_START,
+                 "GOMP_loop_runtime_start",
+                 BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_STATIC_START,
+                 "GOMP_loop_ordered_static_start",
+                 BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_START,
+                 "GOMP_loop_ordered_dynamic_start",
+                 BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_START,
+                 "GOMP_loop_ordered_guided_start",
+                 BT_FN_BOOL_LONG_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_START,
+                 "GOMP_loop_ordered_runtime_start",
+                 BT_FN_BOOL_LONG_LONG_LONG_LONGPTR_LONGPTR,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_STATIC_NEXT, "GOMP_loop_static_next",
+                 BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_DYNAMIC_NEXT, "GOMP_loop_dynamic_next",
+                 BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_GUIDED_NEXT, "GOMP_loop_guided_next",
+                 BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_RUNTIME_NEXT, "GOMP_loop_runtime_next",
+                 BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_STATIC_NEXT,
+                 "GOMP_loop_ordered_static_next",
+                 BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_DYNAMIC_NEXT,
+                 "GOMP_loop_ordered_dynamic_next",
+                 BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_GUIDED_NEXT,
+                 "GOMP_loop_ordered_guided_next",
+                 BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_ORDERED_RUNTIME_NEXT,
+                 "GOMP_loop_ordered_runtime_next",
+                 BT_FN_BOOL_LONGPTR_LONGPTR, ATTR_NOTHROW_LIST)
+/* NOTE: Do not change the order of BUILT_IN_GOMP_PARALLEL_LOOP_*_START.
+   They are used in index arithmetic with enum omp_clause_schedule_kind
+   in omp-low.c.  */
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START,
+                 "GOMP_parallel_loop_static_start",
+                 BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_DYNAMIC_START,
+                 "GOMP_parallel_loop_dynamic_start",
+                 BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_GUIDED_START,
+                 "GOMP_parallel_loop_guided_start",
+                 BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG_LONG,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_LOOP_RUNTIME_START,
+                 "GOMP_parallel_loop_runtime_start",
+                 BT_FN_VOID_OMPFN_PTR_UINT_LONG_LONG_LONG,
+                 ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_END, "GOMP_loop_end",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_LOOP_END_NOWAIT, "GOMP_loop_end_nowait",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ORDERED_START, "GOMP_ordered_start",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_ORDERED_END, "GOMP_ordered_end",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_START, "GOMP_parallel_start",
+                 BT_FN_VOID_OMPFN_PTR_UINT, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_END, "GOMP_parallel_end",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_START, "GOMP_sections_start",
+                 BT_FN_UINT_UINT, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_NEXT, "GOMP_sections_next",
+                 BT_FN_UINT, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_PARALLEL_SECTIONS_START,
+                 "GOMP_parallel_sections_start",
+                 BT_FN_VOID_OMPFN_PTR_UINT_UINT, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_END, "GOMP_sections_end",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SECTIONS_END_NOWAIT,
+                 "GOMP_sections_end_nowait",
+                 BT_FN_VOID, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_START, "GOMP_single_start",
+                 BT_FN_BOOL, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_START, "GOMP_single_copy_start",
+                 BT_FN_PTR, ATTR_NOTHROW_LIST)
+DEF_GOMP_BUILTIN (BUILT_IN_GOMP_SINGLE_COPY_END, "GOMP_single_copy_end",
+                 BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
new file mode 100644 (file)
index 0000000..65907f0
--- /dev/null
@@ -0,0 +1,3309 @@
+/* Lowering pass for OpenMP directives.  Converts OpenMP directives
+   into explicit calls to the runtime library (libgomp) and data
+   marshalling to implement data sharing and copying clauses.
+   Contributed by Diego Novillo <dnovillo@redhat.com>
+
+   Copyright (C) 2005 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 2, or (at yo