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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart

Issue 199873004: Prevent hoisting of certain check nodes, including [HTypeKnow (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Don't move canThrow instructions Created 6 years, 9 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 | Annotate | Revision Log
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 part of ssa; 5 part of ssa;
6 6
7 abstract class OptimizationPhase { 7 abstract class OptimizationPhase {
8 String get name; 8 String get name;
9 void visitGraph(HGraph graph); 9 void visitGraph(HGraph graph);
10 } 10 }
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 return instruction is HGoto 1294 return instruction is HGoto
1295 || instruction.inputs[0].isConstantTrue(); 1295 || instruction.inputs[0].isConstantTrue();
1296 } 1296 }
1297 bool firstInstructionInLoop = block == loopHeader 1297 bool firstInstructionInLoop = block == loopHeader
1298 // Compensate for lack of code motion. 1298 // Compensate for lack of code motion.
1299 || (blockChangesFlags[loopHeader.id] == 0 1299 || (blockChangesFlags[loopHeader.id] == 0
1300 && isLoopAlwaysTaken() 1300 && isLoopAlwaysTaken()
1301 && loopHeader.successors[0] == block); 1301 && loopHeader.successors[0] == block);
1302 while (instruction != null) { 1302 while (instruction != null) {
1303 HInstruction next = instruction.next; 1303 HInstruction next = instruction.next;
1304 if (instruction.useGvn() 1304 if (instruction.useGvn() && instruction.isMovable
1305 && (!instruction.canThrow() || firstInstructionInLoop) 1305 && (!instruction.canThrow() || firstInstructionInLoop)
1306 && !instruction.sideEffects.dependsOn(dependsFlags)) { 1306 && !instruction.sideEffects.dependsOn(dependsFlags)) {
1307 bool loopInvariantInputs = true; 1307 bool loopInvariantInputs = true;
1308 List<HInstruction> inputs = instruction.inputs; 1308 List<HInstruction> inputs = instruction.inputs;
1309 for (int i = 0, length = inputs.length; i < length; i++) { 1309 for (int i = 0, length = inputs.length; i < length; i++) {
1310 if (isInputDefinedAfterDominator(inputs[i], preheader)) { 1310 if (isInputDefinedAfterDominator(inputs[i], preheader)) {
1311 loopInvariantInputs = false; 1311 loopInvariantInputs = false;
1312 break; 1312 break;
1313 } 1313 }
1314 } 1314 }
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 // which instructions can be moved to a dominator block. 1516 // which instructions can be moved to a dominator block.
1517 ValueSet set_ = values[block.id]; 1517 ValueSet set_ = values[block.id];
1518 HInstruction instruction = block.first; 1518 HInstruction instruction = block.first;
1519 int flags = 0; 1519 int flags = 0;
1520 while (instruction != null) { 1520 while (instruction != null) {
1521 int dependsFlags = SideEffects.computeDependsOnFlags(flags); 1521 int dependsFlags = SideEffects.computeDependsOnFlags(flags);
1522 flags |= instruction.sideEffects.getChangesFlags(); 1522 flags |= instruction.sideEffects.getChangesFlags();
1523 1523
1524 HInstruction current = instruction; 1524 HInstruction current = instruction;
1525 instruction = instruction.next; 1525 instruction = instruction.next;
1526 1526 if (!current.useGvn() || !current.isMovable) continue;
1527 // TODO(ngeoffray): this check is needed because we currently do 1527 // TODO(sra): We could move throwing instructions provided we keep the
1528 // not have flags to express 'Gvn'able', but not movable. 1528 // exceptions in the same order. This requires they are in the same order
1529 if (current is HCheck) continue; 1529 // in all successors, which is not tracked by the ValueSet.
1530 if (!current.useGvn()) continue; 1530 if (current.canThrow()) continue;
1531 if (current.sideEffects.dependsOn(dependsFlags)) continue; 1531 if (current.sideEffects.dependsOn(dependsFlags)) continue;
1532 1532
1533 bool canBeMoved = true; 1533 bool canBeMoved = true;
1534 for (final HInstruction input in current.inputs) { 1534 for (final HInstruction input in current.inputs) {
1535 if (input.block == block) { 1535 if (input.block == block) {
1536 canBeMoved = false; 1536 canBeMoved = false;
1537 break; 1537 break;
1538 } 1538 }
1539 } 1539 }
1540 if (!canBeMoved) continue; 1540 if (!canBeMoved) continue;
(...skipping 14 matching lines...) Expand all
1555 final String name = "SsaTypeconversionInserter"; 1555 final String name = "SsaTypeconversionInserter";
1556 final Compiler compiler; 1556 final Compiler compiler;
1557 1557
1558 SsaTypeConversionInserter(this.compiler); 1558 SsaTypeConversionInserter(this.compiler);
1559 1559
1560 void visitGraph(HGraph graph) { 1560 void visitGraph(HGraph graph) {
1561 visitDominatorTree(graph); 1561 visitDominatorTree(graph);
1562 } 1562 }
1563 1563
1564 // Update users of [input] that are dominated by [:dominator.first:] 1564 // Update users of [input] that are dominated by [:dominator.first:]
1565 // to use [newInput] instead. 1565 // to use [TypeKnown] of [input] instead. As the type information depends
1566 void changeUsesDominatedBy(HBasicBlock dominator, 1566 // on the control flow, we mark the inserted [HTypeKnown] nodes as
1567 HInstruction input, 1567 // non-movable.
1568 TypeMask convertedType) { 1568 void insertTypePropagationForDominatedUsers(HBasicBlock dominator,
1569 HInstruction input,
1570 TypeMask convertedType) {
1569 Setlet<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first); 1571 Setlet<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first);
1570 if (dominatedUsers.isEmpty) return; 1572 if (dominatedUsers.isEmpty) return;
1571 1573
1572 HTypeKnown newInput = new HTypeKnown(convertedType, input); 1574 HTypeKnown newInput = new HTypeKnown.pinned(convertedType, input);
1573 dominator.addBefore(dominator.first, newInput); 1575 dominator.addBefore(dominator.first, newInput);
1574 dominatedUsers.forEach((HInstruction user) { 1576 dominatedUsers.forEach((HInstruction user) {
1575 user.changeUse(input, newInput); 1577 user.changeUse(input, newInput);
1576 }); 1578 });
1577 } 1579 }
1578 1580
1579 void visitIs(HIs instruction) { 1581 void visitIs(HIs instruction) {
1580 DartType type = instruction.typeExpression; 1582 DartType type = instruction.typeExpression;
1581 Element element = type.element; 1583 Element element = type.element;
1582 if (!instruction.isRawCheck) { 1584 if (!instruction.isRawCheck) {
1583 return; 1585 return;
1584 } else if (element.isTypedef()) { 1586 } else if (element.isTypedef()) {
1585 return; 1587 return;
1586 } 1588 }
1587 1589
1588 List<HInstruction> ifUsers = <HInstruction>[]; 1590 List<HInstruction> ifUsers = <HInstruction>[];
1589 List<HInstruction> notIfUsers = <HInstruction>[]; 1591 List<HInstruction> notIfUsers = <HInstruction>[];
1590 1592
1591 collectIfUsers(instruction, ifUsers, notIfUsers); 1593 collectIfUsers(instruction, ifUsers, notIfUsers);
1592 1594
1593 if (ifUsers.isEmpty && notIfUsers.isEmpty) return; 1595 if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
1594 1596
1595 TypeMask convertedType = new TypeMask.nonNullSubtype(element); 1597 TypeMask convertedType = new TypeMask.nonNullSubtype(element);
1596 HInstruction input = instruction.expression; 1598 HInstruction input = instruction.expression;
1597 1599
1598 for (HIf ifUser in ifUsers) { 1600 for (HIf ifUser in ifUsers) {
1599 changeUsesDominatedBy(ifUser.thenBlock, input, convertedType); 1601 insertTypePropagationForDominatedUsers(ifUser.thenBlock, input,
1602 convertedType);
1600 // TODO(ngeoffray): Also change uses for the else block on a type 1603 // TODO(ngeoffray): Also change uses for the else block on a type
1601 // that knows it is not of a specific type. 1604 // that knows it is not of a specific type.
1602 } 1605 }
1603 for (HIf ifUser in notIfUsers) { 1606 for (HIf ifUser in notIfUsers) {
1604 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); 1607 insertTypePropagationForDominatedUsers(ifUser.elseBlock, input,
1608 convertedType);
1605 // TODO(ngeoffray): Also change uses for the then block on a type 1609 // TODO(ngeoffray): Also change uses for the then block on a type
1606 // that knows it is not of a specific type. 1610 // that knows it is not of a specific type.
1607 } 1611 }
1608 } 1612 }
1609 1613
1610 void visitIdentity(HIdentity instruction) { 1614 void visitIdentity(HIdentity instruction) {
1611 // At HIf(HIdentity(x, null)) strengthens x to non-null on else branch. 1615 // At HIf(HIdentity(x, null)) strengthens x to non-null on else branch.
1612 HInstruction left = instruction.left; 1616 HInstruction left = instruction.left;
1613 HInstruction right = instruction.right; 1617 HInstruction right = instruction.right;
1614 HInstruction input; 1618 HInstruction input;
(...skipping 11 matching lines...) Expand all
1626 List<HInstruction> ifUsers = <HInstruction>[]; 1630 List<HInstruction> ifUsers = <HInstruction>[];
1627 List<HInstruction> notIfUsers = <HInstruction>[]; 1631 List<HInstruction> notIfUsers = <HInstruction>[];
1628 1632
1629 collectIfUsers(instruction, ifUsers, notIfUsers); 1633 collectIfUsers(instruction, ifUsers, notIfUsers);
1630 1634
1631 if (ifUsers.isEmpty && notIfUsers.isEmpty) return; 1635 if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
1632 1636
1633 TypeMask nonNullType = input.instructionType.nonNullable(); 1637 TypeMask nonNullType = input.instructionType.nonNullable();
1634 1638
1635 for (HIf ifUser in ifUsers) { 1639 for (HIf ifUser in ifUsers) {
1636 changeUsesDominatedBy(ifUser.elseBlock, input, nonNullType); 1640 insertTypePropagationForDominatedUsers(ifUser.elseBlock, input,
1641 nonNullType);
1637 // Uses in thenBlock are `null`, but probably not common. 1642 // Uses in thenBlock are `null`, but probably not common.
1638 } 1643 }
1639 for (HIf ifUser in notIfUsers) { 1644 for (HIf ifUser in notIfUsers) {
1640 changeUsesDominatedBy(ifUser.thenBlock, input, nonNullType); 1645 insertTypePropagationForDominatedUsers(ifUser.thenBlock, input,
1646 nonNullType);
1641 // Uses in elseBlock are `null`, but probably not common. 1647 // Uses in elseBlock are `null`, but probably not common.
1642 } 1648 }
1643 } 1649 }
1644 1650
1645 collectIfUsers(HInstruction instruction, 1651 collectIfUsers(HInstruction instruction,
1646 List<HInstruction> ifUsers, 1652 List<HInstruction> ifUsers,
1647 List<HInstruction> notIfUsers) { 1653 List<HInstruction> notIfUsers) {
1648 for (HInstruction user in instruction.usedBy) { 1654 for (HInstruction user in instruction.usedBy) {
1649 if (user is HIf) { 1655 if (user is HIf) {
1650 ifUsers.add(user); 1656 ifUsers.add(user);
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
2089 2095
2090 keyedValues.forEach((receiver, values) { 2096 keyedValues.forEach((receiver, values) {
2091 result.keyedValues[receiver] = 2097 result.keyedValues[receiver] =
2092 new Map<HInstruction, HInstruction>.from(values); 2098 new Map<HInstruction, HInstruction>.from(values);
2093 }); 2099 });
2094 2100
2095 result.nonEscapingReceivers.addAll(nonEscapingReceivers); 2101 result.nonEscapingReceivers.addAll(nonEscapingReceivers);
2096 return result; 2102 return result;
2097 } 2103 }
2098 } 2104 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698