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