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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/nodes.dart

Issue 14416014: After a dynamic call, refine the receiver type by looking at the potential targets of that call. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/optimize.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 HVisitor<R> { 7 abstract class HVisitor<R> {
8 R visitAdd(HAdd node); 8 R visitAdd(HAdd node);
9 R visitBailoutTarget(HBailoutTarget node); 9 R visitBailoutTarget(HBailoutTarget node);
10 R visitBitAnd(HBitAnd node); 10 R visitBitAnd(HBitAnd node);
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 from.usedBy.clear(); 610 from.usedBy.clear();
611 } 611 }
612 612
613 /** 613 /**
614 * Rewrites all uses of the [from] instruction to using either the 614 * Rewrites all uses of the [from] instruction to using either the
615 * [to] instruction, or a [HCheck] instruction that has better type 615 * [to] instruction, or a [HCheck] instruction that has better type
616 * information on [to], and that dominates the user. 616 * information on [to], and that dominates the user.
617 */ 617 */
618 void rewriteWithBetterUser(HInstruction from, HInstruction to) { 618 void rewriteWithBetterUser(HInstruction from, HInstruction to) {
619 Link<HCheck> better = const Link<HCheck>(); 619 Link<HCheck> better = const Link<HCheck>();
620 for (HInstruction user in to.usedBy) { 620 for (var user in to.usedBy) {
621 if (user is HCheck && identical((user as HCheck).checkedInput, to)) { 621 if (user != from && user is HCheck && user.checkedInput == to) {
622 better = better.prepend(user); 622 better = better.prepend(user);
623 } 623 }
624 } 624 }
625 625
626 if (better.isEmpty) return rewrite(from, to); 626 if (better.isEmpty) return rewrite(from, to);
627 627
628 L1: for (HInstruction user in from.usedBy) { 628 L1: for (HInstruction user in from.usedBy) {
629 for (HCheck check in better) { 629 for (HCheck check in better) {
630 if (check.dominates(user)) { 630 if (check.dominates(user)) {
631 user.rewriteInput(from, check); 631 user.rewriteInput(from, check);
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 923
924 StringBuffer buffer = new StringBuffer(); 924 StringBuffer buffer = new StringBuffer();
925 buffer.write('('); 925 buffer.write('(');
926 addAsCommaSeparated(buffer, inputs); 926 addAsCommaSeparated(buffer, inputs);
927 buffer.write(') - used at ['); 927 buffer.write(') - used at [');
928 addAsCommaSeparated(buffer, usedBy); 928 addAsCommaSeparated(buffer, usedBy);
929 buffer.write(']'); 929 buffer.write(']');
930 return buffer.toString(); 930 return buffer.toString();
931 } 931 }
932 932
933 nonCheck(instruction) {
934 while (instruction is HCheck) instruction = instruction.checkedInput;
935 return instruction;
936 }
937
933 bool gvnEquals(HInstruction other) { 938 bool gvnEquals(HInstruction other) {
934 assert(useGvn() && other.useGvn()); 939 assert(useGvn() && other.useGvn());
935 // Check that the type and the flags match. 940 // Check that the type and the flags match.
936 bool hasSameType = typeEquals(other); 941 bool hasSameType = typeEquals(other);
937 assert(hasSameType == (typeCode() == other.typeCode())); 942 assert(hasSameType == (typeCode() == other.typeCode()));
938 if (!hasSameType) return false; 943 if (!hasSameType) return false;
939 if (flags != other.flags) return false; 944 if (flags != other.flags) return false;
940 // Check that the inputs match. 945 // Check that the inputs match.
941 final int inputsLength = inputs.length; 946 final int inputsLength = inputs.length;
942 final List<HInstruction> otherInputs = other.inputs; 947 final List<HInstruction> otherInputs = other.inputs;
943 if (inputsLength != otherInputs.length) return false; 948 if (inputsLength != otherInputs.length) return false;
944 for (int i = 0; i < inputsLength; i++) { 949 for (int i = 0; i < inputsLength; i++) {
945 if (!identical(inputs[i], otherInputs[i])) return false; 950 if (nonCheck(inputs[i]) != nonCheck(otherInputs[i])) {
951 return false;
952 }
946 } 953 }
947 // Check that the data in the instruction matches. 954 // Check that the data in the instruction matches.
948 return dataEquals(other); 955 return dataEquals(other);
949 } 956 }
950 957
951 int gvnHashCode() { 958 int gvnHashCode() {
952 int result = typeCode(); 959 int result = typeCode();
953 int length = inputs.length; 960 int length = inputs.length;
954 for (int i = 0; i < length; i++) { 961 for (int i = 0; i < length; i++) {
955 result = (result * 19) + (inputs[i].id) + (result >> 7); 962 result = (result * 19) + (nonCheck(inputs[i]).id) + (result >> 7);
956 } 963 }
957 return result; 964 return result;
958 } 965 }
959 966
960 // These methods should be overwritten by instructions that 967 // These methods should be overwritten by instructions that
961 // participate in global value numbering. 968 // participate in global value numbering.
962 int typeCode() => HInstruction.UNDEFINED_TYPECODE; 969 int typeCode() => HInstruction.UNDEFINED_TYPECODE;
963 bool typeEquals(HInstruction other) => false; 970 bool typeEquals(HInstruction other) => false;
964 bool dataEquals(HInstruction other) => false; 971 bool dataEquals(HInstruction other) => false;
965 972
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 if (isSideEffectFree) { 1398 if (isSideEffectFree) {
1392 setUseGvn(); 1399 setUseGvn();
1393 setDependsOnInstancePropertyStore(); 1400 setDependsOnInstancePropertyStore();
1394 } else { 1401 } else {
1395 setDependsOnSomething(); 1402 setDependsOnSomething();
1396 setAllSideEffects(); 1403 setAllSideEffects();
1397 } 1404 }
1398 } 1405 }
1399 toString() => 'invoke dynamic getter: $selector'; 1406 toString() => 'invoke dynamic getter: $selector';
1400 accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this); 1407 accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this);
1408
1409 int typeCode() => HInstruction.FIELD_GET_TYPECODE;
1410 bool typeEquals(other) => other is HFieldGet || other is HInvokeDynamicGetter;
1411 bool dataEquals(other) {
1412 return other is HFieldGet
1413 ? other.element.name == selector.name
1414 : super.dataEquals(other);
1415 }
1401 } 1416 }
1402 1417
1403 class HInvokeDynamicSetter extends HInvokeDynamicField { 1418 class HInvokeDynamicSetter extends HInvokeDynamicField {
1404 HInvokeDynamicSetter(selector, element, inputs, isSideEffectFree) 1419 HInvokeDynamicSetter(selector, element, inputs, isSideEffectFree)
1405 : super(selector, element, inputs, isSideEffectFree) { 1420 : super(selector, element, inputs, isSideEffectFree) {
1406 clearAllSideEffects(); 1421 clearAllSideEffects();
1407 if (isSideEffectFree) { 1422 if (isSideEffectFree) {
1408 setChangesInstanceProperty(); 1423 setChangesInstanceProperty();
1409 } else { 1424 } else {
1410 setAllSideEffects(); 1425 setAllSideEffects();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 bool interceptor = 1493 bool interceptor =
1479 backend.isInterceptorClass(sourceElement.getEnclosingClass()); 1494 backend.isInterceptorClass(sourceElement.getEnclosingClass());
1480 return interceptor && sourceElement is ThisElement; 1495 return interceptor && sourceElement is ThisElement;
1481 } 1496 }
1482 1497
1483 bool canThrow() => receiver.canBeNull(); 1498 bool canThrow() => receiver.canBeNull();
1484 1499
1485 accept(HVisitor visitor) => visitor.visitFieldGet(this); 1500 accept(HVisitor visitor) => visitor.visitFieldGet(this);
1486 1501
1487 int typeCode() => HInstruction.FIELD_GET_TYPECODE; 1502 int typeCode() => HInstruction.FIELD_GET_TYPECODE;
1488 bool typeEquals(other) => other is HFieldGet; 1503 bool typeEquals(other) => other is HFieldGet || other is HInvokeDynamicGetter;
1489 bool dataEquals(HFieldGet other) => element == other.element; 1504 bool dataEquals(other) {
1505 return other is HInvokeDynamicGetter
1506 ? element.name == other.selector.name
1507 : element == other.element;
1508 }
1490 String toString() => "FieldGet $element"; 1509 String toString() => "FieldGet $element";
1491 } 1510 }
1492 1511
1493 class HFieldSet extends HFieldAccess { 1512 class HFieldSet extends HFieldAccess {
1494 HFieldSet(Element element, 1513 HFieldSet(Element element,
1495 HInstruction receiver, 1514 HInstruction receiver,
1496 HInstruction value) 1515 HInstruction value)
1497 : super(element, <HInstruction>[receiver, value]) { 1516 : super(element, <HInstruction>[receiver, value]) {
1498 clearAllSideEffects(); 1517 clearAllSideEffects();
1499 setChangesInstanceProperty(); 1518 setChangesInstanceProperty();
(...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2662 HBasicBlock get start => expression.start; 2681 HBasicBlock get start => expression.start;
2663 HBasicBlock get end { 2682 HBasicBlock get end {
2664 // We don't create a switch block if there are no cases. 2683 // We don't create a switch block if there are no cases.
2665 assert(!statements.isEmpty); 2684 assert(!statements.isEmpty);
2666 return statements.last.end; 2685 return statements.last.end;
2667 } 2686 }
2668 2687
2669 bool accept(HStatementInformationVisitor visitor) => 2688 bool accept(HStatementInformationVisitor visitor) =>
2670 visitor.visitSwitchInfo(this); 2689 visitor.visitSwitchInfo(this);
2671 } 2690 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698