Proposal: simplified arguments passing and first-class support of in parameters
See original GitHub issueHi Lucas!
I’m using InlineIL widely in my project .NEXT. Your add-in helping me a lot to write performance-critical code. However, I feel some inconvenience with it. The first one is an absence of support in-modifiers. Let’s take a look at this code:
public static void Bitcast<T, TResult>(in T input, out TResult output)
where T : unmanaged
where TResult : unmanaged
{
const string slowPath = "slow";
Ldarg(nameof(output));
Sizeof(typeof(T));
Sizeof(typeof(TResult));
Blt_Un(slowPath);
//copy from input into output as-is
Ldarg(nameof(input));
Ldobj(typeof(TResult));
Stobj(typeof(TResult));
Ret();
MarkLabel(slowPath);
Dup();
Initobj(typeof(TResult));
Ldarg(nameof(input));
Ldobj(typeof(T));
Stobj(typeof(T));
Ret();
throw Unreachable(); //output must be defined within scope
}
I have to use Ldarg(nameof(input))
and Ldarg(nameof(output))
because there is no overloads with out and in parameters. This cause unwanted warnings from Roslyn about unused parameters.
The second issue is a method call. It’s verbose. I like Push
helper that allows to push result of parameterless method or property on the evaluation stack. However, this approach is not working for call sites when arguments are not locals or parameters. In this case I have to use Call
with call site descriptor object. I would like to propose T Arg<T>()
and ref T RefArg<T>()
helper which allow to load argument from the evaluation stack:
Ldc_I4(10);
Ldc_I4(2);
Push(Math.Max(Arg<int>(), Arg<int>());
return Return<int>();
//equivalent to
ldc.i4 10
ldc.i4 2
call Math.Max(int, int)
ret
Additionally, it would be great if InlineIL will be able to recognize params correctly:
Ldstr("Hello, {0}!");
Ldstr("Albert Wesker");
Push(Console.WriteLine(Arg<string>(), Arg<string>()); //automatically creates object[] array in resulted IL code
Ret();
Issue Analytics
- State:
- Created 3 years ago
- Comments:27 (12 by maintainers)
Top GitHub Comments
Yes, sure. I need to inspect crash dump before this. It takes some time.
Also, you was right about configuration. I fixed everything and found the explanation why optimized build demonstrates worse result. It was because of my unawareness about how to correctly write benchmarks. If benchmark checks something that has return value then benchmark method should have return type as well.
dotnet crashed with SIGABRT Unfortunately disassembler is not working, at least as easy as on Windows 😢