Skip to content

Commit

Permalink
Make first parameter of substitute by-name; fixes bug with SC-backend
Browse files Browse the repository at this point in the history
Issue was that what was passed to `substitute` escaped to the outer
scope when using PardisIR; we need to enclose it into a block so that
does not happen…

This change is not necessarily something useful in general; it may be 
better to revert it once PardisIR is phased out (by-name params are more
expensive)
  • Loading branch information
LPTK committed May 31, 2017
1 parent 65771b1 commit fd6a0db
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 12 deletions.
2 changes: 1 addition & 1 deletion core/src/main/scala/squid/ir/BaseInterpreter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ class BaseInterpreter extends Base with RuntimeSymbols with TraceDebug {
}
def hole(name: String, typ: TypeRep): Rep = ???
def splicedHole(name: String, typ: TypeRep): Rep = ???
def substitute(r: Rep,defs: scala.collection.immutable.Map[String,Rep]): Rep = ???
def substitute(r: => Rep,defs: scala.collection.immutable.Map[String,Rep]): Rep = ???
def typeHole(name: String): TypeRep = ???


Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/squid/quasi/MetaBases.scala
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ trait MetaBases {
def hole(name: String, typ: TypeRep): Rep = q"$Base.hole($name, $typ)"
def splicedHole(name: String, typ: TypeRep): Rep = q"$Base.splicedHole($name, $typ)"

def substitute(r: Rep, defs: Map[String, Rep]): Rep =
def substitute(r: => Rep, defs: Map[String, Rep]): Rep =
//if (defs isEmpty) r else // <- This "optimization" is not welcome, as some IRs (ANF) may relie on `substitute` being called for all insertions
q"$Base.substitute($r, ..${defs map {case (name, rep) => q"$name -> $rep"}})"
/*
Expand Down Expand Up @@ -312,7 +312,7 @@ trait MetaBases {
def hole(name: String, typ: TypeRep): Rep = q"${TermName(name)}" // TODO ensure hygiene... (this should not clash!)
def splicedHole(name: String, typ: TypeRep): Rep = q"${TermName(name)}: _*"

def substitute(r: Rep, defs: Map[String, Rep]): Rep = r transform {
def substitute(r: => Rep, defs: Map[String, Rep]): Rep = r transform {
//case h @ q"${TermName(name)}" => // Weird! this does not seem to match...
case h @ Ident(TermName(name)) =>
defs.getOrElse(name, h)
Expand Down
6 changes: 3 additions & 3 deletions core/src/main/scala/squid/quasi/QuasiBase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ self: Base =>
// TODO impl correctly
//def substitute(r: Rep, defs: Map[String, Rep]): Rep = substituteLazy(r, defs map (kv => kv._1 -> (() => kv._2)))
//def substituteLazy(r: Rep, defs: Map[String, () => Rep]): Rep
def substitute(r: Rep, defs: Map[String, Rep]): Rep
def substituteLazy(r: Rep, defs: Map[String, () => Rep]): Rep = substitute(r, defs map (kv => kv._1 -> kv._2()))
def substitute(r: => Rep, defs: Map[String, Rep]): Rep
def substituteLazy(r: => Rep, defs: Map[String, () => Rep]): Rep = substitute(r, defs map (kv => kv._1 -> kv._2()))

def hole(name: String, typ: TypeRep): Rep
def splicedHole(name: String, typ: TypeRep): Rep
Expand All @@ -42,7 +42,7 @@ self: Base =>
/* --- --- --- Provided defs --- --- --- */


final def substitute(r: Rep, defs: (String, Rep)*): Rep =
final def substitute(r: => Rep, defs: (String, Rep)*): Rep =
/* if (defs isEmpty) r else */ // <- This "optimization" is not welcome, as some IRs (ANF) may relie on `substitute` being called for all insertions
substitute(r, defs.toMap)

Expand Down
10 changes: 6 additions & 4 deletions sc-backend/src/main/scala/squid/scback/PardisIR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,14 @@ abstract class PardisIR(val sc: pardis.ir.Base) extends Base with squid.ir.Runti
protected def inlineUnlessEnclosedOr(dontInline: Bool)(r: Rep) = r |>=? {
case b: Block if !dontInline => inlineBlockIfEnclosed(b)
}
override def substitute(r: Rep, defs: Map[String, Rep]): Rep = substituteLazy(r, defs.mapValues(() => _))
override def substituteLazy(r: Rep, defs: Map[String, () => Rep]): Rep = {
override def substitute(r: => Rep, defs: Map[String, Rep]): Rep = substituteLazy(r, defs.mapValues(() => _))
override def substituteLazy(mkR: => Rep, defs: Map[String, () => Rep]): Rep = {
val r = if (defs isEmpty) mkR else typedBlock(mkR |> toExpr)
//debug(s"SUBST $r with "+(defs mapValues (f=>util.Try(typedBlock(f())))))

val nameMap = curSubs collect { case k -> Hole(n,_,_) => k -> n }

if (defs isEmpty) r else bottomUp(r) {
val res = if (defs isEmpty) r else bottomUp(r) {
case h @ Hole(n,_,_) => defs get n map (_()) getOrElse h
case h @ SplicedHole(n,_) => defs get n map (_()) getOrElse h
case s: Sym =>
Expand All @@ -294,7 +295,8 @@ abstract class PardisIR(val sc: pardis.ir.Base) extends Base with squid.ir.Runti
case r => r
}

} |> inlineUnlessEnclosedOr(r.isInstanceOf[PardisBlock[_]]) alsoApply (r => debug(s"SUBS RESULT = $r"))
res |> inlineUnlessEnclosedOr(r.isInstanceOf[PardisBlock[_]]) alsoApply (r => debug(s"SUBS RESULT = $r"))
}

def hole(name: String, typ: TypeRep): Rep = Hole(name, typ, None)
def splicedHole(name: String, typ: TypeRep): Rep = SplicedHole(name, typ)
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/squid/ir/AST.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ trait AST extends InspectableBase with ScalaTyping with ASTReinterpreter with Ru
case r => r
}

override def substituteLazy(r: Rep, defs: Map[String, () => Rep]): Rep = if (defs isEmpty) r else bottomUp(r) { r => dfn(r) match {
override def substituteLazy(r: => Rep, defs: Map[String, () => Rep]): Rep = if (defs isEmpty) r else bottomUp(r) { r => dfn(r) match {
case h @ Hole(n) => defs get n map (_()) getOrElse r
case h @ SplicedHole(n) => defs get n map (_()) getOrElse r
case _ => r
}}
override def substitute(r: Rep, defs: Map[String, Rep]): Rep = if (defs isEmpty) r else bottomUp(r) { r => dfn(r) match {
override def substitute(r: => Rep, defs: Map[String, Rep]): Rep = if (defs isEmpty) r else bottomUp(r) { r => dfn(r) match {
case h @ Hole(n) => defs getOrElse (n, r)
case h @ SplicedHole(n) => defs getOrElse (n, r)
case _ => r
Expand Down

0 comments on commit fd6a0db

Please sign in to comment.