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

Side by Side Diff: pkg/compiler/lib/src/ssa/codegen_helpers.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
OLDNEW
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 '../compiler.dart' show Compiler; 5 import '../compiler.dart' show Compiler;
6 import '../constants/values.dart'; 6 import '../constants/values.dart';
7 import '../elements/elements.dart'; 7 import '../elements/elements.dart';
8 import '../js_backend/js_backend.dart'; 8 import '../js_backend/js_backend.dart';
9 import '../types/types.dart'; 9 import '../types/types.dart';
10 import '../universe/selector.dart' show Selector; 10 import '../universe/selector.dart' show Selector;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 } 60 }
61 61
62 HInstruction visitInstruction(HInstruction node) { 62 HInstruction visitInstruction(HInstruction node) {
63 return node; 63 return node;
64 } 64 }
65 65
66 HInstruction visitIs(HIs node) { 66 HInstruction visitIs(HIs node) {
67 if (node.kind == HIs.RAW_CHECK) { 67 if (node.kind == HIs.RAW_CHECK) {
68 HInstruction interceptor = node.interceptor; 68 HInstruction interceptor = node.interceptor;
69 if (interceptor != null) { 69 if (interceptor != null) {
70 return new HIsViaInterceptor(node.typeExpression, interceptor, 70 return new HIsViaInterceptor(
71 backend.boolType); 71 node.typeExpression, interceptor, backend.boolType);
72 } 72 }
73 } 73 }
74 return node; 74 return node;
75 } 75 }
76 76
77 HInstruction visitIdentity(HIdentity node) { 77 HInstruction visitIdentity(HIdentity node) {
78 node.singleComparisonOp = simpleOp(node.left, node.right); 78 node.singleComparisonOp = simpleOp(node.left, node.right);
79 return node; 79 return node;
80 } 80 }
81 81
82 String simpleOp(HInstruction left, HInstruction right) { 82 String simpleOp(HInstruction left, HInstruction right) {
83 // Returns the single identity comparison (== or ===) or null if a more 83 // Returns the single identity comparison (== or ===) or null if a more
84 // complex expression is required. 84 // complex expression is required.
85 TypeMask leftType = left.instructionType; 85 TypeMask leftType = left.instructionType;
86 TypeMask rightType = right.instructionType; 86 TypeMask rightType = right.instructionType;
87 if (leftType.isNullable && rightType.isNullable) { 87 if (leftType.isNullable && rightType.isNullable) {
88 if (left.isConstantNull() || 88 if (left.isConstantNull() ||
89 right.isConstantNull() || 89 right.isConstantNull() ||
90 (left.isPrimitive(compiler) && 90 (left.isPrimitive(compiler) && leftType == rightType)) {
91 leftType == rightType)) {
92 return '=='; 91 return '==';
93 } 92 }
94 return null; 93 return null;
95 } 94 }
96 return '==='; 95 return '===';
97 } 96 }
98 97
99 HInstruction visitInvokeDynamic(HInvokeDynamic node) { 98 HInstruction visitInvokeDynamic(HInvokeDynamic node) {
100 if (node.isInterceptedCall) { 99 if (node.isInterceptedCall) {
101 // Calls of the form 100 // Calls of the form
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 HInstruction left = binary.left; 185 HInstruction left = binary.left;
187 HInstruction right = binary.right; 186 HInstruction right = binary.right;
188 if (isMatchingRead(left)) { 187 if (isMatchingRead(left)) {
189 if (left.usedBy.length == 1) { 188 if (left.usedBy.length == 1) {
190 if (right is HConstant && right.constant.isOne) { 189 if (right is HConstant && right.constant.isOne) {
191 HInstruction rmw = new HReadModifyWrite.preOp( 190 HInstruction rmw = new HReadModifyWrite.preOp(
192 setter.element, incrementOp, receiver, op.instructionType); 191 setter.element, incrementOp, receiver, op.instructionType);
193 return replaceOp(rmw, left); 192 return replaceOp(rmw, left);
194 } else { 193 } else {
195 HInstruction rmw = new HReadModifyWrite.assignOp( 194 HInstruction rmw = new HReadModifyWrite.assignOp(
196 setter.element, 195 setter.element, assignOp, receiver, right, op.instructionType);
197 assignOp,
198 receiver, right, op.instructionType);
199 return replaceOp(rmw, left); 196 return replaceOp(rmw, left);
200 } 197 }
201 } else if (op.usedBy.length == 1 && 198 } else if (op.usedBy.length == 1 &&
202 right is HConstant && 199 right is HConstant &&
203 right.constant.isOne) { 200 right.constant.isOne) {
204 HInstruction rmw = new HReadModifyWrite.postOp( 201 HInstruction rmw = new HReadModifyWrite.postOp(
205 setter.element, incrementOp, receiver, op.instructionType); 202 setter.element, incrementOp, receiver, op.instructionType);
206 block.addAfter(left, rmw); 203 block.addAfter(left, rmw);
207 block.remove(setter); 204 block.remove(setter);
208 block.remove(op); 205 block.remove(op);
209 block.rewrite(left, rmw); 206 block.rewrite(left, rmw);
210 block.remove(left); 207 block.remove(left);
211 return null; 208 return null;
212 } 209 }
213 } 210 }
214 return noMatchingRead(); 211 return noMatchingRead();
215 } 212 }
216 213
217 HInstruction simple(String assignOp, 214 HInstruction simple(
218 HInstruction left, HInstruction right) { 215 String assignOp, HInstruction left, HInstruction right) {
219 if (isMatchingRead(left)) { 216 if (isMatchingRead(left)) {
220 if (left.usedBy.length == 1) { 217 if (left.usedBy.length == 1) {
221 HInstruction rmw = new HReadModifyWrite.assignOp( 218 HInstruction rmw = new HReadModifyWrite.assignOp(
222 setter.element, 219 setter.element, assignOp, receiver, right, op.instructionType);
223 assignOp,
224 receiver, right, op.instructionType);
225 return replaceOp(rmw, left); 220 return replaceOp(rmw, left);
226 } 221 }
227 } 222 }
228 return noMatchingRead(); 223 return noMatchingRead();
229 } 224 }
230 225
231 HInstruction simpleBinary(String assignOp) { 226 HInstruction simpleBinary(String assignOp) {
232 HInvokeBinary binary = op; 227 HInvokeBinary binary = op;
233 return simple(assignOp, binary.left, binary.right); 228 return simple(assignOp, binary.left, binary.right);
234 } 229 }
(...skipping 19 matching lines...) Expand all
254 249
255 return noMatchingRead(); 250 return noMatchingRead();
256 } 251 }
257 } 252 }
258 253
259 /** 254 /**
260 * Remove [HTypeKnown] instructions from the graph, to make codegen 255 * Remove [HTypeKnown] instructions from the graph, to make codegen
261 * analysis easier. 256 * analysis easier.
262 */ 257 */
263 class SsaTypeKnownRemover extends HBaseVisitor { 258 class SsaTypeKnownRemover extends HBaseVisitor {
264
265 void visitGraph(HGraph graph) { 259 void visitGraph(HGraph graph) {
266 visitDominatorTree(graph); 260 visitDominatorTree(graph);
267 } 261 }
268 262
269 void visitBasicBlock(HBasicBlock block) { 263 void visitBasicBlock(HBasicBlock block) {
270 HInstruction instruction = block.first; 264 HInstruction instruction = block.first;
271 while (instruction != null) { 265 while (instruction != null) {
272 HInstruction next = instruction.next; 266 HInstruction next = instruction.next;
273 instruction.accept(this); 267 instruction.accept(this);
274 instruction = next; 268 instruction = next;
275 } 269 }
276 } 270 }
277 271
278 void visitTypeKnown(HTypeKnown instruction) { 272 void visitTypeKnown(HTypeKnown instruction) {
279 instruction.block.rewrite(instruction, instruction.checkedInput); 273 instruction.block.rewrite(instruction, instruction.checkedInput);
280 instruction.block.remove(instruction); 274 instruction.block.remove(instruction);
281 } 275 }
282 } 276 }
283 277
284 /** 278 /**
285 * Remove [HTypeConversion] instructions from the graph in '--trust-primitives' 279 * Remove [HTypeConversion] instructions from the graph in '--trust-primitives'
286 * mode. 280 * mode.
287 */ 281 */
288 class SsaTrustedCheckRemover extends HBaseVisitor { 282 class SsaTrustedCheckRemover extends HBaseVisitor {
289
290 Compiler compiler; 283 Compiler compiler;
291 SsaTrustedCheckRemover(this.compiler); 284 SsaTrustedCheckRemover(this.compiler);
292 285
293 void visitGraph(HGraph graph) { 286 void visitGraph(HGraph graph) {
294 if (!compiler.options.trustPrimitives) return; 287 if (!compiler.options.trustPrimitives) return;
295 visitDominatorTree(graph); 288 visitDominatorTree(graph);
296 } 289 }
297 290
298 void visitBasicBlock(HBasicBlock block) { 291 void visitBasicBlock(HBasicBlock block) {
299 HInstruction instruction = block.first; 292 HInstruction instruction = block.first;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 JavaScriptBackend get backend => compiler.backend; 340 JavaScriptBackend get backend => compiler.backend;
348 341
349 void visitGraph(HGraph graph) { 342 void visitGraph(HGraph graph) {
350 visitDominatorTree(graph); 343 visitDominatorTree(graph);
351 } 344 }
352 345
353 void analyzeInputs(HInstruction user, int start) { 346 void analyzeInputs(HInstruction user, int start) {
354 List<HInstruction> inputs = user.inputs; 347 List<HInstruction> inputs = user.inputs;
355 for (int i = start; i < inputs.length; i++) { 348 for (int i = start; i < inputs.length; i++) {
356 HInstruction input = inputs[i]; 349 HInstruction input = inputs[i];
357 if (!generateAtUseSite.contains(input) 350 if (!generateAtUseSite.contains(input) &&
358 && !input.isCodeMotionInvariant() 351 !input.isCodeMotionInvariant() &&
359 && input.usedBy.length == 1 352 input.usedBy.length == 1 &&
360 && input is !HPhi 353 input is! HPhi &&
361 && input is !HLocalValue 354 input is! HLocalValue &&
362 && !input.isJsStatement()) { 355 !input.isJsStatement()) {
363 if (input.isPure()) { 356 if (input.isPure()) {
364 // Only consider a pure input if it is in the same loop. 357 // Only consider a pure input if it is in the same loop.
365 // Otherwise, we might move GVN'ed instruction back into the 358 // Otherwise, we might move GVN'ed instruction back into the
366 // loop. 359 // loop.
367 if (user.hasSameLoopHeaderAs(input)) { 360 if (user.hasSameLoopHeaderAs(input)) {
368 // Move it closer to [user], so that instructions in 361 // Move it closer to [user], so that instructions in
369 // between do not prevent making it generate at use site. 362 // between do not prevent making it generate at use site.
370 input.moveBefore(user); 363 input.moveBefore(user);
371 pureInputs.add(input); 364 pureInputs.add(input);
372 // Previous computations done on [input] are now invalid 365 // Previous computations done on [input] are now invalid
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 // does not require an expression with multiple uses (because of null / 427 // does not require an expression with multiple uses (because of null /
435 // undefined). 428 // undefined).
436 void visitIdentity(HIdentity instruction) { 429 void visitIdentity(HIdentity instruction) {
437 if (instruction.singleComparisonOp != null) { 430 if (instruction.singleComparisonOp != null) {
438 super.visitIdentity(instruction); 431 super.visitIdentity(instruction);
439 } 432 }
440 // Do nothing. 433 // Do nothing.
441 } 434 }
442 435
443 void visitTypeConversion(HTypeConversion instruction) { 436 void visitTypeConversion(HTypeConversion instruction) {
444 if (!instruction.isArgumentTypeCheck 437 if (!instruction.isArgumentTypeCheck && !instruction.isReceiverTypeCheck) {
445 && !instruction.isReceiverTypeCheck) {
446 assert(instruction.isCheckedModeCheck || instruction.isCastTypeCheck); 438 assert(instruction.isCheckedModeCheck || instruction.isCastTypeCheck);
447 // Checked mode checks and cast checks compile to code that 439 // Checked mode checks and cast checks compile to code that
448 // only use their input once, so we can safely visit them 440 // only use their input once, so we can safely visit them
449 // and try to merge the input. 441 // and try to merge the input.
450 visitInstruction(instruction); 442 visitInstruction(instruction);
451 } 443 }
452 } 444 }
453 445
454 void visitTypeKnown(HTypeKnown instruction) { 446 void visitTypeKnown(HTypeKnown instruction) {
455 // [HTypeKnown] instructions are removed before code generation. 447 // [HTypeKnown] instructions are removed before code generation.
456 assert(false); 448 assert(false);
457 } 449 }
458 450
459 void tryGenerateAtUseSite(HInstruction instruction) { 451 void tryGenerateAtUseSite(HInstruction instruction) {
460 if (instruction.isControlFlow()) return; 452 if (instruction.isControlFlow()) return;
461 markAsGenerateAtUseSite(instruction); 453 markAsGenerateAtUseSite(instruction);
462 } 454 }
463 455
464 bool isBlockSinglePredecessor(HBasicBlock block) { 456 bool isBlockSinglePredecessor(HBasicBlock block) {
465 return block.successors.length == 1 457 return block.successors.length == 1 &&
466 && block.successors[0].predecessors.length == 1; 458 block.successors[0].predecessors.length == 1;
467 } 459 }
468 460
469 void visitBasicBlock(HBasicBlock block) { 461 void visitBasicBlock(HBasicBlock block) {
470 // Compensate from not merging blocks: if the block is the 462 // Compensate from not merging blocks: if the block is the
471 // single predecessor of its single successor, let the successor 463 // single predecessor of its single successor, let the successor
472 // visit it. 464 // visit it.
473 if (isBlockSinglePredecessor(block)) return; 465 if (isBlockSinglePredecessor(block)) return;
474 466
475 tryMergingExpressions(block); 467 tryMergingExpressions(block);
476 } 468 }
(...skipping 19 matching lines...) Expand all
496 assert(nextInput.usedBy.length == 1); 488 assert(nextInput.usedBy.length == 1);
497 if (identical(nextInput, instruction)) { 489 if (identical(nextInput, instruction)) {
498 return true; 490 return true;
499 } 491 }
500 } 492 }
501 return false; 493 return false;
502 } 494 }
503 495
504 block.last.accept(this); 496 block.last.accept(this);
505 for (HInstruction instruction = block.last.previous; 497 for (HInstruction instruction = block.last.previous;
506 instruction != null; 498 instruction != null;
507 instruction = instruction.previous) { 499 instruction = instruction.previous) {
508 if (generateAtUseSite.contains(instruction)) { 500 if (generateAtUseSite.contains(instruction)) {
509 continue; 501 continue;
510 } 502 }
511 if (instruction.isCodeMotionInvariant()) { 503 if (instruction.isCodeMotionInvariant()) {
512 markAsGenerateAtUseSite(instruction); 504 markAsGenerateAtUseSite(instruction);
513 continue; 505 continue;
514 } 506 }
515 if (instruction.isPure()) { 507 if (instruction.isPure()) {
516 if (pureInputs.contains(instruction)) { 508 if (pureInputs.contains(instruction)) {
517 tryGenerateAtUseSite(instruction); 509 tryGenerateAtUseSite(instruction);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 // The current instruction is the next non-trivial 570 // The current instruction is the next non-trivial
579 // expected input. 571 // expected input.
580 tryGenerateAtUseSite(instruction); 572 tryGenerateAtUseSite(instruction);
581 } else { 573 } else {
582 assert(expectedInputs.isEmpty); 574 assert(expectedInputs.isEmpty);
583 } 575 }
584 instruction.accept(this); 576 instruction.accept(this);
585 } 577 }
586 } 578 }
587 579
588 if (block.predecessors.length == 1 580 if (block.predecessors.length == 1 &&
589 && isBlockSinglePredecessor(block.predecessors[0])) { 581 isBlockSinglePredecessor(block.predecessors[0])) {
590 assert(block.phis.isEmpty); 582 assert(block.phis.isEmpty);
591 tryMergingExpressions(block.predecessors[0]); 583 tryMergingExpressions(block.predecessors[0]);
592 } else { 584 } else {
593 expectedInputs = null; 585 expectedInputs = null;
594 pureInputs = null; 586 pureInputs = null;
595 } 587 }
596 } 588 }
597 } 589 }
598 590
599 /** 591 /**
(...skipping 23 matching lines...) Expand all
623 bool hasAnyStatement(HBasicBlock block, HInstruction instruction) { 615 bool hasAnyStatement(HBasicBlock block, HInstruction instruction) {
624 // If [instruction] is not in [block], then if the block is not 616 // If [instruction] is not in [block], then if the block is not
625 // empty, we know there will be a statement to emit. 617 // empty, we know there will be a statement to emit.
626 if (!identical(instruction.block, block)) { 618 if (!identical(instruction.block, block)) {
627 return !identical(block.last, block.first); 619 return !identical(block.last, block.first);
628 } 620 }
629 621
630 // If [instruction] is not the last instruction of the block 622 // If [instruction] is not the last instruction of the block
631 // before the control flow instruction, or the last instruction, 623 // before the control flow instruction, or the last instruction,
632 // then we will have to emit a statement for that last instruction. 624 // then we will have to emit a statement for that last instruction.
633 if (instruction != block.last 625 if (instruction != block.last &&
634 && !identical(instruction, block.last.previous)) return true; 626 !identical(instruction, block.last.previous)) return true;
635 627
636 // If one of the instructions in the block until [instruction] is 628 // If one of the instructions in the block until [instruction] is
637 // not generated at use site, then we will have to emit a 629 // not generated at use site, then we will have to emit a
638 // statement for it. 630 // statement for it.
639 // TODO(ngeoffray): we could generate a comma separated 631 // TODO(ngeoffray): we could generate a comma separated
640 // list of expressions. 632 // list of expressions.
641 for (HInstruction temp = block.first; 633 for (HInstruction temp = block.first;
642 !identical(temp, instruction); 634 !identical(temp, instruction);
643 temp = temp.next) { 635 temp = temp.next) {
644 if (!generateAtUseSite.contains(temp)) return true; 636 if (!generateAtUseSite.contains(temp)) return true;
645 } 637 }
646 638
647 return false; 639 return false;
648 } 640 }
649 641
650 bool isSafeToGenerateAtUseSite(HInstruction user, HInstruction input) { 642 bool isSafeToGenerateAtUseSite(HInstruction user, HInstruction input) {
651 // HForeignNew evaluates arguments in order and passes them to a 643 // HForeignNew evaluates arguments in order and passes them to a
652 // constructor. 644 // constructor.
653 if (user is HForeignNew) return true; 645 if (user is HForeignNew) return true;
654 // A [HForeign] instruction uses operators and if we generate 646 // A [HForeign] instruction uses operators and if we generate
655 // [input] at use site, the precedence might be wrong. 647 // [input] at use site, the precedence might be wrong.
656 if (user is HForeign) return false; 648 if (user is HForeign) return false;
657 // A [HCheck] instruction with control flow uses its input 649 // A [HCheck] instruction with control flow uses its input
658 // multiple times, so we avoid generating it at use site. 650 // multiple times, so we avoid generating it at use site.
659 if (user is HCheck && user.isControlFlow()) return false; 651 if (user is HCheck && user.isControlFlow()) return false;
660 // A [HIs] instruction uses its input multiple times, so we 652 // A [HIs] instruction uses its input multiple times, so we
661 // avoid generating it at use site. 653 // avoid generating it at use site.
662 if (user is HIs) return false; 654 if (user is HIs) return false;
663 return true; 655 return true;
664 } 656 }
665 657
666 void visitBasicBlock(HBasicBlock block) { 658 void visitBasicBlock(HBasicBlock block) {
667 if (block.last is !HIf) return; 659 if (block.last is! HIf) return;
668 HIf startIf = block.last; 660 HIf startIf = block.last;
669 HBasicBlock end = startIf.joinBlock; 661 HBasicBlock end = startIf.joinBlock;
670 662
671 // We check that the structure is the following: 663 // We check that the structure is the following:
672 // If 664 // If
673 // / \ 665 // / \
674 // / \ 666 // / \
675 // 1 expr goto 667 // 1 expr goto
676 // goto / 668 // goto /
677 // \ / 669 // \ /
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 739
748 // Find the next non-HGoto instruction following the phi. 740 // Find the next non-HGoto instruction following the phi.
749 HInstruction nextInstruction = phi.block.first; 741 HInstruction nextInstruction = phi.block.first;
750 while (nextInstruction is HGoto) { 742 while (nextInstruction is HGoto) {
751 nextInstruction = nextInstruction.block.successors[0].first; 743 nextInstruction = nextInstruction.block.successors[0].first;
752 } 744 }
753 745
754 // If the operation is only used by the first instruction 746 // If the operation is only used by the first instruction
755 // of its block and is safe to be generated at use site, mark it 747 // of its block and is safe to be generated at use site, mark it
756 // so. 748 // so.
757 if (phi.usedBy.length == 1 749 if (phi.usedBy.length == 1 &&
758 && phi.usedBy[0] == nextInstruction 750 phi.usedBy[0] == nextInstruction &&
759 && isSafeToGenerateAtUseSite(phi.usedBy[0], phi)) { 751 isSafeToGenerateAtUseSite(phi.usedBy[0], phi)) {
760 markAsGenerateAtUseSite(phi); 752 markAsGenerateAtUseSite(phi);
761 } 753 }
762 754
763 if (identical(elseInput.block, elseBlock)) { 755 if (identical(elseInput.block, elseBlock)) {
764 assert(elseInput.usedBy.length == 1); 756 assert(elseInput.usedBy.length == 1);
765 markAsGenerateAtUseSite(elseInput); 757 markAsGenerateAtUseSite(elseInput);
766 } 758 }
767 759
768 // If [thenInput] is defined in the first predecessor, then it is only used 760 // If [thenInput] is defined in the first predecessor, then it is only used
769 // by [phi] and can be generated at use site. 761 // by [phi] and can be generated at use site.
770 if (identical(thenInput.block, end.predecessors[0])) { 762 if (identical(thenInput.block, end.predecessors[0])) {
771 assert(thenInput.usedBy.length == 1); 763 assert(thenInput.usedBy.length == 1);
772 markAsGenerateAtUseSite(thenInput); 764 markAsGenerateAtUseSite(thenInput);
773 } 765 }
774 } 766 }
775 } 767 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/codegen.dart ('k') | pkg/compiler/lib/src/ssa/interceptor_simplifier.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698