aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_load.c
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2010-11-11 08:23:55 +0100
committerBjörn Gustavsson <[email protected]>2011-01-17 15:23:42 +0100
commit824a481d5f38c748cd6efcb83cba0b8d26b88768 (patch)
treeb516c2028042df57c05bb66faf7d6b3202950bb7 /erts/emulator/beam/beam_load.c
parente4a4632ed173f22642a2b67316b6decbc91b2a5b (diff)
downloadotp-824a481d5f38c748cd6efcb83cba0b8d26b88768.tar.gz
otp-824a481d5f38c748cd6efcb83cba0b8d26b88768.tar.bz2
otp-824a481d5f38c748cd6efcb83cba0b8d26b88768.zip
Optimize creation of tuples
Combine the put_tuple/2 and all following put/1 instructions to one i_put_tuple/2 instruction. In general, that will reduce the number of instruction words by 50 percent. Measurements seem to indicate that the speed is about the same.
Diffstat (limited to 'erts/emulator/beam/beam_load.c')
-rw-r--r--erts/emulator/beam/beam_load.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index bc6186751e..a476e439ca 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -2015,6 +2015,30 @@ load_code(LoaderState* stp)
stp->labels[tmp_op->a[arg].val].patches = ci;
ci++;
break;
+ case TAG_r:
+ CodeNeed(1);
+ code[ci++] = (R_REG_DEF << _TAG_PRIMARY_SIZE) |
+ TAG_PRIMARY_HEADER;
+ break;
+ case TAG_x:
+ CodeNeed(1);
+ code[ci++] = (tmp_op->a[arg].val << _TAG_IMMED1_SIZE) |
+ (X_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER;
+ break;
+ case TAG_y:
+ CodeNeed(1);
+ code[ci++] = (tmp_op->a[arg].val << _TAG_IMMED1_SIZE) |
+ (Y_REG_DEF << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_HEADER;
+ break;
+ case TAG_n:
+ CodeNeed(1);
+ code[ci++] = NIL;
+ break;
+ case TAG_q:
+ CodeNeed(1);
+ new_literal_patch(stp, ci);
+ code[ci++] = tmp_op->a[arg].val;
+ break;
default:
LoadError1(stp, "unsupported primitive type '%c'",
tag_to_letter[tmp_op->a[arg].type]);
@@ -3440,6 +3464,56 @@ gen_guard_bif3(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
return op;
}
+static GenOp*
+tuple_append_put5(LoaderState* stp, GenOpArg Arity, GenOpArg Dst,
+ GenOpArg* Puts, GenOpArg S1, GenOpArg S2, GenOpArg S3,
+ GenOpArg S4, GenOpArg S5)
+{
+ GenOp* op;
+ int arity = Arity.val; /* Arity of tuple, not the instruction */
+ int i;
+
+ NEW_GENOP(stp, op);
+ op->next = NULL;
+ GENOP_ARITY(op, arity+2+5);
+ op->op = genop_i_put_tuple_2;
+ op->a[0] = Dst;
+ op->a[1].type = TAG_u;
+ op->a[1].val = arity + 5;
+ for (i = 0; i < arity; i++) {
+ op->a[i+2] = Puts[i];
+ }
+ op->a[arity+2] = S1;
+ op->a[arity+3] = S2;
+ op->a[arity+4] = S3;
+ op->a[arity+5] = S4;
+ op->a[arity+6] = S5;
+ return op;
+}
+
+static GenOp*
+tuple_append_put(LoaderState* stp, GenOpArg Arity, GenOpArg Dst,
+ GenOpArg* Puts, GenOpArg S)
+{
+ GenOp* op;
+ int arity = Arity.val; /* Arity of tuple, not the instruction */
+ int i;
+
+ NEW_GENOP(stp, op);
+ op->next = NULL;
+ GENOP_ARITY(op, arity+2+1);
+ op->op = genop_i_put_tuple_2;
+ op->a[0] = Dst;
+ op->a[1].type = TAG_u;
+ op->a[1].val = arity + 1;
+ for (i = 0; i < arity; i++) {
+ op->a[i+2] = Puts[i];
+ }
+ op->a[arity+2] = S;
+ return op;
+}
+
+
/*
* Freeze the code in memory, move the string table into place,