Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(405)

Unified Diff: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart

Issue 190763013: Detect total switches to prevent type pollution by default cases. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address review comments Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
index bea5bd525b5e9c4625196a35da3213a13cdeb562..89a6db057cca006e0e5bdd93a7768fdcec661b01 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/optimize.dart
@@ -16,6 +16,7 @@ class SsaOptimizerTask extends CompilerTask {
super(backend.compiler);
String get name => 'SSA optimizer';
Compiler get compiler => backend.compiler;
+ Map<HInstruction, Range> ranges = <HInstruction, Range>{};
void runPhases(HGraph graph, List<OptimizationPhase> phases) {
for (OptimizationPhase phase in phases) {
@@ -66,17 +67,24 @@ class SsaOptimizerTask extends CompilerTask {
new SsaInstructionSimplifier(constantSystem, backend, work),
new SsaCheckInserter(backend, work, context.boundsChecked),
new SsaSimplifyInterceptors(compiler, constantSystem, work),
- dce = new SsaDeadCodeEliminator(compiler)];
+ dce = new SsaDeadCodeEliminator(compiler),
+ new SsaTypePropagator(compiler)];
runPhases(graph, phases);
- if (!dce.eliminatedSideEffects) return;
- phases = <OptimizationPhase>[
- new SsaGlobalValueNumberer(compiler),
- new SsaCodeMotion(),
- new SsaValueRangeAnalyzer(compiler, constantSystem, work),
- new SsaInstructionSimplifier(constantSystem, backend, work),
- new SsaCheckInserter(backend, work, context.boundsChecked),
- new SsaSimplifyInterceptors(compiler, constantSystem, work),
- new SsaDeadCodeEliminator(compiler)];
+ if (dce.eliminatedSideEffects) {
+ phases = <OptimizationPhase>[
+ new SsaGlobalValueNumberer(compiler),
+ new SsaCodeMotion(),
+ new SsaValueRangeAnalyzer(compiler, constantSystem, work),
+ new SsaInstructionSimplifier(constantSystem, backend, work),
+ new SsaCheckInserter(backend, work, context.boundsChecked),
+ new SsaSimplifyInterceptors(compiler, constantSystem, work),
+ new SsaDeadCodeEliminator(compiler)];
+ } else {
+ phases = <OptimizationPhase>[
+ // Run the simplifier to remove unneeded type checks inserted
+ // by type propagation.
+ new SsaInstructionSimplifier(constantSystem, backend, work)];
+ }
runPhases(graph, phases);
});
}
@@ -941,7 +949,7 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
}
void visitGraph(HGraph graph) {
- analyzer = new SsaLiveBlockAnalyzer(graph);
+ analyzer = new SsaLiveBlockAnalyzer(graph, compiler);
analyzer.analyze();
visitPostDominatorTree(graph);
cleanPhis(graph);
@@ -969,6 +977,14 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
void cleanPhis(HGraph graph) {
L: for (HBasicBlock block in graph.blocks) {
List<HBasicBlock> predecessors = block.predecessors;
+ // Zap all inputs to phis that correspond to dead blocks.
+ block.forEachPhi((HPhi phi) {
+ for (int i = 0; i < phi.inputs.length; ++i) {
+ if (!predecessors[i].isLive && phi.inputs[i] != zapInstruction) {
+ replaceInput(i, phi, zapInstruction);
+ }
+ }
+ });
if (predecessors.length < 2) continue L;
// Find the index of the single live predecessor if it exists.
int indexOfLive = -1;
@@ -991,6 +1007,12 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
}
}
+ void replaceInput(int i, HInstruction from, HInstruction by) {
+ from.inputs[i].usedBy.remove(from);
+ from.inputs[i] = by;
+ by.usedBy.add(from);
+ }
+
void removeUsers(HInstruction instruction) {
instruction.usedBy.forEach((user) {
removeInput(user, instruction);
@@ -1002,9 +1024,8 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
List<HInstruction> inputs = user.inputs;
for (int i = 0, length = inputs.length; i < length; i++) {
if (input == inputs[i]) {
- HInstruction zap = zapInstruction;
- inputs[i] = zap;
- zap.usedBy.add(user);
+ user.inputs[i] = zapInstruction;
+ zapInstruction.usedBy.add(user);
}
}
}
@@ -1012,9 +1033,14 @@ class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
class SsaLiveBlockAnalyzer extends HBaseVisitor {
final HGraph graph;
+ final Compiler compiler;
final Set<HBasicBlock> live = new Set<HBasicBlock>();
final List<HBasicBlock> worklist = <HBasicBlock>[];
- SsaLiveBlockAnalyzer(this.graph);
+
+ SsaLiveBlockAnalyzer(this.graph, this.compiler);
+
+ JavaScriptBackend get backend => compiler.backend;
+ Map<HInstruction, Range> get ranges => backend.optimizer.ranges;
bool isDeadBlock(HBasicBlock block) => !live.contains(block);
@@ -1049,6 +1075,40 @@ class SsaLiveBlockAnalyzer extends HBaseVisitor {
visitControlFlow(instruction);
}
}
+
+ void visitSwitch(HSwitch node) {
+ if (!node.isTotal && node.expression.isInteger(compiler)) {
+ Range switchRange = ranges[node.expression];
+ if (switchRange != null &&
+ switchRange.lower is IntValue &&
+ switchRange.upper is IntValue) {
+ IntValue lowerValue = switchRange.lower;
+ IntValue upperValue = switchRange.upper;
+ int lower = lowerValue.value;
+ int upper = upperValue.value;
+ Set<int> liveLabels = new Set<int>();
+ for (int pos = 1; pos < node.inputs.length; pos++) {
+ HConstant input = node.inputs[pos];
+ if (!input.isConstantInteger()) continue;
+ IntConstant constant = input.constant;
+ int label = constant.value;
+ if (!liveLabels.contains(label) &&
+ label <= upper &&
+ label >= lower) {
+ markBlockLive(node.block.successors[pos - 1]);
+ liveLabels.add(label);
+ }
+ }
+ if (liveLabels.length != upper - lower + 1) {
+ markBlockLive(node.defaultTarget);
+ } else {
+ node.isTotal = true;
+ }
+ return;
+ }
+ }
+ visitControlFlow(node);
+ }
}
class SsaDeadPhiEliminator implements OptimizationPhase {
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/ssa/nodes.dart ('k') | sdk/lib/_internal/compiler/implementation/ssa/tracer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698