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

Split swiftmodule and object generation #241

Closed
burakcoskun opened this issue May 24, 2019 · 6 comments
Closed

Split swiftmodule and object generation #241

burakcoskun opened this issue May 24, 2019 · 6 comments

Comments

@burakcoskun
Copy link

I have read the code a bit. Right now we are calling one compile action for a swift_library which produces both object and swiftmodule files. Then we propagate swift_module files with providers and we register object file to be linked.

Given that swift_library rules only depend on swiftmodule files and swiftmodule generation is taking roughly half the time of generating object files. We can run 2 compilation actions per swift_library. One to generate swiftmodule and one to generate object files. And we can unlock dependent swift_library rules once the swiftmodule is generated.

We added this to buckbuild swift rules and we have seen roughly 15% speed increase in our swift builds with the 6 core mac minis. Since it doubles the number of actions advantage of this increases with the number of processes we can run concurrently. And if we are using remote execution this should help much more than with 6 core mac minis.

This can be optional with a config to turn on/off

@allevato
Copy link
Member

This is definitely something I've thought about. My latest focus has been on improving incremental compilation, though. Do you know how this split mode would interact with -incremental? My hunch is that they're not compatible but I haven't explored it yet.

If it's not compatible with incremental mode, then that poses a slight problem because there's no way for the build rules to know at analysis time whether Bazel is going to be running the action in worker mode or not (the strategy decision isn't made until execution time, after the actions have already been registered). That means that users would have to keep two different flags in sync—the SwiftCompile strategy and this new flag—to build correctly, and that's not a very appealing UI.

@kastiglione
Copy link
Contributor

kastiglione commented May 24, 2019

There's a bug that blocks this. Passing -enable-batch-mode in an invocation that has -emit-module but not -emit-object, results in swiftc constructing a frontend action that doesn't create all partial swiftmodules. The merge-module action then fails. Using -wmo works, as does leaving off both -wmo and -enable-batch-mode, but that is very slow.

@burakcoskun
Copy link
Author

This is definitely something I've thought about. My latest focus has been on improving incremental compilation, though. Do you know how this split mode would interact with -incremental? My hunch is that they're not compatible but I haven't explored it yet.

Wow I didn't even know incremental builds would work with bazel. I have looked at your commit about incremental mode: c197356 . So if I understand it correctly you are maintaining a separate file tree which you redirect compiler outputs and you copy necessary files from there to bazel needed paths.

In my view splitting swiftmodule and object generation should not break incremental builds, because we are not changing the output of a swift_library we just generate them separately. I hope as long as we redirect swiftmodule and object files to their correct paths to make incremental build work for subsequent builds I think we should be good to go.

Though I am not very knowledgable about compilers and these stuff and could be missing some important parts.

That means that users would have to keep two different flags in sync—the SwiftCompile strategy and this new flag—to build correctly, and that's not a very appealing UI.

I see, agreed.

There's a bug that blocks this. Passing -enable-batch-mode in an invocation that has -emit-module but not -emit-object, results in swiftc constructing a frontend action that doesn't create all partial swiftmodules. The merge-module action then fails. Using -wmo works, as does leaving off both -wmo and -enable-batch-mode, but that is very slow.

well that's bad :( I don't know most of those modes. We use this with -wmo on buckbuild.

btw, im living in European time and sorry for my late responses.

@burakcoskun
Copy link
Author

burakcoskun commented May 27, 2019

but with incremental we will have more compile commands with less number of source files right?
For that case splitting compile command into two probably wouldn't help, we already have (fast-many compiles) we will double the number of compile commands but we wouldn't gain too much speed i guess.

Maybe it wouldn't be helpful but it would work with incremental mode.

Is incremental build only for local builds(i guess) or both local and remote execution?

If it is only for local, splitting should help in remote execution

@keith
Copy link
Member

keith commented Oct 12, 2020

#504

@keith
Copy link
Member

keith commented Oct 20, 2020

Please try this out with the new swift.split_derived_files_generation feature and file any issues you find!

@keith keith closed this as completed Oct 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants