[PATCH] Mangling for intrinsic names w/function type parameters

Philip Reames listmail at philipreames.com
Tue Jul 22 11:05:40 PDT 2014

On 07/22/2014 10:51 AM, Andrew Trick wrote:
>> On Jul 22, 2014, at 9:33 AM, Philip Reames <listmail at philipreames.com> wrote:
>> On 07/21/2014 06:07 PM, Andrew Trick wrote:
>>> I might be missing something. But I think that LLVM should have a small finite number of intrinsics for patchpoint, and the frontend (JIT client) should be able to pass it a symbolic target with any signature. In other words, we should always treat the target arguments as varargs from the intrinsic's point of view. That doesn't change the actual calling convention used.
>> Andy, I think you may have misread the change.  The suggestion is not changing either the calling convention or the encoding of the arguments passed to the target function.  It's changing the type of the target function itself.  Instead of being an i8*, it could be a void(int)* for example.  The intrinsic would become parametric with the type of the target.
>> Currently, you have to explicitly bitcast your function type to an i8* before passing it to the patchpoint.  This change would remove that requirement.
> Sure, but why can’t the function type be varargs so you don’t need an intrinsic for every function signature?
First, just to make sure I understand your point, you're suggesting the 
following psuedo IR:
declare void @runtime_function(i32, i64);
define void @foo() {
   %t = bitcast void(i32,i64)* @runtime_function to void(...)*
   call void ... @llvm.experimental.patchpoint.something(i32 0, i32 20, 
void(...)* %t, 2, 0, 0xFFFFF);

Is that correct?  If so, this is not in conflict with my proposal. You 
can represent it this way, but the choice to insert the cast is up to 
the frontend author.

I believe you shouldn't *need* to cast a function to a different type 
just to use a patchpoint.  Consider the following pseudo IR:

declare void @runtime_function(i32, i64);
define void @foo() {
   call void ... @llvm.experimental.patchpoint(i32 0, i32 20, 
void(i32,i64)* @runtime_function, 2, 0, 0xFFFFF);

This is much cleaner than the current scheme:
declare void @runtime_function(i32, i64);
define void @foo() {
   %t = bitcast void(i32,i64)* @runtime_function to i8*
   call void ... @llvm.experimental.patchpoint(i32 0, i32 20, i8* %t, 2, 
0, 0xFFFFF);

(Note: This is using symbolic function addresses which aren't supported 
yet.  That's a separate issue.)

As another motivating example for the type mangling, consider this 
alternate intrinsic:

def int_gc_relocate : Intrinsic<[llvm_anyptr_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty]>;

This is taken from the statepoint work. Here, we need the ability to 
represent *any* addrspace(1) pointer. Again, we could do this via a cast 
through "i8 addrspace(1)*", but that's really ugly.


More information about the llvm-commits mailing list