Skip to content
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

make translate-c self-hosted #1964

Closed
3 tasks done
andrewrk opened this issue Feb 15, 2019 · 10 comments
Closed
3 tasks done

make translate-c self-hosted #1964

andrewrk opened this issue Feb 15, 2019 · 10 comments
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals. enhancement Solving this issue will likely involve adding new logic or components to the codebase. frontend Tokenization, parsing, AstGen, Sema, and Liveness. stage1 The process of building from source via WebAssembly and the C backend. standard library This issue involves writing Zig code for the standard library. translate-c C to Zig source translation feature (@cImport)
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Feb 15, 2019

Here's the plan:

  1. Separate translate_c.cpp into zig_clang.h/zig_clang.cpp and translate_c.cpp. The wrapper simply creates a C interface on top of the C++ clang API, and translate_c.cpp goes through the wrapper API. This transition is complete.
  2. Create src-self-hosted/clang.zig which is a Zig version of the src/zig_clang.h file. These will have to be kept in sync in order to prevent a dependency loop.
  3. Port src/translate_c.cpp to src-self-hosted/translate_c.zig and then delete src/translate_c.cpp. This step was completed by @Vexu in Translate-c-2 the rest #3935.

Currently, zig translate-c and @cImport are implemented with translate_c.cpp and zig translate-c-2 is implemented with translate_c.zig. There will be a separate set of translate-c tests specifically for the Zig implementation, until finally the Zig implementation passes all the tests and step 3 is completed.

@andrewrk andrewrk added enhancement Solving this issue will likely involve adding new logic or components to the codebase. standard library This issue involves writing Zig code for the standard library. frontend Tokenization, parsing, AstGen, Sema, and Liveness. stage1 The process of building from source via WebAssembly and the C backend. labels Feb 15, 2019
@andrewrk andrewrk added this to the 0.5.0 milestone Feb 15, 2019
@andrewrk
Copy link
Member Author

I did a sort of proof-of-concept with zig fmt in ba56f36

andrewrk added a commit that referenced this issue Feb 16, 2019
@andrewrk
Copy link
Member Author

andrewrk commented Feb 16, 2019

I started on step 1 in 356cfa0. The last puzzle piece to fit in here is that, until we get self-hosted and start shipping stage2 (#89), we will have an interesting build process:

  • Build zig/zig.exe - the stage1 compiler with @cImport and translate-c capabilities disabled.
  • One of the artifacts from the previous step is zig_cpp.a/zig_cpp.lib. Using that and .zig translate-c source code, build translate_c.a/translate_c.lib.
  • Build zig/zig.exe - the stage1 compiler again, this time with @cImport and translate-c capabilities enabled. Link with translate_c.a/translate_c.lib.

I will note this negates the "small stage1 performance price today" I mentioned earlier. We can have our 🍰 and eat it too!

andrewrk added a commit that referenced this issue Feb 17, 2019
@andrewrk
Copy link
Member Author

andrewrk commented Feb 17, 2019

Marking this as contributor friendly since you can follow the pattern I've started in the latest commit (c3c92ca). The goal is to delete these lines from translate_c.cpp:

#include <clang/Frontend/ASTUnit.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/AST/Expr.h>

Instead relying only on the decls in zig_clang.h. Once that's done we can proceed to steps 2 and 3. If you want to contribute on this you can look for clang::Foo in translate_c.cpp and try to make the code use decls from zig_clang.h instead of the clang::Foo thing.

@andrewrk andrewrk added the contributor friendly This issue is limited in scope and/or knowledge of Zig internals. label Feb 17, 2019
andrewrk added a commit that referenced this issue Apr 11, 2019
@andrewrk
Copy link
Member Author

andrewrk commented Apr 11, 2019

C API Progress Bar (grep 'clang::' ../src/translate_c.cpp | wc -l and then 1137 minus that number out of 1137):

  • 100%

andrewrk added a commit that referenced this issue Apr 11, 2019
andrewrk added a commit that referenced this issue Apr 12, 2019
andrewrk added a commit that referenced this issue Apr 12, 2019
andrewrk added a commit that referenced this issue Apr 12, 2019
andrewrk added a commit that referenced this issue Apr 12, 2019
andrewrk added a commit that referenced this issue Apr 15, 2019
andrewrk added a commit that referenced this issue Apr 16, 2019
andrewrk added a commit that referenced this issue Apr 16, 2019
This modifies the build process of Zig to put all of the source files
into libcompiler.a, except main.cpp and userland.cpp.

Next, the build process links main.cpp, userland.cpp, and libcompiler.a
into zig1. userland.cpp is a shim for functions that will later be
replaced with self-hosted implementations.

Next, the build process uses zig1 to build src-self-hosted/stage1.zig
into libuserland.a, which does not depend on any of the things that
are shimmed in userland.cpp, such as translate-c.

Finally, the build process re-links main.cpp and libcompiler.a, except
with libuserland.a instead of userland.cpp. Now the shims are replaced
with .zig code. This provides all of the Zig standard library to the
stage1 C++ compiler, and enables us to move certain things to userland,
such as translate-c.

As a proof of concept I have made the `zig zen` command use text defined
in userland. I added `zig translate-c-2` which is a work-in-progress
reimplementation of translate-c in userland, which currently calls
`std.debug.panic("unimplemented")` and you can see the stack trace makes
it all the way back into the C++ main() function (Thanks LemonBoy for
improving that!).

This could potentially let us move other things into userland, such as
hashing algorithms, the entire cache system, .d file parsing, pretty
much anything that libuserland.a itself doesn't need to depend on.

This can also let us have `zig fmt` in stage1 without the overhead
of child process execution, and without the initial compilation delay
before it gets cached.

See #1964
@andrewrk
Copy link
Member Author

Now that #2295 is merged, all the proofs of concept are completed, the plan is working, and the rest of this issue is just porting the C++ translate-c code to Zig. We have zig translate-c-2 coexisting with zig translate-c for now. Once the self-hosted version is on par with the C++ version we'll delete the C++ version.

andrewrk added a commit that referenced this issue Apr 26, 2019
Also breaking std lib API change: the return value of
std.zig.parse returns `*ast.Tree` rather than `ast.Tree`.

See #1964
andrewrk added a commit that referenced this issue Apr 27, 2019
Previously, `zig fmt` on the stage1 compiler (which is what we currently
ship) would perform what equates to `zig run std/special/fmt_runner.zig`

Now, `zig fmt` is implemented with the hybrid zig/C++ strategy outlined
by #1964.

This means Zig no longer has to ship some of the stage2 .zig files, and
there is no longer a delay when running `zig fmt` for the first time.
@andrewrk
Copy link
Member Author

Progress:
Screenshot_2019-04-30_00-26-03

@andrewrk andrewrk changed the title a plan to make stage1 and stage2/3 share translate-c code (migrate translate-c to userland) migrate translate-c to userland Apr 30, 2019
@andrewrk andrewrk changed the title migrate translate-c to userland make translate-c self-hosted Apr 30, 2019
@andrewrk
Copy link
Member Author

andrewrk commented May 9, 2019

Progress:

[nix-shell:~/downloads/zig/build]$ cat foo.c
void foo(void);
int x;

[nix-shell:~/downloads/zig/build]$ ./zig translate-c-2 foo.c 
// foo.c:1:6: warning: unsupported type: 'FunctionProto'
// foo.c:1:6: warning: unable to resolve prototype of function 'foo'
// foo.c:2:5: warning: TODO implement translate-c for variables

@andrewrk
Copy link
Member Author

Progress:

[nix-shell:~/downloads/zig/build]$ cat foo.c
int x;
void __attribute__((noreturn)) foo(void);

[nix-shell:~/downloads/zig/build]$ ./zig translate-c-2 foo.c
// foo.c:1:5: warning: TODO implement translate-c for variables
extern fn () noreturn;
// foo.c:2:32: warning: TODO implement more translate-c for function decls

andrewrk added a commit that referenced this issue May 10, 2019
andrewrk added a commit that referenced this issue May 11, 2019
stage1 translate-c actually has this wrong. When exporting a function,
it's ok to use empty parameters. But for prototypes, "no prototype"
means that it has to be emitted as a function that accepts anything,
e.g. extern fn foo(...) void;

See #1964
@andrewrk andrewrk added the translate-c C to Zig source translation feature (@cImport) label Jun 16, 2019
@andrewrk andrewrk modified the milestones: 0.5.0, 0.6.0 Aug 21, 2019
@shawnl
Copy link
Contributor

shawnl commented Sep 30, 2019

My "get_c_type for vectors" patch allows generating header files for @Vector() arguments and return values, but we also need support interfacing with libclang's parsing of Vector. #2945 (Can't link to patch, cause this patch-set is getting constantly rebased)

  • Vector type support for header files

(trying to translate use of vector types is probably not worth it)

andrewrk added a commit that referenced this issue Oct 2, 2019
andrewrk added a commit that referenced this issue Oct 2, 2019
See #1964

translate_c.cpp now exclusively uses the clang API via zig_clang.h

shaves off 5 seconds from building zig when translate_c.cpp
(or any h files it uses) change.
@andrewrk
Copy link
Member Author

andrewrk commented Jan 2, 2020

Huge thanks to @Vexu for doing most of the porting of translate-c to stage2!

This project is now complete.

@andrewrk andrewrk closed this as completed Jan 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contributor friendly This issue is limited in scope and/or knowledge of Zig internals. enhancement Solving this issue will likely involve adding new logic or components to the codebase. frontend Tokenization, parsing, AstGen, Sema, and Liveness. stage1 The process of building from source via WebAssembly and the C backend. standard library This issue involves writing Zig code for the standard library. translate-c C to Zig source translation feature (@cImport)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants