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 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 14 matching lines...) Expand all Loading... | |
25 R visitForeign(HForeign node); | 25 R visitForeign(HForeign node); |
26 R visitForeignNew(HForeignNew node); | 26 R visitForeignNew(HForeignNew node); |
27 R visitGoto(HGoto node); | 27 R visitGoto(HGoto node); |
28 R visitGreater(HGreater node); | 28 R visitGreater(HGreater node); |
29 R visitGreaterEqual(HGreaterEqual node); | 29 R visitGreaterEqual(HGreaterEqual node); |
30 R visitIdentity(HIdentity node); | 30 R visitIdentity(HIdentity node); |
31 R visitIf(HIf node); | 31 R visitIf(HIf node); |
32 R visitIndex(HIndex node); | 32 R visitIndex(HIndex node); |
33 R visitIndexAssign(HIndexAssign node); | 33 R visitIndexAssign(HIndexAssign node); |
34 R visitIntegerCheck(HIntegerCheck node); | 34 R visitIntegerCheck(HIntegerCheck node); |
35 R visitInterceptor(HInterceptor node); | |
35 R visitInvokeClosure(HInvokeClosure node); | 36 R visitInvokeClosure(HInvokeClosure node); |
36 R visitInvokeDynamicGetter(HInvokeDynamicGetter node); | 37 R visitInvokeDynamicGetter(HInvokeDynamicGetter node); |
37 R visitInvokeDynamicMethod(HInvokeDynamicMethod node); | 38 R visitInvokeDynamicMethod(HInvokeDynamicMethod node); |
38 R visitInvokeDynamicSetter(HInvokeDynamicSetter node); | 39 R visitInvokeDynamicSetter(HInvokeDynamicSetter node); |
39 R visitInvokeStatic(HInvokeStatic node); | 40 R visitInvokeStatic(HInvokeStatic node); |
40 R visitInvokeSuper(HInvokeSuper node); | 41 R visitInvokeSuper(HInvokeSuper node); |
41 R visitIs(HIs node); | 42 R visitIs(HIs node); |
42 R visitLazyStatic(HLazyStatic node); | 43 R visitLazyStatic(HLazyStatic node); |
43 R visitLess(HLess node); | 44 R visitLess(HLess node); |
44 R visitLessEqual(HLessEqual node); | 45 R visitLessEqual(HLessEqual node); |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
284 visitForeign(HForeign node) => visitInstruction(node); | 285 visitForeign(HForeign node) => visitInstruction(node); |
285 visitForeignNew(HForeignNew node) => visitForeign(node); | 286 visitForeignNew(HForeignNew node) => visitForeign(node); |
286 visitGoto(HGoto node) => visitControlFlow(node); | 287 visitGoto(HGoto node) => visitControlFlow(node); |
287 visitGreater(HGreater node) => visitRelational(node); | 288 visitGreater(HGreater node) => visitRelational(node); |
288 visitGreaterEqual(HGreaterEqual node) => visitRelational(node); | 289 visitGreaterEqual(HGreaterEqual node) => visitRelational(node); |
289 visitIdentity(HIdentity node) => visitRelational(node); | 290 visitIdentity(HIdentity node) => visitRelational(node); |
290 visitIf(HIf node) => visitConditionalBranch(node); | 291 visitIf(HIf node) => visitConditionalBranch(node); |
291 visitIndex(HIndex node) => visitInvokeStatic(node); | 292 visitIndex(HIndex node) => visitInvokeStatic(node); |
292 visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node); | 293 visitIndexAssign(HIndexAssign node) => visitInvokeStatic(node); |
293 visitIntegerCheck(HIntegerCheck node) => visitCheck(node); | 294 visitIntegerCheck(HIntegerCheck node) => visitCheck(node); |
295 visitInterceptor(HInterceptor node) => visitInstruction(node); | |
294 visitInvokeClosure(HInvokeClosure node) | 296 visitInvokeClosure(HInvokeClosure node) |
295 => visitInvokeDynamic(node); | 297 => visitInvokeDynamic(node); |
296 visitInvokeDynamicMethod(HInvokeDynamicMethod node) | 298 visitInvokeDynamicMethod(HInvokeDynamicMethod node) |
297 => visitInvokeDynamic(node); | 299 => visitInvokeDynamic(node); |
298 visitInvokeDynamicGetter(HInvokeDynamicGetter node) | 300 visitInvokeDynamicGetter(HInvokeDynamicGetter node) |
299 => visitInvokeDynamicField(node); | 301 => visitInvokeDynamicField(node); |
300 visitInvokeDynamicSetter(HInvokeDynamicSetter node) | 302 visitInvokeDynamicSetter(HInvokeDynamicSetter node) |
301 => visitInvokeDynamicField(node); | 303 => visitInvokeDynamicField(node); |
302 visitInvokeStatic(HInvokeStatic node) => visitInvoke(node); | 304 visitInvokeStatic(HInvokeStatic node) => visitInvoke(node); |
303 visitInvokeSuper(HInvokeSuper node) => visitInvoke(node); | 305 visitInvokeSuper(HInvokeSuper node) => visitInvoke(node); |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
774 | 776 |
775 // Other flags. | 777 // Other flags. |
776 static const int FLAG_USE_GVN = FLAG_DEPENDS_ON_SOMETHING + 1; | 778 static const int FLAG_USE_GVN = FLAG_DEPENDS_ON_SOMETHING + 1; |
777 | 779 |
778 // Type codes. | 780 // Type codes. |
779 static const int UNDEFINED_TYPECODE = -1; | 781 static const int UNDEFINED_TYPECODE = -1; |
780 static const int BOOLIFY_TYPECODE = 0; | 782 static const int BOOLIFY_TYPECODE = 0; |
781 static const int TYPE_GUARD_TYPECODE = 1; | 783 static const int TYPE_GUARD_TYPECODE = 1; |
782 static const int BOUNDS_CHECK_TYPECODE = 2; | 784 static const int BOUNDS_CHECK_TYPECODE = 2; |
783 static const int INTEGER_CHECK_TYPECODE = 3; | 785 static const int INTEGER_CHECK_TYPECODE = 3; |
784 static const int INVOKE_INTERCEPTOR_TYPECODE = 4; | 786 static const int INTERCEPTOR_TYPECODE = 4; |
785 static const int ADD_TYPECODE = 5; | 787 static const int ADD_TYPECODE = 5; |
786 static const int DIVIDE_TYPECODE = 6; | 788 static const int DIVIDE_TYPECODE = 6; |
787 static const int MODULO_TYPECODE = 7; | 789 static const int MODULO_TYPECODE = 7; |
788 static const int MULTIPLY_TYPECODE = 8; | 790 static const int MULTIPLY_TYPECODE = 8; |
789 static const int SUBTRACT_TYPECODE = 9; | 791 static const int SUBTRACT_TYPECODE = 9; |
790 static const int TRUNCATING_DIVIDE_TYPECODE = 10; | 792 static const int TRUNCATING_DIVIDE_TYPECODE = 10; |
791 static const int SHIFT_LEFT_TYPECODE = 11; | 793 static const int SHIFT_LEFT_TYPECODE = 11; |
792 static const int SHIFT_RIGHT_TYPECODE = 12; | 794 static const int SHIFT_RIGHT_TYPECODE = 12; |
793 static const int BIT_OR_TYPECODE = 13; | 795 static const int BIT_OR_TYPECODE = 13; |
794 static const int BIT_AND_TYPECODE = 14; | 796 static const int BIT_AND_TYPECODE = 14; |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1384 clearAllSideEffects(); | 1386 clearAllSideEffects(); |
1385 if (isSideEffectFree) { | 1387 if (isSideEffectFree) { |
1386 setChangesInstanceProperty(); | 1388 setChangesInstanceProperty(); |
1387 } else { | 1389 } else { |
1388 setAllSideEffects(); | 1390 setAllSideEffects(); |
1389 } | 1391 } |
1390 } | 1392 } |
1391 } | 1393 } |
1392 | 1394 |
1393 class HInvokeStatic extends HInvoke { | 1395 class HInvokeStatic extends HInvoke { |
1394 bool isSideEffectFree = false; | |
1395 /** The first input must be the target. */ | 1396 /** The first input must be the target. */ |
1396 HInvokeStatic(inputs, [HType knownType = HType.UNKNOWN]) : super(inputs) { | 1397 HInvokeStatic(inputs, [HType knownType = HType.UNKNOWN]) : super(inputs) { |
1397 guaranteedType = knownType; | 1398 guaranteedType = knownType; |
1398 } | 1399 } |
1399 | 1400 |
1400 toString() => 'invoke static: ${element.name}'; | 1401 toString() => 'invoke static: ${element.name}'; |
1401 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); | 1402 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); |
1402 int typeCode() => HInstruction.INVOKE_STATIC_TYPECODE; | 1403 int typeCode() => HInstruction.INVOKE_STATIC_TYPECODE; |
1403 Element get element => target.element; | 1404 Element get element => target.element; |
1404 HStatic get target => inputs[0]; | 1405 HStatic get target => inputs[0]; |
1405 | 1406 |
1406 HType computeDesiredTypeForInput(HInstruction input, | 1407 HType computeDesiredTypeForInput(HInstruction input, |
1407 HTypeMap types, | 1408 HTypeMap types, |
1408 Compiler compiler) { | 1409 Compiler compiler) { |
1409 // TODO(floitsch): we want the target to be a function. | 1410 // TODO(floitsch): we want the target to be a function. |
1410 if (input == target) return HType.UNKNOWN; | 1411 if (input == target) return HType.UNKNOWN; |
1411 return computeDesiredTypeForNonTargetInput(input, types, compiler); | 1412 return computeDesiredTypeForNonTargetInput(input, types, compiler); |
1412 } | 1413 } |
1413 | 1414 |
1414 HType computeDesiredTypeForNonTargetInput(HInstruction input, | 1415 HType computeDesiredTypeForNonTargetInput(HInstruction input, |
1415 HTypeMap types, | 1416 HTypeMap types, |
1416 Compiler compiler) { | 1417 Compiler compiler) { |
1417 return HType.UNKNOWN; | 1418 return HType.UNKNOWN; |
1418 } | 1419 } |
1419 | |
1420 void prepareGvn(HTypeMap types) { | |
ahe
2012/11/22 13:26:11
What is this change for?
ngeoffray
2012/11/22 13:37:59
This code was temporary, to make sure we did not r
| |
1421 clearAllSideEffects(); | |
1422 if (!isSideEffectFree) { | |
1423 setAllSideEffects(); | |
1424 } | |
1425 } | |
1426 } | 1420 } |
1427 | 1421 |
1428 class HInvokeSuper extends HInvokeStatic { | 1422 class HInvokeSuper extends HInvokeStatic { |
1429 final bool isSetter; | 1423 final bool isSetter; |
1430 HInvokeSuper(inputs, {this.isSetter: false}) : super(inputs); | 1424 HInvokeSuper(inputs, {this.isSetter: false}) : super(inputs); |
1431 toString() => 'invoke super: ${element.name}'; | 1425 toString() => 'invoke super: ${element.name}'; |
1432 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); | 1426 accept(HVisitor visitor) => visitor.visitInvokeSuper(this); |
1433 | 1427 |
1434 HInstruction get value { | 1428 HInstruction get value { |
1435 assert(isSetter); | 1429 assert(isSetter); |
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2394 toString() => 'static ${element.name}'; | 2388 toString() => 'static ${element.name}'; |
2395 accept(HVisitor visitor) => visitor.visitStatic(this); | 2389 accept(HVisitor visitor) => visitor.visitStatic(this); |
2396 | 2390 |
2397 int gvnHashCode() => super.gvnHashCode() ^ element.hashCode; | 2391 int gvnHashCode() => super.gvnHashCode() ^ element.hashCode; |
2398 int typeCode() => HInstruction.STATIC_TYPECODE; | 2392 int typeCode() => HInstruction.STATIC_TYPECODE; |
2399 bool typeEquals(other) => other is HStatic; | 2393 bool typeEquals(other) => other is HStatic; |
2400 bool dataEquals(HStatic other) => element == other.element; | 2394 bool dataEquals(HStatic other) => element == other.element; |
2401 bool isCodeMotionInvariant() => !element.isAssignable(); | 2395 bool isCodeMotionInvariant() => !element.isAssignable(); |
2402 } | 2396 } |
2403 | 2397 |
2398 class HInterceptor extends HInstruction { | |
2399 final Set<ClassElement> interceptedClasses; | |
2400 HInterceptor(this.interceptedClasses, HInstruction receiver) | |
2401 : super(<HInstruction>[receiver]); | |
2402 String toString() => 'interceptor on $interceptedClasses'; | |
ahe
2012/11/22 13:26:11
What is the method name?
ngeoffray
2012/11/22 13:37:59
An interceptor is not necessary on one method call
| |
2403 accept(HVisitor visitor) => visitor.visitInterceptor(this); | |
2404 HInstruction get receiver => inputs[0]; | |
2405 | |
2406 void prepareGvn(HTypeMap types) { | |
2407 clearAllSideEffects(); | |
2408 } | |
2409 | |
2410 int typeCode() => HInstruction.INTERCEPTOR_TYPECODE; | |
2411 } | |
2412 | |
2404 /** An [HLazyStatic] is a static that is initialized lazily at first read. */ | 2413 /** An [HLazyStatic] is a static that is initialized lazily at first read. */ |
2405 class HLazyStatic extends HStatic { | 2414 class HLazyStatic extends HStatic { |
2406 HLazyStatic(Element element) : super(element); | 2415 HLazyStatic(Element element) : super(element); |
2407 | 2416 |
2408 void prepareGvn(HTypeMap types) { | 2417 void prepareGvn(HTypeMap types) { |
2409 // TODO(4931): The first access has side-effects, but we afterwards we | 2418 // TODO(4931): The first access has side-effects, but we afterwards we |
2410 // should be able to GVN. | 2419 // should be able to GVN. |
2411 setAllSideEffects(); | 2420 setAllSideEffects(); |
2412 } | 2421 } |
2413 | 2422 |
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2949 HBasicBlock get start => expression.start; | 2958 HBasicBlock get start => expression.start; |
2950 HBasicBlock get end { | 2959 HBasicBlock get end { |
2951 // We don't create a switch block if there are no cases. | 2960 // We don't create a switch block if there are no cases. |
2952 assert(!statements.isEmpty); | 2961 assert(!statements.isEmpty); |
2953 return statements.last.end; | 2962 return statements.last.end; |
2954 } | 2963 } |
2955 | 2964 |
2956 bool accept(HStatementInformationVisitor visitor) => | 2965 bool accept(HStatementInformationVisitor visitor) => |
2957 visitor.visitSwitchInfo(this); | 2966 visitor.visitSwitchInfo(this); |
2958 } | 2967 } |
OLD | NEW |