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

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: 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..277cdbb46f94a34cef8e64a452368d9b692457f6 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,19 @@ 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,
+ // unless they have been zapped before.
+ block.forEachPhi((HPhi phi) {
+ for (int i = 0; i < phi.inputs.length; ++i) {
+ if (!predecessors[i].isLive &&
+ phi.inputs[i] != zapInstruction) {
+ phi.inputs[i].usedBy.remove(phi);
+ HInstruction zap = zapInstruction;
karlklose 2014/03/12 14:43:45 Is this a performance optimization? I would prefer
herhut 2014/03/13 13:27:45 Done.
+ phi.inputs[i] = zap;
+ zap.usedBy.add(phi);
+ }
+ }
+ });
if (predecessors.length < 2) continue L;
// Find the index of the single live predecessor if it exists.
int indexOfLive = -1;
@@ -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);
+
+ Map<HInstruction, Range> get ranges =>
+ (this.compiler.backend as JavaScriptBackend).optimizer.ranges;
karlklose 2014/03/12 14:43:45 If you added a 'backend' field of type JavaScriptB
herhut 2014/03/13 13:27:45 I need the compiler, too, so I have decided to jus
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.inputs[0].isInteger(compiler)) {
karlklose 2014/03/12 14:43:45 'node.inputs[0]' -> 'node.expression'.
herhut 2014/03/13 13:27:45 Done.
+ Range switchRange = ranges[node.inputs[0]];
karlklose 2014/03/12 14:43:45 Ditto.
herhut 2014/03/13 13:27:45 Done.
+ 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];
+ assert(input.isConstantInteger());
karlklose 2014/03/12 14:43:45 I think this assertion is unnecessary, the code be
herhut 2014/03/13 13:27:45 You are probably right about the assert, it is a l
+ IntConstant constant = input.constant;
floitsch 2014/03/12 16:20:25 Pay attention that "-0.0" is a double-constant but
herhut 2014/03/13 13:27:45 0.0 should be illegal in case statements (and hope
+ int label = constant.value;
+ if (!liveLabels.contains(label) &&
+ (label <= upper) &&
karlklose 2014/03/12 14:43:45 No need for parentheses.
herhut 2014/03/13 13:27:45 I just like the visual grouping they provide. To k
+ (label >= lower)) {
karlklose 2014/03/12 14:43:45 Ditto.
herhut 2014/03/13 13:27:45 Done.
+ 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 {

Powered by Google App Engine
This is Rietveld 408576698