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

Side by Side Diff: pkg/compiler/lib/src/ssa/optimize.dart

Issue 2438543004: Improve condition strengthening for last test in short-circuit. (Closed)
Patch Set: fix assert Created 4 years, 2 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 5 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
6 import '../common/names.dart' show Selectors; 6 import '../common/names.dart' show Selectors;
7 import '../common/tasks.dart' show CompilerTask; 7 import '../common/tasks.dart' show CompilerTask;
8 import '../compiler.dart' show Compiler; 8 import '../compiler.dart' show Compiler;
9 import '../constants/constant_system.dart'; 9 import '../constants/constant_system.dart';
10 import '../constants/values.dart'; 10 import '../constants/values.dart';
(...skipping 2092 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 2103
2104 void visitIs(HIs instruction) { 2104 void visitIs(HIs instruction) {
2105 DartType type = instruction.typeExpression; 2105 DartType type = instruction.typeExpression;
2106 Element element = type.element; 2106 Element element = type.element;
2107 if (!instruction.isRawCheck) { 2107 if (!instruction.isRawCheck) {
2108 return; 2108 return;
2109 } else if (element.isTypedef) { 2109 } else if (element.isTypedef) {
2110 return; 2110 return;
2111 } 2111 }
2112 2112
2113 List<HInstruction> ifUsers = <HInstruction>[]; 2113 List<HBasicBlock> trueTargets = <HBasicBlock>[];
2114 List<HInstruction> notIfUsers = <HInstruction>[]; 2114 List<HBasicBlock> falseTargets = <HBasicBlock>[];
2115 2115
2116 collectIfUsers(instruction, ifUsers, notIfUsers); 2116 collectTargets(instruction, trueTargets, falseTargets);
2117 2117
2118 if (ifUsers.isEmpty && notIfUsers.isEmpty) return; 2118 if (trueTargets.isEmpty && falseTargets.isEmpty) return;
2119 2119
2120 TypeMask convertedType = 2120 TypeMask convertedType =
2121 new TypeMask.nonNullSubtype(element, compiler.closedWorld); 2121 new TypeMask.nonNullSubtype(element, compiler.closedWorld);
2122 HInstruction input = instruction.expression; 2122 HInstruction input = instruction.expression;
2123 2123
2124 for (HIf ifUser in ifUsers) { 2124 for (HBasicBlock block in trueTargets) {
2125 insertTypePropagationForDominatedUsers( 2125 insertTypePropagationForDominatedUsers(block, input, convertedType);
2126 ifUser.thenBlock, input, convertedType);
2127 // TODO(ngeoffray): Also change uses for the else block on a type
2128 // that knows it is not of a specific type.
2129 } 2126 }
2130 for (HIf ifUser in notIfUsers) { 2127 // TODO(sra): Also strengthen uses for when the condition is known
2131 insertTypePropagationForDominatedUsers( 2128 // false. Avoid strengthening to `null`.
2132 ifUser.elseBlock, input, convertedType);
2133 // TODO(ngeoffray): Also change uses for the then block on a type
2134 // that knows it is not of a specific type.
2135 }
2136 } 2129 }
2137 2130
2138 void visitIdentity(HIdentity instruction) { 2131 void visitIdentity(HIdentity instruction) {
2139 // At HIf(HIdentity(x, null)) strengthens x to non-null on else branch. 2132 // At HIf(HIdentity(x, null)) strengthens x to non-null on else branch.
2140 HInstruction left = instruction.left; 2133 HInstruction left = instruction.left;
2141 HInstruction right = instruction.right; 2134 HInstruction right = instruction.right;
2142 HInstruction input; 2135 HInstruction input;
2143 2136
2144 if (left.isConstantNull()) { 2137 if (left.isConstantNull()) {
2145 input = right; 2138 input = right;
2146 } else if (right.isConstantNull()) { 2139 } else if (right.isConstantNull()) {
2147 input = left; 2140 input = left;
2148 } else { 2141 } else {
2149 return; 2142 return;
2150 } 2143 }
2151 2144
2152 if (!input.instructionType.isNullable) return; 2145 if (!input.instructionType.isNullable) return;
2153 2146
2154 List<HInstruction> ifUsers = <HInstruction>[]; 2147 List<HBasicBlock> trueTargets = <HBasicBlock>[];
2155 List<HInstruction> notIfUsers = <HInstruction>[]; 2148 List<HBasicBlock> falseTargets = <HBasicBlock>[];
2156 2149
2157 collectIfUsers(instruction, ifUsers, notIfUsers); 2150 collectTargets(instruction, trueTargets, falseTargets);
2158 2151
2159 if (ifUsers.isEmpty && notIfUsers.isEmpty) return; 2152 if (trueTargets.isEmpty && falseTargets.isEmpty) return;
2160 2153
2161 TypeMask nonNullType = input.instructionType.nonNullable(); 2154 TypeMask nonNullType = input.instructionType.nonNullable();
2162 2155
2163 for (HIf ifUser in ifUsers) { 2156 for (HBasicBlock block in falseTargets) {
2164 insertTypePropagationForDominatedUsers( 2157 insertTypePropagationForDominatedUsers(block, input, nonNullType);
2165 ifUser.elseBlock, input, nonNullType);
2166 // Uses in thenBlock are `null`, but probably not common.
2167 } 2158 }
2168 for (HIf ifUser in notIfUsers) { 2159 // We don't strengthen the known-true references. It doesn't happen often
2169 insertTypePropagationForDominatedUsers( 2160 // and we don't want "if (x==null) return x;" to convert between JavaScript
2170 ifUser.thenBlock, input, nonNullType); 2161 // 'null' and 'undefined'.
2171 // Uses in elseBlock are `null`, but probably not common.
2172 }
2173 } 2162 }
2174 2163
2175 collectIfUsers(HInstruction instruction, List<HInstruction> ifUsers, 2164 collectTargets(HInstruction instruction, List<HBasicBlock> trueTargets,
2176 List<HInstruction> notIfUsers) { 2165 List<HBasicBlock> falseTargets) {
2177 for (HInstruction user in instruction.usedBy) { 2166 for (HInstruction user in instruction.usedBy) {
2178 if (user is HIf) { 2167 if (user is HIf) {
2179 ifUsers.add(user); 2168 trueTargets?.add(user.thenBlock);
2169 falseTargets?.add(user.elseBlock);
2180 } else if (user is HNot) { 2170 } else if (user is HNot) {
2181 collectIfUsers(user, notIfUsers, ifUsers); 2171 collectTargets(user, falseTargets, trueTargets);
2172 } else if (user is HPhi) {
2173 List<HInstruction> inputs = user.inputs;
2174 if (inputs.length == 2) {
2175 assert(inputs.contains(instruction));
2176 HInstruction other = inputs[(inputs[0] == instruction) ? 1 : 0];
2177 if (other.isConstantTrue()) {
2178 // The condition flows to a HPhi(true, user), which means that a
2179 // downstream HIf has true-branch control flow that does not depend
2180 // on the original instruction, so stop collecting [trueTargets].
2181 collectTargets(user, null, falseTargets);
2182 } else if (other.isConstantFalse()) {
2183 // Ditto for false.
2184 collectTargets(user, trueTargets, null);
2185 }
2186 }
2187 } else if (user is HBoolify) {
2188 // We collect targets for strictly boolean operations so HBoolify cannot
2189 // change the result.
2190 collectTargets(user, trueTargets, falseTargets);
2182 } 2191 }
2183 } 2192 }
2184 } 2193 }
2185 } 2194 }
2186 2195
2187 /** 2196 /**
2188 * Optimization phase that tries to eliminate memory loads (for 2197 * Optimization phase that tries to eliminate memory loads (for
2189 * example [HFieldGet]), when it knows the value stored in that memory 2198 * example [HFieldGet]), when it knows the value stored in that memory
2190 * location. 2199 * location.
2191 */ 2200 */
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
2709 2718
2710 keyedValues.forEach((receiver, values) { 2719 keyedValues.forEach((receiver, values) {
2711 result.keyedValues[receiver] = 2720 result.keyedValues[receiver] =
2712 new Map<HInstruction, HInstruction>.from(values); 2721 new Map<HInstruction, HInstruction>.from(values);
2713 }); 2722 });
2714 2723
2715 result.nonEscapingReceivers.addAll(nonEscapingReceivers); 2724 result.nonEscapingReceivers.addAll(nonEscapingReceivers);
2716 return result; 2725 return result;
2717 } 2726 }
2718 } 2727 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698