Skip to content

Commit 13230c0

Browse files
authored
Merge pull request #783 from rust-lang/fix/ram-usage
Fix RAM usage by splitting deeply nested expressions
2 parents 8e737d6 + 77a9796 commit 13230c0

File tree

1 file changed

+40
-21
lines changed

1 file changed

+40
-21
lines changed

src/builder.rs

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

24142433
fn difference_or_zero<'gcc>(

0 commit comments

Comments
 (0)