| Index: lib/compiler/implementation/ssa/bailout.dart
|
| diff --git a/lib/compiler/implementation/ssa/bailout.dart b/lib/compiler/implementation/ssa/bailout.dart
|
| index dcc64081ebc7df3f00dbfc8ae180aba2690a5e86..daf0e3018276fed4e59747d9d8d0f69fe2795e37 100644
|
| --- a/lib/compiler/implementation/ssa/bailout.dart
|
| +++ b/lib/compiler/implementation/ssa/bailout.dart
|
| @@ -111,6 +111,27 @@ class SsaTypeGuardInserter extends HGraphVisitor implements OptimizationPhase {
|
| }
|
| }
|
|
|
| + bool typeGuardWouldBeValuable(HInstruction instruction,
|
| + HType speculativeType) {
|
| + bool isNested(HBasicBlock inner, HBasicBlock outer) {
|
| + if (inner === outer) return false;
|
| + if (outer === null) return true;
|
| + while (inner !== null) {
|
| + if (inner === outer) return true;
|
| + inner = inner.parentLoopHeader;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + // If the instruction is not in a loop then the header will be null.
|
| + HBasicBlock currentLoopHeader = instruction.block.enclosingLoopHeader;
|
| + for (HInstruction user in instruction.usedBy) {
|
| + HBasicBlock userLoopHeader = user.block.enclosingLoopHeader;
|
| + if (isNested(userLoopHeader, currentLoopHeader)) return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| bool shouldInsertTypeGuard(HInstruction instruction) {
|
| HType speculativeType = instruction.propagatedType;
|
| HType computedType = instruction.computeTypeFromInputTypes();
|
| @@ -128,8 +149,9 @@ class SsaTypeGuardInserter extends HGraphVisitor implements OptimizationPhase {
|
| if (!speculativeType.isUseful()) return false;
|
| // If the types agree we don't need to check.
|
| if (speculativeType == computedType) return false;
|
| - // TODO(floitsch): Make the creation of type guards more conditional.
|
| - return true;
|
| + // If a bailout check is more expensive than doing the actual operation
|
| + // don't do it either.
|
| + return typeGuardWouldBeValuable(instruction, speculativeType);
|
| }
|
|
|
| void visitInstruction(HInstruction instruction) {
|
|
|