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

Add supernodes for < and > #222

Merged
merged 3 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
34 changes: 25 additions & 9 deletions src/trufflesom/src/trufflesom/compiler/ParserAst.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
import static trufflesom.vm.SymbolTable.strSelf;
import static trufflesom.vm.SymbolTable.strSuper;
import static trufflesom.vm.SymbolTable.symNil;
import static trufflesom.vm.SymbolTable.symSelf;
import static trufflesom.vm.SymbolTable.symSuper;
import static trufflesom.vm.SymbolTable.symbolFor;

import java.math.BigInteger;
Expand Down Expand Up @@ -45,11 +43,15 @@
import trufflesom.interpreter.nodes.literals.GenericLiteralNode;
import trufflesom.interpreter.nodes.literals.IntegerLiteralNode;
import trufflesom.interpreter.nodes.literals.LiteralNode;
import trufflesom.interpreter.supernodes.LocalFieldStringEqualsNode;
import trufflesom.interpreter.supernodes.compare.GreaterThanIntNodeGen;
import trufflesom.interpreter.supernodes.compare.LessThanIntNodeGen;
import trufflesom.interpreter.supernodes.compare.LocalArgGreaterThanInt;
import trufflesom.interpreter.supernodes.compare.LocalArgLessThanInt;
import trufflesom.interpreter.supernodes.compare.LocalFieldStringEqualsNode;
import trufflesom.interpreter.supernodes.LocalVariableSquareNodeGen;
import trufflesom.interpreter.supernodes.NonLocalFieldStringEqualsNode;
import trufflesom.interpreter.supernodes.compare.NonLocalFieldStringEqualsNode;
import trufflesom.interpreter.supernodes.NonLocalVariableSquareNodeGen;
import trufflesom.interpreter.supernodes.StringEqualsNodeGen;
import trufflesom.interpreter.supernodes.compare.StringEqualsNodeGen;
import trufflesom.interpreter.supernodes.inc.IncExpWithValueNodeGen;
import trufflesom.primitives.Primitives;
import trufflesom.vm.Globals;
Expand Down Expand Up @@ -331,6 +333,20 @@ protected ExpressionNode binaryMessage(final MethodGenerationContext mgenc,
} else if (msg == SymbolTable.symMinus && operand instanceof IntegerLiteralNode lit) {
long litValue = lit.executeLong(null);
return IncExpWithValueNodeGen.create(-litValue, true, receiver).initialize(coordWithL);
} else if (binSelector.equals(">") && operand instanceof IntegerLiteralNode lit) {
long litValue = lit.executeLong(null);

if (receiver instanceof LocalArgumentReadNode arg) {
return new LocalArgGreaterThanInt(arg.getArg(), litValue).initialize(coordWithL);
}
return GreaterThanIntNodeGen.create(litValue, receiver).initialize(coordWithL);
} else if (binSelector.equals("<") && operand instanceof IntegerLiteralNode lit) {
long litValue = lit.executeLong(null);

if (receiver instanceof LocalArgumentReadNode arg) {
return new LocalArgLessThanInt(arg.getArg(), litValue).initialize(coordWithL);
}
return LessThanIntNodeGen.create(litValue, receiver).initialize(coordWithL);
}

ExpressionNode inlined =
Expand Down Expand Up @@ -360,21 +376,21 @@ protected ExpressionNode keywordMessage(final MethodGenerationContext mgenc,

SSymbol msg = symbolFor(kw.toString());

long coodWithL = getCoordWithLength(coord);
long coordWithL = getCoordWithLength(coord);

ExpressionNode[] args = arguments.toArray(new ExpressionNode[0]);
if (isSuperSend) {
return MessageSendNode.createSuperSend(
mgenc.getHolder().getSuperClass(), msg, args, coodWithL);
mgenc.getHolder().getSuperClass(), msg, args, coordWithL);
}

ExpressionNode inlined = inlinableNodes.inline(msg, args, mgenc, coodWithL);
ExpressionNode inlined = inlinableNodes.inline(msg, args, mgenc, coordWithL);
if (inlined != null) {
assert !isSuperSend;
return inlined;
}

return MessageSendNode.create(msg, args, coodWithL);
return MessageSendNode.create(msg, args, coordWithL);
}

private ExpressionNode formula(final MethodGenerationContext mgenc)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package trufflesom.interpreter.supernodes.compare;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import trufflesom.interpreter.bc.RespecializeException;
import trufflesom.interpreter.nodes.ExpressionNode;
import trufflesom.interpreter.nodes.GenericMessageSendNode;
import trufflesom.interpreter.nodes.MessageSendNode;
import trufflesom.interpreter.nodes.bc.BytecodeLoopNode;
import trufflesom.interpreter.nodes.literals.IntegerLiteralNode;
import trufflesom.interpreter.nodes.nary.UnaryExpressionNode;
import trufflesom.vm.SymbolTable;
import trufflesom.vm.VmSettings;
import trufflesom.vmobjects.SSymbol;


public abstract class GreaterThanIntNode extends UnaryExpressionNode {
private final long intValue;

public GreaterThanIntNode(final long intValue) {
this.intValue = intValue;
}

@Override
public abstract ExpressionNode getReceiver();

@Specialization
public final boolean doLong(final long rcvr) {
return rcvr > intValue;
}

@Specialization
public final boolean doDouble(final double rcvr) {
return rcvr > intValue;
}

@Fallback
public final Object makeGenericSend(final VirtualFrame frame,
final Object receiver) {
CompilerDirectives.transferToInterpreterAndInvalidate();
return makeGenericSend(SymbolTable.symbolFor(">")).doPreEvaluated(frame,
new Object[] {receiver, intValue});
}

@Override
protected GenericMessageSendNode makeGenericSend(final SSymbol selector) {
CompilerDirectives.transferToInterpreterAndInvalidate();
GenericMessageSendNode send = MessageSendNode.createGeneric(selector,
new ExpressionNode[] {getReceiver(), new IntegerLiteralNode(intValue)}, sourceCoord);

if (VmSettings.UseAstInterp) {
replace(send);
send.notifyDispatchInserted();
return send;
}

assert getParent() instanceof BytecodeLoopNode : "This node was expected to be a direct child of a `BytecodeLoopNode`.";
throw new RespecializeException(send);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package trufflesom.interpreter.supernodes.compare;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import trufflesom.interpreter.bc.RespecializeException;
import trufflesom.interpreter.nodes.ExpressionNode;
import trufflesom.interpreter.nodes.GenericMessageSendNode;
import trufflesom.interpreter.nodes.MessageSendNode;
import trufflesom.interpreter.nodes.bc.BytecodeLoopNode;
import trufflesom.interpreter.nodes.literals.IntegerLiteralNode;
import trufflesom.interpreter.nodes.nary.UnaryExpressionNode;
import trufflesom.vm.SymbolTable;
import trufflesom.vm.VmSettings;
import trufflesom.vmobjects.SSymbol;


public abstract class LessThanIntNode extends UnaryExpressionNode {
private final long intValue;

public LessThanIntNode(final long intValue) {
this.intValue = intValue;
}

@Override
public abstract ExpressionNode getReceiver();

@Specialization
public final boolean doLong(final long rcvr) {
return rcvr < intValue;
}

@Specialization
public final boolean doDouble(final double rcvr) {
return rcvr < intValue;
}

@Fallback
public final Object makeGenericSend(final VirtualFrame frame,
final Object receiver) {
CompilerDirectives.transferToInterpreterAndInvalidate();
return makeGenericSend(SymbolTable.symbolFor("<")).doPreEvaluated(frame,
new Object[] {receiver, intValue});
}

@Override
protected GenericMessageSendNode makeGenericSend(final SSymbol selector) {
CompilerDirectives.transferToInterpreterAndInvalidate();
GenericMessageSendNode send = MessageSendNode.createGeneric(selector,
new ExpressionNode[] {getReceiver(), new IntegerLiteralNode(intValue)}, sourceCoord);

if (VmSettings.UseAstInterp) {
replace(send);
send.notifyDispatchInserted();
return send;
}

assert getParent() instanceof BytecodeLoopNode : "This node was expected to be a direct child of a `BytecodeLoopNode`.";
throw new RespecializeException(send);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package trufflesom.interpreter.supernodes.compare;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.UnexpectedResultException;
import trufflesom.bdt.inlining.ScopeAdaptationVisitor;
import trufflesom.bdt.inlining.ScopeAdaptationVisitor.ScopeElement;
import trufflesom.compiler.Variable.Argument;
import trufflesom.interpreter.bc.RespecializeException;
import trufflesom.interpreter.nodes.ArgumentReadNode.LocalArgumentReadNode;
import trufflesom.interpreter.nodes.ExpressionNode;
import trufflesom.interpreter.nodes.GenericMessageSendNode;
import trufflesom.interpreter.nodes.MessageSendNode;
import trufflesom.interpreter.nodes.bc.BytecodeLoopNode;
import trufflesom.interpreter.nodes.literals.IntegerLiteralNode;
import trufflesom.vm.SymbolTable;
import trufflesom.vm.VmSettings;


public final class LocalArgGreaterThanInt extends ExpressionNode {
private final Argument arg;
private final int argIdx;
private final long intValue;

public LocalArgGreaterThanInt(final Argument arg, final long intValue) {
this.arg = arg;
this.argIdx = arg.index;
this.intValue = intValue;
}

@Override
public Object executeGeneric(final VirtualFrame frame) {
Object arg = frame.getArguments()[argIdx];
if (arg instanceof Long) {
long argVal = (Long) arg;
return argVal > intValue;
}

CompilerDirectives.transferToInterpreterAndInvalidate();
return fallbackGeneric(frame);
}

@Override
public Object doPreEvaluated(final VirtualFrame frame, final Object[] args) {
CompilerDirectives.transferToInterpreterAndInvalidate();
throw new UnsupportedOperationException();
}

@Override
public boolean executeBoolean(final VirtualFrame frame) throws UnexpectedResultException {
Object arg = frame.getArguments()[argIdx];
if (arg instanceof Long) {
long argVal = (Long) arg;
return argVal > intValue;
}

CompilerDirectives.transferToInterpreterAndInvalidate();
return fallbackBool(frame);
}

private boolean fallbackBool(final VirtualFrame frame) throws UnexpectedResultException {
Object result = makeGenericSend().doPreEvaluated(frame,
new Object[] {arg, intValue});
if (result instanceof Boolean) {
return (Boolean) result;
}
throw new UnexpectedResultException(result);
}

private Object fallbackGeneric(final VirtualFrame frame) {
return makeGenericSend().doPreEvaluated(frame,
new Object[] {arg, intValue});
}

protected GenericMessageSendNode makeGenericSend() {
CompilerDirectives.transferToInterpreterAndInvalidate();
GenericMessageSendNode send =
MessageSendNode.createGeneric(SymbolTable.symbolFor(">"), new ExpressionNode[] {
new LocalArgumentReadNode(arg), new IntegerLiteralNode(intValue)}, sourceCoord);

if (VmSettings.UseAstInterp) {
replace(send);
send.notifyDispatchInserted();
return send;
}

assert getParent() instanceof BytecodeLoopNode : "This node was expected to be a direct child of a `BytecodeLoopNode`.";
throw new RespecializeException(send);
}

@Override
public void replaceAfterScopeChange(final ScopeAdaptationVisitor inliner) {
ScopeElement se = inliner.getAdaptedVar(arg);
if (se.var != arg || se.contextLevel < 0) {
if (se.var instanceof Argument arg) {
replace(new LocalArgGreaterThanInt(arg, intValue).initialize(sourceCoord));
} else {
replace(MessageSendNode.createGeneric(SymbolTable.symbolFor(">"),
new ExpressionNode[] {se.var.getReadNode(se.contextLevel, sourceCoord),
new IntegerLiteralNode(intValue)},
sourceCoord));
}
} else {
assert 0 == se.contextLevel;
}
}
}
Loading
Loading