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

Side by Side Diff: pkg/compiler/lib/src/ssa/optimize.dart

Issue 2441463003: Rerun GVN if load elimination creates GVN candidates. (Closed)
Patch Set: dartfmt Created 3 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 5 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
6 import '../common/names.dart' show Selectors; 6 import '../common/names.dart' show Selectors;
7 import '../common/tasks.dart' show CompilerTask; 7 import '../common/tasks.dart' show CompilerTask;
8 import '../compiler.dart' show Compiler; 8 import '../compiler.dart' show Compiler;
9 import '../constants/constant_system.dart'; 9 import '../constants/constant_system.dart';
10 import '../constants/values.dart'; 10 import '../constants/values.dart';
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 void runPhase(OptimizationPhase phase) { 52 void runPhase(OptimizationPhase phase) {
53 measureSubtask(phase.name, () => phase.visitGraph(graph)); 53 measureSubtask(phase.name, () => phase.visitGraph(graph));
54 backend.tracer.traceGraph(phase.name, graph); 54 backend.tracer.traceGraph(phase.name, graph);
55 assert(graph.isValid()); 55 assert(graph.isValid());
56 } 56 }
57 57
58 bool trustPrimitives = compiler.options.trustPrimitives; 58 bool trustPrimitives = compiler.options.trustPrimitives;
59 CodegenRegistry registry = work.registry; 59 CodegenRegistry registry = work.registry;
60 Set<HInstruction> boundsChecked = new Set<HInstruction>(); 60 Set<HInstruction> boundsChecked = new Set<HInstruction>();
61 SsaCodeMotion codeMotion; 61 SsaCodeMotion codeMotion;
62 SsaLoadElimination loadElimination;
62 measure(() { 63 measure(() {
63 List<OptimizationPhase> phases = <OptimizationPhase>[ 64 List<OptimizationPhase> phases = <OptimizationPhase>[
64 // Run trivial instruction simplification first to optimize 65 // Run trivial instruction simplification first to optimize
65 // some patterns useful for type conversion. 66 // some patterns useful for type conversion.
66 new SsaInstructionSimplifier(backend, closedWorld, this, registry), 67 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
67 new SsaTypeConversionInserter(closedWorld), 68 new SsaTypeConversionInserter(closedWorld),
68 new SsaRedundantPhiEliminator(), 69 new SsaRedundantPhiEliminator(),
69 new SsaDeadPhiEliminator(), 70 new SsaDeadPhiEliminator(),
70 new SsaTypePropagator(compiler, closedWorld), 71 new SsaTypePropagator(compiler, closedWorld),
71 // After type propagation, more instructions can be 72 // After type propagation, more instructions can be
72 // simplified. 73 // simplified.
73 new SsaInstructionSimplifier(backend, closedWorld, this, registry), 74 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
74 new SsaCheckInserter( 75 new SsaCheckInserter(
75 trustPrimitives, backend, closedWorld, boundsChecked), 76 trustPrimitives, backend, closedWorld, boundsChecked),
76 new SsaInstructionSimplifier(backend, closedWorld, this, registry), 77 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
77 new SsaCheckInserter( 78 new SsaCheckInserter(
78 trustPrimitives, backend, closedWorld, boundsChecked), 79 trustPrimitives, backend, closedWorld, boundsChecked),
79 new SsaTypePropagator(compiler, closedWorld), 80 new SsaTypePropagator(compiler, closedWorld),
80 // Run a dead code eliminator before LICM because dead 81 // Run a dead code eliminator before LICM because dead
81 // interceptors are often in the way of LICM'able instructions. 82 // interceptors are often in the way of LICM'able instructions.
82 new SsaDeadCodeEliminator(closedWorld, this), 83 new SsaDeadCodeEliminator(closedWorld, this),
83 new SsaGlobalValueNumberer(), 84 new SsaGlobalValueNumberer(),
84 // After GVN, some instructions might need their type to be 85 // After GVN, some instructions might need their type to be
85 // updated because they now have different inputs. 86 // updated because they now have different inputs.
86 new SsaTypePropagator(compiler, closedWorld), 87 new SsaTypePropagator(compiler, closedWorld),
87 codeMotion = new SsaCodeMotion(), 88 codeMotion = new SsaCodeMotion(),
88 new SsaLoadElimination(backend, compiler, closedWorld), 89 loadElimination =
90 new SsaLoadElimination(backend, compiler, closedWorld),
89 new SsaRedundantPhiEliminator(), 91 new SsaRedundantPhiEliminator(),
90 new SsaDeadPhiEliminator(), 92 new SsaDeadPhiEliminator(),
91 // After GVN and load elimination the same value may be used in code 93 // After GVN and load elimination the same value may be used in code
92 // controlled by a test on the value, so redo 'conversion insertion' to 94 // controlled by a test on the value, so redo 'conversion insertion' to
93 // learn from the refined type. 95 // learn from the refined type.
94 new SsaTypeConversionInserter(closedWorld), 96 new SsaTypeConversionInserter(closedWorld),
95 new SsaTypePropagator(compiler, closedWorld), 97 new SsaTypePropagator(compiler, closedWorld),
96 new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this), 98 new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this),
97 // Previous optimizations may have generated new 99 // Previous optimizations may have generated new
98 // opportunities for instruction simplification. 100 // opportunities for instruction simplification.
99 new SsaInstructionSimplifier(backend, closedWorld, this, registry), 101 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
100 new SsaCheckInserter( 102 new SsaCheckInserter(
101 trustPrimitives, backend, closedWorld, boundsChecked), 103 trustPrimitives, backend, closedWorld, boundsChecked),
102 ]; 104 ];
103 phases.forEach(runPhase); 105 phases.forEach(runPhase);
104 106
105 // Simplifying interceptors is not strictly just an optimization, it is 107 // Simplifying interceptors is not strictly just an optimization, it is
106 // required for implementation correctness because the code generator 108 // required for implementation correctness because the code generator
107 // assumes it is always performed. 109 // assumes it is always performed.
108 runPhase(new SsaSimplifyInterceptors( 110 runPhase(new SsaSimplifyInterceptors(
109 compiler, closedWorld, work.element.enclosingClass)); 111 compiler, closedWorld, work.element.enclosingClass));
110 112
111 SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(closedWorld, this); 113 SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(closedWorld, this);
112 runPhase(dce); 114 runPhase(dce);
113 if (codeMotion.movedCode || dce.eliminatedSideEffects) { 115 if (codeMotion.movedCode ||
116 dce.eliminatedSideEffects ||
117 loadElimination.newGvnCandidates) {
114 phases = <OptimizationPhase>[ 118 phases = <OptimizationPhase>[
115 new SsaTypePropagator(compiler, closedWorld), 119 new SsaTypePropagator(compiler, closedWorld),
116 new SsaGlobalValueNumberer(), 120 new SsaGlobalValueNumberer(),
117 new SsaCodeMotion(), 121 new SsaCodeMotion(),
118 new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this), 122 new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this),
119 new SsaInstructionSimplifier(backend, closedWorld, this, registry), 123 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
120 new SsaCheckInserter( 124 new SsaCheckInserter(
121 trustPrimitives, backend, closedWorld, boundsChecked), 125 trustPrimitives, backend, closedWorld, boundsChecked),
122 new SsaSimplifyInterceptors( 126 new SsaSimplifyInterceptors(
123 compiler, closedWorld, work.element.enclosingClass), 127 compiler, closedWorld, work.element.enclosingClass),
(...skipping 2129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2253 * example [HFieldGet]), when it knows the value stored in that memory 2257 * example [HFieldGet]), when it knows the value stored in that memory
2254 * location. 2258 * location.
2255 */ 2259 */
2256 class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { 2260 class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase {
2257 final JavaScriptBackend backend; 2261 final JavaScriptBackend backend;
2258 final Compiler compiler; 2262 final Compiler compiler;
2259 final ClosedWorld closedWorld; 2263 final ClosedWorld closedWorld;
2260 final String name = "SsaLoadElimination"; 2264 final String name = "SsaLoadElimination";
2261 MemorySet memorySet; 2265 MemorySet memorySet;
2262 List<MemorySet> memories; 2266 List<MemorySet> memories;
2267 bool newGvnCandidates = false;
2263 2268
2264 SsaLoadElimination(this.backend, this.compiler, this.closedWorld); 2269 SsaLoadElimination(this.backend, this.compiler, this.closedWorld);
2265 2270
2266 void visitGraph(HGraph graph) { 2271 void visitGraph(HGraph graph) {
2267 memories = new List<MemorySet>(graph.blocks.length); 2272 memories = new List<MemorySet>(graph.blocks.length);
2268 List<HBasicBlock> blocks = graph.blocks; 2273 List<HBasicBlock> blocks = graph.blocks;
2269 for (int i = 0; i < blocks.length; i++) { 2274 for (int i = 0; i < blocks.length; i++) {
2270 HBasicBlock block = blocks[i]; 2275 HBasicBlock block = blocks[i];
2271 visitBasicBlock(block); 2276 visitBasicBlock(block);
2272 if (block.successors.isNotEmpty && block.successors[0].isLoopHeader()) { 2277 if (block.successors.isNotEmpty && block.successors[0].isLoopHeader()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2307 2312
2308 memories[block.id] = memorySet; 2313 memories[block.id] = memorySet;
2309 HInstruction instruction = block.first; 2314 HInstruction instruction = block.first;
2310 while (instruction != null) { 2315 while (instruction != null) {
2311 HInstruction next = instruction.next; 2316 HInstruction next = instruction.next;
2312 instruction.accept(this); 2317 instruction.accept(this);
2313 instruction = next; 2318 instruction = next;
2314 } 2319 }
2315 } 2320 }
2316 2321
2322 void checkNewGvnCandidates(HInstruction instruction, HInstruction existing) {
2323 if (newGvnCandidates) return;
2324 bool hasUseGvn(HInstruction insn) => insn.nonCheck().useGvn();
2325 if (instruction.usedBy.any(hasUseGvn) && existing.usedBy.any(hasUseGvn)) {
2326 newGvnCandidates = true;
2327 }
2328 }
2329
2317 void visitFieldGet(HFieldGet instruction) { 2330 void visitFieldGet(HFieldGet instruction) {
2318 if (instruction.isNullCheck) return; 2331 if (instruction.isNullCheck) return;
2319 FieldEntity element = instruction.element; 2332 FieldEntity element = instruction.element;
2320 HInstruction receiver = instruction.getDartReceiver(closedWorld).nonCheck(); 2333 HInstruction receiver = instruction.getDartReceiver(closedWorld).nonCheck();
2321 _visitFieldGet(element, receiver, instruction); 2334 _visitFieldGet(element, receiver, instruction);
2322 } 2335 }
2323 2336
2324 void visitGetLength(HGetLength instruction) { 2337 void visitGetLength(HGetLength instruction) {
2325 _visitFieldGet(backend.helpers.jsIndexableLength, 2338 _visitFieldGet(backend.helpers.jsIndexableLength,
2326 instruction.receiver.nonCheck(), instruction); 2339 instruction.receiver.nonCheck(), instruction);
2327 } 2340 }
2328 2341
2329 void _visitFieldGet( 2342 void _visitFieldGet(
2330 MemberEntity element, HInstruction receiver, HInstruction instruction) { 2343 MemberEntity element, HInstruction receiver, HInstruction instruction) {
2331 HInstruction existing = memorySet.lookupFieldValue(element, receiver); 2344 HInstruction existing = memorySet.lookupFieldValue(element, receiver);
2332 if (existing != null) { 2345 if (existing != null) {
2346 checkNewGvnCandidates(instruction, existing);
2333 instruction.block.rewriteWithBetterUser(instruction, existing); 2347 instruction.block.rewriteWithBetterUser(instruction, existing);
2334 instruction.block.remove(instruction); 2348 instruction.block.remove(instruction);
2335 } else { 2349 } else {
2336 memorySet.registerFieldValue(element, receiver, instruction); 2350 memorySet.registerFieldValue(element, receiver, instruction);
2337 } 2351 }
2338 } 2352 }
2339 2353
2340 void visitFieldSet(HFieldSet instruction) { 2354 void visitFieldSet(HFieldSet instruction) {
2341 HInstruction receiver = instruction.getDartReceiver(closedWorld).nonCheck(); 2355 HInstruction receiver = instruction.getDartReceiver(closedWorld).nonCheck();
2342 memorySet.registerFieldValueUpdate( 2356 memorySet.registerFieldValueUpdate(
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2405 } 2419 }
2406 2420
2407 void visitLazyStatic(HLazyStatic instruction) { 2421 void visitLazyStatic(HLazyStatic instruction) {
2408 FieldEntity field = instruction.element; 2422 FieldEntity field = instruction.element;
2409 handleStaticLoad(field, instruction); 2423 handleStaticLoad(field, instruction);
2410 } 2424 }
2411 2425
2412 void handleStaticLoad(MemberEntity element, HInstruction instruction) { 2426 void handleStaticLoad(MemberEntity element, HInstruction instruction) {
2413 HInstruction existing = memorySet.lookupFieldValue(element, null); 2427 HInstruction existing = memorySet.lookupFieldValue(element, null);
2414 if (existing != null) { 2428 if (existing != null) {
2429 checkNewGvnCandidates(instruction, existing);
2415 instruction.block.rewriteWithBetterUser(instruction, existing); 2430 instruction.block.rewriteWithBetterUser(instruction, existing);
2416 instruction.block.remove(instruction); 2431 instruction.block.remove(instruction);
2417 } else { 2432 } else {
2418 memorySet.registerFieldValue(element, null, instruction); 2433 memorySet.registerFieldValue(element, null, instruction);
2419 } 2434 }
2420 } 2435 }
2421 2436
2422 void visitStatic(HStatic instruction) { 2437 void visitStatic(HStatic instruction) {
2423 handleStaticLoad(instruction.element, instruction); 2438 handleStaticLoad(instruction.element, instruction);
2424 } 2439 }
2425 2440
2426 void visitStaticStore(HStaticStore instruction) { 2441 void visitStaticStore(HStaticStore instruction) {
2427 memorySet.registerFieldValueUpdate( 2442 memorySet.registerFieldValueUpdate(
2428 instruction.element, null, instruction.inputs.last); 2443 instruction.element, null, instruction.inputs.last);
2429 } 2444 }
2430 2445
2431 void visitLiteralList(HLiteralList instruction) { 2446 void visitLiteralList(HLiteralList instruction) {
2432 memorySet.registerAllocation(instruction); 2447 memorySet.registerAllocation(instruction);
2433 memorySet.killAffectedBy(instruction); 2448 memorySet.killAffectedBy(instruction);
2434 // TODO(sra): Set initial keyed values. 2449 // TODO(sra): Set initial keyed values.
2435 // TODO(sra): Set initial length. 2450 // TODO(sra): Set initial length.
2436 } 2451 }
2437 2452
2438 void visitIndex(HIndex instruction) { 2453 void visitIndex(HIndex instruction) {
2439 HInstruction receiver = instruction.receiver.nonCheck(); 2454 HInstruction receiver = instruction.receiver.nonCheck();
2440 HInstruction existing = 2455 HInstruction existing =
2441 memorySet.lookupKeyedValue(receiver, instruction.index); 2456 memorySet.lookupKeyedValue(receiver, instruction.index);
2442 if (existing != null) { 2457 if (existing != null) {
2458 checkNewGvnCandidates(instruction, existing);
2443 instruction.block.rewriteWithBetterUser(instruction, existing); 2459 instruction.block.rewriteWithBetterUser(instruction, existing);
2444 instruction.block.remove(instruction); 2460 instruction.block.remove(instruction);
2445 } else { 2461 } else {
2446 memorySet.registerKeyedValue(receiver, instruction.index, instruction); 2462 memorySet.registerKeyedValue(receiver, instruction.index, instruction);
2447 } 2463 }
2448 } 2464 }
2449 2465
2450 void visitIndexAssign(HIndexAssign instruction) { 2466 void visitIndexAssign(HIndexAssign instruction) {
2451 HInstruction receiver = instruction.receiver.nonCheck(); 2467 HInstruction receiver = instruction.receiver.nonCheck();
2452 memorySet.registerKeyedValueUpdate( 2468 memorySet.registerKeyedValueUpdate(
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
2788 2804
2789 keyedValues.forEach((receiver, values) { 2805 keyedValues.forEach((receiver, values) {
2790 result.keyedValues[receiver] = 2806 result.keyedValues[receiver] =
2791 new Map<HInstruction, HInstruction>.from(values); 2807 new Map<HInstruction, HInstruction>.from(values);
2792 }); 2808 });
2793 2809
2794 result.nonEscapingReceivers.addAll(nonEscapingReceivers); 2810 result.nonEscapingReceivers.addAll(nonEscapingReceivers);
2795 return result; 2811 return result;
2796 } 2812 }
2797 } 2813 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698