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

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

Issue 206553002: Prevent hoisting of certain check nodes, including [HTypeKnown]. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: take selector of type conversion into account in GVN 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 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 return instruction is HGoto 1236 return instruction is HGoto
1237 || instruction.inputs[0].isConstantTrue(); 1237 || instruction.inputs[0].isConstantTrue();
1238 } 1238 }
1239 bool firstInstructionInLoop = block == loopHeader 1239 bool firstInstructionInLoop = block == loopHeader
1240 // Compensate for lack of code motion. 1240 // Compensate for lack of code motion.
1241 || (blockChangesFlags[loopHeader.id] == 0 1241 || (blockChangesFlags[loopHeader.id] == 0
1242 && isLoopAlwaysTaken() 1242 && isLoopAlwaysTaken()
1243 && loopHeader.successors[0] == block); 1243 && loopHeader.successors[0] == block);
1244 while (instruction != null) { 1244 while (instruction != null) {
1245 HInstruction next = instruction.next; 1245 HInstruction next = instruction.next;
1246 if (instruction.useGvn() 1246 if (instruction.useGvn() && instruction.isMovable
1247 && (!instruction.canThrow() || firstInstructionInLoop) 1247 && (!instruction.canThrow() || firstInstructionInLoop)
1248 && !instruction.sideEffects.dependsOn(dependsFlags)) { 1248 && !instruction.sideEffects.dependsOn(dependsFlags)) {
1249 bool loopInvariantInputs = true; 1249 bool loopInvariantInputs = true;
1250 List<HInstruction> inputs = instruction.inputs; 1250 List<HInstruction> inputs = instruction.inputs;
1251 for (int i = 0, length = inputs.length; i < length; i++) { 1251 for (int i = 0, length = inputs.length; i < length; i++) {
1252 if (isInputDefinedAfterDominator(inputs[i], preheader)) { 1252 if (isInputDefinedAfterDominator(inputs[i], preheader)) {
1253 loopInvariantInputs = false; 1253 loopInvariantInputs = false;
1254 break; 1254 break;
1255 } 1255 }
1256 } 1256 }
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 // which instructions can be moved to a dominator block. 1458 // which instructions can be moved to a dominator block.
1459 ValueSet set_ = values[block.id]; 1459 ValueSet set_ = values[block.id];
1460 HInstruction instruction = block.first; 1460 HInstruction instruction = block.first;
1461 int flags = 0; 1461 int flags = 0;
1462 while (instruction != null) { 1462 while (instruction != null) {
1463 int dependsFlags = SideEffects.computeDependsOnFlags(flags); 1463 int dependsFlags = SideEffects.computeDependsOnFlags(flags);
1464 flags |= instruction.sideEffects.getChangesFlags(); 1464 flags |= instruction.sideEffects.getChangesFlags();
1465 1465
1466 HInstruction current = instruction; 1466 HInstruction current = instruction;
1467 instruction = instruction.next; 1467 instruction = instruction.next;
1468 1468 if (!current.useGvn() || !current.isMovable) continue;
1469 // TODO(ngeoffray): this check is needed because we currently do
1470 // not have flags to express 'Gvn'able', but not movable.
1471 if (current is HCheck) continue;
1472 if (!current.useGvn()) continue;
1473 if (current.sideEffects.dependsOn(dependsFlags)) continue; 1469 if (current.sideEffects.dependsOn(dependsFlags)) continue;
1474 1470
1475 bool canBeMoved = true; 1471 bool canBeMoved = true;
1476 for (final HInstruction input in current.inputs) { 1472 for (final HInstruction input in current.inputs) {
1477 if (input.block == block) { 1473 if (input.block == block) {
1478 canBeMoved = false; 1474 canBeMoved = false;
1479 break; 1475 break;
1480 } 1476 }
1481 } 1477 }
1482 if (!canBeMoved) continue; 1478 if (!canBeMoved) continue;
(...skipping 14 matching lines...) Expand all
1497 final String name = "SsaTypeconversionInserter"; 1493 final String name = "SsaTypeconversionInserter";
1498 final Compiler compiler; 1494 final Compiler compiler;
1499 1495
1500 SsaTypeConversionInserter(this.compiler); 1496 SsaTypeConversionInserter(this.compiler);
1501 1497
1502 void visitGraph(HGraph graph) { 1498 void visitGraph(HGraph graph) {
1503 visitDominatorTree(graph); 1499 visitDominatorTree(graph);
1504 } 1500 }
1505 1501
1506 // Update users of [input] that are dominated by [:dominator.first:] 1502 // Update users of [input] that are dominated by [:dominator.first:]
1507 // to use [newInput] instead. 1503 // to use [TypeKnown] of [input] instead. As the type information depends
1508 void changeUsesDominatedBy(HBasicBlock dominator, 1504 // on the control flow, we mark the inserted [HTypeKnown] nodes as
1509 HInstruction input, 1505 // non-movable.
1510 TypeMask convertedType) { 1506 void insertTypePropagationForDominatedUsers(HBasicBlock dominator,
1507 HInstruction input,
1508 TypeMask convertedType) {
1511 Setlet<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first); 1509 Setlet<HInstruction> dominatedUsers = input.dominatedUsers(dominator.first);
1512 if (dominatedUsers.isEmpty) return; 1510 if (dominatedUsers.isEmpty) return;
1513 1511
1514 HTypeKnown newInput = new HTypeKnown(convertedType, input); 1512 HTypeKnown newInput = new HTypeKnown.pinned(convertedType, input);
1515 dominator.addBefore(dominator.first, newInput); 1513 dominator.addBefore(dominator.first, newInput);
1516 dominatedUsers.forEach((HInstruction user) { 1514 dominatedUsers.forEach((HInstruction user) {
1517 user.changeUse(input, newInput); 1515 user.changeUse(input, newInput);
1518 }); 1516 });
1519 } 1517 }
1520 1518
1521 void visitIs(HIs instruction) { 1519 void visitIs(HIs instruction) {
1522 DartType type = instruction.typeExpression; 1520 DartType type = instruction.typeExpression;
1523 Element element = type.element; 1521 Element element = type.element;
1524 if (!instruction.isRawCheck) { 1522 if (!instruction.isRawCheck) {
1525 return; 1523 return;
1526 } else if (element.isTypedef()) { 1524 } else if (element.isTypedef()) {
1527 return; 1525 return;
1528 } 1526 }
1529 1527
1530 List<HInstruction> ifUsers = <HInstruction>[]; 1528 List<HInstruction> ifUsers = <HInstruction>[];
1531 List<HInstruction> notIfUsers = <HInstruction>[]; 1529 List<HInstruction> notIfUsers = <HInstruction>[];
1532 1530
1533 collectIfUsers(instruction, ifUsers, notIfUsers); 1531 collectIfUsers(instruction, ifUsers, notIfUsers);
1534 1532
1535 if (ifUsers.isEmpty && notIfUsers.isEmpty) return; 1533 if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
1536 1534
1537 TypeMask convertedType = new TypeMask.nonNullSubtype(element); 1535 TypeMask convertedType = new TypeMask.nonNullSubtype(element);
1538 HInstruction input = instruction.expression; 1536 HInstruction input = instruction.expression;
1539 1537
1540 for (HIf ifUser in ifUsers) { 1538 for (HIf ifUser in ifUsers) {
1541 changeUsesDominatedBy(ifUser.thenBlock, input, convertedType); 1539 insertTypePropagationForDominatedUsers(ifUser.thenBlock, input,
1540 convertedType);
1542 // TODO(ngeoffray): Also change uses for the else block on a type 1541 // TODO(ngeoffray): Also change uses for the else block on a type
1543 // that knows it is not of a specific type. 1542 // that knows it is not of a specific type.
1544 } 1543 }
1545 for (HIf ifUser in notIfUsers) { 1544 for (HIf ifUser in notIfUsers) {
1546 changeUsesDominatedBy(ifUser.elseBlock, input, convertedType); 1545 insertTypePropagationForDominatedUsers(ifUser.elseBlock, input,
1546 convertedType);
1547 // TODO(ngeoffray): Also change uses for the then block on a type 1547 // TODO(ngeoffray): Also change uses for the then block on a type
1548 // that knows it is not of a specific type. 1548 // that knows it is not of a specific type.
1549 } 1549 }
1550 } 1550 }
1551 1551
1552 void visitIdentity(HIdentity instruction) { 1552 void visitIdentity(HIdentity instruction) {
1553 // At HIf(HIdentity(x, null)) strengthens x to non-null on else branch. 1553 // At HIf(HIdentity(x, null)) strengthens x to non-null on else branch.
1554 HInstruction left = instruction.left; 1554 HInstruction left = instruction.left;
1555 HInstruction right = instruction.right; 1555 HInstruction right = instruction.right;
1556 HInstruction input; 1556 HInstruction input;
(...skipping 11 matching lines...) Expand all
1568 List<HInstruction> ifUsers = <HInstruction>[]; 1568 List<HInstruction> ifUsers = <HInstruction>[];
1569 List<HInstruction> notIfUsers = <HInstruction>[]; 1569 List<HInstruction> notIfUsers = <HInstruction>[];
1570 1570
1571 collectIfUsers(instruction, ifUsers, notIfUsers); 1571 collectIfUsers(instruction, ifUsers, notIfUsers);
1572 1572
1573 if (ifUsers.isEmpty && notIfUsers.isEmpty) return; 1573 if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
1574 1574
1575 TypeMask nonNullType = input.instructionType.nonNullable(); 1575 TypeMask nonNullType = input.instructionType.nonNullable();
1576 1576
1577 for (HIf ifUser in ifUsers) { 1577 for (HIf ifUser in ifUsers) {
1578 changeUsesDominatedBy(ifUser.elseBlock, input, nonNullType); 1578 insertTypePropagationForDominatedUsers(ifUser.elseBlock, input,
1579 nonNullType);
1579 // Uses in thenBlock are `null`, but probably not common. 1580 // Uses in thenBlock are `null`, but probably not common.
1580 } 1581 }
1581 for (HIf ifUser in notIfUsers) { 1582 for (HIf ifUser in notIfUsers) {
1582 changeUsesDominatedBy(ifUser.thenBlock, input, nonNullType); 1583 insertTypePropagationForDominatedUsers(ifUser.thenBlock, input,
1584 nonNullType);
1583 // Uses in elseBlock are `null`, but probably not common. 1585 // Uses in elseBlock are `null`, but probably not common.
1584 } 1586 }
1585 } 1587 }
1586 1588
1587 collectIfUsers(HInstruction instruction, 1589 collectIfUsers(HInstruction instruction,
1588 List<HInstruction> ifUsers, 1590 List<HInstruction> ifUsers,
1589 List<HInstruction> notIfUsers) { 1591 List<HInstruction> notIfUsers) {
1590 for (HInstruction user in instruction.usedBy) { 1592 for (HInstruction user in instruction.usedBy) {
1591 if (user is HIf) { 1593 if (user is HIf) {
1592 ifUsers.add(user); 1594 ifUsers.add(user);
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
2031 2033
2032 keyedValues.forEach((receiver, values) { 2034 keyedValues.forEach((receiver, values) {
2033 result.keyedValues[receiver] = 2035 result.keyedValues[receiver] =
2034 new Map<HInstruction, HInstruction>.from(values); 2036 new Map<HInstruction, HInstruction>.from(values);
2035 }); 2037 });
2036 2038
2037 result.nonEscapingReceivers.addAll(nonEscapingReceivers); 2039 result.nonEscapingReceivers.addAll(nonEscapingReceivers);
2038 return result; 2040 return result;
2039 } 2041 }
2040 } 2042 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698