[PATCH] D71505: [Utils] Provide a callback encapsulation utility for call sites

Johannes Doerfert via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 13 19:06:18 PST 2019


jdoerfert created this revision.
jdoerfert added a reviewer: hfinkel.
Herald added subscribers: jfb, bollu, hiraditya, mgorny.
Herald added a project: LLVM.

The callback encapsulation utility will wrap a call, either direct or
transitive, such that information can be propagated through it either
without modifying the actual call (or the function interfaces).

Callback encapsulation is a semantic no-op. Thus, the code is always
semantically equivalent to the original input and there is no need to
interpret any of the metadata used by the encoding. Unaware passes will
behave correctly at all times.

This allows us to perform argument promotion and other IPOs that modify
the function signature even if (1) the signatures are fixed (externally
visible declarations) and even if (2) the new function signature is not
known to be better per se which means we might need to revert back to
the original (or some derived form).

The first use case appears when we look at transitive calls, e.g.
through `pthread_create`. We want the payload pointer (often a struct)
to be promoted (=unpacked) at the call site in order to enable other
IPOs, e.g. constant propagation. However, this is so far impossible
because the `pthread_create` interface is fixed. With this functionality
we can unpack the payload, propagate information from call site to the
callee and vice versa, before we at the end fold everything to the
original version again. See the example in CallbackEncapsulate.h.

The second use case appears for example when large structs are passed to
a function and we know we can promote (=unpack) them if we want.  While
doing so will enable other IPOs, as described above, it might also make
it (basically) impossible to pack them (properly) again.  Thus, we might
be stuck with a lot of arguments passed explicitly which can be
significantly more expensive than the original code was. To allow
promotion of large structs without the risk of paying this price we can
encapsulate the call site in a callback. The original way of passing
arguments is preserved but we still expose (almost) the same
optimization opportunities.

Callback encapsulation uses `!callback` metadata already available in
the IR as well as `!rpl_cs` and `!rpl_acs` metadata which is new. Since
the `!rpl_cs` and `!rpl_acs` can be safely ignored, we will delay the
description in the language reference until we gained more experience
with it (and performed potentially necessary modifications).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71505

Files:
  llvm/include/llvm/Transforms/Utils/CallbackEncapsulate.h
  llvm/lib/Transforms/Utils/CMakeLists.txt
  llvm/lib/Transforms/Utils/CallbackEncapsulate.cpp
  llvm/unittests/Transforms/Utils/CMakeLists.txt
  llvm/unittests/Transforms/Utils/CallbackEncapsulateTest.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D71505.233909.patch
Type: text/x-patch
Size: 32860 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20191214/a7c5634e/attachment-0001.bin>


More information about the llvm-commits mailing list