Skip to content

Commit

Permalink
Merge branch 'develop' into wip/hubert/11325-uuids-type-error
Browse files Browse the repository at this point in the history
  • Loading branch information
hubertp committed Oct 18, 2024
2 parents 5c19e63 + 7522acf commit 82b31aa
Show file tree
Hide file tree
Showing 9 changed files with 474 additions and 113 deletions.
98 changes: 98 additions & 0 deletions engine/common/src/main/java/org/enso/common/CachePreferences.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package org.enso.common;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

/**
* Contains settings telling which nodes are marked for caching and their kinds.
*
* @param preferences the config with cached preferences
*/
public record CachePreferences(Map<UUID, Kind> preferences) {

/**
* @return empty cache preferences config
*/
public static CachePreferences empty() {
return new CachePreferences(new HashMap<>());
}

/** A kind of cached value. */
public enum Kind {
BINDING_EXPRESSION,
SELF_ARGUMENT
}

/**
* Get the cache preference for the provided node id.
*
* @param id the node id
* @return the kind of cached value if available
*/
public Kind get(UUID id) {
return preferences.get(id);
}

/**
* Get all the node ids marked for caching for a particular node kind.
*
* @param kind the node kind
* @return the set of node ids marked for caching
*/
public Set<UUID> get(Kind kind) {
var result = new HashSet<UUID>();
for (var entry : preferences.entrySet()) {
if (entry.getValue().equals(kind)) {
result.add(entry.getKey());
}
}

return result;
}

/**
* Add a cache preference.
*
* @param id the node id
* @param kind the node kind
*/
public void set(UUID id, Kind kind) {
preferences.put(id, kind);
}

/**
* Remove the cache preference.
*
* @param id the node id to remove
*/
public void remove(UUID id) {
preferences.remove(id);
}

/**
* Check if the provided node id is marked for caching.
*
* @param id the node id
* @return return {@code true} if the provided node id is marked for caching
*/
public boolean contains(UUID id) {
return preferences.containsKey(id);
}

/** Clear all the cache preferences. */
public void clear() {
preferences.clear();
}

/**
* Make a copy of this cache preferences.
*
* @return a copy of this cache preferences
*/
public CachePreferences copy() {
return new CachePreferences(new HashMap<>(preferences));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.enso.compiler.pass.analyse;

import java.io.IOException;
import org.enso.common.CachePreferences;
import org.enso.compiler.pass.analyse.alias.AliasMetadata;
import org.enso.compiler.pass.analyse.alias.graph.Graph;
import org.enso.compiler.pass.analyse.alias.graph.GraphOccurrence;
Expand Down Expand Up @@ -67,6 +68,7 @@
@Persistable(clazz = TypeInference.class, id = 1280)
@Persistable(clazz = FramePointerAnalysis$.class, id = 1281)
@Persistable(clazz = TailCall.TailPosition.class, id = 1282)
@Persistable(clazz = CachePreferences.class, id = 1284)
public final class PassPersistance {
private PassPersistance() {}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.enso.compiler.pass.analyse

import org.enso.common.CachePreferences
import org.enso.compiler.context.{InlineContext, ModuleContext}
import org.enso.compiler.core.Implicits.AsMetadata
import org.enso.compiler.core.ir.CallArgument.Specified
Expand All @@ -20,19 +21,12 @@ import org.enso.compiler.pass.IRPass
import org.enso.compiler.pass.IRProcessingPass
import org.enso.compiler.pass.desugar._

import java.util
import java.util.UUID
import scala.collection.mutable
import scala.jdk.CollectionConverters._

/** This pass implements the preference analysis for caching.
*
* The pass assigns weights to the expressions. The greater the weight, the
* more preferable the expression for caching.
*
* Weights:
*
* - `1` - Right hand side expressions
* The pass assigns preferences to the expressions. To mark the expression for
* caching, it should be added to the [[CachePreferences]] configuration.
*/
case object CachePreferenceAnalysis extends IRPass {

Expand Down Expand Up @@ -143,9 +137,8 @@ case object CachePreferenceAnalysis extends IRPass {
): Expression = {
expression.transformExpressions {
case binding: Expression.Binding =>
binding.getExternalId.foreach(weights.update(_, Weight.Never))
binding.expression.getExternalId
.foreach(weights.update(_, Weight.Always))
.foreach(weights.update(_, CachePreferences.Kind.BINDING_EXPRESSION))
binding
.copy(
name = binding.name.updateMetadata(new MetadataPair(this, weights)),
Expand All @@ -163,10 +156,6 @@ case object CachePreferenceAnalysis extends IRPass {
app
}
case expr =>
expr.getExternalId.foreach {
case id if !weights.contains(id) => weights.update(id, Weight.Never)
case _ =>
}
expr
.mapExpressions(analyseExpression(_, weights))
.updateMetadata(new MetadataPair(this, weights))
Expand All @@ -177,13 +166,13 @@ case object CachePreferenceAnalysis extends IRPass {
callArgument: CallArgument,
weights: WeightInfo
): CallArgument = {
callArgument.value.getExternalId.foreach(weights.update(_, Weight.Always))
callArgument.value.getExternalId
.foreach(weights.update(_, CachePreferences.Kind.SELF_ARGUMENT))
callArgument match {
case arg: Specified =>
arg.copy(value =
analyseExpression(arg.value, weights).updateMetadata(
new MetadataPair(this, weights)
)
analyseExpression(arg.value, weights)
.updateMetadata(new MetadataPair(this, weights))
)
}
}
Expand Down Expand Up @@ -213,7 +202,7 @@ case object CachePreferenceAnalysis extends IRPass {
* @param weights the storage for weights of the program components
*/
sealed case class WeightInfo(
weights: mutable.HashMap[UUID @ExternalID, Double] = mutable.HashMap()
preferences: CachePreferences = CachePreferences.empty()
) extends IRPass.IRMetadata {

/** The name of the metadata as a string. */
Expand All @@ -230,35 +219,13 @@ case object CachePreferenceAnalysis extends IRPass {
/** Assign the weight to an id.
*
* @param id the external id
* @param weight the assigned weight
* @param kind the assigned expression kind
*/
def update(id: UUID @ExternalID, weight: Double): Unit =
weights.put(id, weight)

/** Get the weight associated with given id */
def get(id: UUID @ExternalID): Double =
weights.getOrElse(id, Weight.Never)

/** Check if the weight is assigned to this id. */
def contains(id: UUID @ExternalID): Boolean =
weights.contains(id)
def update(id: UUID @ExternalID, kind: CachePreferences.Kind): Unit =
preferences.set(id, kind)

/** @return weights as the Java collection */
def asJavaWeights: util.Map[UUID @ExternalID, java.lang.Double] =
weights.asJava
.asInstanceOf[util.Map[UUID @ExternalID, java.lang.Double]]

override def duplicate(): Option[IRPass.IRMetadata] =
Some(copy(weights = this.weights))
}

/** Weight constants */
object Weight {

/** Maximum weight meaning that the program component is always cached. */
val Always: Double = 1.0

/** Minimum weight meaning that the program component is never cached. */
val Never: Double = 0.0
override def duplicate(): Option[IRPass.IRMetadata] = {
Some(copy(preferences = this.preferences.copy()))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.enso.common.CachePreferences;
import org.enso.interpreter.service.ExecutionService;

/** A storage for computed values. */
Expand All @@ -18,7 +19,7 @@ public final class RuntimeCache implements java.util.function.Function<String, O
private final Map<UUID, Reference<Object>> expressions = new HashMap<>();
private final Map<UUID, String> types = new HashMap<>();
private final Map<UUID, ExecutionService.FunctionCallInfo> calls = new HashMap<>();
private Map<UUID, Double> weights = new HashMap<>();
private CachePreferences preferences = CachePreferences.empty();
private Consumer<UUID> observer;

/**
Expand All @@ -30,8 +31,7 @@ public final class RuntimeCache implements java.util.function.Function<String, O
*/
@CompilerDirectives.TruffleBoundary
public boolean offer(UUID key, Object value) {
var weight = weights.get(key);
if (weight != null && weight > 0) {
if (preferences.contains(key)) {
var ref = new SoftReference<>(value);
cache.put(key, ref);
expressions.put(key, new WeakReference<>(value));
Expand Down Expand Up @@ -87,6 +87,20 @@ public void clear() {
cache.clear();
}

/**
* Clear cached values of the provided kind.
*
* @param kind the kind of cached value to clear
* @return the set of cleared keys
*/
public Set<UUID> clear(CachePreferences.Kind kind) {
var keys = preferences.get(kind);
for (var key : keys) {
cache.remove(key);
}
return keys;
}

/**
* Cache the type of expression.
*
Expand Down Expand Up @@ -161,25 +175,33 @@ public void clearTypes() {
}

/**
* @return the weights of this cache.
* @return the preferences of this cache.
*/
public Map<UUID, Double> getWeights() {
return weights;
public CachePreferences getPreferences() {
return preferences;
}

/** Set the new weights. */
public void setWeights(Map<UUID, Double> weights) {
this.weights = weights;
/**
* Set the new cache preferences.
*
* @param preferences the new cache preferences
*/
public void setPreferences(CachePreferences preferences) {
this.preferences = preferences;
}

/** Remove the weight associated with the provided key. */
public void removeWeight(UUID key) {
weights.remove(key);
/**
* Remove the cache preference associated with the provided key.
*
* @param key the preference to remove
*/
public void removePreference(UUID key) {
preferences.remove(key);
}

/** Clear the weights. */
public void clearWeights() {
weights.clear();
/** Clear the cache preferences. */
public void clearPreferences() {
preferences.clear();
}

/**
Expand Down
Loading

0 comments on commit 82b31aa

Please sign in to comment.