summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@ucc.asn.au>2017-04-29 14:13:22 +0800
committerJohn Hodge <tpg@ucc.asn.au>2017-04-29 14:13:22 +0800
commit6a2d30690eb4e5c6c2801a6c340ccfb65a3875b9 (patch)
tree437f2776f868b75f21d32708da61f85c324c75bd
parentab964bfae8b857c64b66ed3fadf0b363e8370929 (diff)
downloadmrust-6a2d30690eb4e5c6c2801a6c340ccfb65a3875b9.tar.gz
Add a custom intrinsic to reduce cost of [T]::len
-rw-r--r--Makefile3
-rw-r--r--rust_src.patch25
-rw-r--r--src/main.cpp1
-rw-r--r--src/mir/optimise.cpp14
4 files changed, 36 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index b2259641..7816f9ed 100644
--- a/Makefile
+++ b/Makefile
@@ -297,7 +297,7 @@ output/rustc: $(RUSTCSRC)src/rustc/rustc.rs output/librustc_driver.hir output/ru
.PHONY: RUSTCSRC
RUSTCSRC: $(RUSTCSRC)
-$(RUSTCSRC): rust-nightly-date
+$(RUSTCSRC): rust-nightly-date rust_src.patch
@export DL_RUST_DATE=$$(cat rust-nightly-date); \
export DISK_RUST_DATE=$$([ -f $(RUSTC_SRC_DL) ] && cat $(RUSTC_SRC_DL)); \
if [ "$$DL_RUST_DATE" != "$$DISK_RUST_DATE" ]; then \
@@ -306,6 +306,7 @@ $(RUSTCSRC): rust-nightly-date
rm -rf rustc-nightly; \
curl -sS https://static.rust-lang.org/dist/$${DL_RUST_DATE}/rustc-nightly-src.tar.gz -o rustc-nightly-src.tar.gz; \
tar -xf rustc-nightly-src.tar.gz --transform 's~^rustc-nightly-src~rustc-nightly~'; \
+ patch -p0 < rust_src.patch; \
echo "$$DL_RUST_DATE" > $(RUSTC_SRC_DL); \
fi
diff --git a/rust_src.patch b/rust_src.patch
new file mode 100644
index 00000000..d782d16b
--- /dev/null
+++ b/rust_src.patch
@@ -0,0 +1,25 @@
+--- rustc-nightly/src/libcore/intrinsics.rs
++++ rustc-nightly/src/libcore/intrinsics.rs
+@@ -643,5 +643,8 @@
+ pub fn drop_in_place<T: ?Sized>(to_drop: *mut T);
+
++ /// Obtain the length of a slice pointer
++ pub fn mrustc_slice_len<T>(pointer: *const [T]) -> usize;
++
+ /// Gets a static string slice containing the name of a type.
+ pub fn type_name<T: ?Sized>() -> &'static str;
+
+--- rustc-nightly/src/libcore/slice.rs
++++ rustc-nightly/src/libcore/slice.rs
+@@ -340,6 +340,8 @@
+ #[inline]
+ fn len(&self) -> usize {
+- unsafe {
+- mem::transmute::<&[T], Repr<T>>(self).len
+- }
++ #[cfg(not(rust_compiler="mrustc"))]
++ let rv = unsafe { mem::transmute::<&[T], Repr<T>>(self).len };
++ #[cfg(rust_compiler="mrustc")]
++ let rv = unsafe { ::intrinsics::mrustc_slice_len(self) };
++ rv
+ }
diff --git a/src/main.cpp b/src/main.cpp
index cb506ffb..f06ee545 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -173,6 +173,7 @@ int main(int argc, char *argv[])
ProgramParams params(argc, argv);
// Set up cfg values
+ Cfg_SetValue("rust_compiler", "mrustc");
// TODO: Target spec
Cfg_SetFlag("unix");
Cfg_SetFlag("linux");
diff --git a/src/mir/optimise.cpp b/src/mir/optimise.cpp
index b83a1169..81574afd 100644
--- a/src/mir/optimise.cpp
+++ b/src/mir/optimise.cpp
@@ -1396,12 +1396,14 @@ bool MIR_Optimise_ConstPropagte(::MIR::TypeResolve& state, ::MIR::Function& fcn)
bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block);
changed = true;
}
- //else if( tef.name == "get_dst_meta_slice" )
- //{
- // MIR_ASSERT(state, te.args.at(0).is_LValue(), "Argument to `get_dst_meta` must be a lvalue");
- // auto& e = te.args.at(0).as_LValue();
- // bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), ::MIR::RValue::make_DstMeta({ mv$(*e) }) }));
- //}
+ else if( tef.name == "mrustc_slice_len" )
+ {
+ MIR_ASSERT(state, te.args.at(0).is_LValue(), "Argument to `get_dst_meta` must be a lvalue");
+ auto& e = te.args.at(0).as_LValue();
+ bb.statements.push_back(::MIR::Statement::make_Assign({ mv$(te.ret_val), ::MIR::RValue::make_DstMeta({ mv$(e) }) }));
+ bb.terminator = ::MIR::Terminator::make_Goto(te.ret_block);
+ changed = true;
+ }
else
{
// Ignore any other intrinsics