Skip to content

Commit

Permalink
Converts J2clEqualitySameRewriterPass to be a peephole optimization.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=167788618
  • Loading branch information
gkdn authored and blickly committed Sep 8, 2017
1 parent f562c69 commit deb0130
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 62 deletions.
50 changes: 23 additions & 27 deletions src/com/google/javascript/jscomp/DefaultPassConfig.java
Expand Up @@ -1001,7 +1001,7 @@ private List<PassFactory> getMainOptimizationLoop() {


if (options.j2clPassMode.shouldAddJ2clPasses()) { if (options.j2clPassMode.shouldAddJ2clPasses()) {
passes.add(j2clConstantHoisterPass); passes.add(j2clConstantHoisterPass);
passes.add(j2clOptBundlePass); passes.add(j2clClinitPass);
} }


assertAllLoopablePasses(passes); assertAllLoopablePasses(passes);
Expand Down Expand Up @@ -1674,7 +1674,12 @@ protected FeatureSet featureSet() {
new PassFactory("earlyPeepholeOptimizations", true) { new PassFactory("earlyPeepholeOptimizations", true) {
@Override @Override
protected CompilerPass create(AbstractCompiler compiler) { protected CompilerPass create(AbstractCompiler compiler) {
return new PeepholeOptimizationsPass(compiler, getName(), new PeepholeRemoveDeadCode()); List<AbstractPeepholeOptimization> peepholeOptimizations = new ArrayList<>();
peepholeOptimizations.add(new PeepholeRemoveDeadCode());
if (compiler.getOptions().j2clPassMode.shouldAddJ2clPasses()) {
peepholeOptimizations.add(new J2clEqualitySameRewriterPass());
}
return new PeepholeOptimizationsPass(compiler, getName(), peepholeOptimizations);
} }


@Override @Override
Expand Down Expand Up @@ -1709,16 +1714,18 @@ private static CompilerPass createPeepholeOptimizationsPass(
AbstractCompiler compiler, String passName) { AbstractCompiler compiler, String passName) {
final boolean late = false; final boolean late = false;
final boolean useTypesForOptimization = compiler.getOptions().useTypesForLocalOptimization; final boolean useTypesForOptimization = compiler.getOptions().useTypesForLocalOptimization;
return new PeepholeOptimizationsPass( List<AbstractPeepholeOptimization> optimizations = new ArrayList<>();
compiler, optimizations.add(new MinimizeExitPoints(compiler));
passName, optimizations.add(new PeepholeMinimizeConditions(late, useTypesForOptimization));
new MinimizeExitPoints(compiler), optimizations.add(new PeepholeSubstituteAlternateSyntax(late));
new PeepholeMinimizeConditions(late, useTypesForOptimization), optimizations.add(new PeepholeReplaceKnownMethods(late, useTypesForOptimization));
new PeepholeSubstituteAlternateSyntax(late), optimizations.add(new PeepholeRemoveDeadCode());
new PeepholeReplaceKnownMethods(late, useTypesForOptimization), if (compiler.getOptions().j2clPassMode.shouldAddJ2clPasses()) {
new PeepholeRemoveDeadCode(), optimizations.add(new J2clEqualitySameRewriterPass());
new PeepholeFoldConstants(late, useTypesForOptimization), }
new PeepholeCollectPropertyAssignments()); optimizations.add(new PeepholeFoldConstants(late, useTypesForOptimization));
optimizations.add(new PeepholeCollectPropertyAssignments());
return new PeepholeOptimizationsPass(compiler, passName, optimizations);
} }


/** Various peephole optimizations. */ /** Various peephole optimizations. */
Expand Down Expand Up @@ -3283,24 +3290,13 @@ protected CompilerPass create(AbstractCompiler compiler) {
} }
}; };


/** Rewrites J2CL constructs to be more optimizable. */ /** Optimizes J2CL clinit methods. */
private final PassFactory j2clOptBundlePass = private final PassFactory j2clClinitPass =
new PassFactory("j2clOptBundlePass", false) { new PassFactory("j2clClinitPass", false) {
@Override @Override
protected CompilerPass create(AbstractCompiler compiler) { protected CompilerPass create(AbstractCompiler compiler) {
List<Node> changedScopeNodes = compiler.getChangedScopeNodesForPass(getName()); List<Node> changedScopeNodes = compiler.getChangedScopeNodesForPass(getName());
final J2clClinitPrunerPass j2clClinitPrunerPass = return new J2clClinitPrunerPass(compiler, changedScopeNodes);
new J2clClinitPrunerPass(compiler, changedScopeNodes);
final J2clEqualitySameRewriterPass j2clEqualitySameRewriterPass =
new J2clEqualitySameRewriterPass(compiler, changedScopeNodes);
return new CompilerPass() {

@Override
public void process(Node externs, Node root) {
j2clClinitPrunerPass.process(externs, root);
j2clEqualitySameRewriterPass.process(externs, root);
}
};
} }
}; };


Expand Down
54 changes: 25 additions & 29 deletions src/com/google/javascript/jscomp/J2clEqualitySameRewriterPass.java
Expand Up @@ -15,71 +15,67 @@
*/ */
package com.google.javascript.jscomp; package com.google.javascript.jscomp;


import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
import com.google.javascript.rhino.IR; import com.google.javascript.rhino.IR;
import com.google.javascript.rhino.Node; import com.google.javascript.rhino.Node;
import java.util.List;


/** An optimization pass to re-write J2CL Equality.$same. */ /** An optimization pass to re-write J2CL Equality.$same. */
public class J2clEqualitySameRewriterPass extends AbstractPostOrderCallback public class J2clEqualitySameRewriterPass extends AbstractPeepholeOptimization {
implements CompilerPass {


/** Whether to use "==" or "===". */ /** Whether to use "==" or "===". */
private static enum Eq { private static enum Eq {
DOUBLE, DOUBLE,
TRIPLE TRIPLE
} }


private final AbstractCompiler compiler; private boolean shouldRunJ2clPasses = false;
private final List<Node> changedScopeNodes;


J2clEqualitySameRewriterPass(AbstractCompiler compiler, List<Node> changedScopeNodes) { @Override
this.compiler = compiler; void beginTraversal(AbstractCompiler compiler) {
this.changedScopeNodes = changedScopeNodes; super.beginTraversal(compiler);
shouldRunJ2clPasses = J2clSourceFileChecker.shouldRunJ2clPasses(compiler);
} }


@Override @Override
public void process(Node externs, Node root) { Node optimizeSubtree(Node node) {
if (!J2clSourceFileChecker.shouldRunJ2clPasses(compiler)) { if (!shouldRunJ2clPasses) {
return; return node;
} }


NodeTraversal.traverseEs6ScopeRoots(compiler, root, changedScopeNodes, this, false); if (!isEqualitySameCall(node)) {
} return node;
}


@Override Node replacement = trySubstituteEqualitySame(node);
public void visit(NodeTraversal t, Node node, Node parent) { if (replacement != node) {
if (isEqualitySameCall(node)) { replacement = replacement.useSourceInfoIfMissingFrom(node);
trySubstituteEqualitySame(node); node.replaceWith(replacement);
reportCodeChange();
} }
return replacement;
} }


private void trySubstituteEqualitySame(Node callNode) { private Node trySubstituteEqualitySame(Node callNode) {
Node firstExpr = callNode.getSecondChild(); Node firstExpr = callNode.getSecondChild();
Node secondExpr = callNode.getLastChild(); Node secondExpr = callNode.getLastChild();


if (NodeUtil.isNullOrUndefined(firstExpr) || NodeUtil.isNullOrUndefined(secondExpr)) { if (NodeUtil.isNullOrUndefined(firstExpr) || NodeUtil.isNullOrUndefined(secondExpr)) {
// At least one side is null or undefined so no coercion danger. // At least one side is null or undefined so no coercion danger.
rewriteToEq(callNode, firstExpr, secondExpr, Eq.DOUBLE); return rewriteToEq(firstExpr, secondExpr, Eq.DOUBLE);
return;
} }


if (NodeUtil.isLiteralValue(firstExpr, true) || NodeUtil.isLiteralValue(secondExpr, true)) { if (NodeUtil.isLiteralValue(firstExpr, true) || NodeUtil.isLiteralValue(secondExpr, true)) {
// There is a coercion danger but since at least one side is not null, we can use === that // There is a coercion danger but since at least one side is not null, we can use === that
// will not trigger any coercion. // will not trigger any coercion.
rewriteToEq(callNode, firstExpr, secondExpr, Eq.TRIPLE); return rewriteToEq(firstExpr, secondExpr, Eq.TRIPLE);
return;
} }

return callNode;
} }


private void rewriteToEq(Node callNode, Node firstExpr, Node secondExpr, Eq eq) { private Node rewriteToEq(Node firstExpr, Node secondExpr, Eq eq) {
Node parent = callNode.getParent();
firstExpr.detach(); firstExpr.detach();
secondExpr.detach(); secondExpr.detach();
Node replacement = return eq == Eq.DOUBLE ? IR.eq(firstExpr, secondExpr) : IR.sheq(firstExpr, secondExpr);
eq == Eq.DOUBLE ? IR.eq(firstExpr, secondExpr) : IR.sheq(firstExpr, secondExpr);
parent.replaceChild(callNode, replacement.useSourceInfoIfMissingFrom(callNode));
compiler.reportChangeToEnclosingScope(parent);
} }


private static boolean isEqualitySameCall(Node node) { private static boolean isEqualitySameCall(Node node) {
Expand Down
10 changes: 9 additions & 1 deletion src/com/google/javascript/jscomp/PeepholeOptimizationsPass.java
Expand Up @@ -19,6 +19,7 @@
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback; import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
import com.google.javascript.rhino.Node; import com.google.javascript.rhino.Node;
import java.util.Arrays;
import java.util.List; import java.util.List;


/** /**
Expand All @@ -31,12 +32,19 @@ class PeepholeOptimizationsPass implements CompilerPass {


private final AbstractCompiler compiler; private final AbstractCompiler compiler;
private final String passName; private final String passName;
private final AbstractPeepholeOptimization[] peepholeOptimizations; private final List<AbstractPeepholeOptimization> peepholeOptimizations;
private boolean retraverseOnChange; private boolean retraverseOnChange;


/** Creates a peephole optimization pass that runs the given optimizations. */ /** Creates a peephole optimization pass that runs the given optimizations. */
PeepholeOptimizationsPass( PeepholeOptimizationsPass(
AbstractCompiler compiler, String passName, AbstractPeepholeOptimization... optimizations) { AbstractCompiler compiler, String passName, AbstractPeepholeOptimization... optimizations) {
this(compiler, passName, Arrays.asList(optimizations));
}

PeepholeOptimizationsPass(
AbstractCompiler compiler,
String passName,
List<AbstractPeepholeOptimization> optimizations) {
this.compiler = compiler; this.compiler = compiler;
this.passName = passName; this.passName = passName;
this.peepholeOptimizations = optimizations; this.peepholeOptimizations = optimizations;
Expand Down
Expand Up @@ -29,18 +29,15 @@ protected void setUp() throws Exception {
} }


@Override @Override
protected CompilerPass getProcessor(Compiler compiler) { protected CompilerPass getProcessor(final Compiler compiler) {
return new J2clEqualitySameRewriterPass( return new PeepholeOptimizationsPass(compiler, getName(), new J2clEqualitySameRewriterPass());
compiler, compiler.getChangedScopeNodesForPass("J2clEqualitySameRewriterPass"));
} }

@Override @Override
protected CompilerOptions getOptions() { protected CompilerOptions getOptions() {
CompilerOptions options = super.getOptions(); CompilerOptions options = super.getOptions();
options.setJ2clPass(CompilerOptions.J2clPassMode.ON); options.setJ2clPass(CompilerOptions.J2clPassMode.ON);
return options; return options;
} }

public void testRewriteEqualitySame() { public void testRewriteEqualitySame() {
test( test(
LINE_JOINER.join( LINE_JOINER.join(
Expand Down

0 comments on commit deb0130

Please sign in to comment.