@@ -652,7 +652,37 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
652652 OperandRef { val, layout : place. layout }
653653 }
654654
655+ fn write_operand_repeatedly (
656+ mut self ,
657+ cg_elem : OperandRef < ' tcx , & ' ll Value > ,
658+ count : u64 ,
659+ dest : PlaceRef < ' tcx , & ' ll Value > ,
660+ ) -> Self {
661+ let zero = self . const_usize ( 0 ) ;
662+ let count = self . const_usize ( count) ;
663+ let start = dest. project_index ( & mut self , zero) . llval ;
664+ let end = dest. project_index ( & mut self , count) . llval ;
665+
666+ let mut header_bx = self . build_sibling_block ( "repeat_loop_header" ) ;
667+ let mut body_bx = self . build_sibling_block ( "repeat_loop_body" ) ;
668+ let next_bx = self . build_sibling_block ( "repeat_loop_next" ) ;
669+
670+ self . br ( header_bx. llbb ( ) ) ;
671+ let current = header_bx. phi ( self . val_ty ( start) , & [ start] , & [ self . llbb ( ) ] ) ;
672+
673+ let keep_going = header_bx. icmp ( IntPredicate :: IntNE , current, end) ;
674+ header_bx. cond_br ( keep_going, body_bx. llbb ( ) , next_bx. llbb ( ) ) ;
655675
676+ let align = dest. align . restrict_for_offset ( dest. layout . field ( self . cx ( ) , 0 ) . size ) ;
677+ cg_elem. val . store ( & mut body_bx,
678+ PlaceRef :: new_sized ( current, cg_elem. layout , align) ) ;
679+
680+ let next = body_bx. inbounds_gep ( current, & [ self . const_usize ( 1 ) ] ) ;
681+ body_bx. br ( header_bx. llbb ( ) ) ;
682+ header_bx. add_incoming_to_phi ( current, next, body_bx. llbb ( ) ) ;
683+
684+ next_bx
685+ }
656686
657687 fn range_metadata ( & mut self , load : & ' ll Value , range : Range < u128 > ) {
658688 if self . sess ( ) . target . target . arch == "amdgpu" {
@@ -873,20 +903,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
873903 }
874904
875905 /* Miscellaneous instructions */
876- fn phi ( & mut self , ty : & ' ll Type , vals : & [ & ' ll Value ] , bbs : & [ & ' ll BasicBlock ] ) -> & ' ll Value {
877- self . count_insn ( "addincoming" ) ;
878- assert_eq ! ( vals. len( ) , bbs. len( ) ) ;
879- let phi = unsafe {
880- llvm:: LLVMBuildPhi ( self . llbuilder , ty, noname ( ) )
881- } ;
882- unsafe {
883- llvm:: LLVMAddIncoming ( phi, vals. as_ptr ( ) ,
884- bbs. as_ptr ( ) ,
885- vals. len ( ) as c_uint ) ;
886- phi
887- }
888- }
889-
890906 fn inline_asm_call ( & mut self , asm : & CStr , cons : & CStr ,
891907 inputs : & [ & ' ll Value ] , output : & ' ll Type ,
892908 volatile : bool , alignstack : bool ,
@@ -1188,13 +1204,6 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11881204 }
11891205 }
11901206
1191- fn add_incoming_to_phi ( & mut self , phi : & ' ll Value , val : & ' ll Value , bb : & ' ll BasicBlock ) {
1192- self . count_insn ( "addincoming" ) ;
1193- unsafe {
1194- llvm:: LLVMAddIncoming ( phi, & val, & bb, 1 as c_uint ) ;
1195- }
1196- }
1197-
11981207 fn set_invariant_load ( & mut self , load : & ' ll Value ) {
11991208 unsafe {
12001209 llvm:: LLVMSetMetadata ( load, llvm:: MD_invariant_load as c_uint ,
@@ -1526,4 +1535,25 @@ impl Builder<'a, 'll, 'tcx> {
15261535 let ptr = self . pointercast ( ptr, self . cx . type_i8p ( ) ) ;
15271536 self . call ( lifetime_intrinsic, & [ self . cx . const_u64 ( size) , ptr] , None ) ;
15281537 }
1538+
1539+ fn phi ( & mut self , ty : & ' ll Type , vals : & [ & ' ll Value ] , bbs : & [ & ' ll BasicBlock ] ) -> & ' ll Value {
1540+ self . count_insn ( "addincoming" ) ;
1541+ assert_eq ! ( vals. len( ) , bbs. len( ) ) ;
1542+ let phi = unsafe {
1543+ llvm:: LLVMBuildPhi ( self . llbuilder , ty, noname ( ) )
1544+ } ;
1545+ unsafe {
1546+ llvm:: LLVMAddIncoming ( phi, vals. as_ptr ( ) ,
1547+ bbs. as_ptr ( ) ,
1548+ vals. len ( ) as c_uint ) ;
1549+ phi
1550+ }
1551+ }
1552+
1553+ fn add_incoming_to_phi ( & mut self , phi : & ' ll Value , val : & ' ll Value , bb : & ' ll BasicBlock ) {
1554+ self . count_insn ( "addincoming" ) ;
1555+ unsafe {
1556+ llvm:: LLVMAddIncoming ( phi, & val, & bb, 1 as c_uint ) ;
1557+ }
1558+ }
15291559}
0 commit comments