about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libextra/lib.rs2
-rw-r--r--src/libextra/test.rs16
2 files changed, 15 insertions, 3 deletions
diff --git a/src/libextra/lib.rs b/src/libextra/lib.rs
index 519192fd177..109bf2e489b 100644
--- a/src/libextra/lib.rs
+++ b/src/libextra/lib.rs
@@ -29,7 +29,7 @@ Rust extras are part of the standard Rust distribution.
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")];
 
-#[feature(macro_rules, globs, managed_boxes)];
+#[feature(macro_rules, globs, managed_boxes, asm)];
 
 #[deny(non_camel_case_types)];
 #[deny(missing_doc)];
diff --git a/src/libextra/test.rs b/src/libextra/test.rs
index d1fffd9e515..d809d69b58e 100644
--- a/src/libextra/test.rs
+++ b/src/libextra/test.rs
@@ -1091,13 +1091,25 @@ impl MetricMap {
 
 // Benchmarking
 
+/// A function that is opaque to the optimiser, to allow benchmarks to
+/// pretend to use outputs to assist in avoiding dead-code
+/// elimination.
+///
+/// This function is a no-op, and does not even read from `dummy`.
+pub fn black_box<T>(dummy: T) {
+    // we need to "use" the argument in some way LLVM can't
+    // introspect.
+    unsafe {asm!("" : : "r"(&dummy))}
+}
+
+
 impl BenchHarness {
     /// Callback for benchmark functions to run in their body.
-    pub fn iter(&mut self, inner: ||) {
+    pub fn iter<T>(&mut self, inner: || -> T) {
         self.ns_start = precise_time_ns();
         let k = self.iterations;
         for _ in range(0u64, k) {
-            inner();
+            black_box(inner());
         }
         self.ns_end = precise_time_ns();
     }