This does a number of things, but especially dramatically reduce the
number of allocations performed for operations involving attributes/
meta items:
- Converts ast::meta_item & ast::attribute and other associated enums
to CamelCase.
- Converts several standalone functions in syntax::attr into methods,
defined on two traits AttrMetaMethods & AttributeMethods. The former
is common to both MetaItem and Attribute since the latter is a thin
wrapper around the former.
- Deletes functions that are unnecessary due to iterators.
- Converts other standalone functions to use iterators and the generic
AttrMetaMethods rather than allocating a lot of new vectors (e.g. the
old code would have to allocate a new vector to use functions that
operated on &[meta_item] on &[attribute].)
- Moves the core algorithm of the #[cfg] matching to syntax::attr,
similar to find_inline_attr and find_linkage_metas.
This doesn't have much of an effect on the speed of #[cfg] stripping,
despite hugely reducing the number of allocations performed; presumably
most of the time is spent in the ast folder rather than doing attribute
checks.
Also fixes the Eq instance of MetaItem_ to correctly ignore spaces, so
that `rustc --cfg 'foo(bar)'` now works.
`rustpkg build`, if executed in a package source directory inside
a workspace, will now build that package. By "inside a workspace"
I mean that the parent directory has to be called `src`, and rustpkg
will create a `build` directory in .. if there isn't already one.
Same goes for `rustpkg install` and `rustpkg clean`.
For the time being, `rustpkg build` (etc.) will still error out if
you run it inside a directory whose parent isn't called `src`.
I'm not sure whether or not it's desirable to have it do something
in a non-workspace directory.
Updated all users of HashMap, HashSet ::consume() to use
.consume_iter().
Since .consume_iter() takes the map or set by value, it needs awkward
extra code to in librusti's use of @mut HashMap, where the map value can
not be directly moved out.
Addresses issue #7719
Updated all users of HashMap, HashSet old .consume() to use .consume()
with a for loop.
Since .consume() takes the map or set by value, it needs awkward
extra code to in librusti's use of @mut HashMap, where the map value can
not be directly moved out.
Note that this is not actually *used* by default; it is a matter of
configuration still, because you might want to:
- Compile all .rs files with `rustc %` (where each can be built itself)
- Compile all .rs files with `rustc some-file.rs` (where you are editing
part of a crate)
- Compile with a different tool, such as `make`. (In this case you might
put a `~/.vim/after/compiler/rustc.vim` to match such cases, set
makeprg and extend errorformat as appropriate. That should probably go
in a different compiler mode, e.g. make-rustc.)
To try using it, `:compiler rustc`. Then, `:make` on a file you would
run `rustc` on will work its magic, invoking rustc. To automate this,
you could have something like `autocmd FileType rust compiler rustc` in
your Vim config.
r? anyone
The only bit that I'm a little concerned about is whether there's some way the assignments to `hi` could somehow still be necessary; but I think that could only be the case if it had been `&const` borrowed (or whatever the hypothetical syntax is for that), and that's not going on in this file.
This should get us over the hump of activating basic ratcheting on codegen tests, at least. It also puts in place optional (disabled by default) ratcheting on all #[bench] tests, and records all metrics from them to harvestable .json files in any case.
It disables the insertion of `use std::prelude::*;` into the top of
all the modules below the item on which it is placed (including that
item itself).
(Similar to GHC's `-XNoImplicitPrelude`.)
This is the first of a series of refactorings to get rid of the `codemap::spanned<T>` struct (see this thread for more information: https://mail.mozilla.org/pipermail/rust-dev/2013-July/004798.html).
The changes in this PR should not change any semantics, just rename `ast::blk_` to `ast::blk` and add a span field to it. 95% of the changes were of the form `block.node.id` -> `block.id`. Only some transformations in `libsyntax::fold` where not entirely trivial.
Currently, our intrinsics are generated as functions that have the
usual setup, which means an alloca, and therefore also a jump, for
those intrinsics that return an immediate value. This is especially bad
for unoptimized builds because it means that an intrinsic like
"contains_managed" that should be just "ret 0" or "ret 1" actually ends
up allocating stack space, doing a jump and a store/load sequence
before it finally returns the value.
To fix that, we need a way to stop the generic function declaration
mechanism from allocating stack space for the return value. This
implicitly also kills the jump, because the block for static allocas
isn't required anymore.
Additionally, trans_intrinsic needs to build the return itself instead
of calling finish_fn, because the latter relies on the availability of
the return value pointer.
With these changes, we get the bare minimum code required for our
intrinsics, which makes them small enough that inlining them makes the
resulting code smaller, so we can mark them as "always inline" to get
better performing unoptimized builds.
Optimized builds also benefit slightly from this change as there's less
code for LLVM to translate and the smaller intrinsics help it to make
better inlining decisions for a few code paths.
Building stage2 librustc gets ~1% faster for the optimized version and 5% for
the unoptimized version.
Most arms of the huge match contain the same code, differing only in
small details like the name of the llvm intrinsic that is to be called.
Thus the duplicated code can be factored out into a few functions that
take some parameters to handle the differences.
Simulates borrow checks for '@mut' boxes, or at least it's the same idea. This allows you to store owned values, but mutate them while they're owned by TLS.
This should remove the necessity for a `pop`/`set` pattern to mutate data structures in TLS.
Whenever a lang_item is required, some relevant message is displayed, often with
a span of what triggered the usage of the lang item.
Now "hello word" is as small as:
```rust
#[no_std];
extern {
fn puts(s: *u8);
}
extern "rust-intrinsic" {
fn transmute<T, U>(t: T) -> U;
}
#[start]
fn main(_: int, _: **u8, _: *u8) -> int {
unsafe {
let (ptr, _): (*u8, uint) = transmute("Hello!");
puts(ptr);
}
return 0;
}
```
Allowing them in type signatures is a significant amount of extra work, unfortunately. This also doesn't apply to static values, which takes a different code path.
Changes int/uint range_rev to iterate over range `(hi,lo]` instead of `[hi,lo)`.
Fix#5270.
Also:
* Adds unit tests for int/uint range functions
* Updates the uses of `range_rev` to account for the new semantics. (Note that pretty much all of the updates there were strict improvements to the code in question; yay!)
* Exposes new function, `range_step_inclusive`, which does the range `[hi,lo]`, (at least when `hi-lo` is a multiple of the `step` parameter).
* Special-cases when `|step| == 1` removing unnecessary bounds-check. (I did not check whether LLVM was already performing this optimization; I figure it would be a net win to not leave that analysis to the compiler. If reviewer objects, I can easily remove that from the refactored code.)
(This pull request is a rebased version of PR #7524, which went stale due to recent unrelated changes to num libraries.)
As per @pcwalton's request, `debug!(..)` is only activated when the `debug` cfg is set; that is, for `RUST_LOG=some_module=4 ./some_program` to work, it needs to be compiled with `rustc --cfg debug some_program.rs`. (Although, there is the sneaky `__debug!(..)` macro that is always active, if you *really* need it.)
It functions by making `debug!` expand to `if false { __debug!(..) }` (expanding to an `if` like this is required to make sure `debug!` statements are typechecked and to avoid unused variable warnings), and adjusting trans to skip the pointless branches in `if true ...` and `if false ...`.
The conditional expansion change also required moving the inject-std-macros step into a new pass, and makes it actually insert them at the top of the crate; this means that the cfg stripping traverses over the macros and so filters out the unused ones.
This appears to takes an unoptimised build of `librustc` from 65s to 59s; and the full bootstrap from 18m41s to 18m26s on my computer (with general background use).
`./configure --enable-debug` will enable `debug!` statements in the bootstrap build.
That is, the `b` branch in `if true { a } else { b }` will not be
trans'd, and that expression will be exactly the same as `a`. This
means that, for example, macros conditionally expanding to `if false
{ .. }` (like debug!) will not waste time in LLVM (or trans).
An alloca in an unreachable block would shortcircuit with Undef, but with type
`Type`, rather than type `*Type` (i.e. a plain value, not a pointer) but it is
expected to return a pointer into the stack, leading to confusion and LLVM
asserts later.
Similarly, attaching the range metadata to a Load in an unreachable block
makes LLVM unhappy, since the Load returns Undef.
Fixes#7344.
Note that Version's `le` is not "less than or equal to" now, since `lt`
ignores build metadata. I think the new ordering algorithm satisfies
strict weak ordering which C++ STL requires, instead of strict total
ordering.
Macros can be conditionally defined because stripping occurs before macro
expansion, but, the built-in macros were only added as part of the actual
expansion process and so couldn't be stripped to have definitions conditional
on cfg flags.
debug! is defined conditionally in terms of the debug config, expanding to
nothing unless the --cfg debug flag is passed (to be precise it expands to
`if false { normal_debug!(...) }` so that they are still type checked, and
to avoid unused variable lints).
Note that the headers are still on `~[T]` when `T` is managed. This is continued from #7605, which removed all the code relying on the headers and removed them from `~T` for non-managed `T`.
Implement set difference, sym. difference, intersection and union using Iterators.
The set methods are left since they are part of the Set trait. A grep over the tree indicates that the four hashset operations have no users at all.
Also remove HashMap::mutate_values since it is unused, replaced by .mut_iter(), and not part of a trait.
Implement the difference, union, etc iterators with the help of a custom
iterator combinator with explicit closure environment. Reported issue #7814
to be able to use the std::iterator filter combinator.
r? @graydon rustpkg can now build code from a local git repository. In the
case where the local repo is in a directory not in the RUST_PATH,
it checks out the repository into a directory in the first workspace
in the RUST_PATH.
The tests no longer try to connect to github.com, which should
solve some of the sporadic failures we've been seeing.
rustpkg can now build code from a local git repository. In the
case where the local repo is in a directory not in the RUST_PATH,
it checks out the repository into a directory in the first workspace
in the RUST_PATH.
The tests no longer try to connect to github.com, which should
solve some of the sporadic failures we've been seeing.
Teach `extra::term` to support more terminal attributes than just color.
Fix the compiler diagnostic messages to print in bold instead of bright white. This matches Clang's output.
Cache the term::Terminal instead of re-parsing for every diagnostic (fixes#6827).
Clang actually highlights using bold, not using bright white. Match
clang on this so our diagnostics are still readable on terminals with a
white background.
If the TLS key is 0-sized, then the linux linker is apparently smart enough to
put everything at the same pointer. OSX on the other hand, will reserve some
space for all of them. To get around this, the TLS key now actuall consumes
space to ensure that it gets a unique pointer
We used to have concrete types in glue functions, but the way we used
to implement that broke inlining of those functions. To fix that, we
converted all glue to just take an i8* and always casted to that type.
The problem with the old implementation was that we made a wrong
assumption about the glue functions, taking it for granted that they
always take an i8*, because that's the function type expected by the
TyDesc fields. Therefore, we always ended up with some kind of cast.
But actually, we can initially have the glue with concrete types and
only cast the functions to the generic type once we actually emit the
TyDesc data.
That means that for glue calls that can be statically resolved, we don't
need any casts, unless the glue uses a simplified type. In that case we
cast the argument. And for glue calls that are resolved at runtime, we
cast the argument to i8*, because that's what the glue function in the
TyDesc expects.
Since most of out glue calls are static, this saves a lot of bitcasts.
The size of the unoptimized librustc.ll goes down by 240k lines.
The new names make it obvious that these generate formatted output.
Add a one-argument case that uses %? to format, just like the other
format-using macros (e.g. info!()).
See #4989. I didn't add Persistent{Set,Map} since the only
persistent data structure is fun_treemap and its functionality is
currently too limited to build a trait out of.
Turns out this was a more subtle bug than I originally thought. My analysis can be found in #7732, but I also tried to put descriptive info into the comments.
Closes#7732
Fixes most of #4989. I didn't add Persistent{Set,Map} since the only
persistent data structure is fun_treemap and its functionality is
currently too limited to build a trait out of.
The new names make it obvious that these generate formatted output.
Add a one-argument case that uses %? to format, just like the other
format-using macros (e.g. info!()).
These commits remove a bunch of empty or otherwise unnecessary blocks, reducing the size of the pre-optimization IR and improving its readability. `librustc.ll` created with `--passes ""` shrinks by about 120k lines which equals about 5% of the total size.
We used to have concrete types in glue functions, but the way we used
to implement that broke inlining of those functions. To fix that, we
converted all glue to just take an i8* and always casted to that type.
The problem with the old implementation was that we made a wrong
assumption about the glue functions, taking it for granted that they
always take an i8*, because that's the function type expected by the
TyDesc fields. Therefore, we always ended up with some kind of cast.
But actually, we can initially have the glue with concrete types and
only cast the functions to the generic type once we actually emit the
TyDesc data.
That means that for glue calls that can be statically resolved, we don't
need any casts, unless the glue uses a simplified type. In that case we
cast the argument. And for glue calls that are resolved at runtime, we
cast the argument to i8*, because that's what the glue function in the
TyDesc expects.
Since most of out glue calls are static, this saves a lot of bitcasts.
The size of the unoptimized librustc.ll goes down by 240k lines.
Rust will allow to supply default methods for all four methods, but we
don't have any nice error reporting for the case where at least one
method must be implemented, but it's arbitrary which.
So in this case, we require `lt`, but allow implementing the others if needed.
Currently, we always create a dedicated "return" basic block, but when
there's only a single predecessor for that block, it can be merged with
that predecessor. We can achieve that merge by only creating the return
block on demand, avoiding its creation when its not required.
Reduces the pre-optimization size of librustc.ll created with --passes ""
by about 90k lines which equals about 4%.
It will be simpler to implement only one method for Ord, while we also
allow implementing all four Ord methods for semantics or performance
reasons.
We only supply three default methods (and not four), because don't have
any nice error reporting for the case where at least one method must be
implemented, but it's arbitrary which.
Unify the mutable iterators too. Switch the ListInsertion trait to use
method .insert_next() and .peek_next() for list mutation. .insert_next()
inserts an element into the list that will not appear in iteration, of
course; so the length of the iteration can not change during iteration.
Did not properly allow runs from the `other` list to be merged in. The
test case was using a wrong expected value.
Edited docs for merge so they explain more clearly what it does.
Also make sure insert_ordered is marked pub.
When it's a lifetime, a single quotation mark shouldn't have a matching
single quotation mark inserted after it, as delimitMate does by default.
Note that this is not without problems; a char literal coming after an
odd number of lifetime markers will have its quotation marks behave a
little strangely. That, however, is not my fault, but delimitMate's:
https://github.com/Raimondi/delimitMate/issues/135
Currently, immediate values are copied into an alloca only to have an
addressable storage so that it can be used with memcpy. Obviously we
can skip the memcpy in this case.
Note that this is not actually *used* by default; it is a matter of
configuration still, because you might want to:
- Compile all .rs files with `rustc %` (where each can be built itself)
- Compile all .rs files with `rustc some-file.rs` (where you are editing
part of a crate)
- Compile with a different tool, such as `make`. (In this case you might
put a `~/.vim/after/compiler/rustc.vim` to match such cases, set
makeprg and extend errorformat as appropriate. That should probably go
in a different compiler mode, e.g. make-rustc.)
To try using it, `:compiler rustc`. Then, `:make` on a file you would
run `rustc` on will work its magic, invoking rustc. To automate this,
you could have something like `autocmd FileType rust compiler rustc` in
your Vim config.
Moves multibyte code to it's own function to make char_range_at
easier to inline, and faster for single and multibyte chars.
Benchmarked reading example.json 100 times, 1.18s before, 1.08s
after.
Also, optimize str::is_utf8 for the single and multibyte case
Before:
is_utf8_ascii: 272.355162 ms
is_utf8_multibyte: 167.337334 ms
After:
is_utf8_ascii: 218.088049 ms
is_utf8_multibyte: 134.836722 ms