Drop of arrays is now translated in trans::block in an ugly way that I
should clean up in a later PR, and does not handle panics in the middle
of an array drop, but this commit & PR are growing too big.
These changes are in the same commit to avoid needing to adapt
meth::trans_object_shim to the new scheme.
One codegen-units test is broken because we instantiate the shims even
when they are not needed. This will be fixed in the next PR.
first pass at isolating dep-graph tasks
This intentionally leaves `DepGraph::in_task()`, the more common form,
alone. Eventually all uses of `DepGraph::in_task()` should be ported
to `with_task()`, but I wanted to start with a smaller subset.
I also used `AssertDepGraphSafe` on the closures that are found in
trans. This is because the types there are non-trivial and I wanted to
lay down the mechanism and come back to the more subtle cases.
The current approach taken in this PR has a downside: it is necessary
to manually "reify" fn types into fn pointers when starting a task,
like so:
dep_graph.with_task(..., task_fn as fn(_))
this is because `with_task` takes some type `T` that implements
`DepGraphTask` rather than taking a `fn()` type directly. *This* is so
that we can accept closure and also so that we can accept fns with
multiple arities. I am not sure this is the right approach.
Originally I wanted to use closures bound by an auto trait, but that
approach has some limitations:
- the trait cannot have a `read()` method; since the current method
is unused, that may not be a problem.
- more importantly, we would want the auto trait to be "undefined" for all types
*by default* -- that is, this use case doesn't really fit the typical
auto trait scenario. For example, imagine that there is a `u32` loaded
out of a `hir::Node` -- we don't really want to be passing that
`u32` into the task!
A task function is now given as a `fn` pointer to ensure that it carries
no state. Each fn can take two arguments, because that worked out to be
convenient -- these two arguments must be of some type that is
`DepGraphSafe`, a new trait that is intended to prevent "leaking"
information into the task that was derived from tracked state.
This intentionally leaves `DepGraph::in_task()`, the more common form,
alone. Eventually all uses of `DepGraph::in_task()` should be ported
to `with_task()`, but I wanted to start with a smaller subset.
Originally I wanted to use closures bound by an auto trait, but that
approach has some limitations:
- the trait cannot have a `read()` method; since the current method
is unused, that may not be a problem.
- more importantly, we would want the auto trait to be "undefined" for all types
*by default* -- that is, this use case doesn't really fit the typical
auto trait scenario. For example, imagine that there is a `u32` loaded
out of a `hir::Node` -- we don't really want to be passing that
`u32` into the task!
In MIR construction, operands need to live exactly until they are used,
which is during the (sub)expression that made the call to `as_operand`.
Before this PR, operands lived until the end of the temporary scope,
which was sometimes unnecessarily longer and sometimes too short.
Fixes#38669.
transition borrowck to visit all **bodies** and not item-likes
This is a better structure for incremental compilation and also more compatible with the eventual borrowck mir. It also fixes#38520 as a drive-by fix.
r? @eddyb
This reduces the number of dynamic drops in libstd from 1141 to 899.
However, without this change, the next patch would have created much
more dynamic drops.
A basic merge unswitching hack reduced the number of dynamic drops to
644, with no effect on stack usage. I should be writing a more dedicated
drop unswitching pass.
No performance measurements.
The types of statics, like all other items, are stored in the tcx
unnormalized. This is necessarily so, because
a) Item types other than statics have generics, which can't be
normalized.
b) Eager normalization causes undesirable on-demand dependencies.
Keeping with the principle that MIR lvalues require no normalization in
order to interpret, this patch stores the normalized type of the statics
in the Lvalue and reads it to get the lvalue type.
Fixes#39367.
add `-C overflow-checks` option
In addition to defining and handling the new option, we also add a method on librustc::Session for determining the necessity of overflow checks. This method provides a single point to sort out the three (!) different ways for turning on overflow checks: -C debug-assertions, -C overflow-checks, and -Z force-overflow-checks.
I was seeing a [run-pass/issue-28950.rs](b1363a73ed/src/test/run-pass/issue-28950.rs) failure on my machine with these patches, but I was also seeing the failure without the changes to the core compiler. We'll see what travis says.
Fixes#33134. r? @alexcrichton
In addition to defining and handling the new option, we also add a
method on librustc::Session for determining the necessity of overflow
checks. This method provides a single point to sort out the three (!)
different ways for turning on overflow checks: -C debug-assertions, -C
overflow-checks, and -Z force-overflow-checks.
Fixes#33134.
[MIR] SwitchInt Everywhere
Something I've been meaning to do for a very long while. This PR essentially gets rid of 3 kinds of conditional branching and only keeps the most general one - `SwitchInt`. Primary benefits are such that dealing with MIR now does not involve dealing with 3 different ways to do conditional control flow. On the other hand, constructing a `SwitchInt` currently requires more code than what previously was necessary to build an equivalent `If` terminator. Something trivially "fixable" with some constructor methods somewhere (MIR needs stuff like that badly in general).
Some timings (tl;dr: slightly faster^1 (unexpected), but also uses slightly more memory at peak (expected)):
^1: Not sure if the speed benefits are because of LLVM liking the generated code better or the compiler itself getting compiled better. Either way, its a net benefit. The CORE and SYNTAX timings done for compilation without optimisation.
```
AFTER:
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Finished release [optimized] target(s) in 31.50 secs
Finished release [optimized] target(s) in 31.42 secs
Building stage1 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Finished release [optimized] target(s) in 439.56 secs
Finished release [optimized] target(s) in 435.15 secs
CORE: 99% (24.81 real, 0.13 kernel, 24.57 user); 358536k resident
CORE: 99% (24.56 real, 0.15 kernel, 24.36 user); 359168k resident
SYNTAX: 99% (49.98 real, 0.48 kernel, 49.42 user); 653416k resident
SYNTAX: 99% (50.07 real, 0.58 kernel, 49.43 user); 653604k resident
BEFORE:
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Finished release [optimized] target(s) in 31.84 secs
Building stage1 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Finished release [optimized] target(s) in 451.17 secs
CORE: 99% (24.66 real, 0.20 kernel, 24.38 user); 351096k resident
CORE: 99% (24.36 real, 0.17 kernel, 24.18 user); 352284k resident
SYNTAX: 99% (52.24 real, 0.56 kernel, 51.66 user); 645544k resident
SYNTAX: 99% (51.55 real, 0.48 kernel, 50.99 user); 646428k resident
```
cc @nikomatsakis @eddyb