Rotate between compilation units while translating. The "worker threads"
commit added support for multiple compilation units, but only translated into
one, leaving the rest empty. With this commit, `trans` rotates between various
compilation units while translating, using a simple stragtegy: upon entering a
module, switch to translating into whichever compilation unit currently
contains the fewest LLVM instructions.
Most of the actual changes here involve getting symbol linkage right, so that
items translated into different compilation units will link together properly
at the end.
Generic extern functions written in Rust have their names mangled, as well as their internal clownshoe __rust_abi functions. This allows e.g. specific monomorphizations of these functions to be used as callbacks.
Closes#12502.
LLVM doesn't handle i1 value in allocas/memory very well and skips a number of optimizations if it hits it. So we have to do the same thing that Clang does, using i1 for SSA values, but storing i8 in memory.
Fixes#15203.
LLVM doesn't really like types with a bit-width that isn't a multiple of
8 and disable various optimizations if it encounters such types used
with loads/stores. OTOH, booleans must be represented as i1 when used as
SSA values. To get the best results, we must use i1 for SSA values, and
i8 when storing the value to memory.
By using range asserts on loads, LLVM can eliminate the required
zero-extend and truncate operations.
Fixes#15203
This commit removes all support in the compiler for the #[crate_id] attribute
and all of its derivative infrastructure. A list of the functionality removed is:
* The #[crate_id] attribute no longer exists
* There is no longer the concept of a version of a crate
* Version numbers are no longer appended to symbol names
* The --crate-id command line option has been removed
To migrate forward, rename #[crate_id] to #[crate_name] and only the name of the
crate itself should be mentioned. The version/path of the old crate id should be
removed.
For a transitionary state, the #[crate_id] attribute is still accepted if
the #[crate_name] is not present, but it is warned about if it is the only
identifier present.
RFC: 0035-remove-crate-id
[breaking-change]
floating point numbers for real.
This will break code that looks like:
let mut x = 0;
while ... {
x += 1;
}
println!("{}", x);
Change that code to:
let mut x = 0i;
while ... {
x += 1;
}
println!("{}", x);
Closes#15201.
[breaking-change]
When calling a foreign function, some arguments and/or return value
attributes are required to conform to the foreign ABI. Currently those
attributes are only added to the declaration of foreign functions. With
direct calls, this is no problem, because LLVM can see that those
attributes apply to the call. But with an indirect call, LLVM cannot do
that and the attribute is missing.
To fix that, we have to add those attribute to the calls to foreign
functions as well.
This also allows to remove the special handling of the SRet attribute,
which is ABI-dependent and will be set via the `attr` field of the
return type's `ArgType`.
The ArgType type gives us a generic way to specify an attribute for a
type to ensure ABI conformance for foreign functions. But the code that
actually sets the argument attributes in the function declaration
only sets the attribute for the return type when the type is indirect.
Since LLVMAddAttribute() doesn't allow to set attributes on the return
type, we have to use LLVMAddFunctionAttribute() instead.
This didn't cause problems yet, because currently only some indirect
types require attributes to be set.
* The select/plural methods from format strings are removed
* The # character no longer needs to be escaped
* The \-based escapes have been removed
* '{{' is now an escape for '{'
* '}}' is now an escape for '}'
Closes#14810
[breaking-change]
This commit is part of the ongoing libstd facade efforts (cc #13851). The
compiler now recognizes some language items as "extern { fn foo(...); }" and
will automatically perform the following actions:
1. The foreign function has a pre-defined name.
2. The crate and downstream crates can only be built as rlibs until a crate
defines the lang item itself.
3. The actual lang item has a pre-defined name.
This is essentially nicer compiler support for the hokey
core-depends-on-std-failure scheme today, but it is implemented the same way.
The details are a little more hidden under the covers.
In addition to failure, this commit promotes the eh_personality and
rust_stack_exhausted functions to official lang items. The compiler can generate
calls to these functions, causing linkage errors if they are left undefined. The
checking for these items is not as precise as it could be. Crates compiling with
`-Z no-landing-pads` will not need the eh_personality lang item, and crates
compiling with no split stacks won't need the stack exhausted lang item. For
ease, however, these items are checked for presence in all final outputs of the
compiler.
It is quite easy to define dummy versions of the functions necessary:
#[lang = "stack_exhausted"]
extern fn stack_exhausted() { /* ... */ }
#[lang = "eh_personality"]
extern fn eh_personality() { /* ... */ }
cc #11922, rust_stack_exhausted is now a lang item
cc #13851, libcollections is blocked on eh_personality becoming weak
This change removes the AbiSet from the AST, converting all usage to have just
one Abi value. The current scheme selects a relevant ABI given a list of ABIs
based on the target architecture and how relevant each ABI is to that
architecture.
Instead of this mildly complicated scheme, only one ABI will be allowed in abi
strings, and pseudo-abis will be created for special cases as necessary. For
example the "system" abi exists for stdcall on win32 and C on win64.
Closes#10049
Remove the linker_private and linker_private_weak linkage attributes,
they have been superseded by private and private_weak and have been
removed in upstream LLVM in commit r203866.
It is often convenient to have forms of weak linkage or other various types of
linkage. Sadly, just using these flavors of linkage are not compatible with
Rust's typesystem and how it considers some pointers to be non-null.
As a compromise, this commit adds support for weak linkage to external symbols,
but it requires that this is only placed on extern statics of type `*T`.
Codegen-wise, we get translations like:
// rust code
extern {
#[linkage = "extern_weak"]
static foo: *i32;
}
// generated IR
@foo = extern_weak global i32
@_some_internal_symbol = internal global *i32 @foo
All references to the rust value of `foo` then reference `_some_internal_symbol`
instead of the symbol `_foo` itself. This allows us to guarantee that the
address of `foo` will never be null while the value may sometimes be null.
An example was implemented in `std::rt::thread` to determine if
`__pthread_get_minstack()` is available at runtime, and a test is checked in to
use it for a static value as well. Function pointers a little odd because you
still need to transmute the pointer value to a function pointer, but it's
thankfully better than not having this capability at all.