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 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 5 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 6 import '../common/names.dart' show Selectors; | 6 import '../common/names.dart' show Selectors; |
| 7 import '../common/tasks.dart' show CompilerTask; | 7 import '../common/tasks.dart' show CompilerTask; |
| 8 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
| 9 import '../constants/constant_system.dart'; | 9 import '../constants/constant_system.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| (...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1178 // All intercepted classes extend `Interceptor`, so if the receiver can't | 1178 // All intercepted classes extend `Interceptor`, so if the receiver can't |
| 1179 // be a class extending `Interceptor` then it can be called directly. | 1179 // be a class extending `Interceptor` then it can be called directly. |
| 1180 if (new TypeMask.nonNullSubclass( | 1180 if (new TypeMask.nonNullSubclass( |
| 1181 _helpers.jsInterceptorClass, _closedWorld) | 1181 _helpers.jsInterceptorClass, _closedWorld) |
| 1182 .isDisjoint(input.instructionType, _closedWorld)) { | 1182 .isDisjoint(input.instructionType, _closedWorld)) { |
| 1183 var inputs = <HInstruction>[input, input]; // [interceptor, receiver]. | 1183 var inputs = <HInstruction>[input, input]; // [interceptor, receiver]. |
| 1184 HInstruction result = new HInvokeDynamicMethod( | 1184 HInstruction result = new HInvokeDynamicMethod( |
| 1185 selector, | 1185 selector, |
| 1186 input.instructionType, // receiver mask. | 1186 input.instructionType, // receiver mask. |
| 1187 inputs, | 1187 inputs, |
| 1188 toStringType)..sourceInformation = node.sourceInformation; | 1188 toStringType) |
| 1189 ..sourceInformation = node.sourceInformation; | |
| 1189 return result; | 1190 return result; |
| 1190 } | 1191 } |
| 1191 return null; | 1192 return null; |
| 1192 } | 1193 } |
| 1193 | 1194 |
| 1194 return tryConstant() ?? tryToString() ?? node; | 1195 return tryConstant() ?? tryToString() ?? node; |
| 1195 } | 1196 } |
| 1196 | 1197 |
| 1197 HInstruction visitOneShotInterceptor(HOneShotInterceptor node) { | 1198 HInstruction visitOneShotInterceptor(HOneShotInterceptor node) { |
| 1198 return handleInterceptedCall(node); | 1199 return handleInterceptedCall(node); |
| (...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2287 } else if (user is HBoolify) { | 2288 } else if (user is HBoolify) { |
| 2288 // We collect targets for strictly boolean operations so HBoolify cannot | 2289 // We collect targets for strictly boolean operations so HBoolify cannot |
| 2289 // change the result. | 2290 // change the result. |
| 2290 collectTargets(user, trueTargets, falseTargets); | 2291 collectTargets(user, trueTargets, falseTargets); |
| 2291 } | 2292 } |
| 2292 } | 2293 } |
| 2293 } | 2294 } |
| 2294 } | 2295 } |
| 2295 | 2296 |
| 2296 /** | 2297 /** |
| 2297 * Optimization phase that tries to eliminate memory loads (for | 2298 * Optimization phase that tries to eliminate memory loads (for example |
| 2298 * example [HFieldGet]), when it knows the value stored in that memory | 2299 * [HFieldGet]), when it knows the value stored in that memory location, and |
| 2299 * location. | 2300 * stores that overwrite with the same value. |
| 2300 */ | 2301 */ |
| 2301 class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { | 2302 class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase { |
| 2302 final BackendHelpers _helpers; | 2303 final BackendHelpers _helpers; |
| 2303 final Compiler compiler; | 2304 final Compiler compiler; |
| 2304 final ClosedWorld closedWorld; | 2305 final ClosedWorld closedWorld; |
| 2305 final String name = "SsaLoadElimination"; | 2306 final String name = "SsaLoadElimination"; |
| 2306 MemorySet memorySet; | 2307 MemorySet memorySet; |
| 2307 List<MemorySet> memories; | 2308 List<MemorySet> memories; |
| 2308 bool newGvnCandidates = false; | 2309 bool newGvnCandidates = false; |
| 2309 | 2310 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2386 if (existing != null) { | 2387 if (existing != null) { |
| 2387 checkNewGvnCandidates(instruction, existing); | 2388 checkNewGvnCandidates(instruction, existing); |
| 2388 instruction.block.rewriteWithBetterUser(instruction, existing); | 2389 instruction.block.rewriteWithBetterUser(instruction, existing); |
| 2389 instruction.block.remove(instruction); | 2390 instruction.block.remove(instruction); |
| 2390 } else { | 2391 } else { |
| 2391 memorySet.registerFieldValue(element, receiver, instruction); | 2392 memorySet.registerFieldValue(element, receiver, instruction); |
| 2392 } | 2393 } |
| 2393 } | 2394 } |
| 2394 | 2395 |
| 2395 void visitFieldSet(HFieldSet instruction) { | 2396 void visitFieldSet(HFieldSet instruction) { |
| 2397 FieldEntity element = instruction.element; | |
| 2396 HInstruction receiver = instruction.getDartReceiver(closedWorld).nonCheck(); | 2398 HInstruction receiver = instruction.getDartReceiver(closedWorld).nonCheck(); |
| 2397 memorySet.registerFieldValueUpdate( | 2399 if (memorySet.registerFieldValueUpdate( |
| 2398 instruction.element, receiver, instruction.inputs.last); | 2400 element, receiver, instruction.value)) { |
| 2401 instruction.block.remove(instruction); | |
| 2402 } | |
| 2399 } | 2403 } |
| 2400 | 2404 |
| 2401 void visitCreate(HCreate instruction) { | 2405 void visitCreate(HCreate instruction) { |
| 2402 memorySet.registerAllocation(instruction); | 2406 memorySet.registerAllocation(instruction); |
| 2403 if (shouldTrackInitialValues(instruction)) { | 2407 if (shouldTrackInitialValues(instruction)) { |
| 2404 int argumentIndex = 0; | 2408 int argumentIndex = 0; |
| 2405 compiler.codegenWorldBuilder.forEachInstanceField(instruction.element, | 2409 compiler.codegenWorldBuilder.forEachInstanceField(instruction.element, |
| 2406 (_, FieldEntity member) { | 2410 (_, FieldEntity member) { |
| 2407 if (compiler.elementHasCompileTimeError( | 2411 if (compiler.elementHasCompileTimeError( |
| 2408 // ignore: UNNECESSARY_CAST | 2412 // ignore: UNNECESSARY_CAST |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2475 } else { | 2479 } else { |
| 2476 memorySet.registerFieldValue(element, null, instruction); | 2480 memorySet.registerFieldValue(element, null, instruction); |
| 2477 } | 2481 } |
| 2478 } | 2482 } |
| 2479 | 2483 |
| 2480 void visitStatic(HStatic instruction) { | 2484 void visitStatic(HStatic instruction) { |
| 2481 handleStaticLoad(instruction.element, instruction); | 2485 handleStaticLoad(instruction.element, instruction); |
| 2482 } | 2486 } |
| 2483 | 2487 |
| 2484 void visitStaticStore(HStaticStore instruction) { | 2488 void visitStaticStore(HStaticStore instruction) { |
| 2485 memorySet.registerFieldValueUpdate( | 2489 if (memorySet.registerFieldValueUpdate( |
| 2486 instruction.element, null, instruction.inputs.last); | 2490 instruction.element, null, instruction.inputs.last)) { |
| 2491 instruction.block.remove(instruction); | |
| 2492 } | |
| 2487 } | 2493 } |
| 2488 | 2494 |
| 2489 void visitLiteralList(HLiteralList instruction) { | 2495 void visitLiteralList(HLiteralList instruction) { |
| 2490 memorySet.registerAllocation(instruction); | 2496 memorySet.registerAllocation(instruction); |
| 2491 memorySet.killAffectedBy(instruction); | 2497 memorySet.killAffectedBy(instruction); |
| 2492 // TODO(sra): Set initial keyed values. | 2498 // TODO(sra): Set initial keyed values. |
| 2493 // TODO(sra): Set initial length. | 2499 // TODO(sra): Set initial length. |
| 2494 } | 2500 } |
| 2495 | 2501 |
| 2496 void visitIndex(HIndex instruction) { | 2502 void visitIndex(HIndex instruction) { |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2606 return !nonEscapingReceivers.contains(receiver); | 2612 return !nonEscapingReceivers.contains(receiver); |
| 2607 } | 2613 } |
| 2608 | 2614 |
| 2609 void registerAllocation(HInstruction instruction) { | 2615 void registerAllocation(HInstruction instruction) { |
| 2610 assert(instruction == instruction.nonCheck()); | 2616 assert(instruction == instruction.nonCheck()); |
| 2611 nonEscapingReceivers.add(instruction); | 2617 nonEscapingReceivers.add(instruction); |
| 2612 } | 2618 } |
| 2613 | 2619 |
| 2614 /** | 2620 /** |
| 2615 * Sets `receiver.element` to contain [value]. Kills all potential places that | 2621 * Sets `receiver.element` to contain [value]. Kills all potential places that |
| 2616 * may be affected by this update. | 2622 * may be affected by this update. Returns `true` if the update is redundant. |
| 2617 */ | 2623 */ |
| 2618 void registerFieldValueUpdate( | 2624 bool registerFieldValueUpdate( |
| 2619 MemberEntity element, HInstruction receiver, HInstruction value) { | 2625 MemberEntity element, HInstruction receiver, HInstruction value) { |
| 2620 assert(receiver == null || receiver == receiver.nonCheck()); | 2626 assert(receiver == null || receiver == receiver.nonCheck()); |
| 2621 if (closedWorld.nativeData.isNativeMember(element)) { | 2627 if (closedWorld.nativeData.isNativeMember(element)) { |
| 2622 return; // TODO(14955): Remove this restriction? | 2628 return false; // TODO(14955): Remove this restriction? |
| 2623 } | 2629 } |
| 2624 // [value] is being set in some place in memory, we remove it from | 2630 // [value] is being set in some place in memory, we remove it from the |
| 2625 // the non-escaping set. | 2631 // non-escaping set. |
| 2626 nonEscapingReceivers.remove(value.nonCheck()); | 2632 nonEscapingReceivers.remove(value.nonCheck()); |
|
Siggi Cherem (dart-lang)
2017/04/28 22:22:38
if the assignments is redundant, would the kill he
sra1
2017/04/28 23:25:24
I would expect so, but it is not worth skipping.
I
| |
| 2627 Map<HInstruction, HInstruction> map = | 2633 Map<HInstruction, HInstruction> map = |
| 2628 fieldValues.putIfAbsent(element, () => <HInstruction, HInstruction>{}); | 2634 fieldValues.putIfAbsent(element, () => <HInstruction, HInstruction>{}); |
| 2635 bool isRedundant = map[receiver] == value; | |
| 2629 map.forEach((key, value) { | 2636 map.forEach((key, value) { |
| 2630 if (mayAlias(receiver, key)) map[key] = null; | 2637 if (mayAlias(receiver, key)) map[key] = null; |
| 2631 }); | 2638 }); |
| 2632 map[receiver] = value; | 2639 map[receiver] = value; |
| 2640 return isRedundant; | |
| 2633 } | 2641 } |
| 2634 | 2642 |
| 2635 /** | 2643 /** |
| 2636 * Registers that `receiver.element` is now [value]. | 2644 * Registers that `receiver.element` is now [value]. |
| 2637 */ | 2645 */ |
| 2638 void registerFieldValue( | 2646 void registerFieldValue( |
| 2639 MemberEntity element, HInstruction receiver, HInstruction value) { | 2647 MemberEntity element, HInstruction receiver, HInstruction value) { |
| 2640 assert(receiver == null || receiver == receiver.nonCheck()); | 2648 assert(receiver == null || receiver == receiver.nonCheck()); |
| 2641 if (closedWorld.nativeData.isNativeMember(element)) { | 2649 if (closedWorld.nativeData.isNativeMember(element)) { |
| 2642 return; // TODO(14955): Remove this restriction? | 2650 return; // TODO(14955): Remove this restriction? |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2857 | 2865 |
| 2858 keyedValues.forEach((receiver, values) { | 2866 keyedValues.forEach((receiver, values) { |
| 2859 result.keyedValues[receiver] = | 2867 result.keyedValues[receiver] = |
| 2860 new Map<HInstruction, HInstruction>.from(values); | 2868 new Map<HInstruction, HInstruction>.from(values); |
| 2861 }); | 2869 }); |
| 2862 | 2870 |
| 2863 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2871 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
| 2864 return result; | 2872 return result; |
| 2865 } | 2873 } |
| 2866 } | 2874 } |
| OLD | NEW |