Skip to content

Commit

Permalink
BitOperations are now used for native performance of certain WASM ins…
Browse files Browse the repository at this point in the history
…tructions when the target framework supports it.
  • Loading branch information
RyanLamansky committed Jul 30, 2022
1 parent 2b69476 commit ecd8499
Show file tree
Hide file tree
Showing 11 changed files with 135 additions and 12 deletions.
16 changes: 14 additions & 2 deletions WebAssembly/Instructions/Int32CountLeadingZeroes.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,11 +24,18 @@ public Int32CountLeadingZeroes()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo leadingZeroCount = typeof(BitOperations).GetMethod(nameof(BitOperations.LeadingZeroCount), new[] { typeof(uint) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
//Assuming validation passes, the remaining type will be Int32.
context.ValidateStack(OpCode.Int32CountLeadingZeroes, WebAssemblyValueType.Int32);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Call, leadingZeroCount);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int32CountLeadingZeroes, (helper, c) =>
{
var result = context.CheckedExportsBuilder.DefineMethod(
Expand Down Expand Up @@ -80,6 +91,7 @@ internal sealed override void Compile(CompilationContext context)

return result;
}
]);
]);
#endif
}
}
15 changes: 13 additions & 2 deletions WebAssembly/Instructions/Int32CountOneBits.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,11 +24,18 @@ public Int32CountOneBits()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo popCount = typeof(BitOperations).GetMethod(nameof(BitOperations.PopCount), new[] { typeof(uint) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
//Assuming validation passes, the remaining type will be Int32.
context.ValidateStack(OpCode.Int32CountOneBits, WebAssemblyValueType.Int32);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Call, popCount);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int32CountOneBits, CreateHelper]);
}

Expand Down Expand Up @@ -71,7 +82,7 @@ internal static MethodBuilder CreateHelper(HelperMethod helper, CompilationConte
il.Emit(OpCodes.Ldc_I4_S, 24);
il.Emit(OpCodes.Shr_Un);
il.Emit(OpCodes.Ret);

return result;
#endif
}
}
14 changes: 13 additions & 1 deletion WebAssembly/Instructions/Int32CountTrailingZeroes.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,11 +24,18 @@ public Int32CountTrailingZeroes()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo trailingZeroCount = typeof(BitOperations).GetMethod(nameof(BitOperations.TrailingZeroCount), new[] { typeof(uint) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
//Assuming validation passes, the remaining type will be this.
context.ValidateStack(OpCode.Int32CountTrailingZeroes, WebAssemblyValueType.Int32);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Call, trailingZeroCount);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int32CountTrailingZeroes, (helper, c) =>
{
var result = context.CheckedExportsBuilder.DefineMethod(
Expand All @@ -49,5 +60,6 @@ internal sealed override void Compile(CompilationContext context)
return result;
}
]);
#endif
}
}
14 changes: 13 additions & 1 deletion WebAssembly/Instructions/Int32RotateLeft.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,13 +24,20 @@ public Int32RotateLeft()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo rotateLeft = typeof(BitOperations).GetMethod(nameof(BitOperations.RotateLeft), new[] { typeof(uint), typeof(int) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
var stack = context.Stack;

context.PopStackNoReturn(OpCode.Int32RotateLeft, WebAssemblyValueType.Int32, WebAssemblyValueType.Int32);
stack.Push(WebAssemblyValueType.Int32);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Call, rotateLeft);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int32RotateLeft, (helper, c) =>
{
var builder = c.CheckedExportsBuilder.DefineMethod(
Expand Down Expand Up @@ -60,5 +71,6 @@ internal sealed override void Compile(CompilationContext context)
return builder;
}
]);
#endif
}
}
14 changes: 13 additions & 1 deletion WebAssembly/Instructions/Int32RotateRight.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,13 +24,20 @@ public Int32RotateRight()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo rotateRight = typeof(BitOperations).GetMethod(nameof(BitOperations.RotateRight), new[] { typeof(uint), typeof(int) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
var stack = context.Stack;

context.PopStackNoReturn(OpCode.Int32RotateRight, WebAssemblyValueType.Int32, WebAssemblyValueType.Int32);
stack.Push(WebAssemblyValueType.Int32);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Call, rotateRight);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int32RotateRight, (helper, c) =>
{
var builder = c.CheckedExportsBuilder.DefineMethod(
Expand Down Expand Up @@ -60,5 +71,6 @@ internal sealed override void Compile(CompilationContext context)
return builder;
}
]);
#endif
}
}
14 changes: 13 additions & 1 deletion WebAssembly/Instructions/Int64CountLeadingZeroes.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,11 +24,18 @@ public Int64CountLeadingZeroes()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo leadingZeroCount = typeof(BitOperations).GetMethod(nameof(BitOperations.LeadingZeroCount), new[] { typeof(ulong) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
//Assuming validation passes, the remaining type will be Int64.
context.ValidateStack(OpCode.Int64CountLeadingZeroes, WebAssemblyValueType.Int64);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Call, leadingZeroCount);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int64CountLeadingZeroes, (helper, c) =>
{
var result = context.CheckedExportsBuilder.DefineMethod(
Expand Down Expand Up @@ -89,5 +100,6 @@ internal sealed override void Compile(CompilationContext context)
return result;
}
]);
#endif
}
}
14 changes: 13 additions & 1 deletion WebAssembly/Instructions/Int64CountOneBits.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,11 +24,18 @@ public Int64CountOneBits()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo popCount = typeof(BitOperations).GetMethod(nameof(BitOperations.PopCount), new[] { typeof(ulong) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
//Assuming validation passes, the remaining type will be Int64.
context.ValidateStack(OpCode.Int64CountOneBits, WebAssemblyValueType.Int64);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Call, popCount);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int64CountOneBits, CreateHelper]);
}

Expand Down Expand Up @@ -73,5 +84,6 @@ internal static MethodBuilder CreateHelper(HelperMethod helper, CompilationConte
il.Emit(OpCodes.Ret);

return result;
#endif
}
}
14 changes: 13 additions & 1 deletion WebAssembly/Instructions/Int64CountTrailingZeroes.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,11 +24,18 @@ public Int64CountTrailingZeroes()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo trailingZeroCount = typeof(BitOperations).GetMethod(nameof(BitOperations.TrailingZeroCount), new[] { typeof(ulong) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
//Assuming validation passes, the remaining type will be Int64.
context.ValidateStack(OpCode.Int64CountTrailingZeroes, WebAssemblyValueType.Int64);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Call, trailingZeroCount);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int64CountTrailingZeroes, (helper, c) =>
{
var result = context.CheckedExportsBuilder.DefineMethod(
Expand All @@ -50,5 +61,6 @@ internal sealed override void Compile(CompilationContext context)
return result;
}
]);
#endif
}
}
15 changes: 14 additions & 1 deletion WebAssembly/Instructions/Int64RotateLeft.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,13 +24,21 @@ public Int64RotateLeft()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo rotateLeft = typeof(BitOperations).GetMethod(nameof(BitOperations.RotateLeft), new[] { typeof(ulong), typeof(int) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
var stack = context.Stack;

context.PopStackNoReturn(OpCode.Int64RotateLeft, WebAssemblyValueType.Int64, WebAssemblyValueType.Int64);
stack.Push(WebAssemblyValueType.Int64);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Conv_I4);
context.Emit(OpCodes.Call, rotateLeft);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int64RotateLeft, (helper, c) =>
{
var builder = c.CheckedExportsBuilder.DefineMethod(
Expand Down Expand Up @@ -62,5 +74,6 @@ internal sealed override void Compile(CompilationContext context)
return builder;
}
]);
#endif
}
}
15 changes: 14 additions & 1 deletion WebAssembly/Instructions/Int64RotateRight.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
using System.Reflection.Emit;
#if NETCOREAPP3_0_OR_GREATER
using System.Numerics;
using System.Reflection;
#endif
using System.Reflection.Emit;
using WebAssembly.Runtime.Compilation;

namespace WebAssembly.Instructions;
Expand All @@ -20,13 +24,21 @@ public Int64RotateRight()
{
}

#if NETCOREAPP3_0_OR_GREATER
private static readonly MethodInfo rotateRight = typeof(BitOperations).GetMethod(nameof(BitOperations.RotateRight), new[] { typeof(ulong), typeof(int) })!;
#endif

internal sealed override void Compile(CompilationContext context)
{
var stack = context.Stack;

context.PopStackNoReturn(OpCode.Int64RotateRight, WebAssemblyValueType.Int64, WebAssemblyValueType.Int64);
stack.Push(WebAssemblyValueType.Int64);

#if NETCOREAPP3_0_OR_GREATER
context.Emit(OpCodes.Conv_I4);
context.Emit(OpCodes.Call, rotateRight);
#else
context.Emit(OpCodes.Call, context[HelperMethod.Int64RotateRight, (helper, c) =>
{
var builder = c.CheckedExportsBuilder.DefineMethod(
Expand Down Expand Up @@ -62,5 +74,6 @@ internal sealed override void Compile(CompilationContext context)
return builder;
}
]);
#endif
}
}
2 changes: 2 additions & 0 deletions WebAssembly/Runtime/Compilation/HelperMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum HelperMethod
Float32CopySign,
Float64CopySign,
GrowMemory,
#if !NETCOREAPP3_0_OR_GREATER
Int32CountOneBits,
Int64CountOneBits,
Int32CountLeadingZeroes,
Expand All @@ -36,6 +37,7 @@ enum HelperMethod
Int32RotateRight,
Int64RotateLeft,
Int64RotateRight,
#endif
Int32TruncateSaturateFloat32Signed,
Int32TruncateSaturateFloat32Unsigned,
Int32TruncateSaturateFloat64Signed,
Expand Down

0 comments on commit ecd8499

Please sign in to comment.