-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ahead-of-Time Compiler using IKVM #10
Comments
+1 My primary interest in this project is in using it to convert WASM into .NET assembly files. I've done some fiddling around in this area, but not as far as @mccoyp has gone. I found myself wanting the guts of this library to be a bit more abstracted, so that it could be used for its current use case (generating IL on the fly in memory) or with one of the various libraries for writing an assembly to a file, such as the IKVM stuff mentioned above, or even System.Reflection.Metadata. But I recognized that my particular interests may not be the same as the goals for this project. |
Just want to mention that the reason @mccoyp and I ended up using IKVM.Reflection was because it follows the API and semantics of System.Reflection pretty closely - so it was fairly straightforward to retarget dotnet-webassembly for a proof of concept without having to re-architect the internals of dotnet-webassembly too much. We wanted to see if we could build something useful in a short amount of time. With more time and more serious intent there are more options for the backend reflection library. |
@lambdageek Yep, that all makes sense. I mention S.R.M simply because it is another alternative, but going down that path would open a big can of worms, as the impedance mismatch is fairly high. |
Well, the original purpose of the library is simply the outcome of me reading through the WASM spec, realizing how close it was to the .NET CIL spec, and deciding that a project like this should exist, if only because it can exist. I'm not looking to add any more dependencies than it has now (which is just System.Reflection.Emit on .NET Standard and nothing at all on .NET 4.5+), but I'm happy to make it more extensible so that project like yours have can integrate with the main library instead of needing to fork. AoT compilation is something I've definitely considered. In fact, it's very easy to achieve on .NET 4.5+ since this capability is built right into AssemblyBuilder via AssemblyBuilder.RunAndSave/Save. .NET Core does not have this capability, but it's been a known issue for years (which you may want to add to your watch list): https://github.com/dotnet/corefx/issues/4491 . I've been hoping they'd get to it eventually... |
Happy to hear that extensibility is an option, @RyanLamansky - not sure what you have in mind, but I think you've built a pretty great general foundation for working with wasm modules from .NET - transpiling is one use-case, but maybe it doesn't have to be the only one. As for .NET Core and RunAndSave... comments like https://github.com/dotnet/corefx/issues/4491#issuecomment-189756092 or https://github.com/dotnet/corefx/issues/4491#issuecomment-305010239 really don't offer a lot of hope that it will happen any time soon. |
@lambdageek @mccoyp I heard about your current work thanks to this tweet, and I am so happy I found this project. This open huge interoperability perspective. (Some cryptographic libraries in C are too hard for normal human to port into C#, and I don't want to spend time cross compiling because this is a PITA) Forgive me my ignorance as I am still learning about what is being done in this area, but why using IKVM instead of Mono.Cecil? |
@lambdageek My current thought is to modify the compiler to emit instructions more abstractly. The built-in process would still default to wrapping AssemblyBuilder, but it could be swapped out with another service. I could leverage this internally to, for example, disable streaming compilation so that the WASM "names" section at the end of the file can be used to set accurate function names for easier debugging, or provide a clean way to do AoT on .NET 4.5 where this capability is already part of the platform. I realize it's unlikely that Microsoft is going to fix https://github.com/dotnet/corefx/issues/4491 any time soon, but the long-term success of this project will require some effort from them. A growing problem is that .NET doesn't offer access to all the same raw CPU instructions that WebAssembly can use. I've been able to use combinations of other instructions to work around this so far (see https://github.com/RyanLamansky/dotnet-webassembly/blob/9599f9e122ab15ee7c91f905303f5d696f9f25b4/WebAssembly/Instructions/Int32CountOneBits.cs for one of the uglier examples) at the expense of performance, but some of the proposals I've seen for SIMD will be problematic and threads may be impossible. With @migueldeicaza seeming excited about the potential here, there's hope for a path to clear these approaching roadblocks. Ultimately, this requires Microsoft to decide that the ability to run any WASM directly on .NET is of strategic interest, because opening up threading in a way WebAssembly will need would be complicated project. |
@RyanLamansky for your particular example of If I understand how it works, .NET Core JIT on encountering a call to |
So playing with intrinsic, I found out that it would be very hard to leverage this in a ".wasm to .dll" feature: The reason is that we don't know if However, if wasm to IL compiler run in the target environment, then this is a quite nice optimization. |
The idea of using int result;
if (System.Runtime.Intrinsics.X86.Popcnt.IsSupported)
{
result = System.Runtime.Intrinsics.X86.Popcnt.PopCount(x);
}
else
{
result = SoftwarePopCount(x);
}
int result = System.Runtime.Intrinsics.X86.Popcnt.PopCount(x); if it's supported, otherwise int result = SoftwarePopCount(x); |
@Suchiman this is amazing and exciting. This is sad that this is not more documented. Because if the JIT does not, the implementation would be a recursive call. Second question, does the generated assembly need |
@NicolasDorier .NET Framework won't be getting this (don't have any hopes for new features in there), mono is thinking about adapting them IIRC |
I am surprised, I thought .NET Framework was using RyuJIT by now so that would just work. |
Yes but this also requires support from the VM side and the VM is not shared with NETFX so that part is #ifdef'd out for NETFX |
Regarding |
I'll definitely leverage any intrinsics shipped! I'm still concerned about how I'm going to deal with further out features like atomic memory instructions... |
Anyway, back on topic, adding extensibility to make AoT compilation easier to achieve is now on the Potential Future Features list. I looked over all the work you (@mccoyp @lambdageek) did and feel bad that it was so difficult, I'm sure I can make it better! Doing this is lower priority than getting 1.0 shipped. I'm so close to having 100% coverage of the base WASM spec that it's all I want to think about right now... I'll leave this issue open until I have something that I think is good enough to meet your needs. |
Hello! I was wondering if there were plans to incorporate AOT compilation of wasm into this project. I'm a student who's spent some time building a prototype for an AOT compiler based off of this library (my fork is here).
My approach uses IKVM.Reflection to allow assembly saving as a DLL on .NET Standard 2.0 - the version of IKVM used is derived from Mono's fork of IKVM reflection (here). The prototype isn't fully fleshed out, but it does show for a number of examples that AOT wasm compilation can work for .NET Core (and Mono). It required some pretty heavy refactoring of the Compiler and CompilationContext to switch to an IKVM.Reflection dependency, but I think it could be a very useful addition to the project.
Either I or @lambdageek (who helped me with the development) can help to explain the approach a bit more and upstream changes if you're interested in this approach.
The text was updated successfully, but these errors were encountered: