Skip to content

Commit

Permalink
Using provider and lazy val to guarantee idempotent results
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach committed Aug 17, 2024
1 parent 3283747 commit 32344c1
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void close() throws IOException {
.localScope()
.foreach(
s -> {
s.scope().apply().removeScopeFromParent();
s.scope().removeScopeFromParent();
return null;
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ import scala.jdk.CollectionConverters._
class LocalScope(
final val parentScope: Option[LocalScope],
final val aliasingGraph: () => AliasGraph,
final val scope: () => AliasGraph.Scope,
final val dataflowInfo: () => DataflowAnalysis.Metadata,
final private val scopeProvider: () => AliasGraph.Scope,
final private val dataflowInfoProvider: () => DataflowAnalysis.Metadata,
final val flattenToParent: Boolean = false,
private val parentFrameSlotIdxs: Map[AliasGraph.Id, Int] = Map()
) {
lazy val scope: AliasGraph.Scope = scopeProvider()
lazy val dataflowInfo: DataflowAnalysis.Metadata = dataflowInfoProvider()

private lazy val localFrameSlotIdxs: Map[AliasGraph.Id, Int] =
gatherLocalFrameSlotIdxs()

Expand All @@ -50,7 +53,7 @@ class LocalScope(
*
* @return a child of this scope
*/
def createChild(): LocalScope = createChild(() => scope().addChild())
def createChild(): LocalScope = createChild(() => scope.addChild())

/** Creates a child using a known aliasing scope.
*
Expand All @@ -67,7 +70,7 @@ class LocalScope(
Some(this),
aliasingGraph,
childScope,
dataflowInfo,
() => dataflowInfo,
flattenToParent,
allFrameSlotIdxs
)
Expand All @@ -88,7 +91,7 @@ class LocalScope(
* internal slots, that are prepended to every frame.
*/
private def gatherLocalFrameSlotIdxs(): Map[AliasGraph.Id, Int] = {
scope().allDefinitions.zipWithIndex.map { case (definition, i) =>
scope.allDefinitions.zipWithIndex.map { case (definition, i) =>
definition.id -> (i + LocalScope.internalSlotsSize)
}.toMap
}
Expand All @@ -105,7 +108,7 @@ class LocalScope(
.flatMap(scope => Some(scope.flattenBindingsWithLevel(level + 1)))
.getOrElse(Map())

scope().occurrences.foreach {
scope.occurrences.foreach {
case (id, x: GraphOccurrence.Def) =>
parentResult += x.symbol -> new FramePointer(
level,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,18 +126,17 @@ case object AliasAnalysis extends IRPass {
inlineContext.localScope
.map { localScope =>
val scope =
if (shouldWriteState) localScope.scope()
if (shouldWriteState) localScope.scope
else
localScope
.scope()
localScope.scope
.deepCopy(mutable.Map())
.withParent(localScope.scope())
.withParent(localScope.scope)

val ag = localScope.aliasingGraph()
val graph =
if (shouldWriteState) ag
else {
val mapping = mutable.Map(localScope.scope() -> scope)
val mapping = mutable.Map(localScope.scope -> scope)
ag.deepCopy(mapping)
}
val result = analyseExpression(ir, graph, scope)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ case object DataflowAnalysis extends IRPass {
"A valid local scope is required for the inline flow."
)
)
analyseExpression(ir, localScope.dataflowInfo())
analyseExpression(ir, localScope.dataflowInfo)
}

/** @inheritdoc */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ protected EnsoRootNode(
private static FrameDescriptor buildFrameDescriptor(LocalScope localScope) {
var descriptorBuilder = FrameDescriptor.newBuilder();
descriptorBuilder.addSlot(FrameSlotKind.Object, LocalScope.monadicStateSlotName(), null);
for (var definition : ScalaConversions.asJava(localScope.scope().apply().allDefinitions())) {
for (var definition : ScalaConversions.asJava(localScope.scope().allDefinitions())) {
descriptorBuilder.addSlot(FrameSlotKind.Illegal, definition.symbol(), null);
}
descriptorBuilder.defaultValue(DataflowError.UNINITIALIZED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,14 @@ class IrToTruffle(
atomCons: AtomConstructor,
atomDefn: Definition.Data
): Unit = {
def scopeInfo() = atomDefn
.unsafeGetMetadata(
AliasAnalysis,
"No root scope on an atom definition."
)
.unsafeAs[AliasMetadata.RootScope]
def scopeInfo() = {
atomDefn
.unsafeGetMetadata(
AliasAnalysis,
"No root scope on an atom definition."
)
.unsafeAs[AliasMetadata.RootScope]
}

def dataflowInfo() = atomDefn.unsafeGetMetadata(
DataflowAnalysis,
Expand Down Expand Up @@ -373,13 +375,15 @@ class IrToTruffle(
}

methodDefs.foreach(methodDef => {
def scopeInfo() = methodDef
.unsafeGetMetadata(
AliasAnalysis,
s"Missing scope information for method " +
s"`${methodDef.typeName.map(_.name + ".").getOrElse("")}${methodDef.methodName.name}`."
)
.unsafeAs[AliasMetadata.RootScope]
def scopeInfo() = {
methodDef
.unsafeGetMetadata(
AliasAnalysis,
s"Missing scope information for method " +
s"`${methodDef.typeName.map(_.name + ".").getOrElse("")}${methodDef.methodName.name}`."
)
.unsafeAs[AliasMetadata.RootScope]
}
def dataflowInfo() = methodDef.unsafeGetMetadata(
DataflowAnalysis,
"Method definition missing dataflow information."
Expand Down Expand Up @@ -548,15 +552,17 @@ class IrToTruffle(
)
val scopeName =
scopeElements.mkString(Constants.SCOPE_SEPARATOR)
def scopeInfo() = annotation
.unsafeGetMetadata(
AliasAnalysis,
s"Missing scope information for annotation " +
s"${annotation.name} of method " +
scopeElements.init
.mkString(Constants.SCOPE_SEPARATOR)
)
.unsafeAs[AliasMetadata.RootScope]
def scopeInfo() = {
annotation
.unsafeGetMetadata(
AliasAnalysis,
s"Missing scope information for annotation " +
s"${annotation.name} of method " +
scopeElements.init
.mkString(Constants.SCOPE_SEPARATOR)
)
.unsafeAs[AliasMetadata.RootScope]
}
def dataflowInfo() = annotation.unsafeGetMetadata(
DataflowAnalysis,
"Missing dataflow information for annotation " +
Expand Down Expand Up @@ -767,13 +773,15 @@ class IrToTruffle(

// Register the conversion definitions in scope
conversionDefs.foreach(methodDef => {
def scopeInfo() = methodDef
.unsafeGetMetadata(
AliasAnalysis,
s"Missing scope information for conversion " +
s"`${methodDef.typeName.map(_.name + ".").getOrElse("")}${methodDef.methodName.name}`."
)
.unsafeAs[AliasMetadata.RootScope]
def scopeInfo() = {
methodDef
.unsafeGetMetadata(
AliasAnalysis,
s"Missing scope information for conversion " +
s"`${methodDef.typeName.map(_.name + ".").getOrElse("")}${methodDef.methodName.name}`."
)
.unsafeAs[AliasMetadata.RootScope]
}
def dataflowInfo() = methodDef.unsafeGetMetadata(
DataflowAnalysis,
"Method definition missing dataflow information."
Expand Down Expand Up @@ -1332,12 +1340,14 @@ class IrToTruffle(
*/
private def processBlock(block: Expression.Block): RuntimeExpression = {
if (block.suspended) {
def scopeInfo() = block
.unsafeGetMetadata(
AliasAnalysis,
"Missing scope information on block."
)
.unsafeAs[AliasMetadata.ChildScope]
def scopeInfo() = {
block
.unsafeGetMetadata(
AliasAnalysis,
"Missing scope information on block."
)
.unsafeAs[AliasMetadata.ChildScope]
}

val childFactory = this.createChild(
"suspended-block",
Expand Down Expand Up @@ -1446,12 +1456,14 @@ class IrToTruffle(
def processCaseBranch(
branch: Case.Branch
): Either[BadPatternMatch, BranchNode] = {
def scopeInfo() = branch
.unsafeGetMetadata(
AliasAnalysis,
"No scope information on a case branch."
)
.unsafeAs[AliasMetadata.ChildScope]
def scopeInfo() = {
branch
.unsafeGetMetadata(
AliasAnalysis,
"No scope information on a case branch."
)
.unsafeAs[AliasMetadata.ChildScope]
}

val childProcessor =
this.createChild(
Expand Down Expand Up @@ -1846,10 +1858,11 @@ class IrToTruffle(
function: Function,
binding: Boolean
): RuntimeExpression = {
def scopeInfo() = function
.unsafeGetMetadata(AliasAnalysis, "No scope info on a function.")
.unsafeAs[AliasMetadata.ChildScope]

def scopeInfo() = {
function
.unsafeGetMetadata(AliasAnalysis, "No scope info on a function.")
.unsafeAs[AliasMetadata.ChildScope]
}
if (function.body.isInstanceOf[Function]) {
throw new CompilerError(
"Lambda found directly as function body. It looks like Lambda " +
Expand Down Expand Up @@ -2438,12 +2451,14 @@ class IrToTruffle(
_,
_
) =>
def scopeInfo() = arg
.unsafeGetMetadata(
AliasAnalysis,
"No scope attached to a call argument."
)
.unsafeAs[AliasMetadata.ChildScope]
def scopeInfo() = {
arg
.unsafeGetMetadata(
AliasAnalysis,
"No scope attached to a call argument."
)
.unsafeAs[AliasMetadata.ChildScope]
}

def valueHasSomeTypeCheck() =
value.getMetadata(TypeSignatures).isDefined
Expand Down

0 comments on commit 32344c1

Please sign in to comment.