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

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

Issue 1087973002: Rewrite for-in loop as indexing loop for JavaScript indexable arrays (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: retry Created 5 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « pkg/compiler/lib/src/ssa/nodes.dart ('k') | sdk/lib/_internal/compiler/js_lib/js_helper.dart » ('j') | 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 part of ssa; 5 part of ssa;
6 6
7 abstract class OptimizationPhase { 7 abstract class OptimizationPhase {
8 String get name; 8 String get name;
9 void visitGraph(HGraph graph); 9 void visitGraph(HGraph graph);
10 } 10 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 new SsaTypePropagator(compiler), 48 new SsaTypePropagator(compiler),
49 // Run a dead code eliminator before LICM because dead 49 // Run a dead code eliminator before LICM because dead
50 // interceptors are often in the way of LICM'able instructions. 50 // interceptors are often in the way of LICM'able instructions.
51 new SsaDeadCodeEliminator(compiler, this), 51 new SsaDeadCodeEliminator(compiler, this),
52 new SsaGlobalValueNumberer(compiler), 52 new SsaGlobalValueNumberer(compiler),
53 // After GVN, some instructions might need their type to be 53 // After GVN, some instructions might need their type to be
54 // updated because they now have different inputs. 54 // updated because they now have different inputs.
55 new SsaTypePropagator(compiler), 55 new SsaTypePropagator(compiler),
56 new SsaCodeMotion(), 56 new SsaCodeMotion(),
57 new SsaLoadElimination(compiler), 57 new SsaLoadElimination(compiler),
58 new SsaRedundantPhiEliminator(),
58 new SsaDeadPhiEliminator(), 59 new SsaDeadPhiEliminator(),
59 new SsaTypePropagator(compiler), 60 new SsaTypePropagator(compiler),
60 new SsaValueRangeAnalyzer(compiler, constantSystem, this, work), 61 new SsaValueRangeAnalyzer(compiler, constantSystem, this, work),
61 // Previous optimizations may have generated new 62 // Previous optimizations may have generated new
62 // opportunities for instruction simplification. 63 // opportunities for instruction simplification.
63 new SsaInstructionSimplifier(constantSystem, backend, this, work), 64 new SsaInstructionSimplifier(constantSystem, backend, this, work),
64 new SsaCheckInserter( 65 new SsaCheckInserter(
65 trustPrimitives, backend, work, context.boundsChecked), 66 trustPrimitives, backend, work, context.boundsChecked),
66 ]; 67 ];
67 phases.forEach(runPhase); 68 phases.forEach(runPhase);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 191
191 HInstruction visitInstruction(HInstruction node) { 192 HInstruction visitInstruction(HInstruction node) {
192 return node; 193 return node;
193 } 194 }
194 195
195 HInstruction visitBoolify(HBoolify node) { 196 HInstruction visitBoolify(HBoolify node) {
196 List<HInstruction> inputs = node.inputs; 197 List<HInstruction> inputs = node.inputs;
197 assert(inputs.length == 1); 198 assert(inputs.length == 1);
198 HInstruction input = inputs[0]; 199 HInstruction input = inputs[0];
199 if (input.isBoolean(compiler)) return input; 200 if (input.isBoolean(compiler)) return input;
201
202 // If the code is unreachable, remove the HBoolify. This can happen when
203 // there is a throw expression in a short-circuit conditional. Removing the
204 // unreachable HBoolify makes it easier to reconstruct the short-circuit
205 // operation.
206 if (input.instructionType.isEmpty && !input.instructionType.isNullable)
207 return input;
208
200 // All values that cannot be 'true' are boolified to false. 209 // All values that cannot be 'true' are boolified to false.
201 TypeMask mask = input.instructionType; 210 TypeMask mask = input.instructionType;
202 if (!mask.contains(backend.jsBoolClass, compiler.world)) { 211 if (!mask.contains(backend.jsBoolClass, compiler.world)) {
203 return graph.addConstantBool(false, compiler); 212 return graph.addConstantBool(false, compiler);
204 } 213 }
205 return node; 214 return node;
206 } 215 }
207 216
208 HInstruction visitNot(HNot node) { 217 HInstruction visitNot(HNot node) {
209 List<HInstruction> inputs = node.inputs; 218 List<HInstruction> inputs = node.inputs;
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 // in the remaining optimizations. 515 // in the remaining optimizations.
507 return super.visitRelational(node); 516 return super.visitRelational(node);
508 } 517 }
509 518
510 HInstruction handleIdentityCheck(HRelational node) { 519 HInstruction handleIdentityCheck(HRelational node) {
511 HInstruction left = node.left; 520 HInstruction left = node.left;
512 HInstruction right = node.right; 521 HInstruction right = node.right;
513 TypeMask leftType = left.instructionType; 522 TypeMask leftType = left.instructionType;
514 TypeMask rightType = right.instructionType; 523 TypeMask rightType = right.instructionType;
515 524
525 HInstruction makeTrue() => graph.addConstantBool(true, compiler);
526 HInstruction makeFalse() => graph.addConstantBool(false, compiler);
527
516 // Intersection of int and double return conflicting, so 528 // Intersection of int and double return conflicting, so
517 // we don't optimize on numbers to preserve the runtime semantics. 529 // we don't optimize on numbers to preserve the runtime semantics.
518 if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler))) { 530 if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler))) {
519 TypeMask intersection = leftType.intersection(rightType, compiler.world); 531 TypeMask intersection = leftType.intersection(rightType, compiler.world);
520 if (intersection.isEmpty && !intersection.isNullable) { 532 if (intersection.isEmpty && !intersection.isNullable) {
521 return graph.addConstantBool(false, compiler); 533 return makeFalse();
522 } 534 }
523 } 535 }
524 536
525 if (left.isNull() && right.isNull()) { 537 if (left.isNull() && right.isNull()) {
526 return graph.addConstantBool(true, compiler); 538 return makeTrue();
539 }
540
541 HInstruction compareConstant(HConstant constant, HInstruction input) {
542 if (constant.constant.isTrue) {
543 return input;
544 } else {
545 return new HNot(input, backend.boolType);
546 }
527 } 547 }
528 548
529 if (left.isConstantBoolean() && right.isBoolean(compiler)) { 549 if (left.isConstantBoolean() && right.isBoolean(compiler)) {
530 HConstant constant = left; 550 return compareConstant(left, right);
531 if (constant.constant.isTrue) {
532 return right;
533 } else {
534 return new HNot(right, backend.boolType);
535 }
536 } 551 }
537 552
538 if (right.isConstantBoolean() && left.isBoolean(compiler)) { 553 if (right.isConstantBoolean() && left.isBoolean(compiler)) {
539 HConstant constant = right; 554 return compareConstant(right, left);
540 if (constant.constant.isTrue) { 555 }
541 return left; 556
542 } else { 557
543 return new HNot(left, backend.boolType); 558 if (identical(left.nonCheck(), right.nonCheck())) {
544 } 559 // Avoid constant-folding `identical(x, x)` when `x` might be double. The
560 // dart2js runtime has not always been consistent with the Dart
561 // specification (section 16.0.1), which makes distinctions on NaNs and
562 // -0.0 that are hard to implement efficiently.
563 if (left.isIntegerOrNull(compiler)) return makeTrue();
564 if (!left.canBePrimitiveNumber(compiler)) return makeTrue();
545 } 565 }
546 566
547 return null; 567 return null;
548 } 568 }
549 569
550 HInstruction visitIdentity(HIdentity node) { 570 HInstruction visitIdentity(HIdentity node) {
551 HInstruction newInstruction = handleIdentityCheck(node); 571 HInstruction newInstruction = handleIdentityCheck(node);
552 return newInstruction == null ? super.visitIdentity(node) : newInstruction; 572 return newInstruction == null ? super.visitIdentity(node) : newInstruction;
553 } 573 }
554 574
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 type, 835 type,
816 HTypeConversion.CHECKED_MODE_CHECK); 836 HTypeConversion.CHECKED_MODE_CHECK);
817 if (other != value) { 837 if (other != value) {
818 node.block.addBefore(node, other); 838 node.block.addBefore(node, other);
819 value = other; 839 value = other;
820 } 840 }
821 } 841 }
822 return new HFieldSet(field, receiver, value); 842 return new HFieldSet(field, receiver, value);
823 } 843 }
824 844
845 HInstruction visitInvokeStatic(HInvokeStatic node) {
846 if (node.element == backend.getCheckConcurrentModificationError()) {
847 if (node.inputs.length == 2) {
848 HInstruction firstArgument = node.inputs[0];
849 if (firstArgument is HConstant) {
850 HConstant constant = firstArgument;
851 if (constant.constant.isTrue) return constant;
852 }
853 }
854 }
855 return node;
856 }
857
825 HInstruction visitStringConcat(HStringConcat node) { 858 HInstruction visitStringConcat(HStringConcat node) {
826 // Simplify string concat: 859 // Simplify string concat:
827 // 860 //
828 // "" + R -> R 861 // "" + R -> R
829 // L + "" -> L 862 // L + "" -> L
830 // "L" + "R" -> "LR" 863 // "L" + "R" -> "LR"
831 // (prefix + "L") + "R" -> prefix + "LR" 864 // (prefix + "L") + "R" -> prefix + "LR"
832 // 865 //
833 StringConstantValue getString(HInstruction instruction) { 866 StringConstantValue getString(HInstruction instruction) {
834 if (!instruction.isConstantString()) return null; 867 if (!instruction.isConstantString()) return null;
(...skipping 1411 matching lines...) Expand 10 before | Expand all | Expand 10 after
2246 2279
2247 keyedValues.forEach((receiver, values) { 2280 keyedValues.forEach((receiver, values) {
2248 result.keyedValues[receiver] = 2281 result.keyedValues[receiver] =
2249 new Map<HInstruction, HInstruction>.from(values); 2282 new Map<HInstruction, HInstruction>.from(values);
2250 }); 2283 });
2251 2284
2252 result.nonEscapingReceivers.addAll(nonEscapingReceivers); 2285 result.nonEscapingReceivers.addAll(nonEscapingReceivers);
2253 return result; 2286 return result;
2254 } 2287 }
2255 } 2288 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/nodes.dart ('k') | sdk/lib/_internal/compiler/js_lib/js_helper.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698