Skip to content

Commit

Permalink
Revert "Delay conversion of Truffle function body nodes until the fun…
Browse files Browse the repository at this point in the history
…ction is invoked (#3429)"

This reverts commit 3ab2c8f.
  • Loading branch information
hubertp committed May 9, 2022
1 parent 078c665 commit 2ccdec6
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 123 deletions.
2 changes: 0 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@
- [Converting Enso Date to java.time.LocalDate and back][3374]
- [Functions with all-defaulted arguments now execute automatically][3414]
- [Provide `tagValues` for function arguments in the language server][3422]
- [Delay construction of Truffle nodes to speed initialization][3429]
- [Frgaal compiler integration to allow for latest Java constructs][3421]
- [Move Builtin Types and Methods definitions to stdlib][3363]

Expand All @@ -207,7 +206,6 @@
[3414]: https://github.com/enso-org/enso/pull/3414
[3417]: https://github.com/enso-org/enso/pull/3417
[3422]: https://github.com/enso-org/enso/pull/3422
[3429]: https://github.com/enso-org/enso/pull/3429
[3421]: https://github.com/enso-org/enso/pull/3421
[3363]: https://github.com/enso-org/enso/pull/3363

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package org.enso.interpreter.node;

import com.oracle.truffle.api.dsl.ReportPolymorphism;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.NodeInfo;
import com.oracle.truffle.api.source.SourceSection;
import java.util.function.Supplier;
import org.enso.interpreter.Language;
import org.enso.interpreter.runtime.callable.atom.AtomConstructor;
import org.enso.interpreter.runtime.scope.LocalScope;
Expand Down Expand Up @@ -46,30 +44,12 @@ private static String shortName(String atomName, String methodName) {
* @param language the language identifier
* @param localScope a description of the local scope
* @param moduleScope a description of the module scope
* @param body the program provider to be executed
* @param section a mapping from {@code provider} to the program source
* @param body the program body to be executed
* @param section a mapping from {@code body} to the program source
* @param atomConstructor the constructor this method is defined for
* @param methodName the name of this method
* @return a node representing the specified closure
*/
public static MethodRootNode build(
Language language,
LocalScope localScope,
ModuleScope moduleScope,
Supplier<ExpressionNode> body,
SourceSection section,
AtomConstructor atomConstructor,
String methodName) {
return build(
language,
localScope,
moduleScope,
new LazyBodyNode(body),
section,
atomConstructor,
methodName);
}

public static MethodRootNode build(
Language language,
LocalScope localScope,
Expand Down Expand Up @@ -107,19 +87,4 @@ public AtomConstructor getAtomConstructor() {
public String getMethodName() {
return methodName;
}

private static class LazyBodyNode extends ExpressionNode {
private final Supplier<ExpressionNode> provider;

LazyBodyNode(Supplier<ExpressionNode> body) {
this.provider = body;
}

@Override
public Object executeGeneric(VirtualFrame frame) {
ExpressionNode newNode = replace(provider.get());
notifyInserted(newNode);
return newNode.executeGeneric(frame);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ public static BlockNode build(ExpressionNode[] expressions, ExpressionNode retur
return new BlockNode(expressions, returnExpr);
}

public static BlockNode buildSilent(ExpressionNode[] expressions, ExpressionNode returnExpr) {
return new BlockNode(expressions, returnExpr);
}

/**
* Executes the body of the function.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ private Function buildConstructorFunction(
ArgumentDefinition[] args) {

ExpressionNode instantiateNode = InstantiateNode.build(this, varReads);
BlockNode instantiateBlock = BlockNode.buildSilent(assignments, instantiateNode);
BlockNode instantiateBlock = BlockNode.build(assignments, instantiateNode);
RootNode rootNode =
ClosureRootNode.build(
null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,28 +318,23 @@ class IrToTruffle(
)
.map(_.filterNot(_ => cons.isBuiltin))
case fn: IR.Function =>
val bodyBuilder =
new expressionProcessor.BuildFunctionBody(fn.arguments, fn.body)
val (body, arguments) =
expressionProcessor.buildFunctionBody(fn.arguments, fn.body)
val rootNode = MethodRootNode.build(
language,
expressionProcessor.scope,
moduleScope,
() => bodyBuilder.bodyNode(),
body,
makeSection(methodDef.location),
cons,
methodDef.methodName.name
)
val callTarget = Truffle.getRuntime.createCallTarget(rootNode)
val arguments = bodyBuilder.args()
Right(
Some(
new RuntimeFunction(
callTarget,
null,
new FunctionSchema(arguments: _*)
)
)
)
Right(Some(new RuntimeFunction(
callTarget,
null,
new FunctionSchema(arguments: _*)
)))
case _ =>
Left(
new CompilerError(
Expand Down Expand Up @@ -390,19 +385,18 @@ class IrToTruffle(

val function = methodDef.body match {
case fn: IR.Function =>
val bodyBuilder =
new expressionProcessor.BuildFunctionBody(fn.arguments, fn.body)
val (body, arguments) =
expressionProcessor.buildFunctionBody(fn.arguments, fn.body)
val rootNode = MethodRootNode.build(
language,
expressionProcessor.scope,
moduleScope,
() => bodyBuilder.bodyNode(),
body,
makeSection(methodDef.location),
toType,
methodDef.methodName.name
)
val callTarget = Truffle.getRuntime.createCallTarget(rootNode)
val arguments = bodyBuilder.args()
new RuntimeFunction(
callTarget,
null,
Expand Down Expand Up @@ -1235,72 +1229,59 @@ class IrToTruffle(
* @return a node for the final shape of function body and pre-processed
* argument definitions.
*/
class BuildFunctionBody(
val arguments: List[IR.DefinitionArgument],
val body: IR.Expression
) {
private val argFactory = new DefinitionArgumentProcessor(scopeName, scope)
private lazy val slots = computeSlots()
private lazy val bodyN = computeBodyNode()

def args(): Array[ArgumentDefinition] = slots._2
def bodyNode(): BlockNode = bodyN

private def computeBodyNode(): BlockNode = {
val (argSlots, _, argExpressions) = slots

val bodyExpr = body match {
case IR.Foreign.Definition(lang, code, _, _, _) =>
buildForeignBody(
lang,
code,
arguments.map(_.name.name),
argSlots
)
case _ => ExpressionProcessor.this.run(body)
}
BlockNode.build(argExpressions.toArray, bodyExpr)
}
def buildFunctionBody(
arguments: List[IR.DefinitionArgument],
body: IR.Expression
): (BlockNode, Array[ArgumentDefinition]) = {
val argFactory = new DefinitionArgumentProcessor(scopeName, scope)

private def computeSlots(): (
List[FrameSlot],
Array[ArgumentDefinition],
ArrayBuffer[RuntimeExpression]
) = {
val seenArgNames = mutable.Set[String]()
val argDefinitions = new Array[ArgumentDefinition](arguments.size)
val argExpressions = new ArrayBuffer[RuntimeExpression]
// Note [Rewriting Arguments]
val argSlots = arguments.zipWithIndex.map {
case (unprocessedArg, idx) =>
val arg = argFactory.run(unprocessedArg, idx)
argDefinitions(idx) = arg

val occInfo = unprocessedArg
.unsafeGetMetadata(
AliasAnalysis,
"No occurrence on an argument definition."
)
.unsafeAs[AliasAnalysis.Info.Occurrence]
val argDefinitions = new Array[ArgumentDefinition](arguments.size)
val argExpressions = new ArrayBuffer[RuntimeExpression]
val seenArgNames = mutable.Set[String]()

// Note [Rewriting Arguments]
val argSlots =
arguments.zipWithIndex.map { case (unprocessedArg, idx) =>
val arg = argFactory.run(unprocessedArg, idx)
argDefinitions(idx) = arg

val occInfo = unprocessedArg
.unsafeGetMetadata(
AliasAnalysis,
"No occurrence on an argument definition."
)
.unsafeAs[AliasAnalysis.Info.Occurrence]

val slot = scope.createVarSlot(occInfo.id)
val readArg =
ReadArgumentNode.build(idx, arg.getDefaultValue.orElse(null))
val assignArg = AssignmentNode.build(readArg, slot)
val slot = scope.createVarSlot(occInfo.id)
val readArg =
ReadArgumentNode.build(idx, arg.getDefaultValue.orElse(null))
val assignArg = AssignmentNode.build(readArg, slot)

argExpressions.append(assignArg)
argExpressions.append(assignArg)

val argName = arg.getName
val argName = arg.getName

if (seenArgNames contains argName) {
throw new IllegalStateException(
s"A duplicate argument name, $argName, was found during codegen."
)
} else seenArgNames.add(argName)
slot
if (seenArgNames contains argName) {
throw new IllegalStateException(
s"A duplicate argument name, $argName, was found during codegen."
)
} else seenArgNames.add(argName)
slot
}
(argSlots, argDefinitions, argExpressions)

val bodyExpr = body match {
case IR.Foreign.Definition(lang, code, _, _, _) =>
buildForeignBody(
lang,
code,
arguments.map(_.name.name),
argSlots
)
case _ => this.run(body)
}

val fnBodyNode = BlockNode.build(argExpressions.toArray, bodyExpr)
(fnBodyNode, argDefinitions)
}

private def buildForeignBody(
Expand Down Expand Up @@ -1330,18 +1311,18 @@ class IrToTruffle(
body: IR.Expression,
location: Option[IdentifiedLocation]
): CreateFunctionNode = {
val bodyBuilder = new BuildFunctionBody(arguments, body)
val (fnBodyNode, argDefinitions) = buildFunctionBody(arguments, body)
val fnRootNode = ClosureRootNode.build(
language,
scope,
moduleScope,
bodyBuilder.bodyNode(),
fnBodyNode,
makeSection(location),
scopeName
)
val callTarget = Truffle.getRuntime.createCallTarget(fnRootNode)

val expr = CreateFunctionNode.build(callTarget, bodyBuilder.args())
val expr = CreateFunctionNode.build(callTarget, argDefinitions)

setLocation(expr, location)
}
Expand Down

0 comments on commit 2ccdec6

Please sign in to comment.