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 abstract class HVisitor<R> { | 5 abstract class HVisitor<R> { |
6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
7 R visitBailoutTarget(HBailoutTarget node); | 7 R visitBailoutTarget(HBailoutTarget node); |
8 R visitBitAnd(HBitAnd node); | 8 R visitBitAnd(HBitAnd node); |
9 R visitBitNot(HBitNot node); | 9 R visitBitNot(HBitNot node); |
10 R visitBitOr(HBitOr node); | 10 R visitBitOr(HBitOr node); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 HInstruction last = end.last; | 358 HInstruction last = end.last; |
359 if (last is HConditionalBranch || last is HSwitch) return last.inputs[0]; | 359 if (last is HConditionalBranch || last is HSwitch) return last.inputs[0]; |
360 return null; | 360 return null; |
361 } | 361 } |
362 } | 362 } |
363 | 363 |
364 class HInstructionList { | 364 class HInstructionList { |
365 HInstruction first = null; | 365 HInstruction first = null; |
366 HInstruction last = null; | 366 HInstruction last = null; |
367 | 367 |
368 bool isEmpty() { | 368 bool get isEmpty { |
369 return first == null; | 369 return first == null; |
370 } | 370 } |
371 | 371 |
372 void addAfter(HInstruction cursor, HInstruction instruction) { | 372 void addAfter(HInstruction cursor, HInstruction instruction) { |
373 if (cursor == null) { | 373 if (cursor == null) { |
374 assert(isEmpty()); | 374 assert(isEmpty); |
375 first = last = instruction; | 375 first = last = instruction; |
376 } else if (identical(cursor, last)) { | 376 } else if (identical(cursor, last)) { |
377 last.next = instruction; | 377 last.next = instruction; |
378 instruction.previous = last; | 378 instruction.previous = last; |
379 last = instruction; | 379 last = instruction; |
380 } else { | 380 } else { |
381 instruction.previous = cursor; | 381 instruction.previous = cursor; |
382 instruction.next = cursor.next; | 382 instruction.next = cursor.next; |
383 cursor.next.previous = instruction; | 383 cursor.next.previous = instruction; |
384 cursor.next = instruction; | 384 cursor.next = instruction; |
385 } | 385 } |
386 } | 386 } |
387 | 387 |
388 void addBefore(HInstruction cursor, HInstruction instruction) { | 388 void addBefore(HInstruction cursor, HInstruction instruction) { |
389 if (cursor == null) { | 389 if (cursor == null) { |
390 assert(isEmpty()); | 390 assert(isEmpty); |
391 first = last = instruction; | 391 first = last = instruction; |
392 } else if (identical(cursor, first)) { | 392 } else if (identical(cursor, first)) { |
393 first.previous = instruction; | 393 first.previous = instruction; |
394 instruction.next = first; | 394 instruction.next = first; |
395 first = instruction; | 395 first = instruction; |
396 } else { | 396 } else { |
397 instruction.next = cursor; | 397 instruction.next = cursor; |
398 instruction.previous = cursor.previous; | 398 instruction.previous = cursor.previous; |
399 cursor.previous.next = instruction; | 399 cursor.previous.next = instruction; |
400 cursor.previous = instruction; | 400 cursor.previous = instruction; |
(...skipping 11 matching lines...) Expand all Loading... |
412 if (instruction.next == null) { | 412 if (instruction.next == null) { |
413 last = instruction.previous; | 413 last = instruction.previous; |
414 } else { | 414 } else { |
415 instruction.next.previous = instruction.previous; | 415 instruction.next.previous = instruction.previous; |
416 } | 416 } |
417 instruction.previous = null; | 417 instruction.previous = null; |
418 instruction.next = null; | 418 instruction.next = null; |
419 } | 419 } |
420 | 420 |
421 void remove(HInstruction instruction) { | 421 void remove(HInstruction instruction) { |
422 assert(instruction.usedBy.isEmpty()); | 422 assert(instruction.usedBy.isEmpty); |
423 detach(instruction); | 423 detach(instruction); |
424 } | 424 } |
425 | 425 |
426 /** Linear search for [instruction]. */ | 426 /** Linear search for [instruction]. */ |
427 bool contains(HInstruction instruction) { | 427 bool contains(HInstruction instruction) { |
428 HInstruction cursor = first; | 428 HInstruction cursor = first; |
429 while (cursor != null) { | 429 while (cursor != null) { |
430 if (identical(cursor, instruction)) return true; | 430 if (identical(cursor, instruction)) return true; |
431 cursor = cursor.next; | 431 cursor = cursor.next; |
432 } | 432 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 | 481 |
482 bool isLabeledBlock() => | 482 bool isLabeledBlock() => |
483 blockFlow != null && | 483 blockFlow != null && |
484 blockFlow.body is HLabeledBlockInformation; | 484 blockFlow.body is HLabeledBlockInformation; |
485 | 485 |
486 HBasicBlock get enclosingLoopHeader { | 486 HBasicBlock get enclosingLoopHeader { |
487 if (isLoopHeader()) return this; | 487 if (isLoopHeader()) return this; |
488 return parentLoopHeader; | 488 return parentLoopHeader; |
489 } | 489 } |
490 | 490 |
491 bool hasBailoutTargets() => !bailoutTargets.isEmpty(); | 491 bool hasBailoutTargets() => !bailoutTargets.isEmpty; |
492 | 492 |
493 void open() { | 493 void open() { |
494 assert(isNew()); | 494 assert(isNew()); |
495 status = STATUS_OPEN; | 495 status = STATUS_OPEN; |
496 } | 496 } |
497 | 497 |
498 void close(HControlFlow end) { | 498 void close(HControlFlow end) { |
499 assert(isOpen()); | 499 assert(isOpen()); |
500 addAfter(last, end); | 500 addAfter(last, end); |
501 status = STATUS_CLOSED; | 501 status = STATUS_CLOSED; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 | 574 |
575 void remove(HInstruction instruction) { | 575 void remove(HInstruction instruction) { |
576 assert(isOpen() || isClosed()); | 576 assert(isOpen() || isClosed()); |
577 assert(instruction is !HPhi); | 577 assert(instruction is !HPhi); |
578 super.remove(instruction); | 578 super.remove(instruction); |
579 assert(instruction.block == this); | 579 assert(instruction.block == this); |
580 instruction.notifyRemovedFromBlock(); | 580 instruction.notifyRemovedFromBlock(); |
581 } | 581 } |
582 | 582 |
583 void addSuccessor(HBasicBlock block) { | 583 void addSuccessor(HBasicBlock block) { |
584 if (successors.isEmpty()) { | 584 if (successors.isEmpty) { |
585 successors = [block]; | 585 successors = [block]; |
586 } else { | 586 } else { |
587 successors.add(block); | 587 successors.add(block); |
588 } | 588 } |
589 block.predecessors.add(this); | 589 block.predecessors.add(this); |
590 } | 590 } |
591 | 591 |
592 void postProcessLoopHeader() { | 592 void postProcessLoopHeader() { |
593 assert(isLoopHeader()); | 593 assert(isLoopHeader()); |
594 // Only the first entry into the loop is from outside the | 594 // Only the first entry into the loop is from outside the |
(...skipping 21 matching lines...) Expand all Loading... |
616 * information on [to], and that dominates the user. | 616 * information on [to], and that dominates the user. |
617 */ | 617 */ |
618 void rewriteWithBetterUser(HInstruction from, HInstruction to) { | 618 void rewriteWithBetterUser(HInstruction from, HInstruction to) { |
619 Link<HCheck> better = const Link<HCheck>(); | 619 Link<HCheck> better = const Link<HCheck>(); |
620 for (HInstruction user in to.usedBy) { | 620 for (HInstruction user in to.usedBy) { |
621 if (user is HCheck && identical((user as HCheck).checkedInput, to)) { | 621 if (user is HCheck && identical((user as HCheck).checkedInput, to)) { |
622 better = better.prepend(user); | 622 better = better.prepend(user); |
623 } | 623 } |
624 } | 624 } |
625 | 625 |
626 if (better.isEmpty()) return rewrite(from, to); | 626 if (better.isEmpty) return rewrite(from, to); |
627 | 627 |
628 L1: for (HInstruction user in from.usedBy) { | 628 L1: for (HInstruction user in from.usedBy) { |
629 for (HCheck check in better) { | 629 for (HCheck check in better) { |
630 if (check.dominates(user)) { | 630 if (check.dominates(user)) { |
631 user.rewriteInput(from, check); | 631 user.rewriteInput(from, check); |
632 check.usedBy.add(user); | 632 check.usedBy.add(user); |
633 continue L1; | 633 continue L1; |
634 } | 634 } |
635 } | 635 } |
636 user.rewriteInput(from, to); | 636 user.rewriteInput(from, to); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 for (int i = 0; i < inputs.length; i++) { | 978 for (int i = 0; i < inputs.length; i++) { |
979 assert(inputs[i].isInBasicBlock()); | 979 assert(inputs[i].isInBasicBlock()); |
980 inputs[i].usedBy.add(this); | 980 inputs[i].usedBy.add(this); |
981 } | 981 } |
982 block = targetBlock; | 982 block = targetBlock; |
983 assert(isValid()); | 983 assert(isValid()); |
984 } | 984 } |
985 | 985 |
986 void notifyRemovedFromBlock() { | 986 void notifyRemovedFromBlock() { |
987 assert(isInBasicBlock()); | 987 assert(isInBasicBlock()); |
988 assert(usedBy.isEmpty()); | 988 assert(usedBy.isEmpty); |
989 | 989 |
990 // Remove [this] from the inputs' uses. | 990 // Remove [this] from the inputs' uses. |
991 for (int i = 0; i < inputs.length; i++) { | 991 for (int i = 0; i < inputs.length; i++) { |
992 inputs[i].removeUser(this); | 992 inputs[i].removeUser(this); |
993 } | 993 } |
994 this.block = null; | 994 this.block = null; |
995 assert(isValid()); | 995 assert(isValid()); |
996 } | 996 } |
997 | 997 |
998 void rewriteInput(HInstruction from, HInstruction to) { | 998 void rewriteInput(HInstruction from, HInstruction to) { |
(...skipping 1968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2967 HSwitchBlockInformation(this.expression, | 2967 HSwitchBlockInformation(this.expression, |
2968 this.matchExpressions, | 2968 this.matchExpressions, |
2969 this.statements, | 2969 this.statements, |
2970 this.hasDefault, | 2970 this.hasDefault, |
2971 this.target, | 2971 this.target, |
2972 this.labels); | 2972 this.labels); |
2973 | 2973 |
2974 HBasicBlock get start => expression.start; | 2974 HBasicBlock get start => expression.start; |
2975 HBasicBlock get end { | 2975 HBasicBlock get end { |
2976 // We don't create a switch block if there are no cases. | 2976 // We don't create a switch block if there are no cases. |
2977 assert(!statements.isEmpty()); | 2977 assert(!statements.isEmpty); |
2978 return statements.last().end; | 2978 return statements.last().end; |
2979 } | 2979 } |
2980 | 2980 |
2981 bool accept(HStatementInformationVisitor visitor) => | 2981 bool accept(HStatementInformationVisitor visitor) => |
2982 visitor.visitSwitchInfo(this); | 2982 visitor.visitSwitchInfo(this); |
2983 } | 2983 } |
OLD | NEW |