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

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

Issue 2585223002: Access ConstantSystem through ClosedWorld. (Closed)
Patch Set: Created 4 years 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
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';
11 import '../core_types.dart' show CommonElements, CoreClasses; 11 import '../core_types.dart' show CommonElements;
12 import '../dart_types.dart'; 12 import '../dart_types.dart';
13 import '../elements/elements.dart'; 13 import '../elements/elements.dart';
14 import '../js/js.dart' as js; 14 import '../js/js.dart' as js;
15 import '../js_backend/backend_helpers.dart' show BackendHelpers; 15 import '../js_backend/backend_helpers.dart' show BackendHelpers;
16 import '../js_backend/js_backend.dart'; 16 import '../js_backend/js_backend.dart';
17 import '../native/native.dart' as native; 17 import '../native/native.dart' as native;
18 import '../tree/dartstring.dart' as ast; 18 import '../tree/dartstring.dart' as ast;
19 import '../types/types.dart'; 19 import '../types/types.dart';
20 import '../universe/selector.dart' show Selector; 20 import '../universe/selector.dart' show Selector;
21 import '../universe/side_effects.dart' show SideEffects; 21 import '../universe/side_effects.dart' show SideEffects;
(...skipping 24 matching lines...) Expand all
46 46
47 Compiler get compiler => backend.compiler; 47 Compiler get compiler => backend.compiler;
48 48
49 void optimize(CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) { 49 void optimize(CodegenWorkItem work, HGraph graph, ClosedWorld closedWorld) {
50 void runPhase(OptimizationPhase phase) { 50 void runPhase(OptimizationPhase phase) {
51 measureSubtask(phase.name, () => phase.visitGraph(graph)); 51 measureSubtask(phase.name, () => phase.visitGraph(graph));
52 backend.tracer.traceGraph(phase.name, graph); 52 backend.tracer.traceGraph(phase.name, graph);
53 assert(graph.isValid()); 53 assert(graph.isValid());
54 } 54 }
55 55
56 ConstantSystem constantSystem = compiler.backend.constantSystem;
57 bool trustPrimitives = compiler.options.trustPrimitives; 56 bool trustPrimitives = compiler.options.trustPrimitives;
58 CodegenRegistry registry = work.registry; 57 CodegenRegistry registry = work.registry;
59 Set<HInstruction> boundsChecked = new Set<HInstruction>(); 58 Set<HInstruction> boundsChecked = new Set<HInstruction>();
60 SsaCodeMotion codeMotion; 59 SsaCodeMotion codeMotion;
61 measure(() { 60 measure(() {
62 List<OptimizationPhase> phases = <OptimizationPhase>[ 61 List<OptimizationPhase> phases = <OptimizationPhase>[
63 // Run trivial instruction simplification first to optimize 62 // Run trivial instruction simplification first to optimize
64 // some patterns useful for type conversion. 63 // some patterns useful for type conversion.
65 new SsaInstructionSimplifier( 64 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
66 constantSystem, backend, closedWorld, this, registry),
67 new SsaTypeConversionInserter(closedWorld), 65 new SsaTypeConversionInserter(closedWorld),
68 new SsaRedundantPhiEliminator(), 66 new SsaRedundantPhiEliminator(),
69 new SsaDeadPhiEliminator(), 67 new SsaDeadPhiEliminator(),
70 new SsaTypePropagator(compiler, closedWorld), 68 new SsaTypePropagator(compiler, closedWorld),
71 // After type propagation, more instructions can be 69 // After type propagation, more instructions can be
72 // simplified. 70 // simplified.
73 new SsaInstructionSimplifier( 71 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
74 constantSystem, backend, closedWorld, this, registry),
75 new SsaCheckInserter( 72 new SsaCheckInserter(
76 trustPrimitives, backend, closedWorld, boundsChecked), 73 trustPrimitives, backend, closedWorld, boundsChecked),
77 new SsaInstructionSimplifier( 74 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
78 constantSystem, backend, closedWorld, this, registry),
79 new SsaCheckInserter( 75 new SsaCheckInserter(
80 trustPrimitives, backend, closedWorld, boundsChecked), 76 trustPrimitives, backend, closedWorld, boundsChecked),
81 new SsaTypePropagator(compiler, closedWorld), 77 new SsaTypePropagator(compiler, closedWorld),
82 // Run a dead code eliminator before LICM because dead 78 // Run a dead code eliminator before LICM because dead
83 // interceptors are often in the way of LICM'able instructions. 79 // interceptors are often in the way of LICM'able instructions.
84 new SsaDeadCodeEliminator(compiler, closedWorld, this), 80 new SsaDeadCodeEliminator(closedWorld, this),
85 new SsaGlobalValueNumberer(compiler), 81 new SsaGlobalValueNumberer(),
86 // After GVN, some instructions might need their type to be 82 // After GVN, some instructions might need their type to be
87 // updated because they now have different inputs. 83 // updated because they now have different inputs.
88 new SsaTypePropagator(compiler, closedWorld), 84 new SsaTypePropagator(compiler, closedWorld),
89 codeMotion = new SsaCodeMotion(), 85 codeMotion = new SsaCodeMotion(),
90 new SsaLoadElimination(compiler, closedWorld), 86 new SsaLoadElimination(compiler, closedWorld),
91 new SsaRedundantPhiEliminator(), 87 new SsaRedundantPhiEliminator(),
92 new SsaDeadPhiEliminator(), 88 new SsaDeadPhiEliminator(),
93 new SsaTypePropagator(compiler, closedWorld), 89 new SsaTypePropagator(compiler, closedWorld),
94 new SsaValueRangeAnalyzer(compiler, closedWorld, constantSystem, this), 90 new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this),
95 // Previous optimizations may have generated new 91 // Previous optimizations may have generated new
96 // opportunities for instruction simplification. 92 // opportunities for instruction simplification.
97 new SsaInstructionSimplifier( 93 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
98 constantSystem, backend, closedWorld, this, registry),
99 new SsaCheckInserter( 94 new SsaCheckInserter(
100 trustPrimitives, backend, closedWorld, boundsChecked), 95 trustPrimitives, backend, closedWorld, boundsChecked),
101 ]; 96 ];
102 phases.forEach(runPhase); 97 phases.forEach(runPhase);
103 98
104 // Simplifying interceptors is not strictly just an optimization, it is 99 // Simplifying interceptors is not strictly just an optimization, it is
105 // required for implementation correctness because the code generator 100 // required for implementation correctness because the code generator
106 // assumes it is always performed. 101 // assumes it is always performed.
107 runPhase(new SsaSimplifyInterceptors( 102 runPhase(
108 compiler, closedWorld, constantSystem, work.element)); 103 new SsaSimplifyInterceptors(compiler, closedWorld, work.element));
109 104
110 SsaDeadCodeEliminator dce = 105 SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(closedWorld, this);
111 new SsaDeadCodeEliminator(compiler, closedWorld, this);
112 runPhase(dce); 106 runPhase(dce);
113 if (codeMotion.movedCode || dce.eliminatedSideEffects) { 107 if (codeMotion.movedCode || dce.eliminatedSideEffects) {
114 phases = <OptimizationPhase>[ 108 phases = <OptimizationPhase>[
115 new SsaTypePropagator(compiler, closedWorld), 109 new SsaTypePropagator(compiler, closedWorld),
116 new SsaGlobalValueNumberer(compiler), 110 new SsaGlobalValueNumberer(),
117 new SsaCodeMotion(), 111 new SsaCodeMotion(),
118 new SsaValueRangeAnalyzer( 112 new SsaValueRangeAnalyzer(backend.helpers, closedWorld, this),
119 compiler, closedWorld, constantSystem, this), 113 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
120 new SsaInstructionSimplifier(
121 constantSystem, backend, closedWorld, this, registry),
122 new SsaCheckInserter( 114 new SsaCheckInserter(
123 trustPrimitives, backend, closedWorld, boundsChecked), 115 trustPrimitives, backend, closedWorld, boundsChecked),
124 new SsaSimplifyInterceptors( 116 new SsaSimplifyInterceptors(compiler, closedWorld, work.element),
125 compiler, closedWorld, constantSystem, work.element), 117 new SsaDeadCodeEliminator(closedWorld, this),
126 new SsaDeadCodeEliminator(compiler, closedWorld, this),
127 ]; 118 ];
128 } else { 119 } else {
129 phases = <OptimizationPhase>[ 120 phases = <OptimizationPhase>[
130 new SsaTypePropagator(compiler, closedWorld), 121 new SsaTypePropagator(compiler, closedWorld),
131 // Run the simplifier to remove unneeded type checks inserted by 122 // Run the simplifier to remove unneeded type checks inserted by
132 // type propagation. 123 // type propagation.
133 new SsaInstructionSimplifier( 124 new SsaInstructionSimplifier(backend, closedWorld, this, registry),
134 constantSystem, backend, closedWorld, this, registry),
135 ]; 125 ];
136 } 126 }
137 phases.forEach(runPhase); 127 phases.forEach(runPhase);
138 }); 128 });
139 } 129 }
140 } 130 }
141 131
142 /// Returns `true` if [mask] represents only types that have a length that 132 /// Returns `true` if [mask] represents only types that have a length that
143 /// cannot change. The current implementation is conservative for the purpose 133 /// cannot change. The current implementation is conservative for the purpose
144 /// of identifying gvn-able lengths and mis-identifies some unions of fixed 134 /// of identifying gvn-able lengths and mis-identifies some unions of fixed
(...skipping 20 matching lines...) Expand all
165 class SsaInstructionSimplifier extends HBaseVisitor 155 class SsaInstructionSimplifier extends HBaseVisitor
166 implements OptimizationPhase { 156 implements OptimizationPhase {
167 // We don't produce constant-folded strings longer than this unless they have 157 // We don't produce constant-folded strings longer than this unless they have
168 // a single use. This protects against exponentially large constant folded 158 // a single use. This protects against exponentially large constant folded
169 // strings. 159 // strings.
170 static const MAX_SHARED_CONSTANT_FOLDED_STRING_LENGTH = 512; 160 static const MAX_SHARED_CONSTANT_FOLDED_STRING_LENGTH = 512;
171 161
172 final String name = "SsaInstructionSimplifier"; 162 final String name = "SsaInstructionSimplifier";
173 final JavaScriptBackend backend; 163 final JavaScriptBackend backend;
174 final ClosedWorld closedWorld; 164 final ClosedWorld closedWorld;
175 final ConstantSystem constantSystem;
176 final CodegenRegistry registry; 165 final CodegenRegistry registry;
177 HGraph graph; 166 HGraph graph;
178 Compiler get compiler => backend.compiler; 167 Compiler get compiler => backend.compiler;
179 final SsaOptimizerTask optimizer; 168 final SsaOptimizerTask optimizer;
180 169
181 SsaInstructionSimplifier(this.constantSystem, this.backend, this.closedWorld, 170 SsaInstructionSimplifier(
182 this.optimizer, this.registry); 171 this.backend, this.closedWorld, this.optimizer, this.registry);
183 172
184 CommonElements get commonElements => closedWorld.commonElements; 173 CommonElements get commonElements => closedWorld.commonElements;
185 174
186 BackendHelpers get helpers => backend.helpers; 175 BackendHelpers get helpers => backend.helpers;
187 176
177 ConstantSystem get constantSystem => closedWorld.constantSystem;
178
188 GlobalTypeInferenceResults get globalInferenceResults => 179 GlobalTypeInferenceResults get globalInferenceResults =>
189 compiler.globalInference.results; 180 compiler.globalInference.results;
190 181
191 void visitGraph(HGraph visitee) { 182 void visitGraph(HGraph visitee) {
192 graph = visitee; 183 graph = visitee;
193 visitDominatorTree(visitee); 184 visitDominatorTree(visitee);
194 } 185 }
195 186
196 visitBasicBlock(HBasicBlock block) { 187 visitBasicBlock(HBasicBlock block) {
197 HInstruction instruction = block.first; 188 HInstruction instruction = block.first;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 242 }
252 // TODO(het): consider supporting other values (short strings?) 243 // TODO(het): consider supporting other values (short strings?)
253 } 244 }
254 return null; 245 return null;
255 } 246 }
256 247
257 void propagateConstantValueToUses(HInstruction node) { 248 void propagateConstantValueToUses(HInstruction node) {
258 if (node.usedBy.isEmpty) return; 249 if (node.usedBy.isEmpty) return;
259 ConstantValue value = getConstantFromType(node); 250 ConstantValue value = getConstantFromType(node);
260 if (value != null) { 251 if (value != null) {
261 HConstant constant = graph.addConstant(value, compiler); 252 HConstant constant = graph.addConstant(value, closedWorld);
262 for (HInstruction user in node.usedBy.toList()) { 253 for (HInstruction user in node.usedBy.toList()) {
263 user.changeUse(node, constant); 254 user.changeUse(node, constant);
264 } 255 }
265 } 256 }
266 } 257 }
267 258
268 HInstruction visitParameterValue(HParameterValue node) { 259 HInstruction visitParameterValue(HParameterValue node) {
269 // [HParameterValue]s are either the value of the parameter (in fully SSA 260 // [HParameterValue]s are either the value of the parameter (in fully SSA
270 // converted code), or the mutable variable containing the value (in 261 // converted code), or the mutable variable containing the value (in
271 // incompletely SSA converted code, e.g. methods containing exceptions). 262 // incompletely SSA converted code, e.g. methods containing exceptions).
(...skipping 26 matching lines...) Expand all
298 289
299 // If the code is unreachable, remove the HBoolify. This can happen when 290 // If the code is unreachable, remove the HBoolify. This can happen when
300 // there is a throw expression in a short-circuit conditional. Removing the 291 // there is a throw expression in a short-circuit conditional. Removing the
301 // unreachable HBoolify makes it easier to reconstruct the short-circuit 292 // unreachable HBoolify makes it easier to reconstruct the short-circuit
302 // operation. 293 // operation.
303 if (input.instructionType.isEmpty) return input; 294 if (input.instructionType.isEmpty) return input;
304 295
305 // All values that cannot be 'true' are boolified to false. 296 // All values that cannot be 'true' are boolified to false.
306 TypeMask mask = input.instructionType; 297 TypeMask mask = input.instructionType;
307 if (!mask.contains(helpers.jsBoolClass, closedWorld)) { 298 if (!mask.contains(helpers.jsBoolClass, closedWorld)) {
308 return graph.addConstantBool(false, compiler); 299 return graph.addConstantBool(false, closedWorld);
309 } 300 }
310 return node; 301 return node;
311 } 302 }
312 303
313 HInstruction visitNot(HNot node) { 304 HInstruction visitNot(HNot node) {
314 List<HInstruction> inputs = node.inputs; 305 List<HInstruction> inputs = node.inputs;
315 assert(inputs.length == 1); 306 assert(inputs.length == 1);
316 HInstruction input = inputs[0]; 307 HInstruction input = inputs[0];
317 if (input is HConstant) { 308 if (input is HConstant) {
318 HConstant constant = input; 309 HConstant constant = input;
319 bool isTrue = constant.constant.isTrue; 310 bool isTrue = constant.constant.isTrue;
320 return graph.addConstantBool(!isTrue, compiler); 311 return graph.addConstantBool(!isTrue, closedWorld);
321 } else if (input is HNot) { 312 } else if (input is HNot) {
322 return input.inputs[0]; 313 return input.inputs[0];
323 } 314 }
324 return node; 315 return node;
325 } 316 }
326 317
327 HInstruction visitInvokeUnary(HInvokeUnary node) { 318 HInstruction visitInvokeUnary(HInvokeUnary node) {
328 HInstruction folded = 319 HInstruction folded =
329 foldUnary(node.operation(constantSystem), node.operand); 320 foldUnary(node.operation(constantSystem), node.operand);
330 return folded != null ? folded : node; 321 return folded != null ? folded : node;
331 } 322 }
332 323
333 HInstruction foldUnary(UnaryOperation operation, HInstruction operand) { 324 HInstruction foldUnary(UnaryOperation operation, HInstruction operand) {
334 if (operand is HConstant) { 325 if (operand is HConstant) {
335 HConstant receiver = operand; 326 HConstant receiver = operand;
336 ConstantValue folded = operation.fold(receiver.constant); 327 ConstantValue folded = operation.fold(receiver.constant);
337 if (folded != null) return graph.addConstant(folded, compiler); 328 if (folded != null) return graph.addConstant(folded, closedWorld);
338 } 329 }
339 return null; 330 return null;
340 } 331 }
341 332
342 HInstruction tryOptimizeLengthInterceptedGetter(HInvokeDynamic node) { 333 HInstruction tryOptimizeLengthInterceptedGetter(HInvokeDynamic node) {
343 HInstruction actualReceiver = node.inputs[1]; 334 HInstruction actualReceiver = node.inputs[1];
344 if (actualReceiver.isIndexablePrimitive(closedWorld)) { 335 if (actualReceiver.isIndexablePrimitive(closedWorld)) {
345 if (actualReceiver.isConstantString()) { 336 if (actualReceiver.isConstantString()) {
346 HConstant constantInput = actualReceiver; 337 HConstant constantInput = actualReceiver;
347 StringConstantValue constant = constantInput.constant; 338 StringConstantValue constant = constantInput.constant;
348 return graph.addConstantInt(constant.length, compiler); 339 return graph.addConstantInt(constant.length, closedWorld);
349 } else if (actualReceiver.isConstantList()) { 340 } else if (actualReceiver.isConstantList()) {
350 HConstant constantInput = actualReceiver; 341 HConstant constantInput = actualReceiver;
351 ListConstantValue constant = constantInput.constant; 342 ListConstantValue constant = constantInput.constant;
352 return graph.addConstantInt(constant.length, compiler); 343 return graph.addConstantInt(constant.length, closedWorld);
353 } 344 }
354 MemberElement element = helpers.jsIndexableLength; 345 MemberElement element = helpers.jsIndexableLength;
355 bool isFixed = isFixedLength(actualReceiver.instructionType, closedWorld); 346 bool isFixed = isFixedLength(actualReceiver.instructionType, closedWorld);
356 TypeMask actualType = node.instructionType; 347 TypeMask actualType = node.instructionType;
357 TypeMask resultType = closedWorld.commonMasks.positiveIntType; 348 TypeMask resultType = closedWorld.commonMasks.positiveIntType;
358 // If we already have computed a more specific type, keep that type. 349 // If we already have computed a more specific type, keep that type.
359 if (HInstruction.isInstanceOf( 350 if (HInstruction.isInstanceOf(
360 actualType, helpers.jsUInt31Class, closedWorld)) { 351 actualType, helpers.jsUInt31Class, closedWorld)) {
361 resultType = closedWorld.commonMasks.uint31Type; 352 resultType = closedWorld.commonMasks.uint31Type;
362 } else if (HInstruction.isInstanceOf( 353 } else if (HInstruction.isInstanceOf(
363 actualType, helpers.jsUInt32Class, closedWorld)) { 354 actualType, helpers.jsUInt32Class, closedWorld)) {
364 resultType = closedWorld.commonMasks.uint32Type; 355 resultType = closedWorld.commonMasks.uint32Type;
365 } 356 }
366 HFieldGet result = new HFieldGet(element, actualReceiver, resultType, 357 HFieldGet result = new HFieldGet(element, actualReceiver, resultType,
367 isAssignable: !isFixed); 358 isAssignable: !isFixed);
368 return result; 359 return result;
369 } else if (actualReceiver.isConstantMap()) { 360 } else if (actualReceiver.isConstantMap()) {
370 HConstant constantInput = actualReceiver; 361 HConstant constantInput = actualReceiver;
371 MapConstantValue constant = constantInput.constant; 362 MapConstantValue constant = constantInput.constant;
372 return graph.addConstantInt(constant.length, compiler); 363 return graph.addConstantInt(constant.length, closedWorld);
373 } 364 }
374 return null; 365 return null;
375 } 366 }
376 367
377 HInstruction handleInterceptedCall(HInvokeDynamic node) { 368 HInstruction handleInterceptedCall(HInvokeDynamic node) {
378 // Try constant folding the instruction. 369 // Try constant folding the instruction.
379 Operation operation = node.specializer.operation(constantSystem); 370 Operation operation = node.specializer.operation(constantSystem);
380 if (operation != null) { 371 if (operation != null) {
381 HInstruction instruction = node.inputs.length == 2 372 HInstruction instruction = node.inputs.length == 2
382 ? foldUnary(operation, node.inputs[1]) 373 ? foldUnary(operation, node.inputs[1])
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 } 578 }
588 return node; 579 return node;
589 } 580 }
590 581
591 HInstruction foldBinary( 582 HInstruction foldBinary(
592 BinaryOperation operation, HInstruction left, HInstruction right) { 583 BinaryOperation operation, HInstruction left, HInstruction right) {
593 if (left is HConstant && right is HConstant) { 584 if (left is HConstant && right is HConstant) {
594 HConstant op1 = left; 585 HConstant op1 = left;
595 HConstant op2 = right; 586 HConstant op2 = right;
596 ConstantValue folded = operation.fold(op1.constant, op2.constant); 587 ConstantValue folded = operation.fold(op1.constant, op2.constant);
597 if (folded != null) return graph.addConstant(folded, compiler); 588 if (folded != null) return graph.addConstant(folded, closedWorld);
598 } 589 }
599 return null; 590 return null;
600 } 591 }
601 592
602 HInstruction visitAdd(HAdd node) { 593 HInstruction visitAdd(HAdd node) {
603 HInstruction left = node.left; 594 HInstruction left = node.left;
604 HInstruction right = node.right; 595 HInstruction right = node.right;
605 // We can only perform this rewriting on Integer, as it is not 596 // We can only perform this rewriting on Integer, as it is not
606 // valid for -0.0. 597 // valid for -0.0.
607 if (left.isInteger(closedWorld) && right.isInteger(closedWorld)) { 598 if (left.isInteger(closedWorld) && right.isInteger(closedWorld)) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 // in the remaining optimizations. 639 // in the remaining optimizations.
649 return super.visitRelational(node); 640 return super.visitRelational(node);
650 } 641 }
651 642
652 HInstruction handleIdentityCheck(HRelational node) { 643 HInstruction handleIdentityCheck(HRelational node) {
653 HInstruction left = node.left; 644 HInstruction left = node.left;
654 HInstruction right = node.right; 645 HInstruction right = node.right;
655 TypeMask leftType = left.instructionType; 646 TypeMask leftType = left.instructionType;
656 TypeMask rightType = right.instructionType; 647 TypeMask rightType = right.instructionType;
657 648
658 HInstruction makeTrue() => graph.addConstantBool(true, compiler); 649 HInstruction makeTrue() => graph.addConstantBool(true, closedWorld);
659 HInstruction makeFalse() => graph.addConstantBool(false, compiler); 650 HInstruction makeFalse() => graph.addConstantBool(false, closedWorld);
660 651
661 // Intersection of int and double return conflicting, so 652 // Intersection of int and double return conflicting, so
662 // we don't optimize on numbers to preserve the runtime semantics. 653 // we don't optimize on numbers to preserve the runtime semantics.
663 if (!(left.isNumberOrNull(closedWorld) && 654 if (!(left.isNumberOrNull(closedWorld) &&
664 right.isNumberOrNull(closedWorld))) { 655 right.isNumberOrNull(closedWorld))) {
665 if (leftType.isDisjoint(rightType, closedWorld)) { 656 if (leftType.isDisjoint(rightType, closedWorld)) {
666 return makeFalse(); 657 return makeFalse();
667 } 658 }
668 } 659 }
669 660
(...skipping 30 matching lines...) Expand all
700 } 691 }
701 692
702 HInstruction visitIdentity(HIdentity node) { 693 HInstruction visitIdentity(HIdentity node) {
703 HInstruction newInstruction = handleIdentityCheck(node); 694 HInstruction newInstruction = handleIdentityCheck(node);
704 return newInstruction == null ? super.visitIdentity(node) : newInstruction; 695 return newInstruction == null ? super.visitIdentity(node) : newInstruction;
705 } 696 }
706 697
707 void simplifyCondition( 698 void simplifyCondition(
708 HBasicBlock block, HInstruction condition, bool value) { 699 HBasicBlock block, HInstruction condition, bool value) {
709 condition.dominatedUsers(block.first).forEach((user) { 700 condition.dominatedUsers(block.first).forEach((user) {
710 HInstruction newCondition = graph.addConstantBool(value, compiler); 701 HInstruction newCondition = graph.addConstantBool(value, closedWorld);
711 user.changeUse(condition, newCondition); 702 user.changeUse(condition, newCondition);
712 }); 703 });
713 } 704 }
714 705
715 HInstruction visitIf(HIf node) { 706 HInstruction visitIf(HIf node) {
716 HInstruction condition = node.condition; 707 HInstruction condition = node.condition;
717 if (condition.isConstant()) return node; 708 if (condition.isConstant()) return node;
718 bool isNegated = condition is HNot; 709 bool isNegated = condition is HNot;
719 710
720 if (isNegated) { 711 if (isNegated) {
(...skipping 22 matching lines...) Expand all
743 734
744 if (!node.isRawCheck) { 735 if (!node.isRawCheck) {
745 return node; 736 return node;
746 } else if (type.isTypedef) { 737 } else if (type.isTypedef) {
747 return node; 738 return node;
748 } else if (element == commonElements.functionClass) { 739 } else if (element == commonElements.functionClass) {
749 return node; 740 return node;
750 } 741 }
751 742
752 if (type.isObject || type.treatAsDynamic) { 743 if (type.isObject || type.treatAsDynamic) {
753 return graph.addConstantBool(true, compiler); 744 return graph.addConstantBool(true, closedWorld);
754 } 745 }
755 746
756 HInstruction expression = node.expression; 747 HInstruction expression = node.expression;
757 if (expression.isInteger(closedWorld)) { 748 if (expression.isInteger(closedWorld)) {
758 if (element == commonElements.intClass || 749 if (element == commonElements.intClass ||
759 element == commonElements.numClass || 750 element == commonElements.numClass ||
760 Elements.isNumberOrStringSupertype(element, commonElements)) { 751 Elements.isNumberOrStringSupertype(element, commonElements)) {
761 return graph.addConstantBool(true, compiler); 752 return graph.addConstantBool(true, closedWorld);
762 } else if (element == commonElements.doubleClass) { 753 } else if (element == commonElements.doubleClass) {
763 // We let the JS semantics decide for that check. Currently 754 // We let the JS semantics decide for that check. Currently
764 // the code we emit will always return true. 755 // the code we emit will always return true.
765 return node; 756 return node;
766 } else { 757 } else {
767 return graph.addConstantBool(false, compiler); 758 return graph.addConstantBool(false, closedWorld);
768 } 759 }
769 } else if (expression.isDouble(closedWorld)) { 760 } else if (expression.isDouble(closedWorld)) {
770 if (element == commonElements.doubleClass || 761 if (element == commonElements.doubleClass ||
771 element == commonElements.numClass || 762 element == commonElements.numClass ||
772 Elements.isNumberOrStringSupertype(element, commonElements)) { 763 Elements.isNumberOrStringSupertype(element, commonElements)) {
773 return graph.addConstantBool(true, compiler); 764 return graph.addConstantBool(true, closedWorld);
774 } else if (element == commonElements.intClass) { 765 } else if (element == commonElements.intClass) {
775 // We let the JS semantics decide for that check. Currently 766 // We let the JS semantics decide for that check. Currently
776 // the code we emit will return true for a double that can be 767 // the code we emit will return true for a double that can be
777 // represented as a 31-bit integer and for -0.0. 768 // represented as a 31-bit integer and for -0.0.
778 return node; 769 return node;
779 } else { 770 } else {
780 return graph.addConstantBool(false, compiler); 771 return graph.addConstantBool(false, closedWorld);
781 } 772 }
782 } else if (expression.isNumber(closedWorld)) { 773 } else if (expression.isNumber(closedWorld)) {
783 if (element == commonElements.numClass) { 774 if (element == commonElements.numClass) {
784 return graph.addConstantBool(true, compiler); 775 return graph.addConstantBool(true, closedWorld);
785 } else { 776 } else {
786 // We cannot just return false, because the expression may be of 777 // We cannot just return false, because the expression may be of
787 // type int or double. 778 // type int or double.
788 } 779 }
789 } else if (expression.canBePrimitiveNumber(closedWorld) && 780 } else if (expression.canBePrimitiveNumber(closedWorld) &&
790 element == commonElements.intClass) { 781 element == commonElements.intClass) {
791 // We let the JS semantics decide for that check. 782 // We let the JS semantics decide for that check.
792 return node; 783 return node;
793 // We need the [:hasTypeArguments:] check because we don't have 784 // We need the [:hasTypeArguments:] check because we don't have
794 // the notion of generics in the backend. For example, [:this:] in 785 // the notion of generics in the backend. For example, [:this:] in
795 // a class [:A<T>:], is currently always considered to have the 786 // a class [:A<T>:], is currently always considered to have the
796 // raw type. 787 // raw type.
797 } else if (!RuntimeTypes.hasTypeArguments(type)) { 788 } else if (!RuntimeTypes.hasTypeArguments(type)) {
798 TypeMask expressionMask = expression.instructionType; 789 TypeMask expressionMask = expression.instructionType;
799 assert(TypeMask.assertIsNormalized(expressionMask, closedWorld)); 790 assert(TypeMask.assertIsNormalized(expressionMask, closedWorld));
800 TypeMask typeMask = (element == commonElements.nullClass) 791 TypeMask typeMask = (element == commonElements.nullClass)
801 ? new TypeMask.subtype(element, closedWorld) 792 ? new TypeMask.subtype(element, closedWorld)
802 : new TypeMask.nonNullSubtype(element, closedWorld); 793 : new TypeMask.nonNullSubtype(element, closedWorld);
803 if (expressionMask.union(typeMask, closedWorld) == typeMask) { 794 if (expressionMask.union(typeMask, closedWorld) == typeMask) {
804 return graph.addConstantBool(true, compiler); 795 return graph.addConstantBool(true, closedWorld);
805 } else if (expressionMask.isDisjoint(typeMask, closedWorld)) { 796 } else if (expressionMask.isDisjoint(typeMask, closedWorld)) {
806 return graph.addConstantBool(false, compiler); 797 return graph.addConstantBool(false, closedWorld);
807 } 798 }
808 } 799 }
809 return node; 800 return node;
810 } 801 }
811 802
812 HInstruction visitTypeConversion(HTypeConversion node) { 803 HInstruction visitTypeConversion(HTypeConversion node) {
813 DartType type = node.typeExpression; 804 DartType type = node.typeExpression;
814 if (type != null) { 805 if (type != null) {
815 if (type.isMalformed) { 806 if (type.isMalformed) {
816 // Malformed types are treated as dynamic statically, but should 807 // Malformed types are treated as dynamic statically, but should
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 if (node.element == helpers.jsIndexableLength) { 858 if (node.element == helpers.jsIndexableLength) {
868 if (graph.allocatedFixedLists.contains(receiver)) { 859 if (graph.allocatedFixedLists.contains(receiver)) {
869 // TODO(ngeoffray): checking if the second input is an integer 860 // TODO(ngeoffray): checking if the second input is an integer
870 // should not be necessary but it currently makes it easier for 861 // should not be necessary but it currently makes it easier for
871 // other optimizations to reason about a fixed length constructor 862 // other optimizations to reason about a fixed length constructor
872 // that we know takes an int. 863 // that we know takes an int.
873 if (receiver.inputs[0].isInteger(closedWorld)) { 864 if (receiver.inputs[0].isInteger(closedWorld)) {
874 return receiver.inputs[0]; 865 return receiver.inputs[0];
875 } 866 }
876 } else if (receiver.isConstantList() || receiver.isConstantString()) { 867 } else if (receiver.isConstantList() || receiver.isConstantString()) {
877 return graph.addConstantInt(receiver.constant.length, compiler); 868 return graph.addConstantInt(receiver.constant.length, closedWorld);
878 } else { 869 } else {
879 var type = receiver.instructionType; 870 var type = receiver.instructionType;
880 if (type.isContainer && type.length != null) { 871 if (type.isContainer && type.length != null) {
881 HInstruction constant = graph.addConstantInt(type.length, compiler); 872 HInstruction constant =
873 graph.addConstantInt(type.length, closedWorld);
882 if (type.isNullable) { 874 if (type.isNullable) {
883 // If the container can be null, we update all uses of the 875 // If the container can be null, we update all uses of the
884 // length access to use the constant instead, but keep the 876 // length access to use the constant instead, but keep the
885 // length access in the graph, to ensure we still have a 877 // length access in the graph, to ensure we still have a
886 // null check. 878 // null check.
887 node.block.rewrite(node, constant); 879 node.block.rewrite(node, constant);
888 return node; 880 return node;
889 } else { 881 } else {
890 return constant; 882 return constant;
891 } 883 }
892 } 884 }
893 } 885 }
894 } 886 }
895 887
896 // HFieldGet of a constructed constant can be replaced with the constant's 888 // HFieldGet of a constructed constant can be replaced with the constant's
897 // field. 889 // field.
898 if (receiver is HConstant) { 890 if (receiver is HConstant) {
899 ConstantValue constant = receiver.constant; 891 ConstantValue constant = receiver.constant;
900 if (constant.isConstructedObject) { 892 if (constant.isConstructedObject) {
901 ConstructedConstantValue constructedConstant = constant; 893 ConstructedConstantValue constructedConstant = constant;
902 Map<Element, ConstantValue> fields = constructedConstant.fields; 894 Map<Element, ConstantValue> fields = constructedConstant.fields;
903 ConstantValue value = fields[node.element]; 895 ConstantValue value = fields[node.element];
904 if (value != null) { 896 if (value != null) {
905 return graph.addConstant(value, compiler); 897 return graph.addConstant(value, closedWorld);
906 } 898 }
907 } 899 }
908 } 900 }
909 901
910 return node; 902 return node;
911 } 903 }
912 904
913 HInstruction visitIndex(HIndex node) { 905 HInstruction visitIndex(HIndex node) {
914 if (node.receiver.isConstantList() && node.index.isConstantInteger()) { 906 if (node.receiver.isConstantList() && node.index.isConstantInteger()) {
915 var instruction = node.receiver; 907 var instruction = node.receiver;
916 List<ConstantValue> entries = instruction.constant.entries; 908 List<ConstantValue> entries = instruction.constant.entries;
917 instruction = node.index; 909 instruction = node.index;
918 int index = instruction.constant.primitiveValue; 910 int index = instruction.constant.primitiveValue;
919 if (index >= 0 && index < entries.length) { 911 if (index >= 0 && index < entries.length) {
920 return graph.addConstant(entries[index], compiler); 912 return graph.addConstant(entries[index], closedWorld);
921 } 913 }
922 } 914 }
923 return node; 915 return node;
924 } 916 }
925 917
926 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { 918 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) {
927 propagateConstantValueToUses(node); 919 propagateConstantValueToUses(node);
928 if (node.isInterceptedCall) { 920 if (node.isInterceptedCall) {
929 HInstruction folded = handleInterceptedCall(node); 921 HInstruction folded = handleInterceptedCall(node);
930 if (folded != node) return folded; 922 if (folded != node) return folded;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 } 1057 }
1066 1058
1067 if (leftString.primitiveValue.length + rightString.primitiveValue.length > 1059 if (leftString.primitiveValue.length + rightString.primitiveValue.length >
1068 MAX_SHARED_CONSTANT_FOLDED_STRING_LENGTH) { 1060 MAX_SHARED_CONSTANT_FOLDED_STRING_LENGTH) {
1069 if (node.usedBy.length > 1) return node; 1061 if (node.usedBy.length > 1) return node;
1070 } 1062 }
1071 1063
1072 HInstruction folded = graph.addConstant( 1064 HInstruction folded = graph.addConstant(
1073 constantSystem.createString(new ast.DartString.concat( 1065 constantSystem.createString(new ast.DartString.concat(
1074 leftString.primitiveValue, rightString.primitiveValue)), 1066 leftString.primitiveValue, rightString.primitiveValue)),
1075 compiler); 1067 closedWorld);
1076 if (prefix == null) return folded; 1068 if (prefix == null) return folded;
1077 return new HStringConcat( 1069 return new HStringConcat(
1078 prefix, folded, closedWorld.commonMasks.stringType); 1070 prefix, folded, closedWorld.commonMasks.stringType);
1079 } 1071 }
1080 1072
1081 HInstruction visitStringify(HStringify node) { 1073 HInstruction visitStringify(HStringify node) {
1082 HInstruction input = node.inputs[0]; 1074 HInstruction input = node.inputs[0];
1083 if (input.isString(closedWorld)) return input; 1075 if (input.isString(closedWorld)) return input;
1084 1076
1085 HInstruction tryConstant() { 1077 HInstruction tryConstant() {
1086 if (!input.isConstant()) return null; 1078 if (!input.isConstant()) return null;
1087 HConstant constant = input; 1079 HConstant constant = input;
1088 if (!constant.constant.isPrimitive) return null; 1080 if (!constant.constant.isPrimitive) return null;
1089 if (constant.constant.isInt) { 1081 if (constant.constant.isInt) {
1090 // Only constant-fold int.toString() when Dart and JS results the same. 1082 // Only constant-fold int.toString() when Dart and JS results the same.
1091 // TODO(18103): We should be able to remove this work-around when issue 1083 // TODO(18103): We should be able to remove this work-around when issue
1092 // 18103 is resolved by providing the correct string. 1084 // 18103 is resolved by providing the correct string.
1093 IntConstantValue intConstant = constant.constant; 1085 IntConstantValue intConstant = constant.constant;
1094 // Very conservative range. 1086 // Very conservative range.
1095 if (!intConstant.isUInt32()) return null; 1087 if (!intConstant.isUInt32()) return null;
1096 } 1088 }
1097 PrimitiveConstantValue primitive = constant.constant; 1089 PrimitiveConstantValue primitive = constant.constant;
1098 return graph.addConstant( 1090 return graph.addConstant(
1099 constantSystem.createString(primitive.toDartString()), compiler); 1091 constantSystem.createString(primitive.toDartString()), closedWorld);
1100 } 1092 }
1101 1093
1102 HInstruction tryToString() { 1094 HInstruction tryToString() {
1103 // If the `toString` method is guaranteed to return a string we can call 1095 // If the `toString` method is guaranteed to return a string we can call
1104 // it directly. Keep the stringifier for primitives (since they have fast 1096 // it directly. Keep the stringifier for primitives (since they have fast
1105 // path code in the stringifier) and for classes requiring interceptors 1097 // path code in the stringifier) and for classes requiring interceptors
1106 // (since SsaInstructionSimplifier runs after SsaSimplifyInterceptors). 1098 // (since SsaInstructionSimplifier runs after SsaSimplifyInterceptors).
1107 if (input.canBePrimitive(closedWorld)) return null; 1099 if (input.canBePrimitive(closedWorld)) return null;
1108 if (input.canBeNull()) return null; 1100 if (input.canBeNull()) return null;
1109 Selector selector = Selectors.toString_; 1101 Selector selector = Selectors.toString_;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 object.element, (int index) => typeInfo.inputs[index]); 1274 object.element, (int index) => typeInfo.inputs[index]);
1283 } 1275 }
1284 } else { 1276 } else {
1285 // Non-generic type (which extends or mixes in a generic type, for 1277 // Non-generic type (which extends or mixes in a generic type, for
1286 // example CodeUnits extends UnmodifiableListBase<int>). Also used for 1278 // example CodeUnits extends UnmodifiableListBase<int>). Also used for
1287 // raw-type when the type parameters are elided. 1279 // raw-type when the type parameters are elided.
1288 registerInstantiations(); 1280 registerInstantiations();
1289 return finishSubstituted( 1281 return finishSubstituted(
1290 object.element, 1282 object.element,
1291 // If there are type arguments, all type arguments are 'dynamic'. 1283 // If there are type arguments, all type arguments are 'dynamic'.
1292 (int i) => graph.addConstantNull(compiler)); 1284 (int i) => graph.addConstantNull(closedWorld));
1293 } 1285 }
1294 } 1286 }
1295 1287
1296 // TODO(sra): Factory constructors pass type arguments after the value 1288 // TODO(sra): Factory constructors pass type arguments after the value
1297 // arguments. The [selectTypeArgumentFromObjectCreation] argument of 1289 // arguments. The [selectTypeArgumentFromObjectCreation] argument of
1298 // [finishSubstituted] indexes into these type arguments. 1290 // [finishSubstituted] indexes into these type arguments.
1299 1291
1300 return node; 1292 return node;
1301 } 1293 }
1302 } 1294 }
(...skipping 26 matching lines...) Expand all
1329 HInstruction instruction = block.first; 1321 HInstruction instruction = block.first;
1330 while (instruction != null) { 1322 while (instruction != null) {
1331 HInstruction next = instruction.next; 1323 HInstruction next = instruction.next;
1332 instruction = instruction.accept(this); 1324 instruction = instruction.accept(this);
1333 instruction = next; 1325 instruction = next;
1334 } 1326 }
1335 } 1327 }
1336 1328
1337 HBoundsCheck insertBoundsCheck( 1329 HBoundsCheck insertBoundsCheck(
1338 HInstruction indexNode, HInstruction array, HInstruction indexArgument) { 1330 HInstruction indexNode, HInstruction array, HInstruction indexArgument) {
1339 Compiler compiler = backend.compiler;
1340 HFieldGet length = new HFieldGet(helpers.jsIndexableLength, array, 1331 HFieldGet length = new HFieldGet(helpers.jsIndexableLength, array,
1341 closedWorld.commonMasks.positiveIntType, 1332 closedWorld.commonMasks.positiveIntType,
1342 isAssignable: !isFixedLength(array.instructionType, closedWorld)); 1333 isAssignable: !isFixedLength(array.instructionType, closedWorld));
1343 indexNode.block.addBefore(indexNode, length); 1334 indexNode.block.addBefore(indexNode, length);
1344 1335
1345 TypeMask type = indexArgument.isPositiveInteger(closedWorld) 1336 TypeMask type = indexArgument.isPositiveInteger(closedWorld)
1346 ? indexArgument.instructionType 1337 ? indexArgument.instructionType
1347 : closedWorld.commonMasks.positiveIntType; 1338 : closedWorld.commonMasks.positiveIntType;
1348 HBoundsCheck check = new HBoundsCheck(indexArgument, length, array, type); 1339 HBoundsCheck check = new HBoundsCheck(indexArgument, length, array, type);
1349 indexNode.block.addBefore(indexNode, check); 1340 indexNode.block.addBefore(indexNode, check);
(...skipping 24 matching lines...) Expand all
1374 } 1365 }
1375 1366
1376 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) { 1367 void visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
1377 MemberElement element = node.element; 1368 MemberElement element = node.element;
1378 if (node.isInterceptedCall) return; 1369 if (node.isInterceptedCall) return;
1379 if (element != helpers.jsArrayRemoveLast) return; 1370 if (element != helpers.jsArrayRemoveLast) return;
1380 if (boundsChecked.contains(node)) return; 1371 if (boundsChecked.contains(node)) return;
1381 // `0` is the index we want to check, but we want to report `-1`, as if we 1372 // `0` is the index we want to check, but we want to report `-1`, as if we
1382 // executed `a[a.length-1]` 1373 // executed `a[a.length-1]`
1383 HBoundsCheck check = insertBoundsCheck( 1374 HBoundsCheck check = insertBoundsCheck(
1384 node, node.receiver, graph.addConstantInt(0, backend.compiler)); 1375 node, node.receiver, graph.addConstantInt(0, closedWorld));
1385 HInstruction minusOne = graph.addConstantInt(-1, backend.compiler); 1376 HInstruction minusOne = graph.addConstantInt(-1, closedWorld);
1386 check.inputs.add(minusOne); 1377 check.inputs.add(minusOne);
1387 minusOne.usedBy.add(check); 1378 minusOne.usedBy.add(check);
1388 } 1379 }
1389 } 1380 }
1390 1381
1391 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase { 1382 class SsaDeadCodeEliminator extends HGraphVisitor implements OptimizationPhase {
1392 final String name = "SsaDeadCodeEliminator"; 1383 final String name = "SsaDeadCodeEliminator";
1393 1384
1394 final Compiler compiler;
1395 final ClosedWorld closedWorld; 1385 final ClosedWorld closedWorld;
1396 final SsaOptimizerTask optimizer; 1386 final SsaOptimizerTask optimizer;
1397 SsaLiveBlockAnalyzer analyzer; 1387 SsaLiveBlockAnalyzer analyzer;
1398 Map<HInstruction, bool> trivialDeadStoreReceivers = 1388 Map<HInstruction, bool> trivialDeadStoreReceivers =
1399 new Maplet<HInstruction, bool>(); 1389 new Maplet<HInstruction, bool>();
1400 bool eliminatedSideEffects = false; 1390 bool eliminatedSideEffects = false;
1401 1391
1402 SsaDeadCodeEliminator(this.compiler, this.closedWorld, this.optimizer); 1392 SsaDeadCodeEliminator(this.closedWorld, this.optimizer);
1403 1393
1404 HInstruction zapInstructionCache; 1394 HInstruction zapInstructionCache;
1405 HInstruction get zapInstruction { 1395 HInstruction get zapInstruction {
1406 if (zapInstructionCache == null) { 1396 if (zapInstructionCache == null) {
1407 // A constant with no type does not pollute types at phi nodes. 1397 // A constant with no type does not pollute types at phi nodes.
1408 ConstantValue constant = new SyntheticConstantValue( 1398 ConstantValue constant = new SyntheticConstantValue(
1409 SyntheticConstantKind.EMPTY_VALUE, const TypeMask.nonNullEmpty()); 1399 SyntheticConstantKind.EMPTY_VALUE, const TypeMask.nonNullEmpty());
1410 zapInstructionCache = analyzer.graph.addConstant(constant, compiler); 1400 zapInstructionCache = analyzer.graph.addConstant(constant, closedWorld);
1411 } 1401 }
1412 return zapInstructionCache; 1402 return zapInstructionCache;
1413 } 1403 }
1414 1404
1415 /// Returns true of [foreign] will throw an noSuchMethod error if 1405 /// Returns true of [foreign] will throw an noSuchMethod error if
1416 /// receiver is `null` before having any other side-effects. 1406 /// receiver is `null` before having any other side-effects.
1417 bool templateThrowsNSMonNull(HForeignCode foreign, HInstruction receiver) { 1407 bool templateThrowsNSMonNull(HForeignCode foreign, HInstruction receiver) {
1418 if (foreign.inputs.length < 1) return false; 1408 if (foreign.inputs.length < 1) return false;
1419 if (foreign.inputs.first != receiver) return false; 1409 if (foreign.inputs.first != receiver) return false;
1420 if (foreign.throwBehavior.isNullNSMGuard) return true; 1410 if (foreign.throwBehavior.isNullNSMGuard) return true;
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 } 1785 }
1796 1786
1797 class GvnWorkItem { 1787 class GvnWorkItem {
1798 final HBasicBlock block; 1788 final HBasicBlock block;
1799 final ValueSet valueSet; 1789 final ValueSet valueSet;
1800 GvnWorkItem(this.block, this.valueSet); 1790 GvnWorkItem(this.block, this.valueSet);
1801 } 1791 }
1802 1792
1803 class SsaGlobalValueNumberer implements OptimizationPhase { 1793 class SsaGlobalValueNumberer implements OptimizationPhase {
1804 final String name = "SsaGlobalValueNumberer"; 1794 final String name = "SsaGlobalValueNumberer";
1805 final Compiler compiler;
1806 final Set<int> visited; 1795 final Set<int> visited;
1807 1796
1808 List<int> blockChangesFlags; 1797 List<int> blockChangesFlags;
1809 List<int> loopChangesFlags; 1798 List<int> loopChangesFlags;
1810 1799
1811 SsaGlobalValueNumberer(this.compiler) : visited = new Set<int>(); 1800 SsaGlobalValueNumberer() : visited = new Set<int>();
1812 1801
1813 void visitGraph(HGraph graph) { 1802 void visitGraph(HGraph graph) {
1814 computeChangesFlags(graph); 1803 computeChangesFlags(graph);
1815 moveLoopInvariantCode(graph); 1804 moveLoopInvariantCode(graph);
1816 List<GvnWorkItem> workQueue = <GvnWorkItem>[ 1805 List<GvnWorkItem> workQueue = <GvnWorkItem>[
1817 new GvnWorkItem(graph.entry, new ValueSet()) 1806 new GvnWorkItem(graph.entry, new ValueSet())
1818 ]; 1807 ];
1819 do { 1808 do {
1820 GvnWorkItem item = workQueue.removeLast(); 1809 GvnWorkItem item = workQueue.removeLast();
1821 visitBasicBlock(item.block, item.valueSet, workQueue); 1810 visitBasicBlock(item.block, item.valueSet, workQueue);
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
2753 2742
2754 keyedValues.forEach((receiver, values) { 2743 keyedValues.forEach((receiver, values) {
2755 result.keyedValues[receiver] = 2744 result.keyedValues[receiver] =
2756 new Map<HInstruction, HInstruction>.from(values); 2745 new Map<HInstruction, HInstruction>.from(values);
2757 }); 2746 });
2758 2747
2759 result.nonEscapingReceivers.addAll(nonEscapingReceivers); 2748 result.nonEscapingReceivers.addAll(nonEscapingReceivers);
2760 return result; 2749 return result;
2761 } 2750 }
2762 } 2751 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698