From d1cb15d3cff6ab01c8e7816c185ad13d6a2f5967 Mon Sep 17 00:00:00 2001 From: Julien Lopez <julien.lopez@lri.fr> Date: Thu, 15 Feb 2018 15:46:49 +0100 Subject: [PATCH] Fixed QIRInterface and implement IsExportableVisitor --- .../qirinterface/IsExportableVisitor.java | 149 +++++++++--------- .../r/nodes/qirinterface/QIRInterface.java | 31 +++- 2 files changed, 101 insertions(+), 79 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/IsExportableVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/IsExportableVisitor.java index 74fae0422d..c87f05dd83 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/IsExportableVisitor.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/IsExportableVisitor.java @@ -1,5 +1,6 @@ package com.oracle.truffle.r.nodes.qirinterface; +import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.r.nodes.RSyntaxNodeVisitor; import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.WriteLocalFrameVariableNode; @@ -11,6 +12,7 @@ import com.oracle.truffle.r.nodes.control.ForNode; import com.oracle.truffle.r.nodes.control.IfNode; import com.oracle.truffle.r.nodes.control.ReplacementDispatchNode; import com.oracle.truffle.r.nodes.control.WhileNode; +import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; import com.oracle.truffle.r.nodes.function.FunctionExpressionNode; import com.oracle.truffle.r.nodes.function.RCallNode; import com.oracle.truffle.r.nodes.function.RCallSpecialNode; @@ -25,6 +27,10 @@ import com.oracle.truffle.r.nodes.query.RQIRWrapperNode; import com.oracle.truffle.r.nodes.query.RRightJoinNode; import com.oracle.truffle.r.nodes.query.RSelectNode; import com.oracle.truffle.r.nodes.query.RWhereNode; +import com.oracle.truffle.r.runtime.Arguments; +import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public class IsExportableVisitor implements RSyntaxNodeVisitor<Boolean> { public static final IsExportableVisitor instance = new IsExportableVisitor(); @@ -33,146 +39,145 @@ public class IsExportableVisitor implements RSyntaxNodeVisitor<Boolean> { } @Override - public Boolean visit(IfNode ifNode) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final IfNode ifNode) { + return ifNode.getCondition().asRSyntaxNode().accept(this) && ifNode.getThenPart().asRSyntaxNode().accept(this) && ifNode.getElsePart().asRSyntaxNode().accept(this); } @Override - public Boolean visit(WhileNode whileNode) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final WhileNode whileNode) { + return whileNode.getCondition().accept(this) && whileNode.getBody().asRSyntaxNode().accept(this); } @Override - public Boolean visit(ForNode forNode) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final ForNode forNode) { + return forNode.getRange().asRSyntaxNode().accept(this) && forNode.getBody().asRSyntaxNode().accept(this); } @Override - public Boolean visit(BreakNode b) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final BreakNode breakNode) { + return true; } + /** + * Translation of a sequence of statements. Note: This is also where the STRAD-ASSIGN rules are + * handled. + */ @Override - public Boolean visit(BlockNode block) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final BlockNode block) { + final RNode[] children = block.getSequence(); + + for (int i = 0; i < children.length; i++) + if (!children[i].asRSyntaxNode().accept(this)) + return false; + return true; } @Override - public Boolean visit(LookupNode var) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final LookupNode var) { + return true; } @Override - public Boolean visit(WriteLocalFrameVariableNode var) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final WriteLocalFrameVariableNode var) { + return var.getRhs().asRSyntaxNode().accept(this); } @Override - public Boolean visit(FunctionExpressionNode fun) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final FunctionExpressionNode fun) { + final RootCallTarget target = fun.getCallTarget(); + if (target == null) + return false; + return ((FunctionDefinitionNode) target.getRootNode()).getBody().accept(this); } @Override - public Boolean visit(InternalNode b) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final InternalNode fun) { + throw new RuntimeException("Error in translation to QIR: InternalNode unsupported."); } @Override - public Boolean visit(RCallNode callNode) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RCallNode call) { + final Arguments<RSyntaxNode> args = call.getArguments(); + if (!call.getFunction().asRSyntaxNode().accept(this)) + return false; + for (int i = 0; i < args.getLength(); i++) + if (!args.getArgument(i).accept(this)) + return false; + return true; } @Override - public Boolean visit(RCallSpecialNode callNode) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RCallSpecialNode call) { + final RSyntaxElement[] args = call.getSyntaxArguments(); + // TODO: Handle builtin + for (int i = 0; i < args.length; i++) + if (!((RSyntaxNode) args[i]).accept(this)) + return false; + return true; } @Override - public Boolean visit(ReplacementDispatchNode repl) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final ReplacementDispatchNode repl) { + return repl.lhs.asRSyntaxNode().accept(this) && repl.rhs.asRSyntaxNode().accept(this); } @Override - public Boolean visit(RQIRWrapperNode qir) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RQIRWrapperNode query) { + return true; } @Override - public Boolean visit(RSelectNode select) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RSelectNode select) { + return select.formatter.asRSyntaxNode().accept(this) && select.query.asRSyntaxNode().accept(this); } @Override - public Boolean visit(RFromNode from) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RFromNode from) { + return from.getTable().asRSyntaxNode().accept(this); } @Override - public Boolean visit(RWhereNode where) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RWhereNode where) { + return where.getFilter().asRSyntaxNode().accept(this) && where.getQuery().asRSyntaxNode().accept(this); } @Override - public Boolean visit(RGroupNode group) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RGroupNode group) { + return group.getGroup().asRSyntaxNode().accept(this) && group.getQuery().asRSyntaxNode().accept(this); } @Override - public Boolean visit(ROrderNode order) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final ROrderNode order) { + return order.getIsAscending().asRSyntaxNode().accept(this) && order.getOrder().asRSyntaxNode().accept(this) && order.getQuery().asRSyntaxNode().accept(this); } @Override - public Boolean visit(RJoinNode join) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RJoinNode join) { + return join.getFilter().asRSyntaxNode().accept(this) && join.getLeft().asRSyntaxNode().accept(this) && join.getRight().asRSyntaxNode().accept(this); } @Override - public Boolean visit(RLeftJoinNode join) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RLeftJoinNode join) { + return join.getFilter().asRSyntaxNode().accept(this) && join.getLeft().asRSyntaxNode().accept(this) && join.getRight().asRSyntaxNode().accept(this); } @Override - public Boolean visit(RRightJoinNode join) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RRightJoinNode join) { + return join.getFilter().asRSyntaxNode().accept(this) && join.getLeft().asRSyntaxNode().accept(this) && join.getRight().asRSyntaxNode().accept(this); } @Override - public Boolean visit(RLimitNode limit) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final RLimitNode limit) { + return limit.getLimit().asRSyntaxNode().accept(this) && limit.getQuery().asRSyntaxNode().accept(this); } @Override - public Boolean visit(ConstantNode cst) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final ConstantNode cst) { + return true; } @Override - public Boolean visit(MissingNode node) { - // TODO Auto-generated method stub - return null; + public final Boolean visit(final MissingNode node) { + throw new RuntimeException("Cannot translate MissingNode to QIR."); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java index 04a6b0bc9e..9e22f84a49 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/qirinterface/QIRInterface.java @@ -34,6 +34,7 @@ import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.api.vm.EngineTruffleObject; import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.api.vm.PolyglotEngine.Value; import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; @@ -235,6 +236,8 @@ public final class QIRInterface { return RToQIRType(src, fun.getValue()); return RToQIRType(src, fun.getClosure().eval(fun.getFrame())); } + if (value instanceof EngineTruffleObject) + return RToQIRType(src, ((EngineTruffleObject) value).getDelegate()); throw new RuntimeException("Unsupported value: " + value); } @@ -249,17 +252,31 @@ public final class QIRInterface { } static final QIRTruffleNode apply(final QIRTruffleNode fun, final List<QIRNode> args) { - return fun instanceof QIRExportableTruffleNode - ? new QIRExportableTruffleNode(fun.sourceSection, "r", fun.executeTruffle, fun.apply, - fun.code + "(" + args.stream().map(arg -> arg.toString()).collect(Collectors.joining(",")) + ")") - : new QIRExportableTruffleNode(fun.sourceSection, "r", fun.executeTruffle, fun.apply, - fun.code + "(" + args.stream().map(arg -> arg.toString()).collect(Collectors.joining(",")) + ")"); + int argIndex = 1; + String code = ""; + List<String> applyArgs = new ArrayList<>(); + + for (QIRNode arg : args) { + if (arg instanceof QIRTuple) { + final String argName = "res" + argIndex; + code += "\n" + argName + " = new.env();"; + for (QIRNode v = arg; v instanceof QIRTcons; v = ((QIRTcons) v).tail) { + final Object value = QIRToRType(((QIRTcons) v).value); + code += "\n" + argName + "$" + ((QIRTcons) v).id + " = " + (value instanceof String ? "\"" + value + "\"" : value) + ";"; + } + applyArgs.add(argName); + } else + applyArgs.add(QIRToRType(arg).toString()); + } + code += "\n(" + fun.code + ")(" + applyArgs.stream().collect(Collectors.joining(",")) + ")"; + return fun instanceof QIRExportableTruffleNode ? new QIRExportableTruffleNode(fun.sourceSection, "SL", QIRInterface::execute, fun.apply, code) + : new QIRUnexportableTruffleNode(fun.sourceSection, "SL", QIRInterface::execute, fun.apply, code); } private static final QIRNode RFunctionToQIRType(final SourceSection src, final String funName, final FunctionDefinitionNode fun) { try { - QIRNode res = ((FunctionDefinitionNode) fun.getCallTarget().getRootNode()).getBody().accept(QIRTranslateVisitor.instance); - final String[] args = ((FunctionDefinitionNode) fun.getCallTarget().getRootNode()).getSignature().getNames(); + QIRNode res = fun.getBody().accept(QIRTranslateVisitor.instance); + final String[] args = fun.getSignature().getNames(); if (args.length == 0) return new QIRLambda(src, funName, null, res, new FrameDescriptor()); -- GitLab