about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2016-01-14 04:22:20 +0530
committerManish Goregaokar <manishsmail@gmail.com>2016-01-14 11:04:43 +0530
commite51de045ef5fd2e6878b2e770a8deb7abcf64691 (patch)
tree4bedd2756923c3ab4165ace8d5051210cfeef694
parent6ceaa2f77a2d217fd05fa2029c2724564cf43a09 (diff)
parente3abc3cfe746c0ab078f33bc4566f6fb9773f489 (diff)
downloadrust-e51de045ef5fd2e6878b2e770a8deb7abcf64691.tar.gz
rust-e51de045ef5fd2e6878b2e770a8deb7abcf64691.zip
Rollup merge of #30851 - jonas-schievink:unneeded-dropflags, r=pnkfelix
Apparently we allocate and maintain non-working dropflag hints since June... In anticipation of a working implementation of on-stack drop flag hints, let's not spend even more time on types that don't even need to be dropped.

```rust
fn main() {
    let (i,j,k,l) = (0,0,0,0);
}
```
used to translate to (unoptimized only, of course):
```llvm
define internal void @_ZN4main20ha8deb085c47920d8eaaE() unnamed_addr #0 {
entry-block:
  %dropflag_hint_10 = alloca i8
  %dropflag_hint_11 = alloca i8
  %dropflag_hint_12 = alloca i8
  %dropflag_hint_13 = alloca i8
  %const = alloca { i32, i32, i32, i32 }
  %i = alloca i32
  %j = alloca i32
  %k = alloca i32
  %l = alloca i32
  store i8 61, i8* %dropflag_hint_10
  store i8 61, i8* %dropflag_hint_11
  store i8 61, i8* %dropflag_hint_12
  store i8 61, i8* %dropflag_hint_13
  %0 = bitcast { i32, i32, i32, i32 }* %const to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast ({ i32, i32, i32, i32 }* @const2752 to i8*), i64 16, i32 4, i1 false)
  %1 = getelementptr inbounds { i32, i32, i32, i32 }, { i32, i32, i32, i32 }* %const, i32 0, i32 0
  %2 = load i32, i32* %1, align 4
  store i32 %2, i32* %i, align 4
  %3 = getelementptr inbounds { i32, i32, i32, i32 }, { i32, i32, i32, i32 }* %const, i32 0, i32 1
  %4 = load i32, i32* %3, align 4
  store i32 %4, i32* %j, align 4
  %5 = getelementptr inbounds { i32, i32, i32, i32 }, { i32, i32, i32, i32 }* %const, i32 0, i32 2
  %6 = load i32, i32* %5, align 4
  store i32 %6, i32* %k, align 4
  %7 = getelementptr inbounds { i32, i32, i32, i32 }, { i32, i32, i32, i32 }* %const, i32 0, i32 3
  %8 = load i32, i32* %7, align 4
  store i32 %8, i32* %l, align 4
  ret void
}
```

Now it gives:
```llvm
define internal void @_ZN4main20ha8deb085c47920d8eaaE() unnamed_addr #0 {
entry-block:
  %const = alloca { i32, i32, i32, i32 }
  %i = alloca i32
  %j = alloca i32
  %k = alloca i32
  %l = alloca i32
  %0 = bitcast { i32, i32, i32, i32 }* %const to i8*
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* bitcast ({ i32, i32, i32, i32 }* @const2748 to i8*), i64 16, i32 4, i1 false)
  %1 = getelementptr inbounds { i32, i32, i32, i32 }, { i32, i32, i32, i32 }* %const, i32 0, i32 0
  %2 = load i32, i32* %1, align 4
  store i32 %2, i32* %i, align 4
  %3 = getelementptr inbounds { i32, i32, i32, i32 }, { i32, i32, i32, i32 }* %const, i32 0, i32 1
  %4 = load i32, i32* %3, align 4
  store i32 %4, i32* %j, align 4
  %5 = getelementptr inbounds { i32, i32, i32, i32 }, { i32, i32, i32, i32 }* %const, i32 0, i32 2
  %6 = load i32, i32* %5, align 4
  store i32 %6, i32* %k, align 4
  %7 = getelementptr inbounds { i32, i32, i32, i32 }, { i32, i32, i32, i32 }* %const, i32 0, i32 3
  %8 = load i32, i32* %7, align 4
  store i32 %8, i32* %l, align 4
  ret void
}
```

Let's hope I didn't break anything!
-rw-r--r--src/librustc_trans/trans/base.rs21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 5f2fe98727f..f8b5f8e48f4 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -1649,6 +1649,7 @@ pub fn init_function<'a, 'tcx>(fcx: &'a FunctionContext<'a, 'tcx>,
     // Create the drop-flag hints for every unfragmented path in the function.
     let tcx = fcx.ccx.tcx();
     let fn_did = tcx.map.local_def_id(fcx.id);
+    let tables = tcx.tables.borrow();
     let mut hints = fcx.lldropflag_hints.borrow_mut();
     let fragment_infos = tcx.fragment_infos.borrow();
 
@@ -1672,12 +1673,22 @@ pub fn init_function<'a, 'tcx>(fcx: &'a FunctionContext<'a, 'tcx>,
             let (var, datum) = match info {
                 ty::FragmentInfo::Moved { var, .. } |
                 ty::FragmentInfo::Assigned { var, .. } => {
-                    let datum = seen.get(&var).cloned().unwrap_or_else(|| {
-                        let datum = make_datum(var);
-                        seen.insert(var, datum.clone());
-                        datum
+                    let opt_datum = seen.get(&var).cloned().unwrap_or_else(|| {
+                        let ty = tables.node_types[&var];
+                        if fcx.type_needs_drop(ty) {
+                            let datum = make_datum(var);
+                            seen.insert(var, Some(datum.clone()));
+                            Some(datum)
+                        } else {
+                            // No drop call needed, so we don't need a dropflag hint
+                            None
+                        }
                     });
-                    (var, datum)
+                    if let Some(datum) = opt_datum {
+                        (var, datum)
+                    } else {
+                        continue
+                    }
                 }
             };
             match info {