[cfe-dev] Implementing blocks with try-finally semantics
John McCall via cfe-dev
cfe-dev at lists.llvm.org
Thu Jun 21 12:45:03 PDT 2018
> On Jun 21, 2018, at 3:37 PM, João Paulo Labegalini de Carvalho <jaopaulolc at gmail.com> wrote:
> John,
>
> Thank you very much! Pushing a cleanup via EHStack did the trick!
Note that if you're interested in making this user-facing, you should probably add something to the JumpDiagnostics checker to make sure you can't jump *into* this thing.
I think the analysis part is fairly easy to find examples of how to modify; the more subtle thing is that you need to call `getCurFunction()->setHasBranchProtectedScope()` to ensure that the analysis is run.
John.
> On Thu, Jun 21, 2018 at 3:02 PM John McCall <rjmccall at apple.com <mailto:rjmccall at apple.com>> wrote:
>
>> On Jun 21, 2018, at 1:26 PM, João Paulo Labegalini de Carvalho via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>>
>> Reid,
>>
>> Thank you for the quick reply.
>>
>> I am not worried about exceptions, I am more interested in the concept of finally, a block of code which is guaranteed to execute "no matter what" happens inside the try block. But you are right, my example is a little crude.
>>
>> My goal is to guarantee that __end_spec() is called on every exit of __speculate blocks. Even if __speculate is within a for/while-loop and a there is a break/return inside of it. The __speculate block annotates a block that will be transformed into a two-path code: (i) instrumented with software load/store barriers to detect conflicts and (ii) instrumentation-free that will either execute under mutual exclusion or using hardware support for speculative execution.
>>
>> I am already generating correct code when the compound statement does not have any statements which cause control flow to "escape" the block within which __speculate resides.
>>
>> My question was motivated more by my worry to no generate an ugly solution (e.g. fixing up every exit of the block) or (re)coding something that is(might have been) implemented.
>
> You're hacking the compiler, right? In the IRGen for your new declaration (statement?), push a cleanup.
>
> John.
>
>>
>> On Thu, Jun 21, 2018 at 1:51 PM Reid Kleckner <rnk at google.com <mailto:rnk at google.com>> wrote:
>> Hi,
>>
>> From your example, it's not clear to me what you want this feature to do. Do you want the finally block to execute:
>> 1. When a C++ exception is thrown?
>> 2. When normal control flow leaves the scope (goto, break, return)?
>> 3. When a hardware trap occurs (div by zero, access violation, segv)?
>>
>> 3 is not implementable with LLVM today. It's not implemented properly even for __try / __finally.
>>
>> 1 and 2 are simple and can be accomplished with regular C++ destructors. You can do things like:
>> struct Cleanup {
>> Cleanup(std::function<void()> f) : f(f) {}
>> ~Cleanup() { f(); }
>> std::function<void()> f;
>> };
>> void foo() {
>> Cleanup c([&]() {
>> .. // any finally code here
>> });
>> // any try body code here
>> }
>>
>> Reid
>>
>> On Thu, Jun 21, 2018 at 9:26 AM João Paulo Labegalini de Carvalho via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>> Hi,
>>
>> I am working on a block annotation which should have a try-finally semantics. For example, given a code like this:
>>
>> __speculate {
>> if (x > 2) {
>> y = 0;
>> }
>> }
>>
>> clang should produce something like
>>
>> __exec_mode = __begin_spec();
>> if (__exec_mode == SW) {
>> if (__read_barrier(&x) > 2) {
>> __write_barrier(&y, 0);
>> }
>> __end_spec();
>> } else {
>> if (x > 2) {
>> y = 0;
>> }
>> __end_spec();
>> }
>>
>> such that __end_spec() is guaranteed to be called on every exit of the __speculate {} block.
>>
>> It is my understanding that Clang implements try-finally statements as a Microsoft Specific Extension. However, I would not like to have such restriction, since such extension is only available for a reduced number of targets.
>>
>> My question is, how should I implement try-finally semantics? Through an IR pass (fixing up every exit with a call to __end_spec()) or it is possible to extend from CXXTryStmt (reusing some CodeGen code)?
>> --
>> João Paulo L. de Carvalho
>> Computer Science | IC-UNICAMP | Campinas , SP - Brazil
>> jaopaulolc at gmail.com <mailto:jaopaulolc at gmail.com>
>> joao.carvalho at ic.unicamp.br <mailto:joao.carvalho at ic.unicamp.br>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev>
>> --
>> João Paulo L. de Carvalho
>> Computer Science | IC-UNICAMP | Campinas , SP - Brazil
>> jaopaulolc at gmail.com <mailto:jaopaulolc at gmail.com>
>> joao.carvalho at ic.unicamp.br <mailto:joao.carvalho at ic.unicamp.br>_______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev>
> --
> João Paulo L. de Carvalho
> Computer Science | IC-UNICAMP | Campinas , SP - Brazil
> jaopaulolc at gmail.com <mailto:jaopaulolc at gmail.com>
> joao.carvalho at ic.unicamp.br <mailto:joao.carvalho at ic.unicamp.br>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180621/72cf67af/attachment.html>
More information about the cfe-dev
mailing list