diff --git a/src/kirin/dialects/ilist/rewrite/inline_getitem.py b/src/kirin/dialects/ilist/rewrite/inline_getitem.py index a84612a44..c8b307d2a 100644 --- a/src/kirin/dialects/ilist/rewrite/inline_getitem.py +++ b/src/kirin/dialects/ilist/rewrite/inline_getitem.py @@ -25,6 +25,9 @@ def rewrite_Statement(self, node: ir.Statement) -> abc.RewriteResult: if not isinstance(index_const := node.index.hints.get("const"), const.Value): return abc.RewriteResult() + if not node.result.uses: + return abc.RewriteResult() + index = index_const.data if isinstance(index, int) and ( 0 <= index < len(stmt.args) or -len(stmt.args) <= index < 0 diff --git a/src/kirin/rewrite/getitem.py b/src/kirin/rewrite/getitem.py index 47c10c130..1126db75f 100644 --- a/src/kirin/rewrite/getitem.py +++ b/src/kirin/rewrite/getitem.py @@ -19,6 +19,9 @@ def rewrite_Statement(self, node: ir.Statement) -> RewriteResult: if not isinstance(index_value := node.index.hints.get("const"), const.Value): return RewriteResult() + if not node.result.uses: + return RewriteResult() + stmt = node.obj.owner index = index_value.data if isinstance(index, int) and ( diff --git a/test/dialects/ilist/test_inline_getitem.py b/test/dialects/ilist/test_inline_getitem.py index 119a87e82..c81490a51 100644 --- a/test/dialects/ilist/test_inline_getitem.py +++ b/test/dialects/ilist/test_inline_getitem.py @@ -95,3 +95,22 @@ def func(): after = func() assert before == after + + +def test_getitem_slice_does_nothing(): + """Test that inline_getiem returns `has_done_something=False` when the getitem + statement has no uses""" + + @basic_no_opt + def func(): + ylist = ilist.New(values=(0, 1, 2, 3, 4), elem_type=types.PyClass(int)) + ylist[0] # no use + return 1 + + constprop = const.Propagate(func.dialects) + frame, _ = constprop.run(func) + Fixpoint(Walk(WrapConst(frame))).rewrite(func.code) + + inline_getitem = InlineGetItem() + + assert not Walk(inline_getitem).rewrite(func.code).has_done_something diff --git a/test/dialects/test_ilist.py b/test/dialects/test_ilist.py index e36ae6168..4dffdaa2f 100644 --- a/test/dialects/test_ilist.py +++ b/test/dialects/test_ilist.py @@ -207,7 +207,8 @@ def test_inline_getitem_slice(): [ qreg := ilist.New(values=values), slice_value := py.Constant(slice(2, 5, 1)), - py.GetItem(obj=qreg.result, index=slice_value.result), + res := py.GetItem(obj=qreg.result, index=slice_value.result), + func.Return(res.result), ] ) slice_value.result.hints["const"] = const.Value(slice(2, 5, 1)) @@ -219,7 +220,8 @@ def test_inline_getitem_slice(): [ qreg := ilist.New(values=values), slice_value := py.Constant(slice(2, 5, 1)), - ilist.New(values=(values[2], values[3], values[4])), + res := ilist.New(values=(values[2], values[3], values[4])), + func.Return(res.result), ] ) assert test_block.is_structurally_equal(expected_block) diff --git a/test/rules/test_getitem.py b/test/rules/test_getitem.py index 76e7633de..0550771c4 100644 --- a/test/rules/test_getitem.py +++ b/test/rules/test_getitem.py @@ -92,3 +92,22 @@ def func(): after = func() assert before == after + + +def test_getitem_slice_does_nothing(): + """Test that inline_getiem returns `has_done_something=False` when the getitem + statement has no uses""" + + @basic_no_opt + def func(): + ylist = (0, 1, 2, 3, 4) + ylist[0] # no use + return 1 + + constprop = const.Propagate(func.dialects) + frame, _ = constprop.run(func) + Fixpoint(Walk(WrapConst(frame))).rewrite(func.code) + + inline_getitem = InlineGetItem() + + assert not Walk(inline_getitem).rewrite(func.code).has_done_something