-
Notifications
You must be signed in to change notification settings - Fork 2
WIP: add an L3
-> LLVM IR translation pass
#146
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
base: main
Are you sure you want to change the base?
Conversation
Introducing a dedicated pointer type for use in the earlier passes was planned for some time now (it removes the need to pass the pointer size to some of the passes) -- the LLVM pass more or less requires it.
Now that there's a dedicated pointer type, use it.
* translate NimSkull pointer types to the IL `Ptr` type * emit conversions when treating globals or integer constants as pointers
Pointer types are no longer identical to unsigned integers, thus requiring the same to-uint conversion signed integers do.
Converting between different pointers types is a no-op at the IL level.
Exceptions currently use the Itanium "zero cost" exception handling, but this might be subject to change, should implementing the personality function be too much of a hassle.
A conversion was always emitted, even if the types were already equal. The target IL requires the Conv types to be different.
The length instead of the payload field was tested for a nil value. At compile time, this shows up as a type error in passes that care about proper typing.
None of the previous passes cared about the size of unions, but the LLVM code generator does, so the size and alignment has to be set to the correct values now.
Locally, I'm able to compile > skully phy/phy.nim phy.txt
> phy --source:L25 --target:llvm c phy.txt
> llvm-as -o phy.bc out.ll
> llc -filetype=native -o phy.o phy.bc
> clang phy.o runtime.c It's also possible to combine the LLVM steps by using (stock) clang, but this routinely resulted in clang crashing, at least on my system. The above is not reproducible with a stock NimSkull yet, as there are multiple bugs in the NimSkull compiler where incorrectly typed MIR code is emitted. Since This PR will most likely stay open for quite some time, as there's no rush to finish it. It's also not clear whether it should be merged at all, or whether it's better for the LLVM pass to be implemented in a separate repository. I mainly wanted to experiment with how easy/possible it is to implement a to-LLVM translation pass with the current compiler. |
There's a proper `Ptr` type now.
The L3 semantics changed considerably. Conversions have become simpler, there are dedicated pointers types, and globals support storing complex data.
This includes building and running an executable out of the code- generator produced assembler code.
This also makes the LLVM produced by the code generator compile, as there are no longer any duplicated interface names.
I've merged the PR with upstream and also added a test for the code generator to the CI. There's still one issue remaining in the NimSkull compiler, namely, that the Separately, I've concluded that the IL |
Add a pass that translates
L3
code into LLVM IR, making it possible to compile source language programs and NimSkull program's compiled viaskully
to native executables via LLVM.At the moment, the pass is biased towards code produced by
skully
.Instead of using the LLVM API to create the LLVM IR and compile it into an executable, the pass simply emits textual LLVM IR, which has a number of benefits:
phy
doesn't depend on a dev version of LLVM; LLVM doesn't have to be built from source to compilephy
In the future, the pass could move to emit LLVM bitcode, which would speed up the pass and produce smaller artifacts.
To-Do
skully
produce incorrect codeskully
fixes into a separate PRPtr
type introduction to a separate PRConv
into multiple operators (separate PR)Select
supportruntime.c
skully
+ LLVM pass in the CIL25
IL as input