[PATCH] D58260: [INLINER] allow inlining of blockaddresses if sole uses are callbrs

Bill Wendling via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 30 13:15:58 PDT 2019


void added a comment.

In D58260#1484879 <https://reviews.llvm.org/D58260#1484879>, @efriedma wrote:

> In D58260#1483021 <https://reviews.llvm.org/D58260#1483021>, @void wrote:
>
> > Right. My point is that it's equivalent to passing a pointer around, except that the pointer cannot be dereferenced anywhere except the originating function. (For the purposes of what Nick's trying to do, "originating function" includes code that's inlined into a function.) As long as IPSCCP and the like don't violate that constraint, passing the pointer around isn't going to cause semantic changes to the program. (A function that tries to jump to a block address that's not within that function is already undefined and still should be.)
>
>
> Oh, you're saying that if we're inlining a function that contains an indirectbr, but we aren't inlining the indirectbr, we can allow inlining as long as we as the blockaddress still points to the original function.  That's abstractly reasonable, but it probably breaks the Linux kernel's _THIS_IP_ macro (and therefore, I'm guessing, isn't what gcc does).


Here's pseudo code that might explain what I'm getting at. Like I said, I might be missing something, but I think inlining a function that uses `blockaddresses` should be a fairly straight-forward process.

  label label_array = []
  
  function foo()
    label_array.append(_x)
    label_array.append(_y)
  
    // some code that calculates v
  
    mux(label_array[v])
  
    // maybe more code
  
    goto label_array[v]
  
  _x: // do something fancy
  
  _y: // do cleanup
  
  
  function bar()
    foo()

In `foo`, even though the values of `_x` and `_y` escape the function, they can't be modified outside of `foo` (or, really, inside the function). If something outside of `foo` modifies the values in `label_array`, it's either a bug in the compiler or the user explicitly doing something bad. That's what we have today, I believe.

Now if we inline `foo` into `bar`, it should be an easy task of modifying the now inlined `indirectbr` to point to the new `_x` and `_y`:

  function bar()
    label_array.append(_x_new)
    label_array.append(_y_new)
  
    // some code that calculates v
  
    mux(label_array[v])
  
    // maybe more code
  
    goto label_array[v]
  
  _x_new: // do something fancy
  
  _y_new: // do cleanup

There's the obvious issue that `label_array` now has different entries depending on the inlining, but we have that already with regular inlining that modifies a global array.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D58260/new/

https://reviews.llvm.org/D58260





More information about the llvm-commits mailing list