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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/gvn.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/finalize.dart ('k') | pkg/compiler/lib/src/cps_ir/inline.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 library dart2js.cps_ir.gvn; 5 library dart2js.cps_ir.gvn;
6 6
7 import 'cps_ir_nodes.dart'; 7 import 'cps_ir_nodes.dart';
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import 'optimizers.dart' show Pass; 9 import 'optimizers.dart' show Pass;
10 import 'loop_hierarchy.dart'; 10 import 'loop_hierarchy.dart';
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // ------------------ GLOBAL VALUE NUMBERING --------------------- 88 // ------------------ GLOBAL VALUE NUMBERING ---------------------
89 89
90 /// True if [prim] can be eliminated if its value is already in scope. 90 /// True if [prim] can be eliminated if its value is already in scope.
91 bool canReplaceWithExistingValue(Primitive prim) { 91 bool canReplaceWithExistingValue(Primitive prim) {
92 // Primitives that have no side effects other than potentially throwing are 92 // Primitives that have no side effects other than potentially throwing are
93 // known not the throw if the value is already in scope. Handling those 93 // known not the throw if the value is already in scope. Handling those
94 // specially is equivalent to updating refinements during GVN. 94 // specially is equivalent to updating refinements during GVN.
95 // GetLazyStatic cannot have side effects because the field has already 95 // GetLazyStatic cannot have side effects because the field has already
96 // been initialized. 96 // been initialized.
97 return prim.isSafeForElimination || 97 return prim.isSafeForElimination ||
98 prim is GetField || 98 prim is GetField ||
99 prim is GetLength || 99 prim is GetLength ||
100 prim is GetIndex || 100 prim is GetIndex ||
101 prim is GetLazyStatic; 101 prim is GetLazyStatic;
102 } 102 }
103 103
104 @override 104 @override
105 Expression traverseLetPrim(LetPrim node) { 105 Expression traverseLetPrim(LetPrim node) {
106 Expression next = node.body; 106 Expression next = node.body;
107 Primitive prim = node.primitive; 107 Primitive prim = node.primitive;
108 108
109 loopHeaderFor[prim] = currentLoopHeader; 109 loopHeaderFor[prim] = currentLoopHeader;
110 110
111 if (prim is Refinement) { 111 if (prim is Refinement) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 143
144 // Try to reuse a previously computed value with the same GVN. 144 // Try to reuse a previously computed value with the same GVN.
145 Primitive existing = environment[gvn]; 145 Primitive existing = environment[gvn];
146 if (existing != null && 146 if (existing != null &&
147 canReplaceWithExistingValue(prim) && 147 canReplaceWithExistingValue(prim) &&
148 !isFastConstant(prim)) { 148 !isFastConstant(prim)) {
149 if (prim is Interceptor) { 149 if (prim is Interceptor) {
150 Interceptor interceptor = existing; 150 Interceptor interceptor = existing;
151 interceptor.interceptedClasses.addAll(prim.interceptedClasses); 151 interceptor.interceptedClasses.addAll(prim.interceptedClasses);
152 } 152 }
153 prim..replaceUsesWith(existing)..destroy(); 153 prim
154 ..replaceUsesWith(existing)
155 ..destroy();
154 node.remove(); 156 node.remove();
155 return next; 157 return next;
156 } 158 }
157 159
158 if (tryToHoistOutOfLoop(prim, gvn)) { 160 if (tryToHoistOutOfLoop(prim, gvn)) {
159 return next; 161 return next;
160 } 162 }
161 163
162 // The primitive could not be hoisted. Put the primitive in the 164 // The primitive could not be hoisted. Put the primitive in the
163 // environment while processing the body of the LetPrim. 165 // environment while processing the body of the LetPrim.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 }); 242 });
241 243
242 // Bail out if it can not be hoisted further out than it is now. 244 // Bail out if it can not be hoisted further out than it is now.
243 if (hoistDepth == loopHierarchy.getDepth(currentLoopHeader)) return false; 245 if (hoistDepth == loopHierarchy.getDepth(currentLoopHeader)) return false;
244 246
245 // Walk up the loop hierarchy and check at every step that any heap 247 // Walk up the loop hierarchy and check at every step that any heap
246 // dependencies can safely be hoisted out of the loop. 248 // dependencies can safely be hoisted out of the loop.
247 Continuation enclosingLoop = currentLoopHeader; 249 Continuation enclosingLoop = currentLoopHeader;
248 Continuation hoistTarget = null; 250 Continuation hoistTarget = null;
249 while (loopHierarchy.getDepth(enclosingLoop) > hoistDepth && 251 while (loopHierarchy.getDepth(enclosingLoop) > hoistDepth &&
250 canHoistHeapDependencyOutOfLoop(prim, enclosingLoop)) { 252 canHoistHeapDependencyOutOfLoop(prim, enclosingLoop)) {
251 hoistTarget = enclosingLoop; 253 hoistTarget = enclosingLoop;
252 enclosingLoop = loopHierarchy.getEnclosingLoop(enclosingLoop); 254 enclosingLoop = loopHierarchy.getEnclosingLoop(enclosingLoop);
253 } 255 }
254 256
255 // Bail out if heap dependencies prohibit any hoisting at all. 257 // Bail out if heap dependencies prohibit any hoisting at all.
256 if (hoistTarget == null) return false; 258 if (hoistTarget == null) return false;
257 259
258 if (isFastConstant(prim)) { 260 if (isFastConstant(prim)) {
259 // The overhead from introducting a temporary might be greater than 261 // The overhead from introducting a temporary might be greater than
260 // the overhead of evaluating this primitive at every iteration. 262 // the overhead of evaluating this primitive at every iteration.
(...skipping 26 matching lines...) Expand all
287 if (loopHierarchy.getDepth(loop) <= target) break; 289 if (loopHierarchy.getDepth(loop) <= target) break;
288 Refinement refinement = input; 290 Refinement refinement = input;
289 input = refinement.value.definition; 291 input = refinement.value.definition;
290 } 292 }
291 ref.changeTo(input); 293 ref.changeTo(input);
292 }); 294 });
293 } 295 }
294 296
295 // Put the primitive in the environment while processing the loop. 297 // Put the primitive in the environment while processing the loop.
296 environment[gvn] = prim; 298 environment[gvn] = prim;
297 loopHoistedBindings 299 loopHoistedBindings.putIfAbsent(hoistTarget, () => <int>[]).add(gvn);
298 .putIfAbsent(hoistTarget, () => <int>[])
299 .add(gvn);
300 return true; 300 return true;
301 } 301 }
302 302
303 /// If the given primitive is a trivial primitive that should be hoisted 303 /// If the given primitive is a trivial primitive that should be hoisted
304 /// on-demand, hoist it and its dependent values above [loopBinding]. 304 /// on-demand, hoist it and its dependent values above [loopBinding].
305 void hoistTrivialPrimitive(Primitive prim, 305 void hoistTrivialPrimitive(
306 LetCont loopBinding, 306 Primitive prim, LetCont loopBinding, Continuation enclosingLoop) {
307 Continuation enclosingLoop) {
308 assert(isFastConstant(prim)); 307 assert(isFastConstant(prim));
309 308
310 // The primitive might already be bound in an outer scope. Do not relocate 309 // The primitive might already be bound in an outer scope. Do not relocate
311 // the primitive unless we are lifting it. For example; 310 // the primitive unless we are lifting it. For example;
312 // t1 = a + b 311 // t1 = a + b
313 // t2 = t1 + c 312 // t2 = t1 + c
314 // t3 = t1 * t2 313 // t3 = t1 * t2
315 // If it was decided that `t3` should be hoisted, `t1` will be seen twice by 314 // If it was decided that `t3` should be hoisted, `t1` will be seen twice by
316 // this method: by the direct reference and by reference through `t2`. 315 // this method: by the direct reference and by reference through `t2`.
317 // The second time it is seen, it will already have been moved. 316 // The second time it is seen, it will already have been moved.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 return _table.putIfAbsent(new GvnEntry(vector), _makeNewGvn); 431 return _table.putIfAbsent(new GvnEntry(vector), _makeNewGvn);
433 } 432 }
434 } 433 }
435 434
436 /// Wrapper around a [List] that compares for equality based on contents 435 /// Wrapper around a [List] that compares for equality based on contents
437 /// instead of object identity. 436 /// instead of object identity.
438 class GvnEntry { 437 class GvnEntry {
439 final List vector; 438 final List vector;
440 final int hashCode; 439 final int hashCode;
441 440
442 GvnEntry(List vector) : vector = vector, hashCode = computeHashCode(vector); 441 GvnEntry(List vector)
442 : vector = vector,
443 hashCode = computeHashCode(vector);
443 444
444 bool operator==(other) { 445 bool operator ==(other) {
445 if (other is! GvnEntry) return false; 446 if (other is! GvnEntry) return false;
446 GvnEntry entry = other; 447 GvnEntry entry = other;
447 List otherVector = entry.vector; 448 List otherVector = entry.vector;
448 if (vector.length != otherVector.length) return false; 449 if (vector.length != otherVector.length) return false;
449 for (int i = 0; i < vector.length; ++i) { 450 for (int i = 0; i < vector.length; ++i) {
450 if (vector[i] != otherVector[i]) return false; 451 if (vector[i] != otherVector[i]) return false;
451 } 452 }
452 return true; 453 return true;
453 } 454 }
454 455
455 /// Combines the hash codes of [vector] using Jenkin's hash function, with 456 /// Combines the hash codes of [vector] using Jenkin's hash function, with
456 /// intermediate results truncated to SMI range. 457 /// intermediate results truncated to SMI range.
457 static int computeHashCode(List vector) { 458 static int computeHashCode(List vector) {
458 int hash = 0; 459 int hash = 0;
459 for (int i = 0; i < vector.length; ++i) { 460 for (int i = 0; i < vector.length; ++i) {
460 hash = 0x1fffffff & (hash + vector[i].hashCode); 461 hash = 0x1fffffff & (hash + vector[i].hashCode);
461 hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); 462 hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
462 hash = hash ^ (hash >> 6); 463 hash = hash ^ (hash >> 6);
463 } 464 }
464 hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); 465 hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
465 hash = hash ^ (hash >> 11); 466 hash = hash ^ (hash >> 11);
466 return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); 467 return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
467 } 468 }
468 } 469 }
469 470
470 /// Converts GVN'able primitives to a vector containing all the values 471 /// Converts GVN'able primitives to a vector containing all the values
471 /// to be considered when computing a GVN for it. 472 /// to be considered when computing a GVN for it.
472 /// 473 ///
473 /// This includes the instruction type, inputs, effect numbers for any part 474 /// This includes the instruction type, inputs, effect numbers for any part
474 /// of the heap being depended on, as well as any instruction-specific payload 475 /// of the heap being depended on, as well as any instruction-specific payload
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 static const int GET_INDEX = 6; 594 static const int GET_INDEX = 6;
594 static const int GET_STATIC = 7; 595 static const int GET_STATIC = 7;
595 static const int CONSTANT = 8; 596 static const int CONSTANT = 8;
596 static const int REIFY_RUNTIME_TYPE = 9; 597 static const int REIFY_RUNTIME_TYPE = 9;
597 static const int READ_TYPE_VARIABLE = 10; 598 static const int READ_TYPE_VARIABLE = 10;
598 static const int TYPE_EXPRESSION = 11; 599 static const int TYPE_EXPRESSION = 11;
599 static const int INTERCEPTOR = 12; 600 static const int INTERCEPTOR = 12;
600 } 601 }
601 602
602 typedef ReferenceCallback(Reference ref); 603 typedef ReferenceCallback(Reference ref);
604
603 class InputVisitor extends DeepRecursiveVisitor { 605 class InputVisitor extends DeepRecursiveVisitor {
604 ReferenceCallback callback; 606 ReferenceCallback callback;
605 607
606 InputVisitor(this.callback); 608 InputVisitor(this.callback);
607 609
608 @override 610 @override
609 processReference(Reference ref) { 611 processReference(Reference ref) {
610 callback(ref); 612 callback(ref);
611 } 613 }
612 614
613 static void forEach(Primitive node, ReferenceCallback callback) { 615 static void forEach(Primitive node, ReferenceCallback callback) {
614 new InputVisitor(callback).visit(node); 616 new InputVisitor(callback).visit(node);
615 } 617 }
616 } 618 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/finalize.dart ('k') | pkg/compiler/lib/src/cps_ir/inline.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698