summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro Matsumoto <[email protected]>2012-08-02 13:13:41 +0900
committerYukihiro Matsumoto <[email protected]>2012-08-02 13:13:41 +0900
commita7f0e3bc8081f30bbcfe0058824a4edae7ea7af4 (patch)
tree961603dc33d78e3a3c2a2bb7670008d8802e5445
parent91318da3bc2f7465ed490544afb531041aa4a092 (diff)
downloadmruby-a7f0e3bc8081f30bbcfe0058824a4edae7ea7af4.tar.gz
mruby-a7f0e3bc8081f30bbcfe0058824a4edae7ea7af4.zip
small return optimization: use R0 to set return value if possible
-rw-r--r--src/codegen.c65
1 files changed, 58 insertions, 7 deletions
diff --git a/src/codegen.c b/src/codegen.c
index 321223d9d..0d4de9734 100644
--- a/src/codegen.c
+++ b/src/codegen.c
@@ -244,6 +244,51 @@ genop_peep(codegen_scope *s, mrb_code i, int val)
return;
}
break;
+ case OP_RETURN:
+ switch (c0) {
+ case OP_MOVE:
+ s->iseq[s->pc-1] = MKOP_AB(OP_MOVE, 0, GETARG_B(i0));
+ genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+ return;
+ case OP_LOADI:
+ s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, 0, GETARG_sBx(i0));
+ genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+ return;
+ case OP_ARRAY:
+ case OP_HASH:
+ case OP_RANGE:
+ case OP_AREF:
+ case OP_GETUPVAR:
+ s->iseq[s->pc-1] = MKOP_ABC(c0, 0, GETARG_B(i0), GETARG_C(i0));
+ genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+ return;
+ case OP_LOADSYM:
+ case OP_GETGLOBAL:
+ case OP_GETIV:
+ case OP_GETCV:
+ case OP_GETCONST:
+ case OP_GETSPECIAL:
+ case OP_LOADL:
+ case OP_STRING:
+ s->iseq[s->pc-1] = MKOP_ABx(c0, 0, GETARG_Bx(i0));
+ genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+ return;
+ case OP_SCLASS:
+ s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0));
+ genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+ return;
+ case OP_LOADNIL:
+ case OP_LOADSELF:
+ case OP_LOADT:
+ case OP_LOADF:
+ case OP_OCLASS:
+ s->iseq[s->pc-1] = MKOP_A(c0, 0);
+ genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+ return;
+ default:
+ break;
+ }
+ break;
default:
break;
}
@@ -427,7 +472,7 @@ for_body(codegen_scope *s, node *tree)
pop();
c = s->iseq[s->pc-1];
if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) {
- genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL));
+ genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
loop_pop(s, NOVAL);
scope_finish(s, idx);
@@ -510,9 +555,12 @@ lambda_body(codegen_scope *s, node *tree, int blk)
c = s->iseq[s->pc-1];
if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) {
if (s->nregs == 0) {
- genop(s, MKOP_A(OP_LOADNIL, cursp()));
+ genop(s, MKOP_A(OP_LOADNIL, 0));
+ genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+ }
+ else {
+ genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
- genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL));
}
if (blk) {
loop_pop(s, NOVAL);
@@ -535,9 +583,12 @@ scope_body(codegen_scope *s, node *tree)
else {
pop_(scope);
if (scope->nregs == 0) {
- genop(scope, MKOP_A(OP_LOADNIL, scope->sp));
+ genop(scope, MKOP_A(OP_LOADNIL, 0));
+ genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
+ }
+ else {
+ genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp, OP_R_NORMAL), NOVAL);
}
- genop(scope, MKOP_AB(OP_RETURN, scope->sp, OP_R_NORMAL));
}
scope_finish(scope, idx);
@@ -1397,7 +1448,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN));
}
else {
- genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL));
+ genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
break;
@@ -1449,7 +1500,7 @@ codegen(codegen_scope *s, node *tree, int val)
else {
codegen(s, tree, VAL);
pop();
- genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL));
+ genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
}
if (val) push();
break;