Function parameters that are to be passed by value but don't fit into a
single register are currently passed by creating a copy on the stack and
passing a pointer to that copy to the callee. Since the copy is made
just for the function call, there are no aliases.
For example, this sometimes allows LLVM to eliminate unnecessary calls
to drop glue. Given
````rust
struct Foo {
a: int,
b: Option<~str>,
}
extern {
fn eat(eat: Option<~str>);
}
pub fn foo(v: Foo) {
match v {
Foo { a: _, b } => unsafe { eat(b) }
}
}
````
LLVM currently can't eliminate the drop call for the string, because it
only sees a _pointer_ to Foo, for which it has to expect an alias. So we
get:
````llvm
; Function Attrs: uwtable
define void @_ZN3foo20h9f32c90ae7201edbxaa4v0.0E(%struct.Foo* nocapture) unnamed_addr #0 {
"_ZN34std..option..Option$LT$$UP$str$GT$9glue_drop17hc39b3015f3b9c69dE.exit":
%1 = getelementptr inbounds %struct.Foo* %0, i64 0, i32 1, i32 0
%2 = load { i64, i64, [0 x i8] }** %1, align 8
store { i64, i64, [0 x i8] }* null, { i64, i64, [0 x i8] }** %1, align 8
%3 = ptrtoint { i64, i64, [0 x i8] }* %2 to i64
%.fca.0.insert = insertvalue { i64 } undef, i64 %3, 0
tail call void @eat({ i64 } %.fca.0.insert)
%4 = load { i64, i64, [0 x i8] }** %1, align 8
%5 = icmp eq { i64, i64, [0 x i8] }* %4, null
br i1 %5, label %_ZN3Foo9glue_drop17hf611996539d3036fE.exit, label %"_ZN8_$UP$str9glue_drop17h15dbdbe2b8897a98E.exit.i.i"
"_ZN8_$UP$str9glue_drop17h15dbdbe2b8897a98E.exit.i.i": ; preds = %"_ZN34std..option..Option$LT$$UP$str$GT$9glue_drop17hc39b3015f3b9c69dE.exit"
%6 = bitcast { i64, i64, [0 x i8] }* %4 to i8*
tail call void @free(i8* %6) #1
br label %_ZN3Foo9glue_drop17hf611996539d3036fE.exit
_ZN3Foo9glue_drop17hf611996539d3036fE.exit: ; preds = %"_ZN34std..option..Option$LT$$UP$str$GT$9glue_drop17hc39b3015f3b9c69dE.exit", %"_ZN8_$UP$str9glue_drop17h15dbdbe2b8897a98E.exit.i.i"
ret void
}
````
But with the `noalias` attribute, it can safely optimize that to:
````llvm
define void @_ZN3foo20hd28431f929f0d6c4xaa4v0.0E(%struct.Foo* noalias nocapture) unnamed_addr #0 {
_ZN3Foo9glue_drop17he9afbc09d4e9c851E.exit:
%1 = getelementptr inbounds %struct.Foo* %0, i64 0, i32 1, i32 0
%2 = load { i64, i64, [0 x i8] }** %1, align 8
store { i64, i64, [0 x i8] }* null, { i64, i64, [0 x i8] }** %1, align 8
%3 = ptrtoint { i64, i64, [0 x i8] }* %2 to i64
%.fca.0.insert = insertvalue { i64 } undef, i64 %3, 0
tail call void @eat({ i64 } %.fca.0.insert)
ret void
}
````
Function parameters that are to be passed by value but don't fit into a
single register are currently passed by creating a copy on the stack and
passing a pointer to that copy to the callee. Since the copy is made
just for the function call, there are no aliases.
For example, this sometimes allows LLVM to eliminate unnecessary calls
to drop glue. Given
````rust
struct Foo {
a: int,
b: Option<~str>,
}
extern {
fn eat(eat: Option<~str>);
}
pub fn foo(v: Foo) {
match v {
Foo { a: _, b } => unsafe { eat(b) }
}
}
````
LLVM currently can't eliminate the drop call for the string, because it
only sees a _pointer_ to Foo, for which it has to expect an alias. So we
get:
````llvm
; Function Attrs: uwtable
define void @_ZN3foo20h9f32c90ae7201edbxaa4v0.0E(%struct.Foo* nocapture) unnamed_addr #0 {
"_ZN34std..option..Option$LT$$UP$str$GT$9glue_drop17hc39b3015f3b9c69dE.exit":
%1 = getelementptr inbounds %struct.Foo* %0, i64 0, i32 1, i32 0
%2 = load { i64, i64, [0 x i8] }** %1, align 8
store { i64, i64, [0 x i8] }* null, { i64, i64, [0 x i8] }** %1, align 8
%3 = ptrtoint { i64, i64, [0 x i8] }* %2 to i64
%.fca.0.insert = insertvalue { i64 } undef, i64 %3, 0
tail call void @eat({ i64 } %.fca.0.insert)
%4 = load { i64, i64, [0 x i8] }** %1, align 8
%5 = icmp eq { i64, i64, [0 x i8] }* %4, null
br i1 %5, label %_ZN3Foo9glue_drop17hf611996539d3036fE.exit, label %"_ZN8_$UP$str9glue_drop17h15dbdbe2b8897a98E.exit.i.i"
"_ZN8_$UP$str9glue_drop17h15dbdbe2b8897a98E.exit.i.i": ; preds = %"_ZN34std..option..Option$LT$$UP$str$GT$9glue_drop17hc39b3015f3b9c69dE.exit"
%6 = bitcast { i64, i64, [0 x i8] }* %4 to i8*
tail call void @free(i8* %6) #1
br label %_ZN3Foo9glue_drop17hf611996539d3036fE.exit
_ZN3Foo9glue_drop17hf611996539d3036fE.exit: ; preds = %"_ZN34std..option..Option$LT$$UP$str$GT$9glue_drop17hc39b3015f3b9c69dE.exit", %"_ZN8_$UP$str9glue_drop17h15dbdbe2b8897a98E.exit.i.i"
ret void
}
````
But with the `noalias` attribute, it can safely optimize that to:
````llvm
define void @_ZN3foo20hd28431f929f0d6c4xaa4v0.0E(%struct.Foo* noalias nocapture) unnamed_addr #0 {
_ZN3Foo9glue_drop17he9afbc09d4e9c851E.exit:
%1 = getelementptr inbounds %struct.Foo* %0, i64 0, i32 1, i32 0
%2 = load { i64, i64, [0 x i8] }** %1, align 8
store { i64, i64, [0 x i8] }* null, { i64, i64, [0 x i8] }** %1, align 8
%3 = ptrtoint { i64, i64, [0 x i8] }* %2 to i64
%.fca.0.insert = insertvalue { i64 } undef, i64 %3, 0
tail call void @eat({ i64 } %.fca.0.insert)
ret void
}
````
Change `os::args()` and `os::env()` to use `str::from_utf8_lossy()`.
Add new functions `os::args_as_bytes()` and `os::env_as_bytes()` to retrieve the args/env as byte vectors instead.
The existing methods were left returning strings because I expect that the common use-case is to want string handling.
Fixes#7188.
I created RefReader and RefWriter structs that wrap a mutable reference to a Reader or Writer value. This works exactly like the ByRef struct in the iter module and allows passing a reference to a Reader or Writer to function expecting a Reader or Writer by value with the caller retaining ownership to the original value.
I also modified LimitReader to take the wrapped Reader by value instead of by reference.
@sfackler
It's too easy to forget the `rust` tag to have a code example tested, and it's
far more common to have testable code than untestable code.
This alters rustdoc to have only two directives, `ignore` and `should_fail`. The
`ignore` directive ignores the code block entirely, and the `should_fail`
directive has been fixed to only fail the test if the code execution fails, not
also compilation.
Parse the environment by default with from_utf8_lossy. Also provide
byte-vector equivalents (e.g. os::env_as_bytes()).
Unfortunately, setenv() can't have a byte-vector equivalent because of
Windows support, unless we want to define a setenv_bytes() that fails
under Windows for non-UTF8 (or non-UTF16).
os::args() was using str::raw::from_c_str(), which would assert if the
C-string wasn't valid UTF-8. Switch to using from_utf8_lossy() instead,
and add a separate function os::args_as_bytes() that returns the ~[u8]
byte-vectors instead.
I've been working on binary installers and ended up taking this detour, which does a few things:
* It expands the documentation on the build system with new comments in Makefile.in
* It displays some of that documentation via `make help`
* Removes some unused and broken snapshot code
* Adds `NO_MKFILE_DEPS` to convenience makefile hacking
* Moves almost all of Makefile.in to files in `mk/`
The documentation provided by `make help` and its implementation are somewhat quirky.
The std macros used to be injected with a filename of "<std-macros>", but macros
are now injected with a filename of "<{} macros>" where `{}` is filled in with
the crate name. This updates rustdoc to understand this new system so it'll
render source more frequently.
Because the build system treats Makefile.in and the .mk files slightly
differently (.in is copied, .mk are included), this makes the system
more uniform. Fewer build system changes will require a complete
reconfigure.
Strip trait impls for types that are stripped either due to the strip-hidden or strip-private passes.
This fixes the search index including trait methods on stripped structs (which breaks searching), and it also removes private types from the implementors list of a trait.
Fixes#9981 and #11439.
The std macros used to be injected with a filename of "<std-macros>", but macros
are now injected with a filename of "<{} macros>" where `{}` is filled in with
the crate name. This updates rustdoc to understand this new system so it'll
render source more frequently.
In strip-private, also strip impls of traits for private types. This
fixes the search index so searching for "drop", "eq", etc doesn't throw
an exception.
Currently when you run `make -jN` it's likely that you'll remove compiler-rt and
then it won't get cp'd back into the right place. I believe the reason for this
is that the compiler-rt library target never got updated so make decided it
never needed to copy the files back into place. The files were all there at the
beginning of `make`, but then we may clean out the stage0 versions if we unzip
the snapshot again.
This will hopefully bring us closer to #11937. We're still using gcc's idea of
"startup files", but this should prevent us from leaking in dependencies that we
don't quite want (libgcc for example once compiler-rt is what we use).
This will hopefully bring us closer to #11937. We're still using gcc's idea of
"startup files", but this should prevent us from leaking in dependencies that we
don't quite want (libgcc for example once compiler-rt is what we use).