[cfe-dev] Implementing blocks with try-finally semantics

João Paulo Labegalini de Carvalho via cfe-dev cfe-dev at lists.llvm.org
Thu Jun 21 10:26:29 PDT 2018


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.

On Thu, Jun 21, 2018 at 1:51 PM Reid Kleckner <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> 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
>> joao.carvalho at ic.unicamp.br
>>
> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at lists.llvm.org
>> 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
joao.carvalho at ic.unicamp.br
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180621/b166c170/attachment.html>


More information about the cfe-dev mailing list