10 ms·
Closing the gap: cross-language LTO between Rust and C/C++
- angrygoat 7y agoThis is awesome, especially with the gains for Firefox, but this bit seemed odd to me: > We quickly learned, however, that the LLVM linker plugin crashes with a segmentation fault when trying to perform another round of ThinLTO on a module that had already gone through the process. It sounds like they worked around this, rather than fixing the segfault and putting some error handling in place? Might make it easier for the next bunch of people working in this part of clang.
- xiphias2 7y agoYou're right, but it still looks like a big improvement. It means that Firefox devs can write every new functionality in Rust, no matter how small it is.
- phkahler 7y ago>> It means that Firefox devs can write every new functionality in Rust, no matter how small it is. True, but they should still focus on oxidizing whole modules and subsystems in their entirety whenever possible.
- bla3 7y ago> No problem, we thought and instructed the Rust compiler to disable its own ThinLTO pass when compiling for the cross-language case and indeed everything was fine -- until the segmentation faults mysteriously returned a few weeks later even though ThinLTO was still disabled. [...] Since then ThinLTO is turned off for libstd by default. Instead of fixing the crash, they landed a workaround. > We learned that all LLVM versions involved really have to be a close match in order for things to work out. The Rust compiler's documentation now offers a compatibility table for the various versions of Rust and Clang. It's cool they got it working, but it sounds like this is currently proof-of-concept quality and not very productionized yet. To me, the overall tone of the article sounds like they ran into a bunch of issues and opted for duct tape instead of systemic fixes. Which is fine to get things off the ground, of course! But I hope they take the time to go back and fix the underlying issues they ran into too.
- pornel 7y agoThe long-term plan for Rust is to treat its standard library (almost) like any other crate, so it could be recompiled with your custom compiler settings if necessary. However, libstd is by necessity tied quite closely to the compiler, it's one of the oldest and most fundamental parts of the stack, and there are tons of little complications around making it "just" a crate, so changes to libstd/rustc/Cargo necessary to make that possible will take longer. In the meantime, changing one problematic compiler flag seems like a sensible solution.
- dblohm7 7y agoThe low-level tools team consistently reports bugs against the upstream projects. I have no doubt that they did so during the course of this project.
- pcwalton 7y agoThis isn't anything new. Rust has had to land workarounds for lots of LLVM issues in its history. For example, Rust had to stop using noalias on function parameters because LLVM miscompiled too many functions with it, as Rust can use it way more than C/C++ do and therefore it didn't receive much upstream test coverage.
- bla3 7y agoRust could fix upstream issues it runs into, no?
- throwupaway123 7y agoThey actually do sometimes AFAIK
- bzbarsky 7y agoThey could, and they do. That said, they don't have infinite time, and if, as in this case, the upstream fix would: (1) be pretty involved and (2) be very likely to get regressed because upstream doesn't have the capability to run tests that would prevent that (e.g. because upstream only runs C++ compilation tests and there is no way to exercise the relevant bugs via C++ code), then investing in fixing upstream may not be the right tradeoff. In theory, one could first change upstream's test harness to allow Rust code, but that involves upstream tests depending on the Rust compiler frontend, which apart from being a technical problem is probably a political one. Maybe it would have been possible to do upstream tests via bitcode source instead of Rust or C++; I don't know about LLVM to say offhand. But in either case this is not as easy as just "fix a simple upstream bug"...
- pornel 7y agoIt's nice to see such post on the LLVM blog (as opposed to typical Rust-only outlets). Feels like recognition that Rust is a serious and important LLVM user.
- Mathnerd314 7y agoI looked through the archives and only GHC/Haskell and LLILC have made it: http://blog.llvm.org/2010/05/glasgow-haskell-compiler-and-llvm.html http://blog.llvm.org/2010/05/glasgow-haskell-compiler-and-ll... http://blog.llvm.org/2015/04/llilc-llvm-based-compiler-for-dotnet.html http://blog.llvm.org/2015/04/llilc-llvm-based-compiler-for-d... But I think the limitation is on developers willing to write a blog post rather than "serious" development. Excluding "LLVM Weekly" which has since moved to http://llvmweekly.org/ http://llvmweekly.org/, there's been less than 1 post per month, even though LLVM conferences have grown significantly in size.
- masklinn 7y agoNow if only LLVM could feel it was important enough to make noalias work reliably.
- fluffything 7y agoLLVM devs don't really care about Rust. They haven't fixed noalias in years, there isn't still a freeze intrinsic in the IR, the LLVM-IR semantics are often not documented enough for the Rust compiler to know whether it is generating IR that has UB or not... I see a couple of Rust developers working on LLVM almost full-time (like nikic), but there should be more. The Rust language needs to become a more important stakeholder, and for that it needs more paid full-time LLVM developers, infinite loops are UB in LLVM-IR...
- ncmncm 7y agoLLVM developers are focused on the needs of (literally!) millions of C and C++ programmers. Until you can point to a few hundred-thousand production Rust coders, or get somebody with deep pockets to depend on it, Rust is just not important enough. The solution is to fund your own LLVM developers. If you can't raise the money to pay them, who should? People with deep pockets are typically advised not to depend on unsupported infrastructure. It is hard and, often, unwise to argue with such advice. It is still early days. Give it ten years: Rust will either have taken off or sunk, by then. Maybe somewhere in those years there will be some new hotness to jump on instead.
- jokoon 7y agoI'm not a huge fan of rust, but that would make rust much more attractive and simple to use. Keeping C++ software while making sure important parts are bug free sounds awesome...
- mlindner 7y agoYou don't have to love Rust to still use it in specific narrow areas.
- azakai 7y agoThe need to use "compatible" versions of LLVM between the C++ and Rust compilers is scary. Anything aside from the exact same LLVM revision could in theory lead to bad results, including bugs or security vulnerabilities (if LLVM changes the meaning of something in its IR). This isn't Rust or Clang's fault, of course, it's just a consequence of using LLVM IR as the data for LTO, that LLVM IR has no backwards compatibility guarantees, and that Rust is out-of-tree for LLVM. In theory using a stable format for LTO would avoid issues like this. Wasm is one option that has working cross-language inlining already today, but on the other hand it has less rich an IR, and the optimizers are less powerful than LLVM.
- bla3 7y agoLLVM bitcode is backwards compatible. It is however not forward compatible, so the linker needs to understand the newer bitcode format that clang and rustc use.
- azakai 7y agoThe issue isn't of being able to load the bitcode (which LLVM has gotten pretty good at supporting in a backwards compatible way). It's that the meaning of things might change, undefined behavior may be handled differently, and so forth. In other words a newer optimizer running on older IR may emit broken code.
- bla3 7y agoI thought bitcode backwards compat included that too. If it didn't, Apple's collecting bitcode for watch apps for transparent 64-bit support wouldn't work.
- azakai 7y agoIt's possible to try to support that, but you can never be sure. For example, imagine that LLVM has a known bug with some pass, and it has a workaround somewhere else that disables generating IR that would hit that bug. A different version of LLVM may fix that bug, and remove the workaround - but then optimizing bitcode from another version could be vulnerable. Another example is undefined behavior in LLVM IR. It may be handled differently in different versions, and it's hard to know what might happen from mixing them. In general, LLVM is heavily tested - on each revision. I'm not aware of any large-scale project that tests all LLVM versions on LLVM IR from all other versions. That's untested. I'd be afraid to rely on that. I don't know what Apple does with user-supplied bitcode, but if I were them I'd be recompiling old bitcode with the old LLVM that matches it, or something else (like subset the bitcode to remove undefined behavior, etc.).
- zelly 7y agoRust needs easy interop with C++'s ABI. Easy as in I should be able to "import Boost" and have it all mapped to Rust structures without doing anything. A big reason C++ took off was backward compatibility with C. Network effects. Today C++ has the role that C had in the 80s. No one uses any other compiler but LLVM for Rust anyway, so who cares about compatibility with MSVC and others. This will also force adoption of LLVM, which can be a good incentive for LLVM to support it.
- khuey 7y agoAll FFI in Rust requires `unsafe` so it's impossible to do this "without doing anything".
- deleted 7y ago[deleted]
- comex 7y agoI think this is both possible and desirable. Basically, create a bridge between rustc and Clang, kind of like Swift's C importer, but far more complex in order to be able to do things like instantiate C++ templates on demand (perhaps even with Rust types as arguments!). However, it would also be extremely hard; I don't think any programming language has ever created such a tight bridge to C++. The existing approaches I've seen are: - Swig, rust-bindgen, etc.: Pass through auto-generated C ABI wrappers; support for generics is limited and requires declaring up front what types you want to instantiate them with. - D: You can bind directly to C++ if you rewrite your C++ header in D, generics and all... including the implementations of all inline functions. Both very limited, especially in template-happy modern C++.
- Jaxan 7y agoThere was Objective-C++, which combined Objective-C and C++. You could literally write both languages mixed together. Honestly, it was a Frankenstein monster. The semantics were very vague (especially since C++ uses raii and obj-c uses reference counting in a garbage pool).
- 7y ago