Commit graph

66 commits

Author SHA1 Message Date
kennytm
15e8b0fd3d
Fix covered-switch-default warnings in PassWrapper
(See #39063 for explanation)
2017-08-08 16:17:33 +08:00
Josh Stone
881a724660 Gate LLVMRustHasFeature on LLVM_RUSTLLVM
Commit c4710203c0 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-31 18:10:01 -07:00
Luca Barbato
c4710203c0 Make LLVMRustHasFeature more robust
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-28 14:30:06 +00:00
Stepan Koltsov
b62bdaafe0 When writing LLVM IR output demangled fn name in comments
`--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-07-01 03:16:43 +03:00
bors
4cb396c680 Auto merge of #41560 - alevy:rwpi-ropi, r=eddyb
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-05-01 17:23:09 +00:00
Amit Aryeh Levy
0f00f27e0d Added LLVMRustRelocMode
Replaces the llvm-c exposed LLVMRelocMode, which does not include all
relocation model variants, with a LLVMRustRelocMode modeled after
LLVMRustCodeMode.
2017-04-28 17:33:56 -05:00
Amit Aryeh Levy
32b92669e4 Add RWPI/ROPI relocation model support
Adds support for using LLVM 4's ROPI and RWPI relocation models for ARM
2017-04-26 16:25:14 -04:00
Michael Wu
c558a2ae37 Add Hexagon support
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-04-25 01:56:44 -04:00
bors
ac5cd3bd43 Auto merge of #38745 - CannedYerins:llvm-code-style, r=rkruppe
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-01 11:58:02 +00:00
Seo Sanghyeon
b14785d3d0 Merge branch 'master' into sparc64 2017-01-01 12:40:10 +09:00
Ian Kerins
e6f97114ca 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.
2016-12-31 13:20:30 -05:00
karpinski
72ebc02f13 Switching from NULL to nullptr in src/rustllvm. 2016-12-30 16:37:05 +01:00
karpinski
c72d859e4f Ran clang-format on src/rustllvm with llvm as the coding style. 2016-12-30 16:36:50 +01:00
Jonathan A. Kollasch
982849535d further enable the Sparc LLVM backend 2016-12-29 21:30:01 -05:00
Robin Kruppe
f58e553001 printf type correctness
The %.*s format specifier requires an int for the maximum size, but StringRef::size is a size_t

cc @shepmaster
2016-12-07 17:09:34 +01:00
Robin Kruppe
85dc08e525 Don't assume llvm::StringRef is null terminated
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-28 17:33:13 +01:00
Robin Kruppe
cb0e24eafa Adapt LLVMRustPrintPasses to LLVM 4.0 preferring StringRef over char * 2016-11-27 14:48:47 +01:00
Jake Goulding
acc9efa528 [LLVM 4.0] Update AlwaysInliner pass header and constructor 2016-11-18 11:21:47 -05:00
Jorge Aparicio
4f9f7b014e also enable the MSP430 backend in Makefiles 2016-11-12 17:33:35 -05:00
Jake Goulding
e6e117c33a Extend preprocessor LLVM version checks to support LLVM 4.x
This doesn't actually do anything for LLVM 4.x yet, but sets the stage.
2016-09-26 13:40:29 -04:00
Jorge Aparicio
15d8dfb6a0 build llvm with systemz backend enabled, and link to related libraries
when building rust against system llvm

closes #36077
2016-08-28 13:18:28 -05:00
Cameron Hart
cbb88faad7 Merge branch 'master' into issue-30961 2016-08-06 15:50:48 +10:00
Eduard Burtescu
63f0c4de67 Support removed LLVM intrinsics by invoking its AutoUpgrade mechanism. 2016-08-03 22:37:57 +03:00
Ariel Ben-Yehuda
3041a97b1a finish type-auditing rustllvm 2016-08-03 15:08:47 +03:00
Ariel Ben-Yehuda
696691e3c4 audit LLVM C++ types in ArchiveWrapper and PassWrapper 2016-08-03 15:08:47 +03:00
Jan-Erik Rediger
2c16e24643 Use C type when passing value to LLVM pass
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
c9b262bfbd/lib/Target/TargetMachineC.cpp (L104-L121)

This was found by @eddyb.
2016-07-29 10:29:44 +02:00
Jan-Erik Rediger
deafab19be [LLVM-3.9] Increase PIELevel
Previously, we had a PositionIndependentExecutable, now we simply
choose the highest level. This should be equivalent.

🍰
2016-07-29 10:29:44 +02:00
Jan-Erik Rediger
9e706f90cb [LLVM-3.9] Configure PIE at the module level instead of compilation unit level
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 10:29:44 +02:00
Jan-Erik Rediger
5b44e10fb7 [LLVM-3.9] Preserve certain functions when internalizing
This makes sure to still use the old way for older LLVM versions.
2016-07-29 10:29:44 +02:00
Jan-Erik Rediger
6ed5db8d35 [LLVM-3.9] Specify that we are using the legacy interface
LLVM pass manager infrastructure is currently getting rewritten to be
more flexible, but the rewrite isn't complete yet.
2016-07-29 10:29:44 +02:00
Cameron Hart
ce50bedd8c Pass -DLLVM_RUSTLLVM to compile against rust llvm fork.
If using system llvm don't try use modifications made in the fork.
2016-07-24 19:49:10 +10:00
Cameron Hart
e1efa324ec Add help for target CPUs, features, relocation and code models. 2016-07-11 00:22:13 +10:00
Jake Goulding
4f01329e0e Reflect supporting only LLVM 3.7+ in the LLVM wrappers 2016-06-09 15:59:26 -04:00
Andrea Canciani
c883463e94 Implement feature extraction from TargetMachine
Add the `LLVMRustHasFeature` function to check whether a
`TargetMachine` has a given feature.
2016-04-09 00:39:04 +02:00
Corey Farwell
d9426210b1 Register LLVM passes with the correct LLVM pass manager.
LLVM was upgraded to a new version in this commit:

f9d4149c29

which was part of this pull request:

https://github.com/rust-lang/rust/issues/26025

Consider the following two lines from that commit:

f9d4149c29 (diff-a3b24dbe2ea7c1981f9ac79f9745f40aL462)

f9d4149c29 (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
2016-01-25 00:15:39 -05:00
Brian Anderson
99741700e5 Remove segmented stack option from LLVMRustCreateTargetMachine. Unused. 2015-11-19 16:58:23 -08:00
Seo Sanghyeon
b285f92025 rustllvm: Update to LLVM trunk 2015-10-24 18:42:23 +09:00
Seo Sanghyeon
22dc408217 Avoid using getDataLayout, deprecated in LLVM 3.7 2015-10-13 15:11:59 +09:00
Cristi Cobzarenco
4b308b44e1 typos: fix a grabbag of typos all over the place 2015-10-08 19:49:31 +01:00
Alex Crichton
958d563825 trans: Clean up handling the LLVM data layout
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-07-16 20:25:52 -07:00
Alex Crichton
f9d4149c29 rustc: Update LLVM
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-06-16 22:56:42 -07:00
Tamir Duberstein
ba276adab5 LLVM < 3.5 is unsupported since bb18a3c 2015-04-21 07:20:48 -07:00
Julian Orth
660b48fae5 Add support for target-cpu=native 2015-03-10 01:56:51 +01:00
Daniel Micay
4deb4bcba5 optimize position independent code in executables
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-12 09:18:14 -04:00
Luqman Aden
4b22178d32 Update LLVM. 2014-10-04 13:28:57 -04:00
Luqman Aden
90eeb92e10 Update to LLVM head and mark various ptrs as nonnull. 2014-05-22 21:06:24 -04:00
Alex Crichton
a7bee7b05d Add a crate for missing stubs from libcore
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-05-15 13:50:37 -07:00
Alex Crichton
58ab4a0064 rustc: Enable -f{function,data}-sections
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.
2014-04-29 10:29:00 -07:00
Alex Crichton
de7845ac72 rustc: Fix passing errors from LLVM to rustc
Many of the instances of setting a global error variable ended up leaving a
dangling pointer into free'd memory. This changes the method of error
transmission to strdup any error and "relinquish ownership" to rustc when it
gets an error. The corresponding Rust code will then free the error as
necessary.

Closes #12865
2014-04-23 10:04:29 -07:00
Alex Crichton
30ff17f809 Upgrade LLVM
This comes with a number of fixes to be compatible with upstream LLVM:

* Previously all monomorphizations of "mem::size_of()" would receive the same
  symbol. In the past LLVM would silently rename duplicated symbols, but it
  appears to now be dropping the duplicate symbols and functions now. The symbol
  names of monomorphized functions are now no longer solely based on the type of
  the function, but rather the type and the unique hash for the
  monomorphization.

* Split stacks are no longer a global feature controlled by a flag in LLVM.
  Instead, they are opt-in on a per-function basis through a function attribute.
  The rust #[no_split_stack] attribute will disable this, otherwise all
  functions have #[split_stack] attached to them.

* The compare and swap instruction now takes two atomic orderings, one for the
  successful case and one for the failure case. LLVM internally has an
  implementation of calculating the appropriate failure ordering given a
  particular success ordering (previously only a success ordering was
  specified), and I copied that into the intrinsic translation so the failure
  ordering isn't supplied on a source level for now.

* Minor tweaks to LLVM's API in terms of debuginfo, naming, c++11 conventions,
  etc.
2014-04-17 11:11:39 -07:00