* [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997)
@ 2016-01-20 17:57 Ryan Burn
2016-02-10 18:00 ` Jeff Law
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Ryan Burn @ 2016-01-20 17:57 UTC (permalink / raw)
To: gcc-patches, Jason Merrill, Jeff Law, igor.zamyatin, Jakub Jelinek
[-- Attachment #1: Type: text/plain, Size: 1436 bytes --]
This patch follows on from
https://gcc.gnu.org/ml/gcc-patches/2015-12/msg02142.html
As discussed, it creates a separate function
cilk_cp_detect_spawn_and_unwrap in gcc/cp to handle processing
cilk_spawn expressions for c++ and adds support for implicit
constructor and type conversions.
Bootstrapped and regression tested on x86_64-linux.
gcc/c-family/ChangeLog:
2015-01-20 Ryan Burn <contact@rnburn.com>
PR c++/69024
PR c++/68997
* cilk.c (cilk_ignorable_spawn_rhs_op): Change to have external linkage.
* cilk.c (recognize_spawn): Rename to cilk_recognize_spawn. Change to have
external linkage.
* cilk.c (cilk_detect_and_unwrap): Rename to recognize_spawn to
cilk_recognize_spawn.
* cilk.c (extract_free_variables): Don't extract free variables from
AGGR_INIT_EXPR slot.
gcc/cp/ChangeLog
2015-01-20 Ryan Burn <contact@rnburn.com>
PR c++/69024
PR c++/68997
* cp-gimplify.c (cp_gimplify_expr): Call cilk_cp_detect_spawn_and_unwrap
instead of cilk_detect_spawn_and_unwrap.
* cp-cilkplus.c (is_conversion_operator_function_decl_p): New.
* cp-cilkplus.c (find_spawn): New.
* cp-cilkplus.c (cilk_cp_detect_spawn_and_unwrap): New.
gcc/testsuite/ChangeLog
2015-01-20 Ryan Burn <contact@rnburn.com>
PR c++/69024
PR c++/68997
* g++.dg/cilk-plus/CK/pr68001.cc: Fix to not depend on broken diagnostic.
* g++.dg/cilk-plus/CK/pr69024.cc: New test.
* g++.dg/cilk-plus/CK/pr68997.cc: New test.
[-- Attachment #2: cilk3.diff --]
[-- Type: text/plain, Size: 8530 bytes --]
Index: gcc/c-family/cilk.c
===================================================================
--- gcc/c-family/cilk.c (revision 232444)
+++ gcc/c-family/cilk.c (working copy)
@@ -185,7 +185,7 @@
A comparison to constant is simple enough to allow, and
is used to convert to bool. */
-static bool
+bool
cilk_ignorable_spawn_rhs_op (tree exp)
{
enum tree_code code = TREE_CODE (exp);
@@ -223,8 +223,8 @@
/* Returns true when EXP is a CALL_EXPR with _Cilk_spawn in front. Unwraps
CILK_SPAWN_STMT wrapper from the CALL_EXPR in *EXP0 statement. */
-static bool
-recognize_spawn (tree exp, tree *exp0)
+bool
+cilk_recognize_spawn (tree exp, tree *exp0)
{
bool spawn_found = false;
if (TREE_CODE (exp) == CILK_SPAWN_STMT)
@@ -292,7 +292,7 @@
/* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
it, or return false. */
- if (recognize_spawn (exp, exp0))
+ if (cilk_recognize_spawn (exp, exp0))
return true;
return false;
}
@@ -1251,6 +1251,21 @@
return;
case AGGR_INIT_EXPR:
+ {
+ int len = 0;
+ int ii = 0;
+ extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
+ {
+ len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
+
+ for (ii = 3; ii < len; ii++)
+ extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
+ extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
+ }
+ break;
+ }
+
case CALL_EXPR:
{
int len = 0;
Index: gcc/cp/cp-gimplify.c
===================================================================
--- gcc/cp/cp-gimplify.c (revision 232444)
+++ gcc/cp/cp-gimplify.c (working copy)
@@ -39,6 +39,7 @@
static tree cp_fold_r (tree *, int *, void *);
static void cp_genericize_tree (tree*);
static tree cp_fold (tree);
+bool cilk_cp_detect_spawn_and_unwrap (tree *);
/* Local declarations. */
@@ -619,7 +620,7 @@
case INIT_EXPR:
if (fn_contains_cilk_spawn_p (cfun))
{
- if (cilk_detect_spawn_and_unwrap (expr_p))
+ if (cilk_cp_detect_spawn_and_unwrap (expr_p))
{
cilk_cp_gimplify_call_params_in_spawned_fn (expr_p,
pre_p, post_p);
@@ -637,7 +638,7 @@
modify_expr_case:
{
if (fn_contains_cilk_spawn_p (cfun)
- && cilk_detect_spawn_and_unwrap (expr_p)
+ && cilk_cp_detect_spawn_and_unwrap (expr_p)
&& !seen_error ())
{
cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
@@ -738,7 +739,7 @@
case CILK_SPAWN_STMT:
gcc_assert(fn_contains_cilk_spawn_p (cfun)
- && cilk_detect_spawn_and_unwrap (expr_p));
+ && cilk_cp_detect_spawn_and_unwrap (expr_p));
if (!seen_error ())
{
@@ -749,7 +750,7 @@
case CALL_EXPR:
if (fn_contains_cilk_spawn_p (cfun)
- && cilk_detect_spawn_and_unwrap (expr_p)
+ && cilk_cp_detect_spawn_and_unwrap (expr_p)
&& !seen_error ())
{
cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
Index: gcc/cp/cp-cilkplus.c
===================================================================
--- gcc/cp/cp-cilkplus.c (revision 232444)
+++ gcc/cp/cp-cilkplus.c (working copy)
@@ -27,6 +27,108 @@
#include "tree-iterator.h"
#include "cilk.h"
+bool cilk_ignorable_spawn_rhs_op (tree);
+bool cilk_recognize_spawn (tree, tree *);
+
+/* Return TRUE if T is a FUNCTION_DECL for a type-conversion operator. */
+
+static bool
+is_conversion_operator_function_decl_p (tree t) {
+ if (TREE_CODE (t) != FUNCTION_DECL)
+ return false;
+
+ return DECL_NAME (t) && IDENTIFIER_TYPENAME_P (DECL_NAME (t));
+}
+
+/* Recursively traverse EXP to search for a CILK_SPAWN_STMT subtree. Return the
+ CILK_SPAWN_STMT subtree if found; otherwise, the last subtree searched. */
+
+static tree
+find_spawn (tree exp)
+{
+ /* Happens with C++ TARGET_EXPR. */
+ if (exp == NULL_TREE)
+ return exp;
+
+ if (cilk_ignorable_spawn_rhs_op (exp))
+ return find_spawn (TREE_OPERAND (exp, 0));
+
+ switch (TREE_CODE (exp))
+ {
+ case AGGR_INIT_EXPR:
+ {
+ /* Check for initialization via a constructor call that represents
+ implicit conversion. */
+ if (AGGR_INIT_VIA_CTOR_P (exp) && aggr_init_expr_nargs (exp) == 2)
+ return find_spawn (AGGR_INIT_EXPR_ARG (exp, 1));
+
+ /* Check for initialization via a call to a type-conversion
+ operator. */
+ tree fn = AGGR_INIT_EXPR_FN (exp);
+ if (TREE_CODE (fn) == ADDR_EXPR
+ && is_conversion_operator_function_decl_p (TREE_OPERAND (fn, 0))
+ && aggr_init_expr_nargs (exp) == 1)
+ return find_spawn (AGGR_INIT_EXPR_ARG (exp, 0));
+ }
+ break;
+
+ case CALL_EXPR:
+ {
+ /* Check for a call to a type-conversion operator. */
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ if (is_conversion_operator_function_decl_p (fndecl)
+ && call_expr_nargs (exp) == 1)
+ return find_spawn (CALL_EXPR_ARG (exp, 0));
+ }
+ break;
+
+ case TARGET_EXPR:
+ return find_spawn (TARGET_EXPR_INITIAL (exp));
+
+ case CLEANUP_POINT_EXPR:
+ case COMPOUND_EXPR:
+ case EXPR_STMT:
+ return find_spawn (TREE_OPERAND (exp, 0));
+
+ default:
+ break;
+ }
+
+ return exp;
+}
+
+/* Returns true if *EXP0 is a recognized form of spawn. Recognized forms are,
+ after conversion to void, a call expression at outer level or an assignment
+ at outer level with the right hand side being a spawned call.
+ In addition to this, it also unwraps the CILK_SPAWN_STMT cover from the
+ CALL_EXPR that is being spawned.
+ Note that `=' in C++ may turn into a CALL_EXPR rather than a MODIFY_EXPR. */
+
+bool
+cilk_cp_detect_spawn_and_unwrap (tree *exp0)
+{
+ tree exp = *exp0;
+
+ if (!TREE_SIDE_EFFECTS (exp))
+ return false;
+
+ /* Strip off any conversion to void. It does not affect whether spawn
+ is supported here. */
+ if (TREE_CODE (exp) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (exp)))
+ exp = TREE_OPERAND (exp, 0);
+
+ if (TREE_CODE (exp) == MODIFY_EXPR || TREE_CODE (exp) == INIT_EXPR)
+ exp = TREE_OPERAND (exp, 1);
+
+ exp = find_spawn (exp);
+ if (exp == NULL_TREE)
+ return false;
+
+ /* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
+ it, or return false. */
+ return cilk_recognize_spawn (exp, exp0);
+}
+
/* Callback for cp_walk_tree to validate the body of a pragma simd loop
or _cilk_for loop.
Index: gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc
===================================================================
--- gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc (revision 232444)
+++ gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc (working copy)
@@ -11,7 +11,7 @@
int main()
{
- std::vector<double> x = _Cilk_spawn f(); /* { dg-error "invalid use of" } */
+ std::vector<double> x = _Cilk_spawn f ();
std::vector<double> y = f();
_Cilk_sync;
return 0;
Index: gcc/testsuite/g++.dg/cilk-plus/CK/pr69024.cc
===================================================================
--- gcc/testsuite/g++.dg/cilk-plus/CK/pr69024.cc (revision 0)
+++ gcc/testsuite/g++.dg/cilk-plus/CK/pr69024.cc (working copy)
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+struct A1 {
+};
+
+struct A2 {
+ A2 () {}
+ A2 (const A2&) {}
+};
+
+struct B1 {
+ operator A1 () {
+ return A1 ();
+ }
+};
+
+B1 fb1 () {
+ return B1 ();
+}
+
+struct B2 {
+ operator A2 () {
+ return A2 ();
+ }
+};
+
+B2 fb2 () {
+ return B2 ();
+}
+
+void t1 () {
+ A1 a1 = _Cilk_spawn fb1 ();
+}
+
+void t2 () {
+ A2 a2 = _Cilk_spawn fb2 ();
+}
Index: gcc/testsuite/g++.dg/cilk-plus/CK/pr68997.cc
===================================================================
--- gcc/testsuite/g++.dg/cilk-plus/CK/pr68997.cc (revision 0)
+++ gcc/testsuite/g++.dg/cilk-plus/CK/pr68997.cc (working copy)
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c++11 -fcilkplus" } */
+
+struct A1 {
+ A1 () {}
+ A1 (const A1&) {}
+};
+
+A1 fa1 () {
+ return A1 ();
+}
+
+struct A2 {
+ A2 () {}
+ A2 (A2&&) {}
+};
+
+A2 fa2 () {
+ A2 ();
+}
+
+struct B1 {
+};
+
+B1 fb1 () {
+ return B1 ();
+}
+
+struct A3 {
+ A3 (const B1&) {}
+};
+
+struct A4 {
+ A4 (B1) {}
+};
+
+struct B2 {
+ B2 () {}
+ B2 (const B2&) {}
+};
+
+B2 fb2 () {
+ return B2 ();
+}
+
+struct A5 {
+ A5 (B2) {}
+};
+
+void t1 () {
+ A1 a1 = _Cilk_spawn fa1 ();
+}
+
+void t2 () {
+ A2 a2 = _Cilk_spawn fa2 ();
+}
+
+void t3 () {
+ A3 a3 = _Cilk_spawn fb1 ();
+}
+
+void t4 () {
+ A4 a4 = _Cilk_spawn fb1 ();
+}
+
+void t5 () {
+ A5 a5 = _Cilk_spawn fb2 ();
+}
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997)
2016-01-20 17:57 [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997) Ryan Burn
@ 2016-02-10 18:00 ` Jeff Law
2016-04-20 23:19 ` Ryan Burn
2016-04-21 21:35 ` Jason Merrill
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Jeff Law @ 2016-02-10 18:00 UTC (permalink / raw)
To: Ryan Burn, gcc-patches, Jason Merrill, igor.zamyatin, Jakub Jelinek
On 01/20/2016 10:57 AM, Ryan Burn wrote:
> This patch follows on from
> https://gcc.gnu.org/ml/gcc-patches/2015-12/msg02142.html
>
> As discussed, it creates a separate function
> cilk_cp_detect_spawn_and_unwrap in gcc/cp to handle processing
> cilk_spawn expressions for c++ and adds support for implicit
> constructor and type conversions.
>
> Bootstrapped and regression tested on x86_64-linux.
FYI, Just saw your assignment fly by. I'll try to get a close look at
this patch shortly.
jeff
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997)
2016-02-10 18:00 ` Jeff Law
@ 2016-04-20 23:19 ` Ryan Burn
0 siblings, 0 replies; 6+ messages in thread
From: Ryan Burn @ 2016-04-20 23:19 UTC (permalink / raw)
To: Jeff Law; +Cc: gcc-patches, Jason Merrill, igor.zamyatin, Jakub Jelinek
Can we push this now that the gcc 7 branch is open?
On Wed, Feb 10, 2016 at 1:00 PM, Jeff Law <law@redhat.com> wrote:
> On 01/20/2016 10:57 AM, Ryan Burn wrote:
>>
>> This patch follows on from
>> https://gcc.gnu.org/ml/gcc-patches/2015-12/msg02142.html
>>
>> As discussed, it creates a separate function
>> cilk_cp_detect_spawn_and_unwrap in gcc/cp to handle processing
>> cilk_spawn expressions for c++ and adds support for implicit
>> constructor and type conversions.
>>
>> Bootstrapped and regression tested on x86_64-linux.
>
> FYI, Just saw your assignment fly by. I'll try to get a close look at this
> patch shortly.
>
> jeff
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997)
2016-01-20 17:57 [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997) Ryan Burn
2016-02-10 18:00 ` Jeff Law
@ 2016-04-21 21:35 ` Jason Merrill
2016-04-27 17:09 ` Jeff Law
2016-04-27 20:43 ` Jeff Law
3 siblings, 0 replies; 6+ messages in thread
From: Jason Merrill @ 2016-04-21 21:35 UTC (permalink / raw)
To: Ryan Burn, gcc-patches, Jeff Law, igor.zamyatin, Jakub Jelinek
On 01/20/2016 12:57 PM, Ryan Burn wrote:
> case AGGR_INIT_EXPR:
> + {
> + int len = 0;
> + int ii = 0;
> + extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
> + if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
> + {
> + len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
> +
> + for (ii = 3; ii < len; ii++)
> + extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
> + extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
> + }
> + break;
> + }
Please add a comment about skipping operand 2 (the slot). Would it make
sense to skip operand 2 (the static chain) for CALL_EXPR, too?
> +is_conversion_operator_function_decl_p (tree t) {
Open brace gets its own line.
> + tree fn = AGGR_INIT_EXPR_FN (exp);
> + if (TREE_CODE (fn) == ADDR_EXPR
> + && is_conversion_operator_function_decl_p (TREE_OPERAND (fn, 0))
It would be good to have a cp_get_callee_fndecl like the normal
get_callee_fndecl, but supporting AGGR_INIT_EXPR as well. That would
replace the less capable get_function_named_in_call function in
constexpr.c and various other places that access AGGR_INIT_EXPR_FN
directly. Mind doing that, either in this patch or as a follow-up?
Jason
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997)
2016-01-20 17:57 [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997) Ryan Burn
2016-02-10 18:00 ` Jeff Law
2016-04-21 21:35 ` Jason Merrill
@ 2016-04-27 17:09 ` Jeff Law
2016-04-27 20:43 ` Jeff Law
3 siblings, 0 replies; 6+ messages in thread
From: Jeff Law @ 2016-04-27 17:09 UTC (permalink / raw)
To: Ryan Burn, gcc-patches, Jason Merrill, igor.zamyatin, Jakub Jelinek
On 01/20/2016 10:57 AM, Ryan Burn wrote:
> This patch follows on from
> https://gcc.gnu.org/ml/gcc-patches/2015-12/msg02142.html
>
> As discussed, it creates a separate function
> cilk_cp_detect_spawn_and_unwrap in gcc/cp to handle processing
> cilk_spawn expressions for c++ and adds support for implicit
> constructor and type conversions.
>
> Bootstrapped and regression tested on x86_64-linux.
>
> gcc/c-family/ChangeLog:
> 2015-01-20 Ryan Burn <contact@rnburn.com>
>
> PR c++/69024
> PR c++/68997
> * cilk.c (cilk_ignorable_spawn_rhs_op): Change to have external linkage.
> * cilk.c (recognize_spawn): Rename to cilk_recognize_spawn. Change to have
> external linkage.
> * cilk.c (cilk_detect_and_unwrap): Rename to recognize_spawn to
> cilk_recognize_spawn.
> * cilk.c (extract_free_variables): Don't extract free variables from
> AGGR_INIT_EXPR slot.
>
> gcc/cp/ChangeLog
> 2015-01-20 Ryan Burn <contact@rnburn.com>
>
> PR c++/69024
> PR c++/68997
> * cp-gimplify.c (cp_gimplify_expr): Call cilk_cp_detect_spawn_and_unwrap
> instead of cilk_detect_spawn_and_unwrap.
> * cp-cilkplus.c (is_conversion_operator_function_decl_p): New.
> * cp-cilkplus.c (find_spawn): New.
> * cp-cilkplus.c (cilk_cp_detect_spawn_and_unwrap): New.
>
> gcc/testsuite/ChangeLog
> 2015-01-20 Ryan Burn <contact@rnburn.com>
>
> PR c++/69024
> PR c++/68997
> * g++.dg/cilk-plus/CK/pr68001.cc: Fix to not depend on broken diagnostic.
> * g++.dg/cilk-plus/CK/pr69024.cc: New test.
> * g++.dg/cilk-plus/CK/pr68997.cc: New test.
>
>
> cilk3.diff
>
>
> Index: gcc/cp/cp-gimplify.c
> ===================================================================
> --- gcc/cp/cp-gimplify.c (revision 232444)
> +++ gcc/cp/cp-gimplify.c (working copy)
> @@ -39,6 +39,7 @@
> static tree cp_fold_r (tree *, int *, void *);
> static void cp_genericize_tree (tree*);
> static tree cp_fold (tree);
> +bool cilk_cp_detect_spawn_and_unwrap (tree *);
The right thing to do here is create cp-cilkplus.h and put the prototype
in here. Along with cpp_validate_cilk_plus_loop.
> Index: gcc/cp/cp-cilkplus.c
> ===================================================================
> --- gcc/cp/cp-cilkplus.c (revision 232444)
> +++ gcc/cp/cp-cilkplus.c (working copy)
> @@ -27,6 +27,108 @@
> #include "tree-iterator.h"
> #include "cilk.h"
>
> +bool cilk_ignorable_spawn_rhs_op (tree);
> +bool cilk_recognize_spawn (tree, tree *);
These should be prototyped in an appropriate .h file. c-common.h, while
not ideal, would be OK. c-common seems to be a fairly bad dumping
ground and we'll want to untangle separately.
> +
> +/* Return TRUE if T is a FUNCTION_DECL for a type-conversion operator. */
> +
> +static bool
> +is_conversion_operator_function_decl_p (tree t) {
> + if (TREE_CODE (t) != FUNCTION_DECL)
> + return false;
> +
> + return DECL_NAME (t) && IDENTIFIER_TYPENAME_P (DECL_NAME (t));
> +}
Formatting. The open-curly goes on a line by itself
I'm spinning up those changes for testing. Assuming they pass, I'll
update the ChangeLog appropriately as well.
Jeff
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997)
2016-01-20 17:57 [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997) Ryan Burn
` (2 preceding siblings ...)
2016-04-27 17:09 ` Jeff Law
@ 2016-04-27 20:43 ` Jeff Law
3 siblings, 0 replies; 6+ messages in thread
From: Jeff Law @ 2016-04-27 20:43 UTC (permalink / raw)
To: Ryan Burn, gcc-patches, Jason Merrill, igor.zamyatin, Jakub Jelinek
[-- Attachment #1: Type: text/plain, Size: 1728 bytes --]
On 01/20/2016 10:57 AM, Ryan Burn wrote:
> This patch follows on from
> https://gcc.gnu.org/ml/gcc-patches/2015-12/msg02142.html
>
> As discussed, it creates a separate function
> cilk_cp_detect_spawn_and_unwrap in gcc/cp to handle processing
> cilk_spawn expressions for c++ and adds support for implicit
> constructor and type conversions.
>
> Bootstrapped and regression tested on x86_64-linux.
>
> gcc/c-family/ChangeLog:
> 2015-01-20 Ryan Burn <contact@rnburn.com>
>
> PR c++/69024
> PR c++/68997
> * cilk.c (cilk_ignorable_spawn_rhs_op): Change to have external linkage.
> * cilk.c (recognize_spawn): Rename to cilk_recognize_spawn. Change to have
> external linkage.
> * cilk.c (cilk_detect_and_unwrap): Rename to recognize_spawn to
> cilk_recognize_spawn.
> * cilk.c (extract_free_variables): Don't extract free variables from
> AGGR_INIT_EXPR slot.
>
> gcc/cp/ChangeLog
> 2015-01-20 Ryan Burn <contact@rnburn.com>
>
> PR c++/69024
> PR c++/68997
> * cp-gimplify.c (cp_gimplify_expr): Call cilk_cp_detect_spawn_and_unwrap
> instead of cilk_detect_spawn_and_unwrap.
> * cp-cilkplus.c (is_conversion_operator_function_decl_p): New.
> * cp-cilkplus.c (find_spawn): New.
> * cp-cilkplus.c (cilk_cp_detect_spawn_and_unwrap): New.
>
> gcc/testsuite/ChangeLog
> 2015-01-20 Ryan Burn <contact@rnburn.com>
>
> PR c++/69024
> PR c++/68997
> * g++.dg/cilk-plus/CK/pr68001.cc: Fix to not depend on broken diagnostic.
> * g++.dg/cilk-plus/CK/pr69024.cc: New test.
> * g++.dg/cilk-plus/CK/pr68997.cc: New test.
>
The updated patch (as expected) bootstrapped and regression tested. I
fixed a few more whitespace/formatting nits, updated the ChangeLogs and
committed the change.
Jeff
[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 15049 bytes --]
commit adc44ab035896ab23180ed4bd552226610e958ab
Author: Jeff Law <law@redhat.com>
Date: Wed Apr 27 14:39:01 2016 -0600
PR c++/69024
PR c++/68997
* cilk.c (cilk_ignorable_spawn_rhs_op): Change to external linkage.
(cilk_recognize_spawn): Renamed from recognize_spawn and change to
external linkage.
(cilk_detect_and_unwrap): Corresponding changes.
(extract_free_variables): Don't extract free variables from
AGGR_INIT_EXPR slot.
* c-common.h (cilk_ignorable_spawn_rhs_op): Prototype.
(cilk_recognize_spawn): Likewise.
PR c++/69024
PR c++/68997
* cp-gimplify.c (cp_gimplify_expr): Call cilk_cp_detect_spawn_and_unwrap
instead of cilk_detect_spawn_and_unwrap.
* cp-cilkplus.c (is_conversion_operator_function_decl_p): New.
(find_spawn): New.
(cilk_cp_detect_spawn_and_unwrap): New.
* lambda.c: Include cp-cilkplus.h.
* parser.c: Include cp-cilkplus.h.
* cp-tree.h (cpp_validate_cilk_plus_loop): Move prototype into...
* cp-cilkpus.h: New file.
PR c++/69024
PR c++/68997
* g++.dg/cilk-plus/CK/pr68001.cc: Fix to not depend on broken
diagnostic.
* g++.dg/cilk-plus/CK/pr69024.cc: New test.
* g++.dg/cilk-plus/CK/pr68997.cc: New test.
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 1d87d9d..ac3be53 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,16 @@
+2015-04-27 Ryan Burn <contact@rnburn.com>
+
+ PR c++/69024
+ PR c++/68997
+ * cilk.c (cilk_ignorable_spawn_rhs_op): Change to external linkage.
+ (cilk_recognize_spawn): Renamed from recognize_spawn and change to
+ external linkage.
+ (cilk_detect_and_unwrap): Corresponding changes.
+ (extract_free_variables): Don't extract free variables from
+ AGGR_INIT_EXPR slot.
+ * c-common.h (cilk_ignorable_spawn_rhs_op): Prototype.
+ (cilk_recognize_spawn): Likewise.
+
2016-04-27 Bernd Schmidt <bschmidt@redhat.com>
* c.opt (Wmemset-elt-size): New option.
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index b631e7d..1309549 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1468,4 +1468,7 @@ extern bool reject_gcc_builtin (const_tree, location_t = UNKNOWN_LOCATION);
extern void warn_duplicated_cond_add_or_warn (location_t, tree, vec<tree> **);
extern bool valid_array_size_p (location_t, tree, tree);
+extern bool cilk_ignorable_spawn_rhs_op (tree);
+extern bool cilk_recognize_spawn (tree, tree *);
+
#endif /* ! GCC_C_COMMON_H */
diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index 0b876b9..69a79ba 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -185,7 +185,7 @@ call_graph_add_fn (tree fndecl)
A comparison to constant is simple enough to allow, and
is used to convert to bool. */
-static bool
+bool
cilk_ignorable_spawn_rhs_op (tree exp)
{
enum tree_code code = TREE_CODE (exp);
@@ -223,8 +223,8 @@ unwrap_cilk_spawn_stmt (tree *tp, int *walk_subtrees, void *)
/* Returns true when EXP is a CALL_EXPR with _Cilk_spawn in front. Unwraps
CILK_SPAWN_STMT wrapper from the CALL_EXPR in *EXP0 statement. */
-static bool
-recognize_spawn (tree exp, tree *exp0)
+bool
+cilk_recognize_spawn (tree exp, tree *exp0)
{
bool spawn_found = false;
if (TREE_CODE (exp) == CILK_SPAWN_STMT)
@@ -292,7 +292,7 @@ cilk_detect_spawn_and_unwrap (tree *exp0)
/* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
it, or return false. */
- if (recognize_spawn (exp, exp0))
+ if (cilk_recognize_spawn (exp, exp0))
return true;
return false;
}
@@ -1250,6 +1250,21 @@ extract_free_variables (tree t, struct wrapper_data *wd,
return;
case AGGR_INIT_EXPR:
+ {
+ int len = 0;
+ int ii = 0;
+ extract_free_variables (TREE_OPERAND (t, 1), wd, ADD_READ);
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST)
+ {
+ len = TREE_INT_CST_LOW (TREE_OPERAND (t, 0));
+
+ for (ii = 3; ii < len; ii++)
+ extract_free_variables (TREE_OPERAND (t, ii), wd, ADD_READ);
+ extract_free_variables (TREE_TYPE (t), wd, ADD_READ);
+ }
+ break;
+ }
+
case CALL_EXPR:
{
int len = 0;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b21666b..1219f82 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,18 @@
+2015-04-27 Ryan Burn <contact@rnburn.com>
+ Jeff Law <law@redhat.com>
+
+ PR c++/69024
+ PR c++/68997
+ * cp-gimplify.c (cp_gimplify_expr): Call cilk_cp_detect_spawn_and_unwrap
+ instead of cilk_detect_spawn_and_unwrap.
+ * cp-cilkplus.c (is_conversion_operator_function_decl_p): New.
+ (find_spawn): New.
+ (cilk_cp_detect_spawn_and_unwrap): New.
+ * lambda.c: Include cp-cilkplus.h.
+ * parser.c: Include cp-cilkplus.h.
+ * cp-tree.h (cpp_validate_cilk_plus_loop): Move prototype into...
+ * cp-cilkpus.h: New file.
+
2016-04-27 Nathan Sidwell <nathan@acm.org>
* constexpr.c (get_fundef_copy): Use the original function for
diff --git a/gcc/cp/cp-cilkplus.c b/gcc/cp/cp-cilkplus.c
index 3b6cda2..7cde099 100644
--- a/gcc/cp/cp-cilkplus.c
+++ b/gcc/cp/cp-cilkplus.c
@@ -26,6 +26,110 @@
#include "cp-tree.h"
#include "tree-iterator.h"
#include "cilk.h"
+#include "c-family/c-common.h"
+
+/* Return TRUE if T is a FUNCTION_DECL for a type-conversion operator. */
+
+static bool
+is_conversion_operator_function_decl_p (tree t)
+{
+ if (TREE_CODE (t) != FUNCTION_DECL)
+ return false;
+
+ return DECL_NAME (t) && IDENTIFIER_TYPENAME_P (DECL_NAME (t));
+}
+
+/* Recursively traverse EXP to search for a CILK_SPAWN_STMT subtree.
+ Return the CILK_SPAWN_STMT subtree if found; otherwise, the last subtree
+ searched. */
+
+static tree
+find_spawn (tree exp)
+{
+ /* Happens with C++ TARGET_EXPR. */
+ if (exp == NULL_TREE)
+ return exp;
+
+ if (cilk_ignorable_spawn_rhs_op (exp))
+ return find_spawn (TREE_OPERAND (exp, 0));
+
+ switch (TREE_CODE (exp))
+ {
+ case AGGR_INIT_EXPR:
+ {
+ /* Check for initialization via a constructor call that represents
+ implicit conversion. */
+ if (AGGR_INIT_VIA_CTOR_P (exp) && aggr_init_expr_nargs (exp) == 2)
+ return find_spawn (AGGR_INIT_EXPR_ARG (exp, 1));
+
+ /* Check for initialization via a call to a type-conversion
+ operator. */
+ tree fn = AGGR_INIT_EXPR_FN (exp);
+ if (TREE_CODE (fn) == ADDR_EXPR
+ && is_conversion_operator_function_decl_p (TREE_OPERAND (fn, 0))
+ && aggr_init_expr_nargs (exp) == 1)
+ return find_spawn (AGGR_INIT_EXPR_ARG (exp, 0));
+ }
+ break;
+
+ case CALL_EXPR:
+ {
+ /* Check for a call to a type-conversion operator. */
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ if (is_conversion_operator_function_decl_p (fndecl)
+ && call_expr_nargs (exp) == 1)
+ return find_spawn (CALL_EXPR_ARG (exp, 0));
+ }
+ break;
+
+ case TARGET_EXPR:
+ return find_spawn (TARGET_EXPR_INITIAL (exp));
+
+ case CLEANUP_POINT_EXPR:
+ case COMPOUND_EXPR:
+ case EXPR_STMT:
+ return find_spawn (TREE_OPERAND (exp, 0));
+
+ default:
+ break;
+ }
+
+ return exp;
+}
+
+/* Return true if *EXP0 is a recognized form of spawn. Recognized forms
+ are, after conversion to void, a call expression at outer level or an
+ assignment at outer level with the right hand side being a spawned call.
+ In addition to this, it also unwraps the CILK_SPAWN_STMT cover from the
+ CALL_EXPR that is being spawned.
+
+ Note that `=' in C++ may turn into a CALL_EXPR rather than a
+ MODIFY_EXPR. */
+
+bool
+cilk_cp_detect_spawn_and_unwrap (tree *exp0)
+{
+ tree exp = *exp0;
+
+ if (!TREE_SIDE_EFFECTS (exp))
+ return false;
+
+ /* Strip off any conversion to void. It does not affect whether spawn
+ is supported here. */
+ if (TREE_CODE (exp) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (exp)))
+ exp = TREE_OPERAND (exp, 0);
+
+ if (TREE_CODE (exp) == MODIFY_EXPR || TREE_CODE (exp) == INIT_EXPR)
+ exp = TREE_OPERAND (exp, 1);
+
+ exp = find_spawn (exp);
+ if (exp == NULL_TREE)
+ return false;
+
+ /* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
+ it, or return false. */
+ return cilk_recognize_spawn (exp, exp0);
+}
/* Callback for cp_walk_tree to validate the body of a pragma simd loop
or _cilk_for loop.
diff --git a/gcc/cp/cp-cilkplus.h b/gcc/cp/cp-cilkplus.h
new file mode 100644
index 0000000..a93711e
--- /dev/null
+++ b/gcc/cp/cp-cilkplus.h
@@ -0,0 +1,28 @@
+/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
+
+ Copyright (C) 2002-2016 Free Software Foundation, Inc.
+ Contributed by Jason Merrill <jason@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 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_CP_CILKPLUS_H
+#define GCC_CP_CILKPLUS_H
+
+extern bool cilk_cp_detect_spawn_and_unwrap (tree *);
+extern bool cpp_validate_cilk_plus_loop (tree);
+
+#endif /* ! GCC_CP_CILKPLUS_H */
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 30ac660..de04bcb 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h"
#include "c-family/c-ubsan.h"
#include "cilk.h"
+#include "cp-cilkplus.h"
/* Forward declarations. */
@@ -615,7 +616,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
case INIT_EXPR:
if (fn_contains_cilk_spawn_p (cfun))
{
- if (cilk_detect_spawn_and_unwrap (expr_p))
+ if (cilk_cp_detect_spawn_and_unwrap (expr_p))
{
cilk_cp_gimplify_call_params_in_spawned_fn (expr_p,
pre_p, post_p);
@@ -633,7 +634,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
modify_expr_case:
{
if (fn_contains_cilk_spawn_p (cfun)
- && cilk_detect_spawn_and_unwrap (expr_p)
+ && cilk_cp_detect_spawn_and_unwrap (expr_p)
&& !seen_error ())
{
cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
@@ -734,7 +735,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
case CILK_SPAWN_STMT:
gcc_assert(fn_contains_cilk_spawn_p (cfun)
- && cilk_detect_spawn_and_unwrap (expr_p));
+ && cilk_cp_detect_spawn_and_unwrap (expr_p));
if (!seen_error ())
{
@@ -745,7 +746,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
case CALL_EXPR:
if (fn_contains_cilk_spawn_p (cfun)
- && cilk_detect_spawn_and_unwrap (expr_p)
+ && cilk_cp_detect_spawn_and_unwrap (expr_p)
&& !seen_error ())
{
cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 0e46ae1..4c548c9 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6873,9 +6873,6 @@ extern void vtv_save_class_info (tree);
extern void vtv_recover_class_info (void);
extern void vtv_build_vtable_verify_fndecl (void);
-/* In cp-cilkplus.c. */
-extern bool cpp_validate_cilk_plus_loop (tree);
-
/* In cp/cp-array-notations.c */
extern tree expand_array_notation_exprs (tree);
bool cilkplus_an_triplet_types_ok_p (location_t, tree, tree, tree,
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 374a78b..08d6d82 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "toplev.h"
#include "gimplify.h"
+#include "cp-cilkplus.h"
/* Constructor for a lambda expression. */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 98a0cd4..7fb3c01 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "gomp-constants.h"
#include "c-family/c-indentation.h"
#include "context.h"
+#include "cp-cilkplus.h"
\f
/* The lexer. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b1ab13d..6189bee 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2015-04-27 Ryan Burn <contact@rnburn.com>
+
+ PR c++/69024
+ PR c++/68997
+ * g++.dg/cilk-plus/CK/pr68001.cc: Fix to not depend on broken
+ diagnostic.
+ * g++.dg/cilk-plus/CK/pr69024.cc: New test.
+ * g++.dg/cilk-plus/CK/pr68997.cc: New test.
+
2016-04-27 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/limited_with4.ad[sb]: New test.
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc
index 07f7c5f..bf2fefa 100644
--- a/gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc
@@ -11,7 +11,7 @@ std::vector<double> f() {
int main()
{
- std::vector<double> x = _Cilk_spawn f(); /* { dg-error "invalid use of" } */
+ std::vector<double> x = _Cilk_spawn f ();
std::vector<double> y = f();
_Cilk_sync;
return 0;
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/pr68997.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/pr68997.cc
new file mode 100644
index 0000000..b442bf9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/pr68997.cc
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c++11 -fcilkplus" } */
+
+struct A1 {
+ A1 () {}
+ A1 (const A1&) {}
+};
+
+A1 fa1 () {
+ return A1 ();
+}
+
+struct A2 {
+ A2 () {}
+ A2 (A2&&) {}
+};
+
+A2 fa2 () {
+ A2 ();
+}
+
+struct B1 {
+};
+
+B1 fb1 () {
+ return B1 ();
+}
+
+struct A3 {
+ A3 (const B1&) {}
+};
+
+struct A4 {
+ A4 (B1) {}
+};
+
+struct B2 {
+ B2 () {}
+ B2 (const B2&) {}
+};
+
+B2 fb2 () {
+ return B2 ();
+}
+
+struct A5 {
+ A5 (B2) {}
+};
+
+void t1 () {
+ A1 a1 = _Cilk_spawn fa1 ();
+}
+
+void t2 () {
+ A2 a2 = _Cilk_spawn fa2 ();
+}
+
+void t3 () {
+ A3 a3 = _Cilk_spawn fb1 ();
+}
+
+void t4 () {
+ A4 a4 = _Cilk_spawn fb1 ();
+}
+
+void t5 () {
+ A5 a5 = _Cilk_spawn fb2 ();
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/pr69024.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/pr69024.cc
new file mode 100644
index 0000000..b87dc1a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/CK/pr69024.cc
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+struct A1 {
+};
+
+struct A2 {
+ A2 () {}
+ A2 (const A2&) {}
+};
+
+struct B1 {
+ operator A1 () {
+ return A1 ();
+ }
+};
+
+B1 fb1 () {
+ return B1 ();
+}
+
+struct B2 {
+ operator A2 () {
+ return A2 ();
+ }
+};
+
+B2 fb2 () {
+ return B2 ();
+}
+
+void t1 () {
+ A1 a1 = _Cilk_spawn fb1 ();
+}
+
+void t2 () {
+ A2 a2 = _Cilk_spawn fb2 ();
+}
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-04-27 20:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-20 17:57 [PATCH][cilkplus] fix c++ implicit conversions with cilk_spawn (PR/69024, PR/68997) Ryan Burn
2016-02-10 18:00 ` Jeff Law
2016-04-20 23:19 ` Ryan Burn
2016-04-21 21:35 ` Jason Merrill
2016-04-27 17:09 ` Jeff Law
2016-04-27 20:43 ` Jeff Law
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).