[PATCH] A new HeapToStack allocation promotion pass

Hal Finkel hfinkel at anl.gov
Fri Oct 4 09:16:29 PDT 2013


----- Original Message -----
> Hi Hal,
> 
> On 04/10/13 14:38, Hal Finkel wrote:
> > ----- Original Message -----
> >> (I am not on the list)
> >>
> >>> This adds a new optimization pass that can 'promote' malloc'd
> >>> memory to
> >>> stack-allocated memory when the lifetime of the allocation can be
> >>> determined to be bounded by the execution of the function.
> >>>
> >>> To be specific, consider the following three cases:
> >>>
> >>> void bar(int *x);
> >>>
> >>> void foo1() {
> >>>    int *x = malloc(16);
> >>>    bar(x);
> >>>    free(x);
> >>> }
> >>>
> >>> In this case the malloc can be replaced by an alloca, and the
> >>> free
> >>> removed. Note that this is true even though the pointer 'x' is
> >>> definitely
> >>> captured (and may be recorded in global storage, etc.).
> >>
> >> Hello,
> >>
> >> this seems to rely on the fact that 'bar' returns normally, and
> >> thus
> >> that
> >> whenever malloc is executed, free will be as well. However, bar
> >> could
> >> never return, or return abnormally by throwing an exception which
> >> will
> >> skip the call to free.
> >>
> >> void bar(int *x) {
> >>     free(x);
> >>     throw 42;
> >> }
> >>
> >> will result in calling free on the stack. Now if there was a
> >> destructor
> >> calling free in foo1... Do you actually also consider exceptions
> >> when
> >> you
> >> test that all paths from malloc to the exits contain a call to
> >> free?
> >> That
> >> would only leave noreturn functions.
> >
> > Marc,
> >
> > Thanks!
> >
> > My understanding is that the extra control-flow from exception
> > handling should be accounted for by the basic-block
> > successor/predecessor information (because calling a function that
> > might throw uses invoke, and then you see both the regular
> > predecessor and the cleanup block as predecessors). I'll
> > double-check that's correct. Also, you're right, I should check
> > the function's does-not-return attribute also.
> 
> a function can never return without having the no-return attribute.

In practice, agreed. no-return is a hint (for optimizations and also for removing useless frontend warnings). But what assumptions do we get to make about code reachability? A key question seems to be this: When DT->isReachableFromEntry returns true, do I need to go outside of the standard for it to be wrong, and if not, in what cases (maybe setjmp/longjmp)?

>  For example:
> 
>    void bar(int *x) {
>         free(x);
>         .. infinite loop ..
>     }
> 
> This comes up in PR965 too.
> 
> Summary: no-return attribute => does not return.  The reverse
> implication is
> false.

But we get to assume that all loops terminate, no? This seems equivalent to assuming that all functions return (unless they call exit, etc.). And you'd need to be quite deliberate here in order for the transformation to do the wrong thing (explicitly writing dead code that was known to be invalid except that it is unreachable). Does the standard say anything about that?

Thanks again,
Hal

> 
> Ciao, Duncan.
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-commits mailing list