summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorJohn Hawthorn <john@hawthorn.email>2022-08-25 15:01:27 -0700
committerJohn Hawthorn <john@hawthorn.email>2022-09-01 17:36:20 -0700
commitfc2d9fedc2cc21f25608034518d75a8337301e9a (patch)
treefe45fd92072f05d8954fddb329568eb3265334cb /compile.c
parent3401e58f23eb05e40cda67e111a1bb4c382619f5 (diff)
Use getblockparamproxy with branch
A common pattern when the block is an explicit parameter is to branch based on the block parameter instead of using `block_given?`, for example `block.call if block`. This commit checks in the peephole optimizer for that case and uses the getblockparamproxy optimization, which avoids allocating a proc for simple cases, whenever a getblockparam instruction is followed immediately by branchif or branchunless. ./miniruby --dump=insns -e 'def foo(&block); 123 if block; end' == disasm: #<ISeq:foo@-e:1 (1,0)-(1,34)> (catch: FALSE) local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: 0, kw: -1@-1, kwrest: -1]) [ 1] block@0<Block> 0000 getblockparamproxy block@0, 0 ( 1)[LiCa] 0003 branchunless 8 0005 putobject 123 0007 leave [Re] 0008 putnil 0009 leave [Re]
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6286
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/compile.c b/compile.c
index 95318ffa84..4db1440bfa 100644
--- a/compile.c
+++ b/compile.c
@@ -3614,6 +3614,12 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
}
}
+ if (IS_INSN_ID(iobj, getblockparam)) {
+ if (IS_NEXT_INSN_ID(&iobj->link, branchif) || IS_NEXT_INSN_ID(&iobj->link, branchunless)) {
+ iobj->insn_id = BIN(getblockparamproxy);
+ }
+ }
+
return COMPILE_OK;
}