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

Sanjoy Das via llvm-dev llvm-dev at lists.llvm.org
Thu Jan 5 12:03:40 PST 2017


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.  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)
  }


More information about the llvm-dev mailing list