@@ -668,32 +668,38 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
668668 }
669669
670670 fn add ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
671- self . gcc_add ( a, b)
671+ self . assign_to_var ( self . gcc_add ( a, b) )
672672 }
673673
674674 fn fadd ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
675- a + b
675+ self . assign_to_var ( a + b)
676676 }
677677
678678 // TODO(antoyo): should we also override the `unchecked_` versions?
679679 fn sub ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
680- self . gcc_sub ( a, b)
680+ self . assign_to_var ( self . gcc_sub ( a, b) )
681681 }
682682
683683 fn fsub ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
684- a - b
684+ self . assign_to_var ( a - b)
685685 }
686686
687687 fn mul ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
688- self . gcc_mul ( a, b)
688+ self . assign_to_var ( self . gcc_mul ( a, b) )
689689 }
690690
691691 fn fmul ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
692- self . cx . context . new_binary_op ( self . location , BinaryOp :: Mult , a. get_type ( ) , a, b)
692+ self . assign_to_var ( self . cx . context . new_binary_op (
693+ self . location ,
694+ BinaryOp :: Mult ,
695+ a. get_type ( ) ,
696+ a,
697+ b,
698+ ) )
693699 }
694700
695701 fn udiv ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
696- self . gcc_udiv ( a, b)
702+ self . assign_to_var ( self . gcc_udiv ( a, b) )
697703 }
698704
699705 fn exactudiv ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
@@ -702,11 +708,11 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
702708 let a = self . gcc_int_cast ( a, a_type) ;
703709 let b_type = b. get_type ( ) . to_unsigned ( self ) ;
704710 let b = self . gcc_int_cast ( b, b_type) ;
705- self . gcc_udiv ( a, b)
711+ self . assign_to_var ( self . gcc_udiv ( a, b) )
706712 }
707713
708714 fn sdiv ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
709- self . gcc_sdiv ( a, b)
715+ self . assign_to_var ( self . gcc_sdiv ( a, b) )
710716 }
711717
712718 fn exactsdiv ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
@@ -715,19 +721,19 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
715721 // should be the same.
716722 let typ = a. get_type ( ) . to_signed ( self ) ;
717723 let b = self . gcc_int_cast ( b, typ) ;
718- self . gcc_sdiv ( a, b)
724+ self . assign_to_var ( self . gcc_sdiv ( a, b) )
719725 }
720726
721727 fn fdiv ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
722- a / b
728+ self . assign_to_var ( a / b)
723729 }
724730
725731 fn urem ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
726- self . gcc_urem ( a, b)
732+ self . assign_to_var ( self . gcc_urem ( a, b) )
727733 }
728734
729735 fn srem ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
730- self . gcc_srem ( a, b)
736+ self . assign_to_var ( self . gcc_srem ( a, b) )
731737 }
732738
733739 fn frem ( & mut self , a : RValue < ' gcc > , b : RValue < ' gcc > ) -> RValue < ' gcc > {
@@ -865,22 +871,26 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
865871
866872 fn fadd_fast ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
867873 // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC.
868- set_rvalue_location ( self , lhs + rhs)
874+ let result = set_rvalue_location ( self , lhs + rhs) ;
875+ self . assign_to_var ( result)
869876 }
870877
871878 fn fsub_fast ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
872879 // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC.
873- set_rvalue_location ( self , lhs - rhs)
880+ let result = set_rvalue_location ( self , lhs - rhs) ;
881+ self . assign_to_var ( result)
874882 }
875883
876884 fn fmul_fast ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
877885 // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC.
878- set_rvalue_location ( self , lhs * rhs)
886+ let result = set_rvalue_location ( self , lhs * rhs) ;
887+ self . assign_to_var ( result)
879888 }
880889
881890 fn fdiv_fast ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
882891 // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC.
883- set_rvalue_location ( self , lhs / rhs)
892+ let result = set_rvalue_location ( self , lhs / rhs) ;
893+ self . assign_to_var ( result)
884894 }
885895
886896 fn frem_fast ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
@@ -892,22 +902,22 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
892902
893903 fn fadd_algebraic ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
894904 // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC.
895- lhs + rhs
905+ self . assign_to_var ( lhs + rhs)
896906 }
897907
898908 fn fsub_algebraic ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
899909 // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC.
900- lhs - rhs
910+ self . assign_to_var ( lhs - rhs)
901911 }
902912
903913 fn fmul_algebraic ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
904914 // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC.
905- lhs * rhs
915+ self . assign_to_var ( lhs * rhs)
906916 }
907917
908918 fn fdiv_algebraic ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
909919 // NOTE: it seems like we cannot enable fast-mode for a single operation in GCC.
910- lhs / rhs
920+ self . assign_to_var ( lhs / rhs)
911921 }
912922
913923 fn frem_algebraic ( & mut self , lhs : RValue < ' gcc > , rhs : RValue < ' gcc > ) -> RValue < ' gcc > {
@@ -2409,6 +2419,15 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
24092419 let res = then_vals | else_vals;
24102420 self . bitcast_if_needed ( res, result_type)
24112421 }
2422+
2423+ // GCC doesn't like deeply nested expressions.
2424+ // By assigning intermediate expressions to a variable, this allow us to avoid deeply nested
2425+ // expressions and GCC will use much less RAM.
2426+ fn assign_to_var ( & self , value : RValue < ' gcc > ) -> RValue < ' gcc > {
2427+ let var = self . current_func ( ) . new_local ( self . location , value. get_type ( ) , "opResult" ) ;
2428+ self . llbb ( ) . add_assignment ( self . location , var, value) ;
2429+ var. to_rvalue ( )
2430+ }
24122431}
24132432
24142433fn difference_or_zero < ' gcc > (
0 commit comments