text: from pypy.translator.backendopt.ssa import *
  from pypy.translator.translator import TranslationContext
  from pypy.objspace.flow.model import flatten, Block, Link, Variable, Constant
  from pypy.objspace.flow.model import SpaceOperation
  
  
  def test_data_flow_families():
      def snippet_fn(xx, yy):
          while yy > 0:
              if 0 < xx:
                  yy = yy - xx
              else:
                  yy = yy + xx
          return yy
      t = TranslationContext()
      graph = t.buildflowgraph(snippet_fn)
      operations = []
      for block in graph.iterblocks():
          operations += block.operations
  
      variable_families = DataFlowFamilyBuilder(graph).get_variable_families()
  
      # we expect to find xx only once:
      v_xx = variable_families.find_rep(graph.getargs()[0])
      found = 0
      for op in operations:
          if op.opname in ('add', 'sub', 'lt'):
              assert variable_families.find_rep(op.args[1]) == v_xx
              found += 1
      assert found == 3
  
  
  def test_SSI_to_SSA():
      def snippet_fn(v1, v2, v3):
          if v1:                             # v4 = is_true(v1)
              while v3:                      # v5 = is_true(v3)
                  pass
              passed_over = 0
          else:
              v6 = snippet_fn(v3, v2, v1)    # v6 = simple_call(v3, v2, v1)
              passed_over = v6
          v7 = passed_over                   # v7 = inputarg
          return v7+v1                       # v8 = add(v7, v1)
  
      t = TranslationContext()
      graph = t.buildflowgraph(snippet_fn)
      SSI_to_SSA(graph)
      allvars = []
      for block in graph.iterblocks():
              allvars += [v.name for v in block.getvariables()]
      # see comments above for where the 8 remaining variables are expected to be
      assert len(dict.fromkeys(allvars)) == 8
  
  
  def test_SSA_to_SSI():
      c = Variable('c')
      x = Variable('x')
      y = Variable('y')
      b1 = Block([c])
      b2 = Block([x])
      b3 = Block([])
  
      b2.operations.append(SpaceOperation('add', [x, c], y))
      b2.exitswitch = y
  
      b1.closeblock(Link([Constant(0)], b2))
      b2.closeblock(Link([y], b2), Link([], b3))
      b3.closeblock(Link([y, c], None))
  
      SSA_to_SSI({b1: True,     # reachable from outside
                  b2: False,
                  b3: False})
  
      assert len(b1.inputargs) == 1
      assert len(b2.inputargs) == 2
      assert len(b3.inputargs) == 2
  
      assert b2.inputargs == b2.operations[0].args
      assert len(b1.exits[0].args) == 2
      assert b1.exits[0].args[1] is c
      assert len(b2.exits[0].args) == 2
      assert b2.exits[0].args == [y, b2.inputargs[1]]
      assert len(b2.exits[1].args) == 2
      assert len(b3.exits[0].args) == 2
  
      index = b3.inputargs.index(b3.exits[0].args[0])
      assert b2.exits[1].args[index] is b2.operations[0].result
  
      index = b3.inputargs.index(b3.exits[0].args[1])
      assert b2.exits[1].args[index] is b2.inputargs[1]
  
  
  def test_SSA_to_SSI_2():
      x = Variable('x')
      y = Variable('y')
      z = Variable('z')
      b1 = Block([x])
      b2 = Block([y])
      b3 = Block([])
  
      b3.operations.append(SpaceOperation('hello', [y], z))
      b1.closeblock(Link([x], b2), Link([], b3))
  
      SSA_to_SSI({b1: True,     # reachable from outside
                  b2: False,
                  b3: False})
  
      assert b1.inputargs == [x]
      assert b2.inputargs == [y]
      assert b3.inputargs == [b3.operations[0].args[0]]
      assert b1.exits[0].args == [x]
      assert b1.exits[1].args == [x]
  