summary refs log tree commit diff
path: root/src/rustllvm/PassWrapper.cpp
AgeCommit message (Collapse)AuthorLines
2017-10-07rustc: Implement ThinLTOAlex Crichton-0/+461
This commit is an implementation of LLVM's ThinLTO for consumption in rustc itself. Currently today LTO works by merging all relevant LLVM modules into one and then running optimization passes. "Thin" LTO operates differently by having more sharded work and allowing parallelism opportunities between optimizing codegen units. Further down the road Thin LTO also allows *incremental* LTO which should enable even faster release builds without compromising on the performance we have today. This commit uses a `-Z thinlto` flag to gate whether ThinLTO is enabled. It then also implements two forms of ThinLTO: * In one mode we'll *only* perform ThinLTO over the codegen units produced in a single compilation. That is, we won't load upstream rlibs, but we'll instead just perform ThinLTO amongst all codegen units produced by the compiler for the local crate. This is intended to emulate a desired end point where we have codegen units turned on by default for all crates and ThinLTO allows us to do this without performance loss. * In anther mode, like full LTO today, we'll optimize all upstream dependencies in "thin" mode. Unlike today, however, this LTO step is fully parallelized so should finish much more quickly. There's a good bit of comments about what the implementation is doing and where it came from, but the tl;dr; is that currently most of the support here is copied from upstream LLVM. This code duplication is done for a number of reasons: * Controlling parallelism means we can use the existing jobserver support to avoid overloading machines. * We will likely want a slightly different form of incremental caching which integrates with our own incremental strategy, but this is yet to be determined. * This buys us some flexibility about when/where we run ThinLTO, as well as having it tailored to fit our needs for the time being. * Finally this allows us to reuse some artifacts such as our `TargetMachine` creation, where all our options we used today aren't necessarily supported by upstream LLVM yet. My hope is that we can get some experience with this copy/paste in tree and then eventually upstream some work to LLVM itself to avoid the duplication while still ensuring our needs are met. Otherwise I fear that maintaining these bindings may be quite costly over the years with LLVM updates!
2017-09-15Add 'native' to -C target-cpu=helpMatt Ickstadt-0/+7
2017-08-08Fix covered-switch-default warnings in PassWrapperkennytm-2/+4
(See #39063 for explanation)
2017-07-31Gate LLVMRustHasFeature on LLVM_RUSTLLVMJosh Stone-1/+1
Commit c4710203c098b in #43492 make `LLVMRustHasFeature` "more robust" by using `getFeatureTable()`. However, this function is specific to Rust's own LLVM fork, not upstream LLVM-4.0, so we need to use `#if LLVM_RUSTLLVM` to guard this call.
2017-07-28Make LLVMRustHasFeature more robustLuca Barbato-13/+7
The function should accept feature strings that old LLVM might not support. Simplify the code using the same approach used by LLVMRustPrintTargetFeatures. Dummify the function for non 4.0 LLVM and update the tests accordingly.
2017-07-01When writing LLVM IR output demangled fn name in commentsStepan Koltsov-2/+126
`--emit=llvm-ir` looks like this now: ``` ; <alloc::vec::Vec<T> as core::ops::index::IndexMut<core::ops::range::RangeFull>>::index_mut ; Function Attrs: inlinehint uwtable define internal { i8*, i64 } @"_ZN106_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$core..ops..index..IndexMut$LT$core..ops..range..RangeFull$GT$$GT$9index_mut17h7f7b576609f30262E"(%"alloc::vec::Vec<u8>"* dereferenceable(24)) unnamed_addr #0 { start: ... ``` cc https://github.com/integer32llc/rust-playground/issues/15
2017-05-01Auto merge of #41560 - alevy:rwpi-ropi, r=eddybbors-23/+43
Add RWPI/ROPI relocation model support This PR adds support for using LLVM 4's ROPI and RWPI relocation models for ARM. ROPI (Read-Only Position Independence) and RWPI (Read-Write Position Independence) are two new relocation models in LLVM for the ARM backend ([LLVM changset](https://reviews.llvm.org/rL278015)). The motivation is that these are the specific strategies we use in userspace [Tock](https://www.tockos.org) apps, so supporting this is an important step (perhaps the final step, but can't confirm yet) in enabling userspace Rust processes. ## Explanation ROPI makes all code and immutable accesses PC relative, but not assumed to be overriden at runtime (so for example, jumps are always relative). RWPI uses a base register (`r9`) that stores the addresses of the GOT in memory so the runtime (e.g. a kernel) only adjusts r9 tell running code where the GOT is. ## Complications adding support in Rust While this landed in LLVM master back in August, the header files in `llvm-c` have not been updated yet to reflect it. Rust replicates that header file's version of the `LLVMRelocMode` enum as the Rust enum `llvm::RelocMode` and uses an implicit cast in the ffi to translate from Rust's notion of the relocation model to the LLVM library's notion. My workaround for this currently is to replace the `LLVMRelocMode` argument to `LLVMTargetMachineRef` with an int and using the hardcoded int representation of the `RelocMode` enum. This is A Bad Idea(tm), but I think very nearly the right thing. Would a better alternative be to patch rust-llvm to support these enum variants (also a fairly trivial change)?
2017-04-28Added LLVMRustRelocModeAmit Aryeh Levy-34/+43
Replaces the llvm-c exposed LLVMRelocMode, which does not include all relocation model variants, with a LLVMRustRelocMode modeled after LLVMRustCodeMode.
2017-04-26Add RWPI/ROPI relocation model supportAmit Aryeh Levy-4/+15
Adds support for using LLVM 4's ROPI and RWPI relocation models for ARM
2017-04-25Add Hexagon supportMichael Wu-1/+8
This requires an updated LLVM with D31999 and D32000 to build libcore. A basic hello world builds and runs successfully on the hexagon simulator.
2017-01-01Auto merge of #38745 - CannedYerins:llvm-code-style, r=rkruppebors-65/+65
Improve naming style in rustllvm. As per the LLVM style guide, use CamelCase for all locals and classes, and camelCase for all non-FFI functions. Also, make names of variables of commonly used types more consistent. Fixes #38688. r? @rkruppe
2017-01-01Merge branch 'master' into sparc64Seo Sanghyeon-350/+306
2016-12-31Improve naming style in rustllvm.Ian Kerins-65/+65
As per the LLVM style guide, use CamelCase for all locals and classes, and camelCase for all non-FFI functions. Also, make names of variables of commonly used types more consistent. Fixes #38688.
2016-12-30Switching from NULL to nullptr in src/rustllvm.karpinski-4/+4
2016-12-30Ran clang-format on src/rustllvm with llvm as the coding style.karpinski-349/+305
2016-12-29further enable the Sparc LLVM backendJonathan A. Kollasch-1/+8
2016-12-07printf type correctnessRobin Kruppe-2/+5
The %.*s format specifier requires an int for the maximum size, but StringRef::size is a size_t cc @shepmaster
2016-11-28Don't assume llvm::StringRef is null terminatedRobin Kruppe-3/+5
StringRefs have a length and their contents are not usually null-terminated. The solution is to either copy the string data (in rustc_llvm::diagnostic) or take the size into account (in LLVMRustPrintPasses). I couldn't trigger a bug caused by this (apparently all the strings returned in practice are actually null-terminated) but this is more correct and more future-proof.
2016-11-27Adapt LLVMRustPrintPasses to LLVM 4.0 preferring `StringRef` over `char *`Robin Kruppe-0/+7
2016-11-18[LLVM 4.0] Update AlwaysInliner pass header and constructorJake Goulding-0/+7
2016-11-12also enable the MSP430 backend in MakefilesJorge Aparicio-1/+8
2016-09-26Extend preprocessor LLVM version checks to support LLVM 4.xJake Goulding-6/+6
This doesn't actually do anything for LLVM 4.x yet, but sets the stage.
2016-08-28build llvm with systemz backend enabled, and link to related librariesJorge Aparicio-1/+8
when building rust against system llvm closes #36077
2016-08-06Merge branch 'master' into issue-30961Cameron Hart-31/+173
2016-08-03Support removed LLVM intrinsics by invoking its AutoUpgrade mechanism.Eduard Burtescu-0/+8
2016-08-03finish type-auditing rustllvmAriel Ben-Yehuda-3/+3
2016-08-03audit LLVM C++ types in ArchiveWrapper and PassWrapperAriel Ben-Yehuda-26/+112
2016-07-29Use C type when passing value to LLVM passJan-Erik Rediger-1/+24
Previously the C type LLVMRelocMode (available as RelocMode in Rust) was passed as is to the function. However createTargetMachine expects a Reloc::Model, which is an enum just one value short. Additionally, the function was marked as requiring Reloc::Model in the C code, but RelocMode on the Rust-side. We now use the correct C type LLVMRelocMode and convert it to an Optional<Reloc::Model> as expected by the createTargetMachine call the same the original LLVMCreateTargetMachine function does. See https://github.com/llvm-mirror/llvm/blob/c9b262bfbd5b9fb6f10749dba1465569f39bd625/lib/Target/TargetMachineC.cpp#L104-L121 This was found by @eddyb.
2016-07-29[LLVM-3.9] Increase PIELevelJan-Erik Rediger-1/+1
Previously, we had a PositionIndependentExecutable, now we simply choose the highest level. This should be equivalent. :cake:
2016-07-29[LLVM-3.9] Configure PIE at the module level instead of compilation unit levelJan-Erik Rediger-0/+10
This was deleted here[1] which appears to be replaced by this[2] which is a new setPIELevel function on the LLVM module itself. [1]: http://reviews.llvm.org/D19753 [2]: http://reviews.llvm.org/D19671
2016-07-29[LLVM-3.9] Preserve certain functions when internalizingJan-Erik Rediger-1/+16
This makes sure to still use the old way for older LLVM versions.
2016-07-29[LLVM-3.9] Specify that we are using the legacy interfaceJan-Erik Rediger-3/+3
LLVM pass manager infrastructure is currently getting rewritten to be more flexible, but the rewrite isn't complete yet.
2016-07-24Pass -DLLVM_RUSTLLVM to compile against rust llvm fork.Cameron Hart-3/+17
If using system llvm don't try use modifications made in the fork.
2016-07-11Add help for target CPUs, features, relocation and code models.Cameron Hart-0/+38
2016-06-09Reflect supporting only LLVM 3.7+ in the LLVM wrappersJake Goulding-52/+1
2016-04-09Implement feature extraction from `TargetMachine`Andrea Canciani-0/+69
Add the `LLVMRustHasFeature` function to check whether a `TargetMachine` has a given feature.
2016-01-25Register LLVM passes with the correct LLVM pass manager.Corey Farwell-6/+30
LLVM was upgraded to a new version in this commit: https://github.com/rust-lang/rust/commit/f9d4149c29e8b989fa3624993be379f380e48dcf which was part of this pull request: https://github.com/rust-lang/rust/issues/26025 Consider the following two lines from that commit: https://github.com/rust-lang/rust/commit/f9d4149c29e8b989fa3624993be379f380e48dcf#diff-a3b24dbe2ea7c1981f9ac79f9745f40aL462 https://github.com/rust-lang/rust/commit/f9d4149c29e8b989fa3624993be379f380e48dcf#diff-a3b24dbe2ea7c1981f9ac79f9745f40aL469 The purpose of these lines is to register LLVM passes. Prior to the that commit, the passes being handled were assumed to be ModulePasses (a specific type of LLVM pass) since they were being added to a ModulePass manager. After that commit, both lines were refactored (presumably in an attempt to DRY out the code), but the ModulePasses were changed to be registered to a FunctionPass manager. This change resulted in ModulePasses being run, but a Function object was being passed as a parameter to the pass instead of a Module, which resulted in segmentation faults. In this commit, I changed relevant sections of the code to check the type of the passes being added and register them to the appropriate pass manager. Closes https://github.com/rust-lang/rust/issues/31067
2015-11-19Remove segmented stack option from LLVMRustCreateTargetMachine. Unused.Brian Anderson-1/+0
2015-10-24rustllvm: Update to LLVM trunkSeo Sanghyeon-0/+2
2015-10-13Avoid using getDataLayout, deprecated in LLVM 3.7Seo Sanghyeon-2/+1
2015-10-08typos: fix a grabbag of typos all over the placeCristi Cobzarenco-1/+1
2015-07-16trans: Clean up handling the LLVM data layoutAlex Crichton-0/+27
Turns out for OSX our data layout was subtly wrong and the LLVM update must have exposed this. Instead of fixing this I've removed all data layouts from the compiler to just use the defaults that LLVM provides for all targets. All data layouts (and a number of dead modules) are removed from the compiler here. Custom target specifications can still provide a custom data layout, but it is now an optional key as the default will be used if one isn't specified.
2015-06-16rustc: Update LLVMAlex Crichton-7/+51
This commit updates the LLVM submodule in use to the current HEAD of the LLVM repository. This is primarily being done to start picking up unwinding support for MSVC, which is currently unimplemented in the revision of LLVM we are using. Along the way a few changes had to be made: * As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some significant changes to our RustWrapper.cpp * As usual, some pass management changed in LLVM, so clang was re-scrutinized to ensure that we're doing the same thing as clang. * Some optimization options are now passed directly into the `PassManagerBuilder` instead of through CLI switches to LLVM. * The `NoFramePointerElim` option was removed from LLVM, favoring instead the `no-frame-pointer-elim` function attribute instead. Additionally, LLVM has picked up some new optimizations which required fixing an existing soundness hole in the IR we generate. It appears that the current LLVM we use does not expose this hole. When an enum is moved, the previous slot in memory is overwritten with a bit pattern corresponding to "dropped". When the drop glue for this slot is run, however, the switch on the discriminant can often start executing the `unreachable` block of the switch due to the discriminant now being outside the normal range. This was patched over locally for now by having the `unreachable` block just change to a `ret void`.
2015-04-21LLVM < 3.5 is unsupported since bb18a3cTamir Duberstein-16/+3
2015-03-10Add support for target-cpu=nativeJulian Orth-1/+7
2014-10-12optimize position independent code in executablesDaniel Micay-0/+2
Position independent code has fewer requirements in executables, so pass the appropriate flag to LLVM in order to allow more optimization. At the moment this means faster thread-local storage.
2014-10-04Update LLVM.Luqman Aden-3/+15
2014-05-22Update to LLVM head and mark various ptrs as nonnull.Luqman Aden-0/+1
2014-05-15Add a crate for missing stubs from libcoreAlex Crichton-4/+14
The core library in theory has 0 dependencies, but in practice it has some in order for it to be efficient. These dependencies are in the form of the basic memory operations provided by libc traditionally, such as memset, memcmp, etc. These functions are trivial to implement and themselves have 0 dependencies. This commit adds a new crate, librlibc, which will serve the purpose of providing these dependencies. The crate is never linked to by default, but is available to be linked to by downstream consumers. Normally these functions are provided by the system libc, but in other freestanding contexts a libc may not be available. In these cases, librlibc will suffice for enabling execution with libcore. cc #10116
2014-04-29rustc: Enable -f{function,data}-sectionsAlex Crichton-1/+5
The compiler has previously been producing binaries on the order of 1.8MB for hello world programs "fn main() {}". This is largely a result of the compilation model used by compiling entire libraries into a single object file and because static linking is favored by default. When linking, linkers will pull in the entire contents of an object file if any symbol from the object file is used. This means that if any symbol from a rust library is used, the entire library is pulled in unconditionally, regardless of whether the library is used or not. Traditional C/C++ projects do not normally encounter these large executable problems because their archives (rust's rlibs) are composed of many objects. Because of this, linkers can eliminate entire objects from being in the final executable. With rustc, however, the linker does not have the opportunity to leave out entire object files. In order to get similar benefits from dead code stripping at link time, this commit enables the -ffunction-sections and -fdata-sections flags in LLVM, as well as passing --gc-sections to the linker *by default*. This means that each function and each global will be placed into its own section, allowing the linker to GC all unused functions and data symbols. By enabling these flags, rust is able to generate much smaller binaries default. On linux, a hello world binary went from 1.8MB to 597K (a 67% reduction in size). The output size of dynamic libraries remained constant, but the output size of rlibs increased, as seen below: libarena - 2.27% bigger ( 292872 => 299508) libcollections - 0.64% bigger ( 6765884 => 6809076) libflate - 0.83% bigger ( 186516 => 188060) libfourcc - 14.71% bigger ( 307290 => 352498) libgetopts - 4.42% bigger ( 761468 => 795102) libglob - 2.73% bigger ( 899932 => 924542) libgreen - 9.63% bigger ( 1281718 => 1405124) libhexfloat - 13.88% bigger ( 333738 => 380060) liblibc - 10.79% bigger ( 551280 => 610736) liblog - 10.93% bigger ( 218208 => 242060) libnative - 8.26% bigger ( 1362096 => 1474658) libnum - 2.34% bigger ( 2583400 => 2643916) librand - 1.72% bigger ( 1608684 => 1636394) libregex - 6.50% bigger ( 1747768 => 1861398) librustc - 4.21% bigger (151820192 => 158218924) librustdoc - 8.96% bigger ( 13142604 => 14320544) librustuv - 4.13% bigger ( 4366896 => 4547304) libsemver - 2.66% bigger ( 396166 => 406686) libserialize - 1.91% bigger ( 6878396 => 7009822) libstd - 3.59% bigger ( 39485286 => 40902218) libsync - 3.95% bigger ( 1386390 => 1441204) libsyntax - 4.96% bigger ( 35757202 => 37530798) libterm - 13.99% bigger ( 924580 => 1053902) libtest - 6.04% bigger ( 2455720 => 2604092) libtime - 2.84% bigger ( 1075708 => 1106242) liburl - 6.53% bigger ( 590458 => 629004) libuuid - 4.63% bigger ( 326350 => 341466) libworkcache - 8.45% bigger ( 1230702 => 1334750) This increase in size is a result of encoding many more section names into each object file (rlib). These increases are moderate enough that this change seems worthwhile to me, due to the drastic improvements seen in the final artifacts. The overall increase of the stage2 target folder (not the size of an install) went from 337MB to 348MB (3% increase). Additionally, linking is generally slower when executed with all these new sections plus the --gc-sections flag. The stage0 compiler takes 1.4s to link the `rustc` binary, where the stage1 compiler takes 1.9s to link the binary. Three megabytes are shaved off the binary. I found this increase in link time to be acceptable relative to the benefits of code size gained. This commit only enables --gc-sections for *executables*, not dynamic libraries. LLVM does all the heavy lifting when producing an object file for a dynamic library, so there is little else for the linker to do (remember that we only have one object file). I conducted similar experiments by putting a *module's* functions and data symbols into its own section (granularity moved to a module level instead of a function/static level). The size benefits of a hello world were seen to be on the order of 400K rather than 1.2MB. It seemed that enough benefit was gained using ffunction-sections that this route was less desirable, despite the lesser increases in binary rlib size.