about summary refs log tree commit diff
path: root/src/test/codegen
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-05-21 07:16:44 +0000
committerbors <bors@rust-lang.org>2020-05-21 07:16:44 +0000
commit7f79e98c0356642db62e5113327e436c951e843d (patch)
treeb140158d00b7dfe9c34315a771816496adab9280 /src/test/codegen
parent963bf528292d8f97104515e32908e30c2467b6a8 (diff)
parentf50986205756075fb05a9371b94facd58cc048a6 (diff)
downloadrust-7f79e98c0356642db62e5113327e436c951e843d.tar.gz
rust-7f79e98c0356642db62e5113327e436c951e843d.zip
Auto merge of #72205 - ecstatic-morse:nrvo, r=oli-obk
Dumb NRVO

This is a very simple version of an NRVO pass, which scans backwards from the `return` terminator to see if there is an an assignment like `_0 = _1`. If a basic block with two or more predecessors is encountered during this scan without first seeing an assignment to the return place, we bail out. This avoids running a full "reaching definitions" dataflow analysis.

I wanted to see how much `rustc` would benefit from even a very limited version of this optimization. We should be able to use this as a point of comparison for more advanced versions that are based on live ranges.

r? @ghost
Diffstat (limited to 'src/test/codegen')
-rw-r--r--src/test/codegen/align-enum.rs2
-rw-r--r--src/test/codegen/align-struct.rs2
-rw-r--r--src/test/codegen/nrvo.rs17
3 files changed, 19 insertions, 2 deletions
diff --git a/src/test/codegen/align-enum.rs b/src/test/codegen/align-enum.rs
index 72447fbc079..95ca7cfe750 100644
--- a/src/test/codegen/align-enum.rs
+++ b/src/test/codegen/align-enum.rs
@@ -1,4 +1,4 @@
-// compile-flags: -C no-prepopulate-passes
+// compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0
 // ignore-tidy-linelength
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/align-struct.rs b/src/test/codegen/align-struct.rs
index 5e290323907..cda7235a3d8 100644
--- a/src/test/codegen/align-struct.rs
+++ b/src/test/codegen/align-struct.rs
@@ -1,4 +1,4 @@
-// compile-flags: -C no-prepopulate-passes
+// compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0
 // ignore-tidy-linelength
 
 #![crate_type = "lib"]
diff --git a/src/test/codegen/nrvo.rs b/src/test/codegen/nrvo.rs
new file mode 100644
index 00000000000..fddb0d1fb3c
--- /dev/null
+++ b/src/test/codegen/nrvo.rs
@@ -0,0 +1,17 @@
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// Ensure that we do not call `memcpy` for the following function.
+// `memset` and `init` should be called directly on the return pointer.
+#[no_mangle]
+pub fn nrvo(init: fn(&mut [u8; 4096])) -> [u8; 4096] {
+    // CHECK-LABEL: nrvo
+    // CHECK: @llvm.memset
+    // CHECK-NOT: @llvm.memcpy
+    // CHECK: ret
+    // CHECK-EMPTY
+    let mut buf = [0; 4096];
+    init(&mut buf);
+    buf
+}