| 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 |