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

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

Issue 12042003: Move relational operators to the new interceptors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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
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);
11 R visitBitNot(HBitNot node); 11 R visitBitNot(HBitNot node);
12 R visitBitOr(HBitOr node); 12 R visitBitOr(HBitOr node);
13 R visitBitXor(HBitXor node); 13 R visitBitXor(HBitXor node);
14 R visitBoolify(HBoolify node); 14 R visitBoolify(HBoolify node);
15 R visitBoundsCheck(HBoundsCheck node); 15 R visitBoundsCheck(HBoundsCheck node);
16 R visitBreak(HBreak node); 16 R visitBreak(HBreak node);
17 R visitConstant(HConstant node); 17 R visitConstant(HConstant node);
18 R visitContinue(HContinue node); 18 R visitContinue(HContinue node);
19 R visitDivide(HDivide node); 19 R visitDivide(HDivide node);
20 R visitEquals(HEquals node);
21 R visitExit(HExit node); 20 R visitExit(HExit node);
22 R visitExitTry(HExitTry node); 21 R visitExitTry(HExitTry node);
23 R visitFieldGet(HFieldGet node); 22 R visitFieldGet(HFieldGet node);
24 R visitFieldSet(HFieldSet node); 23 R visitFieldSet(HFieldSet node);
25 R visitForeign(HForeign node); 24 R visitForeign(HForeign node);
26 R visitForeignNew(HForeignNew node); 25 R visitForeignNew(HForeignNew node);
27 R visitGoto(HGoto node); 26 R visitGoto(HGoto node);
28 R visitGreater(HGreater node); 27 R visitGreater(HGreater node);
29 R visitGreaterEqual(HGreaterEqual node); 28 R visitGreaterEqual(HGreaterEqual node);
30 R visitIdentity(HIdentity node); 29 R visitIdentity(HIdentity node);
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 visitBinaryArithmetic(HBinaryArithmetic node) => visitInvokeBinary(node); 255 visitBinaryArithmetic(HBinaryArithmetic node) => visitInvokeBinary(node);
257 visitBinaryBitOp(HBinaryBitOp node) => visitBinaryArithmetic(node); 256 visitBinaryBitOp(HBinaryBitOp node) => visitBinaryArithmetic(node);
258 visitInvoke(HInvoke node) => visitInstruction(node); 257 visitInvoke(HInvoke node) => visitInstruction(node);
259 visitInvokeBinary(HInvokeBinary node) => visitInstruction(node); 258 visitInvokeBinary(HInvokeBinary node) => visitInstruction(node);
260 visitInvokeDynamic(HInvokeDynamic node) => visitInvoke(node); 259 visitInvokeDynamic(HInvokeDynamic node) => visitInvoke(node);
261 visitInvokeDynamicField(HInvokeDynamicField node) => visitInvokeDynamic(node); 260 visitInvokeDynamicField(HInvokeDynamicField node) => visitInvokeDynamic(node);
262 visitInvokeUnary(HInvokeUnary node) => visitInstruction(node); 261 visitInvokeUnary(HInvokeUnary node) => visitInstruction(node);
263 visitConditionalBranch(HConditionalBranch node) => visitControlFlow(node); 262 visitConditionalBranch(HConditionalBranch node) => visitControlFlow(node);
264 visitControlFlow(HControlFlow node) => visitInstruction(node); 263 visitControlFlow(HControlFlow node) => visitInstruction(node);
265 visitFieldAccess(HFieldAccess node) => visitInstruction(node); 264 visitFieldAccess(HFieldAccess node) => visitInstruction(node);
266 visitRelational(HRelational node) => visitInvokeStatic(node); 265 visitRelational(HRelational node) => visitInvokeBinary(node);
267 266
268 visitAdd(HAdd node) => visitBinaryArithmetic(node); 267 visitAdd(HAdd node) => visitBinaryArithmetic(node);
269 visitBailoutTarget(HBailoutTarget node) => visitInstruction(node); 268 visitBailoutTarget(HBailoutTarget node) => visitInstruction(node);
270 visitBitAnd(HBitAnd node) => visitBinaryBitOp(node); 269 visitBitAnd(HBitAnd node) => visitBinaryBitOp(node);
271 visitBitNot(HBitNot node) => visitInvokeUnary(node); 270 visitBitNot(HBitNot node) => visitInvokeUnary(node);
272 visitBitOr(HBitOr node) => visitBinaryBitOp(node); 271 visitBitOr(HBitOr node) => visitBinaryBitOp(node);
273 visitBitXor(HBitXor node) => visitBinaryBitOp(node); 272 visitBitXor(HBitXor node) => visitBinaryBitOp(node);
274 visitBoolify(HBoolify node) => visitInstruction(node); 273 visitBoolify(HBoolify node) => visitInstruction(node);
275 visitBoundsCheck(HBoundsCheck node) => visitCheck(node); 274 visitBoundsCheck(HBoundsCheck node) => visitCheck(node);
276 visitBreak(HBreak node) => visitJump(node); 275 visitBreak(HBreak node) => visitJump(node);
277 visitContinue(HContinue node) => visitJump(node); 276 visitContinue(HContinue node) => visitJump(node);
278 visitCheck(HCheck node) => visitInstruction(node); 277 visitCheck(HCheck node) => visitInstruction(node);
279 visitConstant(HConstant node) => visitInstruction(node); 278 visitConstant(HConstant node) => visitInstruction(node);
280 visitDivide(HDivide node) => visitBinaryArithmetic(node); 279 visitDivide(HDivide node) => visitBinaryArithmetic(node);
281 visitEquals(HEquals node) => visitRelational(node);
282 visitExit(HExit node) => visitControlFlow(node); 280 visitExit(HExit node) => visitControlFlow(node);
283 visitExitTry(HExitTry node) => visitControlFlow(node); 281 visitExitTry(HExitTry node) => visitControlFlow(node);
284 visitFieldGet(HFieldGet node) => visitFieldAccess(node); 282 visitFieldGet(HFieldGet node) => visitFieldAccess(node);
285 visitFieldSet(HFieldSet node) => visitFieldAccess(node); 283 visitFieldSet(HFieldSet node) => visitFieldAccess(node);
286 visitForeign(HForeign node) => visitInstruction(node); 284 visitForeign(HForeign node) => visitInstruction(node);
287 visitForeignNew(HForeignNew node) => visitForeign(node); 285 visitForeignNew(HForeignNew node) => visitForeign(node);
288 visitGoto(HGoto node) => visitControlFlow(node); 286 visitGoto(HGoto node) => visitControlFlow(node);
289 visitGreater(HGreater node) => visitRelational(node); 287 visitGreater(HGreater node) => visitRelational(node);
290 visitGreaterEqual(HGreaterEqual node) => visitRelational(node); 288 visitGreaterEqual(HGreaterEqual node) => visitRelational(node);
291 visitIdentity(HIdentity node) => visitRelational(node); 289 visitIdentity(HIdentity node) => visitRelational(node);
(...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1542 HForeignNew(this.element, List<HInstruction> inputs) 1540 HForeignNew(this.element, List<HInstruction> inputs)
1543 : super(const LiteralDartString("new"), 1541 : super(const LiteralDartString("new"),
1544 const LiteralDartString("Object"), inputs); 1542 const LiteralDartString("Object"), inputs);
1545 accept(HVisitor visitor) => visitor.visitForeignNew(this); 1543 accept(HVisitor visitor) => visitor.visitForeignNew(this);
1546 } 1544 }
1547 1545
1548 abstract class HInvokeBinary extends HInstruction { 1546 abstract class HInvokeBinary extends HInstruction {
1549 HInvokeBinary(HInstruction left, HInstruction right) 1547 HInvokeBinary(HInstruction left, HInstruction right)
1550 : super(<HInstruction>[left, right]); 1548 : super(<HInstruction>[left, right]);
1551 1549
1550 void prepareGvn(HTypeMap types) {
1551 clearAllSideEffects();
1552 setUseGvn();
1553 }
1554
1552 HInstruction get left => inputs[0]; 1555 HInstruction get left => inputs[0];
1553 HInstruction get right => inputs[1]; 1556 HInstruction get right => inputs[1];
1554 1557
1555 BinaryOperation operation(ConstantSystem constantSystem); 1558 BinaryOperation operation(ConstantSystem constantSystem);
1556 } 1559 }
1557 1560
1558 abstract class HBinaryArithmetic extends HInvokeBinary { 1561 abstract class HBinaryArithmetic extends HInvokeBinary {
1559 HBinaryArithmetic(HInstruction left, HInstruction right) : super(left, right); 1562 HBinaryArithmetic(HInstruction left, HInstruction right) : super(left, right);
1560 1563
1561 void prepareGvn(HTypeMap types) {
1562 clearAllSideEffects();
1563 setUseGvn();
1564 }
1565
1566 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler) { 1564 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler) {
1567 if (left.isInteger(types) && right.isInteger(types)) return HType.INTEGER; 1565 if (left.isInteger(types) && right.isInteger(types)) return HType.INTEGER;
1568 if (left.isDouble(types)) return HType.DOUBLE; 1566 if (left.isDouble(types)) return HType.DOUBLE;
1569 return HType.NUMBER; 1567 return HType.NUMBER;
1570 } 1568 }
1571 1569
1572 BinaryOperation operation(ConstantSystem constantSystem); 1570 BinaryOperation operation(ConstantSystem constantSystem);
1573 } 1571 }
1574 1572
1575 class HAdd extends HBinaryArithmetic { 1573 class HAdd extends HBinaryArithmetic {
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
1991 assert(isLogicalOperator()); 1989 assert(isLogicalOperator());
1992 if (logicalOperatorType == IS_AND) return "&&"; 1990 if (logicalOperatorType == IS_AND) return "&&";
1993 assert(logicalOperatorType == IS_OR); 1991 assert(logicalOperatorType == IS_OR);
1994 return "||"; 1992 return "||";
1995 } 1993 }
1996 1994
1997 toString() => 'phi'; 1995 toString() => 'phi';
1998 accept(HVisitor visitor) => visitor.visitPhi(this); 1996 accept(HVisitor visitor) => visitor.visitPhi(this);
1999 } 1997 }
2000 1998
2001 abstract class HRelational extends HInvokeStatic { 1999 abstract class HRelational extends HInvokeBinary {
2002 bool usesBoolifiedInterceptor = false; 2000 bool usesBoolifiedInterceptor = false;
2003 HRelational(HStatic target, HInstruction left, HInstruction right) 2001 HRelational(HInstruction left, HInstruction right) : super(left, right);
2004 : super(<HInstruction>[target, left, right]); 2002 HType get guaranteedType => HType.BOOLEAN;
2005
2006 void prepareGvn(HTypeMap types) {
2007 clearAllSideEffects();
2008 // Relational expressions can take part in global value numbering
2009 // and do not have any side-effects if we know all the inputs are
2010 // numbers. This can be improved for at least equality.
2011 if (isBuiltin(types)) {
2012 setUseGvn();
2013 } else {
2014 setAllSideEffects();
2015 }
2016 }
2017
2018 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler) {
2019 if (left.isNumber(types) || usesBoolifiedInterceptor) return HType.BOOLEAN;
2020 return HType.UNKNOWN;
2021 }
2022
2023 HType get guaranteedType {
2024 if (usesBoolifiedInterceptor) return HType.BOOLEAN;
2025 return HType.UNKNOWN;
2026 }
2027
2028 HType computeDesiredTypeForNonTargetInput(HInstruction input,
2029 HTypeMap types,
2030 Compiler compiler) {
2031 HType propagatedType = types[this];
2032 // For all relational operations except HEquals, we expect to get numbers
2033 // only. With numbers the outgoing type is a boolean. If something else
2034 // is desired, then numbers are incorrect, though.
2035 if (propagatedType.isUnknown() || propagatedType.isBoolean()) {
2036 if (left.isTypeUnknown(types) || left.isNumber(types)) {
2037 return HType.NUMBER;
2038 }
2039 }
2040 return HType.UNKNOWN;
2041 }
2042
2043 HType computeLikelyType(HTypeMap types, Compiler compiler) => HType.BOOLEAN;
2044
2045 bool isBuiltin(HTypeMap types)
2046 => left.isNumber(types) && right.isNumber(types);
2047
2048 HInstruction get left => inputs[1];
2049 HInstruction get right => inputs[2];
2050
2051 BinaryOperation operation(ConstantSystem constantSystem);
2052 }
2053
2054 class HEquals extends HRelational {
2055 HEquals(HStatic target, HInstruction left, HInstruction right)
2056 : super(target, left, right);
2057 accept(HVisitor visitor) => visitor.visitEquals(this);
2058
2059 bool isBuiltin(HTypeMap types) {
2060 // All primitive types have 'identical' semantics.
2061 // Note that this includes all constants except the user-constructed
2062 // objects.
2063 return types[left].isPrimitiveOrNull() || right.isConstantNull();
2064 }
2065
2066 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler) {
2067 if (isBuiltin(types) || usesBoolifiedInterceptor) return HType.BOOLEAN;
2068 return HType.UNKNOWN;
2069 }
2070
2071 HType computeDesiredTypeForNonTargetInput(HInstruction input,
2072 HTypeMap types,
2073 Compiler compiler) {
2074 HType propagatedType = types[this];
2075 if (input == left && types[right].isUseful()) {
2076 // All our useful types have 'identical' semantics. But we don't want to
2077 // speculatively test for all possible types. Therefore we try to match
2078 // the two types. That is, if we see x == 3, then we speculatively test
2079 // if x is a number and bailout if it isn't.
2080 // If right is a number we don't need more than a number (no need to match
2081 // the exact type of right).
2082 if (right.isNumber(types)) return HType.NUMBER;
2083 return types[right];
2084 }
2085 // String equality testing is much more common than array equality testing.
2086 if (input == left && left.isIndexablePrimitive(types)) {
2087 return HType.READABLE_ARRAY;
2088 }
2089 // String equality testing is much more common than array equality testing.
2090 if (input == right && right.isIndexablePrimitive(types)) {
2091 return HType.STRING;
2092 }
2093 return HType.UNKNOWN;
2094 }
2095
2096 BinaryOperation operation(ConstantSystem constantSystem)
2097 => constantSystem.equal;
2098 int typeCode() => HInstruction.EQUALS_TYPECODE;
2099 bool typeEquals(other) => other is HEquals;
2100 bool dataEquals(HInstruction other) => true;
2101 } 2003 }
2102 2004
2103 class HIdentity extends HRelational { 2005 class HIdentity extends HRelational {
2104 HIdentity(HStatic target, HInstruction left, HInstruction right) 2006 HIdentity(HInstruction left, HInstruction right) : super(left, right);
2105 : super(target, left, right);
2106 accept(HVisitor visitor) => visitor.visitIdentity(this); 2007 accept(HVisitor visitor) => visitor.visitIdentity(this);
2107 2008
2108 bool isBuiltin(HTypeMap types) => true;
2109
2110 HType get guaranteedType => HType.BOOLEAN;
2111 HType computeTypeFromInputTypes(HTypeMap types, Compiler compiler)
2112 => HType.BOOLEAN;
2113 // Note that the identity operator really does not care for its input types.
2114 HType computeDesiredTypeForInput(HInstruction input,
2115 HTypeMap types,
2116 Compiler compiler) {
2117 return HType.UNKNOWN;
2118 }
2119
2120 BinaryOperation operation(ConstantSystem constantSystem) 2009 BinaryOperation operation(ConstantSystem constantSystem)
2121 => constantSystem.identity; 2010 => constantSystem.identity;
2122 int typeCode() => HInstruction.IDENTITY_TYPECODE; 2011 int typeCode() => HInstruction.IDENTITY_TYPECODE;
2123 bool typeEquals(other) => other is HIdentity; 2012 bool typeEquals(other) => other is HIdentity;
2124 bool dataEquals(HInstruction other) => true; 2013 bool dataEquals(HInstruction other) => true;
2125 } 2014 }
2126 2015
2127 class HGreater extends HRelational { 2016 class HGreater extends HRelational {
2128 HGreater(HStatic target, HInstruction left, HInstruction right) 2017 HGreater(HInstruction left, HInstruction right) : super(left, right);
2129 : super(target, left, right);
2130 accept(HVisitor visitor) => visitor.visitGreater(this); 2018 accept(HVisitor visitor) => visitor.visitGreater(this);
2131 2019
2132 BinaryOperation operation(ConstantSystem constantSystem) 2020 BinaryOperation operation(ConstantSystem constantSystem)
2133 => constantSystem.greater; 2021 => constantSystem.greater;
2134 int typeCode() => HInstruction.GREATER_TYPECODE; 2022 int typeCode() => HInstruction.GREATER_TYPECODE;
2135 bool typeEquals(other) => other is HGreater; 2023 bool typeEquals(other) => other is HGreater;
2136 bool dataEquals(HInstruction other) => true; 2024 bool dataEquals(HInstruction other) => true;
2137 } 2025 }
2138 2026
2139 class HGreaterEqual extends HRelational { 2027 class HGreaterEqual extends HRelational {
2140 HGreaterEqual(HStatic target, HInstruction left, HInstruction right) 2028 HGreaterEqual(HInstruction left, HInstruction right) : super(left, right);
2141 : super(target, left, right);
2142 accept(HVisitor visitor) => visitor.visitGreaterEqual(this); 2029 accept(HVisitor visitor) => visitor.visitGreaterEqual(this);
2143 2030
2144 BinaryOperation operation(ConstantSystem constantSystem) 2031 BinaryOperation operation(ConstantSystem constantSystem)
2145 => constantSystem.greaterEqual; 2032 => constantSystem.greaterEqual;
2146 int typeCode() => HInstruction.GREATER_EQUAL_TYPECODE; 2033 int typeCode() => HInstruction.GREATER_EQUAL_TYPECODE;
2147 bool typeEquals(other) => other is HGreaterEqual; 2034 bool typeEquals(other) => other is HGreaterEqual;
2148 bool dataEquals(HInstruction other) => true; 2035 bool dataEquals(HInstruction other) => true;
2149 } 2036 }
2150 2037
2151 class HLess extends HRelational { 2038 class HLess extends HRelational {
2152 HLess(HStatic target, HInstruction left, HInstruction right) 2039 HLess(HInstruction left, HInstruction right) : super(left, right);
2153 : super(target, left, right);
2154 accept(HVisitor visitor) => visitor.visitLess(this); 2040 accept(HVisitor visitor) => visitor.visitLess(this);
2155 2041
2156 BinaryOperation operation(ConstantSystem constantSystem) 2042 BinaryOperation operation(ConstantSystem constantSystem)
2157 => constantSystem.less; 2043 => constantSystem.less;
2158 int typeCode() => HInstruction.LESS_TYPECODE; 2044 int typeCode() => HInstruction.LESS_TYPECODE;
2159 bool typeEquals(other) => other is HLess; 2045 bool typeEquals(other) => other is HLess;
2160 bool dataEquals(HInstruction other) => true; 2046 bool dataEquals(HInstruction other) => true;
2161 } 2047 }
2162 2048
2163 class HLessEqual extends HRelational { 2049 class HLessEqual extends HRelational {
2164 HLessEqual(HStatic target, HInstruction left, HInstruction right) 2050 HLessEqual(HInstruction left, HInstruction right) : super(left, right);
2165 : super(target, left, right);
2166 accept(HVisitor visitor) => visitor.visitLessEqual(this); 2051 accept(HVisitor visitor) => visitor.visitLessEqual(this);
2167 2052
2168 BinaryOperation operation(ConstantSystem constantSystem) 2053 BinaryOperation operation(ConstantSystem constantSystem)
2169 => constantSystem.lessEqual; 2054 => constantSystem.lessEqual;
2170 int typeCode() => HInstruction.LESS_EQUAL_TYPECODE; 2055 int typeCode() => HInstruction.LESS_EQUAL_TYPECODE;
2171 bool typeEquals(other) => other is HLessEqual; 2056 bool typeEquals(other) => other is HLessEqual;
2172 bool dataEquals(HInstruction other) => true; 2057 bool dataEquals(HInstruction other) => true;
2173 } 2058 }
2174 2059
2175 class HReturn extends HControlFlow { 2060 class HReturn extends HControlFlow {
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
2752 HBasicBlock get start => expression.start; 2637 HBasicBlock get start => expression.start;
2753 HBasicBlock get end { 2638 HBasicBlock get end {
2754 // We don't create a switch block if there are no cases. 2639 // We don't create a switch block if there are no cases.
2755 assert(!statements.isEmpty); 2640 assert(!statements.isEmpty);
2756 return statements.last.end; 2641 return statements.last.end;
2757 } 2642 }
2758 2643
2759 bool accept(HStatementInformationVisitor visitor) => 2644 bool accept(HStatementInformationVisitor visitor) =>
2760 visitor.visitSwitchInfo(this); 2645 visitor.visitSwitchInfo(this);
2761 } 2646 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698