mirror of
https://github.com/enso-org/enso.git
synced 2024-12-23 17:34:10 +03:00
Optimize AliasAnalysis hotspot (#8701)
`scopeFor` is a real hotspot that hasn't been particularly optimized. By using iterator and a simple variable instead of a list and checking its length I was able to get 10% speedup. Note that it seems tempting to throw the exception within the loop but that seems to create a less optimized code. # Important Notes I'm consistently getting ~10% speedup on a hello world example (with standard libraries). For example I'm no longer seeing 20ms spent in `scopeFor` and most of them are below 10ms: ![Screenshot from 2024-01-08 12-15-30](https://github.com/enso-org/enso/assets/292128/033ece07-eb15-45b5-971f-417bf9f17ef7) Before ![Screenshot from 2024-01-08 12-17-32](https://github.com/enso-org/enso/assets/292128/3848d7c2-0fe8-4951-b222-c8f40d2daf01) After ![Screenshot from 2024-01-08 12-17-09](https://github.com/enso-org/enso/assets/292128/524496f5-3cf0-47f4-8b05-edd330080b14)
This commit is contained in:
parent
fc0361f502
commit
a94cad6bfa
@ -1010,16 +1010,10 @@ case object AliasAnalysis extends IRPass {
|
||||
def resolveLocalUsage(
|
||||
occurrence: Graph.Occurrence.Use
|
||||
): Option[Graph.Link] = {
|
||||
scopeFor(occurrence.id) match {
|
||||
case Some(scope) =>
|
||||
scope.resolveUsage(occurrence) match {
|
||||
case Some(link) =>
|
||||
links += link
|
||||
Some(link)
|
||||
case None => None
|
||||
}
|
||||
case None => None
|
||||
}
|
||||
scopeFor(occurrence.id).flatMap(_.resolveUsage(occurrence).map { link =>
|
||||
links += link
|
||||
link
|
||||
})
|
||||
}
|
||||
|
||||
/** Resolves any links for the given usage of a symbol, assuming the symbol
|
||||
@ -1457,20 +1451,35 @@ case object AliasAnalysis extends IRPass {
|
||||
def scopeFor(id: Graph.Id): Option[Scope] = {
|
||||
val possibleCandidates = occurrences.filter(o => o.id == id)
|
||||
|
||||
if (possibleCandidates.size == 1) {
|
||||
Some(this)
|
||||
} else if (possibleCandidates.isEmpty) {
|
||||
val childCandidates = childScopes.map(_.scopeFor(id)).collect {
|
||||
case Some(scope) => scope
|
||||
}
|
||||
|
||||
if (childCandidates.length == 1) {
|
||||
Some(childCandidates.head)
|
||||
} else if (childCandidates.isEmpty) {
|
||||
if (possibleCandidates.isEmpty) {
|
||||
if (childScopes.isEmpty) {
|
||||
None
|
||||
} else {
|
||||
throw new CompilerError(s"ID $id defined in multiple scopes.")
|
||||
var childCandidate: Scope = null
|
||||
val iter = childScopes.iterator
|
||||
var moreThanOne = false
|
||||
while (iter.hasNext && !moreThanOne) {
|
||||
iter.next().scopeFor(id) match {
|
||||
case Some(s) =>
|
||||
if (childCandidate == null) {
|
||||
childCandidate = s
|
||||
} else {
|
||||
moreThanOne = true
|
||||
}
|
||||
case None =>
|
||||
}
|
||||
}
|
||||
|
||||
if (childCandidate == null) {
|
||||
None
|
||||
} else if (moreThanOne) {
|
||||
throw new CompilerError(s"ID $id defined in multiple scopes.")
|
||||
} else {
|
||||
Some(childCandidate)
|
||||
}
|
||||
}
|
||||
} else if (possibleCandidates.size == 1) {
|
||||
Some(this)
|
||||
} else {
|
||||
throw new CompilerError(s"Multiple occurrences found for ID $id.")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user