{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/35437","repository_url":"https://api.github.com/repos/rust-lang/rust","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/35437/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/35437/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/35437/events","html_url":"https://github.com/rust-lang/rust/issues/35437","id":169770661,"number":35437,"title":"Port `compiler-rt` intrinsics to Rust","user":{"login":"japaric","id":5018213,"avatar_url":"https://avatars.githubusercontent.com/u/5018213?v=3","gravatar_id":"","url":"https://api.github.com/users/japaric","html_url":"https://github.com/japaric","followers_url":"https://api.github.com/users/japaric/followers","following_url":"https://api.github.com/users/japaric/following{/other_user}","gists_url":"https://api.github.com/users/japaric/gists{/gist_id}","starred_url":"https://api.github.com/users/japaric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/japaric/subscriptions","organizations_url":"https://api.github.com/users/japaric/orgs","repos_url":"https://api.github.com/users/japaric/repos","events_url":"https://api.github.com/users/japaric/events{/privacy}","received_events_url":"https://api.github.com/users/japaric/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":12,"created_at":"2016-08-06T22:59:55Z","updated_at":"2016-08-08T19:23:32Z","closed_at":null,"body":"## Rationale\r\n\r\n> Porting `compiler-rt` to Rust is one of the remaining obstacles towards the intersection of our \"on the fly compilation of std\" and \"rust everywhere\" dreams.\r\n\r\nFor our goal of \"on the fly compilation of std\" (or any other set of \"standard\" crates), we want to minimize the number of C dependencies required to build `std` as these complicate the compilation process: users need a C (cross) compiler and we (rust-lang/rust) have to support (cross) compiling each of these C dependencies, which are wrapped in crates, to every target (even custom ones!) that downstream users may use -- this last part leads to [complicated `build.rs` scripts][0] that need to handle [conditional compilation logic][1] and deal with [obscure `gcc` flags][2] . On Linux, there are three C dependencies that we have to deal with: `backtrace`, `jemalloc` and `compiler-rt`. `backtrace` and `jemalloc` are optional on Linux and not available on some other platforms but `compiler-rt` is mandatory on most (all?) the targets we support.\r\n\r\nThis issue is about porting `compiler-rt` to Rust. Once ported, we can say goodbye to its complicated `build.rs` and make `std` easier to (cross) compile! An extra advantage is that, with this change, the compiler-rt intrinsics will receive the same optimizations as the `std` crate. This is not done today because it would make the `build.rs` even more complicated: flags like `-march` and `-mcpu` would have to be conditionally passed to `gcc` according to `$TARGET`.\r\n\r\n[0]: https://github.com/japaric/rust/blob/rustc-builtins/src/librustc_builtins/build.rs\r\n[1]: https://github.com/japaric/rust/blob/rustc-builtins/src/librustc_builtins/build.rs#L184-L395\r\n[2]: https://github.com/japaric/rust/blob/rustc-builtins/src/librustc_builtins/build.rs#L76-L89\r\n\r\n## The process\r\n\r\nThe goal is simple: We have to port [each and every compiler-rt intrinsic][3] along with [their tests][4] to the `rustc-builtins` crate.\r\n\r\n[3]: https://github.com/rust-lang/compiler-rt/tree/8598065bd965d9713bfafb6c1e766d63a7b17b89/lib/builtins\r\n[4]: https://github.com/rust-lang/compiler-rt/tree/8598065bd965d9713bfafb6c1e766d63a7b17b89/test/builtins/Unit\r\n\r\nThe process could go two ways:\r\n\r\n1. Using a \"wholesale\" approach: We can develop the new `rustc-builtins` crate out of tree: porting intrinsics and unit tests over time. Once all the intrinsics and unit tests are ported we can replace the in-tree `rustc-builtins` crate with the out-of-tree one and have the buildbots (and probably crater) serve as an integration test.\r\n  \r\n2. Using an incremental approach: We can rely on the fact that `gcc_s` provides the same intrinsics as `compiler-rt` and simply remove `rustc-builtins`'s `build.rs`. This effectively means that `rustc-builtins` will no longer provide any intrinsic and that `std` programs will instead use `gcc_s`' intrinsics. Then we can start porting intrinsics + unit tests and adding them to `rustc-builtins` one by one. Each time a intrinsic is added, Rust programs will start using that intrinsic instead of the `gcc_s`' one.\r\n  \r\nThe advantage of (2) is that we get an `std` that's easy to cross compile early on (because `rustc-builtins` is essentially empty!). Its disadvantage is that `no_std` programs which don't link to `gcc_s` and that depend on `compiler-rt` intrinsics will abruptly stop to compile because of linker errors (undefined reference to `$intrinsic`).\r\n  \r\n## Prioritization\r\n\r\nSome Rust targets use more or different intrinsics than others. If we take the incremental approach mentioned in the previous section, it makes sense to prioritize porting the intrinsics required by tier-1 platforms. [This gist][5] contains a \"hack\" to yields the list of intrinsics required to link `rustc` for a certain target plus lists of intrinsics generated with this \"hack\" for a few (right now, two) targets. The lists contained therein can be used to decide which intrinsics to prioritize.\r\n\r\n[5]: https://gist.github.com/japaric/9b5d41921b775e270bc02aa04aeb858d\r\n\r\n## Drawbacks\r\n\r\nOn each LLVM upgrade, we would have to carefully check if any compiler-rt intrinsics have been added (we already have to do this today) and the upgrade would be blocked on porting those new intrinsics to Rust first (this is the extra work that this change would create). \r\n\r\n## Unresolved questions\r\n\r\n- Pick an approach to implement this change.\r\n\r\n### `compilerrt_abort`\r\n\r\nSome intrinsics can fail (e.g. `absvdi2`). `compiler-rt` handles the failures by \"aborting\" -- it calls a [`compilerrt_abort()`][6] function. Should this function be ported to Rust? Or should the intrinsics, instead, `panic!` on failure?\r\n\r\n[6]: https://github.com/rust-lang/compiler-rt/blob/8598065bd965d9713bfafb6c1e766d63a7b17b89/lib/builtins/int_util.c#L26-L59\r\n\r\n---\r\n\r\ncc @alexcrichton @brson"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/238347781","html_url":"https://github.com/rust-lang/rust/issues/35437#issuecomment-238347781","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/35437","id":238347781,"user":{"login":"japaric","id":5018213,"avatar_url":"https://avatars.githubusercontent.com/u/5018213?v=3","gravatar_id":"","url":"https://api.github.com/users/japaric","html_url":"https://github.com/japaric","followers_url":"https://api.github.com/users/japaric/followers","following_url":"https://api.github.com/users/japaric/following{/other_user}","gists_url":"https://api.github.com/users/japaric/gists{/gist_id}","starred_url":"https://api.github.com/users/japaric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/japaric/subscriptions","organizations_url":"https://api.github.com/users/japaric/orgs","repos_url":"https://api.github.com/users/japaric/repos","events_url":"https://api.github.com/users/japaric/events{/privacy}","received_events_url":"https://api.github.com/users/japaric/received_events","type":"User","site_admin":false},"created_at":"2016-08-08T19:23:32Z","updated_at":"2016-08-08T19:23:32Z","body":"@shepmaster \r\n\r\n`#[linkage = \"weak\"]` does the trick (on Linux at least):\r\n\r\n``` rust\r\n#[linkage = \"weak\"]\r\n#[no_mangle]\r\npub extern fn memfoo() {}\r\n```\r\n\r\n```\r\n$ nm target/debug/libfoo.rlib\r\n0000000000000000 W memfoo\r\n0000000000000000 N __rustc_debug_gdb_scripts_section__\r\n```\r\n\r\n@alexcrichton Sounds good to me. One thing I like about having `rustc-builtins` in its own repo is that I've set up testing infrastructure (Travis + AppVeyor) to test the intrinsics for several targets (using QEMU), which I think is not trivial to integrate with the buildbots. Also, fast test times. Perhaps we can keep this advantage if we turn `rustc-builtins` into a submodule."}}
{"actor":{"display_login":"japaric"}}