[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