Chromium Code Reviews| 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 |