switch (n.getToken()) { case NOT: { MinimizedCondition subtree = computeMinimizedCondition(n.getFirstChild()); MeasuredNode positive = pickBest( MeasuredNode.addNode(n, subtree.positive), subtree.negative); MeasuredNode negative = pickBest( subtree.negative.negate(), subtree.positive); return new MinimizedCondition(positive, negative); MinimizedCondition leftSubtree = computeMinimizedCondition(n.getFirstChild()); MinimizedCondition rightSubtree = computeMinimizedCondition(n.getLastChild()); MeasuredNode positive = pickBest( MeasuredNode.addNode(n, leftSubtree.positive, leftSubtree.negative, rightSubtree.negative).negate()); MeasuredNode negative = pickBest( MeasuredNode.addNode(n, leftSubtree.positive, leftSubtree.negative, rightSubtree.negative).change()); return new MinimizedCondition(positive, negative); Node thenNode = cond.getNext(); Node elseNode = thenNode.getNext();
/** * Try to minimize condition expression, as there are additional * assumptions that can be made when it is known that the final result * is a boolean. * * @return The replacement for n, or the original if no change was made. */ private Node tryMinimizeCondition(Node n) { n = performConditionSubstitutions(n); MinimizedCondition minCond = MinimizedCondition.fromConditionNode(n); return replaceNode( minCond.getPlaceholder(), minCond.getMinimized(MinimizationStyle.PREFER_UNNEGATED)); }
/** * Remove the passed condition node from the AST, and then return a * MinimizedCondition that represents the condition node after * minimization. */ static MinimizedCondition fromConditionNode(Node n) { switch (n.getType()) { case Token.NOT: case Token.AND: case Token.OR: case Token.HOOK: case Token.COMMA: Node placeholder = swapWithPlaceholderNode(n); return computeMinimizedCondition(n).setPlaceholder(placeholder); default: return unoptimized(n); } }
/** * Try to minimize condition expression, as there are additional * assumptions that can be made when it is known that the final result * is a boolean. * * @return The replacement for n, or the original if no change was made. */ private Node tryMinimizeCondition(Node n) { n = performConditionSubstitutions(n); MinimizedCondition minCond = MinimizedCondition.fromConditionNode(n); return replaceNode( n, minCond.getMinimized(MinimizationStyle.PREFER_UNNEGATED)); }
/** * Returns a MinimizedCondition that represents the condition node after * minimization. */ static MinimizedCondition fromConditionNode(Node n) { checkState(n.getParent() != null); switch (n.getToken()) { case NOT: case AND: case OR: case HOOK: case COMMA: return computeMinimizedCondition(n); default: return unoptimized(n); } }
/** * Return a MeasuredNode of the given condition node, without minimizing * the result. * <p> * Since a MinimizedCondition necessarily must contain two trees, this * method sets the negative side to a {@link Token#SCRIPT} node (never valid * inside an expression) with an unreasonably high length so that it will * never be chosen by {@link #getMinimized}. * * @param n the conditional expression tree to minimize. * This must be connected to the AST, and will be swapped * with a placeholder node during minimization. * @return a MinimizedCondition object representing that tree. */ static MinimizedCondition unoptimized(Node n) { Preconditions.checkNotNull(n.getParent()); Node placeholder = swapWithPlaceholderNode(n); MeasuredNode pos = new MeasuredNode(n, 0, false); MeasuredNode neg = new MeasuredNode(IR.script(), Integer.MAX_VALUE, true); return new MinimizedCondition(pos, neg).setPlaceholder(placeholder); }
case Token.NOT: { MinimizedCondition subtree = computeMinimizedCondition(n.getFirstChild().detachFromParent()); ImmutableList<MeasuredNode> positiveAsts = ImmutableList.of( subtree.positive.cloneTree().addNot(), subtree.negative.negate(), subtree.positive); return new MinimizedCondition( Collections.min(positiveAsts, AST_LENGTH_COMPARATOR), Collections.min(negativeAsts, AST_LENGTH_COMPARATOR)); int complementType = opType == Token.AND ? Token.OR : Token.AND; MinimizedCondition leftSubtree = computeMinimizedCondition(n.getFirstChild().detachFromParent()); MinimizedCondition rightSubtree = computeMinimizedCondition(n.getLastChild().detachFromParent()); ImmutableList<MeasuredNode> positiveAsts = ImmutableList.of( MeasuredNode.addNode(new Node(opType).srcref(n), leftSubtree.negative, rightSubtree.negative)); return new MinimizedCondition( Collections.min(positiveAsts, AST_LENGTH_COMPARATOR), Collections.min(negativeAsts, AST_LENGTH_COMPARATOR)); Node elseNode = thenNode.getNext(); MinimizedCondition thenSubtree = computeMinimizedCondition(thenNode.detachFromParent());
/** * Return a MeasuredNode of the given condition node, without minimizing * the result. * <p> * Since a MinimizedCondition necessarily must contain two trees, * this method sets the negative side to a invalid node * with an unreasonably high length so that it will * never be chosen by {@link #getMinimized}. * * @param n the conditional expression tree * @return a MinimizedCondition object representing that tree. */ static MinimizedCondition unoptimized(Node n) { checkNotNull(n.getParent()); MeasuredNode pos = new MeasuredNode(n, null, 0, false); MeasuredNode neg = new MeasuredNode(null, null, Integer.MAX_VALUE, true); return new MinimizedCondition(pos, neg); }
/** * Try to remove leading NOTs from EXPR_RESULTS. * * Returns the replacement for n or the original if no replacement was * necessary. */ private Node tryMinimizeExprResult(Node n) { Node originalExpr = n.getFirstChild(); MinimizedCondition minCond = MinimizedCondition.fromConditionNode(originalExpr); MeasuredNode mNode = minCond.getMinimized(MinimizationStyle.ALLOW_LEADING_NOT); if (mNode.isNot()) { // Remove the leading NOT in the EXPR_RESULT. replaceNode(originalExpr, mNode.withoutNot()); } else { replaceNode(originalExpr, mNode); } return n; }
/** * Try to remove leading NOTs from EXPR_RESULTS. * * Returns the replacement for n or the original if no replacement was * necessary. */ private Node tryMinimizeExprResult(Node n) { MinimizedCondition minCond = MinimizedCondition.fromConditionNode(n.getFirstChild()); MinimizedCondition.MeasuredNode mNode = minCond.getMinimized(MinimizationStyle.ALLOW_LEADING_NOT); Node placeholder = minCond.getPlaceholder(); if (mNode.getNode().isNot()) { // Remove the leading NOT in the EXPR_RESULT. n.replaceChild(placeholder, mNode.getNode().removeFirstChild()); reportCodeChange(); } else { replaceNode(placeholder, mNode); } return n; }
/** * Try flipping HOOKs that have negated conditions. * * Returns the replacement for n or the original if no replacement was * necessary. */ private Node tryMinimizeHook(Node n) { Node originalCond = n.getFirstChild(); MinimizedCondition minCond = MinimizedCondition.fromConditionNode(originalCond); MeasuredNode mNode = minCond.getMinimized(MinimizationStyle.ALLOW_LEADING_NOT); if (mNode.isNot()) { // Swap the HOOK Node thenBranch = n.getSecondChild(); replaceNode(originalCond, mNode.withoutNot()); n.removeChild(thenBranch); n.addChildToBack(thenBranch); reportChangeToEnclosingScope(n); } else { replaceNode(originalCond, mNode); } return n; }
/** * Try flipping HOOKs that have negated conditions. * * Returns the replacement for n or the original if no replacement was * necessary. */ private Node tryMinimizeHook(Node n) { MinimizedCondition minCond = MinimizedCondition.fromConditionNode(n.getFirstChild()); MinimizedCondition.MeasuredNode mNode = minCond.getMinimized(MinimizationStyle.ALLOW_LEADING_NOT); Node placeholder = minCond.getPlaceholder(); if (mNode.getNode().isNot()) { // Swap the HOOK Node thenBranch = n.getSecondChild(); n.replaceChild(placeholder, mNode.getNode().removeFirstChild()); n.removeChild(thenBranch); n.addChildToBack(thenBranch); reportCodeChange(); } else { replaceNode(placeholder, mNode); } return n; }
Node elseBranch = thenBranch.getNext(); MinimizedCondition minCond = MinimizedCondition.fromConditionNode(originalCond); MeasuredNode unnegatedCond = minCond.getMinimized(MinimizationStyle.PREFER_UNNEGATED); MeasuredNode shortCond = minCond.getMinimized(MinimizationStyle.ALLOW_LEADING_NOT);
MinimizedCondition.fromConditionNode(originalCond); Node placeholder = minCond.getPlaceholder(); unnegatedCond = minCond.getMinimized(MinimizationStyle.PREFER_UNNEGATED); shortCond = minCond.getMinimized(MinimizationStyle.ALLOW_LEADING_NOT);