@@ -395,6 +395,38 @@ impl MemoryBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
395395 self . call ( llintrinsicfn, & [ ptr, fill_byte, size, align, volatile] , None ) ;
396396 }
397397
398+ fn write_operand_repeatedly (
399+ mut self ,
400+ cg_elem : OperandRef < ' tcx , & ' ll Value > ,
401+ count : u64 ,
402+ dest : PlaceRef < ' tcx , & ' ll Value > ,
403+ ) -> Self {
404+ let zero = self . const_usize ( 0 ) ;
405+ let count = self . const_usize ( count) ;
406+ let start = dest. project_index ( & mut self , zero) . llval ;
407+ let end = dest. project_index ( & mut self , count) . llval ;
408+
409+ let mut header_bx = self . build_sibling_block ( "repeat_loop_header" ) ;
410+ let mut body_bx = self . build_sibling_block ( "repeat_loop_body" ) ;
411+ let next_bx = self . build_sibling_block ( "repeat_loop_next" ) ;
412+
413+ self . br ( header_bx. llbb ( ) ) ;
414+ let current = header_bx. phi ( self . val_ty ( start) , & [ start] , & [ self . llbb ( ) ] ) ;
415+
416+ let keep_going = header_bx. icmp ( IntPredicate :: IntNE , current, end) ;
417+ header_bx. cond_br ( keep_going, body_bx. llbb ( ) , next_bx. llbb ( ) ) ;
418+
419+ let align = dest. align . restrict_for_offset ( dest. layout . field ( self . cx ( ) , 0 ) . size ) ;
420+ cg_elem. val . store ( & mut body_bx,
421+ PlaceRef :: new_sized ( current, cg_elem. layout , align) ) ;
422+
423+ let next = body_bx. inbounds_gep ( current, & [ self . const_usize ( 1 ) ] ) ;
424+ body_bx. br ( header_bx. llbb ( ) ) ;
425+ header_bx. add_incoming_to_phi ( current, next, body_bx. llbb ( ) ) ;
426+
427+ next_bx
428+ }
429+
398430 fn atomic_load (
399431 & mut self ,
400432 ptr : & ' ll Value ,
@@ -994,20 +1026,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
9941026 }
9951027
9961028 /* Miscellaneous instructions */
997- fn phi ( & mut self , ty : & ' ll Type , vals : & [ & ' ll Value ] , bbs : & [ & ' ll BasicBlock ] ) -> & ' ll Value {
998- self . count_insn ( "addincoming" ) ;
999- assert_eq ! ( vals. len( ) , bbs. len( ) ) ;
1000- let phi = unsafe {
1001- llvm:: LLVMBuildPhi ( self . llbuilder , ty, noname ( ) )
1002- } ;
1003- unsafe {
1004- llvm:: LLVMAddIncoming ( phi, vals. as_ptr ( ) ,
1005- bbs. as_ptr ( ) ,
1006- vals. len ( ) as c_uint ) ;
1007- phi
1008- }
1009- }
1010-
10111029 fn inline_asm_call ( & mut self , asm : & CStr , cons : & CStr ,
10121030 inputs : & [ & ' ll Value ] , output : & ' ll Type ,
10131031 volatile : bool , alignstack : bool ,
@@ -1197,13 +1215,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11971215 }
11981216 }
11991217
1200- fn add_incoming_to_phi ( & mut self , phi : & ' ll Value , val : & ' ll Value , bb : & ' ll BasicBlock ) {
1201- self . count_insn ( "addincoming" ) ;
1202- unsafe {
1203- llvm:: LLVMAddIncoming ( phi, & val, & bb, 1 as c_uint ) ;
1204- }
1205- }
1206-
12071218 fn set_invariant_load ( & mut self , load : & ' ll Value ) {
12081219 unsafe {
12091220 llvm:: LLVMSetMetadata ( load, llvm:: MD_invariant_load as c_uint ,
@@ -1518,4 +1529,25 @@ impl Builder<'a, 'll, 'tcx> {
15181529 let ptr = self . pointercast ( ptr, self . cx . type_i8p ( ) ) ;
15191530 self . call ( lifetime_intrinsic, & [ self . cx . const_u64 ( size) , ptr] , None ) ;
15201531 }
1532+
1533+ fn phi ( & mut self , ty : & ' ll Type , vals : & [ & ' ll Value ] , bbs : & [ & ' ll BasicBlock ] ) -> & ' ll Value {
1534+ self . count_insn ( "addincoming" ) ;
1535+ assert_eq ! ( vals. len( ) , bbs. len( ) ) ;
1536+ let phi = unsafe {
1537+ llvm:: LLVMBuildPhi ( self . llbuilder , ty, noname ( ) )
1538+ } ;
1539+ unsafe {
1540+ llvm:: LLVMAddIncoming ( phi, vals. as_ptr ( ) ,
1541+ bbs. as_ptr ( ) ,
1542+ vals. len ( ) as c_uint ) ;
1543+ phi
1544+ }
1545+ }
1546+
1547+ fn add_incoming_to_phi ( & mut self , phi : & ' ll Value , val : & ' ll Value , bb : & ' ll BasicBlock ) {
1548+ self . count_insn ( "addincoming" ) ;
1549+ unsafe {
1550+ llvm:: LLVMAddIncoming ( phi, & val, & bb, 1 as c_uint ) ;
1551+ }
1552+ }
15211553}
0 commit comments