Skip to content

Commit b1b2c08

Browse files
author
Alexey Romanov
committed
Combine lhs and mhs in TTP
1 parent 80fdb75 commit b1b2c08

18 files changed

+160
-139
lines changed

src/common/IfThenElse.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,14 @@ trait BaseGenIfThenElseFat extends BaseGenIfThenElse with GenericFatCodegen {
211211
import IR._
212212

213213
override def fatten(e: Stm): Stm = e match {
214-
case TP(sym, o: AbstractIfThenElse[_]) =>
215-
TTP(List(sym), List(o), SimpleFatIfThenElse(o.cond, List(o.thenp), List(o.elsep)))
216-
case TP(sym, p @ Reflect(o: AbstractIfThenElse[_], u, es)) => //if !u.maySimple && !u.mayGlobal => // contrary, fusing will not change observable order
214+
case tp @ TP(sym, o: AbstractIfThenElse[_]) =>
215+
TTP(List(tp), SimpleFatIfThenElse(o.cond, List(o.thenp), List(o.elsep)))
216+
case tp @ TP(sym, p @ Reflect(o: AbstractIfThenElse[_], u, es)) => //if !u.maySimple && !u.mayGlobal => // contrary, fusing will not change observable order
217217
// assume body will reflect, too...
218218
printdbg("-- fatten effectful if/then/else " + e)
219219
val e2 = SimpleFatIfThenElse(o.cond, List(o.thenp), List(o.elsep))
220220
e2.extradeps = es //HACK
221-
TTP(List(sym), List(p), e2)
221+
TTP(List(tp), e2)
222222
case _ => super.fatten(e)
223223
}
224224
}

src/common/LoopFusionOpt.scala

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
269269
val levelScope = getExactScope(currentScope)(result) // could provide as input ...
270270
// TODO: cannot in general fuse several effect loops (one effectful and several pure ones is ok though)
271271
// so we need a strategy. a simple one would be exclude all effectful loops right away (TODO).
272-
levelScope collect { case e @ TTP(_, _, SimpleFatLoop(_,_,_)) => e }
272+
levelScope collect { case e @ TTP(_, SimpleFatLoop(_,_,_)) => e }
273273
}
274274

275275
// FIXME: more than one super call means exponential cost -- is there a better way?
@@ -284,7 +284,7 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
284284
var done = false
285285

286286
// keep track of loops in inner scopes
287-
var UloopSyms = currentScope collect { case e @ TTP(lhs, _, SimpleFatLoop(_,_,_)) if !Wloops.contains(e) => lhs }
287+
var UloopSyms = currentScope collect { case e @ TTP(_, SimpleFatLoop(_,_,_)) if !Wloops.contains(e) => e.lhs }
288288

289289
//do{
290290

@@ -367,7 +367,7 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
367367
var partitionsIn = Wloops
368368
var partitionsOut = Nil:List[Stm]
369369

370-
for (b@ TTP(_,_,_) <- partitionsIn) {
370+
for (b@ TTP(_,_) <- partitionsIn) {
371371
// try to add to an item in partitionsOut, if not possible add as-is
372372
partitionsOut.find(a => canFuse(a,b)) match {
373373
case Some(a: TTP) =>
@@ -394,13 +394,14 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
394394
shapeA
395395
}
396396

397-
val lhs = a.lhs ++ b.lhs
397+
val tps = a.tps ++ b.tps
398398

399-
val fused = TTP(lhs, a.mhs ++ b.mhs, SimpleFatLoop(shape, targetVar, WgetLoopRes(a):::WgetLoopRes(b)))
399+
val fused = TTP(tps, SimpleFatLoop(shape, targetVar, WgetLoopRes(a):::WgetLoopRes(b)))
400400
partitionsOut = fused :: (partitionsOut diff List(a))
401401

402-
val preNeg = WtableNeg collect { case p if (lhs contains p._2) => p._1 }
403-
val postNeg = WtableNeg collect { case p if (lhs contains p._1) => p._2 }
402+
val syms = tps.map(_.sym).toSet
403+
val preNeg = WtableNeg collect { case p if (syms contains p._2) => p._1 }
404+
val postNeg = WtableNeg collect { case p if (syms contains p._1) => p._2 }
404405

405406
val fusedNeg = preNeg flatMap { s1 => postNeg map { s2 => (s1,s2) } }
406407
WtableNeg = (fusedNeg ++ WtableNeg).distinct
@@ -461,10 +462,10 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
461462

462463
// prune Wloops (some might be no longer necessary)
463464
Wloops = pOutT map {
464-
case TTP(lhs, mhs, SimpleFatLoop(s, x, rhs)) =>
465-
val ex = lhs map (s => currentScope exists (_.lhs contains s))
465+
case TTP(tps, SimpleFatLoop(s, x, rhs)) =>
466+
val ex = tps map (s => currentScope exists (_.lhs contains s.sym))
466467
def select[A](a: List[A], b: List[Boolean]) = (a zip b) collect { case (w, true) => w }
467-
TTP(select(lhs, ex), select(mhs, ex), SimpleFatLoop(s, x, select(rhs, ex)))
468+
TTP(select(tps, ex), SimpleFatLoop(s, x, select(rhs, ex)))
468469
}
469470

470471
currentScope = (currentScope diff pInT) ++ Wloops
@@ -520,7 +521,7 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
520521
val levelScope = getExactScope(currentScope)(result) // could provide as input ...
521522
// TODO: cannot in general fuse several effect loops (one effectful and several pure ones is ok though)
522523
// so we need a strategy. a simple one would be exclude all effectful loops right away (TODO).
523-
levelScope collect { case e @ TTP(_, _, SimpleFatLoop(_,_,_)) => e }
524+
levelScope collect { case e @ TTP(_, SimpleFatLoop(_,_,_)) => e }
524525
}
525526
526527
// FIXME: more than one super call means exponential cost -- is there a better way?
@@ -535,7 +536,7 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
535536
var done = false
536537
537538
// keep track of loops in inner scopes
538-
var UloopSyms = currentScope collect { case e @ TTP(lhs, _, SimpleFatLoop(_,_,_)) if !Wloops.contains(e) => lhs }
539+
var UloopSyms = currentScope collect { case e @ TTP(lhs, SimpleFatLoop(_,_,_)) if !Wloops.contains(e) => lhs.map(_.sym) }
539540
540541
do {
541542
// utils
@@ -630,7 +631,7 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
630631
var partitionsIn = Wloops
631632
var partitionsOut = Nil:List[Stm]
632633
633-
for (b@ TTP(_,_,_) <- partitionsIn) {
634+
for (b@ TTP(_,_) <- partitionsIn) {
634635
// try to add to an item in partitionsOut, if not possible add as-is
635636
partitionsOut.find(a => canFuse(a,b)) match {
636637
case Some(a: TTP) =>
@@ -659,11 +660,12 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
659660
660661
val lhs = a.lhs ++ b.lhs
661662
662-
val fused = TTP(lhs, a.mhs ++ b.mhs, SimpleFatLoop(shape, targetVar, WgetLoopRes(a):::WgetLoopRes(b)))
663+
val fused = TTP(lhs, SimpleFatLoop(shape, targetVar, WgetLoopRes(a):::WgetLoopRes(b)))
663664
partitionsOut = fused :: (partitionsOut diff List(a))
664665
665-
val preNeg = WtableNeg collect { case p if (lhs contains p._2) => p._1 }
666-
val postNeg = WtableNeg collect { case p if (lhs contains p._1) => p._2 }
666+
val syms = lhs.map(_.sym).toSet
667+
val preNeg = WtableNeg collect { case p if (syms contains p._2) => p._1 }
668+
val postNeg = WtableNeg collect { case p if (syms contains p._1) => p._2 }
667669
668670
val fusedNeg = preNeg flatMap { s1 => postNeg map { s2 => (s1,s2) } }
669671
WtableNeg = (fusedNeg ++ WtableNeg).distinct
@@ -722,19 +724,19 @@ trait LoopFusionCore extends internal.FatScheduling with CodeMotion with Simplif
722724
723725
// prune Wloops (some might be no longer necessary)
724726
Wloops = Wloops map {
725-
case TTP(lhs, mhs, SimpleFatLoop(s, x, rhs)) =>
726-
val ex = lhs map (s => currentScope exists (_.lhs == List(s)))
727+
case TTP(lhs, SimpleFatLoop(s, x, rhs)) =>
728+
val ex = lhs map (s => currentScope exists (_.lhs == List(s.sym)))
727729
def select[A](a: List[A], b: List[Boolean]) = (a zip b) collect { case (w, true) => w }
728-
TTP(select(lhs, ex), select(mhs, ex), SimpleFatLoop(s, x, select(rhs, ex)))
730+
TTP(select(lhs, ex), SimpleFatLoop(s, x, select(rhs, ex)))
729731
}
730732
731733
// PREVIOUS PROBLEM: don't throw out all loops, might have some that are *not* in levelScope
732734
// note: if we don't do it here, we will likely see a problem going back to innerScope in
733735
// FatCodegen.focusExactScopeFat below. --> how to go back from SimpleFatLoop to VectorPlus??
734736
// UPDATE: UloopSyms puts a tentative fix in place. check if it is sufficient!!
735737
// what is the reason we cannot just look at Wloops??
736-
currentScope = currentScope.filter { case e@TTP(lhs, _, _: AbstractFatLoop) =>
737-
val keep = UloopSyms contains lhs
738+
currentScope = currentScope.filter { case e@TTP(lhs, _: AbstractFatLoop) =>
739+
val keep = UloopSyms contains lhs.map(_.sym)
738740
//if (!keep) println("dropping: " + e + ", not int UloopSyms: " + UloopSyms)
739741
keep case _ => true } ::: Wloops
740742

src/common/Loops.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,11 @@ trait BaseLoopsTraversalFat extends FatBlockTraversal {
137137
import IR._
138138

139139
override def fatten(e: Stm): Stm = e match {
140-
case TP(sym, op: AbstractLoop[_]) =>
141-
TTP(List(sym), List(op), SimpleFatLoop(op.size, op.v, List(op.body)))
142-
case TP(sym, p @ Reflect(op: AbstractLoop[_], u, es)) if !u.maySimple && !u.mayGlobal => // assume body will reflect, too. bring it on...
140+
case tp @ TP(sym, op: AbstractLoop[_]) =>
141+
TTP(List(tp), SimpleFatLoop(op.size, op.v, List(op.body)))
142+
case tp @ TP(sym, p @ Reflect(op: AbstractLoop[_], u, es)) if !u.maySimple && !u.mayGlobal => // assume body will reflect, too. bring it on...
143143
printdbg("-- fatten effectful loop " + e)
144-
TTP(List(sym), List(p), SimpleFatLoop(op.size, op.v, List(op.body)))
144+
TTP(List(tp), SimpleFatLoop(op.size, op.v, List(op.body)))
145145
case _ => super.fatten(e)
146146
}
147147

src/common/SimplifyTransform.scala

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -106,65 +106,88 @@ trait SimplifyTransform extends internal.FatScheduling {
106106
case s: Sym[Any] => (Option(scopeIndex.get(s)) orElse findDefinition(s)).toList // check scope before target graph
107107
case _ => Nil
108108
}
109-
case TTP(lhs, mhs, SimpleFatIfThenElse(c,as,bs)) =>
109+
case TTP(tps, SimpleFatIfThenElse(c,as,bs)) =>
110110
// alternate strategy: transform thin def, then fatten again (a little detour)
111-
printdbg("need to transform rhs of fat if/then/else: " + lhs + ", if " + c + " then " + as + " else " + bs)
112-
val lhs2 = (lhs zip mhs).map { case (s,r) => transformOne(s, r, t) }.distinct.asInstanceOf[List[Sym[Any]]]
111+
val lhs1 = tps.map(_.sym)
112+
printdbg("need to transform rhs of fat if/then/else: " + lhs1 + ", if " + c + " then " + as + " else " + bs)
113+
val lhs2 = tps.map { case TP(s,r) => transformOne(s, r, t) }.distinct.asInstanceOf[List[Sym[Any]]]
113114
val mhs2 = lhs2.map(s => findDefinition(s).get.defines(s).get)
114115
// TBD: we're mirroring the defs in mhs, creating new stms
115116
// we don't really want new stms: if the defs are just abstract descriptions we only want them updated
116117

117118
// this means we'll have both a TP and a TTP defining the same sym in globalDefs --> bad!
118119
// not quite so fast, chances are the TTP's never make it into globalDefs (no toAtom call)!!!
119-
120-
if (lhs != lhs2) {
120+
121+
val lhsesAreDifferent = lhs1 != lhs2
122+
if (lhsesAreDifferent) {
121123
val missing = Nil//(lhs2.map(s => findDefinition(s).get) diff innerScope)
122-
printdbg("lhs changed! will add to innerScope: "+missing.mkString(","))
124+
printdbg("tps changed! will add to innerScope: "+missing.mkString(","))
123125
//innerScope = innerScope ::: missing
124126
}
125127

126128
def infix_toIf(d: Def[Any]) = d match {
127129
case l: AbstractIfThenElse[_] => l
128130
case Reflect(l: AbstractIfThenElse[_], _, _) => l
129131
}
130-
val cond2 = if (lhs != lhs2) mhs2.map (_.toIf.cond) reduceLeft { (s1,s2) => assert(s1==s2,"conditions don't agree: "+s1+","+s2); s1 }
131-
else t(c)
132-
val as2 = (if (lhs != lhs2) (lhs2 zip (mhs2 map (_.toIf.thenp)))
133-
else (lhs zip as)) map { case (s,r) => transformIfBody(s,r,t) }
134-
val bs2 = (if (lhs != lhs2) (lhs2 zip (mhs2 map (_.toIf.elsep)))
135-
else (lhs zip bs)) map { case (s,r) => transformIfBody(s,r,t) }
132+
def branches(ifDifferent: AbstractIfThenElse[_] => Block[_], ifSame: List[Block[_]]) = {
133+
val rhs2 = if (lhsesAreDifferent)
134+
mhs2.map(x => ifDifferent(x.toIf))
135+
else
136+
ifSame
137+
lhs2.zip(rhs2).map { case (s,r) => transformIfBody(s,r,t) }
138+
}
139+
140+
val cond2 = if (lhsesAreDifferent)
141+
mhs2.map(_.toIf.cond).reduceLeft { (s1,s2) =>
142+
assert(s1==s2,"conditions don't agree: "+s1+","+s2)
143+
s1
144+
}
145+
else
146+
t(c)
147+
val as2 = branches(_.thenp, as)
148+
val bs2 = branches(_.elsep, bs)
136149

137150
printdbg("came up with: " + lhs2 + ", if " + cond2 + " then " + as2 + " else " + bs2 + " with subst " + t.subst.mkString(","))
138-
List(TTP(lhs2, mhs2, SimpleFatIfThenElse(cond2,as2,bs2)))
151+
List(TTP(lhs2.zip(mhs2).map { case (s, d) => TP(s,d) }, SimpleFatIfThenElse(cond2,as2,bs2)))
139152

140-
case TTP(lhs, mhs, SimpleFatLoop(s,x,rhs)) =>
153+
case TTP(tps, SimpleFatLoop(s,x,rhs)) =>
141154
// alternate strategy: transform thin def, then fatten again (a little detour)
142-
printdbg("need to transform rhs of fat loop: " + lhs + ", " + rhs)
143-
val lhs2 = (lhs zip mhs).map { case (s,r) => transformOne(s, r, t) }.distinct.asInstanceOf[List[Sym[Any]]]
155+
val lhs1 = tps.map(_.sym)
156+
printdbg("need to transform rhs of fat loop: " + lhs1 + ", " + rhs)
157+
val lhs2 = tps.map { case TP(s,r) => transformOne(s, r, t) }.distinct.asInstanceOf[List[Sym[Any]]]
144158
val mhs2 = lhs2.map(s => findDefinition(s).get.defines(s).get)
145-
if (lhs != lhs2) {
159+
val lhsesAreDifferent = lhs1 != lhs2
160+
if (lhsesAreDifferent) {
146161
val missing = (lhs2.map(s => findDefinition(s).get) diff scope/*innerScope*/)
147-
printdbg("lhs changed! will add to innerScope: "+missing.mkString(","))
162+
printdbg("tps changed! will add to innerScope: "+missing.mkString(","))
148163
//innerScope = innerScope ::: missing
149164
}
150-
//val shape2 = if (lhs != lhs2) lhs2.map { case Def(SimpleLoop(s,_,_)) => s } reduceLeft { (s1,s2) => assert(s1==s2,"shapes don't agree: "+s1+","+s2); s1 }
165+
//val shape2 = if (lhs1 != lhs2) lhs2.map { case Def(SimpleLoop(s,_,_)) => s } reduceLeft { (s1,s2) => assert(s1==s2,"shapes don't agree: "+s1+","+s2); s1 }
151166
def infix_toLoop(d: Def[Any]) = d match {
152167
case l: AbstractLoop[_] => l
153168
case Reflect(l: AbstractLoop[_], _, _) => l
154169
}
155-
val shape2 = if (lhs != lhs2) mhs2.map (_.toLoop.size) reduceLeft { (s1,s2) => assert(s1==s2,"shapes don't agree: "+s1+","+s2); s1 }
156-
else t(s)
157-
val rhs2 = (if (lhs != lhs2) (lhs2 zip (mhs2 map (_.toLoop.body)))
158-
else (lhs zip rhs)) map { case (s,r) => transformLoopBody(s,r,t) }
170+
val shape2 = if (lhsesAreDifferent)
171+
mhs2.map(_.toLoop.size).reduceLeft { (s1,s2) =>
172+
assert(s1==s2,"shapes don't agree: "+s1+","+s2)
173+
s1
174+
}
175+
else
176+
t(s)
177+
val rhs2 = if (lhsesAreDifferent)
178+
mhs2 map (_.toLoop.body)
179+
else
180+
rhs
181+
val rhs3 = lhs2.zip(rhs2).map { case (s,r) => transformLoopBody(s,r,t) }
159182

160183
/* //update innerScope -- change definition of lhs2 in place (necessary?)
161184
innerScope = innerScope map {
162-
case TP(l,_) if lhs2 contains l => TP(l, SimpleLoop(shape2,t(x).asInstanceOf[Sym[Int]],rhs2(lhs2.indexOf(l))))
185+
case TP(l,_) if lhs2 contains l => TP(l, SimpleLoop(shape2,t(x).asInstanceOf[Sym[Int]],rhs3(lhs2.indexOf(l))))
163186
case d => d
164187
}*/
165188

166-
printdbg("came up with: " + lhs2 + ", " + rhs2 + " with subst " + t.subst.mkString(","))
167-
List(TTP(lhs2, mhs2, SimpleFatLoop(shape2,t(x).asInstanceOf[Sym[Int]],rhs2)))
189+
printdbg("came up with: " + lhs2 + ", " + rhs3 + " with subst " + t.subst.mkString(","))
190+
List(TTP(lhs2.zip(mhs2).map { case (s, d) => TP(s,d) }, SimpleFatLoop(shape2,t(x).asInstanceOf[Sym[Int]],rhs3)))
168191
// still problem: VectorSum(a,b) = SimpleLoop(i, ReduceElem(f(i)))
169192
// might need to translate f(i), but looking up VectorSum will not be changed at all!!!
170193
// --> change rhs nonetheless???

src/common/SplitEffects.scala

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,14 @@ trait BaseGenSplitEffects extends BaseGenIfThenElseFat with GenericFatCodegen {
183183

184184

185185
override def fatten(e: Stm): Stm = e match {
186-
case TP(s,d@While(c,b)) => TTP(List(s),List(d),SimpleFatWhile(c,List(b)))
187-
case TP(s,d@Reflect(While(c,b),u,es)) =>
186+
case tp @ TP(s,d@While(c,b)) => TTP(List(tp),SimpleFatWhile(c,List(b)))
187+
case tp @ TP(s,d@Reflect(While(c,b),u,es)) =>
188188
val x = SimpleFatWhile(c,List(b))
189189
x.extradeps = es.asInstanceOf[List[Sym[Any]]]
190-
TTP(List(s),List(d),x)
191-
case TP(s,d@Reflect(PreviousIteration(k),u,es)) =>
190+
TTP(List(tp),x)
191+
case tp @ TP(s,d@Reflect(PreviousIteration(k),u,es)) =>
192192
val x = SimpleFatPrevious(k,es.asInstanceOf[List[Sym[Any]]])
193-
TTP(List(s),List(d),x)
193+
TTP(List(tp),x)
194194
case _ => super.fatten(e)
195195
}
196196

@@ -205,31 +205,31 @@ trait BaseGenSplitEffects extends BaseGenIfThenElseFat with GenericFatCodegen {
205205
//println(e1)
206206

207207
val e2 = e1 collect {
208-
case t@TTP(lhs, mhs, p @ SimpleFatIfThenElse(c,as,bs)) => t
209-
case t@TTP(lhs, mhs, p @ SimpleFatWhile(c,b)) => t
210-
case t@TTP(lhs, mhs, p @ SimpleFatPrevious(k,es)) => t
208+
case t@TTP(_, p @ SimpleFatIfThenElse(c,as,bs)) => t
209+
case t@TTP(_, p @ SimpleFatWhile(c,b)) => t
210+
case t@TTP(_, p @ SimpleFatPrevious(k,es)) => t
211211
}
212212

213213
val m = e2 groupBy {
214-
case t@TTP(lhs, mhs, p @ SimpleFatIfThenElse(c,as,bs)) => (c, "if")
215-
case t@TTP(lhs, mhs, p @ SimpleFatWhile(Block(Def(Reify(c,_,_))),b)) => (c, "while")
216-
case t@TTP(lhs, mhs, p @ SimpleFatPrevious(k,es)) => (k,"prev")
214+
case t@TTP(_, p @ SimpleFatIfThenElse(c,as,bs)) => (c, "if")
215+
case t@TTP(_, p @ SimpleFatWhile(Block(Def(Reify(c,_,_))),b)) => (c, "while")
216+
case t@TTP(_, p @ SimpleFatPrevious(k,es)) => (k,"prev")
217217
}
218218

219219
val e3 = e1 diff e2
220220

221221
val g1 = m map {
222-
case ((c:Exp[Boolean], "if"), ifs: List[TTP]) => TTP(ifs.flatMap(_.lhs), ifs.flatMap(_.mhs),
222+
case ((c:Exp[Boolean], "if"), ifs: List[TTP]) => TTP(ifs.flatMap(_.tps),
223223
SimpleFatIfThenElse(c, ifs.flatMap(_.rhs.asInstanceOf[SimpleFatIfThenElse].thenp),
224224
ifs.flatMap(_.rhs.asInstanceOf[SimpleFatIfThenElse].elsep)))
225225
case ((c, "while"), wls: List[TTP]) =>
226226
val x = SimpleFatWhile(wls.map(_.rhs.asInstanceOf[SimpleFatWhile].cond).apply(0), //FIXME: merge cond!!!
227227
wls.flatMap(_.rhs.asInstanceOf[SimpleFatWhile].body))
228-
x.extradeps = wls.flatMap(_.rhs.asInstanceOf[SimpleFatWhile].extradeps) diff wls.flatMap(_.lhs)
229-
TTP(wls.flatMap(_.lhs), wls.flatMap(_.mhs), // TODO: merge cond blocks!
228+
x.extradeps = wls.flatMap(_.rhs.asInstanceOf[SimpleFatWhile].extradeps) diff wls.flatMap(_.tps)
229+
TTP(wls.flatMap(_.tps), // TODO: merge cond blocks!
230230
x)
231231
case ((k:Exp[Nothing],"prev"), pvs: List[TTP]) =>
232-
TTP(pvs.flatMap(_.lhs), pvs.flatMap(_.mhs), SimpleFatPrevious(k,pvs.flatMap(_.rhs.asInstanceOf[SimpleFatPrevious].extra)))
232+
TTP(pvs.flatMap(_.tps), SimpleFatPrevious(k,pvs.flatMap(_.rhs.asInstanceOf[SimpleFatPrevious].extra)))
233233
}
234234

235235
val r = e3 ++ g1

0 commit comments

Comments
 (0)