public function process(Vertex $vertex, Digraph $graph) { if ($vertex instanceof Assignment && $vertex->isIdempotent() && 1 >= $this->countUsages($vertex->getResult(), $graph)) { Helper::remove($vertex, $graph); return true; } return false; }
public function process(Vertex $vertex, Digraph $graph) { if ($vertex->getName() === 'BooleanNot') { if ($vertex->getResult()->getType()->isUnknown() && !$vertex->getValue()->getType()->isUnknown()) { $vertex->getResult()->setType(new Type(Type::TYPE_BOOLEAN)); return true; } } return false; }
public function process(Vertex $vertex, Digraph $graph) { if ($vertex instanceof Vertex\FunctionCall) { if ($vertex->getResult()->getType()->isUnknown() && !$vertex->getSignature()->getReturn()->isUnknown()) { $vertex->getResult()->setType($vertex->getSignature()->getReturn()); return true; } } return false; }
public function process(Vertex $vertex, Digraph $graph) { if ($vertex instanceof Vertex\Phi) { $types = []; foreach ($vertex->getValues() as $value) { $types[] = (string) $value->getType(); } $types = array_unique($types); if ($vertex->getResult()->getType()->isUnknown()) { $type = null; $setAll = false; if (count($types) === 1 && $types[0] !== 'unknown') { $type = Type::normalizeType($types[0]); } elseif (count($types) === 2 && in_array('long', $types) && in_array('numeric', $types)) { $type = new Type(Type::TYPE_LONG); $setAll = true; } elseif (count($types) === 2 && in_array('double', $types) && in_array('numeric', $types)) { $type = new Type(Type::TYPE_DOUBLE); $setAll = true; } elseif (count($types) === 2 && in_array('bool', $types) && in_array('numeric', $types)) { $type = new Type(Type::TYPE_BOOLEAN); } if ($type) { $vertex->getResult()->setType($type); if ($setAll) { foreach ($vertex->getValues() as $value) { $value->setType($type); } } return true; } } if (count($vertex->getValues()) === 1) { // remove phi node list($val) = iterator_to_array($vertex->getValues()); $result = $vertex->getResult(); foreach ($graph->vertices() as $vtx) { $vtx->replaceVariable($result, $val); if ($vtx instanceof Assignment && $vtx->getResult() === $result) { $vtx->setResult($val); } } Helper::remove($vertex, $graph); return true; } } return false; }
public function process(Vertex $vertex, Digraph $graph) { if ($vertex->getName() === 'Assign') { if ($vertex->getResult()->getType()->isUnknown() && !$vertex->getValue()->getType()->isUnknown()) { $vertex->getResult()->setType($vertex->getValue()->getType()); return true; } } return false; }
public function process(Vertex $vertex, Digraph $graph) { if ($vertex->getName() === 'BitwiseNot') { if ($vertex->getResult()->getType()->isUnknown() && !$vertex->getValue()->getType()->isUnknown()) { if ($vertex->getValue()->getType()->getType() === Type::TYPE_STRING) { $vertex->getResult()->setType(new Type(Type::TYPE_STRING)); } else { $vertex->getResult()->setType(new Type(Type::TYPE_LONG)); } return true; } } return false; }
public function getVarStub(Vertex $vertex, \StdClass $state) { $output = ''; $varStub = ''; foreach ($vertex->getVariables() as $var) { if (!isset($state->scope[$var])) { $state->scope[$var] = ++$state->varidx; if ($var instanceof Constant) { $value = $var->getValue(); if ('string' == (string) $var->getType()) { $value = base64_encode($value); } $varStub .= 'const $' . $state->scope[$var] . ' ' . $var->getType() . ' ' . $value . "\n"; } elseif ($vertex instanceof Vertex\Function_) { $varStub .= 'param $' . $state->scope[$var] . ' ' . $var->getType() . "\n"; } else { $varStub .= 'var $' . $state->scope[$var] . ' ' . $var->getType() . "\n"; } } $output .= ' $' . $state->scope[$var]; } return [$output, $varStub]; }
public function process(Vertex $vertex, Digraph $graph) { if ($vertex instanceof JitBinaryOp && $vertex->getA() instanceof Constant && $vertex->getB() instanceof Constant) { $ret = null; switch ($vertex->getKind()) { case JitBinaryOp::CONCAT: $ret = $vertex->getA()->getValue() . $vertex->getB()->getValue(); break; case JitBinaryOp::PLUS: $ret = $vertex->getA()->getValue() + $vertex->getB()->getValue(); break; case JitBinaryOp::MINUS: $ret = $vertex->getA()->getValue() - $vertex->getB()->getValue(); break; case JitBinaryOp::MUL: $ret = $vertex->getA()->getValue() * $vertex->getB()->getValue(); break; case JitBinaryOp::DIV: $ret = $vertex->getA()->getValue() / $vertex->getB()->getValue(); break; case JitBinaryOp::MOD: $ret = $vertex->getA()->getValue() % $vertex->getB()->getValue(); break; case JitBinaryOp::EQUAL: $ret = $vertex->getA()->getValue() == $vertex->getB()->getValue(); break; case JitBinaryOp::NOT_EQUAL: $ret = $vertex->getA()->getValue() != $vertex->getB()->getValue(); break; case JitBinaryOp::IDENTICAL: $ret = $vertex->getA()->getValue() == $vertex->getB()->getValue(); break; case JitBinaryOp::NOT_IDENTICAL: $ret = $vertex->getA()->getValue() !== $vertex->getB()->getValue(); break; case JitBinaryOp::GREATER: $ret = $vertex->getA()->getValue() > $vertex->getB()->getValue(); break; case JitBinaryOp::GREATER_EQUAL: $ret = $vertex->getA()->getValue() >= $vertex->getB()->getValue(); break; case JitBinaryOp::SMALLER: $ret = $vertex->getA()->getValue() < $vertex->getB()->getValue(); break; case JitBinaryOp::SMALLER_EQUAL: $ret = $vertex->getA()->getValue() <= $vertex->getB()->getValue(); break; case JitBinaryOp::BITWISE_AND: $ret = $vertex->getA()->getValue() & $vertex->getB()->getValue(); break; case JitBinaryOp::BITWISE_OR: $ret = $vertex->getA()->getValue() | $vertex->getB()->getValue(); break; case JitBinaryOp::BITWISE_XOR: $ret = $vertex->getA()->getValue() ^ $vertex->getB()->getValue(); break; case JitBinaryOp::SHIFT_LEFT: $ret = $vertex->getA()->getValue() << $vertex->getB()->getValue(); break; case JitBinaryOp::SHIFT_RIGHT: $ret = $vertex->getA()->getValue() >> $vertex->getB()->getValue(); break; } // replace binary op with assign op Helper::replace($vertex, new JitAssign(new Constant($ret), $vertex->getResult()), $graph); return true; } return false; }
public function process(Vertex $vertex, Digraph $graph) { if ($vertex->getName() !== 'BinaryOp') { return false; } $result = $vertex->getResult(); $rType = $result->getType(); if ($rType->isUnknown() || $rType->getType() === Type::TYPE_NUMERIC) { $typePair = [$vertex->getA()->getType()->getType(), $vertex->getB()->getType()->getType()]; $newType = Type::TYPE_UNKNOWN; switch ($vertex->getKind()) { case JitBinaryOp::PLUS: case JitBinaryOp::MINUS: case JitBinaryOp::MUL: switch ($typePair) { case [Type::TYPE_LONG, Type::TYPE_LONG]: $newType = Type::TYPE_NUMERIC; break; case [Type::TYPE_DOUBLE, Type::TYPE_LONG]: case [Type::TYPE_LONG, Type::TYPE_DOUBLE]: case [Type::TYPE_DOUBLE, Type::TYPE_NUMERIC]: case [Type::TYPE_NUMERIC, Type::TYPE_DOUBLE]: case [Type::TYPE_DOUBLE, Type::TYPE_DOUBLE]: $newType = Type::TYPE_DOUBLE; break; case [Type::TYPE_NUMERIC, Type::TYPE_NUMERIC]: case [Type::TYPE_NUMERIC, Type::TYPE_LONG]: case [Type::TYPE_LONG, Type::TYPE_NUMERIC]: $newType = Type::TYPE_NUMERIC; break; default: if (in_array(Type::TYPE_DOUBLE, $typePair)) { $newType = Type::TYPE_DOUBLE; } else { $newType = Type::TYPE_NUMERIC; } } break; case JitBinaryOp::DIV: $newType = Type::TYPE_DOUBLE; break; case JitBinaryOp::EQUAL: case JitBinaryOp::NOT_EQUAL: case JitBinaryOp::IDENTICAL: case JitBinaryOp::NOT_IDENTICAL: case JitBinaryOp::GREATER: case JitBinaryOp::GREATER_EQUAL: case JitBinaryOp::SMALLER: case JitBinaryOp::SMALLER_EQUAL: $newType = Type::TYPE_BOOLEAN; break; case JitBinaryOp::BITWISE_AND: case JitBinaryOp::BITWISE_OR: case JitBinaryOp::BITWISE_XOR: if ($typePair === [Type::TYPE_STRING, Type::TYPE_STRING]) { $newType = Type::TYPE_STRING; break; } // Fallthrough intentional // Fallthrough intentional case JitBinaryOp::SHIFT_LEFT: case JitBinaryOp::SHIFT_RIGHT: $newType = Type::TYPE_LONG; break; } if ($newType !== Type::TYPE_UNKNOWN && $newType !== $rType->getType()) { $result->setType(new Type($newType)); return true; } } return false; }