[llvm-dev] RFC: Allow readnone and readonly functions to throw exceptions

Hal Finkel via llvm-dev
Thu, 05 Jan 2017 20:05:59 -0000

On 01/05/2017 02:03 PM, Sanjoy Das wrote:
> On Thu, Jan 5, 2017 at 11:43 AM, Hal Finkel <hfinkel at anl.gov>
wrote:
>> On 01/05/2017 01:20 PM, Sanjoy Das wrote:
>>> Hi Hal,
>>>
>>> On Thu, Jan 5, 2017 at 11:10 AM, Hal Finkel via llvm-dev
>>> <llvm-dev at lists.llvm.org> wrote:
>>>> It is still only a function of its arguments, so it can be
CSE'd.
>>> That's a good example -- we can CSE it without worrying about
the
>>> memory state flowing in.
>>>
>>> In fact, if we have:
>>>
>>> *a = 10;
>>> call @readnone_may_unwind()
>>> *a = 20;
>>> call @readnone_may_unwind()
>>> *a = 30;
>>>
>>> then we can first transform this to:
>>>
>>> *a = 10;
>>> call @readnone_may_unwind()
>>> *a = 20;
>>> call @readnone_may_unwind()  nounwind // only on this call (since
we
>>> returned normally)
>>> *a = 30;
>>>
>>> and then DSE:
>>>
>>> *a = 10;
>>> call @readnone_may_unwind()
>>> // *a = 20;
>>> call @readnone_may_unwind()  nounwind // only on this call
>>> *a = 30;
>>>
>>>
>>>> Also, if I have this:
>>>>
>>>>    *a = 10;
>>>>    b = a_readnone_unwind_func();
>>>>    *a = 10;
>>>>
>>>> I can still conclude that this last store is redundant and can
be
>>>> removed. I
>>>> know that the readnone function does not touch it, and if it
unwinds,
>>>> than
>>>> the later store is dead. If I know that &*a has not escaped
to where an
>>>> exception handler might access it, then I know that the first
store than
>>>> be
>>>> removed.
>>> That's not specific to readnone though, right?  Even if the
function
>>> was readonly-mayunwind, the optimization would be legal.
>> Yes, unless the readonly-mayunwind functions takes the memory as a
>> parameter, in which case the latter sentence does not apply.
> I'm not a 100% sure I understand what you meant to say, but I don't
> think that part is specific to readonly either.  Neither readonly nor
> readnone functions can escape pointers by writing them to memory
> (within their body).  However, both readnone or readonly functions
> could resume with a pointer they take as an argument which the
> exception handler could read from.

Agreed.

Thanks again,
Hal

>   That is:
>
>    void f(i32* %ptr) { // either readnone or readonly
>      resume %ptr
>    }
>
>    void g() {
>      %p = malloc()
>      *%p = 20;  // can't DSE this because ...
>      f(%p)
>    }
>
> ... we could have this further up the stack
>
>    void h() {
>      invoke g() to %normal unwind %unwind
>    unwind:
>      %ptr = landingpad
>      assert(*%ptr == 20)
>    }

--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory