11
11
use libc:: c_uint;
12
12
use llvm:: { self , ValueRef , BasicBlockRef } ;
13
13
use llvm:: debuginfo:: DIScope ;
14
- use rustc:: ty:: { self , layout} ;
14
+ use rustc:: ty:: { self , layout, Ty , TypeFoldable } ;
15
15
use rustc:: mir:: { self , Mir } ;
16
16
use rustc:: mir:: tcx:: LvalueTy ;
17
17
use rustc:: ty:: subst:: Substs ;
18
18
use rustc:: infer:: TransNormalize ;
19
- use rustc:: ty:: TypeFoldable ;
20
19
use session:: config:: FullDebugInfo ;
21
20
use base;
22
21
use builder:: Builder ;
23
- use common:: { self , CrateContext , C_null , Funclet } ;
22
+ use common:: { self , CrateContext , Funclet } ;
24
23
use debuginfo:: { self , declare_local, VariableAccess , VariableKind , FunctionDebugContext } ;
25
24
use monomorphize:: { self , Instance } ;
26
25
use abi:: FnType ;
27
- use type_of;
28
26
29
27
use syntax_pos:: { DUMMY_SP , NO_EXPANSION , COMMAND_LINE_EXPN , BytePos , Span } ;
30
28
use syntax:: symbol:: keywords;
@@ -176,23 +174,12 @@ enum LocalRef<'tcx> {
176
174
177
175
impl < ' tcx > LocalRef < ' tcx > {
178
176
fn new_operand < ' a > ( ccx : & CrateContext < ' a , ' tcx > ,
179
- ty : ty :: Ty < ' tcx > ) -> LocalRef < ' tcx > {
177
+ ty : Ty < ' tcx > ) -> LocalRef < ' tcx > {
180
178
if common:: type_is_zero_size ( ccx, ty) {
181
179
// Zero-size temporaries aren't always initialized, which
182
180
// doesn't matter because they don't contain data, but
183
181
// we need something in the operand.
184
- let llty = type_of:: type_of ( ccx, ty) ;
185
- let val = if common:: type_is_imm_pair ( ccx, ty) {
186
- let fields = llty. field_types ( ) ;
187
- OperandValue :: Pair ( C_null ( fields[ 0 ] ) , C_null ( fields[ 1 ] ) )
188
- } else {
189
- OperandValue :: Immediate ( C_null ( llty) )
190
- } ;
191
- let op = OperandRef {
192
- val : val,
193
- ty : ty
194
- } ;
195
- LocalRef :: Operand ( Some ( op) )
182
+ LocalRef :: Operand ( Some ( OperandRef :: new_zst ( ccx, ty) ) )
196
183
} else {
197
184
LocalRef :: Operand ( None )
198
185
}
@@ -212,15 +199,17 @@ pub fn trans_mir<'a, 'tcx: 'a>(
212
199
debug ! ( "fn_ty: {:?}" , fn_ty) ;
213
200
let debug_context =
214
201
debuginfo:: create_function_debug_context ( ccx, instance, sig, llfn, mir) ;
215
- let bcx = Builder :: new_block ( ccx, llfn, "entry-block " ) ;
202
+ let bcx = Builder :: new_block ( ccx, llfn, "start " ) ;
216
203
217
204
let cleanup_kinds = analyze:: cleanup_kinds ( & mir) ;
218
205
219
- // Allocate a `Block` for every basic block
206
+ // Allocate a `Block` for every basic block, except
207
+ // the start block, if nothing loops back to it.
208
+ let reentrant_start_block = !mir. predecessors_for ( mir:: START_BLOCK ) . is_empty ( ) ;
220
209
let block_bcxs: IndexVec < mir:: BasicBlock , BasicBlockRef > =
221
210
mir. basic_blocks ( ) . indices ( ) . map ( |bb| {
222
- if bb == mir:: START_BLOCK {
223
- bcx. build_sibling_block ( "start" ) . llbb ( )
211
+ if bb == mir:: START_BLOCK && !reentrant_start_block {
212
+ bcx. llbb ( )
224
213
} else {
225
214
bcx. build_sibling_block ( & format ! ( "{:?}" , bb) ) . llbb ( )
226
215
}
@@ -307,9 +296,10 @@ pub fn trans_mir<'a, 'tcx: 'a>(
307
296
. collect ( )
308
297
} ;
309
298
310
- // Branch to the START block
311
- let start_bcx = mircx. blocks [ mir:: START_BLOCK ] ;
312
- bcx. br ( start_bcx) ;
299
+ // Branch to the START block, if it's not the entry block.
300
+ if reentrant_start_block {
301
+ bcx. br ( mircx. blocks [ mir:: START_BLOCK ] ) ;
302
+ }
313
303
314
304
// Up until here, IR instructions for this function have explicitly not been annotated with
315
305
// source code location, so we don't step into call setup code. From here on, source location
0 commit comments