@@ -708,25 +708,23 @@ impl Compiler {
708708 // Check if second arg is a small constant integer
709709 if let Some ( imm) = args[ 1 ] . as_int ( ) {
710710 if imm >= i8:: MIN as i64 && imm <= i8:: MAX as i64 {
711- let a_reg = self . alloc_reg ( ) ;
712- self . compile_expr ( & args[ 0 ] , a_reg , false ) ?;
711+ // Optimization: compile first arg directly into dest
712+ self . compile_expr ( & args[ 0 ] , dest , false ) ?;
713713 if op == "+" {
714- self . emit ( Op :: AddImm ( dest, a_reg , imm as i8 ) ) ;
714+ self . emit ( Op :: AddImm ( dest, dest , imm as i8 ) ) ;
715715 } else {
716- self . emit ( Op :: SubImm ( dest, a_reg , imm as i8 ) ) ;
716+ self . emit ( Op :: SubImm ( dest, dest , imm as i8 ) ) ;
717717 }
718- self . free_reg ( ) ;
719718 return Ok ( Some ( true ) ) ;
720719 }
721720 }
722721 // Check if first arg is a small constant integer (for + only, since + is commutative)
723722 if op == "+" {
724723 if let Some ( imm) = args[ 0 ] . as_int ( ) {
725724 if imm >= i8:: MIN as i64 && imm <= i8:: MAX as i64 {
726- let b_reg = self . alloc_reg ( ) ;
727- self . compile_expr ( & args[ 1 ] , b_reg, false ) ?;
728- self . emit ( Op :: AddImm ( dest, b_reg, imm as i8 ) ) ;
729- self . free_reg ( ) ;
725+ // Optimization: compile second arg directly into dest
726+ self . compile_expr ( & args[ 1 ] , dest, false ) ?;
727+ self . emit ( Op :: AddImm ( dest, dest, imm as i8 ) ) ;
730728 return Ok ( Some ( true ) ) ;
731729 }
732730 }
@@ -749,17 +747,15 @@ impl Compiler {
749747 } ;
750748
751749 if let Some ( make_op) = make_binary_op {
752- // Compile both arguments
753- let a_reg = self . alloc_reg ( ) ;
754- self . compile_expr ( & args[ 0 ] , a_reg, false ) ?;
750+ // Optimization: compile first arg directly into dest to save a register
751+ self . compile_expr ( & args[ 0 ] , dest, false ) ?;
755752 let b_reg = self . alloc_reg ( ) ;
756753 self . compile_expr ( & args[ 1 ] , b_reg, false ) ?;
757754
758- // Emit the operation
759- self . emit ( make_op ( dest, a_reg , b_reg) ) ;
755+ // Emit the operation (dest = dest op b_reg)
756+ self . emit ( make_op ( dest, dest , b_reg) ) ;
760757
761- // Free temp registers
762- self . free_reg ( ) ;
758+ // Free temp register
763759 self . free_reg ( ) ;
764760
765761 return Ok ( Some ( true ) ) ;
@@ -769,19 +765,17 @@ impl Compiler {
769765 // Unary operators
770766 if args. len ( ) == 1 {
771767 if op == "not" {
772- let a_reg = self . alloc_reg ( ) ;
773- self . compile_expr ( & args[ 0 ] , a_reg, false ) ?;
774- self . emit ( Op :: Not ( dest, a_reg) ) ;
775- self . free_reg ( ) ;
768+ // Optimization: compile arg directly into dest
769+ self . compile_expr ( & args[ 0 ] , dest, false ) ?;
770+ self . emit ( Op :: Not ( dest, dest) ) ;
776771 return Ok ( Some ( true ) ) ;
777772 }
778773
779774 // Unary minus: (- x)
780775 if op == "-" {
781- let a_reg = self . alloc_reg ( ) ;
782- self . compile_expr ( & args[ 0 ] , a_reg, false ) ?;
783- self . emit ( Op :: Neg ( dest, a_reg) ) ;
784- self . free_reg ( ) ;
776+ // Optimization: compile arg directly into dest
777+ self . compile_expr ( & args[ 0 ] , dest, false ) ?;
778+ self . emit ( Op :: Neg ( dest, dest) ) ;
785779 return Ok ( Some ( true ) ) ;
786780 }
787781 }
@@ -824,18 +818,18 @@ impl Compiler {
824818 let nargs = args. len ( ) as u8 ;
825819
826820 if tail_pos {
827- // For TailCallGlobal, we need to be careful not to overwrite parameters
828- // that might be used in later arguments. Compile to temp registers first,
821+ // For TailCallGlobal, compile args to temp registers first,
829822 // then we'll copy to r0, r1, ... at call time.
830- let arg_start = self . alloc_reg ( ) ;
823+ // Optimization: track first_arg position without allocating unused marker register
824+ let first_arg = self . locals . len ( ) as Reg ;
831825 for arg in args. iter ( ) {
832826 let arg_reg = self . alloc_reg ( ) ;
833827 self . compile_expr ( arg, arg_reg, false ) ?;
834828 }
835- self . emit ( Op :: TailCallGlobal ( name_idx, arg_start , nargs) ) ;
829+ self . emit ( Op :: TailCallGlobal ( name_idx, first_arg , nargs) ) ;
836830 self . emit ( Op :: LoadNil ( dest) ) ;
837831 // Free the temp registers
838- for _ in 0 ..= nargs {
832+ for _ in 0 ..nargs {
839833 self . free_reg ( ) ;
840834 }
841835 } else {
0 commit comments