@@ -1147,48 +1147,63 @@ pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, val: ValueRef, f: F) ->
1147
1147
next_cx
1148
1148
}
1149
1149
1150
- pub fn call_lifetime_start ( cx : Block , ptr : ValueRef ) {
1151
- if cx. sess ( ) . opts . optimize == config:: No {
1150
+ enum Lifetime { Start , End }
1151
+
1152
+ // If LLVM lifetime intrinsic support is enabled (i.e. optimizations
1153
+ // on), and `ptr` is nonzero-sized, then extracts the size of `ptr`
1154
+ // and the intrinsic for `lt` and passes them to `emit`, which is in
1155
+ // charge of generating code to call the passed intrinsic on whatever
1156
+ // block of generated code is targetted for the intrinsic.
1157
+ //
1158
+ // If LLVM lifetime intrinsic support is disabled (i.e. optimizations
1159
+ // off) or `ptr` is zero-sized, then no-op (does not call `emit`).
1160
+ fn core_lifetime_emit < ' blk , ' tcx , F > ( ccx : & ' blk CrateContext < ' blk , ' tcx > ,
1161
+ ptr : ValueRef ,
1162
+ lt : Lifetime ,
1163
+ emit : F )
1164
+ where F : FnOnce ( & ' blk CrateContext < ' blk , ' tcx > , machine:: llsize , ValueRef )
1165
+ {
1166
+ if ccx. sess ( ) . opts . optimize == config:: No {
1152
1167
return ;
1153
1168
}
1154
1169
1155
- let _icx = push_ctxt ( "lifetime_start" ) ;
1156
- let ccx = cx. ccx ( ) ;
1170
+ let _icx = push_ctxt ( match lt {
1171
+ Lifetime :: Start => "lifetime_start" ,
1172
+ Lifetime :: End => "lifetime_end"
1173
+ } ) ;
1157
1174
1158
1175
let size = machine:: llsize_of_alloc ( ccx, val_ty ( ptr) . element_type ( ) ) ;
1159
1176
if size == 0 {
1160
1177
return ;
1161
1178
}
1162
1179
1163
- let ptr = PointerCast ( cx, ptr, Type :: i8p ( ccx) ) ;
1164
- let lifetime_start = ccx. get_intrinsic ( & "llvm.lifetime.start" ) ;
1165
- Call ( cx,
1166
- lifetime_start,
1167
- & [ C_u64 ( ccx, size) , ptr] ,
1168
- None ,
1169
- DebugLoc :: None ) ;
1180
+ let lifetime_intrinsic = ccx. get_intrinsic ( match lt {
1181
+ Lifetime :: Start => "llvm.lifetime.start" ,
1182
+ Lifetime :: End => "llvm.lifetime.end"
1183
+ } ) ;
1184
+ emit ( ccx, size, lifetime_intrinsic)
1170
1185
}
1171
1186
1172
- pub fn call_lifetime_end ( cx : Block , ptr : ValueRef ) {
1173
- if cx. sess ( ) . opts . optimize == config:: No {
1174
- return ;
1175
- }
1176
-
1177
- let _icx = push_ctxt ( "lifetime_end" ) ;
1178
- let ccx = cx. ccx ( ) ;
1179
-
1180
- let size = machine:: llsize_of_alloc ( ccx, val_ty ( ptr) . element_type ( ) ) ;
1181
- if size == 0 {
1182
- return ;
1183
- }
1187
+ pub fn call_lifetime_start ( cx : Block , ptr : ValueRef ) {
1188
+ core_lifetime_emit ( cx. ccx ( ) , ptr, Lifetime :: Start , |ccx, size, lifetime_start| {
1189
+ let ptr = PointerCast ( cx, ptr, Type :: i8p ( ccx) ) ;
1190
+ Call ( cx,
1191
+ lifetime_start,
1192
+ & [ C_u64 ( ccx, size) , ptr] ,
1193
+ None ,
1194
+ DebugLoc :: None ) ;
1195
+ } )
1196
+ }
1184
1197
1185
- let ptr = PointerCast ( cx, ptr, Type :: i8p ( ccx) ) ;
1186
- let lifetime_end = ccx. get_intrinsic ( & "llvm.lifetime.end" ) ;
1187
- Call ( cx,
1188
- lifetime_end,
1189
- & [ C_u64 ( ccx, size) , ptr] ,
1190
- None ,
1191
- DebugLoc :: None ) ;
1198
+ pub fn call_lifetime_end ( cx : Block , ptr : ValueRef ) {
1199
+ core_lifetime_emit ( cx. ccx ( ) , ptr, Lifetime :: End , |ccx, size, lifetime_end| {
1200
+ let ptr = PointerCast ( cx, ptr, Type :: i8p ( ccx) ) ;
1201
+ Call ( cx,
1202
+ lifetime_end,
1203
+ & [ C_u64 ( ccx, size) , ptr] ,
1204
+ None ,
1205
+ DebugLoc :: None ) ;
1206
+ } )
1192
1207
}
1193
1208
1194
1209
// Generates code for resumption of unwind at the end of a landing pad.
0 commit comments