Add peephole optimizer for newarray(2)/expandarray(2, 0) -> swap
An optimization for multiple assignment in the popped case to avoid array allocation was lost in my fix to make multiple assignment follow left-to-right evaluation (50c54d40a81bb2a4794a6be5f1861152900b4fed). Before, in the two element case, swap was used. Afterward, newarray(2) and expandarray(2, 0) were used, which is the same as swap, with the addition of an unnecessary allocation. Because this issue is not specific to multiple assignment, and the multiple assignment code is complex enough as it is, this updates the peephole optimizer to do the newarray(2)/expandarray(2, 0) -> swap conversion. A more general optimization pass for newarray(X)/expandarray(X, 0) -> reverse(X) will follow, but that requires readding the reverse instruction.
This commit is contained in:
parent
3569d13095
commit
9f8abd28ba
Notes:
git
2022-08-10 14:20:08 +09:00
19
compile.c
19
compile.c
@ -3332,6 +3332,25 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_INSN_ID(iobj, newarray)) {
|
||||
LINK_ELEMENT *next = iobj->link.next;
|
||||
if (IS_INSN(next) && IS_INSN_ID(next, expandarray) &&
|
||||
OPERAND_AT(iobj, 0) == OPERAND_AT(next, 0) &&
|
||||
OPERAND_AT(next, 1) == INT2FIX(0)) {
|
||||
/*
|
||||
* newarray 2
|
||||
* expandarray 2, 0
|
||||
* =>
|
||||
* swap
|
||||
*/
|
||||
if (OPERAND_AT(iobj, 0) == INT2FIX(2)) {
|
||||
ELEM_REMOVE(next);
|
||||
INSN_OF(iobj) = BIN(swap);
|
||||
iobj->operand_size = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_INSN_ID(iobj, anytostring)) {
|
||||
LINK_ELEMENT *next = iobj->link.next;
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user