diff options
author | Björn Gustavsson <[email protected]> | 2010-12-08 15:27:37 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2011-01-17 15:23:46 +0100 |
commit | 74d7bd100b742a803c8de82c9c997308cf871038 (patch) | |
tree | 8230b273d29b0c2f60950c9c7a0db747d217d18d /erts/emulator/beam/beam_emu.c | |
parent | b166f8975387d7ef07409e841d45c2cd74c2282e (diff) | |
download | otp-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.c | 46 |
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; |