about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <oli-obk@users.noreply.github.com>2017-07-20 22:08:02 +0200
committerGitHub <noreply@github.com>2017-07-20 22:08:02 +0200
commit308c7cadf1a947faef831b96de83618badc1fd56 (patch)
treee750c327e108b93d5ab507fc8c44a912725a25dc
parent9710ff481eb18f691072e59cba5996fd0f4cfd02 (diff)
parentf2d0101065c150026ea8f73410f2088ecddba9c6 (diff)
downloadrust-308c7cadf1a947faef831b96de83618badc1fd56.tar.gz
rust-308c7cadf1a947faef831b96de83618badc1fd56.zip
Merge pull request #265 from oli-obk/optimize_prime
Also test optimized MIR
-rw-r--r--src/bin/miri.rs6
-rw-r--r--src/step.rs22
-rw-r--r--tests/compiletest.rs31
-rw-r--r--tests/run-pass-fullmir/integer-ops.rs3
-rw-r--r--tests/run-pass/cast-rfc0401-vtable-kinds.rs4
5 files changed, 46 insertions, 20 deletions
diff --git a/src/bin/miri.rs b/src/bin/miri.rs
index 8d27f9057f5..01a4a8656b4 100644
--- a/src/bin/miri.rs
+++ b/src/bin/miri.rs
@@ -199,11 +199,7 @@ fn main() {
         args.push(sysroot_flag);
         args.push(find_sysroot());
     }
-    // we run the optimization passes inside miri
-    // if we ran them twice we'd get funny failures due to borrowck ElaborateDrops only working on
-    // unoptimized MIR
-    // FIXME: add an after-mir-passes hook to rustc driver
-    args.push("-Zmir-opt-level=0".to_owned());
+
     // for auxilary builds in unit tests
     args.push("-Zalways-encode-mir".to_owned());
 
diff --git a/src/step.rs b/src/step.rs
index d854218d7a9..4804059d799 100644
--- a/src/step.rs
+++ b/src/step.rs
@@ -87,14 +87,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
 
                 match *dest_layout {
                     Layout::General { discr, .. } => {
-                        // FIXME: I (oli-obk) think we need to check the
-                        // `dest_ty` for the variant's discriminant and write
-                        // instead of the variant index
-                        // We don't have any tests actually going through these lines
-                        let discr_ty = discr.to_ty(&self.tcx, false);
-                        let discr_lval = self.lvalue_field(dest, 0, dest_ty, discr_ty)?;
-
-                        self.write_value(Value::ByVal(PrimVal::Bytes(variant_index as u128)), discr_lval, discr_ty)?;
+                        let discr_size = discr.size().bytes();
+                        let dest_ptr = self.force_allocation(dest)?.to_ptr()?;
+                        self.memory.write_uint(dest_ptr, variant_index as u128, discr_size)?
                     }
 
                     Layout::RawNullablePointer { nndiscr, .. } => {
@@ -103,6 +98,17 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
                         }
                     }
 
+                    Layout::StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => {
+                        if variant_index as u64 != nndiscr {
+                            let (offset, ty) = self.nonnull_offset_and_ty(dest_ty, nndiscr, discrfield)?;
+                            let nonnull = self.force_allocation(dest)?.to_ptr()?.offset(offset.bytes(), self.memory.layout)?;
+                            trace!("struct wrapped nullable pointer type: {}", ty);
+                            // only the pointer part of a fat pointer is used for this space optimization
+                            let discr_size = self.type_size(ty)?.expect("bad StructWrappedNullablePointer discrfield");
+                            self.memory.write_uint(nonnull, 0, discr_size)?;
+                        }
+                    },
+
                     _ => bug!("SetDiscriminant on {} represented as {:#?}", dest_ty, dest_layout),
                 }
             }
diff --git a/tests/compiletest.rs b/tests/compiletest.rs
index 5512669cedb..2f8383ba504 100644
--- a/tests/compiletest.rs
+++ b/tests/compiletest.rs
@@ -1,5 +1,8 @@
+#![feature(slice_concat_ext)]
+
 extern crate compiletest_rs as compiletest;
 
+use std::slice::SliceConcatExt;
 use std::path::{PathBuf, Path};
 use std::io::Write;
 
@@ -41,22 +44,34 @@ fn run_pass(path: &str) {
     compiletest::run_tests(&config);
 }
 
-fn miri_pass(path: &str, target: &str, host: &str, fullmir: bool) {
-    eprintln!("## Running run-pass tests in {} against miri for target {}", path, target);
+fn miri_pass(path: &str, target: &str, host: &str, fullmir: bool, opt: bool) {
+    let opt_str = if opt {
+        " with optimizations"
+    } else {
+        ""
+    };
+    eprintln!("## Running run-pass tests in {} against miri for target {}{}", path, target, opt_str);
     let mut config = compiletest::default_config();
     config.mode = "mir-opt".parse().expect("Invalid mode");
     config.src_base = PathBuf::from(path);
     config.target = target.to_owned();
     config.host = host.to_owned();
     config.rustc_path = PathBuf::from("target/debug/miri");
+    let mut flags = Vec::new();
     if fullmir {
         if host != target {
             // skip fullmir on nonhost
             return;
         }
         let sysroot = Path::new(&std::env::var("HOME").unwrap()).join(".xargo").join("HOST");
-        config.target_rustcflags = Some(format!("--sysroot {}", sysroot.to_str().unwrap()));
+        flags.push(format!("--sysroot {}", sysroot.to_str().unwrap()));
+    }
+    if opt {
+        flags.push("-Zmir-opt-level=3".to_owned());
+    } else {
+        flags.push("-Zmir-opt-level=0".to_owned());
     }
+    config.target_rustcflags = Some(flags.join(" "));
     // don't actually execute the final binary, it might be for other targets and we only care
     // about running miri, not the binary.
     config.runtool = Some("echo \"\" || ".to_owned());
@@ -113,10 +128,12 @@ fn run_pass_miri() {
     let sysroot = get_sysroot();
     let host = get_host();
 
-    for_all_targets(&sysroot, |target| {
-        miri_pass("tests/run-pass", &target, &host, false);
-    });
-    miri_pass("tests/run-pass-fullmir", &host, &host, true);
+    for &opt in [false, true].iter() {
+        for_all_targets(&sysroot, |target| {
+            miri_pass("tests/run-pass", &target, &host, false, opt);
+        });
+        miri_pass("tests/run-pass-fullmir", &host, &host, true, opt);
+    }
 }
 
 #[test]
diff --git a/tests/run-pass-fullmir/integer-ops.rs b/tests/run-pass-fullmir/integer-ops.rs
index 3773e699ddf..7f66dbd521f 100644
--- a/tests/run-pass-fullmir/integer-ops.rs
+++ b/tests/run-pass-fullmir/integer-ops.rs
@@ -8,6 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// FIXME: remove the next line once https://github.com/rust-lang/rust/issues/43359 is fixed
+// compile-flags: -Zmir-opt-level=0
+
 use std::i32;
 
 pub fn main() {
diff --git a/tests/run-pass/cast-rfc0401-vtable-kinds.rs b/tests/run-pass/cast-rfc0401-vtable-kinds.rs
index 3a9f24ad4cc..24c6e151a7e 100644
--- a/tests/run-pass/cast-rfc0401-vtable-kinds.rs
+++ b/tests/run-pass/cast-rfc0401-vtable-kinds.rs
@@ -8,6 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+
+// FIXME: remove the next line when https://github.com/rust-lang/rust/issues/43358 is resolved
+// compile-flags: -Zmir-opt-level=0
+
 // Check that you can cast between different pointers to trait objects
 // whose vtable have the same kind (both lengths, or both trait pointers).