@@ -767,30 +767,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
767767 count : u64 ,
768768 dest : PlaceRef < ' tcx , & ' ll Value > ,
769769 ) {
770- let zero = self . const_usize ( 0 ) ;
771- let count = self . const_usize ( count) ;
772-
773- let header_bb = self . append_sibling_block ( "repeat_loop_header" ) ;
774- let body_bb = self . append_sibling_block ( "repeat_loop_body" ) ;
775- let next_bb = self . append_sibling_block ( "repeat_loop_next" ) ;
776-
777- self . br ( header_bb) ;
778-
779- let mut header_bx = Self :: build ( self . cx , header_bb) ;
780- let i = header_bx. phi ( self . val_ty ( zero) , & [ zero] , & [ self . llbb ( ) ] ) ;
781-
782- let keep_going = header_bx. icmp ( IntPredicate :: IntULT , i, count) ;
783- header_bx. cond_br ( keep_going, body_bb, next_bb) ;
784-
785- let mut body_bx = Self :: build ( self . cx , body_bb) ;
786- let dest_elem = dest. project_index ( & mut body_bx, i) ;
787- cg_elem. val . store ( & mut body_bx, dest_elem) ;
788-
789- let next = body_bx. unchecked_uadd ( i, self . const_usize ( 1 ) ) ;
790- body_bx. br ( header_bb) ;
791- header_bx. add_incoming_to_phi ( i, next, body_bb) ;
792-
793- * self = Self :: build ( self . cx , next_bb) ;
770+ if self . cx . sess ( ) . opts . optimize == OptLevel :: No {
771+ self . write_operand_repeatedly_unoptimized ( cg_elem, count, dest) ;
772+ } else {
773+ self . write_operand_repeatedly_optimized ( cg_elem, count, dest) ;
774+ }
794775 }
795776
796777 fn range_metadata ( & mut self , load : & ' ll Value , range : WrappingRange ) {
@@ -1527,6 +1508,78 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
15271508 pub ( crate ) fn set_unpredictable ( & mut self , inst : & ' ll Value ) {
15281509 self . set_metadata_node ( inst, llvm:: MD_unpredictable , & [ ] ) ;
15291510 }
1511+
1512+ fn write_operand_repeatedly_optimized (
1513+ & mut self ,
1514+ cg_elem : OperandRef < ' tcx , & ' ll Value > ,
1515+ count : u64 ,
1516+ dest : PlaceRef < ' tcx , & ' ll Value > ,
1517+ ) {
1518+ let zero = self . const_usize ( 0 ) ;
1519+ let count = self . const_usize ( count) ;
1520+
1521+ let header_bb = self . append_sibling_block ( "repeat_loop_header" ) ;
1522+ let body_bb = self . append_sibling_block ( "repeat_loop_body" ) ;
1523+ let next_bb = self . append_sibling_block ( "repeat_loop_next" ) ;
1524+
1525+ self . br ( header_bb) ;
1526+
1527+ let mut header_bx = Self :: build ( self . cx , header_bb) ;
1528+ let i = header_bx. phi ( self . val_ty ( zero) , & [ zero] , & [ self . llbb ( ) ] ) ;
1529+
1530+ let keep_going = header_bx. icmp ( IntPredicate :: IntULT , i, count) ;
1531+ header_bx. cond_br ( keep_going, body_bb, next_bb) ;
1532+
1533+ let mut body_bx = Self :: build ( self . cx , body_bb) ;
1534+ let dest_elem = dest. project_index ( & mut body_bx, i) ;
1535+ cg_elem. val . store ( & mut body_bx, dest_elem) ;
1536+
1537+ let next = body_bx. unchecked_uadd ( i, self . const_usize ( 1 ) ) ;
1538+ body_bx. br ( header_bb) ;
1539+ header_bx. add_incoming_to_phi ( i, next, body_bb) ;
1540+
1541+ * self = Self :: build ( self . cx , next_bb) ;
1542+ }
1543+
1544+ fn write_operand_repeatedly_unoptimized (
1545+ & mut self ,
1546+ cg_elem : OperandRef < ' tcx , & ' ll Value > ,
1547+ count : u64 ,
1548+ dest : PlaceRef < ' tcx , & ' ll Value > ,
1549+ ) {
1550+ let zero = self . const_usize ( 0 ) ;
1551+ let count = self . const_usize ( count) ;
1552+ let start = dest. project_index ( self , zero) . val . llval ;
1553+ let end = dest. project_index ( self , count) . val . llval ;
1554+
1555+ let header_bb = self . append_sibling_block ( "repeat_loop_header" ) ;
1556+ let body_bb = self . append_sibling_block ( "repeat_loop_body" ) ;
1557+ let next_bb = self . append_sibling_block ( "repeat_loop_next" ) ;
1558+
1559+ self . br ( header_bb) ;
1560+
1561+ let mut header_bx = Self :: build ( self . cx , header_bb) ;
1562+ let current = header_bx. phi ( self . val_ty ( start) , & [ start] , & [ self . llbb ( ) ] ) ;
1563+
1564+ let keep_going = header_bx. icmp ( IntPredicate :: IntNE , current, end) ;
1565+ header_bx. cond_br ( keep_going, body_bb, next_bb) ;
1566+
1567+ let mut body_bx = Self :: build ( self . cx , body_bb) ;
1568+ let align = dest. val . align . restrict_for_offset ( dest. layout . field ( self . cx ( ) , 0 ) . size ) ;
1569+ cg_elem
1570+ . val
1571+ . store ( & mut body_bx, PlaceRef :: new_sized_aligned ( current, cg_elem. layout , align) ) ;
1572+
1573+ let next = body_bx. inbounds_gep (
1574+ self . backend_type ( cg_elem. layout ) ,
1575+ current,
1576+ & [ self . const_usize ( 1 ) ] ,
1577+ ) ;
1578+ body_bx. br ( header_bb) ;
1579+ header_bx. add_incoming_to_phi ( current, next, body_bb) ;
1580+
1581+ * self = Self :: build ( self . cx , next_bb) ;
1582+ }
15301583}
15311584impl < ' a , ' ll , CX : Borrow < SCx < ' ll > > > GenericBuilder < ' a , ' ll , CX > {
15321585 pub ( crate ) fn minnum ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
0 commit comments