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

Unified Diff: pkg/compiler/lib/src/ssa/optimize.dart

Issue 1343783002: dart2js ssa: Avoid tracking too much in load elimination (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/ssa/nodes.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/ssa/optimize.dart
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index eeb12c5e0ad154d4b5c420457318d9b917424894..cb0318362417e0d38d9acea196e443eadf794362 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -1961,17 +1961,57 @@ class SsaLoadElimination extends HBaseVisitor implements OptimizationPhase {
void visitForeignNew(HForeignNew instruction) {
memorySet.registerAllocation(instruction);
- int argumentIndex = 0;
- instruction.element.forEachInstanceField((_, Element member) {
- if (compiler.elementHasCompileTimeError(member)) return;
- memorySet.registerFieldValue(
- member, instruction, instruction.inputs[argumentIndex++]);
- }, includeSuperAndInjectedMembers: true);
+ if (shouldTrackInitialValues(instruction)) {
+ int argumentIndex = 0;
+ instruction.element.forEachInstanceField((_, Element member) {
+ if (compiler.elementHasCompileTimeError(member)) return;
+ memorySet.registerFieldValue(
+ member, instruction, instruction.inputs[argumentIndex++]);
+ }, includeSuperAndInjectedMembers: true);
+ }
// In case this instruction has as input non-escaping objects, we
// need to mark these objects as escaping.
memorySet.killAffectedBy(instruction);
}
+ bool shouldTrackInitialValues(HForeignNew instruction) {
+ // Don't track initial field values of an allocation that are
+ // unprofitable. We search the chain of single uses in allocations for a
+ // limited depth.
+
+ const MAX_HEAP_DEPTH = 5;
+
+ bool interestingUse(HInstruction instruction, int heapDepth) {
+ // Heuristic: if the allocation is too deep in heap it is unlikely we will
+ // recover a field by load-elimination.
+ // TODO(sra): We can measure this depth by looking at load chains.
+ if (heapDepth == MAX_HEAP_DEPTH) return false;
+ // There are multiple uses so do the full store analysis.
+ if (instruction.usedBy.length != 1) return true;
+ HInstruction use = instruction.usedBy.single;
+ // When the only use is an allocation, the allocation becomes the only
+ // heap alias for the current instruction.
+ if (use is HForeignNew) return interestingUse(use, heapDepth + 1);
+ if (use is HLiteralList) return interestingUse(use, heapDepth + 1);
+ if (use is HInvokeStatic) {
+ // Assume the argument escapes. All we do with our initial allocation is
+ // have it escape or store it into an object that escapes.
+ return false;
+ // TODO(sra): Handle more functions. `setRuntimeTypeInfo` does not
+ // actually kill it's input, but we don't make use of that elsewhere so
+ // there is not point in checking here.
+ }
+ if (use is HPhi) {
+ // The initial allocation (it's only alias) gets merged out of the model
+ // of the heap before load.
+ return false;
+ }
+ return true;
+ }
+
+ return interestingUse(instruction, 0);
+ }
+
void visitInstruction(HInstruction instruction) {
if (instruction.isAllocation) {
memorySet.registerAllocation(instruction);
« no previous file with comments | « pkg/compiler/lib/src/ssa/nodes.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698