Skip to content

Commit ea3ac77

Browse files
rahul-kamatcopybara-github
authored andcommitted
Implement marker passes for JSCompiler stage 2 splitting
This CL implements the proposal to use marker passes for splitting JSCompiler's Stage 2 optimization phase. Previously, users adding custom passes could encounter errors if the target pass for 'addBefore' was only present in one segment of the split stage 2. This change resolves the issue by: - Always returning the complete list of stage 2 passes in `DefaultPassConfig.getOptimizations()`, including an empty marker pass (`PassNames.OPTIMIZATIONS_HALFWAY_POINT`) to indicate the split. - Modifying `Compiler.performTranspilationAndOptimizations()` to construct the actual pass list for each stage 2 segment based on the marker pass, and then providing this list to `PhaseOptimizer`. PiperOrigin-RevId: 734309816
1 parent 78f9aa1 commit ea3ac77

File tree

3 files changed

+80
-15
lines changed

3 files changed

+80
-15
lines changed

src/com/google/javascript/jscomp/Compiler.java

+76-3
Original file line numberDiff line numberDiff line change
@@ -2974,17 +2974,21 @@ boolean endsWith(String suffix) {
29742974
void performTranspilationAndOptimizations(OptimizationPasses optimizationPasses) {
29752975
checkState(options.shouldOptimize());
29762976
// getOptimizations() also includes transpilation passes
2977-
ImmutableList<PassFactory> optimizations =
2977+
ImmutableList<PassFactory> allOptimizationPassesToRun =
29782978
getPassConfig().getOptimizations(optimizationPasses).build();
2979-
if (optimizations.isEmpty()) {
2979+
if (allOptimizationPassesToRun.isEmpty()) {
29802980
return;
29812981
}
29822982

2983+
// Get the subset of optimization passes to run in the current segment of optimizations.
2984+
List<PassFactory> optimizationPassesToRunInCurrentSegment =
2985+
getOptimizationPassesToRunInCurrentSegment(optimizationPasses, allOptimizationPassesToRun);
2986+
29832987
// note whether any script gets transpiled
29842988
markTranspiledFiles();
29852989

29862990
phaseOptimizer = createPhaseOptimizer();
2987-
phaseOptimizer.consume(optimizations);
2991+
phaseOptimizer.consume(optimizationPassesToRunInCurrentSegment);
29882992
phaseOptimizer.process(externsRoot, jsRoot);
29892993
phaseOptimizer = null;
29902994
}
@@ -3015,6 +3019,75 @@ ControlFlowGraph<Node> computeCFG() {
30153019
return cfg;
30163020
}
30173021

3022+
/**
3023+
* Takes the entire list of optimization passes to run in the current build, and returns the
3024+
* subset of passes that should be run in this current segment of optimizations.
3025+
*
3026+
* <p>The 3 cases are:
3027+
*
3028+
* <ol>
3029+
* <li>If we are running `OptimizationPasses.ALL`, this will return the entire list of
3030+
* optimization passes.
3031+
* <li>If we are running `OptimizationPasses.FIRST_HALF`, this will return all passes up to the
3032+
* half-way point marker pass `OPTIMIZATIONS_HALFWAY_POINT`.
3033+
* <li>If we are running `OptimizationPasses.SECOND_HALF`, this will return all passes after the
3034+
* half-way point marker pass `OPTIMIZATIONS_HALFWAY_POINT`.
3035+
* </ol>
3036+
*/
3037+
private List<PassFactory> getOptimizationPassesToRunInCurrentSegment(
3038+
OptimizationPasses optimizationPasses, List<PassFactory> allOptimizationPassesToRun) {
3039+
3040+
// Create a list of passes based on which segment of optimizations we are running.
3041+
List<PassFactory> optimizationPassList = new ArrayList<>();
3042+
3043+
switch (optimizationPasses) {
3044+
case ALL:
3045+
optimizationPassList = allOptimizationPassesToRun;
3046+
break;
3047+
case FIRST_HALF:
3048+
optimizationPassList =
3049+
passListUntil(allOptimizationPassesToRun, PassNames.OPTIMIZATIONS_HALFWAY_POINT);
3050+
break;
3051+
case SECOND_HALF:
3052+
optimizationPassList =
3053+
passListAfter(allOptimizationPassesToRun, PassNames.OPTIMIZATIONS_HALFWAY_POINT);
3054+
break;
3055+
}
3056+
3057+
return optimizationPassList;
3058+
}
3059+
3060+
/**
3061+
* Returns a subset of passes from the given list of passes, up to but not including the given
3062+
* pass name.
3063+
*/
3064+
private List<PassFactory> passListUntil(List<PassFactory> passes, String passName) {
3065+
List<PassFactory> passList = new ArrayList<>();
3066+
for (PassFactory pass : passes) {
3067+
if (pass.getName().equals(passName)) {
3068+
return passList;
3069+
}
3070+
passList.add(pass);
3071+
}
3072+
return passList;
3073+
}
3074+
3075+
/**
3076+
* Returns a subset of passes from the given list of passes, starting right after the given pass
3077+
* name.
3078+
*/
3079+
private List<PassFactory> passListAfter(List<PassFactory> passes, String passName) {
3080+
List<PassFactory> passList = new ArrayList<>();
3081+
for (PassFactory pass : passes) {
3082+
if (pass.getName().equals(passName)) {
3083+
passList.clear();
3084+
continue;
3085+
}
3086+
passList.add(pass);
3087+
}
3088+
return passList;
3089+
}
3090+
30183091
private static final String SYNTHETIC_FILE_NAME_PREFIX = " [synthetic:";
30193092

30203093
private static final InputId SYNTHETIC_CODE_INPUT_ID =

src/com/google/javascript/jscomp/DefaultPassConfig.java

+3-12
Original file line numberDiff line numberDiff line change
@@ -524,18 +524,9 @@ protected PassListBuilder getOptimizations(OptimizationPasses optimizationPasses
524524
return passes;
525525
}
526526

527-
switch (optimizationPasses) {
528-
case FIRST_HALF:
529-
passes.addAll(getEarlyOptimizationPasses());
530-
break;
531-
case SECOND_HALF:
532-
passes.addAll(getLateOptimizationPasses());
533-
break;
534-
case ALL:
535-
passes.addAll(getEarlyOptimizationPasses());
536-
passes.addAll(getLateOptimizationPasses());
537-
break;
538-
}
527+
passes.addAll(getEarlyOptimizationPasses());
528+
passes.maybeAdd(createEmptyPass(PassNames.OPTIMIZATIONS_HALFWAY_POINT));
529+
passes.addAll(getLateOptimizationPasses());
539530

540531
return passes;
541532
}

src/com/google/javascript/jscomp/PassNames.java

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public final class PassNames {
7777
public static final String LINT_CHECKS = "lintChecks";
7878
public static final String MARK_UNNORMALIZED = "markUnnormalized";
7979
public static final String NORMALIZE = "normalize";
80+
public static final String OPTIMIZATIONS_HALFWAY_POINT = "optimizationsHalfwayPoint";
8081
public static final String OPTIMIZE_CALLS = "optimizeCalls";
8182
public static final String PARSE_INPUTS = "parseInputs";
8283
public static final String PEEPHOLE_OPTIMIZATIONS = "peepholeOptimizations";

0 commit comments

Comments
 (0)