Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More IR mini passes #11501

Merged
merged 67 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
ad6504d
Move ScalaConversions from runtime to engine-common
Akirathan Nov 6, 2024
f811f2e
Convert ImportSymbolAnalysis to mini pass
Akirathan Nov 6, 2024
410bd55
fmt
Akirathan Nov 6, 2024
fd3814a
createForInlineCompilation cannot return null
Akirathan Nov 8, 2024
76af72e
ChainedMiniPass delegates to transformModule
Akirathan Nov 8, 2024
207946f
ImportSymbolAnalysis copies unchanged imports
Akirathan Nov 8, 2024
2e4106b
Fix compilation of a test
Akirathan Nov 8, 2024
eb20aaf
Combining mini passes can result in null
Akirathan Nov 8, 2024
91119ee
Merge branch 'develop' into wip/akirathan/11326-more-mini-passes
Akirathan Nov 14, 2024
8d3c4b3
Add consistency validation to PassManager
Akirathan Nov 15, 2024
cab74dc
Add assert that bindingsMap != null
Akirathan Nov 15, 2024
1935b9e
Consistency validation has better error message.
Akirathan Nov 19, 2024
546f17c
CompilerTestSetup explicitly changes IR in ModuleContext.
Akirathan Nov 19, 2024
289a255
runtime-integration-tests accesses PassManager field via reflection
Akirathan Nov 19, 2024
494975d
Add MiniPassTraverserTest
Akirathan Nov 20, 2024
deadad5
MiniPassTraverser supports end of the traversal
Akirathan Nov 20, 2024
abc32ad
Fix MockMiniPass - stopExpression is not even prepared
Akirathan Nov 20, 2024
806406c
ImportSymbolAnalysis skips processing
Akirathan Nov 20, 2024
eaf10e8
Merge branch 'develop' into wip/akirathan/11326-more-mini-passes
Akirathan Nov 20, 2024
edcd10b
Migrate AmbiguousImportsAnalysis to mini pass and to Java
Akirathan Nov 20, 2024
5493586
Add some tests for chained passes
Akirathan Nov 20, 2024
84a02d9
ChainedMiniPass handles null passes
Akirathan Nov 21, 2024
e0eba27
Fix compilation error in PasesTest
Akirathan Nov 21, 2024
7a047bb
Merge branch 'develop' into wip/akirathan/11326-more-mini-passes
Akirathan Nov 21, 2024
a204ed2
Fix NPE
Akirathan Nov 21, 2024
5a74cc1
Fix errors in polyglot imports
Akirathan Nov 21, 2024
92a0725
Remove unnecessary isntancdeof
Akirathan Nov 21, 2024
62cecbb
MiniPassTest does not call PassManager.runModule directly.
Akirathan Nov 21, 2024
e27a59f
Move tests from runtime-compiler to runtime-integration-tests
Akirathan Nov 21, 2024
2b5c76c
MockMiniPass uses builder pattern
Akirathan Nov 21, 2024
3033462
Remove EventRecorder, MockMiniPass is not IRProcessingPass
Akirathan Nov 21, 2024
0a4ac1f
Move MiniPassTraverserTest back into runtime-compiler/Test
Akirathan Nov 21, 2024
6d2f6c6
PassManager.runInline also chains mini passes.
Akirathan Nov 21, 2024
239029a
MiniPassFactory.createForInlineCompilation can return null.
Akirathan Nov 21, 2024
f2687db
Fix IR inconsistency in TypeInferenceTest
Akirathan Nov 22, 2024
6ead57e
Remove unused method from PassManager
Akirathan Nov 22, 2024
2bcdede
ImportSymbolAnalysis does not support inline compilation.
Akirathan Nov 22, 2024
04181f9
Convert PrivateModuleAnalysis to mini pass
Akirathan Nov 22, 2024
7032b4a
Fix spurious errors
Akirathan Nov 22, 2024
303c9fe
Convert PrivateConstructorAnalysis to mini pass
Akirathan Nov 22, 2024
557f356
FIx compilation error in a test
Akirathan Nov 22, 2024
4e6837f
Convert MethodDefinitions to Java
Akirathan Nov 22, 2024
0bb6b5e
FIx compilation error in a test
Akirathan Nov 22, 2024
866ffd9
Fix NPE
Akirathan Nov 22, 2024
1166f02
FIx compilation error in a test
Akirathan Nov 22, 2024
8d9db8f
MetadataStorage.EMPTY is not a global reference
Akirathan Nov 22, 2024
9136a8b
FIx compilation error in a test
Akirathan Nov 22, 2024
a3321fe
MethodDefinitions.lambdaWithNewSelfArg copies arguments
Akirathan Nov 22, 2024
a47798f
Fix copy of static method in MethodDefinitions
Akirathan Nov 25, 2024
6c77612
Ensure consistency between ModuleContext and IR in uncachedParseModule
Akirathan Nov 25, 2024
a1d2270
Better error message in IrToTruffle.generateReExportBindings
Akirathan Nov 25, 2024
b0ce6c4
Fix No_Such_Method error.
Akirathan Nov 26, 2024
e0f3d31
Merge branch 'develop' into wip/akirathan/11326-more-mini-passes
Akirathan Nov 26, 2024
fb3e29d
Fix invalid IR in GlobalNamesTest
Akirathan Nov 26, 2024
808ae22
Convert MethodDefinitions to mini pass
Akirathan Nov 27, 2024
8d68146
FIx compilation of MethodDefinitionsTest
Akirathan Nov 27, 2024
fe7e50a
Remove TODO comment
Akirathan Nov 27, 2024
417843d
Move ScalaConversions to scala-libs-wrapper
Akirathan Nov 28, 2024
273bea8
Move check for null minipasses to the factory method when combining
Akirathan Nov 28, 2024
bd10bf6
ChainedMiniPass can disable itself from processing subtree
Akirathan Nov 28, 2024
b3f750e
Rename variables
Akirathan Nov 28, 2024
cb5f8c1
ImportSymbolAnalysis is final
Akirathan Nov 28, 2024
85ab82f
Typo in docs
Akirathan Nov 28, 2024
3e1ade9
Make PassManager.passes field private
Akirathan Nov 28, 2024
4380b08
Fix: ChainedMiniPass can disable itself from processing subtree
Akirathan Nov 28, 2024
023d1aa
Add mini pass traverser test
Akirathan Nov 28, 2024
f605f16
PassManager.passes field needs to be protected
Akirathan Nov 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2947,6 +2947,16 @@ lazy val `runtime-integration-tests` =
(`runtime` / javaModuleName).value -> Seq(javaSrcDir, testClassesDir)
)
},
Test / addOpens := {
val compilerModName = (`runtime-compiler` / javaModuleName).value
// In the tests, we access a private field of org.enso.compiler.pass.PassManager via reflection.
Map(
compilerModName + "/org.enso.compiler.pass" -> Seq(
(`runtime` / javaModuleName).value,
"ALL-UNNAMED"
)
)
},
// runtime-integration-tests does not have module descriptor on its own, so we have
// to explicitly add some modules to the resolution.
Test / addModules := Seq(
Expand Down Expand Up @@ -3230,7 +3240,8 @@ lazy val `runtime-compiler` =
"org.yaml" % "snakeyaml" % snakeyamlVersion % Test,
"org.jline" % "jline" % jlineVersion % Test,
"com.typesafe" % "config" % typesafeConfigVersion % Test,
"org.graalvm.polyglot" % "polyglot" % graalMavenPackagesVersion % Test
"org.graalvm.polyglot" % "polyglot" % graalMavenPackagesVersion % Test,
"org.hamcrest" % "hamcrest-all" % hamcrestVersion % Test
),
Compile / moduleDependencies ++= Seq(
"org.slf4j" % "slf4j-api" % slf4jVersion,
Expand All @@ -3241,6 +3252,7 @@ lazy val `runtime-compiler` =
(`pkg` / Compile / exportedModule).value,
(`runtime-parser` / Compile / exportedModule).value,
(`syntax-rust-definition` / Compile / exportedModule).value,
(`scala-libs-wrapper` / Compile / exportedModule).value,
(`persistance` / Compile / exportedModule).value,
(`editions` / Compile / exportedModule).value
),
Expand Down Expand Up @@ -3269,9 +3281,14 @@ lazy val `runtime-compiler` =
javaModuleName.value
),
Test / patchModules := {
// Patch test-classes into the runtime module. This is standard way to deal with the
// split package problem in unit tests. For example, Maven's surefire plugin does this.
val testClassDir = (Test / productDirectories).value.head
// Patching with sources is useful for compilation, patching with compiled classes for runtime.
val javaSrcDir = (Test / javaSource).value
Map(
javaModuleName.value -> Seq(
javaSrcDir,
testClassDir
)
)
Expand Down
1 change: 1 addition & 0 deletions engine/runtime-compiler/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
requires org.enso.runtime.parser;
requires static org.enso.persistance;
requires org.enso.syntax;
requires org.enso.scala.wrapper;

requires org.openide.util.lookup.RELEASE180;
requires org.slf4j;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package org.enso.compiler;

import org.enso.compiler.core.IR;
import org.enso.compiler.core.ir.MetadataStorage.MetadataPair;
import org.enso.compiler.core.ir.ProcessingPass;
import org.enso.compiler.pass.IRPass;
import org.enso.compiler.pass.IRProcessingPass;
import scala.Option;

/**
Expand All @@ -11,7 +12,7 @@
* <p>This encapsulates the friction of interop between Scala and Java types.
*/
public final class MetadataInteropHelpers {
public static <T> T getMetadataOrNull(IR ir, IRPass pass, Class<T> expectedType) {
public static <T> T getMetadataOrNull(IR ir, IRProcessingPass pass, Class<T> expectedType) {
Option<ProcessingPass.Metadata> option = ir.passData().get(pass);
if (option.isDefined()) {
try {
Expand All @@ -30,7 +31,7 @@ public static <T> T getMetadataOrNull(IR ir, IRPass pass, Class<T> expectedType)
}
}

public static <T> T getMetadata(IR ir, IRPass pass, Class<T> expectedType) {
public static <T> T getMetadata(IR ir, IRProcessingPass pass, Class<T> expectedType) {
T metadataOrNull = getMetadataOrNull(ir, pass, expectedType);
if (metadataOrNull == null) {
throw new IllegalStateException("Missing expected " + pass + " metadata for " + ir + ".");
Expand All @@ -39,5 +40,11 @@ public static <T> T getMetadata(IR ir, IRPass pass, Class<T> expectedType) {
return metadataOrNull;
}

public static <T extends ProcessingPass> void updateMetadata(
IR ir, T pass, ProcessingPass.Metadata metadata) {
var metaPair = new MetadataPair<>(pass, metadata);
ir.passData().update(metaPair);
}

private MetadataInteropHelpers() {}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.enso.compiler.pass;

import java.util.Objects;
import org.enso.compiler.core.IR;
import org.enso.compiler.core.ir.Expression;
import org.enso.compiler.core.ir.Module;

/** Utility class for chaining mini passes together. */
final class ChainedMiniPass extends MiniIRPass {
Expand All @@ -15,37 +15,43 @@ private ChainedMiniPass(MiniIRPass firstPass, MiniIRPass secondPass) {
}

static MiniIRPass chain(MiniIRPass firstPass, MiniIRPass secondPass) {
if (firstPass == null) {
return secondPass;
}
return new ChainedMiniPass(firstPass, secondPass);
}

@Override
public MiniIRPass prepare(IR parent, Expression current) {
var first = firstPass.prepare(parent, current);
var second = secondPass.prepare(parent, current);
if (first == firstPass && second == secondPass) {
var firstPrepared = firstPass == null ? null : firstPass.prepare(parent, current);
var secondPrepared = secondPass == null ? null : secondPass.prepare(parent, current);
if (firstPrepared == firstPass && secondPrepared == secondPass) {
return this;
} else {
return new ChainedMiniPass(first, second);
return new ChainedMiniPass(firstPrepared, secondPrepared);
}
}

@Override
public Expression transformExpression(Expression ir) {
var fstIr = firstPass.transformExpression(ir);
var sndIr = secondPass.transformExpression(fstIr);
var fstIr = firstPass == null ? ir : firstPass.transformExpression(ir);
var sndIr = secondPass == null ? fstIr : secondPass.transformExpression(fstIr);
return sndIr;
}

@Override
public Module transformModule(Module moduleIr) {
var first = firstPass == null ? moduleIr : firstPass.transformModule(moduleIr);
var second = secondPass == null ? first : secondPass.transformModule(first);
return second;
}

@Override
public boolean checkPostCondition(IR ir) {
return firstPass.checkPostCondition(ir) && secondPass.checkPostCondition(ir);
var firstCheck = firstPass == null || firstPass.checkPostCondition(ir);
var secondCheck = secondPass == null || secondPass.checkPostCondition(ir);
return firstCheck && secondCheck;
}

@Override
public String toString() {
return Objects.toString(firstPass) + ":" + Objects.toString(secondPass);
return "{" + firstPass + " + " + secondPass + "}";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ public interface IRProcessingPass extends ProcessingPass {
/** The passes that this pass depends _directly_ on to run. */
public Seq<? extends IRProcessingPass> precursorPasses();

/** The passes that are invalidated by running this pass. */
/**
* The passes that are invalidated by running this pass.
*
* <p>If {@code P1} invalidates {@code P2}, and {@code P1} is a precursor of {@code P2}, then
* {@code P1} must finish before {@code P2} starts.
*/
public Seq<? extends IRProcessingPass> invalidatedPasses();
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ public abstract class MiniIRPass {
*
* @param parent the the parent of the edge
* @param child the child expression element to be be processed.
* @return an instance of the pass to process the child's element subtree
* @return an instance of the pass to process the child's element subtree. If null is returned,
* the subtree of the child element is not processed, including {@code child} (i.e. {@code
* child} is not processed as well).
*/
public MiniIRPass prepare(IR parent, Expression child) {
return this;
Expand Down Expand Up @@ -103,10 +105,17 @@ public String toString() {
* Combines two mini IR passes into one that delegates to both of them.
*
* @param first first mini pass (can be {@code null})
* @param second second mini pass
* @return a combined pass that calls both non-{@code null} of the provided passes
* @param second second mini pass (can be {@code null})
* @return a combined pass that calls both non-{@code null} of the provided passes. {@code null}
* if both provided passes are {@code null}.
*/
public static MiniIRPass combine(MiniIRPass first, MiniIRPass second) {
if (first == null) {
return second;
}
if (second == null) {
return first;
}
return ChainedMiniPass.chain(first, second);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ public interface MiniPassFactory extends IRProcessingPass {
* a module.
*
* @param moduleContext A mini pass can optionally save reference to this module context.
* @return May return {@code null} if module compilation is not supported.
* @return May return {@code null} if module compilation is not supported, or if the compilation
* for the given {@code moduleContext} should be skipped.
*/
MiniIRPass createForModuleCompilation(ModuleContext moduleContext);

Expand All @@ -25,7 +26,7 @@ public interface MiniPassFactory extends IRProcessingPass {
* an inline compilation.
*
* @param inlineContext A mini pass can optionally save reference to this inline context.
* @return Must not return {@code null}. Inline compilation should always be supported.
* @return May return {@code null} if the inline compilation is not supported.
*/
MiniIRPass createForInlineCompilation(InlineContext inlineContext);
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static IR compileDeep(IR root, MiniIRPass miniPass) {
* @param queue queue to put objects in
* @param ir IR to process
* @param miniPass process with this mini pass
* @return {@code true} if the has been modified with new tries to process first
* @return {@code true} if the {@code queue} has been modified with new tries to process first
*/
private static List<IR> enqueueSubExpressions(
Collection<MiniPassTraverser> queue, IR ir, MiniIRPass miniPass) {
Expand All @@ -81,7 +81,9 @@ private static List<IR> enqueueSubExpressions(
(ch) -> {
var preparedMiniPass = miniPass.prepare(ir, ch);
childExpressions.add(ch);
queue.add(new MiniPassTraverser(preparedMiniPass, childExpressions, i[0]++));
if (preparedMiniPass != null) {
queue.add(new MiniPassTraverser(preparedMiniPass, childExpressions, i[0]++));
}
return ch;
});
return childExpressions;
Expand Down
Loading
Loading