> -----Original Message----- > From: Jason Merrill [mailto:ja...@redhat.com] > Sent: Thursday, November 28, 2013 9:11 AM > To: Iyer, Balaji V; gcc-patches@gcc.gnu.org > Cc: Jeff Law > Subject: Re: _Cilk_spawn and _Cilk_sync for C++ > > On 11/27/2013 11:05 PM, Iyer, Balaji V wrote: > > Found the bug. I was not utilizing the stabilize_expr's output correctly. > > Unfortunately, I think I was misleading you with talk of stabilize; like you > said, > you want to evaluate the whole expression in the spawned function rather > than in the caller, so that any temporaries (including the lambda closure) > live > until the _Cilk_sync. Using stabilize_expr this way (the way I was > suggesting) > forces the lambda closure to be evaluated in the caller, and then destroyed > at the end of the enclosing statement, which is likely to erase any data that > the spawned function needs to do its work, if anything captured by copy has > a destructor. > > As I said in my last mail, I think the right fix is to make sure that A gets > remapped properly during copy_body so that its use in the initializer for the > closure doesn't confuse later passes.
Ok. I think I cut and pasted the wrong part. I am very sorry about it. Here is the original code: global_var = 0; _Cilk_spawn [=](int *Aa, int size){ foo1_c(A, size); }(B, 2); foo1 (A, 2); _Cilk_sync; if (global_var != 2) return (++q); Here is the gimple output with _Cilk_spawn and _Cilk_sync *DISABLED* try { A[0] = 5; A[1] = 3; B[0] = 5; B[1] = 3; main_size = argc + 1; q = 0; global_var = 0; D.2219.__A = A; try { main2(int)::<lambda(int*, int)>::operator() (&D.2219, &B, 2); } finally { D.2219 = {CLOBBER}; } foo1 (&A, 2); global_var.4 = global_var; if (global_var.4 != 2) goto <D.2255>; else goto <D.2256>; <D.2255>: q = q + 1; D.2257 = q; return D.2257; <D.2256>: D.2257 = q; return D.2257; } finally { A = {CLOBBER}; B = {CLOBBER}; } Here is the gimple output with _Cilk_spawn and _Cilk_synd enabled try { try { __cilkrts_enter_frame_fast_1 (&D.2258); D.2351 = D.2258.worker; D.2352 = D.2351->pedigree.rank; D.2258.pedigree.rank = D.2352; D.2353 = D.2258.worker; D.2354 = D.2353->pedigree.parent; D.2258.pedigree.parent = D.2354; D.2355 = D.2258.call_parent; D.2356 = D.2258.worker; D.2357 = D.2356->pedigree.rank; D.2355->pedigree.rank = D.2357; D.2358 = D.2258.call_parent; D.2359 = D.2258.worker; D.2360 = D.2359->pedigree.parent; D.2358->pedigree.parent = D.2360; D.2361 = D.2258.worker; D.2361->pedigree.rank = 0; D.2362 = D.2258.worker; D.2362->pedigree.parent = &D.2258.pedigree; __cilkrts_detach (&D.2258); B.5 = &CHAIN.7->B; D.2219.__A = CHAIN.7->A; try { main2(int)::<lambda(int*, int)>::operator() (&D.2219, B.5, 2); } finally { D.2219 = {CLOBBER}; <================ CLOBBERING LINE } } catch { catch (NULL) { try { D.2364 = D.2258.flags; D.2365 = D.2364 | 16; D.2258.flags = D.2365; D.2366 = __builtin_eh_pointer (0); D.2258.except_data = D.2366; D.2367 = __builtin_eh_pointer (0); __cxa_begin_catch (D.2367); __cxa_rethrow (); } finally { __cxa_end_catch (); } } } } finally { D.2368 = D.2258.worker; D.2369 = D.2258.call_parent; D.2368->current_stack_frame = D.2369; __cilkrts_pop_frame (&D.2258); D.2370 = D.2258.flags; if (D.2370 != 16777216) goto <D.2371>; else goto <D.2372>; <D.2371>: __cilkrts_leave_frame (&D.2258); goto <D.2373>; <D.2372>: <D.2373>: } } In this line (<=====) it is clobbering the lambda closure. Sorry again about the mistake. By the way, I have only cut and pasted the part from the top-level try expression to just show the relevant part. If you want, I can show you the rest. > > Jason