diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2016-01-14 04:22:20 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2016-01-14 11:04:43 +0530 |
| commit | e51de045ef5fd2e6878b2e770a8deb7abcf64691 (patch) | |
| tree | 4bedd2756923c3ab4165ace8d5051210cfeef694 | |
| parent | 6ceaa2f77a2d217fd05fa2029c2724564cf43a09 (diff) | |
| parent | e3abc3cfe746c0ab078f33bc4566f6fb9773f489 (diff) | |
| download | rust-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.rs | 21 |
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 { |
