Skip to content

Commit

Permalink
Speeding up Ordering_Comparator (#10593)
Browse files Browse the repository at this point in the history
  • Loading branch information
JaroslavTulach authored Jul 19, 2024
1 parent 451d7cb commit c0f5759
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ assert_same_comparators this that ~action =
False -> Error.throw (Incomparable_Values.Error this that)

compare_with_comparators this that -> Ordering ! Incomparable_Values =
any_result = Panic.catch Type_Error handler=identity <|
yield_an_error _ = Error.throw (Incomparable_Values.Error this that)
Panic.catch Type_Error handler=yield_an_error <|
comp_this = Comparable.from this
comp_that = Comparable.from that

if Meta.is_same_object comp_this.comparator comp_that.comparator then
any_result = if Meta.is_same_object comp_this.comparator comp_that.comparator then
comp_this.comparator.compare comp_this.value comp_that.value

case any_result of
result:Ordering -> result
_ -> Error.throw (Incomparable_Values.Error this that)
result = any_result:Ordering
result

## PRIVATE
type Positive_Integer_Comparator
Expand All @@ -92,7 +92,10 @@ type Positive_Integer_Comparator
## PRIVATE
type Ordering_Comparator
## PRIVATE
compare x:Ordering y:Ordering = Ordering.compare x.to_sign y.to_sign
compare x:Ordering y:Ordering = if Meta.is_same_object x y then Ordering.Equal else
if Meta.is_same_object x Ordering.Equal . not then x else
if Meta.is_same_object y Ordering.Less then Ordering.Greater else
Ordering.Less

## PRIVATE
hash x:Ordering = x.to_sign
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,8 @@ final Object doThatConversionUncached(
for (var thatType : multi.allTypes()) {
var fn = findSymbol(symbol, thatType);
if (fn != null) {
var result =
doDispatch(
frame, self, multi.castTo(thatType), thatType, fn, convertNode, invokeNode);
var thatCasted = EnsoMultiValue.CastToNode.getUncached().executeCast(thatType, multi);
var result = doDispatch(frame, self, thatCasted, thatType, fn, convertNode, invokeNode);
if (result != null) {
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,10 @@ Object doMultiValue(
UnresolvedConversion conversion,
Object self,
EnsoMultiValue that,
Object[] arguments) {
Object[] arguments,
@Cached EnsoMultiValue.CastToNode castTo) {
var type = extractType(self);
var result = that.castTo(type);
var result = castTo.executeCast(type, that);
if (result == null) {
throw new PanicException(
EnsoContext.get(this).getBuiltins().error().makeNoSuchConversion(type, self, conversion),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,11 @@ Object doMultiValue(
UnresolvedSymbol symbol,
EnsoMultiValue self,
Object[] arguments,
@Shared("methodResolverNode") @Cached MethodResolverNode methodResolverNode) {
@Shared("methodResolverNode") @Cached MethodResolverNode methodResolverNode,
@Cached EnsoMultiValue.CastToNode castTo) {
var fnAndType = self.resolveSymbol(methodResolverNode, symbol);
if (fnAndType != null) {
var unwrapSelf = self.castTo(fnAndType.getRight());
var unwrapSelf = castTo.executeCast(fnAndType.getRight(), self);
if (unwrapSelf != null) {
assert arguments[0] == self;
arguments[0] = unwrapSelf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ abstract static class TypeCheckNode extends ReadArgumentCheckNode {
@Child IsValueOfTypeNode checkType;
@CompilerDirectives.CompilationFinal private String expectedTypeMessage;
@CompilerDirectives.CompilationFinal private LazyCheckRootNode lazyCheck;
@Child private EnsoMultiValue.CastToNode castTo;

TypeCheckNode(String name, Type expectedType) {
super(name);
Expand Down Expand Up @@ -354,7 +355,11 @@ final Object findDirectMatch(VirtualFrame frame, Object v) {
return lazyCheckFn;
}
if (v instanceof EnsoMultiValue mv) {
var result = mv.castTo(expectedType);
if (castTo == null) {
CompilerDirectives.transferToInterpreter();
castTo = insert(EnsoMultiValue.CastToNode.create());
}
var result = castTo.executeCast(expectedType, mv);
if (result != null) {
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.NeverDefault;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
Expand All @@ -12,6 +16,7 @@
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import com.oracle.truffle.api.nodes.Node;
import java.math.BigInteger;
import java.time.Duration;
import java.time.LocalDate;
Expand Down Expand Up @@ -413,19 +418,40 @@ public String toString() {
return Arrays.stream(types).map(t -> t.getName()).collect(Collectors.joining(" & "));
}

/**
* Casts value in this multi value into specific t.
*
* @param type the requested t
* @return instance of the {@code t} or {@code null} if no suitable value was found
*/
public final Object castTo(Type type) {
for (var i = 0; i < types.length; i++) {
if (types[i] == type) {
return values[i];
/** Casts {@link EnsoMultiValue} to requested type effectively. */
@GenerateUncached
public abstract static class CastToNode extends Node {
/**
* Casts value in a multi value into specific type.
*
* @param type the requested t
* @param mv a multi value
* @return instance of the {@code t} or {@code null} if no suitable value was found
*/
public abstract Object executeCast(Type type, EnsoMultiValue mv);

@NeverDefault
public static CastToNode create() {
return EnsoMultiValueFactory.CastToNodeGen.create();
}

@NeverDefault
public static CastToNode getUncached() {
return EnsoMultiValueFactory.CastToNodeGen.getUncached();
}

@Specialization
Object castsToAType(
Type type,
EnsoMultiValue mv,
@Cached(value = "type", allowUncached = true, neverDefault = true) Type cachedType) {
for (var i = 0; i < mv.types.length; i++) {
if (mv.types[i] == cachedType) {
return mv.values[i];
}
}
return null;
}
return null;
}

/**
Expand Down

0 comments on commit c0f5759

Please sign in to comment.