Skip to content

Stage 2 Proposal: Standardise a binary format for ZIR, and enable compilation to and from this representation #5635

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

Open
ghost opened this issue Jun 19, 2020 · 3 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@ghost
Copy link

ghost commented Jun 19, 2020

EDITED -- original text is quoted below

There are a huge variety of hardware architectures in the world, both professionally designed and hobbyist. It would be impossible to actively support all of them in upstream Zig, however we can provide facilities for end users to support them themselves.

The simplest way to do this would be to standardise a binary representation of ZIR, add a command line option to emit this representation, and allow users to develop their own backends consuming this. To allow other language projects to leverage Zig's infrastructure, we could also add a command line option to compile from this representation to native code, and allow users to develop their own frontends as well. If we wanted to go really insane, we could provide these compilation stages as libraries, permitting tighter integration with a host or guest project.

We'd want to wait a while before attempting this, and even then we'd only want to expose a very high-level view of the compilation process, to avoid nailing things down too hard and preventing future optimisations or improvements. Once we've navigated all of that though, this could be a killer feature.

This might already be the plan, but I couldn't find any mention of it, so here's an issue.

Much like it would be impractical to provide special consideration for every hobbyist OS, we can't possibly hope to actively support every architecture that people might create. Even for the ones that we do support, maybe there's some alternative backend that produces faster, more efficient code. Let's enable users to support their own platforms how they choose

This would consist of three parts: allowing userland code to override certain private standard library functions (such as the various syscalls), allowing build.zig to register a user-defined function per compilation unit to perform code generation, and (once #1535 is implemented) somehow teaching the linker about the allowed relocations in the object format. (I won't give possible examples here, as I don't know enough about the design of the compiler to know what would make sense.)

This would require standardisation of in-memory ZIR at the ABI level, so it probably won't be feasible for some time, but in the long term I think we should definitely make it a goal.

@Vexu Vexu added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Jun 19, 2020
@Vexu Vexu added this to the 0.7.0 milestone Jun 19, 2020
@SpexGuy
Copy link
Contributor

SpexGuy commented Jun 19, 2020

I think we could at least do this eventually:

  • standardize a binary representation of ZIR
  • add a compiler option to emit this binary representation into a file as the compiler output
  • third parties can write programs that read this file and do arbitrary processing, including generating assembly, which are invoked from their build.zig.

Supporting incremental compilation through this process is a very different idea, requiring a much more complex interaction between the compiler and the code generator. I'm not sure that standardizing that interface is a good idea in the long term. IMO new backends are best represented as a fork that integrates the backend into the compiler (and hopefully gets upstreamed once it's stable). This would allow the backend to be tuned to its needs, whatever they may be.

For example, a backend may need a specialized data structure to be built to accelerate code generation, but the most efficient place to generate that data structure is in the parser. If the backend is part of the compiler, the parser can be modified to check which backend is in use and generate the needed structure. Without that, we need to perform an extra processing step in the backend to rebuild data that was available when the parser ran. This increases both complexity and run time.

We should certainly keep an updated document containing a list of things that need to change in the compiler in order to add a new backend, and we should devote design effort to keeping this list small and to keep it from changing often. But I don't really see much value in being able to add a backend from a program's build.zig, or even in having a strict binary separation between the backend and the rest of the compiler.

@ghost
Copy link
Author

ghost commented Jun 25, 2020

Yes, you're probably right.

@ghost ghost changed the title Stage 2 Proposal: Bring your own backend Stage 2 Proposal: Standardise a binary format for ZIR, and enable compilation to and from this representation Jun 25, 2020
@ghost
Copy link
Author

ghost commented Jun 25, 2020

Updated to be more realistic.

@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 27, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 May 19, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 1.1.0 Nov 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

3 participants