Skip to content

Commit

Permalink
Complete replacement of RUPP with RemoveUnusedCode.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=178636068
  • Loading branch information
brad4d committed Dec 11, 2017
1 parent 8ca4910 commit 34616d9
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 1,004 deletions.
2 changes: 1 addition & 1 deletion src/com/google/javascript/jscomp/CompilerOptions.java
Expand Up @@ -2286,7 +2286,7 @@ public void setExtractPrototypeMemberDeclarations(ExtractPrototypeMemberDeclarat
public void setRemoveUnusedPrototypeProperties(boolean enabled) { public void setRemoveUnusedPrototypeProperties(boolean enabled) {
this.removeUnusedPrototypeProperties = enabled; this.removeUnusedPrototypeProperties = enabled;
// InlineSimpleMethods makes similar assumptions to // InlineSimpleMethods makes similar assumptions to
// RemoveUnusedPrototypeProperties, so they are enabled together. // RemoveUnusedCode, so they are enabled together.
this.inlineGetters = enabled; this.inlineGetters = enabled;
} }


Expand Down
48 changes: 14 additions & 34 deletions src/com/google/javascript/jscomp/DefaultPassConfig.java
Expand Up @@ -820,8 +820,8 @@ protected List<PassFactory> getOptimizations() {


// After inlining some of the variable uses, some variables are unused. // After inlining some of the variable uses, some variables are unused.
// Re-run remove unused vars to clean it up. // Re-run remove unused vars to clean it up.
if (options.removeUnusedVars || options.removeUnusedLocalVars) { if (shouldRunRemoveUnusedCode()) {
passes.add(getRemoveUnusedCodeOnce()); passes.add(removeUnusedCodeOnce);
} }
} }


Expand Down Expand Up @@ -1007,10 +1007,6 @@ private List<PassFactory> getMainOptimizationLoop() {
passes.add(optimizeCalls); passes.add(optimizeCalls);
} }


if (options.removeUnusedVars || options.removeUnusedLocalVars) {
passes.add(getRemoveUnusedCode());
}

if (options.j2clPassMode.shouldAddJ2clPasses()) { if (options.j2clPassMode.shouldAddJ2clPasses()) {
passes.add(j2clConstantHoisterPass); passes.add(j2clConstantHoisterPass);
passes.add(j2clClinitPass); passes.add(j2clClinitPass);
Expand Down Expand Up @@ -1041,8 +1037,8 @@ private List<PassFactory> getCodeRemovingPasses() {
passes.add(removeUnreachableCode); passes.add(removeUnreachableCode);
} }


if (options.removeUnusedPrototypeProperties) { if (shouldRunRemoveUnusedCode()) {
passes.add(removeUnusedPrototypeProperties); passes.add(removeUnusedCode);
} }


if (options.removeUnusedClassProperties) { if (options.removeUnusedClassProperties) {
Expand All @@ -1053,6 +1049,12 @@ private List<PassFactory> getCodeRemovingPasses() {
return passes; return passes;
} }


private boolean shouldRunRemoveUnusedCode() {
return options.removeUnusedVars
|| options.removeUnusedLocalVars
|| options.removeUnusedPrototypeProperties;
}

private final HotSwapPassFactory checkSideEffects = private final HotSwapPassFactory checkSideEffects =
new HotSwapPassFactory("checkSideEffects") { new HotSwapPassFactory("checkSideEffects") {
@Override @Override
Expand Down Expand Up @@ -2710,23 +2712,6 @@ protected FeatureSet featureSet() {
} }
}; };


/** Remove prototype properties that do not appear to be used. */
private final PassFactory removeUnusedPrototypeProperties =
new PassFactory(PassNames.REMOVE_UNUSED_PROTOTYPE_PROPERTIES, false) {
@Override
protected CompilerPass create(AbstractCompiler compiler) {
return new RemoveUnusedPrototypeProperties(
compiler,
options.removeUnusedPrototypePropertiesInExterns,
!options.removeUnusedVars);
}

@Override
protected FeatureSet featureSet() {
return ES8_MODULES;
}
};

/** Remove prototype properties that do not appear to be used. */ /** Remove prototype properties that do not appear to be used. */
private final PassFactory removeUnusedClassProperties = private final PassFactory removeUnusedClassProperties =
new PassFactory(PassNames.REMOVE_UNUSED_CLASS_PROPERTIES, false) { new PassFactory(PassNames.REMOVE_UNUSED_CLASS_PROPERTIES, false) {
Expand Down Expand Up @@ -2880,24 +2865,19 @@ protected FeatureSet featureSet() {
} }
}; };


private PassFactory getRemoveUnusedCode() { private PassFactory removeUnusedCodeOnce = getRemoveUnusedCode(true /* isOneTimePass */);
return getRemoveUnusedCode(false /* isOneTimePass */); private PassFactory removeUnusedCode = getRemoveUnusedCode(false /* isOneTimePass */);
}

private PassFactory getRemoveUnusedCodeOnce() {
return getRemoveUnusedCode(true /* isOneTimePass */);
}


private PassFactory getRemoveUnusedCode(boolean isOneTimePass) { private PassFactory getRemoveUnusedCode(boolean isOneTimePass) {
/** Removes variables that are never used. */ /** Removes variables that are never used. */
return new PassFactory(PassNames.REMOVE_UNUSED_CODE, isOneTimePass) { return new PassFactory(PassNames.REMOVE_UNUSED_CODE, isOneTimePass) {
@Override @Override
protected CompilerPass create(AbstractCompiler compiler) { protected CompilerPass create(AbstractCompiler compiler) {
boolean removeOnlyLocals = options.removeUnusedLocalVars && !options.removeUnusedVars;
boolean preserveAnonymousFunctionNames = boolean preserveAnonymousFunctionNames =
options.anonymousFunctionNaming != AnonymousFunctionNamingPolicy.OFF; options.anonymousFunctionNaming != AnonymousFunctionNamingPolicy.OFF;
return new RemoveUnusedCode.Builder(compiler) return new RemoveUnusedCode.Builder(compiler)
.removeGlobals(!removeOnlyLocals) .removeLocalVars(options.removeUnusedLocalVars)
.removeGlobals(options.removeUnusedVars)
.preserveFunctionExpressionNames(preserveAnonymousFunctionNames) .preserveFunctionExpressionNames(preserveAnonymousFunctionNames)
.removeUnusedPrototypeProperties(options.removeUnusedPrototypeProperties) .removeUnusedPrototypeProperties(options.removeUnusedPrototypeProperties)
.allowRemovalOfExternProperties(options.removeUnusedPrototypePropertiesInExterns) .allowRemovalOfExternProperties(options.removeUnusedPrototypePropertiesInExterns)
Expand Down
Expand Up @@ -32,7 +32,7 @@
* constructors or interfaces. Explicitly ignored is the possibility that * constructors or interfaces. Explicitly ignored is the possibility that
* these properties may be indirectly referenced using "for-in" or * these properties may be indirectly referenced using "for-in" or
* "Object.keys". This is the same assumption used with * "Object.keys". This is the same assumption used with
* RemoveUnusedPrototypeProperties but is slightly wider in scope. * RemoveUnusedCode but is slightly wider in scope.
* *
* TODO(tomnguyen) Handle destructuring of objects/classes as cases where the field is used. * TODO(tomnguyen) Handle destructuring of objects/classes as cases where the field is used.
* *
Expand Down
49 changes: 30 additions & 19 deletions src/com/google/javascript/jscomp/RemoveUnusedCode.java
Expand Up @@ -96,6 +96,7 @@ class RemoveUnusedCode implements CompilerPass {


private final CodingConvention codingConvention; private final CodingConvention codingConvention;


private final boolean removeLocalVars;
private final boolean removeGlobals; private final boolean removeGlobals;


private final boolean preserveFunctionExpressionNames; private final boolean preserveFunctionExpressionNames;
Expand All @@ -118,7 +119,7 @@ class RemoveUnusedCode implements CompilerPass {
private final Multimap<String, Removable> removablesForPropertyNames = HashMultimap.create(); private final Multimap<String, Removable> removablesForPropertyNames = HashMultimap.create();


/** Single value to use for all vars for which we cannot remove anything at all. */ /** Single value to use for all vars for which we cannot remove anything at all. */
private final VarInfo canonicalTotallyUnremovableVarInfo; private final VarInfo canonicalUnremovableVarInfo;


/** /**
* Keep track of scopes that we've traversed. * Keep track of scopes that we've traversed.
Expand All @@ -133,20 +134,22 @@ class RemoveUnusedCode implements CompilerPass {
RemoveUnusedCode(Builder builder) { RemoveUnusedCode(Builder builder) {
this.compiler = builder.compiler; this.compiler = builder.compiler;
this.codingConvention = builder.compiler.getCodingConvention(); this.codingConvention = builder.compiler.getCodingConvention();
this.removeLocalVars = builder.removeLocalVars;
this.removeGlobals = builder.removeGlobals; this.removeGlobals = builder.removeGlobals;
this.preserveFunctionExpressionNames = builder.preserveFunctionExpressionNames; this.preserveFunctionExpressionNames = builder.preserveFunctionExpressionNames;
this.removeUnusedPrototypeProperties = builder.removeUnusedPrototypeProperties; this.removeUnusedPrototypeProperties = builder.removeUnusedPrototypeProperties;
this.allowRemovalOfExternProperties = builder.allowRemovalOfExternProperties; this.allowRemovalOfExternProperties = builder.allowRemovalOfExternProperties;
this.scopeCreator = new Es6SyntacticScopeCreator(builder.compiler); this.scopeCreator = new Es6SyntacticScopeCreator(builder.compiler);


// All Vars that are completely unremovable will share this VarInfo instance. // All Vars that are completely unremovable will share this VarInfo instance.
canonicalTotallyUnremovableVarInfo = new VarInfo(); canonicalUnremovableVarInfo = new VarInfo();
canonicalTotallyUnremovableVarInfo.setIsExplicitlyNotRemovable(); canonicalUnremovableVarInfo.setIsExplicitlyNotRemovable();
} }


public static class Builder { public static class Builder {
private final AbstractCompiler compiler; private final AbstractCompiler compiler;


private boolean removeLocalVars = false;
private boolean removeGlobals = false; private boolean removeGlobals = false;
private boolean preserveFunctionExpressionNames = false; private boolean preserveFunctionExpressionNames = false;
private boolean removeUnusedPrototypeProperties = false; private boolean removeUnusedPrototypeProperties = false;
Expand All @@ -156,6 +159,11 @@ public static class Builder {
this.compiler = compiler; this.compiler = compiler;
} }


Builder removeLocalVars(boolean value) {
this.removeLocalVars = value;
return this;
}

Builder removeGlobals(boolean value) { Builder removeGlobals(boolean value) {
this.removeGlobals = value; this.removeGlobals = value;
return this; return this;
Expand Down Expand Up @@ -1085,7 +1093,8 @@ private void maybeRemoveUnusedTrailingParameters(Node argList, Scope fparamScope
*/ */
private VarInfo traverseVar(Var var) { private VarInfo traverseVar(Var var) {
checkNotNull(var); checkNotNull(var);
if (var.isArguments()) { if (removeLocalVars && var.isArguments()) {
// If we are considering removing local variables, that includes parameters.
// If `arguments` is used in a function we must consider all parameters to be referenced. // If `arguments` is used in a function we must consider all parameters to be referenced.
Scope functionScope = var.getScope().getClosestHoistScope(); Scope functionScope = var.getScope().getClosestHoistScope();
Node paramList = NodeUtil.getFunctionParameters(functionScope.getRootNode()); Node paramList = NodeUtil.getFunctionParameters(functionScope.getRootNode());
Expand All @@ -1104,7 +1113,7 @@ private VarInfo traverseVar(Var var) {
getVarInfo(paramVar).markAsReferenced(); getVarInfo(paramVar).markAsReferenced();
} }
// `arguments` is never removable. // `arguments` is never removable.
return canonicalTotallyUnremovableVarInfo; return canonicalUnremovableVarInfo;
} else { } else {
return getVarInfo(var); return getVarInfo(var);
} }
Expand All @@ -1119,26 +1128,28 @@ private VarInfo traverseVar(Var var) {
*/ */
private VarInfo getVarInfo(Var var) { private VarInfo getVarInfo(Var var) {
checkNotNull(var); checkNotNull(var);
VarInfo varInfo = varInfoMap.get(var); boolean isGlobal = var.isGlobal();
if (varInfo == null) { if (isGlobal && !removeGlobals) {
boolean isGlobal = var.isGlobal(); return canonicalUnremovableVarInfo;
if (isGlobal && !removeGlobals && !removeUnusedPrototypeProperties) { } else if (!isGlobal && !removeLocalVars) {
varInfo = canonicalTotallyUnremovableVarInfo; return canonicalUnremovableVarInfo;
} else if (codingConvention.isExported(var.getName(), !isGlobal)) { } else if (codingConvention.isExported(var.getName(), !isGlobal)) {
varInfo = canonicalTotallyUnremovableVarInfo; return canonicalUnremovableVarInfo;
} else if (var.isArguments()) { } else if (var.isArguments()) {
varInfo = canonicalTotallyUnremovableVarInfo; return canonicalUnremovableVarInfo;
} else { } else {
VarInfo varInfo = varInfoMap.get(var);
if (varInfo == null) {
varInfo = new VarInfo(); varInfo = new VarInfo();
if (isGlobal && !removeGlobals) { if (var.getParentNode().isParamList()) {
varInfo.setIsExplicitlyNotRemovable(); // We don't know where a parameter value comes from, so setting a property on it
} else if (var.getParentNode().isParamList()) { // has unknown side effects and makes it not removable.
varInfo.propertyAssignmentsWillPreventRemoval = true; varInfo.propertyAssignmentsWillPreventRemoval = true;
} }
varInfoMap.put(var, varInfo); varInfoMap.put(var, varInfo);
} }
return varInfo;
} }
return varInfo;
} }


/** /**
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion test/com/google/javascript/jscomp/MultiPassTest.java
Expand Up @@ -425,7 +425,7 @@ private void addRemoveUnusedVars() {
new PassFactory("removeUnusedVars", false) { new PassFactory("removeUnusedVars", false) {
@Override @Override
protected CompilerPass create(AbstractCompiler compiler) { protected CompilerPass create(AbstractCompiler compiler) {
return new RemoveUnusedCode.Builder(compiler).build(); return new RemoveUnusedCode.Builder(compiler).removeLocalVars(true).build();
} }


@Override @Override
Expand Down
6 changes: 5 additions & 1 deletion test/com/google/javascript/jscomp/OptimizeCallsTest.java
Expand Up @@ -50,7 +50,11 @@ public void process(Node externs, Node root) {
defFinder.process(externs, root); defFinder.process(externs, root);


new PureFunctionIdentifier(compiler, defFinder).process(externs, root); new PureFunctionIdentifier(compiler, defFinder).process(externs, root);
new RemoveUnusedCode.Builder(compiler).removeGlobals(true).build().process(externs, root); new RemoveUnusedCode.Builder(compiler)
.removeLocalVars(true)
.removeGlobals(true)
.build()
.process(externs, root);


final OptimizeCalls passes = new OptimizeCalls(compiler); final OptimizeCalls passes = new OptimizeCalls(compiler);
passes.addPass(new OptimizeReturns(compiler)); passes.addPass(new OptimizeReturns(compiler));
Expand Down

0 comments on commit 34616d9

Please sign in to comment.