Esempio n. 1
0
    def test_constrained_move(self):
        """ Test a constrained move.

            Do this by creating two pre-colored registers. Move one
            and add the other with the copy of the first.

            The move can then not be coalesced, and will be frozen.
        """
        f = Frame('tst')
        t1 = R0
        t2 = R0
        t3 = ExampleRegister('t3')
        t4 = ExampleRegister('t4')
        f.instructions.append(Def(t1))
        move = Mov(t3, t1, ismove=True)
        f.instructions.append(move)
        f.instructions.append(Def(t2))
        f.instructions.append(Add(t4, t2, t3))
        f.instructions.append(Use(t4))
        self.register_allocator.alloc_frame(f)

        # Check t1 and t2 are pre-colored:
        self.assertEqual({self.register_allocator.node(R0)},
                         self.register_allocator.precolored)
        self.assertEqual(set(), self.register_allocator.coalescedMoves)
        self.assertEqual({move}, self.register_allocator.constrainedMoves)
        self.conflict(t2, t3)
        self.assertEqual(set(), self.register_allocator.frozenMoves)
        self.assertIn(move, f.instructions)
Esempio n. 2
0
 def test_register_allocation(self):
     f = Frame('tst')
     t1 = ExampleRegister('t1')
     t2 = ExampleRegister('t2')
     t3 = ExampleRegister('t3')
     t4 = ExampleRegister('t4')
     t5 = ExampleRegister('t5')
     f.instructions.append(Def(t1))
     f.instructions.append(Def(t2))
     f.instructions.append(Def(t3))
     f.instructions.append(Add(t4, t1, t2))
     f.instructions.append(Add(t5, t4, t3))
     f.instructions.append(Use(t5))
     self.register_allocator.alloc_frame(f)
     self.conflict(t1, t2)
     self.conflict(t2, t3)
Esempio n. 3
0
 def test_register_coalescing(self):
     """ Register coalescing happens when a move can be eliminated """
     f = Frame('tst')
     t1 = ExampleRegister('t1')
     t2 = ExampleRegister('t2')
     t3 = ExampleRegister('t3')
     t4 = ExampleRegister('t4')
     t5 = ExampleRegister('t5')
     t6 = ExampleRegister('t6')
     f.instructions.append(Def(t1))
     f.instructions.append(Def(t2))
     f.instructions.append(Def(t3))
     f.instructions.append(Add(t4, t2, t1))
     f.instructions.append(Mov(t5, t3))
     f.instructions.append(Add(t5, t4, t5))
     f.instructions.append(Mov(t6, t5))
     f.instructions.append(Use(t6))
     self.register_allocator.alloc_frame(f)
     self.conflict(t1, t2)
     self.conflict(t2, t3)
     self.conflict(t1, t3)
Esempio n. 4
0
    def test_freeze(self):
        """ Create a situation where no select and no coalesc is possible
        """
        f = Frame('tst')
        t4 = ExampleRegister('t4')
        t5 = ExampleRegister('t5')
        f.instructions.append(Def(R0))
        move = Mov(R1, R0, ismove=True)
        f.instructions.append(move)
        f.instructions.append(Def(t4))
        f.instructions.append(Add(t5, t4, R1))
        f.instructions.append(Use(t5))
        self.register_allocator.alloc_frame(f)

        self.assertEqual(set(), self.register_allocator.coalescedMoves)
        # self.assertEqual({move}, self.register_allocator.frozenMoves)
        self.conflict(R1, R0)
Esempio n. 5
0
    def test_multiple_successors(self):
        """ Example from wikipedia about liveness """
        a = ExampleRegister('a')
        b = ExampleRegister('b')
        c = ExampleRegister('c')
        d = ExampleRegister('d')
        x = ExampleRegister('x')
        i1 = Def(a)  # a = 3
        i2 = Def(b)  # b = 5
        i3 = Def(d)  # d = 4
        i4 = Def(x)  # x = 100
        i6 = Add(c, a, b)  # c = a + b
        i8 = Def(c)  # c = 4
        i7 = Def(d, jumps=[i8])  # d = 2
        i9 = Use3(b, d, c)  # return b * d + c
        i5 = Cmp(a, b, jumps=[i6, i8])  # if a > b
        instrs = [i1, i2, i3, i4, i5, i6, i7, i8, i9]
        cfg = FlowGraph(instrs)
        cfg.calculate_liveness()

        # Get blocks:
        b1 = cfg.get_node(i1)
        b2 = cfg.get_node(i6)
        b3 = cfg.get_node(i8)
        # Should be 3 nodes:
        self.assertEqual(3, len(cfg))

        # Check successors:
        self.assertEqual({b2, b3}, b1.successors)
        self.assertEqual({b3}, b2.successors)
        self.assertEqual(set(), b3.successors)

        # Check predecessors:
        self.assertEqual(set(), b1.predecessors)
        self.assertEqual({b1}, b2.predecessors)
        self.assertEqual({b2, b1}, b3.predecessors)

        # Check block 1:
        self.assertEqual(5, len(b1.instructions))
        self.assertEqual(set(), b1.gen)
        self.assertEqual({a, b, d, x}, b1.kill)

        # Check block 2 gen and killl:
        self.assertEqual(2, len(b2.instructions))
        self.assertEqual({a, b}, b2.gen)
        self.assertEqual({c, d}, b2.kill)

        # Check block 3:
        self.assertEqual(2, len(b3.instructions))
        self.assertEqual({b, d}, b3.gen)
        self.assertEqual({c}, b3.kill)

        # Check block 1 live in and out:
        self.assertEqual(set(), b1.live_in)
        self.assertEqual({a, b, d}, b1.live_out)

        # Check block 2:
        self.assertEqual({a, b}, b2.live_in)
        self.assertEqual({b, d}, b2.live_out)

        # Check block 3:
        self.assertEqual({b, d}, b3.live_in)
        self.assertEqual(set(), b3.live_out)

        # Create interference graph:
        ig = InterferenceGraph()
        ig.calculate_interference(cfg)