From 7e6c9f363501c49d3a1f666d85d41891f50890b8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 22 Jun 2017 13:14:00 -0700 Subject: [PATCH] Switch to rust-lang-nursery/compiler-builtins This commit migrates the in-tree `libcompiler_builtins` to the upstream version at https://github.com/rust-lang-nursery/compiler-builtins. The upstream version has a number of intrinsics written in Rust and serves as an in-progress rewrite of compiler-rt into Rust. Additionally it also contains all the existing intrinsics defined in `libcompiler_builtins` for 128-bit integers. It's been the intention since the beginning to make this transition but previously it just lacked the manpower to get done. As this PR likely shows it wasn't a trivial integration! Some highlight changes are: * The PR rust-lang-nursery/compiler-builtins#166 contains a number of fixes across platforms and also some refactorings to make the intrinsics easier to read. The additional testing added there also fixed a number of integration issues when pulling the repository into this tree. * LTO with the compiler-builtins crate was fixed to link in the entire crate after the LTO process as these intrinsics are excluded from LTO. * Treatment of hidden symbols was updated as previously the `#![compiler_builtins]` crate would mark all symbol *imports* as hidden whereas it was only intended to mark *exports* as hidden. --- .gitmodules | 6 +- src/Cargo.lock | 1 - src/bootstrap/bin/rustc.rs | 19 +- src/bootstrap/bootstrap.py | 2 +- src/bootstrap/dist.rs | 2 +- src/build_helper/lib.rs | 5 +- src/ci/init_repo.sh | 7 +- src/compiler-rt | 1 - .../library-features/compiler-builtins-lib.md | 35 - src/libcompiler_builtins | 1 + src/libcompiler_builtins/Cargo.toml | 19 - src/libcompiler_builtins/build.rs | 423 ---------- src/libcompiler_builtins/lib.rs | 721 ------------------ src/libprofiler_builtins/build.rs | 2 +- src/librustc_trans/attributes.rs | 2 +- src/librustc_trans/back/link.rs | 27 +- src/librustc_trans/back/write.rs | 3 +- src/librustc_trans/declare.rs | 11 - src/librustc_trans/trans_item.rs | 12 + src/libstd/Cargo.toml | 2 +- src/rustc/compiler_builtins_shim/Cargo.toml | 24 + .../compiler_builtins_shim/build.rs} | 13 +- src/test/run-pass/lib-defaults.rs | 9 +- src/test/run-pass/rfc1717/library-override.rs | 7 +- src/tools/tidy/src/lib.rs | 1 + 25 files changed, 110 insertions(+), 1245 deletions(-) delete mode 160000 src/compiler-rt delete mode 100644 src/doc/unstable-book/src/library-features/compiler-builtins-lib.md create mode 160000 src/libcompiler_builtins delete mode 100644 src/libcompiler_builtins/Cargo.toml delete mode 100644 src/libcompiler_builtins/build.rs delete mode 100644 src/libcompiler_builtins/lib.rs create mode 100644 src/rustc/compiler_builtins_shim/Cargo.toml rename src/{test/run-pass/auxiliary/clibrary.rs => rustc/compiler_builtins_shim/build.rs} (62%) diff --git a/.gitmodules b/.gitmodules index 1ef3c086a1c..6244b3c0951 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,9 +2,6 @@ path = src/llvm url = https://github.com/rust-lang/llvm.git branch = master -[submodule "src/compiler-rt"] - path = src/compiler-rt - url = https://github.com/rust-lang/compiler-rt.git [submodule "src/rt/hoedown"] path = src/rt/hoedown url = https://github.com/rust-lang/hoedown.git @@ -33,3 +30,6 @@ [submodule "src/tools/rls"] path = src/tools/rls url = https://github.com/rust-lang-nursery/rls.git +[submodule "src/libcompiler_builtins"] + path = src/libcompiler_builtins + url = https://github.com/rust-lang-nursery/compiler-builtins diff --git a/src/Cargo.lock b/src/Cargo.lock index 2d42903ad0a..cf4c3dce6e3 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -273,7 +273,6 @@ dependencies = [ name = "compiler_builtins" version = "0.0.0" dependencies = [ - "build_helper 0.1.0", "core 0.0.0", "gcc 0.3.51 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 8c6eaee24f2..fbb2ae29ef2 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -142,6 +142,11 @@ fn main() { } } + let crate_name = args.windows(2) + .find(|a| &*a[0] == "--crate-name") + .unwrap(); + let crate_name = &*crate_name[1]; + // If we're compiling specifically the `panic_abort` crate then we pass // the `-C panic=abort` option. Note that we do not do this for any // other crate intentionally as this is the only crate for now that we @@ -150,9 +155,7 @@ fn main() { // This... is a bit of a hack how we detect this. Ideally this // information should be encoded in the crate I guess? Would likely // require an RFC amendment to RFC 1513, however. - let is_panic_abort = args.windows(2) - .any(|a| &*a[0] == "--crate-name" && &*a[1] == "panic_abort"); - if is_panic_abort { + if crate_name == "panic_abort" { cmd.arg("-C").arg("panic=abort"); } @@ -167,7 +170,15 @@ fn main() { Ok(s) => if s == "true" { "y" } else { "n" }, Err(..) => "n", }; - cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions)); + + // The compiler builtins are pretty sensitive to symbols referenced in + // libcore and such, so we never compile them with debug assertions. + if crate_name == "compiler_builtins" { + cmd.arg("-C").arg("debug-assertions=no"); + } else { + cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions)); + } + if let Ok(s) = env::var("RUSTC_CODEGEN_UNITS") { cmd.arg("-C").arg(format!("codegen-units={}", s)); } diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index eaf2a40f2fa..ebc4c2fdf7b 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -583,7 +583,7 @@ class RustBuild(object): (self.get_toml('jemalloc') or self.get_mk('CFG_JEMALLOC_ROOT'))))] run(["git", "submodule", "update", - "--init"] + submodules, + "--init", "--recursive"] + submodules, cwd=self.rust_root, verbose=self.verbose) run(["git", "submodule", "-q", "foreach", "git", "reset", "-q", "--hard"], diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 753bd1df0d8..3bf1b82b0a8 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -564,10 +564,10 @@ pub fn rust_src(build: &Build) { "src/libstd", "src/libstd_unicode", "src/libunwind", + "src/rustc/compiler_builtins_shim", "src/rustc/libc_shim", "src/libtest", "src/libterm", - "src/compiler-rt", "src/jemalloc", "src/libprofiler_builtins", ]; diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index ea6a822e360..7011261ab6c 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -239,7 +239,10 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str) -> Result return Err(()), }; - native_lib_boilerplate("compiler-rt", sanitizer_name, &link_name, search_path) + native_lib_boilerplate("libcompiler_builtins/compiler-rt", + sanitizer_name, + &link_name, + search_path) } fn dir_up_to_date(src: &Path, threshold: &FileTime) -> bool { diff --git a/src/ci/init_repo.sh b/src/ci/init_repo.sh index 817ed8dd554..f8e86986f82 100755 --- a/src/ci/init_repo.sh +++ b/src/ci/init_repo.sh @@ -67,13 +67,14 @@ for module in $modules; do mv "src/llvm-$commit" src/llvm continue fi - if [ ! -d "$cache_src_dir/$module" ]; then + if [ ! -e "$cache_src_dir/$module/.git" ]; then echo "WARNING: $module not found in pristine repo" - retry sh -c "git submodule deinit -f $module && git submodule update --init $module" + retry sh -c "git submodule deinit -f $module && \ + git submodule update --init --recursive $module" continue fi retry sh -c "git submodule deinit -f $module && \ - git submodule update --init --reference $cache_src_dir/$module $module" + git submodule update --init --recursive --reference $cache_src_dir/$module $module" done travis_fold end update_submodules diff --git a/src/compiler-rt b/src/compiler-rt deleted file mode 160000 index c8a8767c56a..00000000000 --- a/src/compiler-rt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c8a8767c56ad3d3f4eb45c87b95026936fb9aa35 diff --git a/src/doc/unstable-book/src/library-features/compiler-builtins-lib.md b/src/doc/unstable-book/src/library-features/compiler-builtins-lib.md deleted file mode 100644 index 5da8968fd0c..00000000000 --- a/src/doc/unstable-book/src/library-features/compiler-builtins-lib.md +++ /dev/null @@ -1,35 +0,0 @@ -# `compiler_builtins_lib` - -The tracking issue for this feature is: None. - ------------------------- - -This feature is required to link to the `compiler_builtins` crate which contains -"compiler intrinsics". Compiler intrinsics are software implementations of basic -operations like multiplication of `u64`s. These intrinsics are only required on -platforms where these operations don't directly map to a hardware instruction. - -You should never need to explicitly link to the `compiler_builtins` crate when -building "std" programs as `compiler_builtins` is already in the dependency -graph of `std`. But you may need it when building `no_std` **binary** crates. If -you get a *linker* error like: - -``` text -$PWD/src/main.rs:11: undefined reference to `__aeabi_lmul' -$PWD/src/main.rs:11: undefined reference to `__aeabi_uldivmod' -``` - -That means that you need to link to this crate. - -When you link to this crate, make sure it only appears once in your crate -dependency graph. Also, it doesn't matter where in the dependency graph, you -place the `compiler_builtins` crate. - - - -``` rust,ignore -#![feature(compiler_builtins_lib)] -#![no_std] - -extern crate compiler_builtins; -``` diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins new file mode 160000 index 00000000000..238647af806 --- /dev/null +++ b/src/libcompiler_builtins @@ -0,0 +1 @@ +Subproject commit 238647af806470dc73e585c03682083931d29cd5 diff --git a/src/libcompiler_builtins/Cargo.toml b/src/libcompiler_builtins/Cargo.toml deleted file mode 100644 index 2c9cee5e7a0..00000000000 --- a/src/libcompiler_builtins/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -build = "build.rs" -name = "compiler_builtins" -version = "0.0.0" - -[lib] -name = "compiler_builtins" -path = "lib.rs" -test = false -bench = false -doc = false - -[dependencies] -core = { path = "../libcore" } - -[build-dependencies] -build_helper = { path = "../build_helper" } -gcc = "0.3.50" diff --git a/src/libcompiler_builtins/build.rs b/src/libcompiler_builtins/build.rs deleted file mode 100644 index 8fe79057bd8..00000000000 --- a/src/libcompiler_builtins/build.rs +++ /dev/null @@ -1,423 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Compiles the `compiler-rt` library, or at least the builtins part of it. -//! -//! Note that while compiler-rt has a build system associated with it, we -//! specifically don't use it here. The compiler-rt build system, written in -//! CMake, is actually *very* difficult to work with in terms of getting it to -//! compile on all the relevant platforms we want it to compile on. In the end -//! it became so much pain to work with local patches, work around the oddities -//! of the build system, etc, that we're just building everything by hand now. -//! -//! In general compiler-rt is just a bunch of intrinsics that are in practice -//! *very* stable. We just need to make sure that all the relevant functions and -//! such are compiled somewhere and placed in an object file somewhere. -//! Eventually, these should all be written in Rust! -//! -//! So below you'll find a listing of every single file in the compiler-rt repo -//! that we're compiling. We just reach in and compile with the `gcc` crate -//! which should have all the relevant flags and such already configured. -//! -//! The risk here is that if we update compiler-rt we may need to compile some -//! new intrinsics, but to be honest we surely don't use all of the intrinsics -//! listed below today so the likelihood of us actually needing a new intrinsic -//! is quite low. The failure case is also just that someone reports a link -//! error (if any) and then we just add it to the list. Overall, that cost is -//! far far less than working with compiler-rt's build system over time. - -extern crate build_helper; -extern crate gcc; - -use std::collections::BTreeMap; -use std::env; -use std::path::Path; -use build_helper::native_lib_boilerplate; - -struct Sources { - // SYMBOL -> PATH TO SOURCE - map: BTreeMap<&'static str, &'static str>, -} - -impl Sources { - fn new() -> Sources { - Sources { map: BTreeMap::new() } - } - - fn extend(&mut self, sources: &[&'static str]) { - // NOTE Some intrinsics have both a generic implementation (e.g. - // `floatdidf.c`) and an arch optimized implementation - // (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized - // implementation and discard the generic implementation. If we don't - // and keep both implementations, the linker will yell at us about - // duplicate symbols! - for &src in sources { - let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap(); - if src.contains("/") { - // Arch-optimized implementation (preferred) - self.map.insert(symbol, src); - } else { - // Generic implementation - if !self.map.contains_key(symbol) { - self.map.insert(symbol, src); - } - } - } - } -} - -fn main() { - let target = env::var("TARGET").expect("TARGET was not set"); - - // Emscripten's runtime includes all the builtins - if target.contains("emscripten") { - return; - } - - // Can't reuse `sources` list for the freshness check becuse it doesn't contain header files. - let native = match native_lib_boilerplate("compiler-rt", "compiler-rt", "compiler-rt", ".") { - Ok(native) => native, - _ => return, - }; - - let cfg = &mut gcc::Config::new(); - cfg.out_dir(&native.out_dir); - - if target.contains("msvc") { - // Don't pull in extra libraries on MSVC - cfg.flag("/Zl"); - - // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP - cfg.define("__func__", Some("__FUNCTION__")); - } else { - // Turn off various features of gcc and such, mostly copying - // compiler-rt's build system already - cfg.flag("-fno-builtin"); - cfg.flag("-fvisibility=hidden"); - // Accepted practice on Solaris is to never omit frame pointer so that - // system observability tools work as expected. In addition, at least - // on Solaris, -fomit-frame-pointer on sparcv9 appears to generate - // references to data outside of the current stack frame. A search of - // the gcc bug database provides a variety of issues surrounding - // -fomit-frame-pointer on non-x86 platforms. - if !target.contains("solaris") && !target.contains("sparc") { - cfg.flag("-fomit-frame-pointer"); - } - cfg.flag("-ffreestanding"); - cfg.define("VISIBILITY_HIDDEN", None); - } - - let mut sources = Sources::new(); - sources.extend(&["absvdi2.c", - "absvsi2.c", - "adddf3.c", - "addsf3.c", - "addvdi3.c", - "addvsi3.c", - "apple_versioning.c", - "ashldi3.c", - "ashrdi3.c", - "clzdi2.c", - "clzsi2.c", - "cmpdi2.c", - "comparedf2.c", - "comparesf2.c", - "ctzdi2.c", - "ctzsi2.c", - "divdc3.c", - "divdf3.c", - "divdi3.c", - "divmoddi4.c", - "divmodsi4.c", - "divsc3.c", - "divsf3.c", - "divsi3.c", - "divxc3.c", - "extendsfdf2.c", - "extendhfsf2.c", - "ffsdi2.c", - "fixdfdi.c", - "fixdfsi.c", - "fixsfdi.c", - "fixsfsi.c", - "fixunsdfdi.c", - "fixunsdfsi.c", - "fixunssfdi.c", - "fixunssfsi.c", - "fixunsxfdi.c", - "fixunsxfsi.c", - "fixxfdi.c", - "floatdidf.c", - "floatdisf.c", - "floatdixf.c", - "floatsidf.c", - "floatsisf.c", - "floatundidf.c", - "floatundisf.c", - "floatundixf.c", - "floatunsidf.c", - "floatunsisf.c", - "int_util.c", - "lshrdi3.c", - "moddi3.c", - "modsi3.c", - "muldc3.c", - "muldf3.c", - "muldi3.c", - "mulodi4.c", - "mulosi4.c", - "muloti4.c", - "mulsc3.c", - "mulsf3.c", - "mulvdi3.c", - "mulvsi3.c", - "mulxc3.c", - "negdf2.c", - "negdi2.c", - "negsf2.c", - "negvdi2.c", - "negvsi2.c", - "paritydi2.c", - "paritysi2.c", - "popcountdi2.c", - "popcountsi2.c", - "powidf2.c", - "powisf2.c", - "powixf2.c", - "subdf3.c", - "subsf3.c", - "subvdi3.c", - "subvsi3.c", - "truncdfhf2.c", - "truncdfsf2.c", - "truncsfhf2.c", - "ucmpdi2.c", - "udivdi3.c", - "udivmoddi4.c", - "udivmodsi4.c", - "udivsi3.c", - "umoddi3.c", - "umodsi3.c"]); - - if !target.contains("ios") { - sources.extend(&["absvti2.c", - "addvti3.c", - "ashlti3.c", - "ashrti3.c", - "clzti2.c", - "cmpti2.c", - "ctzti2.c", - "divti3.c", - "ffsti2.c", - "fixdfti.c", - "fixsfti.c", - "fixunsdfti.c", - "fixunssfti.c", - "fixunsxfti.c", - "fixxfti.c", - "floattidf.c", - "floattisf.c", - "floattixf.c", - "floatuntidf.c", - "floatuntisf.c", - "floatuntixf.c", - "lshrti3.c", - "modti3.c", - "multi3.c", - "mulvti3.c", - "negti2.c", - "negvti2.c", - "parityti2.c", - "popcountti2.c", - "subvti3.c", - "ucmpti2.c", - "udivmodti4.c", - "udivti3.c", - "umodti3.c"]); - } - - if target.contains("apple") { - sources.extend(&["atomic_flag_clear.c", - "atomic_flag_clear_explicit.c", - "atomic_flag_test_and_set.c", - "atomic_flag_test_and_set_explicit.c", - "atomic_signal_fence.c", - "atomic_thread_fence.c"]); - } - - if target.contains("msvc") { - if target.contains("x86_64") { - sources.extend(&["x86_64/floatdidf.c", "x86_64/floatdisf.c", "x86_64/floatdixf.c"]); - } - } else { - if !target.contains("freebsd") && !target.contains("netbsd") { - sources.extend(&["gcc_personality_v0.c"]); - } - - if target.contains("x86_64") { - sources.extend(&["x86_64/chkstk.S", - "x86_64/chkstk2.S", - "x86_64/floatdidf.c", - "x86_64/floatdisf.c", - "x86_64/floatdixf.c", - "x86_64/floatundidf.S", - "x86_64/floatundisf.S", - "x86_64/floatundixf.S"]); - } - - if target.contains("i386") || target.contains("i586") || target.contains("i686") { - sources.extend(&["i386/ashldi3.S", - "i386/ashrdi3.S", - "i386/chkstk.S", - "i386/chkstk2.S", - "i386/divdi3.S", - "i386/floatdidf.S", - "i386/floatdisf.S", - "i386/floatdixf.S", - "i386/floatundidf.S", - "i386/floatundisf.S", - "i386/floatundixf.S", - "i386/lshrdi3.S", - "i386/moddi3.S", - "i386/muldi3.S", - "i386/udivdi3.S", - "i386/umoddi3.S"]); - } - } - - if target.contains("arm") && !target.contains("ios") { - // (At least) udivsi3.S is broken for Thumb 1 which our gcc uses by - // default, we don't want Thumb 2 since it isn't supported on some - // devices, so disable thumb entirely. - // Upstream bug: https://bugs.llvm.org/show_bug.cgi?id=32492 - cfg.define("__ARM_ARCH_ISA_THUMB", Some("0")); - - sources.extend(&["arm/aeabi_cdcmp.S", - "arm/aeabi_cdcmpeq_check_nan.c", - "arm/aeabi_cfcmp.S", - "arm/aeabi_cfcmpeq_check_nan.c", - "arm/aeabi_dcmp.S", - "arm/aeabi_div0.c", - "arm/aeabi_drsub.c", - "arm/aeabi_fcmp.S", - "arm/aeabi_frsub.c", - "arm/aeabi_idivmod.S", - "arm/aeabi_ldivmod.S", - "arm/aeabi_memcmp.S", - "arm/aeabi_memcpy.S", - "arm/aeabi_memmove.S", - "arm/aeabi_memset.S", - "arm/aeabi_uidivmod.S", - "arm/aeabi_uldivmod.S", - "arm/bswapdi2.S", - "arm/bswapsi2.S", - "arm/clzdi2.S", - "arm/clzsi2.S", - "arm/comparesf2.S", - "arm/divmodsi4.S", - "arm/divsi3.S", - "arm/modsi3.S", - "arm/switch16.S", - "arm/switch32.S", - "arm/switch8.S", - "arm/switchu8.S", - "arm/sync_synchronize.S", - "arm/udivmodsi4.S", - "arm/udivsi3.S", - "arm/umodsi3.S"]); - } - - if target.contains("armv7") { - sources.extend(&["arm/sync_fetch_and_add_4.S", - "arm/sync_fetch_and_add_8.S", - "arm/sync_fetch_and_and_4.S", - "arm/sync_fetch_and_and_8.S", - "arm/sync_fetch_and_max_4.S", - "arm/sync_fetch_and_max_8.S", - "arm/sync_fetch_and_min_4.S", - "arm/sync_fetch_and_min_8.S", - "arm/sync_fetch_and_nand_4.S", - "arm/sync_fetch_and_nand_8.S", - "arm/sync_fetch_and_or_4.S", - "arm/sync_fetch_and_or_8.S", - "arm/sync_fetch_and_sub_4.S", - "arm/sync_fetch_and_sub_8.S", - "arm/sync_fetch_and_umax_4.S", - "arm/sync_fetch_and_umax_8.S", - "arm/sync_fetch_and_umin_4.S", - "arm/sync_fetch_and_umin_8.S", - "arm/sync_fetch_and_xor_4.S", - "arm/sync_fetch_and_xor_8.S"]); - } - - if target.contains("eabihf") { - sources.extend(&["arm/adddf3vfp.S", - "arm/addsf3vfp.S", - "arm/divdf3vfp.S", - "arm/divsf3vfp.S", - "arm/eqdf2vfp.S", - "arm/eqsf2vfp.S", - "arm/extendsfdf2vfp.S", - "arm/fixdfsivfp.S", - "arm/fixsfsivfp.S", - "arm/fixunsdfsivfp.S", - "arm/fixunssfsivfp.S", - "arm/floatsidfvfp.S", - "arm/floatsisfvfp.S", - "arm/floatunssidfvfp.S", - "arm/floatunssisfvfp.S", - "arm/gedf2vfp.S", - "arm/gesf2vfp.S", - "arm/gtdf2vfp.S", - "arm/gtsf2vfp.S", - "arm/ledf2vfp.S", - "arm/lesf2vfp.S", - "arm/ltdf2vfp.S", - "arm/ltsf2vfp.S", - "arm/muldf3vfp.S", - "arm/mulsf3vfp.S", - "arm/negdf2vfp.S", - "arm/negsf2vfp.S", - "arm/nedf2vfp.S", - "arm/nesf2vfp.S", - "arm/restore_vfp_d8_d15_regs.S", - "arm/save_vfp_d8_d15_regs.S", - "arm/subdf3vfp.S", - "arm/subsf3vfp.S", - "arm/truncdfsf2vfp.S", - "arm/unorddf2vfp.S", - "arm/unordsf2vfp.S"]); - } - - if target.contains("aarch64") { - sources.extend(&["comparetf2.c", - "extenddftf2.c", - "extendsftf2.c", - "fixtfdi.c", - "fixtfsi.c", - "fixtfti.c", - "fixunstfdi.c", - "fixunstfsi.c", - "fixunstfti.c", - "floatditf.c", - "floatsitf.c", - "floatunditf.c", - "floatunsitf.c", - "multc3.c", - "trunctfdf2.c", - "trunctfsf2.c"]); - } - - for src in sources.map.values() { - cfg.file(Path::new("../compiler-rt/lib/builtins").join(src)); - } - - cfg.compile("libcompiler-rt.a"); -} diff --git a/src/libcompiler_builtins/lib.rs b/src/libcompiler_builtins/lib.rs deleted file mode 100644 index 09b3d639507..00000000000 --- a/src/libcompiler_builtins/lib.rs +++ /dev/null @@ -1,721 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(compiler_builtins)] -#![no_std] -#![compiler_builtins] -#![unstable(feature = "compiler_builtins_lib", - reason = "internal implementation detail of rustc right now", - issue = "0")] -#![crate_name = "compiler_builtins"] -#![crate_type = "rlib"] -#![allow(unused_features)] -#![feature(staged_api, core_intrinsics, repr_simd, - i128_type, core_float, abi_unadjusted, associated_consts)] -#![allow(non_camel_case_types, unused_variables, unused_imports)] - -#[cfg(any(target_pointer_width="32", target_pointer_width="16", target_os="windows", - target_arch="mips64"))] -pub mod reimpls { - - #![allow(unused_comparisons)] - - use core::intrinsics::unchecked_div; - use core::intrinsics::unchecked_rem; - use core::ptr; - - macro_rules! ashl { - ($a:expr, $b:expr, $ty:ty) => {{ - let (a, b) = ($a, $b); - let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty; - let half_bits = bits.wrapping_shr(1); - if b & half_bits != 0 { - <$ty>::from_parts(0, a.low().wrapping_shl( - b.wrapping_sub(half_bits) as u32)) - } else if b == 0 { - a - } else { - <$ty>::from_parts(a.low().wrapping_shl(b as u32), - a.high().wrapping_shl(b as u32) - | a.low() - .wrapping_shr(half_bits.wrapping_sub(b) as u32)) - } - }} - } - - #[export_name="__ashlti3"] - pub extern "C" fn shl(a: u128, b: u128) -> u128 { - ashl!(a, b, u128) - } - - macro_rules! ashr { - ($a: expr, $b: expr, $ty:ty) => {{ - let (a, b) = ($a, $b); - let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty; - let half_bits = bits.wrapping_shr(1); - if b & half_bits != 0 { - <$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32) - as <$ty as LargeInt>::LowHalf, - a.high().wrapping_shr(half_bits.wrapping_sub(1) as u32)) - } else if b == 0 { - a - } else { - let high_unsigned = a.high() as <$ty as LargeInt>::LowHalf; - <$ty>::from_parts(high_unsigned.wrapping_shl(half_bits.wrapping_sub(b) as u32) - | a.low().wrapping_shr(b as u32), - a.high().wrapping_shr(b as u32)) - } - }} - } - - #[export_name="__ashrti3"] - pub extern "C" fn shr(a: i128, b: i128) -> i128 { - ashr!(a, b, i128) - } - - macro_rules! lshr { - ($a: expr, $b: expr, $ty:ty) => {{ - let (a, b) = ($a, $b); - let bits = ::core::mem::size_of::<$ty>().wrapping_mul(8) as $ty; - let half_bits = bits.wrapping_shr(1); - if b & half_bits != 0 { - <$ty>::from_parts(a.high().wrapping_shr(b.wrapping_sub(half_bits) as u32), 0) - } else if b == 0 { - a - } else { - <$ty>::from_parts(a.high().wrapping_shl(half_bits.wrapping_sub(b) as u32) - | a.low().wrapping_shr(b as u32), - a.high().wrapping_shr(b as u32)) - } - }} - } - - - #[export_name="__lshrti3"] - pub extern "C" fn lshr(a: u128, b: u128) -> u128 { - lshr!(a, b, u128) - } - - pub extern "C" fn u128_div_mod(n: u128, d: u128, rem: *mut u128) -> u128 { - // Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide - unsafe { - // special cases, X is unknown, K != 0 - if n.high() == 0 { - if d.high() == 0 { - // 0 X - // --- - // 0 X - if !rem.is_null() { - *rem = u128::from(unchecked_rem(n.low(), d.low())); - } - return u128::from(unchecked_div(n.low(), d.low())); - } else { - // 0 X - // --- - // K X - if !rem.is_null() { - *rem = n; - } - return 0; - }; - } - - let mut sr; - let mut q; - let mut r; - - if d.low() == 0 { - if d.high() == 0 { - // K X - // --- - // 0 0 - if !rem.is_null() { - *rem = u128::from(unchecked_rem(n.high(), d.low())); - } - return u128::from(unchecked_div(n.high(), d.low())); - } - - if n.low() == 0 { - // K 0 - // --- - // K 0 - if !rem.is_null() { - *rem = u128::from_parts(0, unchecked_rem(n.high(), d.high())); - } - return u128::from(unchecked_div(n.high(), d.high())); - } - - // K K - // --- - // K 0 - - if d.high().is_power_of_two() { - if !rem.is_null() { - *rem = u128::from_parts(n.low(), - n.high() & (d.high().wrapping_sub(1))); - } - return u128::from(n.high().wrapping_shr(d.high().trailing_zeros())); - } - - // K K - // --- - // K 0 - sr = d.high().leading_zeros().wrapping_sub(n.high().leading_zeros()); - - // D > N - if sr > 64 - 2 { - if !rem.is_null() { - *rem = n; - } - return 0; - } - - sr = sr.wrapping_add(1); - - // 1 <= sr <= u64::bits() - 1 - q = n.wrapping_shl(128u32.wrapping_sub(sr)); - r = n.wrapping_shr(sr); - } else { - if d.high() == 0 { - // K X - // --- - // 0 K - if d.low().is_power_of_two() { - if !rem.is_null() { - *rem = u128::from(n.low() & (d.low().wrapping_sub(1))); - } - - if d.low() == 1 { - return n; - } else { - let sr = d.low().trailing_zeros(); - return n.wrapping_shr(sr); - }; - } - - sr = (1 + 64u32) - .wrapping_add(d.low().leading_zeros()) - .wrapping_sub(n.high().leading_zeros()); - - // 2 <= sr <= u64::bits() - 1 - q = n.wrapping_shl(128u32.wrapping_sub(sr)); - r = n.wrapping_shr(sr); - // FIXME the C compiler-rt implementation has something here - // that looks like a speed optimisation. - // It would be worth a try to port it to Rust too and - // compare the speed. - } else { - // K X - // --- - // K K - sr = d.high().leading_zeros().wrapping_sub(n.high().leading_zeros()); - - // D > N - if sr > 64 - 1 { - if !rem.is_null() { - *rem = n; - } - return 0; - } - - sr = sr.wrapping_add(1); - - // 1 <= sr <= u32::bits() - q = n.wrapping_shl(128u32.wrapping_sub(sr)); - r = n.wrapping_shr(sr); - } - } - - // Not a special case - // q and r are initialized with - // q = n << (u64::bits() - sr) - // r = n >> sr - // 1 <= sr <= u64::bits() - 1 - let mut carry = 0; - - // FIXME: replace this with a for loop - // (atm not doable as this generates call to - // eh_personality when optimisations are turned off, - // which in turn gives a linker error in later - // compilation steps) - while sr > 0 { - // r:q = ((r:q) << 1) | carry - r = r.wrapping_shl(1) | q.wrapping_shr(128 - 1); - q = q.wrapping_shl(1) | carry as u128; - - // carry = 0 - // if r >= d { - // r -= d; - // carry = 1; - // } - let s = ((d.wrapping_sub(r).wrapping_sub(1)) as i128).wrapping_shr(128 - 1); - carry = (s & 1) as u64; - r = r.wrapping_sub(d & s as u128); - sr = sr.wrapping_sub(1); - } - - if !rem.is_null() { - *rem = r; - } - (q.wrapping_shl(1)) | carry as u128 - } - } - - fn i128_mod(a: i128, b: i128) -> i128 { - let b = b.uabs(); - let sa = a.signum(); - let a = a.uabs(); - unsafe { - let mut r = ::core::mem::zeroed(); - u128_div_mod(a, b, &mut r); - if sa == -1 { (r as i128).unchecked_neg() } else { r as i128 } - } - } - - fn i128_div(a: i128, b: i128) -> i128 { - let sa = a.signum(); - let sb = b.signum(); - let a = a.uabs(); - let b = b.uabs(); - let sr = sa.wrapping_mul(sb); // sign of quotient - (if sr == -1 { - (u128_div_mod(a, b, ptr::null_mut()) as i128).unchecked_neg() - } else { - u128_div_mod(a, b, ptr::null_mut()) as i128 - }) - } - - macro_rules! mulo { - ($a:expr, $b:expr, $o: expr, $ty: ty) => {{ - let (a, b, overflow) = ($a, $b, $o); - *overflow = 0; - let result = a.wrapping_mul(b); - if a == <$ty>::min_value() { - if b != 0 && b != 1 { - *overflow = 1; - } - return result; - } - if b == <$ty>::min_value() { - if a != 0 && a != 1 { - *overflow = 1; - } - return result; - } - - let sa = a.signum(); - let abs_a = a.iabs(); - let sb = b.signum(); - let abs_b = b.iabs(); - if abs_a < 2 || abs_b < 2 { - return result; - } - if sa == sb { - if abs_a > unchecked_div(<$ty>::max_value(), abs_b) { - *overflow = 1; - } - } else { - if abs_a > unchecked_div(<$ty>::min_value(), abs_b.unchecked_neg()) { - *overflow = 1; - } - } - result - }} - } - - pub trait LargeInt { - type LowHalf; - type HighHalf; - - fn low(self) -> Self::LowHalf; - fn high(self) -> Self::HighHalf; - fn from_parts(low: Self::LowHalf, high: Self::HighHalf) -> Self; - } - impl LargeInt for u128 { - type LowHalf = u64; - type HighHalf = u64; - - fn low(self) -> u64 { - self as u64 - } - fn high(self) -> u64 { - self.wrapping_shr(64) as u64 - } - fn from_parts(low: u64, high: u64) -> u128 { - (high as u128).wrapping_shl(64) | low as u128 - } - } - impl LargeInt for i128 { - type LowHalf = u64; - type HighHalf = i64; - - fn low(self) -> u64 { - self as u64 - } - fn high(self) -> i64 { - self.wrapping_shr(64) as i64 - } - fn from_parts(low: u64, high: i64) -> i128 { - u128::from_parts(low, high as u64) as i128 - } - } - - macro_rules! mul { - ($a:expr, $b:expr, $ty: ty, $tyh: ty) => {{ - let (a, b) = ($a, $b); - let half_bits = ::core::mem::size_of::<$tyh>().wrapping_mul(4) as u32; - let lower_mask = (!0u64).wrapping_shr(half_bits); - let mut low = (a.low() & lower_mask).wrapping_mul(b.low() & lower_mask); - let mut t = low.wrapping_shr(half_bits); - low &= lower_mask; - t = t.wrapping_add(a.low().wrapping_shr(half_bits) - .wrapping_mul(b.low() & lower_mask)); - low = low.wrapping_add((t & lower_mask).wrapping_shl(half_bits)); - let mut high = t.wrapping_shr(half_bits) as $tyh; - t = low.wrapping_shr(half_bits); - low &= lower_mask; - t = t.wrapping_add(b.low().wrapping_shr(half_bits) - .wrapping_mul(a.low() & lower_mask)); - low = low.wrapping_add((t & lower_mask).wrapping_shl(half_bits)); - high = high.wrapping_add(t.wrapping_shr(half_bits) as $tyh); - high = high.wrapping_add(a.low().wrapping_shr(half_bits) - .wrapping_mul(b.low().wrapping_shr(half_bits)) as $tyh); - high = high - .wrapping_add(a.high() - .wrapping_mul(b.low() as $tyh)) - .wrapping_add((a.low() as $tyh) - .wrapping_mul(b.high())); - <$ty>::from_parts(low, high) - }} - } - - #[export_name="__multi3"] - pub extern "C" fn u128_mul(a: i128, b: i128) -> i128 { - mul!(a, b, i128, i64) - } - - trait AbsExt: Sized { - fn uabs(self) -> u128; - fn iabs(self) -> i128; - } - - impl AbsExt for i128 { - fn uabs(self) -> u128 { - self.iabs() as u128 - } - fn iabs(self) -> i128 { - let s = self.wrapping_shr(127); - ((self ^ s).wrapping_sub(s)) - } - } - - trait NegExt: Sized { - fn unchecked_neg(self) -> i128; - } - - impl NegExt for i128 { - fn unchecked_neg(self) -> i128 { - (!self).wrapping_add(1) - } - } - - trait FloatStuff: Sized { - type ToBytes; - - const MANTISSA_BITS: u32; - const MAX_EXP: i32; - const EXP_MASK: Self::ToBytes; - const MANTISSA_MASK: Self::ToBytes; - const MANTISSA_LEAD_BIT: Self::ToBytes; - - fn to_bytes(self) -> Self::ToBytes; - fn get_exponent(self) -> i32; - } - - impl FloatStuff for f32 { - type ToBytes = u32; - const MANTISSA_BITS: u32 = 23; - const MAX_EXP: i32 = 127; - const EXP_MASK: u32 = 0x7F80_0000; - const MANTISSA_MASK: u32 = 0x007F_FFFF; - const MANTISSA_LEAD_BIT: u32 = 0x0080_0000; - - fn to_bytes(self) -> u32 { unsafe { ::core::mem::transmute(self) } } - fn get_exponent(self) -> i32 { - ((self.to_bytes() & Self::EXP_MASK).wrapping_shr(Self::MANTISSA_BITS) as i32) - .wrapping_sub(Self::MAX_EXP) - } - } - - impl FloatStuff for f64 { - type ToBytes = u64; - const MANTISSA_BITS: u32 = 52; - const MAX_EXP: i32 = 1023; - const EXP_MASK: u64 = 0x7FF0_0000_0000_0000; - const MANTISSA_MASK: u64 = 0x000F_FFFF_FFFF_FFFF; - const MANTISSA_LEAD_BIT: u64 = 0x0010_0000_0000_0000; - - fn to_bytes(self) -> u64 { unsafe { ::core::mem::transmute(self) } } - fn get_exponent(self) -> i32 { - ((self.to_bytes() & Self::EXP_MASK).wrapping_shr(Self::MANTISSA_BITS) as i32) - .wrapping_sub(Self::MAX_EXP) - } - } - - macro_rules! float_as_unsigned { - ($from: expr, $fromty: ty, $outty: ty) => { { - use core::num::Float; - let repr = $from.to_bytes(); - let sign = $from.signum(); - let exponent = $from.get_exponent(); - let mantissa_fraction = repr & <$fromty as FloatStuff>::MANTISSA_MASK; - let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT; - if sign == -1.0 || exponent < 0 { return 0 as u128; } - if exponent > ::core::mem::size_of::<$outty>().wrapping_mul(8) as i32 { - return !(0 as u128); - } - (if exponent < (<$fromty as FloatStuff>::MANTISSA_BITS) as i32 { - (mantissa as $outty) - .wrapping_shr((<$fromty as FloatStuff>::MANTISSA_BITS as i32) - .wrapping_sub(exponent) as u32) - } else { - (mantissa as $outty) - .wrapping_shl(exponent.wrapping_sub( - <$fromty as FloatStuff>::MANTISSA_BITS as i32) as u32) - }) - } } - } - - macro_rules! float_as_signed { - ($from: expr, $fromty: ty, $outty: ty) => {{ - use core::num::Float; - let repr = $from.to_bytes(); - let sign = $from.signum(); - let exponent = $from.get_exponent(); - let mantissa_fraction = repr & <$fromty as FloatStuff>::MANTISSA_MASK; - let mantissa = mantissa_fraction | <$fromty as FloatStuff>::MANTISSA_LEAD_BIT; - - if exponent < 0 { return 0 as i128; } - if exponent > ::core::mem::size_of::<$outty>().wrapping_mul(8) as i32 { - let ret = if sign > 0.0 { <$outty>::max_value() } else { <$outty>::min_value() }; - return ret - } - let r = if exponent < (<$fromty as FloatStuff>::MANTISSA_BITS) as i32 { - (mantissa as $outty) - .wrapping_shr((<$fromty as FloatStuff>::MANTISSA_BITS as i32) - .wrapping_sub(exponent) as u32) - } else { - (mantissa as $outty) - .wrapping_shl(exponent.wrapping_sub( - <$fromty as FloatStuff>::MANTISSA_BITS as i32) as u32) - }; - (if sign >= 0.0 { r } else { r.unchecked_neg() }) - }} - } - - - fn i128_as_f64(a: i128) -> f64 { - match a.signum() { - 1 => u128_as_f64(a.uabs()), - 0 => 0.0, - _ => -u128_as_f64(a.uabs()), - } - } - - fn i128_as_f32(a: i128) -> f32 { - match a.signum() { - 1 => u128_as_f32(a.uabs()), - 0 => 0.0, - _ => -u128_as_f32(a.uabs()), - } - } - - fn u128_as_f64(mut a: u128) -> f64 { - use ::core::f64::MANTISSA_DIGITS; - if a == 0 { return 0.0; } - let sd = 128u32.wrapping_sub(a.leading_zeros()); - let mut e = sd.wrapping_sub(1); - const MD1 : u32 = MANTISSA_DIGITS + 1; - const MD2 : u32 = MANTISSA_DIGITS + 2; - - let negn = !0u128; - - if sd > MANTISSA_DIGITS { - a = match sd { - MD1 => a.wrapping_shl(1), - MD2 => a, - _ => a.wrapping_shr(sd.wrapping_sub(MANTISSA_DIGITS + 2)) | - (if (a & (negn.wrapping_shr(128 + MANTISSA_DIGITS + 2) - .wrapping_sub(sd as u128))) == 0 { 0 } else { 1 }) - }; - a |= if (a & 4) == 0 { 0 } else { 1 }; - a = a.wrapping_add(1); - a = a.wrapping_shr(2); - if a & (1 << MANTISSA_DIGITS) != 0 { - a = a.wrapping_shr(1); - e = e.wrapping_add(1); - } - } else { - a = a.wrapping_shl(MANTISSA_DIGITS.wrapping_sub(sd)); - } - unsafe { - ::core::mem::transmute((e as u64).wrapping_add(1023).wrapping_shl(52) - | (a as u64 & 0x000f_ffff_ffff_ffff)) - } - } - - fn u128_as_f32(mut a: u128) -> f32 { - use ::core::f32::MANTISSA_DIGITS; - if a == 0 { return 0.0; } - let sd = 128u32.wrapping_sub(a.leading_zeros()); - let mut e = sd.wrapping_sub(1); - const MD1 : u32 = MANTISSA_DIGITS + 1; - const MD2 : u32 = MANTISSA_DIGITS + 2; - - let negn = !0u128; - - if sd > MANTISSA_DIGITS { - a = match sd { - MD1 => a.wrapping_shl(1), - MD2 => a, - _ => a.wrapping_shr(sd.wrapping_sub(MANTISSA_DIGITS + 2)) | - (if (a & (negn.wrapping_shr(128 + MANTISSA_DIGITS + 2) - .wrapping_sub(sd as u128))) == 0 { 0 } else { 1 }) - }; - a |= if (a & 4) == 0 { 0 } else { 1 }; - a = a.wrapping_add(1); - a = a.wrapping_shr(2); - if a & (1 << MANTISSA_DIGITS) != 0 { - a = a.wrapping_shr(1); - e = e.wrapping_add(1); - } - } else { - a = a.wrapping_shl(MANTISSA_DIGITS.wrapping_sub(sd)); - } - unsafe { - ::core::mem::transmute((e as u32).wrapping_add(127).wrapping_shl(23) - | (a as u32 & 0x007f_ffff)) - } - } - - - macro_rules! why_are_abi_strings_checked_by_parser { ($cret:ty, $conv:expr, $unadj:tt) => { - mod imp { - use super::{LargeInt, FloatStuff, NegExt, AbsExt}; - use super::{i128_as_f64, i128_as_f32, u128_as_f64, u128_as_f32, - i128_div, i128_mod, u128_div_mod, unchecked_div, ptr}; - // For x64 - // rdx:rcx, r9:r8, stack -> rdx:rax - // aka. - // define i128 @__muloti4(i128, i128, i32*) - #[export_name="__muloti4"] - pub unsafe extern $unadj fn i128_mul_oflow(a: i128, b: i128, o: *mut i32) -> i128 { - mulo!(a, b, o, i128) - } - - // For x64 - // rdx:rax -> xmm0 - // aka. - // define double @__muloti4(i128) - #[export_name="__floattidf"] - pub extern $unadj fn i128_as_f64_(a: i128) -> f64 { - i128_as_f64(a) - } - #[export_name="__floattisf"] - pub extern $unadj fn i128_as_f32_(a: i128) -> f32 { - i128_as_f32(a) - } - #[export_name="__floatuntidf"] - pub extern $unadj fn u128_as_f64_(a: u128) -> f64 { - u128_as_f64(a) - } - #[export_name="__floatuntisf"] - pub extern $unadj fn u128_as_f32_(a: u128) -> f32 { - u128_as_f32(a) - } - - // For x64 - // xmm0 -> rdx:rax - // aka. - // define i128 @stuff(double) - #[export_name="__fixunsdfti"] - pub extern $unadj fn f64_as_u128(a: f64) -> u128 { - float_as_unsigned!(a, f64, u128) - } - - #[export_name="__fixunssfti"] - pub extern $unadj fn f32_as_u128(a: f32) -> u128 { - float_as_unsigned!(a, f32, u128) - } - - #[export_name="__fixdfti"] - pub extern $unadj fn f64_as_i128(a: f64) -> i128 { - float_as_signed!(a, f64, i128) - } - - #[export_name="__fixsfti"] - pub extern $unadj fn f32_as_i128(a: f32) -> i128 { - float_as_signed!(a, f32, i128) - } - - #[repr(simd)] - pub struct u64x2(u64, u64); - - // For x64 - // pointers -> xmm0 - // aka. - // define <2 x u64> @stuff(i128*, i128*, i128*) - // - // That almost matches the C ABI, so we simply use the C ABI - #[export_name="__udivmodti4"] - pub extern "C" fn u128_div_mod_(n: u128, d: u128, rem: *mut u128) -> $cret { - let x = u128_div_mod(n, d, rem); - ($conv)(x) - } - - #[export_name="__udivti3"] - pub extern "C" fn u128_div_(a: u128, b: u128) -> $cret { - let x = u128_div_mod(a, b, ptr::null_mut()); - ($conv)(x) - } - - #[export_name="__umodti3"] - pub extern "C" fn u128_mod_(a: u128, b: u128) -> $cret { - unsafe { - let mut r = ::core::mem::zeroed(); - u128_div_mod(a, b, &mut r); - ($conv)(r) - } - } - - #[export_name="__divti3"] - pub extern "C" fn i128_div_(a: i128, b: i128) -> $cret { - let x = i128_div(a, b); - ($conv)(x as u128) - } - - #[export_name="__modti3"] - pub extern "C" fn i128_mod_(a: i128, b: i128) -> $cret { - let x = i128_mod(a, b); - ($conv)(x as u128) - } - } - } } - - // LLVM expectations for ABI on windows x64 are pure madness. - #[cfg(all(windows, target_pointer_width="64"))] - why_are_abi_strings_checked_by_parser!(u64x2, - |i: u128| u64x2(i.low(), i.high()), - "unadjusted"); - - #[cfg(not(all(windows, target_pointer_width="64")))] - why_are_abi_strings_checked_by_parser!(u128, |i|{ i }, "C"); - pub use self::imp::*; -} diff --git a/src/libprofiler_builtins/build.rs b/src/libprofiler_builtins/build.rs index 1ee284ff4da..55df14ea215 100644 --- a/src/libprofiler_builtins/build.rs +++ b/src/libprofiler_builtins/build.rs @@ -53,7 +53,7 @@ fn main() { } for src in profile_sources { - cfg.file(Path::new("../compiler-rt/lib/profile").join(src)); + cfg.file(Path::new("../libcompiler_builtins/compiler-rt/lib/profile").join(src)); } cfg.compile("libprofiler-rt.a"); diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index 6bef31ccf64..fa93c005dcd 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -13,7 +13,7 @@ use std::ffi::{CStr, CString}; use llvm::{self, Attribute, ValueRef}; use llvm::AttributePlace::Function; -pub use syntax::attr::InlineAttr; +pub use syntax::attr::{self, InlineAttr}; use syntax::ast; use context::CrateContext; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index a7f205a18a4..b32e1d4aa8d 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -363,6 +363,24 @@ pub fn each_linked_rlib(sess: &Session, Ok(()) } +/// Returns a boolean indicating whether the specified crate should be ignored +/// during LTO. +/// +/// Crates ignored during LTO are not lumped together in the "massive object +/// file" that we create and are linked in their normal rlib states. See +/// comments below for what crates do not participate in LTO. +/// +/// It's unusual for a crate to not participate in LTO. Typically only +/// compiler-specific and unstable crates have a reason to not participate in +/// LTO. +pub fn ignored_for_lto(sess: &Session, cnum: CrateNum) -> bool { + // `#![no_builtins]` crates don't participate in LTO because the state + // of builtins gets messed up (our crate isn't tagged with no builtins). + // Similarly `#![compiler_builtins]` doesn't participate because we want + // those builtins! + sess.cstore.is_no_builtins(cnum) || sess.cstore.is_compiler_builtins(cnum) +} + fn out_filename(sess: &Session, crate_type: config::CrateType, outputs: &OutputFilenames, @@ -698,7 +716,10 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path, let skip_object_files = native_libs.iter().any(|lib| { lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib) }); - ab.add_rlib(path, &name.as_str(), sess.lto(), skip_object_files).unwrap(); + ab.add_rlib(path, + &name.as_str(), + sess.lto() && !ignored_for_lto(sess, cnum), + skip_object_files).unwrap(); all_native_libs.extend(sess.cstore.native_libraries(cnum)); }); @@ -1247,7 +1268,9 @@ fn add_upstream_rust_crates(cmd: &mut Linker, lib.kind == NativeLibraryKind::NativeStatic && !relevant_lib(sess, lib) }); - if !sess.lto() && crate_type != config::CrateTypeDylib && !skip_native { + if (!sess.lto() || ignored_for_lto(sess, cnum)) && + crate_type != config::CrateTypeDylib && + !skip_native { cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath)); return } diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 562d7171156..1703a121e17 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -1200,8 +1200,7 @@ fn spawn_work<'a>(sess: &'a Session, let crate_types = sess.crate_types.borrow().clone(); let mut each_linked_rlib_for_lto = Vec::new(); drop(link::each_linked_rlib(sess, &mut |cnum, path| { - // `#![no_builtins]` crates don't participate in LTO. - if sess.cstore.is_no_builtins(cnum) { + if link::ignored_for_lto(sess, cnum) { return } each_linked_rlib_for_lto.push((cnum, path.to_path_buf())); diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index 2787812f962..8f9146283ef 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -30,7 +30,6 @@ use context::CrateContext; use common; use type_::Type; use value::Value; -use syntax::attr; use std::ffi::CString; @@ -88,16 +87,6 @@ fn declare_raw_fn(ccx: &CrateContext, name: &str, callconv: llvm::CallConv, ty: } } - // If we're compiling the compiler-builtins crate, e.g. the equivalent of - // compiler-rt, then we want to implicitly compile everything with hidden - // visibility as we're going to link this object all over the place but - // don't want the symbols to get exported. - if attr::contains_name(ccx.tcx().hir.krate_attrs(), "compiler_builtins") { - unsafe { - llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); - } - } - match ccx.tcx().sess.opts.cg.opt_level.as_ref().map(String::as_ref) { Some("s") => { llvm::Attribute::OptimizeForSize.apply_llfn(Function, llfn); diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index 2a6e7c5ace6..200f6dee334 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -162,6 +162,18 @@ impl<'a, 'tcx> TransItem<'tcx> { llvm::SetUniqueComdat(ccx.llmod(), lldecl); } + // If we're compiling the compiler-builtins crate, e.g. the equivalent of + // compiler-rt, then we want to implicitly compile everything with hidden + // visibility as we're going to link this object all over the place but + // don't want the symbols to get exported. + if linkage != llvm::Linkage::InternalLinkage && + linkage != llvm::Linkage::PrivateLinkage && + attr::contains_name(ccx.tcx().hir.krate_attrs(), "compiler_builtins") { + unsafe { + llvm::LLVMRustSetVisibility(lldecl, llvm::Visibility::Hidden); + } + } + debug!("predefine_fn: mono_ty = {:?} instance = {:?}", mono_ty, instance); if common::is_inline_instance(ccx.tcx(), &instance) { attributes::inline(lldecl, attributes::InlineAttr::Hint); diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index b516cbd08ca..09c16816934 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -19,7 +19,7 @@ collections = { path = "../libcollections" } core = { path = "../libcore" } libc = { path = "../rustc/libc_shim" } rand = { path = "../librand" } -compiler_builtins = { path = "../libcompiler_builtins" } +compiler_builtins = { path = "../rustc/compiler_builtins_shim" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } std_unicode = { path = "../libstd_unicode" } unwind = { path = "../libunwind" } diff --git a/src/rustc/compiler_builtins_shim/Cargo.toml b/src/rustc/compiler_builtins_shim/Cargo.toml new file mode 100644 index 00000000000..e0026078a5d --- /dev/null +++ b/src/rustc/compiler_builtins_shim/Cargo.toml @@ -0,0 +1,24 @@ +# See libc_shim/Cargo.toml for why this exists + +[package] +name = "compiler_builtins" +authors = ["The Rust Project Developers"] +version = "0.0.0" +build = "../../libcompiler_builtins/build.rs" + +[lib] +path = "../../libcompiler_builtins/src/lib.rs" +test = false +doctest = false + +[dependencies] +core = { path = "../../libcore" } + +[build-dependencies] +gcc = "0.3" + +[features] +c = [] +default = ["c", "rustbuild", "compiler-builtins"] +rustbuild = [] +compiler-builtins = [] diff --git a/src/test/run-pass/auxiliary/clibrary.rs b/src/rustc/compiler_builtins_shim/build.rs similarity index 62% rename from src/test/run-pass/auxiliary/clibrary.rs rename to src/rustc/compiler_builtins_shim/build.rs index 7438ba21bfc..546f60482e7 100644 --- a/src/test/run-pass/auxiliary/clibrary.rs +++ b/src/rustc/compiler_builtins_shim/build.rs @@ -1,4 +1,4 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,8 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// no-prefer-dynamic -#![crate_type = "staticlib"] +#![deny(warnings)] -#[no_mangle] -pub extern "C" fn foo(x:i32) -> i32 { x } +// See comments in Cargo.toml for why this exists + +fn main() { + println!("cargo:rustc-cfg=stdbuild"); + println!("cargo:rerun-if-changed=build.rs"); +} diff --git a/src/test/run-pass/lib-defaults.rs b/src/test/run-pass/lib-defaults.rs index a38080f8cfe..6e5dccae0a0 100644 --- a/src/test/run-pass/lib-defaults.rs +++ b/src/test/run-pass/lib-defaults.rs @@ -8,16 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// aux-build:clibrary.rs -// compile-flags: -lclibrary +// compile-flags: -lrust_test_helpers -#[link(name = "clibrary", kind = "static")] +#[link(name = "rust_test_helpers", kind = "static")] extern "C" { - pub fn foo(x:i32) -> i32; + pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; } fn main() { unsafe { - foo(42); + rust_dbg_extern_identity_u32(42); } } diff --git a/src/test/run-pass/rfc1717/library-override.rs b/src/test/run-pass/rfc1717/library-override.rs index d6ef96c5add..26713a25543 100644 --- a/src/test/run-pass/rfc1717/library-override.rs +++ b/src/test/run-pass/rfc1717/library-override.rs @@ -8,16 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// aux-build:clibrary.rs -// compile-flags: -lstatic=wronglibrary:clibrary +// compile-flags: -lstatic=wronglibrary:rust_test_helpers #[link(name = "wronglibrary", kind = "dylib")] extern "C" { - pub fn foo(x:i32) -> i32; + pub fn rust_dbg_extern_identity_u32(x: u32) -> u32; } fn main() { unsafe { - foo(42); + rust_dbg_extern_identity_u32(42); } } diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index bcf86e4489b..020570e61dc 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -54,6 +54,7 @@ fn filter_dirs(path: &Path) -> bool { "src/jemalloc", "src/llvm", "src/libbacktrace", + "src/libcompiler_builtins", "src/compiler-rt", "src/rustllvm", "src/liblibc",