best way to represent this pseudocode in LLVM IR?

Greetings,

I implemented a proof of concept of something I’m calling “error return traces” in my frontend (screenshot and explanation at this link): https://github.com/zig-lang/zig/pull/684

Now I’m trying to minimize the runtime size.

Here’s some example IR that I generate:

define internal fastcc i16 @baz1(%StackTrace* nonnull) unnamed_addr #2 !dbg !69 {
Entry:
%1 = getelementptr inbounds %StackTrace, %StackTrace* %0, i32 0, i32 0, !dbg !70
%2 = getelementptr inbounds %StackTrace, %StackTrace* %0, i32 0, i32 1, !dbg !70
%3 = load i64, i64* %1, align 8, !dbg !70
%4 = urem i64 %3, 31, !dbg !70
%5 = getelementptr inbounds [31 x i64], [31 x i64]* %2, i64 0, i64 %4, !dbg !70
store i64 ptrtoint (i8* blockaddress(@baz1, %ReturnError) to i64), i64* %5, align 8, !dbg !70
%6 = add i64 %3, 1, !dbg !70
store i64 %6, i64* %1, align 8, !dbg !70
br label %ReturnError, !dbg !70

ReturnError: ; preds = %Entry
ret i16 1, !dbg !70
}

Everywhere that we can return an error from a function, we generate code like this. Here it is in pseudocode form:

stack_trace_ptr.addresses[stack_trace_ptr.index % 31] = addressOfReturnInstruction;
stack_trace_ptr.index += 1;
return error_code;

I’d like to try to extract some of this out to make a smaller binary size. If we extract pseudocode into a function:

%0 = tail call func(ptr, addressOfReturnInstruction, error_code);
return %0;

func(ptr, address, error_code) {
ptr.addresses[ptr.index % 31] = address;
ptr.index += 1;
return error_code;

}

The function implementation is so simple, I think we should be able to set the return value into the return register and do a single jmp instruction, and then have func return to the caller’s return address.

I’d like this to happen if possible even with no optimization passes.

Is this the best way to represent it? Passing error_code as a parameter to the function and using tail call?

Thanks for looking,
Andrew