Commits

Carl Friedrich Bolz committed f6b8d45

fully remove generalization_of, only leave in on VirtualState

  • Participants
  • Parent commits 25dfebb
  • Branches small-unroll-improvements

Comments (0)

Files changed (2)

File rpython/jit/metainterp/optimizeopt/test/test_virtualstate.py

 from rpython.jit.metainterp.optimizeopt.test.test_optimizeopt import FakeMetaInterpStaticData
 from rpython.jit.metainterp.resoperation import ResOperation, rop
 
-class TestBasic:
-    someptr1 = LLtypeMixin.myptr
-    someptr2 = LLtypeMixin.myptr2
+class BaseTestGenerateGuards(BaseTest):
 
-    def test_position_generalization(self):
-        def postest(info1, info2):
-            info1.position = 0
-            assert info1.generalization_of(info1, {}, {})
-            info2.position = 0
-            assert info1.generalization_of(info2, {}, {})
-            info2.position = 1
-            renum = {}
-            assert info1.generalization_of(info2, renum, {})
-            assert renum == {0:1}
-            assert info1.generalization_of(info2, {0:1}, {})
-            assert info1.generalization_of(info2, {1:1}, {})
-            bad = {}
-            assert not info1.generalization_of(info2, {0:0}, bad)
-            assert info1 in bad and info2 in bad
-
-        for BoxType in (BoxInt, BoxFloat, BoxPtr):
-            info1 = NotVirtualStateInfo(OptValue(BoxType()))
-            info2 = NotVirtualStateInfo(OptValue(BoxType()))
-            postest(info1, info2)
-            
-        info1, info2 = VArrayStateInfo(42), VArrayStateInfo(42)
-        info1.fieldstate = info2.fieldstate = []
-        postest(info1, info2)
-
-        info1, info2 = VStructStateInfo(42, []), VStructStateInfo(42, [])
-        info1.fieldstate = info2.fieldstate = []
-        postest(info1, info2)
-
-        info1, info2 = VirtualStateInfo(ConstInt(42), []), VirtualStateInfo(ConstInt(42), [])
-        info1.fieldstate = info2.fieldstate = []
-        postest(info1, info2)
-
-    def test_NotVirtualStateInfo_generalization(self):
-        def isgeneral(value1, value2):
-            info1 = NotVirtualStateInfo(value1)
-            info1.position = 0
-            info2 = NotVirtualStateInfo(value2)
-            info2.position = 0
-            return info1.generalization_of(info2, {}, {}, LLtypeMixin.cpu)
-
-        assert isgeneral(OptValue(BoxInt()), OptValue(ConstInt(7)))
-        assert not isgeneral(OptValue(ConstInt(7)), OptValue(BoxInt()))
-
-        ptr = OptValue(BoxPtr())
-        nonnull = OptValue(BoxPtr())
-        nonnull.make_nonnull(0)
-        knownclass = OptValue(BoxPtr())
-        clsbox = LLtypeMixin.cpu.ts.cls_of_box(BoxPtr(LLtypeMixin.myptr))
-        knownclass.make_constant_class(clsbox, 0)
-        const = OptValue(BoxPtr)
-        const.make_constant_class(clsbox, 0)
-        const.make_constant(ConstPtr(self.someptr1))
-        inorder = [ptr, nonnull, knownclass, const]
-        for i in range(len(inorder)):
-            for j in range(i, len(inorder)):
-                assert isgeneral(inorder[i], inorder[j])
-                if i != j:
-                    assert not isgeneral(inorder[j], inorder[i])
-
-        value1 = OptValue(BoxInt())
-        value2 = OptValue(BoxInt())
-        value2.intbound.make_lt(IntBound(10, 10))
-        assert isgeneral(value1, value2)
-        assert not isgeneral(value2, value1)
-
-        assert isgeneral(OptValue(ConstInt(7)), OptValue(ConstInt(7)))
-        S = lltype.GcStruct('S')
-        foo = lltype.malloc(S)
-        fooref = lltype.cast_opaque_ptr(llmemory.GCREF, foo)
-        assert isgeneral(OptValue(ConstPtr(fooref)),
-                         OptValue(ConstPtr(fooref)))
-
-        value1 = OptValue(BoxPtr())
-        value1.make_nonnull(None)
-        value2 = OptValue(ConstPtr(LLtypeMixin.nullptr))
-        assert not isgeneral(value1, value2)
-
-    def test_field_matching_generalization(self):
-        const1 = NotVirtualStateInfo(OptValue(ConstInt(1)))
-        const2 = NotVirtualStateInfo(OptValue(ConstInt(2)))
-        const1.position = const2.position = 1
-        assert not const1.generalization_of(const2, {}, {})
-        assert not const2.generalization_of(const1, {}, {})
-
-        def fldtst(info1, info2):
-            info1.position = info2.position = 0
-            info1.fieldstate = [const1]
-            info2.fieldstate = [const2]
-            assert not info1.generalization_of(info2, {}, {})
-            assert not info2.generalization_of(info1, {}, {})
-            assert info1.generalization_of(info1, {}, {})
-            assert info2.generalization_of(info2, {}, {})
-        fldtst(VArrayStateInfo(42), VArrayStateInfo(42))
-        fldtst(VStructStateInfo(42, [7]), VStructStateInfo(42, [7]))
-        fldtst(VirtualStateInfo(ConstInt(42), [7]), VirtualStateInfo(ConstInt(42), [7]))
-
-    def test_known_class_generalization(self):
-        knownclass1 = OptValue(BoxPtr())
-        knownclass1.make_constant_class(ConstPtr(self.someptr1), 0)
-        info1 = NotVirtualStateInfo(knownclass1)
-        info1.position = 0
-        knownclass2 = OptValue(BoxPtr())
-        knownclass2.make_constant_class(ConstPtr(self.someptr1), 0)
-        info2 = NotVirtualStateInfo(knownclass2)
-        info2.position = 0
-        assert info1.generalization_of(info2, {}, {})
-        assert info2.generalization_of(info1, {}, {})
-
-        knownclass3 = OptValue(BoxPtr())
-        knownclass3.make_constant_class(ConstPtr(self.someptr2), 0)
-        info3 = NotVirtualStateInfo(knownclass3)
-        info3.position = 0
-        assert not info1.generalization_of(info3, {}, {})
-        assert not info2.generalization_of(info3, {}, {})
-        assert not info3.generalization_of(info2, {}, {})
-        assert not info3.generalization_of(info1, {}, {})
-
-
-    def test_circular_generalization(self):
-        for info in (VArrayStateInfo(42), VStructStateInfo(42, [7]),
-                     VirtualStateInfo(ConstInt(42), [7])):
-            info.position = 0
-            info.fieldstate = [info]
-            assert info.generalization_of(info, {}, {})
-
-
-class BaseTestGenerateGuards(BaseTest):
     def _box_or_value(self, box_or_value=None):
         if box_or_value is None:
             return None, None
         assert equaloplists(guards, loop.operations, False,
                             boxmap)
 
-    def check_no_guards(self, info1, info2, box_or_value=None):
+    def check_no_guards(self, info1, info2, box_or_value=None, state=None):
         value, _ = self._box_or_value(box_or_value)
-        info1.position = info2.position = 0
-        state = GenerateGuardState(self.cpu)
+        if info1.position == -1:
+            info1.position = 0
+        if info2.position == -1:
+            info2.position = 0
+        if state is None:
+            state = GenerateGuardState(self.cpu)
         info1.generate_guards(info2, value, state)
         assert not state.extra_guards
+        return state
 
-    def check_invalid(self, info1, info2, box_or_value=None):
+    def check_invalid(self, info1, info2, box_or_value=None, state=None):
         value, _ = self._box_or_value(box_or_value)
-        info1.position = info2.position = 0
-        guards = []
+        if info1.position == -1:
+            info1.position = 0
+        if info2.position == -1:
+            info2.position = 0
+        if state is None:
+            state = GenerateGuardState(self.cpu)
         with py.test.raises(InvalidLoop):
-            state = GenerateGuardState(self.cpu)
             info1.generate_guards(info2, value, state)
 
-    def test_nonvirtual_all_combinations(self):
+
+    def test_position_generalization(self):
+        def postest(info1, info2):
+            info1.position = 0
+            self.check_no_guards(info1, info1)
+            info2.position = 0
+            self.check_no_guards(info1, info2)
+            info2.position = 1
+            state = self.check_no_guards(info1, info2)
+            assert state.renum == {0:1}
+
+            assert self.check_no_guards(info1, info2, state=state)
+
+            # feed fake renums
+            state.renum = {1: 1}
+            self.check_no_guards(info1, info2, state=state)
+
+            state.renum = {0: 0}
+            self.check_invalid(info1, info2, state=state)
+            assert info1 in state.bad and info2 in state.bad
+
+        for BoxType in (BoxInt, BoxFloat, BoxPtr):
+            info1 = NotVirtualStateInfo(OptValue(BoxType()))
+            info2 = NotVirtualStateInfo(OptValue(BoxType()))
+            postest(info1, info2)
+
+        info1, info2 = VArrayStateInfo(42), VArrayStateInfo(42)
+        info1.fieldstate = info2.fieldstate = []
+        postest(info1, info2)
+
+        info1, info2 = VStructStateInfo(42, []), VStructStateInfo(42, [])
+        info1.fieldstate = info2.fieldstate = []
+        postest(info1, info2)
+
+        info1, info2 = VirtualStateInfo(ConstInt(42), []), VirtualStateInfo(ConstInt(42), [])
+        info1.fieldstate = info2.fieldstate = []
+        postest(info1, info2)
+
+    def test_NotVirtualStateInfo_generalization(self):
+        def isgeneral(value1, value2):
+            info1 = NotVirtualStateInfo(value1)
+            info1.position = 0
+            info2 = NotVirtualStateInfo(value2)
+            info2.position = 0
+            return VirtualState([info1]).generalization_of(VirtualState([info2]), cpu=self.cpu)
+
+        assert isgeneral(OptValue(BoxInt()), OptValue(ConstInt(7)))
+        assert not isgeneral(OptValue(ConstInt(7)), OptValue(BoxInt()))
+
+        ptr = OptValue(BoxPtr())
+        nonnull = OptValue(BoxPtr())
+        nonnull.make_nonnull(0)
+        knownclass = OptValue(BoxPtr())
+        clsbox = self.cpu.ts.cls_of_box(BoxPtr(self.myptr))
+        knownclass.make_constant_class(clsbox, 0)
+        const = OptValue(BoxPtr)
+        const.make_constant_class(clsbox, 0)
+        const.make_constant(ConstPtr(self.myptr))
+        inorder = [ptr, nonnull, knownclass, const]
+        for i in range(len(inorder)):
+            for j in range(i, len(inorder)):
+                assert isgeneral(inorder[i], inorder[j])
+                if i != j:
+                    assert not isgeneral(inorder[j], inorder[i])
+
+        value1 = OptValue(BoxInt())
+        value2 = OptValue(BoxInt())
+        value2.intbound.make_lt(IntBound(10, 10))
+        assert isgeneral(value1, value2)
+        assert not isgeneral(value2, value1)
+
+        assert isgeneral(OptValue(ConstInt(7)), OptValue(ConstInt(7)))
+        S = lltype.GcStruct('S')
+        foo = lltype.malloc(S)
+        fooref = lltype.cast_opaque_ptr(llmemory.GCREF, foo)
+        assert isgeneral(OptValue(ConstPtr(fooref)),
+                         OptValue(ConstPtr(fooref)))
+
+        value1 = OptValue(BoxPtr())
+        value1.make_nonnull(None)
+        value2 = OptValue(ConstPtr(self.nullptr))
+        assert not isgeneral(value1, value2)
+
+    def test_field_matching_generalization(self):
+        const1 = NotVirtualStateInfo(OptValue(ConstInt(1)))
+        const2 = NotVirtualStateInfo(OptValue(ConstInt(2)))
+        const1.position = const2.position = 1
+        self.check_invalid(const1, const2)
+        self.check_invalid(const2, const1)
+
+        def fldtst(info1, info2):
+            info1.position = info2.position = 0
+            info1.fieldstate = [const1]
+            info2.fieldstate = [const2]
+            self.check_invalid(info1, info2)
+            self.check_invalid(info2, info1)
+            self.check_no_guards(info1, info1)
+            self.check_no_guards(info2, info2)
+        fldtst(VArrayStateInfo(42), VArrayStateInfo(42))
+        fldtst(VStructStateInfo(42, [7]), VStructStateInfo(42, [7]))
+        fldtst(VirtualStateInfo(ConstInt(42), [7]), VirtualStateInfo(ConstInt(42), [7]))
+
+    def test_known_class_generalization(self):
+        knownclass1 = OptValue(BoxPtr())
+        knownclass1.make_constant_class(ConstPtr(self.myptr), 0)
+        info1 = NotVirtualStateInfo(knownclass1)
+        info1.position = 0
+        knownclass2 = OptValue(BoxPtr())
+        knownclass2.make_constant_class(ConstPtr(self.myptr), 0)
+        info2 = NotVirtualStateInfo(knownclass2)
+        info2.position = 0
+        self.check_no_guards(info1, info2)
+        self.check_no_guards(info2, info1)
+
+        knownclass3 = OptValue(BoxPtr())
+        knownclass3.make_constant_class(ConstPtr(self.myptr2), 0)
+        info3 = NotVirtualStateInfo(knownclass3)
+        info3.position = 0
+        self.check_invalid(info1, info3)
+        self.check_invalid(info2, info3)
+        self.check_invalid(info3, info2)
+        self.check_invalid(info3, info1)
+
+
+    def test_circular_generalization(self):
+        for info in (VArrayStateInfo(42), VStructStateInfo(42, [7]),
+                     VirtualStateInfo(ConstInt(42), [7])):
+            info.position = 0
+            info.fieldstate = [info]
+            self.check_no_guards(info, info)
+
+
+    def test_generate_guards_nonvirtual_all_combinations(self):
         # set up infos
         unknown_val = OptValue(self.nodebox)
         unknownnull_val = OptValue(BoxPtr(self.nullptr))

File rpython/jit/metainterp/optimizeopt/virtualstate.py

 class AbstractVirtualStateInfo(resume.AbstractVirtualInfo):
     position = -1
 
-    def generalization_of(self, other, renum, bad, cpu=None):
-        # cpu can be None for testing only
-        guards = []
-        state = GenerateGuardState(cpu, guards, renum, bad)
-        try:
-            self.generate_guards(other, None, state)
-            assert not guards
-            return True
-        except InvalidLoop:
-            return False
-
     def generate_guards(self, other, value, state):
         """ generate guards (output in the list extra_guards) that make runtime
         values of the shape other match the shape of self. if that's not
             s.enum(self)
 
     def generalization_of(self, other, bad=None, cpu=None):
-        if bad is None:
-            bad = {}
+        state = GenerateGuardState(cpu=cpu, bad=bad)
         assert len(self.state) == len(other.state)
-        renum = {}
-        for i in range(len(self.state)):
-            if not self.state[i].generalization_of(other.state[i], renum, bad, cpu=None):
-                return False
+        try:
+            for i in range(len(self.state)):
+                self.state[i].generate_guards(other.state[i], None, state)
+        except InvalidLoop:
+            return False
         return True
 
     def generate_guards(self, other, values, cpu):