Skip to content

Commit e9f6863

Browse files
tekknolagik0kubun
authored andcommitted
Make NewArray DCE-able
Initialize with a vector of operands instead of ArraySet instructions.
1 parent 1826c2d commit e9f6863

File tree

1 file changed

+52
-23
lines changed

1 file changed

+52
-23
lines changed

zjit/src/hir.rs

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ pub enum Insn {
283283
StringCopy { val: InsnId },
284284
StringIntern { val: InsnId },
285285

286-
NewArray { count: usize },
286+
NewArray { elements: Vec<InsnId> },
287287
ArraySet { array: InsnId, idx: usize, val: InsnId },
288288
ArrayDup { val: InsnId },
289289

@@ -409,7 +409,15 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> {
409409
match &self.inner {
410410
Insn::Const { val } => { write!(f, "Const {}", val.print(&self.ptr_map)) }
411411
Insn::Param { idx } => { write!(f, "Param {idx}") }
412-
Insn::NewArray { count } => { write!(f, "NewArray {count}") }
412+
Insn::NewArray { elements } => {
413+
write!(f, "NewArray")?;
414+
let mut prefix = " ";
415+
for element in elements {
416+
write!(f, "{prefix}{element}")?;
417+
prefix = ", ";
418+
}
419+
Ok(())
420+
}
413421
Insn::ArraySet { array, idx, val } => { write!(f, "ArraySet {array}, {idx}, {val}") }
414422
Insn::ArrayDup { val } => { write!(f, "ArrayDup {val}") }
415423
Insn::StringCopy { val } => { write!(f, "StringCopy {val}") }
@@ -1468,11 +1476,12 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
14681476
}
14691477
YARVINSN_newarray => {
14701478
let count = get_arg(pc, 0).as_usize();
1471-
let array = fun.push_insn(block, Insn::NewArray { count });
1472-
for idx in (0..count).rev() {
1473-
fun.push_insn(block, Insn::ArraySet { array, idx, val: state.stack_pop()? });
1479+
let mut elements = vec![];
1480+
for _ in 0..count {
1481+
elements.push(state.stack_pop()?);
14741482
}
1475-
state.stack_push(array);
1483+
elements.reverse();
1484+
state.stack_push(fun.push_insn(block, Insn::NewArray { elements }));
14761485
}
14771486
YARVINSN_duparray => {
14781487
let val = fun.push_insn(block, Insn::Const { val: Const::Value(get_arg(pc, 0)) });
@@ -1870,14 +1879,14 @@ mod infer_tests {
18701879
#[test]
18711880
fn newarray() {
18721881
let mut function = Function::new(std::ptr::null());
1873-
let val = function.push_insn(function.entry_block, Insn::NewArray { count: 0 });
1882+
let val = function.push_insn(function.entry_block, Insn::NewArray { elements: vec![] });
18741883
assert_bit_equal(function.infer_type(val), types::ArrayExact);
18751884
}
18761885

18771886
#[test]
18781887
fn arraydup() {
18791888
let mut function = Function::new(std::ptr::null());
1880-
let arr = function.push_insn(function.entry_block, Insn::NewArray { count: 0 });
1889+
let arr = function.push_insn(function.entry_block, Insn::NewArray { elements: vec![] });
18811890
let val = function.push_insn(function.entry_block, Insn::ArrayDup { val: arr });
18821891
assert_bit_equal(function.infer_type(val), types::ArrayExact);
18831892
}
@@ -1990,11 +1999,33 @@ mod tests {
19901999
assert_method_hir("test", expect![[r#"
19912000
fn test:
19922001
bb0():
1993-
v1:ArrayExact = NewArray 0
2002+
v1:ArrayExact = NewArray
19942003
Return v1
19952004
"#]]);
19962005
}
19972006

2007+
#[test]
2008+
fn test_new_array_with_element() {
2009+
eval("def test(a) = [a]");
2010+
assert_method_hir("test", expect![[r#"
2011+
fn test:
2012+
bb0(v0:BasicObject):
2013+
v2:ArrayExact = NewArray v0
2014+
Return v2
2015+
"#]]);
2016+
}
2017+
2018+
#[test]
2019+
fn test_new_array_with_elements() {
2020+
eval("def test(a, b) = [a, b]");
2021+
assert_method_hir("test", expect![[r#"
2022+
fn test:
2023+
bb0(v0:BasicObject, v1:BasicObject):
2024+
v3:ArrayExact = NewArray v0, v1
2025+
Return v3
2026+
"#]]);
2027+
}
2028+
19982029
#[test]
19992030
fn test_array_dup() {
20002031
eval("def test = [1, 2, 3]");
@@ -2782,38 +2813,36 @@ mod opt_tests {
27822813
}
27832814

27842815
#[test]
2785-
fn test_eliminate_array_dup() {
2816+
fn test_eliminate_new_array_with_elements() {
27862817
eval("
2787-
def test
2788-
c = [1, 2]
2818+
def test(a)
2819+
c = [a]
27892820
5
27902821
end
2791-
test; test
2822+
test(1); test(2)
27922823
");
27932824
assert_optimized_method_hir("test", expect![[r#"
27942825
fn test:
2795-
bb0():
2826+
bb0(v0:BasicObject):
27962827
v4:Fixnum[5] = Const Value(5)
27972828
Return v4
27982829
"#]]);
27992830
}
28002831

28012832
#[test]
2802-
fn test_do_not_eliminate_array_set() {
2833+
fn test_eliminate_array_dup() {
28032834
eval("
2804-
def test(a)
2805-
c = [a]
2835+
def test
2836+
c = [1, 2]
28062837
5
28072838
end
2808-
test(3); test(4)
2839+
test; test
28092840
");
28102841
assert_optimized_method_hir("test", expect![[r#"
28112842
fn test:
2812-
bb0(v0:BasicObject):
2813-
v3:ArrayExact = NewArray 1
2814-
ArraySet v3, 0, v0
2815-
v5:Fixnum[5] = Const Value(5)
2816-
Return v5
2843+
bb0():
2844+
v4:Fixnum[5] = Const Value(5)
2845+
Return v4
28172846
"#]]);
28182847
}
28192848

0 commit comments

Comments
 (0)