1111use libc:: c_uint;
1212use llvm:: { self , ValueRef , BasicBlockRef } ;
1313use llvm:: debuginfo:: DIScope ;
14- use rustc:: ty;
14+ use rustc:: ty:: { self , Ty , TypeFoldable } ;
1515use rustc:: ty:: layout:: { self , LayoutTyper } ;
1616use rustc:: mir:: { self , Mir } ;
1717use rustc:: mir:: tcx:: LvalueTy ;
1818use rustc:: ty:: subst:: Substs ;
1919use rustc:: infer:: TransNormalize ;
20- use rustc:: ty:: TypeFoldable ;
2120use session:: config:: FullDebugInfo ;
2221use base;
2322use builder:: Builder ;
24- use common:: { self , CrateContext , C_null , Funclet } ;
23+ use common:: { self , CrateContext , Funclet } ;
2524use debuginfo:: { self , declare_local, VariableAccess , VariableKind , FunctionDebugContext } ;
2625use monomorphize:: { self , Instance } ;
2726use abi:: FnType ;
@@ -171,23 +170,12 @@ enum LocalRef<'tcx> {
171170
172171impl < ' tcx > LocalRef < ' tcx > {
173172 fn new_operand < ' a > ( ccx : & CrateContext < ' a , ' tcx > ,
174- ty : ty :: Ty < ' tcx > ) -> LocalRef < ' tcx > {
173+ ty : Ty < ' tcx > ) -> LocalRef < ' tcx > {
175174 if common:: type_is_zero_size ( ccx, ty) {
176175 // Zero-size temporaries aren't always initialized, which
177176 // doesn't matter because they don't contain data, but
178177 // 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) ) )
191179 } else {
192180 LocalRef :: Operand ( None )
193181 }
@@ -207,15 +195,17 @@ pub fn trans_mir<'a, 'tcx: 'a>(
207195 debug ! ( "fn_ty: {:?}" , fn_ty) ;
208196 let debug_context =
209197 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 " ) ;
211199
212200 let cleanup_kinds = analyze:: cleanup_kinds ( & mir) ;
213201
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 ( ) ;
215205 let block_bcxs: IndexVec < mir:: BasicBlock , BasicBlockRef > =
216206 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 ( )
219209 } else {
220210 bcx. build_sibling_block ( & format ! ( "{:?}" , bb) ) . llbb ( )
221211 }
@@ -301,9 +291,10 @@ pub fn trans_mir<'a, 'tcx: 'a>(
301291 . collect ( )
302292 } ;
303293
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+ }
307298
308299 // Up until here, IR instructions for this function have explicitly not been annotated with
309300 // source code location, so we don't step into call setup code. From here on, source location
0 commit comments