public function process(GraphState $state) { $graph = $state->getGraph(); $vars = Helper::findVariables($graph); $postdominator = $state->getPostDominator(); $dominator = $state->getDominator(); foreach ($vars as $var) { $usages = []; foreach ($graph->vertices() as $vertex) { if (in_array($var, $vertex->getVariables(), true)) { $usages[] = $vertex; } } $dom = $postdominator->immediateDominatorArray($usages); while ($dom) { foreach ($usages as $usage) { if ($dominator->strictlyDominates($usage, $dom)) { $dom = $postdominator->immediateDominator($dom); continue 2; } } break; } if (!$dom) { continue; } if ($dom instanceof Jump || $dom instanceof JumpZ) { Helper::insertBefore($dom, new Free($var), $graph); } else { Helper::insertAfter($dom, new Free($var), $graph); } } }
public function implementSSA(Variable $old, Variable $new, Vertex $vertex, Digraph $graph, \SplObjectStorage $phiNodes, array $args) { if ($this->stack->contains($vertex)) { if (isset($phiNodes[$vertex])) { // we've visited, so it **must** have a node implemented $phiNodes[$vertex]->addValue($new); } return; } $this->stack->attach($vertex); if ($old !== $new && !$vertex instanceof Phi) { $vertex->replaceVariable($old, $new); } if ($vertex instanceof JitAssignment && $vertex->getResult() === $old) { $new = new Variable($new->getType()); $vertex->setResult($new); } if (isset($phiNodes[$vertex])) { if ($phiNodes[$vertex] === true) { // insert phiNode $next = new Variable(); $phi = new Phi($next); $phiNodes[$vertex] = $phi; if ($old !== $new || in_array($old, $args, true)) { $phiNodes[$vertex]->addValue($new); } Helper::insertAfter($vertex, $phiNodes[$vertex], $graph); $new = $next; } else { $phiNodes[$vertex]->addValue($new); } } foreach ($graph->successorsOf($vertex) as $sub) { // Depth first search $this->implementSSA($old, $new, $sub, $graph, $phiNodes, $args); } }
/** * @covers ::insertAfter */ public function testInsertAfterDouble() { Helper::insertAfter($this->v[1], $this->v[6], $this->graph); $adj = $this->getValues($this->graph->successorsOf($this->v[1])); $this->assertEquals(1, count($adj)); $this->assertSame($this->v[6], $adj[0]); $adj = $this->getValues($this->graph->successorsOf($this->v[6])); $this->assertEquals(2, count($adj)); $this->assertSame($this->v[2], $adj[0]); $this->assertSame($this->v[3], $adj[1]); }