Branch: refs/heads/main
Revision: 8cdc00265c0863d84f7c4c1ba2c416d38ae7bebe
Author: DanilaFe
Link: Extend copy elision to understand `defer` statements by DanilaFe · Pull Request #28801 · chapel-lang/chapel · GitHub
Log Message:
Extend copy elision to understand defer statements (#28801)
As described in the linked issue, production doesn't properly handle
defer statements. It treats them as "any old expression", and treats
uses of variables in them as occurring during the time that the defer
occurs in the code. This is simply not correct; defer statements are
executed after all other code in the block, and in reverse order,
interleaved with variable deallocation. In the program below, copy
elision should not occur, since the defer statement uses the
copied-out-of variable a after the copy into b.
class MyClass2 {}
proc foo() {
var a = new shared MyClass2();
defer {
writeln(a);
}
var b = a;
return;
}
foo();
This PR implements this behavior. Since variable deinitializations do
not trigger copy elision (they have no mentions of other variables in
scope), it's sufficient to simply keep a stack of DeferStmts as they
are encountered. Whenever processing of the block concludes (during an
early return or when reaching its end), the encountered statements are
processed in reverse order. For the time being, I do not allow copy
elisions from "outer" variables into defers. This may be safe, but
seems tricky, and the current implementation is a strict upgrade over
the current behavior. On the other hand, copy elisions of variables that
are both within the defer now work as normal.
Reviewed by @jabraham17 -- thanks!
Testing
- paratest
Diff:
M compiler/passes/splitInit.cpp
A test/statements/defer/copy-elision-branch.chpl
A test/statements/defer/copy-elision-branch.good
A test/statements/defer/copy-elision-defer-local.chpl
A test/statements/defer/copy-elision-defer-local.good
A test/statements/defer/copy-elision.chpl
A test/statements/defer/copy-elision.good
https://github.com/chapel-lang/chapel/pull/28801.diff