Пример #1
0
 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);
         }
     }
 }
Пример #2
0
 /**
  * Actually run the optimization rules over the graph.
  *
  * This will re-run the optimizers if anything was changed in a run. This
  * allows for optimizations to happen in any order, and for one optimization
  * to open the door to another.
  *
  * Unfortunately, this also makes this process EXTREMELY expensive.
  *
  * This is O(scary).
  */
 public function process(GraphState $state)
 {
     $graph = $state->getGraph();
     do {
         $rerun = false;
         foreach ($graph->vertices() as $vertex) {
             foreach ($this->rules as $rule) {
                 $rerun = $rerun || $rule->process($vertex, $graph);
             }
         }
     } while ($rerun);
 }
Пример #3
0
 public function removePhi(Phi $vertex, GraphState $state)
 {
     $graph = $state->getGraph();
     Helper::remove($vertex, $graph);
     $to = $vertex->getResult();
     foreach ($vertex->getValues() as $value) {
         foreach ($graph->vertices() as $v) {
             $v->replaceVariable($value, $to);
             if ($v instanceof Assignment && $v->getResult() === $value) {
                 $v->setResult($to);
             }
         }
     }
 }
Пример #4
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());
 }
Пример #5
0
 public function process(GraphState $state)
 {
     $graph = $state->getGraph();
     $assignments = array_merge(Helper::findVerticesByClass(JitAssignment::class, $graph), [$state->getFunction()]);
     $vars = Helper::findVariables($graph);
     $dominator = $state->getDominator();
     foreach ($vars as $var) {
         $hash = spl_object_hash($var);
         $varAssignments = $this->findAssignmentsByVar($var, $assignments);
         $phi = $this->findPhiNodes($var, $varAssignments, $dominator, $graph);
         $this->implementSSA($var, $var, $state->getFunction(), $graph, $phi, $state->getFunction()->getArguments());
         $this->stack->removeAll($this->stack);
     }
 }