Skip to content

Commit

Permalink
[compiler] SBaseStruct.isFieldMissing returns value (hail-is#10893)
Browse files Browse the repository at this point in the history
* [compiler] SBaseStruct.isFieldMissing returns value

Refactor SBaseStruct.isFieldMissing and dependent methods to `CodeBuilder => Value` style.

* memoize propagates constant bools
  • Loading branch information
patrick-schultz authored Sep 24, 2021
1 parent 9ab3eb8 commit 674844b
Show file tree
Hide file tree
Showing 27 changed files with 164 additions and 158 deletions.
4 changes: 2 additions & 2 deletions hail/src/main/scala/is/hail/expr/ir/Emit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1308,7 +1308,7 @@ class Emit[C](
})

(0 until nDims).foreach { index =>
cb.ifx(shapeTupleValue.isFieldMissing(index),
cb.ifx(shapeTupleValue.isFieldMissing(cb, index),
cb._fatalWithError(errorId, s"shape missing at index $index"))
}

Expand Down Expand Up @@ -1340,7 +1340,7 @@ class Emit[C](
case stream: SStreamValue =>
val xP = PCanonicalNDArray(PType.canonical(stream.st.elementType.storageType().setRequired(true)), nDims)
(0 until nDims).foreach { index =>
cb.ifx(shapeTupleValue.isFieldMissing(index),
cb.ifx(shapeTupleValue.isFieldMissing(cb, index),
cb.append(Code._fatal[Unit](s"shape missing at index $index")))
}

Expand Down
5 changes: 3 additions & 2 deletions hail/src/main/scala/is/hail/expr/ir/EmitCodeBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ class EmitCodeBuilder(val emb: EmitMethodBuilder[_], var code: Code[Unit]) exten
f
}

def memoize[T: TypeInfo](v: Code[T], optionalName: String = ""): Value[T] = {
newLocal[T]("memoize" + optionalName, v)
def memoize[T: TypeInfo](v: Code[T], optionalName: String = ""): Value[T] = v match {
case b: ConstCodeBoolean => coerce[T](b.b)
case _ => newLocal[T]("memoize" + optionalName, v)
}

def memoizeField[T: TypeInfo](v: Code[T]): Value[T] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ abstract class AbstractTypedRegionBackedAggState(val ptype: PType) extends Regio
}

def get(cb: EmitCodeBuilder): IEmitCode = {
IEmitCode(cb, storageType.isFieldMissing(off, 0), ptype.loadCheapSCode(cb, storageType.loadField(off, 0)))
IEmitCode(cb, storageType.isFieldMissing(cb, off, 0), ptype.loadCheapSCode(cb, storageType.loadField(off, 0)))
}

def copyFrom(cb: EmitCodeBuilder, src: Code[Long]): Unit = {
Expand Down
56 changes: 30 additions & 26 deletions hail/src/main/scala/is/hail/expr/ir/agg/AppendOnlyBTree.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ trait BTreeKey {

def compType: PType

def isEmpty(cb: EmitCodeBuilder, off: Code[Long]): Code[Boolean]
def isEmpty(cb: EmitCodeBuilder, off: Code[Long]): Value[Boolean]

def initializeEmpty(cb: EmitCodeBuilder, off: Code[Long]): Unit

Expand Down Expand Up @@ -51,15 +51,18 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
elementsType.stagedInitialize(cb, elements(nodeBucket), true)
}

private def isRoot(node: Code[Long]): Code[Boolean] = storageType.isFieldMissing(node, 0)
private def isRoot(cb: EmitCodeBuilder, node: Code[Long]): Value[Boolean] =
storageType.isFieldMissing(cb, node, 0)

private def isLeaf(node: Code[Long]): Code[Boolean] = storageType.isFieldMissing(node, 1)
private def isLeaf(cb: EmitCodeBuilder, node: Code[Long]): Value[Boolean] =
storageType.isFieldMissing(cb, node, 1)

private def getParent(node: Code[Long]): Code[Long] = Region.loadAddress(storageType.loadField(node, 0))

private def elements(node: Code[Long]): Code[Long] = storageType.loadField(node, 2)

private def hasKey(node: Code[Long], i: Int): Code[Boolean] = elementsType.isFieldDefined(elements(node), i)
private def hasKey(cb: EmitCodeBuilder, node: Code[Long], i: Int): Value[Boolean] =
elementsType.isFieldDefined(cb, elements(node), i)

private def setKeyPresent(cb: EmitCodeBuilder, node: Code[Long], i: Int): Unit = {
elementsType.setFieldPresent(cb, elements(node), i)
Expand All @@ -69,7 +72,8 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
elementsType.setFieldMissing(cb, elements(node), i)
}

private def isFull(node: Code[Long]): Code[Boolean] = hasKey(node, maxElements - 1)
private def isFull(cb: EmitCodeBuilder, node: Code[Long]): Value[Boolean] =
hasKey(cb, node, maxElements - 1)

private def keyOffset(node: Code[Long], i: Int): Code[Long] = eltType.fieldOffset(elementsType.loadField(elements(node), i), 0)

Expand Down Expand Up @@ -112,7 +116,7 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
def makeUninitialized(cb: EmitCodeBuilder, idx: Int): Code[Long] = {
setKeyPresent(cb, node, idx)
key.initializeEmpty(cb, keyOffset(node, idx))
cb.ifx(!isLeaf(node), {
cb.ifx(!isLeaf(cb, node), {
setChild(cb, node, idx, child, "makeUninitialized setChild")
})
loadKey(node, idx)
Expand All @@ -123,7 +127,7 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
val srcNode = cb.newLocal("aobt_copy_from_srcnode", srcNodeC)
setKeyPresent(cb, destNode, destIdx)
key.copy(cb, keyOffset(srcNode, srcIdx), keyOffset(destNode, destIdx))
cb.ifx(!isLeaf(srcNode),
cb.ifx(!isLeaf(cb, srcNode),
{
setChild(cb, destNode, destIdx, loadChild(srcNode, srcIdx), "insert copyFrom")
})
Expand All @@ -140,7 +144,7 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
val Lfound = CodeLabel()

(0 until maxElements).foreach { i =>
val b = cb.newLocal[Boolean]("btree_insertkey_b", !hasKey(parent, i))
val b = cb.newLocal[Boolean]("btree_insertkey_b", !hasKey(cb, parent, i))
cb.ifx(!b, cb.assign(b, key.compWithKey(cb, loadKey(parent, i), ev) >= 0))
cb.ifx(b, {
cb.assign(upperBound, i)
Expand All @@ -149,7 +153,7 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
}

cb.define(Lfound)
cb.ifx(!isLeaf(node), {
cb.ifx(!isLeaf(cb, node), {
setChild(cb, newNode, -1, c, "insertKey !isLeaf")
})
cb.invokeCode(insertAt, parent, upperBound, ev, newNode)
Expand All @@ -159,15 +163,15 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
def promote(cb: EmitCodeBuilder, idx: Int): Unit = {
val nikey = cb.newLocal("aobt_insert_nikey", loadKey(node, idx))

cb.ifx(!isLeaf(node), {
cb.ifx(!isLeaf(cb, node), {
setChild(cb, newNode, -1, loadChild(node, idx), "promote")
})

val upperBound = cb.newLocal("promote_upper_bound", maxElements)
val Lfound = CodeLabel()

(0 until maxElements).foreach { i =>
val b = cb.newLocal[Boolean]("btree_insert_promote_b", !hasKey(parent, i))
val b = cb.newLocal[Boolean]("btree_insert_promote_b", !hasKey(cb, parent, i))
cb.ifx(!b, cb.assign(b, key.compSame(cb, loadKey(parent, i), nikey) >= 0))
cb.ifx(b, {
cb.assign(upperBound, i)
Expand All @@ -181,7 +185,7 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
}

def splitAndInsert(cb: EmitCodeBuilder): Code[Long] = {
cb.ifx(isRoot(node), {
cb.ifx(isRoot(cb, node), {
createNode(cb, root)
setChild(cb, root, -1, node, "splitAndInsert")
})
Expand All @@ -207,7 +211,7 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
val ret = cb.newLocal[Long]("shift_and_insert")
val Lout = CodeLabel()
(1 until maxElements).reverse.foreach { destIdx =>
cb.ifx(hasKey(node, destIdx - 1), {
cb.ifx(hasKey(cb, node, destIdx - 1), {
copyFrom(cb, node, destIdx, node, destIdx - 1)
})
cb.ifx(insertIdx.ceq(destIdx), {
Expand All @@ -222,7 +226,7 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[

insertAt.emitWithBuilder { cb =>
val ret = cb.newLocal[Long]("btree_insert_result")
cb.ifx(isFull(node),
cb.ifx(isFull(cb, node),
cb.assign(ret, splitAndInsert(cb)),
cb.assign(ret, shiftAndInsert(cb)))
ret
Expand All @@ -242,7 +246,7 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
val keyV = cb.newLocal("btree_get_keyV", 0L)

def insertOrGetAt(i: Int) = {
cb.ifx(isLeaf(node), {
cb.ifx(isLeaf(cb, node), {
cb.assign(keyV, insert(cb, node, const(i), k, const(0L)))
cb.assign(cmp, 0)
}, {
Expand All @@ -252,7 +256,7 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[

cb.whileLoop(cmp.cne(0), { Lcont =>
(0 until maxElements).foreach { i =>
cb.ifx(hasKey(node, i), {
cb.ifx(hasKey(cb, node, i), {
cb.assign(keyV, loadKey(node, i))
cb.assign(cmp, key.compWithKey(cb, keyV, k))
cb.ifx(cmp.ceq(0), cb.goto(Lcont))
Expand Down Expand Up @@ -312,16 +316,16 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
cb.goto(Lend)

cb.define(Lminus1)
cb.ifx(!isLeaf(node), {
cb.ifx(!isLeaf(cb, node), {
stackUpdateIdx(0)
stackPush(loadChild(node, -1))
cb.goto(Lstart)
})
(0 until maxElements).foreach { i =>
cb.define(labels(i))
cb.ifx(hasKey(node, i), {
cb.ifx(hasKey(cb, node, i), {
visitor(cb, loadKey(node, i))
cb.ifx(!isLeaf(node), {
cb.ifx(!isLeaf(cb, node), {
stackUpdateIdx(i + 1)
stackPush(loadChild(node, i))
cb.goto(Lstart)
Expand Down Expand Up @@ -350,15 +354,15 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
cb.invokeVoid(cb.emb, newNode, loadChild(srcNode, i))
}

cb.ifx(!isLeaf(srcNode), {
cb.ifx(!isLeaf(cb, srcNode), {
copyChild(-1)
setChild(cb, destNode, -1, newNode, "deepcopy1")
})

(0 until maxElements).foreach { i =>
cb.ifx(hasKey(srcNode, i), {
cb.ifx(hasKey(cb, srcNode, i), {
key.deepCopy(cb, er, destNode, srcNode)
cb.ifx(!isLeaf(srcNode), {
cb.ifx(!isLeaf(cb, srcNode), {
copyChild(i)
setChild(cb, destNode, i, newNode, "deepcopy2")
})
Expand All @@ -377,16 +381,16 @@ class AppendOnlyBTree(kb: EmitClassBuilder[_], val key: BTreeKey, region: Value[
val ob = f.getCodeParam[OutputBuffer](2)

f.voidWithBuilder { cb =>
cb += ob.writeBoolean(!isLeaf(node))
cb.ifx(!isLeaf(node), {
cb += ob.writeBoolean(!isLeaf(cb, node))
cb.ifx(!isLeaf(cb, node), {
cb.invokeVoid(f, loadChild(node, -1), ob)
})
val Lexit = CodeLabel()
(0 until maxElements).foreach { i =>
cb.ifx(hasKey(node, i), {
cb.ifx(hasKey(cb, node, i), {
cb += ob.writeBoolean(true)
keyStore(cb, ob, loadKey(node, i))
cb.ifx(!isLeaf(node), {
cb.ifx(!isLeaf(cb, node), {
cb.invokeVoid(f, loadChild(node, i), ob)
})
}, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ArrayElementState(val kb: EmitClassBuilder[_], val nested: StateTuple) ext
super.load(cb, regionLoader, srcc)
cb.ifx(off.cne(0L),
{
cb.assign(lenRef, typ.isFieldMissing(off, 1).mux(-1,
cb.assign(lenRef, typ.isFieldMissing(cb, off, 1).mux(-1,
arrayType.loadLength(typ.loadField(off, 1))))
})
}
Expand Down Expand Up @@ -157,7 +157,7 @@ class ArrayElementState(val kb: EmitClassBuilder[_], val nested: StateTuple) ext
val eltOffset = arrayType.loadElement(typ.loadField(srcOff, 1), idx)

init(cb, cb => initContainer.copyFrom(cb, initOffset), initLen = false)
cb.ifx(typ.isFieldMissing(srcOff, 1), {
cb.ifx(typ.isFieldMissing(cb, srcOff, 1), {
typ.setFieldMissing(cb, off, 1)
cb.assign(lenRef, -1)
}, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ class TypedKey(typ: PType, kb: EmitClassBuilder[_], region: Value[Region]) exten
override val storageType: PTuple = PCanonicalTuple(false, typ, PCanonicalTuple(false))
override val compType: PType = typ

def isKeyMissing(src: Code[Long]): Code[Boolean] = storageType.isFieldMissing(src, 0)
def isKeyMissing(cb: EmitCodeBuilder, src: Code[Long]): Value[Boolean] =
storageType.isFieldMissing(cb, src, 0)

def loadKey(cb: EmitCodeBuilder, src: Code[Long]): SValue = {
typ.loadCheapSCode(cb, storageType.loadField(src, 0))
}

override def isEmpty(cb: EmitCodeBuilder, off: Code[Long]): Code[Boolean] = storageType.isFieldMissing(off, 1)
override def isEmpty(cb: EmitCodeBuilder, off: Code[Long]): Value[Boolean] =
storageType.isFieldMissing(cb, off, 1)

override def initializeEmpty(cb: EmitCodeBuilder, off: Code[Long]): Unit =
storageType.setFieldMissing(cb, off, 1)
Expand Down Expand Up @@ -54,7 +56,7 @@ class TypedKey(typ: PType, kb: EmitClassBuilder[_], region: Value[Region]) exten
}

override def loadCompKey(cb: EmitCodeBuilder, off: Value[Long]): EmitValue =
EmitValue(Some(cb.memoize(isKeyMissing(off))), loadKey(cb, off))
EmitValue(Some(isKeyMissing(cb, off)), loadKey(cb, off))
}

class AppendOnlySetState(val kb: EmitClassBuilder[_], vt: VirtualTypeWithReq) extends PointerBasedRVAState {
Expand Down Expand Up @@ -106,7 +108,7 @@ class AppendOnlySetState(val kb: EmitClassBuilder[_], vt: VirtualTypeWithReq) ex
def foreach(cb: EmitCodeBuilder)(f: (EmitCodeBuilder, EmitCode) => Unit): Unit =
tree.foreach(cb) { (cb, eoffCode) =>
val eoff = cb.newLocal("casa_foreach_eoff", eoffCode)
f(cb, EmitCode.fromI(cb.emb)(cb => IEmitCode(cb, key.isKeyMissing(eoff), key.loadKey(cb, eoff))))
f(cb, EmitCode.fromI(cb.emb)(cb => IEmitCode(cb, key.isKeyMissing(cb, eoff), key.loadKey(cb, eoff))))
}

def copyFromAddress(cb: EmitCodeBuilder, srcc: Code[Long]): Unit = {
Expand All @@ -121,8 +123,8 @@ class AppendOnlySetState(val kb: EmitClassBuilder[_], vt: VirtualTypeWithReq) ex
{ (cb: EmitCodeBuilder, ob: Value[OutputBuffer]) =>
tree.bulkStore(cb, ob) { (cb, ob, srcCode) =>
val src = cb.newLocal("aoss_ser_src", srcCode)
cb += ob.writeBoolean(key.isKeyMissing(src))
cb.ifx(!key.isKeyMissing(src), {
cb += ob.writeBoolean(key.isKeyMissing(cb, src))
cb.ifx(!key.isKeyMissing(cb, src), {
val k = key.loadKey(cb, src)
et.buildEncoder(k.st, kb)
.apply(cb, k.get, ob)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class DownsampleBTreeKey(binType: PBaseStruct, pointType: PBaseStruct, kb: EmitC
override val compType: PType = binType
private val kcomp = kb.getOrderingFunction(binType.sType, CodeOrdering.Compare())

override def isEmpty(cb: EmitCodeBuilder, off: Code[Long]): Code[Boolean] = PBooleanRequired.loadCheapSCode(cb, storageType.loadField(off, "empty")).boolCode(cb)
override def isEmpty(cb: EmitCodeBuilder, off: Code[Long]): Value[Boolean] =
PBooleanRequired.loadCheapSCode(cb, storageType.loadField(off, "empty")).boolCode(cb)

override def initializeEmpty(cb: EmitCodeBuilder, off: Code[Long]): Unit = cb += Region.storeBoolean(storageType.fieldOffset(off, "empty"), true)

Expand Down Expand Up @@ -317,15 +318,10 @@ class DownsampleState(val kb: EmitClassBuilder[_], labelType: VirtualTypeWithReq
other.foreach(cb) { (cb, v) =>
val mb = kb.genEmitMethod("downsample_copy_from_tree_foreach", FastIndexedSeq[ParamType](LongInfo), UnitInfo)
val value = mb.getCodeParam[Long](1)
val point = mb.newLocal[Long]("point_offset")
val pointX = mb.newLocal[Double]("point_x")
val pointY = mb.newLocal[Double]("point_y")
val lm = mb.newLocal[Boolean]("lm")
mb.voidWithBuilder { cb =>
cb.assign(point, key.storageType.loadField(value, "point"))
cb.assign(pointX, Region.loadDouble(pointType.loadField(point, "x")))
cb.assign(pointY, Region.loadDouble(pointType.loadField(point, "y")))
cb.assign(lm, pointType.isFieldMissing(point, "label"))
val point = cb.memoize(key.storageType.loadField(value, "point"))
val pointX = cb.memoize(Region.loadDouble(pointType.loadField(point, "x")))
val pointY = cb.memoize(Region.loadDouble(pointType.loadField(point, "y")))
insertIntoTree(cb, xBinCoordinate(pointX), yBinCoordinate(pointY), point, deepCopy = true)
}
cb.invokeVoid(mb, v)
Expand Down
14 changes: 7 additions & 7 deletions hail/src/main/scala/is/hail/expr/ir/agg/GroupedAggregator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class GroupedBTreeKey(kt: PType, kb: EmitClassBuilder[_], region: Value[Region],
}
val container = new TupleAggregatorState(kb, states, region, containerOffset(offset), regionIdx)

def isKeyMissing(off: Code[Long]): Code[Boolean] =
storageType.isFieldMissing(off, 0)
def isKeyMissing(cb: EmitCodeBuilder, off: Code[Long]): Value[Boolean] =
storageType.isFieldMissing(cb, off, 0)

def loadKey(cb: EmitCodeBuilder, off: Code[Long]): SValue = {
kt.loadCheapSCodeField(cb, storageType.loadField(off, 0))
Expand Down Expand Up @@ -77,8 +77,8 @@ class GroupedBTreeKey(kt: PType, kb: EmitClassBuilder[_], region: Value[Region],
def get: Code[Long] = storageType.fieldOffset(off, 2)
}

override def isEmpty(cb: EmitCodeBuilder, off: Code[Long]): Code[Boolean] =
Region.loadInt(storageType.fieldOffset(off, 1)) < 0
override def isEmpty(cb: EmitCodeBuilder, off: Code[Long]): Value[Boolean] =
cb.memoize(Region.loadInt(storageType.fieldOffset(off, 1)) < 0)

override def initializeEmpty(cb: EmitCodeBuilder, off: Code[Long]): Unit =
cb += Region.storeInt(storageType.fieldOffset(off, 1), -1)
Expand All @@ -98,7 +98,7 @@ class GroupedBTreeKey(kt: PType, kb: EmitClassBuilder[_], region: Value[Region],
}

override def loadCompKey(cb: EmitCodeBuilder, off: Value[Long]): EmitValue =
EmitValue(Some(cb.memoize(isKeyMissing(off))), loadKey(cb, off))
cb.memoize(IEmitCode(cb, isKeyMissing(cb, off), loadKey(cb, off)))
}

class DictState(val kb: EmitClassBuilder[_], val keyVType: VirtualTypeWithReq, val nested: StateTuple) extends PointerBasedRVAState {
Expand Down Expand Up @@ -186,7 +186,7 @@ class DictState(val kb: EmitClassBuilder[_], val keyVType: VirtualTypeWithReq, v
tree.foreach(cb) { (cb, kvOff) =>
cb.assign(_elt, kvOff)
keyed.loadStates(cb)
f(cb, EmitCode.fromI(cb.emb)(cb => IEmitCode(cb, keyed.isKeyMissing(_elt), keyed.loadKey(cb, _elt))))
f(cb, EmitCode.fromI(cb.emb)(cb => IEmitCode(cb, keyed.isKeyMissing(cb, _elt), keyed.loadKey(cb, _elt))))
}

def copyFromAddress(cb: EmitCodeBuilder, srcCode: Code[Long]): Unit = {
Expand All @@ -209,7 +209,7 @@ class DictState(val kb: EmitClassBuilder[_], val keyVType: VirtualTypeWithReq, v
})
tree.bulkStore(cb, ob) { (cb: EmitCodeBuilder, ob: Value[OutputBuffer], kvOff: Code[Long]) =>
cb.assign(_elt, kvOff)
val km = cb.newLocal[Boolean]("grouped_ser_m", keyed.isKeyMissing(_elt))
val km = keyed.isKeyMissing(cb, _elt)
cb += (ob.writeBoolean(km))
cb.ifx(!km, {
val k = keyed.loadKey(cb, _elt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,14 @@ class TakeByRVAS(val valueVType: VirtualTypeWithReq, val keyVType: VirtualTypeWi

private def elementOffset(i: Value[Int]): Code[Long] = ab.elementOffset(i)

private def keyIsMissing(offset: Code[Long]): Code[Boolean] = indexedKeyType.isFieldMissing(offset, 0)
private def keyIsMissing(cb: EmitCodeBuilder, offset: Code[Long]): Value[Boolean] =
indexedKeyType.isFieldMissing(cb, offset, 0)

private def loadKeyValue(cb: EmitCodeBuilder, offset: Code[Long]): SValue =
keyType.loadCheapSCode(cb, indexedKeyType.loadField(offset, 0))

private def loadKey(cb: EmitCodeBuilder, offset: Value[Long]): EmitValue =
cb.memoize(IEmitCode(cb, keyIsMissing(offset), loadKeyValue(cb, offset)))
cb.memoize(IEmitCode(cb, keyIsMissing(cb, offset), loadKeyValue(cb, offset)))

private val compareElt: (Code[Long], Code[Long]) => Code[Int] = {
val mb = kb.genEmitMethod("i_gt_j", FastIndexedSeq[ParamType](LongInfo, LongInfo), IntInfo)
Expand Down
Loading

0 comments on commit 674844b

Please sign in to comment.