aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_emu.c
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2010-12-08 15:27:37 +0100
committerBjörn Gustavsson <[email protected]>2011-01-17 15:23:46 +0100
commit74d7bd100b742a803c8de82c9c997308cf871038 (patch)
tree8230b273d29b0c2f60950c9c7a0db747d217d18d /erts/emulator/beam/beam_emu.c
parentb166f8975387d7ef07409e841d45c2cd74c2282e (diff)
downloadotp-74d7bd100b742a803c8de82c9c997308cf871038.tar.gz
otp-74d7bd100b742a803c8de82c9c997308cf871038.tar.bz2
otp-74d7bd100b742a803c8de82c9c997308cf871038.zip
Optimize addition of a small integer to a variable
Introduce a new i_increment/4 to optimize the addition of a register and a small integer. This instruction saves two instruction words compared to the standard instructions (an i_fetch/2 instruction followed by a i_plus/3 instruction) and will also be slightly faster.
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r--erts/emulator/beam/beam_emu.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index afba17f7bd..741ba8fb93 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1276,6 +1276,52 @@ void process_main(void)
#define STORE_ARITH_RESULT(res) StoreBifResult(2, (res));
#define ARITH_FUNC(name) erts_gc_##name
+ {
+ Eterm increment_reg_val;
+ Eterm increment_val;
+ Uint live;
+ Eterm result;
+
+ OpCase(i_increment_yIId):
+ increment_reg_val = yb(Arg(0));
+ goto do_increment;
+
+ OpCase(i_increment_xIId):
+ increment_reg_val = xb(Arg(0));
+ goto do_increment;
+
+ OpCase(i_increment_rIId):
+ increment_reg_val = r(0);
+ I--;
+
+ do_increment:
+ increment_val = Arg(1);
+ if (is_small(increment_reg_val)) {
+ Sint i = signed_val(increment_reg_val) + increment_val;
+ ASSERT(MY_IS_SSMALL(i) == IS_SSMALL(i));
+ if (MY_IS_SSMALL(i)) {
+ result = make_small(i);
+ store_result:
+ StoreBifResult(3, result);
+ }
+ }
+
+ live = Arg(2);
+ SWAPOUT;
+ reg[0] = r(0);
+ reg[live] = increment_reg_val;
+ reg[live+1] = make_small(increment_val);
+ result = erts_gc_mixed_plus(c_p, reg, live);
+ r(0) = reg[0];
+ SWAPIN;
+ ERTS_HOLE_CHECK(c_p);
+ if (is_value(result)) {
+ goto store_result;
+ }
+ ASSERT(c_p->freason != BADMATCH || is_value(c_p->fvalue));
+ goto find_func_info;
+ }
+
OpCase(i_plus_jId):
{
Eterm result;