[PATCH] A new HeapToStack allocation promotion pass

Hal Finkel hfinkel at anl.gov
Fri Oct 4 10:45:30 PDT 2013

----- Original Message -----
> Hi Hal,
> >> 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)?
> if the called function bar is no-return then you definitely can't do
> the
> transform, because the correctness of the transform relies on the
> free that
> follows the call to bar being executed (because that tells you that
> it wasn't
> freed in the call to bar already).  I think that's clear.  The
> question is: if
> the function is not marked no-return is the transform OK?


> >
> >>   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?
> Apparently not, this is PR965.  Also, there is no telling whether or
> not bar
> calls "exit" or something like that.  If bar is defined in the same
> translation
> unit, and calls "exit" in an obvious way, and the appropriate
> transform passes
> have been run, then bar will have been marked no-return.  But what if
> bar is in
> another translation unit, or calls some other function quz in another
> translation unit that calls free then exit?  I think this transform
> can only be
> done correctly if you can *prove* that bar returns, which probably
> means adding
> an LLVM attribute for that ('does-return') and a pass that tries to
> deduce the
> 'does-return' attribute.  You can then do the transform if bar is
> does-return,
> but otherwise you can't.  In PR965 I think 'does-return' was called
> 'finite' or
> something like that.  The big problem is that most likely hardly any
> functions
> will end up being marked 'does-return' because it is too hard to
> deduce...

This depends. I think that the number of functions that we could mark would not be insignificant (especially when expanding templated code, which is one big use case for this).

> Also, another issue is that this "back propagates" undefined
> behaviour in a big
> way.  I mean, suppose bar does return, but also frees x.  Then before
> doing the
> transform bar would execute properly, and only afterwards would the
> program
> crash.  After the transform it will crash in bar, maybe much much
> earlier than
> before.  While this is OK per the standard, it is still pretty
> obnoxious.

FWIW, I'm okay with this side effect. Optimizations often have the effect of 'moving up' a crash. I think that the benefit is worthwhile.

> 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?
> I didn't understand you here, got an example?  Forgetting about
> loops, how do
> you tell if a function calls exit (or calls a function that calls a
> function
> that calls exit)?

My point is that it is not just that the function might call exit() (which by itself would not cause a problem), you'd need to put a call to free() after the exiting function, where the exiting function also called free() prior to exiting. So, were the function not to exit, the later free() would be invalid. Or, to put it another way, the later free() is only valid because it is actually dead.

In any case, I think that your point is valid. We probably need to assume that any function is a potential exit point for the function (unless we explicitly know otherwise).

Thanks again,

> Ciao, Duncan.

Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory

More information about the llvm-commits mailing list