Added _Cilk_spawn and _Cilk_sync (2 cilk keywords) for C.
gcc/ChangeLog: 2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com> * builtins.c (is_builtin_name): Added a check for __cilkrts_detach and __cilkrts_pop_frame. If matched, then return true for built-in function name. (expand_builtin): Added BUILT_IN_CILK_DETACH and BUILT_IN_CILK_POP_FRAME case. * langhooks-def.h (lhd_install_body_with_frame_cleanup): New prototype. (lhs_cilk_detect_spawn): Likewise. (LANG_HOOKS_DECLS): Added LANG_HOOKS_CILKPLUS. (LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP): New #define. (LANG_HOOKS_CILKPLUS_FRAME_CLEANUP): Likewise. (LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN): Likewise. (LANG_HOOKS_CILKPLUS): Likewise. * tree.h (CILK_SPAWN_FN): Likewise. * builtin.def (DEF_CILK_BUILTIN_STUB): Likewise. * Makefile.in (C_COMMON_OBJS): Added c-family/cilk.o. (OBJS): Added cilk-common.o. (CILK_H): Added a new define. (gimplify.o): Added CILK_H into dependency list. (builtins.o): Likewise. (ipa-inline.o): Likewise. (ipa-inline-analysis.o): Likewise. (BUILTINS_DEF): Added cilk-builtins.def. * langhooks.c (lhd_install_body_with_frame_cleanup): New function. (lhd_cilk_detect_spawn): Likewise. * langhooks.h (lang_hooks_for_cilkplus): New struct. (struct lang_hooks): Added new field called "cilkplus." * cilk-common.c: New file. * cilk.h: Likewise. * cilk-builtins.def: Likewise. * cppbuiltin.c (define_builtin_macros_for_compilation_flags): Added "__cilk" macro and set it to 200. * function.h (struct function::cilk_frame_decl): New field. (struct function::is_cilk_function): Likewise. (struct function::calls_cilk_spawn): Likewise. * gimplify.c (gimplify_call_expr): Added a check if the function call being gimplified is a spawn detach point. If so, then add pop_frame and detach function calls. (gimplify_expr): Added a CILK_SPAWN_STMT and CILK_SYNC_STMT case for gimplifying _Cilk_spawn and _Cilk_sync statements. (gimplify_return_expr): Added a check for _Cilk_spawn usage in function. If so, added a _Cilk_sync and gimplified it. (gimplify_modify_expr): Added a check for _Cilk_spawn in MODIFY and INIT_EXPRs. If so, then call gimplify_cilk_spawn. * ipa-inline-analysis (initialize_inline_failed): Prevent inlining of spawner function. (can_inline_edge_p): Prevent inling of spawnee function. * ira.c (ira_setup_eliminable_regset): Force usage of frame pointer for functions that use Cilk keywords. * tree-inline.h (struct copy_body_data::remap_var_for_cilk): New field. * tree-pretty-print.c (dump_generic_node): Added CILK_SPAWN_STMT and CILK_SYNC_STMT cases. * tree.def (DEFTREECODE): Added CILK_SPAWN_STMT and CILK_SYNC_STMT trees. * generic.texi (CILK_SPAWN_STMT): Added documentation for _Cilk_spawn. (CILK_SYNC_STMT): Added documentation for _Cilk_sync. * passes.texi (Cilk Keywords): New section that describes the compiler code changes for handling Cilk Keywords. gcc/c/ChangeLog: 2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com> * c-decl.c (finish_function): Added a call for insert_cilk_frame when a spawning function is found. * c-objc-common.h (LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN): New #define. (LANG_HOOKS_CILKPLUS_FRAME_CLEANUP): Likewise. (LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP): Likewise. * c-parser.c (c_parser_statement_after_labels): Added RID_CILK_SYNC case. (c_parser_postfix_expression): Added RID_CILK_SPAWN case. * c-typeck.c (build_compound_expr): Reject _Cilk_spawn in a comma expr. (c_finish_return): Added a check to reject _Cilk_spawn in return expression. (build_cilk_spawn): New function. (build_cilk_sync): Likewise. * Makefile.in (c-decl.o): Added cilk.h in dependency list. gcc/c-family/ChangeLog 2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com> * c-common.c (c_common_reswords[]): Added _Cilk_spawn and _Cilk_sync fields. (c_define_builtins): Called cilk_init_builtins if Cilk Plus is enabled. * c-common.h (enum rid): Added RID_CILK_SPAWN and RID_CILK_SYNC. (insert_cilk_frame): New prototype. (cilk_init_builtins): Likewise. (gimplify_cilk_spawn): Likewise. (c_cilk_install_body_w_frame_cleanup): Likewise. (cilk_detect_spawn_and_unwrap): Likewise. (cilk_set_spawn_marker): Likewise. (build_cilk_sync): Likewise. (build_cilk_spawn): Likewise. * cilk.c: New file. gcc/lto/ChangeLog 2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com> * Make-lang.in (lto/lto-lang.o): Added cilk.h in dependency list. * lto-lang.c (lto_init): Added a call to cilk_init_builtins if Cilk Plus is enabled. gcc/testsuite/ChangeLog 2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com> * c-c++-common/cilk-plus/CK/compound_cilk_spawn.c: New test. * c-c++-common/cilk-plus/CK/concec_cilk_spawn.c: Likewise. * c-c++-common/cilk-plus/CK/fib.c: Likewise. * c-c++-common/cilk-plus/CK/no_args_error.c: Likewise. * c-c++-common/cilk-plus/CK/spawnee_inline.c: Likewise. * c-c++-common/cilk-plus/CK/spawner_inline.c: Likewise. * c-c++-common/cilk-plus/CK/spawning_arg.c: Likewise. * c-c++-common/cilk-plus/CK/steal_check.c: Likewise. * c-c++-common/cilk-plus/CK/test__cilk.c: Likewise. * c-c++-common/cilk-plus/CK/varargs_test.c: Likewise. * c-c++-common/cilk-plus/CK/sync_wo_spawn.c: Likewise. * c-c++-common/cilk-plus/CK/invalid_spawn.c: Likewise. * c-c++-common/cilk-plus/CK/spawn_in_return.c: Likewise. * c-c++-common/cilk-plus/CK/fib_init_expr_xy.c: Likewise. * c-c++-common/cilk-plus/CK/fib_no_sync.c: Likewise. * c-c++-common/cilk-plus/CK/fib_no_return.c: Likewise. * gcc.dg/cilk-plus/cilk-plus.exp: Added support to run Cilk Keywords test stored in c-c++-common. Also, added the Cilk runtime's library to the ld_library_path. From-SVN: r204172
This commit is contained in:
parent
67348ccc9c
commit
939b37da6d
@ -1,3 +1,58 @@
|
||||
2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* builtins.c (is_builtin_name): Added a check for __cilkrts_detach and
|
||||
__cilkrts_pop_frame. If matched, then return true for built-in
|
||||
function name.
|
||||
(expand_builtin): Added BUILT_IN_CILK_DETACH and
|
||||
BUILT_IN_CILK_POP_FRAME case.
|
||||
* langhooks-def.h (lhd_install_body_with_frame_cleanup): New prototype.
|
||||
(lhs_cilk_detect_spawn): Likewise.
|
||||
(LANG_HOOKS_DECLS): Added LANG_HOOKS_CILKPLUS.
|
||||
(LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP): New #define.
|
||||
(LANG_HOOKS_CILKPLUS_FRAME_CLEANUP): Likewise.
|
||||
(LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN): Likewise.
|
||||
(LANG_HOOKS_CILKPLUS): Likewise.
|
||||
* tree.h (CILK_SPAWN_FN): Likewise.
|
||||
* builtin.def (DEF_CILK_BUILTIN_STUB): Likewise.
|
||||
* Makefile.in (C_COMMON_OBJS): Added c-family/cilk.o.
|
||||
(OBJS): Added cilk-common.o.
|
||||
(BUILTINS_DEF): Added cilk-builtins.def.
|
||||
* langhooks.c (lhd_install_body_with_frame_cleanup): New function.
|
||||
(lhd_cilk_detect_spawn): Likewise.
|
||||
* langhooks.h (lang_hooks_for_cilkplus): New struct.
|
||||
(struct lang_hooks): Added new field called "cilkplus."
|
||||
* cilk-common.c: New file.
|
||||
* cilk.h: Likewise.
|
||||
* cilk-builtins.def: Likewise.
|
||||
* cppbuiltin.c (define_builtin_macros_for_compilation_flags): Added
|
||||
"__cilk" macro and set it to 200.
|
||||
* function.h (struct function::cilk_frame_decl): New field.
|
||||
(struct function::is_cilk_function): Likewise.
|
||||
(struct function::calls_cilk_spawn): Likewise.
|
||||
* gimplify.c (gimplify_call_expr): Added a check if the function call
|
||||
being gimplified is a spawn detach point. If so, then add pop_frame
|
||||
and detach function calls.
|
||||
(gimplify_expr): Added a CILK_SPAWN_STMT and CILK_SYNC_STMT case
|
||||
for gimplifying _Cilk_spawn and _Cilk_sync statements.
|
||||
(gimplify_return_expr): Added a check for _Cilk_spawn usage in
|
||||
function. If so, added a _Cilk_sync and gimplified it.
|
||||
(gimplify_modify_expr): Added a check for _Cilk_spawn in MODIFY and
|
||||
INIT_EXPRs. If so, then call gimplify_cilk_spawn.
|
||||
* ipa-inline-analysis (initialize_inline_failed): Prevent inlining of
|
||||
spawner function.
|
||||
(can_inline_edge_p): Prevent inling of spawnee function.
|
||||
* ira.c (ira_setup_eliminable_regset): Force usage of frame pointer
|
||||
for functions that use Cilk keywords.
|
||||
* tree-inline.h (struct copy_body_data::remap_var_for_cilk): New field.
|
||||
* tree-pretty-print.c (dump_generic_node): Added CILK_SPAWN_STMT and
|
||||
CILK_SYNC_STMT cases.
|
||||
* tree.def (DEFTREECODE): Added CILK_SPAWN_STMT and CILK_SYNC_STMT
|
||||
trees.
|
||||
* generic.texi (CILK_SPAWN_STMT): Added documentation for _Cilk_spawn.
|
||||
(CILK_SYNC_STMT): Added documentation for _Cilk_sync.
|
||||
* passes.texi (Cilk Keywords): New section that describes the compiler
|
||||
code changes for handling Cilk Keywords.
|
||||
|
||||
2013-10-29 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
Patch autogenerated by refactor_symtab.py from
|
||||
|
@ -872,7 +872,7 @@ RTL_H = $(RTL_BASE_H) $(FLAGS_H) genrtl.h
|
||||
READ_MD_H = $(OBSTACK_H) $(HASHTAB_H) read-md.h
|
||||
PARAMS_H = params.h params.def
|
||||
BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def \
|
||||
gtm-builtins.def sanitizer.def cilkplus.def
|
||||
gtm-builtins.def sanitizer.def cilkplus.def cilk-builtins.def
|
||||
INTERNAL_FN_DEF = internal-fn.def
|
||||
INTERNAL_FN_H = internal-fn.h $(INTERNAL_FN_DEF)
|
||||
TREE_CORE_H = tree-core.h coretypes.h all-tree.def tree.def \
|
||||
@ -1137,7 +1137,7 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
|
||||
c-family/c-omp.o c-family/c-opts.o c-family/c-pch.o \
|
||||
c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
|
||||
c-family/c-semantics.o c-family/c-ada-spec.o \
|
||||
c-family/array-notation-common.o c-family/c-ubsan.o
|
||||
c-family/array-notation-common.o c-family/cilk.o c-family/c-ubsan.o
|
||||
|
||||
# Language-independent object files.
|
||||
# We put the insn-*.o files first so that a parallel make will build
|
||||
@ -1182,6 +1182,7 @@ OBJS = \
|
||||
cgraphbuild.o \
|
||||
cgraphunit.o \
|
||||
cgraphclones.o \
|
||||
cilk-common.o \
|
||||
combine.o \
|
||||
combine-stack-adj.o \
|
||||
compare-elim.o \
|
||||
|
@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "diagnostic-core.h"
|
||||
#include "builtins.h"
|
||||
#include "ubsan.h"
|
||||
#include "cilk.h"
|
||||
|
||||
|
||||
static tree do_mpc_arg1 (tree, tree, int (*)(mpc_ptr, mpc_srcptr, mpc_rnd_t));
|
||||
@ -235,6 +236,10 @@ is_builtin_name (const char *name)
|
||||
return true;
|
||||
if (strncmp (name, "__atomic_", 9) == 0)
|
||||
return true;
|
||||
if (flag_enable_cilkplus
|
||||
&& (!strcmp (name, "__cilkrts_detach")
|
||||
|| !strcmp (name, "__cilkrts_pop_frame")))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -6685,6 +6690,14 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
|
||||
expand_builtin_set_thread_pointer (exp);
|
||||
return const0_rtx;
|
||||
|
||||
case BUILT_IN_CILK_DETACH:
|
||||
expand_builtin_cilk_detach (exp);
|
||||
return const0_rtx;
|
||||
|
||||
case BUILT_IN_CILK_POP_FRAME:
|
||||
expand_builtin_cilk_pop_frame (exp);
|
||||
return const0_rtx;
|
||||
|
||||
default: /* just do library call, if unknown builtin */
|
||||
break;
|
||||
}
|
||||
|
@ -147,6 +147,13 @@ along with GCC; see the file COPYING3. If not see
|
||||
false, true, true, ATTRS, false, \
|
||||
(flag_openmp || flag_tree_parallelize_loops))
|
||||
|
||||
/* Builtin used by implementation of Cilk Plus. Most of these are decomposed
|
||||
by the compiler but a few are implemented in libcilkrts. */
|
||||
#undef DEF_CILK_BUILTIN_STUB
|
||||
#define DEF_CILK_BUILTIN_STUB(ENUM, NAME) \
|
||||
DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_LAST, BT_LAST, false, false, \
|
||||
false, ATTR_LAST, false, false)
|
||||
|
||||
/* Builtin used by the implementation of GNU TM. These
|
||||
functions are mapped to the actual implementation of the STM library. */
|
||||
#undef DEF_TM_BUILTIN
|
||||
@ -846,6 +853,9 @@ DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
|
||||
/* OpenMP builtins. */
|
||||
#include "omp-builtins.def"
|
||||
|
||||
/* Cilk keywords builtins. */
|
||||
#include "cilk-builtins.def"
|
||||
|
||||
/* GTM builtins. */
|
||||
#include "gtm-builtins.def"
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* c-common.c (c_common_reswords[]): Added _Cilk_spawn and _Cilk_sync
|
||||
fields.
|
||||
(c_define_builtins): Called cilk_init_builtins if Cilk Plus is
|
||||
enabled.
|
||||
* c-common.h (enum rid): Added RID_CILK_SPAWN and RID_CILK_SYNC.
|
||||
(insert_cilk_frame): New prototype.
|
||||
(cilk_init_builtins): Likewise.
|
||||
(gimplify_cilk_spawn): Likewise.
|
||||
(c_cilk_install_body_w_frame_cleanup): Likewise.
|
||||
(cilk_detect_spawn_and_unwrap): Likewise.
|
||||
(cilk_set_spawn_marker): Likewise.
|
||||
(build_cilk_sync): Likewise.
|
||||
(build_cilk_spawn): Likewise.
|
||||
* cilk.c: New file.
|
||||
|
||||
2013-10-29 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
Patch autogenerated by refactor_symtab.py from
|
||||
|
@ -409,6 +409,8 @@ const struct c_common_resword c_common_reswords[] =
|
||||
{ "_Alignof", RID_ALIGNOF, D_CONLY },
|
||||
{ "_Bool", RID_BOOL, D_CONLY },
|
||||
{ "_Complex", RID_COMPLEX, 0 },
|
||||
{ "_Cilk_spawn", RID_CILK_SPAWN, 0 },
|
||||
{ "_Cilk_sync", RID_CILK_SYNC, 0 },
|
||||
{ "_Imaginary", RID_IMAGINARY, D_CONLY },
|
||||
{ "_Decimal32", RID_DFLOAT32, D_CONLY | D_EXT },
|
||||
{ "_Decimal64", RID_DFLOAT64, D_CONLY | D_EXT },
|
||||
@ -5219,6 +5221,9 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node)
|
||||
targetm.init_builtins ();
|
||||
|
||||
build_common_builtin_nodes ();
|
||||
|
||||
if (flag_enable_cilkplus)
|
||||
cilk_init_builtins ();
|
||||
}
|
||||
|
||||
/* Like get_identifier, but avoid warnings about null arguments when
|
||||
|
@ -148,6 +148,9 @@ enum rid
|
||||
/* C++11 */
|
||||
RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT,
|
||||
|
||||
/* Cilk Plus keywords. */
|
||||
RID_CILK_SPAWN, RID_CILK_SYNC,
|
||||
|
||||
/* Objective-C ("AT" reserved words - they are only keywords when
|
||||
they follow '@') */
|
||||
RID_AT_ENCODE, RID_AT_END,
|
||||
@ -1356,4 +1359,18 @@ extern void cilkplus_extract_an_triplets (vec<tree, va_gc> *, size_t, size_t,
|
||||
vec<vec<an_parts> > *);
|
||||
extern vec <tree, va_gc> *fix_sec_implicit_args
|
||||
(location_t, vec <tree, va_gc> *, vec<an_loop_parts>, size_t, tree);
|
||||
|
||||
/* In cilk.c. */
|
||||
extern tree insert_cilk_frame (tree);
|
||||
extern void cilk_init_builtins (void);
|
||||
extern int gimplify_cilk_spawn (tree *, gimple_seq *, gimple_seq *);
|
||||
extern void c_cilk_install_body_w_frame_cleanup (tree, tree);
|
||||
extern bool cilk_detect_spawn_and_unwrap (tree *);
|
||||
extern bool cilk_set_spawn_marker (location_t, tree);
|
||||
extern tree build_cilk_sync (void);
|
||||
extern tree build_cilk_spawn (location_t, tree);
|
||||
extern tree make_cilk_frame (tree);
|
||||
extern tree create_cilk_function_exit (tree, bool, bool);
|
||||
extern tree cilk_install_body_pedigree_operations (tree);
|
||||
|
||||
#endif /* ! GCC_C_COMMON_H */
|
||||
|
1305
gcc/c-family/cilk.c
Normal file
1305
gcc/c-family/cilk.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,21 @@
|
||||
2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* c-decl.c (finish_function): Added a call for insert_cilk_frame when
|
||||
a spawning function is found.
|
||||
* c-objc-common.h (LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN): New #define.
|
||||
(LANG_HOOKS_CILKPLUS_FRAME_CLEANUP): Likewise.
|
||||
(LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP): Likewise.
|
||||
* c-parser.c (c_parser_statement_after_labels): Added RID_CILK_SYNC
|
||||
case.
|
||||
(c_parser_postfix_expression): Added RID_CILK_SPAWN case.
|
||||
* c-typeck.c (build_compound_expr): Reject _Cilk_spawn in a comma
|
||||
expr.
|
||||
(c_finish_return): Added a check to reject _Cilk_spawn in return
|
||||
expression.
|
||||
(build_cilk_spawn): New function.
|
||||
(build_cilk_sync): Likewise.
|
||||
* Makefile.in (c-decl.o): Added cilk.h in dependency list.
|
||||
|
||||
2013-10-27 Tobias Burnus <burnus@net-b.de>
|
||||
|
||||
PR other/33426
|
||||
|
@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "pointer-set.h"
|
||||
#include "plugin.h"
|
||||
#include "c-family/c-ada-spec.h"
|
||||
#include "cilk.h"
|
||||
|
||||
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
|
||||
enum decl_context
|
||||
@ -8447,6 +8448,12 @@ finish_function (void)
|
||||
/* Tie off the statement tree for this function. */
|
||||
DECL_SAVED_TREE (fndecl) = pop_stmt_list (DECL_SAVED_TREE (fndecl));
|
||||
|
||||
/* If the function has _Cilk_spawn in front of a function call inside it
|
||||
i.e. it is a spawning function, then add the appropriate Cilk plus
|
||||
functions inside. */
|
||||
if (fn_contains_cilk_spawn_p (cfun))
|
||||
cfun->cilk_frame_decl = insert_cilk_frame (fndecl);
|
||||
|
||||
finish_fname_decls ();
|
||||
|
||||
/* Complain if there's just no return statement. */
|
||||
|
@ -105,4 +105,13 @@ along with GCC; see the file COPYING3. If not see
|
||||
#undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P
|
||||
#define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P c_vla_unspec_p
|
||||
|
||||
#undef LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN
|
||||
#define LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN gimplify_cilk_spawn
|
||||
|
||||
#undef LANG_HOOKS_CILKPLUS_FRAME_CLEANUP
|
||||
#define LANG_HOOKS_CILKPLUS_FRAME_CLEANUP c_cilk_install_body_w_frame_cleanup
|
||||
|
||||
#undef LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP
|
||||
#define LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP \
|
||||
cilk_detect_spawn_and_unwrap
|
||||
#endif /* GCC_C_OBJC_COMMON */
|
||||
|
@ -4587,6 +4587,14 @@ c_parser_statement_after_labels (c_parser *parser)
|
||||
case RID_FOR:
|
||||
c_parser_for_statement (parser, false);
|
||||
break;
|
||||
case RID_CILK_SYNC:
|
||||
c_parser_consume_token (parser);
|
||||
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
|
||||
if (!flag_enable_cilkplus)
|
||||
error_at (loc, "-fcilkplus must be enabled to use %<_Cilk_sync%>");
|
||||
else
|
||||
add_stmt (build_cilk_sync ());
|
||||
break;
|
||||
case RID_GOTO:
|
||||
c_parser_consume_token (parser);
|
||||
if (c_parser_next_token_is (parser, CPP_NAME))
|
||||
@ -7174,6 +7182,30 @@ c_parser_postfix_expression (c_parser *parser)
|
||||
case RID_GENERIC:
|
||||
expr = c_parser_generic_selection (parser);
|
||||
break;
|
||||
case RID_CILK_SPAWN:
|
||||
c_parser_consume_token (parser);
|
||||
if (!flag_enable_cilkplus)
|
||||
{
|
||||
error_at (loc, "-fcilkplus must be enabled to use "
|
||||
"%<_Cilk_spawn%>");
|
||||
expr = c_parser_postfix_expression (parser);
|
||||
expr.value = error_mark_node;
|
||||
}
|
||||
if (c_parser_peek_token (parser)->keyword == RID_CILK_SPAWN)
|
||||
{
|
||||
error_at (loc, "consecutive %<_Cilk_spawn%> keywords "
|
||||
"are not permitted");
|
||||
/* Now flush out all the _Cilk_spawns. */
|
||||
while (c_parser_peek_token (parser)->keyword == RID_CILK_SPAWN)
|
||||
c_parser_consume_token (parser);
|
||||
expr = c_parser_postfix_expression (parser);
|
||||
}
|
||||
else
|
||||
{
|
||||
expr = c_parser_postfix_expression (parser);
|
||||
expr.value = build_cilk_spawn (loc, expr.value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
c_parser_error (parser, "expected expression");
|
||||
expr.value = error_mark_node;
|
||||
|
@ -4387,6 +4387,14 @@ build_compound_expr (location_t loc, tree expr1, tree expr2)
|
||||
tree eptype = NULL_TREE;
|
||||
tree ret;
|
||||
|
||||
if (flag_enable_cilkplus
|
||||
&& (TREE_CODE (expr1) == CILK_SPAWN_STMT
|
||||
|| TREE_CODE (expr2) == CILK_SPAWN_STMT))
|
||||
{
|
||||
error_at (loc,
|
||||
"spawned function call cannot be part of a comma expression");
|
||||
return error_mark_node;
|
||||
}
|
||||
expr1_int_operands = EXPR_INT_CONST_OPERANDS (expr1);
|
||||
if (expr1_int_operands)
|
||||
expr1 = remove_c_maybe_const_expr (expr1);
|
||||
@ -8694,6 +8702,12 @@ c_finish_return (location_t loc, tree retval, tree origtype)
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
if (flag_enable_cilkplus && retval && TREE_CODE (retval) == CILK_SPAWN_STMT)
|
||||
{
|
||||
error_at (loc, "use of %<_Cilk_spawn%> in a return statement is not "
|
||||
"allowed");
|
||||
return error_mark_node;
|
||||
}
|
||||
if (retval)
|
||||
{
|
||||
tree semantic_type = NULL_TREE;
|
||||
|
33
gcc/cilk-builtins.def
Normal file
33
gcc/cilk-builtins.def
Normal file
@ -0,0 +1,33 @@
|
||||
/* This file contains the definitions and documentation for the
|
||||
Cilk Plus builtins used in the GNU compiler.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
Intel Corporation.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 3, or (at your option) any later
|
||||
version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_ENTER_FRAME, "__cilkrts_enter_frame_1")
|
||||
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_ENTER_FRAME_FAST,
|
||||
"__cilkrts_enter_frame_fast_1")
|
||||
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_DETACH, "__cilkrts_detach")
|
||||
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_RETHROW, "__cilkrts_rethrow")
|
||||
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_SYNCHED, "__cilkrts_synched")
|
||||
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_SYNC, "__cilkrts_sync")
|
||||
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_LEAVE_FRAME, "__cilkrts_leave_frame")
|
||||
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_POP_FRAME, "__cilkrts_pop_frame")
|
||||
DEF_CILK_BUILTIN_STUB (BUILT_IN_CILK_SAVE_FP, "__cilkrts_save_fp_ctrl_state")
|
484
gcc/cilk-common.c
Normal file
484
gcc/cilk-common.c
Normal file
@ -0,0 +1,484 @@
|
||||
/* This file is part of the Intel(R) Cilk(TM) Plus support
|
||||
This file contains the CilkPlus Intrinsics
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>,
|
||||
Intel Corporation
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tree.h"
|
||||
#include "langhooks.h"
|
||||
#include "expr.h"
|
||||
#include "optabs.h"
|
||||
#include "recog.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "gimple.h"
|
||||
#include "cilk.h"
|
||||
|
||||
/* This structure holds all the important fields of the internal structures,
|
||||
internal built-in functions, and Cilk-specific data types. Explanation of
|
||||
all the these fielsd are given in cilk.h. */
|
||||
tree cilk_trees[(int) CILK_TI_MAX];
|
||||
|
||||
/* Returns the value in structure FRAME pointed by the FIELD_NUMBER
|
||||
(e.g. X.y).
|
||||
FIELD_NUMBER is an index to the structure FRAME_PTR. For details
|
||||
about these fields, refer to cilk_trees structure in cilk.h and
|
||||
cilk_init_builtins function in this file. Returns a TREE that is the type
|
||||
of the field represented by FIELD_NUMBER. If VOLATIL parameter is set
|
||||
to true then the returning field is set as volatile. */
|
||||
|
||||
tree
|
||||
cilk_dot (tree frame, int field_number, bool volatil)
|
||||
{
|
||||
tree field = cilk_trees[field_number];
|
||||
field = fold_build3 (COMPONENT_REF, TREE_TYPE (field), frame, field,
|
||||
NULL_TREE);
|
||||
TREE_THIS_VOLATILE (field) = volatil;
|
||||
return field;
|
||||
}
|
||||
|
||||
/* Returns the address of a field in FRAME_PTR, pointed by FIELD_NUMBER.
|
||||
(e.g. (&X)->y). Please see cilk_dot function for explanation of the
|
||||
FIELD_NUMBER. Returns a tree that is the type of the field represented
|
||||
by FIELD_NUMBER. If VOLATIL parameter is set to true then the returning
|
||||
field is set as volatile. */
|
||||
|
||||
tree
|
||||
cilk_arrow (tree frame_ptr, int field_number, bool volatil)
|
||||
{
|
||||
return cilk_dot (fold_build1 (INDIRECT_REF,
|
||||
TREE_TYPE (TREE_TYPE (frame_ptr)), frame_ptr),
|
||||
field_number, volatil);
|
||||
}
|
||||
|
||||
|
||||
/* This function will add FIELD of type TYPE to a defined built-in
|
||||
structure. *NAME is the name of the field to be added. */
|
||||
|
||||
static tree
|
||||
add_field (const char *name, tree type, tree fields)
|
||||
{
|
||||
tree t = get_identifier (name);
|
||||
tree field = build_decl (BUILTINS_LOCATION, FIELD_DECL, t, type);
|
||||
TREE_CHAIN (field) = fields;
|
||||
return field;
|
||||
}
|
||||
|
||||
/* This function will define a built-in function of NAME, of type FNTYPE and
|
||||
register it under the built-in function code CODE. If PUBLISH is set then
|
||||
the declaration is pushed into the declaration list. CODE is the index
|
||||
to the cilk_trees array. *NAME is the name of the function to be added. */
|
||||
|
||||
static tree
|
||||
install_builtin (const char *name, tree fntype, enum built_in_function code,
|
||||
bool publish)
|
||||
{
|
||||
tree fndecl = build_fn_decl (name, fntype);
|
||||
DECL_BUILT_IN_CLASS (fndecl) = BUILT_IN_NORMAL;
|
||||
DECL_FUNCTION_CODE (fndecl) = code;
|
||||
if (publish)
|
||||
{
|
||||
tree t = lang_hooks.decls.pushdecl (fndecl);
|
||||
if (t)
|
||||
fndecl = t;
|
||||
}
|
||||
set_builtin_decl (code, fndecl, true);
|
||||
return fndecl;
|
||||
}
|
||||
|
||||
/* Creates and initializes all the built-in Cilk keywords functions and three
|
||||
structures: __cilkrts_stack_frame, __cilkrts_pedigree and __cilkrts_worker.
|
||||
Detailed information about __cilkrts_stack_frame and
|
||||
__cilkrts_worker structures are given in libcilkrts/include/internal/abi.h.
|
||||
__cilkrts_pedigree is described in libcilkrts/include/cilk/common.h. */
|
||||
|
||||
void
|
||||
cilk_init_builtins (void)
|
||||
{
|
||||
/* Now build the following __cilkrts_pedigree struct:
|
||||
struct __cilkrts_pedigree {
|
||||
uint64_t rank;
|
||||
struct __cilkrts_pedigree *parent;
|
||||
} */
|
||||
|
||||
tree pedigree_type = lang_hooks.types.make_type (RECORD_TYPE);
|
||||
tree pedigree_ptr = build_pointer_type (pedigree_type);
|
||||
tree field = add_field ("rank", uint64_type_node, NULL_TREE);
|
||||
cilk_trees[CILK_TI_PEDIGREE_RANK] = field;
|
||||
field = add_field ("parent", pedigree_ptr, field);
|
||||
cilk_trees[CILK_TI_PEDIGREE_PARENT] = field;
|
||||
finish_builtin_struct (pedigree_type, "__cilkrts_pedigree_GCC", field,
|
||||
NULL_TREE);
|
||||
lang_hooks.types.register_builtin_type (pedigree_type,
|
||||
"__cilkrts_pedigree_t");
|
||||
cilk_pedigree_type_decl = pedigree_type;
|
||||
|
||||
/* Build the Cilk Stack Frame:
|
||||
struct __cilkrts_stack_frame {
|
||||
uint32_t flags;
|
||||
uint32_t size;
|
||||
struct __cilkrts_stack_frame *call_parent;
|
||||
__cilkrts_worker *worker;
|
||||
void *except_data;
|
||||
void *ctx[4];
|
||||
uint32_t mxcsr;
|
||||
uint16_t fpcsr;
|
||||
uint16_t reserved;
|
||||
__cilkrts_pedigree pedigree;
|
||||
}; */
|
||||
|
||||
tree frame = lang_hooks.types.make_type (RECORD_TYPE);
|
||||
tree frame_ptr = build_pointer_type (frame);
|
||||
tree worker_type = lang_hooks.types.make_type (RECORD_TYPE);
|
||||
tree worker_ptr = build_pointer_type (worker_type);
|
||||
tree s_type_node = build_int_cst (size_type_node, 4);
|
||||
|
||||
tree flags = add_field ("flags", uint32_type_node, NULL_TREE);
|
||||
tree size = add_field ("size", uint32_type_node, flags);
|
||||
tree parent = add_field ("call_parent", frame_ptr, size);
|
||||
tree worker = add_field ("worker", worker_ptr, parent);
|
||||
tree except = add_field ("except_data", frame_ptr, worker);
|
||||
tree context = add_field ("ctx",
|
||||
build_array_type (ptr_type_node,
|
||||
build_index_type (s_type_node)),
|
||||
except);
|
||||
tree mxcsr = add_field ("mxcsr", uint32_type_node, context);
|
||||
tree fpcsr = add_field ("fpcsr", uint16_type_node, mxcsr);
|
||||
tree reserved = add_field ("reserved", uint16_type_node, fpcsr);
|
||||
tree pedigree = add_field ("pedigree", pedigree_type, reserved);
|
||||
|
||||
/* Now add them to a common structure whose fields are #defined to something
|
||||
that is used at a later stage. */
|
||||
cilk_trees[CILK_TI_FRAME_FLAGS] = flags;
|
||||
cilk_trees[CILK_TI_FRAME_PARENT] = parent;
|
||||
cilk_trees[CILK_TI_FRAME_WORKER] = worker;
|
||||
cilk_trees[CILK_TI_FRAME_EXCEPTION] = except;
|
||||
cilk_trees[CILK_TI_FRAME_CONTEXT] = context;
|
||||
/* We don't care about reserved, so no need to store it in cilk_trees. */
|
||||
cilk_trees[CILK_TI_FRAME_PEDIGREE] = pedigree;
|
||||
TREE_ADDRESSABLE (frame) = 1;
|
||||
|
||||
finish_builtin_struct (frame, "__cilkrts_st_frame_GCC", pedigree, NULL_TREE);
|
||||
cilk_frame_type_decl = frame;
|
||||
lang_hooks.types.register_builtin_type (frame, "__cilkrts_frame_t");
|
||||
|
||||
cilk_frame_ptr_type_decl = build_qualified_type (frame_ptr,
|
||||
TYPE_QUAL_VOLATILE);
|
||||
/* Now let's do the following worker struct:
|
||||
|
||||
struct __cilkrts_worker {
|
||||
__cilkrts_stack_frame *volatile *volatile tail;
|
||||
__cilkrts_stack_frame *volatile *volatile head;
|
||||
__cilkrts_stack_frame *volatile *volatile exc;
|
||||
__cilkrts_stack_frame *volatile *volatile protected_tail;
|
||||
__cilkrts_stack_frame *volatile *ltq_limit;
|
||||
int32_t self;
|
||||
global_state_t *g;
|
||||
local_state *l;
|
||||
cilkred_map *reducer_map;
|
||||
__cilkrts_stack_frame *current_stack_frame;
|
||||
void *reserved;
|
||||
__cilkrts_worker_sysdep_state *sysdep;
|
||||
__cilkrts_pedigree pedigree;
|
||||
} */
|
||||
|
||||
tree fptr_volatil_type = build_qualified_type (frame_ptr, TYPE_QUAL_VOLATILE);
|
||||
tree fptr_volatile_ptr = build_pointer_type (fptr_volatil_type);
|
||||
tree fptr_vol_ptr_vol = build_qualified_type (fptr_volatile_ptr,
|
||||
TYPE_QUAL_VOLATILE);
|
||||
tree g = lang_hooks.types.make_type (RECORD_TYPE);
|
||||
finish_builtin_struct (g, "__cilkrts_global_state", NULL_TREE, NULL_TREE);
|
||||
tree l = lang_hooks.types.make_type (RECORD_TYPE);
|
||||
finish_builtin_struct (l, "__cilkrts_local_state", NULL_TREE, NULL_TREE);
|
||||
tree sysdep_t = lang_hooks.types.make_type (RECORD_TYPE);
|
||||
finish_builtin_struct (sysdep_t, "__cilkrts_worker_sysdep_state", NULL_TREE,
|
||||
NULL_TREE);
|
||||
|
||||
field = add_field ("tail", fptr_vol_ptr_vol, NULL_TREE);
|
||||
cilk_trees[CILK_TI_WORKER_TAIL] = field;
|
||||
field = add_field ("head", fptr_vol_ptr_vol, field);
|
||||
field = add_field ("exc", fptr_vol_ptr_vol, field);
|
||||
field = add_field ("protected_tail", fptr_vol_ptr_vol, field);
|
||||
field = add_field ("ltq_limit", fptr_volatile_ptr, field);
|
||||
field = add_field ("self", integer_type_node, field);
|
||||
field = add_field ("g", build_pointer_type (g), field);
|
||||
field = add_field ("l", build_pointer_type (g), field);
|
||||
field = add_field ("reducer_map", ptr_type_node, field);
|
||||
field = add_field ("current_stack_frame", frame_ptr, field);
|
||||
cilk_trees[CILK_TI_WORKER_CUR] = field;
|
||||
field = add_field ("saved_protected_tail", fptr_volatile_ptr, field);
|
||||
field = add_field ("sysdep", build_pointer_type (sysdep_t), field);
|
||||
field = add_field ("pedigree", pedigree_type, field);
|
||||
cilk_trees[CILK_TI_WORKER_PEDIGREE] = field;
|
||||
finish_builtin_struct (worker_type, "__cilkrts_worker_GCC", field,
|
||||
NULL_TREE);
|
||||
|
||||
tree fptr_arglist = tree_cons (NULL_TREE, frame_ptr, void_list_node);
|
||||
tree fptr_fun = build_function_type (void_type_node, fptr_arglist);
|
||||
|
||||
/* void __cilkrts_enter_frame_1 (__cilkrts_stack_frame *); */
|
||||
cilk_enter_fndecl = install_builtin ("__cilkrts_enter_frame_1", fptr_fun,
|
||||
BUILT_IN_CILK_ENTER_FRAME, false);
|
||||
|
||||
/* void __cilkrts_enter_frame_fast_1 (__cilkrts_stack_frame *); */
|
||||
cilk_enter_fast_fndecl =
|
||||
install_builtin ("__cilkrts_enter_frame_fast_1", fptr_fun,
|
||||
BUILT_IN_CILK_ENTER_FRAME_FAST, false);
|
||||
|
||||
/* void __cilkrts_pop_frame (__cilkrts_stack_frame *); */
|
||||
cilk_pop_fndecl = install_builtin ("__cilkrts_pop_frame", fptr_fun,
|
||||
BUILT_IN_CILK_POP_FRAME, false);
|
||||
|
||||
/* void __cilkrts_leave_frame (__cilkrts_stack_frame *); */
|
||||
cilk_leave_fndecl = install_builtin ("__cilkrts_leave_frame", fptr_fun,
|
||||
BUILT_IN_CILK_LEAVE_FRAME, false);
|
||||
|
||||
/* void __cilkrts_sync (__cilkrts_stack_frame *); */
|
||||
cilk_sync_fndecl = install_builtin ("__cilkrts_sync", fptr_fun,
|
||||
BUILT_IN_CILK_SYNC, false);
|
||||
|
||||
/* void __cilkrts_detach (__cilkrts_stack_frame *); */
|
||||
cilk_detach_fndecl = install_builtin ("__cilkrts_detach", fptr_fun,
|
||||
BUILT_IN_CILK_DETACH, false);
|
||||
|
||||
/* __cilkrts_rethrow (struct stack_frame *); */
|
||||
cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun,
|
||||
BUILT_IN_CILK_RETHROW, false);
|
||||
|
||||
/* __cilkrts_save_fp_ctrl_state (__cilkrts_stack_frame *); */
|
||||
cilk_save_fp_fndecl = install_builtin ("__cilkrts_save_fp_ctrl_state",
|
||||
fptr_fun, BUILT_IN_CILK_SAVE_FP,
|
||||
false);
|
||||
}
|
||||
|
||||
/* Get the appropriate frame arguments for CALL that is of type CALL_EXPR. */
|
||||
|
||||
static tree
|
||||
get_frame_arg (tree call)
|
||||
{
|
||||
tree arg, argtype;
|
||||
|
||||
gcc_assert (call_expr_nargs (call) >= 1);
|
||||
|
||||
arg = CALL_EXPR_ARG (call, 0);
|
||||
argtype = TREE_TYPE (arg);
|
||||
gcc_assert (TREE_CODE (argtype) == POINTER_TYPE);
|
||||
|
||||
argtype = TREE_TYPE (argtype);
|
||||
|
||||
gcc_assert (!lang_hooks.types_compatible_p
|
||||
|| lang_hooks.types_compatible_p (argtype, cilk_frame_type_decl));
|
||||
|
||||
/* If it is passed in as an address, then just use the value directly
|
||||
since the function is inlined. */
|
||||
if (TREE_CODE (arg) == INDIRECT_REF || TREE_CODE (arg) == ADDR_EXPR)
|
||||
return TREE_OPERAND (arg, 0);
|
||||
return arg;
|
||||
}
|
||||
|
||||
/* Expands the __cilkrts_pop_frame function call stored in EXP. */
|
||||
|
||||
void
|
||||
expand_builtin_cilk_pop_frame (tree exp)
|
||||
{
|
||||
tree frame = get_frame_arg (exp);
|
||||
tree parent = cilk_dot (frame, CILK_TI_FRAME_PARENT, 0);
|
||||
|
||||
tree clear_parent = build2 (MODIFY_EXPR, void_type_node, parent,
|
||||
build_int_cst (TREE_TYPE (parent), 0));
|
||||
expand_expr (clear_parent, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
|
||||
/* During LTO, the is_cilk_function flag gets cleared.
|
||||
If __cilkrts_pop_frame is called, then this definitely must be a
|
||||
cilk function. */
|
||||
if (cfun)
|
||||
cfun->is_cilk_function = 1;
|
||||
}
|
||||
|
||||
/* Expands the cilk_detach function call stored in EXP. */
|
||||
|
||||
void
|
||||
expand_builtin_cilk_detach (tree exp)
|
||||
{
|
||||
rtx insn;
|
||||
tree fptr = get_frame_arg (exp);
|
||||
|
||||
if (fptr == NULL_TREE)
|
||||
return;
|
||||
|
||||
tree parent = cilk_dot (fptr, CILK_TI_FRAME_PARENT, 0);
|
||||
tree worker = cilk_dot (fptr, CILK_TI_FRAME_WORKER, 0);
|
||||
tree tail = cilk_dot (worker, CILK_TI_WORKER_TAIL, 1);
|
||||
|
||||
rtx wreg = expand_expr (worker, NULL_RTX, Pmode, EXPAND_NORMAL);
|
||||
if (GET_CODE (wreg) != REG)
|
||||
wreg = copy_to_reg (wreg);
|
||||
rtx preg = expand_expr (parent, NULL_RTX, Pmode, EXPAND_NORMAL);
|
||||
|
||||
/* TMP <- WORKER.TAIL
|
||||
*TMP <- PARENT
|
||||
TMP <- TMP + 1
|
||||
WORKER.TAIL <- TMP */
|
||||
|
||||
HOST_WIDE_INT worker_tail_offset =
|
||||
tree_low_cst (DECL_FIELD_OFFSET (cilk_trees[CILK_TI_WORKER_TAIL]), 0) +
|
||||
tree_low_cst (DECL_FIELD_BIT_OFFSET (cilk_trees[CILK_TI_WORKER_TAIL]), 0) /
|
||||
BITS_PER_UNIT;
|
||||
rtx tmem0 = gen_rtx_MEM (Pmode,
|
||||
plus_constant (Pmode, wreg, worker_tail_offset));
|
||||
set_mem_attributes (tmem0, tail, 0);
|
||||
MEM_NOTRAP_P (tmem0) = 1;
|
||||
gcc_assert (MEM_VOLATILE_P (tmem0));
|
||||
rtx treg = copy_to_mode_reg (Pmode, tmem0);
|
||||
rtx tmem1 = gen_rtx_MEM (Pmode, treg);
|
||||
set_mem_attributes (tmem1, TREE_TYPE (TREE_TYPE (tail)), 0);
|
||||
MEM_NOTRAP_P (tmem1) = 1;
|
||||
emit_move_insn (tmem1, preg);
|
||||
emit_move_insn (treg, plus_constant (Pmode, treg, GET_MODE_SIZE (Pmode)));
|
||||
|
||||
/* There is a release barrier (st8.rel, membar #StoreStore,
|
||||
sfence, lwsync, etc.) between the two stores. On x86
|
||||
normal volatile stores have proper semantics; the sfence
|
||||
would only be needed for nontemporal stores (which we
|
||||
could generate using the storent optab, for no benefit
|
||||
in this case).
|
||||
|
||||
The predicate may return false even for a REG if this is
|
||||
the limited release operation that only stores 0. */
|
||||
enum insn_code icode = direct_optab_handler (sync_lock_release_optab, Pmode);
|
||||
if (icode != CODE_FOR_nothing
|
||||
&& insn_data[icode].operand[1].predicate (treg, Pmode)
|
||||
&& (insn = GEN_FCN (icode) (tmem0, treg)) != NULL_RTX)
|
||||
emit_insn (insn);
|
||||
else
|
||||
emit_move_insn (tmem0, treg);
|
||||
|
||||
/* The memory barrier inserted above should not prevent
|
||||
the load of flags from being moved before the stores,
|
||||
but in practice it does because it is implemented with
|
||||
unspec_volatile. In-order RISC machines should
|
||||
explicitly load flags earlier. */
|
||||
|
||||
tree flags = cilk_dot (fptr, CILK_TI_FRAME_FLAGS, 0);
|
||||
expand_expr (build2 (MODIFY_EXPR, void_type_node, flags,
|
||||
build2 (BIT_IOR_EXPR, TREE_TYPE (flags), flags,
|
||||
build_int_cst (TREE_TYPE (flags),
|
||||
CILK_FRAME_DETACHED))),
|
||||
const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
}
|
||||
|
||||
/* Returns a setjmp CALL_EXPR with FRAME->context as its parameter. */
|
||||
|
||||
tree
|
||||
cilk_call_setjmp (tree frame)
|
||||
{
|
||||
tree c = cilk_dot (frame, CILK_TI_FRAME_CONTEXT, false);
|
||||
c = build1 (ADDR_EXPR, build_pointer_type (ptr_type_node), c);
|
||||
return build_call_expr (builtin_decl_implicit (BUILT_IN_SETJMP), 1, c);
|
||||
}
|
||||
|
||||
/* This function will expand the _Cilk_sync keyword. */
|
||||
|
||||
static tree
|
||||
expand_cilk_sync (void)
|
||||
{
|
||||
tree frame = cfun->cilk_frame_decl;
|
||||
|
||||
/* Cilk_sync is converted to the following code:
|
||||
|
||||
sf.pedigree = sf.worker->pedigree;
|
||||
if (frame.flags & CILK_FRAME_UNSYNCHED)
|
||||
{
|
||||
__cilkrts_save_fp_state (&sf);
|
||||
if (!builtin_setjmp (sf.ctx)
|
||||
__cilkrts_sync (&sf);
|
||||
else
|
||||
if (sf.flags & CILK_FRAME_EXCEPTING)
|
||||
__cilkrts_rethrow (&sf);
|
||||
}
|
||||
sf.worker->pedigree.rank = sf.worker->pedigree.rank + 1; */
|
||||
|
||||
tree flags = cilk_dot (frame, CILK_TI_FRAME_FLAGS, false);
|
||||
|
||||
tree unsynched = fold_build2 (BIT_AND_EXPR, TREE_TYPE (flags), flags,
|
||||
build_int_cst (TREE_TYPE (flags),
|
||||
CILK_FRAME_UNSYNCHED));
|
||||
|
||||
unsynched = fold_build2 (NE_EXPR, TREE_TYPE (unsynched), unsynched,
|
||||
build_int_cst (TREE_TYPE (unsynched), 0));
|
||||
|
||||
tree frame_addr = build1 (ADDR_EXPR, cilk_frame_ptr_type_decl, frame);
|
||||
|
||||
/* Check if exception (0x10) bit is set in the sf->flags. */
|
||||
tree except_flag = fold_build2 (BIT_AND_EXPR, TREE_TYPE (flags), flags,
|
||||
build_int_cst (TREE_TYPE (flags),
|
||||
CILK_FRAME_EXCEPTING));
|
||||
except_flag = fold_build2 (NE_EXPR, TREE_TYPE (except_flag), except_flag,
|
||||
build_int_cst (TREE_TYPE (except_flag), 0));
|
||||
|
||||
/* If the exception flag is set then call the __cilkrts_rethrow (&sf). */
|
||||
tree except_cond = fold_build3 (COND_EXPR, void_type_node, except_flag,
|
||||
build_call_expr (cilk_rethrow_fndecl, 1,
|
||||
frame_addr),
|
||||
build_empty_stmt (EXPR_LOCATION (unsynched)));
|
||||
|
||||
tree sync_expr = build_call_expr (cilk_sync_fndecl, 1, frame_addr);
|
||||
tree setjmp_expr = cilk_call_setjmp (frame);
|
||||
setjmp_expr = fold_build2 (EQ_EXPR, TREE_TYPE (setjmp_expr), setjmp_expr,
|
||||
build_int_cst (TREE_TYPE (setjmp_expr), 0));
|
||||
|
||||
setjmp_expr = fold_build3 (COND_EXPR, void_type_node, setjmp_expr,
|
||||
sync_expr, except_cond);
|
||||
tree sync_list = alloc_stmt_list ();
|
||||
append_to_statement_list (build_call_expr (cilk_save_fp_fndecl, 1,
|
||||
frame_addr), &sync_list);
|
||||
append_to_statement_list (setjmp_expr, &sync_list);
|
||||
tree sync = fold_build3 (COND_EXPR, void_type_node, unsynched, sync_list,
|
||||
build_empty_stmt (EXPR_LOCATION (unsynched)));
|
||||
tree parent_pedigree = cilk_dot (frame, CILK_TI_FRAME_PEDIGREE, false);
|
||||
tree worker = cilk_dot (frame, CILK_TI_FRAME_WORKER, false);
|
||||
tree worker_pedigree = cilk_arrow (worker, CILK_TI_WORKER_PEDIGREE, false);
|
||||
tree assign_pedigree = fold_build2 (MODIFY_EXPR, void_type_node,
|
||||
parent_pedigree, worker_pedigree);
|
||||
tree w_ped_rank = cilk_dot (unshare_expr (worker_pedigree),
|
||||
CILK_TI_PEDIGREE_RANK, false);
|
||||
tree incr_ped_rank = fold_build2 (PLUS_EXPR, TREE_TYPE (w_ped_rank),
|
||||
w_ped_rank,
|
||||
build_one_cst (TREE_TYPE (w_ped_rank)));
|
||||
incr_ped_rank = fold_build2 (MODIFY_EXPR, void_type_node, w_ped_rank,
|
||||
incr_ped_rank);
|
||||
tree ret_sync_exp = alloc_stmt_list ();
|
||||
append_to_statement_list (assign_pedigree, &ret_sync_exp);
|
||||
append_to_statement_list (sync, &ret_sync_exp);
|
||||
append_to_statement_list (incr_ped_rank, &ret_sync_exp);
|
||||
return ret_sync_exp;
|
||||
}
|
||||
|
||||
/* Gimplifies the cilk_sync expression passed in *EXPR_P. Returns GS_ALL_DONE
|
||||
when finished. */
|
||||
|
||||
void
|
||||
gimplify_cilk_sync (tree *expr_p, gimple_seq *pre_p)
|
||||
{
|
||||
tree sync_expr = expand_cilk_sync ();
|
||||
*expr_p = NULL_TREE;
|
||||
gimplify_and_add (sync_expr, pre_p);
|
||||
}
|
102
gcc/cilk.h
Normal file
102
gcc/cilk.h
Normal file
@ -0,0 +1,102 @@
|
||||
/* This file is part of the Intel(R) Cilk(TM) Plus support
|
||||
This file contains Cilk Support files.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
Contributed by Balaji V. Iyer <balaji.v.iyer@intel.com>,
|
||||
Intel Corporation
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_CILK_H
|
||||
#define GCC_CILK_H
|
||||
|
||||
/* Frame status bits known to compiler. */
|
||||
#define CILK_FRAME_UNSYNCHED 0x02
|
||||
#define CILK_FRAME_DETACHED 0x04
|
||||
#define CILK_FRAME_EXCEPTING 0x10
|
||||
#define CILK_FRAME_VERSION (1 << 24)
|
||||
|
||||
enum cilk_tree_index {
|
||||
/* All the built-in functions for Cilk keywords. */
|
||||
CILK_TI_F_WORKER = 0, /* __cilkrts_get_worker (). */
|
||||
CILK_TI_F_SYNC, /* __cilkrts_sync (). */
|
||||
CILK_TI_F_DETACH, /* __cilkrts_detach (...). */
|
||||
CILK_TI_F_ENTER, /* __cilkrts_enter_frame (...). */
|
||||
CILK_TI_F_ENTER_FAST, /* __cilkrts_enter_frame_fast (.). */
|
||||
CILK_TI_F_LEAVE, /* __cilkrts_leave_frame (...). */
|
||||
CILK_TI_F_POP, /* __cilkrts_pop_frame (...). */
|
||||
CILK_TI_F_RETHROW, /* __cilkrts_rethrow (...). */
|
||||
CILK_TI_F_SAVE_FP, /* __cilkrts_save_fp_ctrl_state (...). */
|
||||
/* __cilkrts_stack_frame struct fields. */
|
||||
CILK_TI_FRAME_FLAGS, /* stack_frame->flags. */
|
||||
CILK_TI_FRAME_PARENT, /* stack_frame->parent. */
|
||||
CILK_TI_FRAME_WORKER, /* stack_frame->worker. */
|
||||
CILK_TI_FRAME_EXCEPTION, /* stack_frame->except_data. */
|
||||
CILK_TI_FRAME_CONTEXT, /* stack_frame->context[4]. */
|
||||
CILK_TI_FRAME_PEDIGREE, /* stack_frame->pedigree. */
|
||||
|
||||
/* __cilkrts_worker struct fields. */
|
||||
CILK_TI_WORKER_CUR, /* worker->current_stack_frame. */
|
||||
CILK_TI_WORKER_TAIL, /* worker->tail. */
|
||||
CILK_TI_WORKER_PEDIGREE, /* worker->pedigree. */
|
||||
|
||||
/* __cilkrts_pedigree struct fields. */
|
||||
CILK_TI_PEDIGREE_RANK, /* pedigree->rank. */
|
||||
CILK_TI_PEDIGREE_PARENT, /* pedigree->parent. */
|
||||
|
||||
/* Types. */
|
||||
CILK_TI_FRAME_TYPE, /* struct __cilkrts_stack_frame. */
|
||||
CILK_TI_FRAME_PTR, /* __cilkrts_stack_frame *. */
|
||||
CILK_TI_WORKER_TYPE, /* struct __cilkrts_worker. */
|
||||
CILK_TI_PEDIGREE_TYPE, /* struct __cilkrts_pedigree. */
|
||||
CILK_TI_MAX
|
||||
};
|
||||
|
||||
extern GTY (()) tree cilk_trees[CILK_TI_MAX];
|
||||
|
||||
#define cilk_worker_fndecl cilk_trees[CILK_TI_F_WORKER]
|
||||
#define cilk_sync_fndecl cilk_trees[CILK_TI_F_SYNC]
|
||||
#define cilk_synched_fndecl cilk_trees[CILK_TI_F_SYNCED]
|
||||
#define cilk_detach_fndecl cilk_trees[CILK_TI_F_DETACH]
|
||||
#define cilk_enter_fndecl cilk_trees[CILK_TI_F_ENTER]
|
||||
#define cilk_enter_fast_fndecl cilk_trees[CILK_TI_F_ENTER_FAST]
|
||||
#define cilk_leave_fndecl cilk_trees[CILK_TI_F_LEAVE]
|
||||
#define cilk_rethrow_fndecl cilk_trees[CILK_TI_F_RETHROW]
|
||||
#define cilk_pop_fndecl cilk_trees[CILK_TI_F_POP]
|
||||
#define cilk_save_fp_fndecl cilk_trees[CILK_TI_F_SAVE_FP]
|
||||
|
||||
#define cilk_worker_type_fndecl cilk_trees[CILK_TI_WORKER_TYPE]
|
||||
#define cilk_frame_type_decl cilk_trees[CILK_TI_FRAME_TYPE]
|
||||
#define cilk_frame_ptr_type_decl cilk_trees[CILK_TI_FRAME_PTR]
|
||||
#define cilk_pedigree_type_decl cilk_trees[CILK_TI_PEDIGREE_TYPE]
|
||||
|
||||
extern void expand_builtin_cilk_detach (tree);
|
||||
extern void expand_builtin_cilk_pop_frame (tree);
|
||||
extern tree cilk_arrow (tree, int, bool);
|
||||
extern tree cilk_dot (tree, int, bool);
|
||||
extern void cilk_init_builtins (void);
|
||||
extern void gimplify_cilk_sync (tree *, gimple_seq *);
|
||||
extern tree cilk_call_setjmp (tree);
|
||||
/* Returns true if Cilk Plus is enabled and if F->cilk_frame_decl is not
|
||||
NULL_TREE. */
|
||||
|
||||
inline bool
|
||||
fn_contains_cilk_spawn_p (function *f)
|
||||
{
|
||||
return (flag_enable_cilkplus
|
||||
&& (f->calls_cilk_spawn || f->cilk_frame_decl != NULL_TREE));
|
||||
}
|
||||
#endif
|
@ -105,6 +105,8 @@ define_builtin_macros_for_compilation_flags (cpp_reader *pfile)
|
||||
|
||||
cpp_define_formatted (pfile, "__FINITE_MATH_ONLY__=%d",
|
||||
flag_finite_math_only);
|
||||
if (flag_enable_cilkplus)
|
||||
cpp_define (pfile, "__cilk=200");
|
||||
}
|
||||
|
||||
|
||||
|
@ -3166,6 +3166,30 @@ several statements chained together.
|
||||
Used to represent a @code{break} statement. There are no additional
|
||||
fields.
|
||||
|
||||
@item CILK_SPAWN_STMT
|
||||
|
||||
Used to represent a spawning function in the Cilk Plus language extension.
|
||||
This tree has one field that holds the name of the spawning function.
|
||||
@code{_Cilk_spawn} can be written in C in the following way:
|
||||
|
||||
@smallexample
|
||||
@code{_Cilk_spawn} <function_name> (<parameters>);
|
||||
@end smallexample
|
||||
|
||||
Detailed description for usage and functionality of @code{_Cilk_spawn} can be
|
||||
found at http://www.cilkplus.org
|
||||
|
||||
@item CILK_SYNC_STMT
|
||||
|
||||
This statement is part of the Cilk Plus language extension. It indicates that
|
||||
the current function cannot continue in parallel with its spawned children.
|
||||
There are no additional fields. @code{_Cilk_sync} can be written in C in the
|
||||
following way:
|
||||
|
||||
@smallexample
|
||||
@code{_Cilk_sync};
|
||||
@end smallexample
|
||||
|
||||
@item CLEANUP_STMT
|
||||
|
||||
Used to represent an action that should take place upon exit from the
|
||||
|
@ -124,13 +124,45 @@ true, then we expand them using either @code{expand_array_notation_exprs} or
|
||||
inside conditions, they are transformed using the function
|
||||
@code{fix_conditional_array_notations}. The C language-specific routines are
|
||||
located in @file{c/c-array-notation.c} and the equivalent C++ routines are in
|
||||
file @file{cp/cp-array-notation.c}. Common routines such as functions to
|
||||
initialize builtin functions are stored in @file{array-notation-common.c}.
|
||||
the file @file{cp/cp-array-notation.c}. Common routines such as functions to
|
||||
initialize built-in functions are stored in @file{array-notation-common.c}.
|
||||
|
||||
@item Cilk keywords:
|
||||
@itemize @bullet
|
||||
@item @code{_Cilk_spawn}:
|
||||
The @code{_Cilk_spawn} keyword is parsed and the function it contains is marked
|
||||
as a spawning function. The spawning function is called the spawner. At
|
||||
the end of the parsing phase, appropriate built-in functions are
|
||||
added to the spawner that are defined in the Cilk runtime. The appropriate
|
||||
locations of these functions, and the internal structures are detailed in
|
||||
@code{cilk_init_builtins} in the file @file{cilk-common.c}. The pointers to
|
||||
Cilk functions and fields of internal structures are described
|
||||
in @file{cilk.h}. The built-in functions are described in
|
||||
@file{cilk-builtins.def}.
|
||||
|
||||
During gimplification, a new "spawn-helper" function is created.
|
||||
The spawned function is replaced with a spawn helper function in the spawner.
|
||||
The spawned function-call is moved into the spawn helper. The main function
|
||||
that does these transformations is @code{gimplify_cilk_spawn} in
|
||||
@file{c-family/cilk.c}. In the spawn-helper, the gimplification function
|
||||
@code{gimplify_call_expr}, inserts a function call @code{__cilkrts_detach}.
|
||||
This function is expanded by @code{builtin_expand_cilk_detach} located in
|
||||
@file{c-family/cilk.c}.
|
||||
|
||||
@item @code{_Cilk_sync}:
|
||||
@code{_Cilk_sync} is parsed like a keyword. During gimplification,
|
||||
the function @code{gimplify_cilk_sync} in @file{c-family/cilk.c}, will replace
|
||||
this keyword with a set of functions that are stored in the Cilk runtime.
|
||||
One of the internal functions inserted during gimplification,
|
||||
@code{__cilkrts_pop_frame} must be expanded by the compiler and is
|
||||
done by @code{builtin_expand_cilk_pop_frame} in @file{cilk-common.c}.
|
||||
|
||||
@end itemize
|
||||
@end itemize
|
||||
|
||||
Detailed information about Cilk Plus and language specification is provided in
|
||||
@w{@uref{http://www.cilkplus.org/}}. It is worth mentioning that the current
|
||||
implementation follows ABI 0.9.
|
||||
Documentation about Cilk Plus and language specification is provided under the
|
||||
"Learn" section in @w{@uref{http://www.cilkplus.org/}}. It is worth mentioning
|
||||
that the current implementation follows ABI 1.1.
|
||||
|
||||
@node Gimplification pass
|
||||
@section Gimplification pass
|
||||
|
@ -552,6 +552,9 @@ struct GTY(()) function {
|
||||
/* Vector of function local variables, functions, types and constants. */
|
||||
vec<tree, va_gc> *local_decls;
|
||||
|
||||
/* In a Cilk function, the VAR_DECL for the frame descriptor. */
|
||||
tree cilk_frame_decl;
|
||||
|
||||
/* For md files. */
|
||||
|
||||
/* tm.h can use this to store whatever it likes. */
|
||||
@ -607,6 +610,12 @@ struct GTY(()) function {
|
||||
either as a subroutine or builtin. */
|
||||
unsigned int calls_alloca : 1;
|
||||
|
||||
/* This will indicate whether a function is a cilk function */
|
||||
unsigned int is_cilk_function : 1;
|
||||
|
||||
/* Nonzero if this is a Cilk function that spawns. */
|
||||
unsigned int calls_cilk_spawn : 1;
|
||||
|
||||
/* Nonzero if function being compiled receives nonlocal gotos
|
||||
from nested functions. */
|
||||
unsigned int has_nonlocal_label : 1;
|
||||
|
@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "vec.h"
|
||||
#include "omp-low.h"
|
||||
#include "gimple-low.h"
|
||||
#include "cilk.h"
|
||||
|
||||
#include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */
|
||||
#include "tree-pass.h" /* FIXME: only for PROP_gimple_any */
|
||||
@ -1309,6 +1310,15 @@ gimplify_return_expr (tree stmt, gimple_seq *pre_p)
|
||||
if (ret_expr == error_mark_node)
|
||||
return GS_ERROR;
|
||||
|
||||
/* Implicit _Cilk_sync must be inserted right before any return statement
|
||||
if there is a _Cilk_spawn in the function. If the user has provided a
|
||||
_Cilk_sync, the optimizer should remove this duplicate one. */
|
||||
if (fn_contains_cilk_spawn_p (cfun))
|
||||
{
|
||||
tree impl_sync = build0 (CILK_SYNC_STMT, void_type_node);
|
||||
gimplify_and_add (impl_sync, pre_p);
|
||||
}
|
||||
|
||||
if (!ret_expr
|
||||
|| TREE_CODE (ret_expr) == RESULT_DECL
|
||||
|| ret_expr == error_mark_node)
|
||||
@ -2498,6 +2508,12 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
|
||||
if (! EXPR_HAS_LOCATION (*expr_p))
|
||||
SET_EXPR_LOCATION (*expr_p, input_location);
|
||||
|
||||
if (fn_contains_cilk_spawn_p (cfun)
|
||||
&& lang_hooks.cilkplus.cilk_detect_spawn_and_unwrap (expr_p)
|
||||
&& !seen_error ())
|
||||
return (enum gimplify_status)
|
||||
lang_hooks.cilkplus.gimplify_cilk_spawn (expr_p, pre_p, NULL);
|
||||
|
||||
/* This may be a call to a builtin function.
|
||||
|
||||
Builtin function calls may be transformed into different
|
||||
@ -4714,6 +4730,12 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
||||
|
||||
gcc_assert (TREE_CODE (*expr_p) == MODIFY_EXPR
|
||||
|| TREE_CODE (*expr_p) == INIT_EXPR);
|
||||
|
||||
if (fn_contains_cilk_spawn_p (cfun)
|
||||
&& lang_hooks.cilkplus.cilk_detect_spawn_and_unwrap (expr_p)
|
||||
&& !seen_error ())
|
||||
return (enum gimplify_status)
|
||||
lang_hooks.cilkplus.gimplify_cilk_spawn (expr_p, pre_p, post_p);
|
||||
|
||||
/* Trying to simplify a clobber using normal logic doesn't work,
|
||||
so handle it here. */
|
||||
@ -7660,6 +7682,19 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
||||
}
|
||||
break;
|
||||
|
||||
case CILK_SPAWN_STMT:
|
||||
gcc_assert
|
||||
(fn_contains_cilk_spawn_p (cfun)
|
||||
&& lang_hooks.cilkplus.cilk_detect_spawn_and_unwrap (expr_p));
|
||||
if (!seen_error ())
|
||||
{
|
||||
ret = (enum gimplify_status)
|
||||
lang_hooks.cilkplus.gimplify_cilk_spawn (expr_p, pre_p,
|
||||
post_p);
|
||||
break;
|
||||
}
|
||||
/* If errors are seen, then just process it as a CALL_EXPR. */
|
||||
|
||||
case CALL_EXPR:
|
||||
ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
|
||||
|
||||
@ -8295,6 +8330,22 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|
||||
break;
|
||||
}
|
||||
|
||||
case CILK_SYNC_STMT:
|
||||
{
|
||||
if (!fn_contains_cilk_spawn_p (cfun))
|
||||
{
|
||||
error_at (EXPR_LOCATION (*expr_p),
|
||||
"expected %<_Cilk_spawn%> before %<_Cilk_sync%>");
|
||||
ret = GS_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
gimplify_cilk_sync (expr_p, pre_p);
|
||||
ret = GS_ALL_DONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
|
||||
{
|
||||
|
@ -95,6 +95,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "cfgloop.h"
|
||||
#include "tree-scalar-evolution.h"
|
||||
#include "ipa-utils.h"
|
||||
#include "cilk.h"
|
||||
|
||||
/* Estimate runtime of function can easilly run into huge numbers with many
|
||||
nested loops. Be sure we can compute time * INLINE_SIZE_SCALE * 2 in an
|
||||
@ -1440,6 +1441,9 @@ initialize_inline_failed (struct cgraph_edge *e)
|
||||
e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
|
||||
else if (e->call_stmt_cannot_inline_p)
|
||||
e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
|
||||
else if (cfun && fn_contains_cilk_spawn_p (cfun))
|
||||
/* We can't inline if the function is spawing a function. */
|
||||
e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
|
||||
else
|
||||
e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
|
||||
}
|
||||
|
@ -115,6 +115,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "ipa-inline.h"
|
||||
#include "ipa-utils.h"
|
||||
#include "sreal.h"
|
||||
#include "cilk.h"
|
||||
|
||||
/* Statistics we collect about inlining algorithm. */
|
||||
static int overall_size;
|
||||
@ -264,7 +265,8 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
|
||||
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
|
||||
inlinable = false;
|
||||
}
|
||||
else if (!inline_summary (callee)->inlinable)
|
||||
else if (!inline_summary (callee)->inlinable
|
||||
|| (caller_cfun && fn_contains_cilk_spawn_p (caller_cfun)))
|
||||
{
|
||||
e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
|
||||
inlinable = false;
|
||||
|
@ -1874,6 +1874,9 @@ ira_setup_eliminable_regset (bool from_ira_p)
|
||||
|| (flag_stack_check && STACK_CHECK_MOVING_SP)
|
||||
|| crtl->accesses_prior_frames
|
||||
|| crtl->stack_realign_needed
|
||||
/* We need a frame pointer for all Cilk Plus functions that use
|
||||
Cilk keywords. */
|
||||
|| (flag_enable_cilkplus && cfun->is_cilk_function)
|
||||
|| targetm.frame_pointer_required ());
|
||||
|
||||
if (from_ira_p && ira_use_lra_p)
|
||||
|
@ -214,6 +214,18 @@ extern tree lhd_make_node (enum tree_code);
|
||||
#define LANG_HOOKS_OMP_CLAUSE_DTOR hook_tree_tree_tree_null
|
||||
#define LANG_HOOKS_OMP_FINISH_CLAUSE hook_void_tree
|
||||
|
||||
extern void lhd_install_body_with_frame_cleanup (tree, tree);
|
||||
extern bool lhd_cilk_detect_spawn (tree *);
|
||||
#define LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP lhd_cilk_detect_spawn
|
||||
#define LANG_HOOKS_CILKPLUS_FRAME_CLEANUP lhd_install_body_with_frame_cleanup
|
||||
#define LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN lhd_gimplify_expr
|
||||
|
||||
#define LANG_HOOKS_CILKPLUS { \
|
||||
LANG_HOOKS_CILKPLUS_DETECT_SPAWN_AND_UNWRAP, \
|
||||
LANG_HOOKS_CILKPLUS_FRAME_CLEANUP, \
|
||||
LANG_HOOKS_CILKPLUS_GIMPLIFY_SPAWN \
|
||||
}
|
||||
|
||||
#define LANG_HOOKS_DECLS { \
|
||||
LANG_HOOKS_GLOBAL_BINDINGS_P, \
|
||||
LANG_HOOKS_PUSHDECL, \
|
||||
@ -291,6 +303,7 @@ extern void lhd_end_section (void);
|
||||
LANG_HOOKS_TREE_DUMP_INITIALIZER, \
|
||||
LANG_HOOKS_DECLS, \
|
||||
LANG_HOOKS_FOR_TYPES_INITIALIZER, \
|
||||
LANG_HOOKS_CILKPLUS, \
|
||||
LANG_HOOKS_LTO, \
|
||||
LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS, \
|
||||
LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS, \
|
||||
|
@ -675,3 +675,18 @@ lhd_end_section (void)
|
||||
saved_section = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Empty function that is replaced with appropriate language dependent
|
||||
frame cleanup function for _Cilk_spawn. */
|
||||
|
||||
void
|
||||
lhd_install_body_with_frame_cleanup (tree, tree)
|
||||
{
|
||||
}
|
||||
|
||||
/* Empty function to handle cilk_valid_spawn. */
|
||||
bool
|
||||
lhd_cilk_detect_spawn (tree *)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -139,6 +139,23 @@ struct lang_hooks_for_types
|
||||
tree (*reconstruct_complex_type) (tree, tree);
|
||||
};
|
||||
|
||||
/* Language hooks related to Cilk Plus. */
|
||||
|
||||
struct lang_hooks_for_cilkplus
|
||||
{
|
||||
/* Returns true if the expression passed in has a spawned function call. */
|
||||
bool (*cilk_detect_spawn_and_unwrap) (tree *);
|
||||
|
||||
/* Function to add the clean up functions after spawn. The reason why it is
|
||||
language dependent is because in C++, it must handle exceptions. */
|
||||
void (*install_body_with_frame_cleanup) (tree, tree);
|
||||
|
||||
/* Function to gimplify a spawned function call. Returns enum gimplify
|
||||
status, but as mentioned in a previous comment, we can't see that type
|
||||
here, so just return an int. */
|
||||
int (*gimplify_cilk_spawn) (tree *, gimple_seq *, gimple_seq *);
|
||||
};
|
||||
|
||||
/* Language hooks related to decls and the symbol table. */
|
||||
|
||||
struct lang_hooks_for_decls
|
||||
@ -408,6 +425,8 @@ struct lang_hooks
|
||||
|
||||
struct lang_hooks_for_types types;
|
||||
|
||||
struct lang_hooks_for_cilkplus cilkplus;
|
||||
|
||||
struct lang_hooks_for_lto lto;
|
||||
|
||||
/* Returns a TREE_VEC of the generic parameters of an instantiation of
|
||||
|
@ -1,3 +1,9 @@
|
||||
2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* Make-lang.in (lto/lto-lang.o): Added cilk.h in dependency list.
|
||||
* lto-lang.c (lto_init): Added a call to cilk_init_builtins if Cilk
|
||||
Plus is enabled.
|
||||
|
||||
2013-10-29 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
Patch autogenerated by refactor_symtab.py from
|
||||
|
@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "diagnostic-core.h"
|
||||
#include "toplev.h"
|
||||
#include "lto-streamer.h"
|
||||
#include "cilk.h"
|
||||
|
||||
static tree lto_type_for_size (unsigned, int);
|
||||
|
||||
@ -1174,6 +1175,9 @@ lto_init (void)
|
||||
lto_define_builtins (va_list_type_node,
|
||||
build_reference_type (va_list_type_node));
|
||||
}
|
||||
|
||||
if (flag_enable_cilkplus)
|
||||
cilk_init_builtins ();
|
||||
|
||||
targetm.init_builtins ();
|
||||
build_common_builtin_nodes ();
|
||||
|
@ -1,3 +1,25 @@
|
||||
2013-10-29 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* c-c++-common/cilk-plus/CK/compound_cilk_spawn.c: New test.
|
||||
* c-c++-common/cilk-plus/CK/concec_cilk_spawn.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/fib.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/no_args_error.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/spawnee_inline.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/spawner_inline.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/spawning_arg.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/steal_check.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/test__cilk.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/varargs_test.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/sync_wo_spawn.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/invalid_spawn.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/spawn_in_return.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/fib_init_expr_xy.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/fib_no_sync.c: Likewise.
|
||||
* c-c++-common/cilk-plus/CK/fib_no_return.c: Likewise.
|
||||
* gcc.dg/cilk-plus/cilk-plus.exp: Added support to run Cilk Keywords
|
||||
test stored in c-c++-common. Also, added the Cilk runtime's library
|
||||
to the ld_library_path.
|
||||
|
||||
2013-10-29 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/58888
|
||||
|
@ -0,0 +1,26 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
|
||||
/* <feature>
|
||||
A program is considered ill formed if the _Cilk_spawn form of this
|
||||
expression appears other than in one of the following contexts:
|
||||
as the entire body of an expression statement,
|
||||
as the entire right hand side of an assignment expression that is the entire
|
||||
body of an expression statement, or as the entire initializer-clause in a
|
||||
simple declaration.
|
||||
</feature>
|
||||
*/
|
||||
|
||||
int spawn_func (int arg)
|
||||
{
|
||||
return arg + 1;
|
||||
}
|
||||
|
||||
int check()
|
||||
{
|
||||
int z;
|
||||
z = 23, _Cilk_spawn spawn_func (3), 3424; /* { dg-error "spawned function call cannot be part of a comma expression" } */
|
||||
23, spawn_func (5), _Cilk_spawn spawn_func (3); /* { dg-error "spawned function call cannot be part of a comma expression" } */
|
||||
_Cilk_spawn spawn_func (0), _Cilk_spawn spawn_func (3), 3, spawn_func (0); /* { dg-error "spawned function call cannot be part of a comma expression" } */
|
||||
return 23;
|
||||
}
|
20
gcc/testsuite/c-c++-common/cilk-plus/CK/concec_cilk_spawn.c
Normal file
20
gcc/testsuite/c-c++-common/cilk-plus/CK/concec_cilk_spawn.c
Normal file
@ -0,0 +1,20 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
|
||||
/* <feature> Consecutive _Cilk_spawn tokens are not permitted
|
||||
</feature>
|
||||
*/
|
||||
|
||||
int spawn_func (int arg)
|
||||
{
|
||||
return arg + 1;
|
||||
}
|
||||
|
||||
void func ()
|
||||
{
|
||||
int a;
|
||||
a = _Cilk_spawn _Cilk_spawn spawn_func (4); /* { dg-error "consecutive" } */
|
||||
a = _Cilk_spawn _Cilk_spawn _Cilk_spawn spawn_func (4); /* { dg-error "consecutive" } */
|
||||
a = _Cilk_spawn _Cilk_spawn _Cilk_spawn _Cilk_spawn spawn_func (4); /* { dg-error "consecutive" } */
|
||||
return;
|
||||
}
|
61
gcc/testsuite/c-c++-common/cilk-plus/CK/fib.c
Normal file
61
gcc/testsuite/c-c++-common/cilk-plus/CK/fib.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
|
||||
/* { dg-options "-fcilkplus -lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
|
||||
|
||||
#if HAVE_IO
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
int fib (int);
|
||||
int fib_serial (int);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ii = 0, error = 0;
|
||||
int fib_result[41], fib_serial_result[41];
|
||||
#if HAVE_IO
|
||||
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
printf("fib (%2d) = %10d\n", ii, fib (ii));
|
||||
#else
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
{
|
||||
fib_result[ii] = fib (ii);
|
||||
fib_serial_result[ii] = fib_serial (ii);
|
||||
}
|
||||
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
{
|
||||
if (fib_result[ii] != fib_serial_result[ii])
|
||||
error = 1;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
int fib_serial (int n)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
x = fib (n-1);
|
||||
y = fib (n-2);
|
||||
return (x+y);
|
||||
}
|
||||
}
|
||||
|
||||
int fib(int n)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
x = _Cilk_spawn fib(n-1);
|
||||
y = fib(n-2);
|
||||
_Cilk_sync;
|
||||
return (x+y);
|
||||
}
|
||||
}
|
60
gcc/testsuite/c-c++-common/cilk-plus/CK/fib_init_expr_xy.c
Normal file
60
gcc/testsuite/c-c++-common/cilk-plus/CK/fib_init_expr_xy.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
|
||||
/* { dg-options "-fcilkplus -lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
|
||||
|
||||
#if HAVE_IO
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
int fib (int);
|
||||
int fib_serial (int);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ii = 0, error = 0;
|
||||
int fib_result[41], fib_serial_result[41];
|
||||
#if HAVE_IO
|
||||
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
printf("fib (%2d) = %10d\n", ii, fib (ii));
|
||||
#else
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
{
|
||||
fib_result[ii] = fib (ii);
|
||||
fib_serial_result[ii] = fib_serial (ii);
|
||||
}
|
||||
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
{
|
||||
if (fib_result[ii] != fib_serial_result[ii])
|
||||
error = 1;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
int fib_serial (int n)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
x = fib (n-1);
|
||||
y = fib (n-2);
|
||||
return (x+y);
|
||||
}
|
||||
}
|
||||
|
||||
int fib(int n)
|
||||
{
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
int x = _Cilk_spawn fib(n-1);
|
||||
int y = fib(n-2);
|
||||
_Cilk_sync;
|
||||
return (x+y);
|
||||
}
|
||||
}
|
65
gcc/testsuite/c-c++-common/cilk-plus/CK/fib_no_return.c
Normal file
65
gcc/testsuite/c-c++-common/cilk-plus/CK/fib_no_return.c
Normal file
@ -0,0 +1,65 @@
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
|
||||
/* { dg-options "-fcilkplus -lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
|
||||
|
||||
#if HAVE_IO
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
void fib (int *, int);
|
||||
int fib_serial (int);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ii = 0, error = 0;
|
||||
int fib_result[41], fib_serial_result[41];
|
||||
|
||||
#if HAVE_IO
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
{
|
||||
int result = 0;
|
||||
fib (&result, ii);
|
||||
printf("fib (%2d) = %10d\n", ii, result);
|
||||
}
|
||||
#else
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
{
|
||||
fib (&fib_result[ii], ii);
|
||||
fib_serial_result[ii] = fib_serial (ii);
|
||||
}
|
||||
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
{
|
||||
if (fib_result[ii] != fib_serial_result[ii])
|
||||
error = 1;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
int fib_serial (int n)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
fib (&x, n-1);
|
||||
fib (&y, n-2);
|
||||
return (x+y);
|
||||
}
|
||||
}
|
||||
|
||||
void fib(int *result, int n)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
if (n < 2)
|
||||
x = n;
|
||||
else
|
||||
{
|
||||
_Cilk_spawn fib(&x, n-1);
|
||||
fib(&y, n-2);
|
||||
_Cilk_sync;
|
||||
}
|
||||
*result = (x+y);
|
||||
}
|
59
gcc/testsuite/c-c++-common/cilk-plus/CK/fib_no_sync.c
Normal file
59
gcc/testsuite/c-c++-common/cilk-plus/CK/fib_no_sync.c
Normal file
@ -0,0 +1,59 @@
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
|
||||
/* { dg-options "-fcilkplus -lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
|
||||
|
||||
#if HAVE_IO
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
int fib (int);
|
||||
int fib_serial (int);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ii = 0, error = 0;
|
||||
int fib_result[41], fib_serial_result[41];
|
||||
#if HAVE_IO
|
||||
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
printf("fib (%2d) = %10d\n", ii, fib (ii));
|
||||
#else
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
{
|
||||
fib_result[ii] = fib (ii);
|
||||
fib_serial_result[ii] = fib_serial (ii);
|
||||
}
|
||||
|
||||
for (ii = 0; ii <= 40; ii++)
|
||||
{
|
||||
if (fib_result[ii] != fib_serial_result[ii])
|
||||
error = 1;
|
||||
}
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
int fib_serial (int n)
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
x = fib (n-1);
|
||||
y = fib (n-2);
|
||||
return (x+y);
|
||||
}
|
||||
}
|
||||
|
||||
int fib(int n)
|
||||
{
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
int x = _Cilk_spawn fib(n-1);
|
||||
int y = fib(n-2);
|
||||
return (x+y);
|
||||
}
|
||||
}
|
11
gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c
Normal file
11
gcc/testsuite/c-c++-common/cilk-plus/CK/invalid_spawns.c
Normal file
@ -0,0 +1,11 @@
|
||||
extern int foo ();
|
||||
int bar = _Cilk_spawn foo (); /* { dg-error "may only be used inside a function" } */
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int x;
|
||||
|
||||
_Cilk_spawn x; /* { dg-error "only function calls can be spawned" } */
|
||||
return x;
|
||||
}
|
11
gcc/testsuite/c-c++-common/cilk-plus/CK/no_args_error.c
Normal file
11
gcc/testsuite/c-c++-common/cilk-plus/CK/no_args_error.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
|
||||
int spawn_1 ();
|
||||
typedef int(*func) (int);
|
||||
|
||||
void check () {
|
||||
func var = spawn_1; /* { dg-error "invalid conversion from" "" { target c++ } 8 } */
|
||||
_Cilk_spawn var (); /* { dg-error "too few arguments to function" } */
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
|
||||
int main (void)
|
||||
{
|
||||
extern int foo ();
|
||||
return _Cilk_spawn foo (); /* { dg-error "return statement is not allowed" } */
|
||||
}
|
80
gcc/testsuite/c-c++-common/cilk-plus/CK/spawnee_inline.c
Normal file
80
gcc/testsuite/c-c++-common/cilk-plus/CK/spawnee_inline.c
Normal file
@ -0,0 +1,80 @@
|
||||
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
|
||||
/* { dg-options "-fcilkplus -w" } */
|
||||
/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#define DEFAULT_VALUE "30"
|
||||
|
||||
int fib (char *n_char)
|
||||
{
|
||||
int n;
|
||||
char n_char_minus_one[20], n_char_minus_two[20];
|
||||
if (n_char)
|
||||
n = atoi (n_char);
|
||||
else
|
||||
n = atoi(DEFAULT_VALUE);
|
||||
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
int x, y;
|
||||
sprintf (n_char_minus_one,"%d", n-1);
|
||||
sprintf (n_char_minus_two,"%d", n-2);
|
||||
x = _Cilk_spawn fib (n_char_minus_one);
|
||||
y = _Cilk_spawn fib (n_char_minus_two);
|
||||
_Cilk_sync;
|
||||
return (x+y);
|
||||
}
|
||||
}
|
||||
|
||||
int fib_serial (int n)
|
||||
{
|
||||
int x, y;
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
x = fib_serial (n-1);
|
||||
y = fib_serial (n-2);
|
||||
return (x+y);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main2_parallel (int argc, char *argv[])
|
||||
{
|
||||
int n, result_parallel = 0;
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
result_parallel = _Cilk_spawn fib (argv[1]);
|
||||
_Cilk_sync;
|
||||
}
|
||||
else
|
||||
{
|
||||
result_parallel = _Cilk_spawn fib((char *)"30");
|
||||
_Cilk_sync;
|
||||
}
|
||||
return result_parallel;
|
||||
}
|
||||
|
||||
int main2_serial (int argc, char *argv[])
|
||||
{
|
||||
int n, result_serial = 0;
|
||||
if (argc == 2)
|
||||
result_serial = fib_serial (atoi (argv[1]));
|
||||
else
|
||||
result_serial = fib_serial (atoi (DEFAULT_VALUE));
|
||||
|
||||
return result_serial;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
if (main2_serial (1, 0) != main2_parallel (1,0))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
67
gcc/testsuite/c-c++-common/cilk-plus/CK/spawner_inline.c
Normal file
67
gcc/testsuite/c-c++-common/cilk-plus/CK/spawner_inline.c
Normal file
@ -0,0 +1,67 @@
|
||||
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
|
||||
|
||||
#include <stdlib.h>
|
||||
#define DEFAULT_VALUE 30
|
||||
int fib (int n)
|
||||
{
|
||||
if (n<2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
int x, y;
|
||||
x = _Cilk_spawn fib (n-1);
|
||||
y = _Cilk_spawn fib (n-2);
|
||||
_Cilk_sync;
|
||||
return (x+y);
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
int main_parallel (int argc, char *argv[])
|
||||
{
|
||||
int n, result;
|
||||
if (argc == 2)
|
||||
n = atoi(argv[1]);
|
||||
else
|
||||
n = DEFAULT_VALUE;
|
||||
result = _Cilk_spawn fib(n);
|
||||
_Cilk_sync;
|
||||
return result;
|
||||
}
|
||||
|
||||
int fib_serial (int n)
|
||||
{
|
||||
int x, y;
|
||||
if (n < 2)
|
||||
return n;
|
||||
else
|
||||
{
|
||||
x = fib (n-1);
|
||||
y = fib (n-2);
|
||||
return (x+y);
|
||||
}
|
||||
}
|
||||
|
||||
int main_serial (int argc, char *argv[])
|
||||
{
|
||||
int n, result;
|
||||
|
||||
if (argc == 2)
|
||||
n = atoi (argv[1]);
|
||||
else
|
||||
n = DEFAULT_VALUE;
|
||||
result = fib_serial (n);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
if (main_serial (1, 0) != main_parallel (1,0))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
37
gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c
Normal file
37
gcc/testsuite/c-c++-common/cilk-plus/CK/spawning_arg.c
Normal file
@ -0,0 +1,37 @@
|
||||
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
|
||||
|
||||
void f0(volatile int *steal_flag)
|
||||
{
|
||||
int i = 0;
|
||||
/* Wait for steal_flag to be set */
|
||||
while (!*steal_flag)
|
||||
;
|
||||
}
|
||||
|
||||
int f1()
|
||||
{
|
||||
|
||||
volatile int steal_flag = 0;
|
||||
_Cilk_spawn f0(&steal_flag);
|
||||
steal_flag = 1; // Indicate stolen
|
||||
_Cilk_sync;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void f2(int q)
|
||||
{
|
||||
q = 5;
|
||||
}
|
||||
|
||||
void f3()
|
||||
{
|
||||
_Cilk_spawn f2(f1());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
f3();
|
||||
return 0;
|
||||
}
|
43
gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c
Normal file
43
gcc/testsuite/c-c++-common/cilk-plus/CK/steal_check.c
Normal file
@ -0,0 +1,43 @@
|
||||
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
|
||||
|
||||
// #include <cilk/cilk_api.h>
|
||||
extern void __cilkrts_set_param (char *, char *);
|
||||
|
||||
void foo(volatile int *);
|
||||
|
||||
void main2(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// __cilkrts_set_param ((char *)"nworkers", (char *)"2");
|
||||
main2();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void main2(void)
|
||||
{
|
||||
int some_var = 0;
|
||||
|
||||
_Cilk_spawn foo(&some_var);
|
||||
|
||||
some_var=1;
|
||||
some_var=5;
|
||||
some_var=3;
|
||||
some_var=4;
|
||||
|
||||
_Cilk_sync;
|
||||
return;
|
||||
}
|
||||
|
||||
void foo(volatile int *some_other_var)
|
||||
{
|
||||
while (*some_other_var == 0)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
9
gcc/testsuite/c-c++-common/cilk-plus/CK/sync_wo_spawn.c
Normal file
9
gcc/testsuite/c-c++-common/cilk-plus/CK/sync_wo_spawn.c
Normal file
@ -0,0 +1,9 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
|
||||
int main (void)
|
||||
{
|
||||
_Cilk_sync; /* { dg-error "expected '_Cilk_spawn' before '_Cilk_sync'" } */
|
||||
return 0;
|
||||
}
|
||||
|
10
gcc/testsuite/c-c++-common/cilk-plus/CK/test__cilk.c
Normal file
10
gcc/testsuite/c-c++-common/cilk-plus/CK/test__cilk.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
|
||||
int main (void)
|
||||
{
|
||||
if (__cilk == 200)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
47
gcc/testsuite/c-c++-common/cilk-plus/CK/varargs_test.c
Normal file
47
gcc/testsuite/c-c++-common/cilk-plus/CK/varargs_test.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
|
||||
/* { dg-options "-fcilkplus" } */
|
||||
/* { dg-options "-lcilkrts" { target { i?86-*-* x86_64-*-* } } } */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
double compute_total (int no_elements, ...);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
double array[5] = {5.0, 4.0, 9.0, 3.0, 4.0};
|
||||
double array2[5] = {5.0, 6.0, 8.0, 6.0};
|
||||
double yy=0, xx=0, xx_serial, yy_serial;
|
||||
|
||||
yy = _Cilk_spawn compute_total(5,array[0],array[1],array[2],
|
||||
array[3], array[4]);
|
||||
xx= compute_total(4,array2[0],array2[1],array2[2], array2[3]);
|
||||
|
||||
_Cilk_sync;
|
||||
|
||||
yy_serial = compute_total(5,array[0],array[1],array[2], array[3], array[4]);
|
||||
xx_serial = compute_total(4,array2[0],array2[1],array2[2], array2[3]);
|
||||
|
||||
if ((xx + yy) != (xx_serial + yy_serial))
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
double compute_total (int no_elements, ...)
|
||||
{
|
||||
double total = 0;
|
||||
va_list args;
|
||||
va_start(args, no_elements);
|
||||
int ii = 0;
|
||||
for (ii = 0; ii < no_elements; ii++)
|
||||
{
|
||||
total += va_arg(args,double);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
@ -23,6 +23,11 @@ if { ![check_effective_target_cilkplus] } {
|
||||
return;
|
||||
}
|
||||
|
||||
verbose "$tool $libdir" 1
|
||||
set library_var [get_multilibs]
|
||||
# Pointing the ld_library_path to the Cilk Runtime library binaries.
|
||||
set ld_library_path "${library_var}/libcilkrts/.libs"
|
||||
|
||||
dg-init
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O0 -fcilkplus" " "
|
||||
@ -46,4 +51,31 @@ dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -f
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -g -O2 -ftree-vectorize -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -fcilkplus -g -O3 -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/AN/*.c]] " -O3 -ftree-vectorize -std=c99 -g -fcilkplus" " "
|
||||
|
||||
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O0 -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O1 -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -ftree-vectorize -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -O0 -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -O1 -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -O2 -ftree-vectorize -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -g -O3 -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -ftree-vectorize -fcilkplus -g" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -O0 -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -O1 -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -O2 -ftree-vectorize -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -O3 -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -g -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -g -O0 -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -g -O1 -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -g -O2 -ftree-vectorize -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -fcilkplus -g -O3 -std=c99" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -ftree-vectorize -std=c99 -g -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O0 -flto -g -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O2 -flto -g -fcilkplus" " "
|
||||
dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -flto -g -fcilkplus" " "
|
||||
dg-finish
|
||||
|
@ -131,6 +131,10 @@ typedef struct copy_body_data
|
||||
the originals have been mapped to a value rather than to a
|
||||
variable. */
|
||||
struct pointer_map_t *debug_map;
|
||||
|
||||
/* Cilk keywords currently need to replace some variables that
|
||||
ordinary nested functions do not. */
|
||||
bool remap_var_for_cilk;
|
||||
} copy_body_data;
|
||||
|
||||
/* Weights of constructions for estimate_num_insns. */
|
||||
|
@ -2644,6 +2644,15 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
|
||||
dump_block_node (buffer, node, spc, flags);
|
||||
break;
|
||||
|
||||
case CILK_SPAWN_STMT:
|
||||
pp_string (buffer, "_Cilk_spawn ");
|
||||
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
|
||||
break;
|
||||
|
||||
case CILK_SYNC_STMT:
|
||||
pp_string (buffer, "_Cilk_sync");
|
||||
break;
|
||||
|
||||
default:
|
||||
NIY;
|
||||
}
|
||||
|
@ -1271,6 +1271,12 @@ DEFTREECODE (TARGET_OPTION_NODE, "target_option_node", tcc_exceptional, 0)
|
||||
Operand 1 is the annotation id. */
|
||||
DEFTREECODE (ANNOTATE_EXPR, "annotate_expr", tcc_expression, 2)
|
||||
|
||||
/* Cilk spawn statement
|
||||
Operand 0 is the CALL_EXPR. */
|
||||
DEFTREECODE (CILK_SPAWN_STMT, "cilk_spawn_stmt", tcc_statement, 1)
|
||||
|
||||
/* Cilk Sync statement: Does not have any operands. */
|
||||
DEFTREECODE (CILK_SYNC_STMT, "cilk_sync_stmt", tcc_statement, 0)
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
|
@ -790,6 +790,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
|
||||
#define CALL_EXPR_RETURN_SLOT_OPT(NODE) \
|
||||
(CALL_EXPR_CHECK (NODE)->base.private_flag)
|
||||
|
||||
/* Cilk keywords accessors. */
|
||||
#define CILK_SPAWN_FN(NODE) TREE_OPERAND (CILK_SPAWN_STMT_CHECK (NODE), 0)
|
||||
|
||||
/* In a RESULT_DECL, PARM_DECL and VAR_DECL, means that it is
|
||||
passed by invisible reference (and the TREE_TYPE is a pointer to the true
|
||||
type). */
|
||||
|
Loading…
Reference in New Issue
Block a user