ensureArc() public method

public ensureArc ( $tail, $head )
Example #1
0
 /**
  * @covers ::generateText
  * @covers ::convertGraph
  */
 public function testGenerateText()
 {
     $a = new DummyVertex('a');
     $b = new DummyVertex('b');
     $c = new DummyVertex('c');
     $graph = new DirectedAdjacencyList();
     $graph->ensureArc($a, $b);
     $graph->ensureArc($b, $c);
     $graph->ensureArc($c, $b);
     $printer = new GraphPrinter();
     $this->assertContains('node_0', $printer->generateText($graph));
 }
Example #2
0
 /**
  * @covers ::process
  */
 public function testExpansionFailure()
 {
     $graph = new DirectedAdjacencyList();
     $end = new End();
     $graph->ensureArc($end, $b = new JitBinaryOp(JitBinaryOp::PLUS, new Constant(1), new Variable(), new Variable()));
     $rule = new ConstBinaryOp();
     $this->assertFalse($rule->process($b, $graph));
 }
Example #3
0
 /**
  * @covers ::__construct
  * @covers ::getGraph
  * @covers ::getFunction
  * @covers ::getDominator
  * @covers ::getPostDominator
  * @covers ::getInverseGraph
  */
 public function testBasicUsage()
 {
     $func = new JitFunction([], new Type(0), $graph = new DirectedAdjacencyList());
     $graph->ensureArc($func, new End());
     $state = new GraphState($func);
     $this->assertSame($func, $state->getFunction());
     $this->assertSame($graph, $state->getGraph());
     $this->assertInstanceOf(Dominator::class, $state->getDominator());
     $this->assertInstanceOf(Dominator::class, $state->getPostDominator());
     $this->assertInstanceOf(DirectedAdjacencyList::class, $state->getInverseGraph());
 }
Example #4
0
    /**
     * @covers ::generateFunction
     * @covers ::generate
     */
    public function testGenerateFunctionReversedJumpZ()
    {
        $generator = new Generator();
        $graph = new DirectedAdjacencyList();
        $long = new Type(Type::TYPE_LONG);
        $double = new Type(Type::TYPE_DOUBLE);
        $func = new Vertex\Function_([$a = new Variable($long), $b = new Variable($double)], $double, $graph);
        $noOp = new Vertex\NoOp();
        $jumpz = new Vertex\JumpZ($noOp, $a);
        $end = new Vertex\End();
        $graph->ensureArc($func, $jumpz);
        $graph->ensureArc($jumpz, $r1 = new Vertex\Return_(new Constant(1.5)));
        $graph->ensureArc($jumpz, $noOp);
        $graph->ensureArc($r1, $end);
        $graph->ensureArc($noOp, $r2 = new Vertex\Return_($b));
        $graph->ensureArc($r2, $end);
        $expected = <<<'EOF'
function test123 double
param $1 long
param $2 double
begin
jumpz $1 @1
const $3 double 1.5
return $3
label @1
return $2
end
EOF;
        $this->assertEquals($expected, $generator->generateFunction('test123', $func));
    }
Example #5
0
 /**
  * @covers ::isLiveVar
  */
 public function testIsLiveVarWithCycleAndLaterValue()
 {
     $graph = new DirectedAdjacencyList();
     $var = new Variable();
     $vertex = $this->getMock(Vertex::class);
     $graph->ensureVertex($vertex);
     $vertex->expects($this->once())->method('getVariables')->will($this->returnValue([]));
     $v1 = $this->getMock(Vertex::class);
     $v1->expects($this->once())->method('getVariables')->will($this->returnValue([$var]));
     $graph->ensureArc($vertex, $v1);
     $this->assertTrue(Helper::isLiveVar($var, $vertex, $graph));
 }
Example #6
0
 /**
  * @covers ::process
  * @covers ::implementSSA
  */
 public function testOperationLoopWithPhi()
 {
     $graph = new DirectedAdjacencyList();
     $a = new Variable();
     $func = new Function_([$a], new Type(0), $graph);
     $start = new NoOp();
     $noOp = new NoOp();
     $jumpz = new JumpZ($noOp, $a);
     $graph->ensureArc($func, $start);
     $graph->ensureArc($start, $jumpz);
     $graph->ensureArc($jumpz, $r = new Return_($a));
     $graph->ensureArc($r, new End());
     $graph->ensureArc($jumpz, $binary = new BinaryOp(BinaryOp::PLUS, $a, new Constant(2), $a));
     $graph->ensureArc($binary, $j = new Jump());
     $graph->ensureArc($j, $start);
     $state = new GraphState($func);
     $compiler = new SSACompiler();
     $compiler->process($state);
     $this->assertSame([$a], $func->getArguments());
     $i = 0;
     foreach ($graph->successorsOf($start) as $v) {
         $this->assertEquals(0, $i++, 'More then one adjacent node');
         $this->assertInstanceOf(Phi::class, $v);
         $this->assertContains($a, $v->getValues());
         $this->assertSame($r->getValue(), $v->getResult());
     }
 }
Example #7
0
 public function checkForCircularReference(array $phiNodes, GraphState $state)
 {
     $graph = new DirectedAdjacencyList();
     foreach ($phiNodes as $phi) {
         $result = $phi->getResult();
         foreach ($phi->getValues() as $value) {
             $graph->ensureArc($value, $result);
         }
     }
     $cycles = $graph->getCycles();
     foreach ($cycles as $cycle) {
         if ($this->areAllUnknown($cycle)) {
             // All are unknown, process!
             $types = array();
             foreach ($cycle as $component) {
                 foreach (Helper::getInboundNodes($component, $graph) as $node) {
                     if (in_array($node, $cycle, true)) {
                         continue;
                     }
                     $types[] = $node->getType()->getType();
                 }
             }
             $types = array_unique($types);
             $newType = 0;
             switch (count($types)) {
                 case 1:
                     if ($types[0] != Type::TYPE_UNKNOWN) {
                         $newType = $types[0];
                     }
                     break;
                 case 2:
                     if (in_array(Type::TYPE_NUMERIC, $types) && in_array(Type::TYPE_LONG, $types)) {
                         $newType = Type::TYPE_NUMERIC;
                     } elseif (in_array(Type::TYPE_NUMERIC, $types) && in_array(Type::TYPE_DOUBLE, $types)) {
                         $newType = Type::TYPE_DOUBLE;
                     }
                     break;
             }
             if ($newType) {
                 foreach ($cycle as $component) {
                     $component->setType(new Type($newType));
                 }
                 return true;
             }
         }
     }
     return false;
 }