-
Notifications
You must be signed in to change notification settings - Fork 326
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
Fix inline compilation benchmarks and Improve searching Graph.Link performance #9520
Changes from all commits
82a32a1
7aa8a14
86dda53
33c2183
e34e229
6fc958b
bddd484
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package org.enso.compiler.benchmarks.inline; | ||
|
||
import java.io.IOException; | ||
import org.enso.compiler.context.InlineContext; | ||
|
||
/** | ||
* InlineContextResource ensures that the underlying InlineContext is properly cleaned up after | ||
* usage. | ||
* | ||
* @param inlineContext InlineContext for the main method | ||
*/ | ||
public record InlineContextResource(InlineContext inlineContext) implements AutoCloseable { | ||
@Override | ||
public void close() throws IOException { | ||
inlineContext | ||
.localScope() | ||
.foreach( | ||
s -> { | ||
s.scope().removeScopeFromParent(); | ||
return null; | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.enso.compiler.benchmarks.inline; | ||
|
||
import org.enso.compiler.PackageRepository; | ||
import org.enso.compiler.context.InlineContext; | ||
import org.enso.interpreter.node.MethodRootNode; | ||
import org.enso.interpreter.runtime.EnsoContext; | ||
import org.enso.interpreter.runtime.data.Type; | ||
import org.enso.interpreter.runtime.scope.ModuleScope; | ||
|
||
public record InlineContextResourceFactory( | ||
ModuleScope moduleScope, | ||
Type assocTypeReceiver, | ||
EnsoContext ensoCtx, | ||
PackageRepository pkgRepository) { | ||
|
||
public InlineContextResource create() { | ||
var mainFunc = moduleScope.getMethodForType(assocTypeReceiver, "main"); | ||
var mainFuncRootNode = (MethodRootNode) mainFunc.getCallTarget().getRootNode(); | ||
var mainLocalScope = mainFuncRootNode.getLocalScope(); | ||
return new InlineContextResource( | ||
InlineContext.fromJava( | ||
mainLocalScope.createChild(), | ||
moduleScope.getModule().asCompilerModule(), | ||
scala.Option.apply(false), | ||
ensoCtx.getCompilerConfig(), | ||
scala.Option.apply(pkgRepository))); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,10 @@ | ||
package org.enso.compiler.benchmarks.inline; | ||
|
||
import java.util.Set; | ||
import org.enso.compiler.context.InlineContext; | ||
|
||
record InlineSource( | ||
String source, | ||
// InlineContext for the main method | ||
InlineContext mainInlineContext, | ||
// InlineContextResource for the main method | ||
InlineContextResourceFactory inlineContextFactory, | ||
// Local variables in main method | ||
Set<String> localVarNames) {} |
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,14 +5,17 @@ import org.enso.syntax.text.Debug | |||||||||||
import org.enso.compiler.pass.analyse.alias.Graph.{Occurrence, Scope} | ||||||||||||
|
||||||||||||
import java.util.UUID | ||||||||||||
import scala.collection.immutable.HashMap | ||||||||||||
import scala.collection.mutable | ||||||||||||
import scala.reflect.ClassTag | ||||||||||||
|
||||||||||||
/** A graph containing aliasing information for a given root scope in Enso. */ | ||||||||||||
sealed class Graph extends Serializable { | ||||||||||||
var rootScope: Graph.Scope = new Graph.Scope() | ||||||||||||
var links: Set[Graph.Link] = Set() | ||||||||||||
var nextIdCounter = 0 | ||||||||||||
var rootScope: Graph.Scope = new Graph.Scope() | ||||||||||||
private var links: Set[Graph.Link] = Set() | ||||||||||||
private var sourceLinks: Map[Graph.Id, Set[Graph.Link]] = new HashMap() | ||||||||||||
private var targetLinks: Map[Graph.Id, Set[Graph.Link]] = new HashMap() | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an implementation of serialization logic for the enso/engine/runtime-compiler/src/main/java/org/enso/compiler/pass/analyse/PassPersistance.java Lines 153 to 157 in 6665c22
Please make sure that it works correctly with the newly added fields and probably update the serialization id There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should work correctly as I'm reproducing |
||||||||||||
var nextIdCounter = 0 | ||||||||||||
|
||||||||||||
private var globalSymbols: Map[Graph.Symbol, Occurrence.Global] = | ||||||||||||
Map() | ||||||||||||
|
@@ -24,11 +27,22 @@ sealed class Graph extends Serializable { | |||||||||||
val copy = new Graph | ||||||||||||
copy.rootScope = this.rootScope.deepCopy(scope_mapping) | ||||||||||||
copy.links = this.links | ||||||||||||
copy.sourceLinks = this.sourceLinks | ||||||||||||
copy.targetLinks = this.targetLinks | ||||||||||||
copy.globalSymbols = this.globalSymbols | ||||||||||||
copy.nextIdCounter = this.nextIdCounter | ||||||||||||
copy | ||||||||||||
} | ||||||||||||
|
||||||||||||
def initLinks(links: Set[Graph.Link]): Unit = { | ||||||||||||
hubertp marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
sourceLinks = new HashMap() | ||||||||||||
targetLinks = new HashMap() | ||||||||||||
links.foreach(addSourceTargetLink) | ||||||||||||
this.links = links | ||||||||||||
} | ||||||||||||
|
||||||||||||
def getLinks(): Set[Graph.Link] = links | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be better to remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kind of like that |
||||||||||||
|
||||||||||||
/** Registers a requested global symbol in the aliasing scope. | ||||||||||||
* | ||||||||||||
* @param sym the symbol occurrence | ||||||||||||
|
@@ -46,6 +60,8 @@ sealed class Graph extends Serializable { | |||||||||||
def copy: Graph = { | ||||||||||||
val graph = new Graph | ||||||||||||
graph.links = links | ||||||||||||
graph.sourceLinks = sourceLinks | ||||||||||||
graph.targetLinks = targetLinks | ||||||||||||
graph.rootScope = rootScope.deepCopy(mutable.Map()) | ||||||||||||
graph.nextIdCounter = nextIdCounter | ||||||||||||
|
||||||||||||
|
@@ -85,10 +101,20 @@ sealed class Graph extends Serializable { | |||||||||||
): Option[Graph.Link] = { | ||||||||||||
scopeFor(occurrence.id).flatMap(_.resolveUsage(occurrence).map { link => | ||||||||||||
links += link | ||||||||||||
addSourceTargetLink(link) | ||||||||||||
link | ||||||||||||
}) | ||||||||||||
} | ||||||||||||
|
||||||||||||
private def addSourceTargetLink(link: Graph.Link): Unit = { | ||||||||||||
sourceLinks = sourceLinks.updatedWith(link.source)(v => | ||||||||||||
v.map(s => s + link).orElse(Some(Set(link))) | ||||||||||||
) | ||||||||||||
targetLinks = targetLinks.updatedWith(link.target)(v => | ||||||||||||
v.map(s => s + link).orElse(Some(Set(link))) | ||||||||||||
) | ||||||||||||
} | ||||||||||||
|
||||||||||||
/** Resolves any links for the given usage of a symbol, assuming the symbol | ||||||||||||
* is global (i.e. method, constructor etc.) | ||||||||||||
* | ||||||||||||
|
@@ -129,7 +155,10 @@ sealed class Graph extends Serializable { | |||||||||||
* @return a list of links in which `id` occurs | ||||||||||||
*/ | ||||||||||||
def linksFor(id: Graph.Id): Set[Graph.Link] = { | ||||||||||||
links.filter(l => l.source == id || l.target == id) | ||||||||||||
sourceLinks.getOrElse(id, Set.empty[Graph.Link]) ++ targetLinks.getOrElse( | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great finding. Good fix. Thank you. |
||||||||||||
id, | ||||||||||||
Set() | ||||||||||||
) | ||||||||||||
} | ||||||||||||
|
||||||||||||
/** Finds all links in the graph where `symbol` appears in the role | ||||||||||||
|
@@ -646,6 +675,17 @@ object Graph { | |||||||||||
|
||||||||||||
isDirectChildOf || isChildOfChildren | ||||||||||||
} | ||||||||||||
|
||||||||||||
private def removeScopeFromParent(scope: Scope): Unit = { | ||||||||||||
childScopes = childScopes.filter(_ != scope) | ||||||||||||
hubertp marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
} | ||||||||||||
|
||||||||||||
/** Disassociates this Scope from its parent. | ||||||||||||
*/ | ||||||||||||
def removeScopeFromParent(): Unit = { | ||||||||||||
assert(this.parent.nonEmpty) | ||||||||||||
this.parent.foreach(_.removeScopeFromParent(this)) | ||||||||||||
} | ||||||||||||
} | ||||||||||||
|
||||||||||||
/** A link in the [[Graph]]. | ||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If
initXyz
is better pattern than callingg.rootScope_$eq(rootScope);
- thenrootScope
could be made private as well, possibly.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried and looks like a lot more stuff depends on it being public. I tried to keep the PR succinct for now.