OLD | NEW |
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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
7 R visitBitAnd(HBitAnd node); | 7 R visitBitAnd(HBitAnd node); |
8 R visitBitNot(HBitNot node); | 8 R visitBitNot(HBitNot node); |
9 R visitBitOr(HBitOr node); | 9 R visitBitOr(HBitOr node); |
10 R visitBitXor(HBitXor node); | 10 R visitBitXor(HBitXor node); |
(...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1305 accept(HVisitor visitor) => visitor.visitFieldGet(this); | 1305 accept(HVisitor visitor) => visitor.visitFieldGet(this); |
1306 | 1306 |
1307 void prepareGvn() { | 1307 void prepareGvn() { |
1308 setUseGvn(); | 1308 setUseGvn(); |
1309 if (!isFinalOrConst) setDependsOnSomething(); | 1309 if (!isFinalOrConst) setDependsOnSomething(); |
1310 } | 1310 } |
1311 | 1311 |
1312 int typeCode() => 27; | 1312 int typeCode() => 27; |
1313 bool typeEquals(other) => other is HFieldGet; | 1313 bool typeEquals(other) => other is HFieldGet; |
1314 bool dataEquals(HFieldGet other) => element == other.element; | 1314 bool dataEquals(HFieldGet other) => element == other.element; |
| 1315 String toString() => "FieldGet $element.name"; |
1315 } | 1316 } |
1316 | 1317 |
1317 class HFieldSet extends HFieldAccess { | 1318 class HFieldSet extends HFieldAccess { |
1318 HFieldSet(Element element, HInstruction receiver, HInstruction value) | 1319 HFieldSet(Element element, HInstruction receiver, HInstruction value) |
1319 : super(element, <HInstruction>[receiver, value]); | 1320 : super(element, <HInstruction>[receiver, value]); |
1320 | 1321 |
1321 HInstruction get receiver() => inputs[0]; | 1322 HInstruction get receiver() => inputs[0]; |
1322 HInstruction get value() => inputs[1]; | 1323 HInstruction get value() => inputs[1]; |
1323 accept(HVisitor visitor) => visitor.visitFieldSet(this); | 1324 accept(HVisitor visitor) => visitor.visitFieldSet(this); |
1324 | 1325 |
1325 void prepareGvn() { | 1326 void prepareGvn() { |
1326 // TODO(ngeoffray): implement more fine grained side effects. | 1327 // TODO(ngeoffray): implement more fine grained side effects. |
1327 setAllSideEffects(); | 1328 setAllSideEffects(); |
1328 } | 1329 } |
1329 | 1330 |
1330 final bool isStatement = true; | 1331 final bool isStatement = true; |
| 1332 String toString() => "FieldSet $element.name"; |
1331 } | 1333 } |
1332 | 1334 |
1333 class HLocalGet extends HFieldGet { | 1335 class HLocalGet extends HFieldGet { |
1334 HLocalGet(Element element, HLocalValue local) : super(element, local); | 1336 HLocalGet(Element element, HLocalValue local) : super(element, local); |
1335 | 1337 |
1336 accept(HVisitor visitor) => visitor.visitLocalGet(this); | 1338 accept(HVisitor visitor) => visitor.visitLocalGet(this); |
1337 | 1339 |
1338 HLocalValue get local() => inputs[0]; | 1340 HLocalValue get local() => inputs[0]; |
1339 | 1341 |
1340 void prepareGvn() { | 1342 void prepareGvn() { |
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1922 void addInput(HInstruction input) { | 1924 void addInput(HInstruction input) { |
1923 assert(isInBasicBlock()); | 1925 assert(isInBasicBlock()); |
1924 inputs.add(input); | 1926 inputs.add(input); |
1925 input.usedBy.add(this); | 1927 input.usedBy.add(this); |
1926 } | 1928 } |
1927 | 1929 |
1928 // Compute the (shared) type of the inputs if any. If all inputs | 1930 // Compute the (shared) type of the inputs if any. If all inputs |
1929 // have the same known type return it. If any two inputs have | 1931 // have the same known type return it. If any two inputs have |
1930 // different known types, we'll return a conflict -- otherwise we'll | 1932 // different known types, we'll return a conflict -- otherwise we'll |
1931 // simply return an unknown type. | 1933 // simply return an unknown type. |
1932 HType computeInputsType(bool unknownWins) { | 1934 HType computeInputsType(bool ignoreUnknowns) { |
1933 HType candidateType = inputs[0].propagatedType; | 1935 HType candidateType = HType.CONFLICTING; |
1934 bool seenUnknown = candidateType.isUnknown(); | 1936 for (int i = 0, length = inputs.length; i < length; i++) { |
1935 for (int i = 1, length = inputs.length; i < length; i++) { | |
1936 HType inputType = inputs[i].propagatedType; | 1937 HType inputType = inputs[i].propagatedType; |
1937 if (inputType.isUnknown()) { | 1938 if (ignoreUnknowns && inputType.isUnknown()) continue; |
1938 seenUnknown = true; | 1939 // Phis need to combine the incoming types using the union operation. |
1939 } else { | 1940 // For example, if one incoming edge has type integer and the other has |
1940 // Phis need to combine the incoming types using the union operation. | 1941 // type double, then the phi is either an integer or double and thus has |
1941 // For example, if one incoming edge has type integer and the other has | 1942 // type number. |
1942 // type double, then the phi is either an integer or double and thus has | 1943 candidateType = candidateType.union(inputType); |
1943 // type number. | 1944 if (candidateType.isUnknown()) return HType.UNKNOWN; |
1944 candidateType = candidateType.union(inputType); | |
1945 if (candidateType.isConflicting()) return HType.CONFLICTING; | |
1946 } | |
1947 } | 1945 } |
1948 if (seenUnknown && unknownWins) return HType.UNKNOWN; | |
1949 return candidateType; | 1946 return candidateType; |
1950 } | 1947 } |
1951 | 1948 |
1952 HType computeTypeFromInputTypes() { | 1949 HType computeTypeFromInputTypes() { |
1953 HType inputsType = computeInputsType(true); | 1950 HType inputsType = computeInputsType(false); |
1954 if (inputsType.isConflicting()) return HType.UNKNOWN; | 1951 if (inputsType.isConflicting()) return HType.UNKNOWN; |
1955 return inputsType; | 1952 return inputsType; |
1956 } | 1953 } |
1957 | 1954 |
1958 HType computeDesiredTypeForInput(HInstruction input) { | 1955 HType computeDesiredTypeForInput(HInstruction input) { |
1959 // Best case scenario for a phi is, when all inputs have the same type. If | 1956 // Best case scenario for a phi is, when all inputs have the same type. If |
1960 // there is no desired outgoing type we therefore try to unify the input | 1957 // there is no desired outgoing type we therefore try to unify the input |
1961 // types (which is basically the [likelyType]). | 1958 // types (which is basically the [likelyType]). |
1962 if (propagatedType.isUnknown()) return likelyType; | 1959 if (propagatedType.isUnknown()) return likelyType; |
1963 // When the desired outgoing type is conflicting we don't need to give any | 1960 // When the desired outgoing type is conflicting we don't need to give any |
1964 // requirements on the inputs. | 1961 // requirements on the inputs. |
1965 if (propagatedType.isConflicting()) return HType.UNKNOWN; | 1962 if (propagatedType.isConflicting()) return HType.UNKNOWN; |
1966 // Otherwise the input type must match the desired outgoing type. | 1963 // Otherwise the input type must match the desired outgoing type. |
1967 return propagatedType; | 1964 return propagatedType; |
1968 } | 1965 } |
1969 | 1966 |
1970 HType get likelyType() { | 1967 HType get likelyType() { |
1971 HType agreedType = computeInputsType(false); | 1968 HType agreedType = computeInputsType(true); |
1972 if (agreedType.isConflicting()) return HType.UNKNOWN; | 1969 if (agreedType.isConflicting()) return HType.UNKNOWN; |
1973 // Don't be too restrictive. If the agreed type is integer or double just | 1970 // Don't be too restrictive. If the agreed type is integer or double just |
1974 // say that the likely type is number. If more is expected the type will be | 1971 // say that the likely type is number. If more is expected the type will be |
1975 // propagated back. | 1972 // propagated back. |
1976 if (agreedType.isNumber()) return HType.NUMBER; | 1973 if (agreedType.isNumber()) return HType.NUMBER; |
1977 return agreedType; | 1974 return agreedType; |
1978 } | 1975 } |
1979 | 1976 |
1980 bool isLogicalOperator() => logicalOperatorType != IS_NOT_LOGICAL_OPERATOR; | 1977 bool isLogicalOperator() => logicalOperatorType != IS_NOT_LOGICAL_OPERATOR; |
1981 | 1978 |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2664 HBasicBlock get start() => expression.start; | 2661 HBasicBlock get start() => expression.start; |
2665 HBasicBlock get end() { | 2662 HBasicBlock get end() { |
2666 // We don't create a switch block if there are no cases. | 2663 // We don't create a switch block if there are no cases. |
2667 assert(!statements.isEmpty()); | 2664 assert(!statements.isEmpty()); |
2668 return statements.last().end; | 2665 return statements.last().end; |
2669 } | 2666 } |
2670 | 2667 |
2671 bool accept(HStatementInformationVisitor visitor) => | 2668 bool accept(HStatementInformationVisitor visitor) => |
2672 visitor.visitSwitchInfo(this); | 2669 visitor.visitSwitchInfo(this); |
2673 } | 2670 } |
OLD | NEW |