Skip to content

Commit

Permalink
perf(compiler): Inliner optimization [LNG-322] (#1047)
Browse files Browse the repository at this point in the history
  • Loading branch information
DieMyst authored Jan 22, 2024
1 parent 27704a9 commit abcb63d
Show file tree
Hide file tree
Showing 20 changed files with 309 additions and 207 deletions.
7 changes: 4 additions & 3 deletions api/api/.jvm/src/main/scala/aqua/api/Test.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,23 @@ import aqua.compiler.AquaCompiled
import aqua.files.FileModuleId

import cats.data.Chain
import cats.data.Validated.{Invalid, Valid}
import cats.effect.{IO, IOApp}
import fs2.io.file.{Files, Path}
import fs2.{Stream, text}

object Test extends IOApp.Simple {

override def run: IO[Unit] = {

APICompilation
.compilePath(
"./aqua-src/antithesis.aqua",
Imports.fromMap(Map("/" -> Map("" -> List("./aqua")))),
AquaAPIConfig(targetType = TypeScriptType),
TypeScriptBackend(false, "IFluenceClient$$")
)
.flatMap { res =>
).timed
.flatMap { case (duration, res) =>
println("Compilation time: " + duration.toMillis)
val (warnings, result) = res.value.run

IO.delay {
Expand Down
55 changes: 24 additions & 31 deletions aqua-src/antithesis.aqua
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
aqua M

export bugLng317
export returnSrvAsAbility

service MyOp("op"):
identity(s: string) -> string
ability MyAb:
call() -> string

ability WorkerJob:
runOnSingleWorker(w: string) -> []string
service MySrv("default-id"):
call() -> string

func runJob(j: -> []string) -> []string:
<- j()
func mySrvDefault() -> MyAb:
<- MySrv

func disjoint_run{WorkerJob}() -> -> []string:
run = func () -> []string:
r <- WorkerJob.runOnSingleWorker("a")
<- r
<- run
func mySrvResolved() -> MyAb:
MySrv "resolved-id"
<- MySrv

func empty() -> string:
a = "empty"
<- a
func mySrvThird() -> MyAb:
MySrv "third-id"
<- MySrv

func bugLng317() -> []string:
func useMyAb{MyAb}() -> string:
<- MyAb.call()

res: *string

outer = () -> string:
<- empty()

clos = () -> -> []string:
job2 = () -> []string:
res <- outer()
res <- MyOp.identity("identity")
<- res
<- job2
worker_job = WorkerJob(runOnSingleWorker = clos())
subnet_job <- disjoint_run{worker_job}()
finalRes <- runJob(subnet_job)
<- finalRes
func returnSrvAsAbility() -> []string:
result: *string
MySrvDefault <- mySrvDefault()
MySrvResolved <- mySrvResolved()
MySrvThird <- mySrvThird()
result <- useMyAb{MySrvDefault}()
result <- useMyAb{MySrvResolved}()
result <- useMyAb{MySrvThird}()
<- result
93 changes: 64 additions & 29 deletions backend/air/src/main/scala/aqua/backend/air/Air.scala
Original file line number Diff line number Diff line change
Expand Up @@ -120,42 +120,77 @@ object Air {

case class Comment(comment: String, air: Air) extends Air(Keyword.NA)

private def show(depth: Int, air: Air): String = {
def showNext(a: Air) = show(depth + 1, a)
private def showInternal(space: String, sb: StringBuilder, air: Air): Unit = {

val space = " " * depth
def showNext(a: Air): Unit = showInternal(space + " ", sb, a)

air match {
case Air.Comment(c, a) =>
space + "; " + c.replace("\n", "\n" + space + "; ") + "\n" +
show(depth, a)
sb.append(space)
.append("; ")
.append(c.replace("\n", "\n" + space + "; "))
.append("\n")

showInternal(space, sb, a)

case _ =>
s"$space(${air.keyword.value}" +
(air match {
case Air.Null ""
case Air.Never ""
case Air.Next(label) s" $label"
case Air.New(item, inst) s" ${item.show}\n${showNext(inst)}$space"
case Air.Fold(iter, label, inst, lastInst)
val l = show(depth + 1, lastInst)
s" ${iter.show} $label\n${showNext(inst)}$l$space"
case Air.Match(left, right, inst)
s" ${left.show} ${right.show}\n${showNext(inst)}$space"
case Air.Mismatch(left, right, inst)
s" ${left.show} ${right.show}\n${showNext(inst)}$space"
case Air.Par(l, r) s"\n${showNext(l)}${showNext(r)}$space"
case Air.Seq(l, r) s"\n${showNext(l)}${showNext(r)}$space"
case Air.Xor(l, r) s"\n${showNext(l)}${showNext(r)}$space"
case Air.Call(triplet, args, res)
s" ${triplet.show} [${args.map(_.show).mkString(" ")}]${res.fold("")(" " + _)}"
case Air.Ap(operand, result) s" ${operand.show} $result"
case Air.ApStreamMap(key, operand, result) s" (${key.show} ${operand.show}) $result"
case Air.Fail(operand) => s" ${operand.show}"
case Air.Canon(operand, peerId, result) s" ${peerId.show} ${operand.show} $result"
case Air.Comment(_, _) => ";; Should not be displayed"
}) + ")\n"
sb.append(s"$space(${air.keyword.value}")
(air match {
case Air.Null
case Air.Never
case Air.Next(label) sb.append(s" $label")
case Air.New(item, inst)
sb.append(s" ${item.show}\n")
showNext(inst)
sb.append(space)
case Air.Fold(iter, label, inst, lastInst)
sb.append(" ").append(s" ${iter.show} $label\n")
showNext(inst)
showNext(lastInst)
sb.append(space)
case Air.Match(left, right, inst)
sb.append(s" ${left.show} ${right.show}\n")
showNext(inst)
sb.append(space)
case Air.Mismatch(left, right, inst)
sb.append(s" ${left.show} ${right.show}\n")
showNext(inst)
sb.append(space)
case Air.Par(l, r)
sb.append("\n")
showNext(l)
showNext(r)
sb.append(space)
case Air.Seq(l, r)
sb.append("\n")
showNext(l)
showNext(r)
sb.append(space)
case Air.Xor(l, r)
sb.append("\n")
showNext(l)
showNext(r)
sb.append(space)
case Air.Call(triplet, args, res)
sb.append(s" ${triplet.show} [${args.map(_.show).mkString(" ")}]${res.fold("")(" " + _)}")
case Air.Ap(operand, result)
sb.append(s" ${operand.show} $result")
case Air.ApStreamMap(key, operand, result)
sb.append(s" (${key.show} ${operand.show}) $result")
case Air.Fail(operand) => sb.append(s" ${operand.show}")
case Air.Canon(operand, peerId, result)
sb.append(s" ${peerId.show} ${operand.show} $result")
case Air.Comment(_, _) => ";; Should not be displayed"
})
sb.append(")\n")
}
}

private def show(depth: Int, air: Air): String = {
val sb = StringBuilder()
val space = " " * depth
showInternal(space, sb, air)
sb.result()
}

implicit val s: Show[Air] = Show.show(show(0, _))
Expand Down
15 changes: 13 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ lazy val inline = crossProject(JVMPlatform, JSPlatform)
.crossType(CrossType.Pure)
.in(file("model/inline"))
.settings(commons)
.dependsOn(raw, model)
.dependsOn(raw, model, mangler)

lazy val transform = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
Expand All @@ -207,7 +207,7 @@ lazy val semantics = crossProject(JVMPlatform, JSPlatform)
"dev.optics" %%% "monocle-macro" % monocleV
)
)
.dependsOn(raw, parser, errors)
.dependsOn(raw, parser, errors, mangler)

lazy val compiler = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
Expand Down Expand Up @@ -253,6 +253,17 @@ lazy val logging = crossProject(JVMPlatform, JSPlatform)
)
)

lazy val mangler = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
.in(file("utils/mangler"))
.settings(commons)
.settings(
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-core" % catsV
)
)

lazy val constants = crossProject(JVMPlatform, JSPlatform)
.withoutSuffixFor(JVMPlatform)
.crossType(CrossType.Pure)
Expand Down
17 changes: 3 additions & 14 deletions compiler/src/main/scala/aqua/compiler/AquaCompiler.scala
Original file line number Diff line number Diff line change
@@ -1,30 +1,19 @@
package aqua.compiler

import aqua.backend.Backend
import aqua.compiler.AquaError.{ParserError as AquaParserError, *}
import aqua.linker.{AquaModule, Linker, Modules}
import aqua.model.AquaContext
import aqua.parser.lift.{LiftParser, Span}
import aqua.parser.{Ast, ParserError}
import aqua.raw.RawPart.Parts
import aqua.raw.{RawContext, RawPart}
import aqua.res.AquaRes
import aqua.semantics.header.{HeaderHandler, HeaderSem, Picker}
import aqua.semantics.{CompilerState, Semantics}
import aqua.semantics.{SemanticError, SemanticWarning}
import aqua.semantics.header.{HeaderHandler, Picker}
import aqua.semantics.{SemanticError, Semantics}

import cats.arrow.FunctionK
import cats.data.*
import cats.data.Validated.{Invalid, Valid, validNec}
import cats.parse.Parser0
import cats.syntax.applicative.*
import cats.syntax.either.*
import cats.syntax.flatMap.*
import cats.syntax.functor.*
import cats.syntax.monoid.*
import cats.syntax.semigroup.*
import cats.syntax.traverse.*
import cats.{Comonad, Functor, Monad, Monoid, Order, ~>}
import cats.{Comonad, Monad, Monoid, Order, ~>}
import scribe.Logging

class AquaCompiler[F[_]: Monad, E, I: Order, S[_]: Comonad, C: Monoid: Picker](
Expand Down
21 changes: 5 additions & 16 deletions compiler/src/main/scala/aqua/compiler/CompilerAPI.scala
Original file line number Diff line number Diff line change
@@ -1,33 +1,22 @@
package aqua.compiler

import aqua.backend.Backend
import aqua.compiler.AquaError.*
import aqua.backend.{AirFunction, Backend}
import aqua.linker.{AquaModule, Linker, Modules}
import aqua.model.AquaContext
import aqua.parser.lift.{LiftParser, Span}
import aqua.parser.{Ast, ParserError}
import aqua.raw.RawPart.Parts
import aqua.raw.{RawContext, RawPart}
import aqua.res.AquaRes
import aqua.raw.RawContext
import aqua.semantics.RawSemantics
import aqua.semantics.header.{HeaderHandler, HeaderSem}
import aqua.semantics.{CompilerState, RawSemantics, Semantics}

import cats.data.*
import cats.data.Validated.{invalid, validNec, Invalid, Valid}
import cats.parse.Parser0
import cats.syntax.applicative.*
import cats.syntax.either.*
import cats.syntax.flatMap.*
import cats.syntax.foldable.*
import cats.syntax.functor.*
import cats.syntax.monoid.*
import cats.syntax.semigroup.*
import cats.syntax.traverse.*
import cats.syntax.either.*
import cats.{~>, Comonad, Monad, Monoid, Order}
import cats.{Comonad, Monad, Monoid, Order}
import scribe.Logging

import scala.collection.MapView

object CompilerAPI extends Logging {

private def toAquaProcessed[I: Order, E, S[_]: Comonad](
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package aqua.model.inline.state

import aqua.mangler.ManglerState
import aqua.model.{FuncArrow, ValueModel}
import aqua.model.inline.state.{Arrows, Counter, Exports, Mangler}
import aqua.raw.arrow.FuncRaw
Expand All @@ -23,7 +24,7 @@ import scribe.Logging
* for [[Counter]]
*/
case class InliningState(
noNames: Set[String] = Set.empty,
noNames: ManglerState = ManglerState(),
resolvedExports: Map[String, ValueModel] = Map.empty,
resolvedArrows: Map[String, FuncArrow] = Map.empty,
instructionCounter: Int = 0
Expand All @@ -35,7 +36,7 @@ object InliningState {
Counter.Simple.transformS(_.instructionCounter, (acc, i) => acc.copy(instructionCounter = i))

given Mangler[InliningState] =
Mangler.Simple.transformS(_.noNames, (acc, nn) => acc.copy(noNames = nn))
Mangler[ManglerState].transformS(_.noNames, (acc, nn) => acc.copy(noNames = nn))

given Arrows[InliningState] =
Arrows.Simple.transformS(_.resolvedArrows, (acc, aa) => acc.copy(resolvedArrows = aa))
Expand Down
Loading

0 comments on commit abcb63d

Please sign in to comment.