Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 #include "vm/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1232 instantiator_type_arguments()->BindTo(null_constant); | 1232 instantiator_type_arguments()->BindTo(null_constant); |
| 1233 } | 1233 } |
| 1234 return this; | 1234 return this; |
| 1235 } | 1235 } |
| 1236 | 1236 |
| 1237 | 1237 |
| 1238 Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) { | 1238 Instruction* BranchInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| 1239 // Only handle strict-compares. | 1239 // Only handle strict-compares. |
| 1240 if (comparison()->IsStrictCompare()) { | 1240 if (comparison()->IsStrictCompare()) { |
| 1241 Definition* replacement = comparison()->Canonicalize(optimizer); | 1241 Definition* replacement = comparison()->Canonicalize(optimizer); |
| 1242 if (replacement == comparison() || replacement == NULL) return this; | 1242 if ((replacement == comparison()) || (replacement == NULL)) { |
| 1243 return this; | |
| 1244 } | |
| 1243 ComparisonInstr* comp = replacement->AsComparison(); | 1245 ComparisonInstr* comp = replacement->AsComparison(); |
| 1244 if ((comp == NULL) || comp->CanDeoptimize()) return this; | 1246 if ((comp == NULL) || comp->CanDeoptimize()) { |
| 1247 return this; | |
| 1248 } | |
| 1245 | 1249 |
| 1246 // Check that comparison is not serving as a pending deoptimization target | 1250 // Check that comparison is not serving as a pending deoptimization target |
| 1247 // for conversions. | 1251 // for conversions. |
| 1248 for (intptr_t i = 0; i < comp->InputCount(); i++) { | 1252 for (intptr_t i = 0; i < comp->InputCount(); i++) { |
| 1249 if (comp->RequiredInputRepresentation(i) != | 1253 if (comp->RequiredInputRepresentation(i) != |
| 1250 comp->InputAt(i)->definition()->representation()) { | 1254 comp->InputAt(i)->definition()->representation()) { |
| 1251 return this; | 1255 return this; |
| 1252 } | 1256 } |
| 1253 } | 1257 } |
| 1254 | 1258 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1267 ASSERT(comp->input_use_list() == NULL); | 1271 ASSERT(comp->input_use_list() == NULL); |
| 1268 comp->ClearSSATempIndex(); | 1272 comp->ClearSSATempIndex(); |
| 1269 comp->ClearTempIndex(); | 1273 comp->ClearTempIndex(); |
| 1270 } | 1274 } |
| 1271 } | 1275 } |
| 1272 return this; | 1276 return this; |
| 1273 } | 1277 } |
| 1274 | 1278 |
| 1275 | 1279 |
| 1276 Definition* StrictCompareInstr::Canonicalize(FlowGraphOptimizer* optimizer) { | 1280 Definition* StrictCompareInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| 1277 if (!right()->BindsToConstant()) return this; | 1281 if (!right()->BindsToConstant()) { |
| 1282 return this; | |
| 1283 } | |
| 1278 const Object& right_constant = right()->BoundConstant(); | 1284 const Object& right_constant = right()->BoundConstant(); |
| 1279 Definition* left_defn = left()->definition(); | 1285 Definition* left_defn = left()->definition(); |
| 1280 // TODO(fschneider): Handle other cases: e === false and e !== true/false. | 1286 // TODO(fschneider): Handle other cases: e === false and e !== true/false. |
| 1281 // Handles e === true. | 1287 // Handles e === true. |
| 1282 if ((kind() == Token::kEQ_STRICT) && | 1288 if ((kind() == Token::kEQ_STRICT) && |
| 1283 (right_constant.raw() == Bool::True().raw()) && | 1289 (right_constant.raw() == Bool::True().raw()) && |
| 1284 (left()->Type()->ToCid() == kBoolCid)) { | 1290 (left()->Type()->ToCid() == kBoolCid)) { |
| 1285 // Return left subexpression as the replacement for this instruction. | 1291 // Return left subexpression as the replacement for this instruction. |
| 1286 return left_defn; | 1292 return left_defn; |
| 1287 } | 1293 } |
| 1294 // x = (a === b); y = x !== true; -> y = a !== b. | |
|
Kevin Millikin (Google)
2013/03/26 12:48:31
Nit: extra space character in the comment.
Perhap
srdjan
2013/03/26 22:35:25
Done.
| |
| 1295 // In order to merge two strict comares, 'left_strict' must have only one use. | |
| 1296 StrictCompareInstr* left_strict = left_defn->AsStrictCompare(); | |
| 1297 if ((kind() == Token::kNE_STRICT) && | |
| 1298 (right_constant.raw() == Bool::True().raw()) && | |
| 1299 (left_strict != NULL) && | |
| 1300 (left_strict->input_use_list()->next_use() == NULL)) { | |
|
Kevin Millikin (Google)
2013/03/26 12:48:31
I suppose there should be not environment uses eit
srdjan
2013/03/26 22:35:25
Thanks!
| |
| 1301 Token::Kind negated_kind = Token::NegateComparison(left_strict->kind()); | |
| 1302 StrictCompareInstr* negated_strict = | |
| 1303 new StrictCompareInstr(negated_kind, | |
|
Kevin Millikin (Google)
2013/03/26 12:48:31
Do you think it's too unsafe to just replace the t
srdjan
2013/03/26 22:35:25
I am on the edge on that one (tried both). Adding
| |
| 1304 left_strict->left()->Copy(), | |
| 1305 left_strict->right()->Copy()); | |
| 1306 left_strict->ReplaceWith(negated_strict, optimizer->current_iterator()); | |
| 1307 return negated_strict; | |
| 1308 } | |
| 1309 | |
| 1288 return this; | 1310 return this; |
| 1289 } | 1311 } |
| 1290 | 1312 |
| 1291 | 1313 |
| 1292 Instruction* CheckClassInstr::Canonicalize(FlowGraphOptimizer* optimizer) { | 1314 Instruction* CheckClassInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| 1293 // TODO(vegorov): Replace class checks with null checks when ToNullableCid | 1315 // TODO(vegorov): Replace class checks with null checks when ToNullableCid |
| 1294 // matches. | 1316 // matches. |
| 1295 | 1317 |
| 1296 const intptr_t value_cid = value()->Type()->ToCid(); | 1318 const intptr_t value_cid = value()->Type()->ToCid(); |
| 1297 if (value_cid == kDynamicCid) { | 1319 if (value_cid == kDynamicCid) { |
| (...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2338 default: | 2360 default: |
| 2339 UNREACHABLE(); | 2361 UNREACHABLE(); |
| 2340 } | 2362 } |
| 2341 return kPowRuntimeEntry; | 2363 return kPowRuntimeEntry; |
| 2342 } | 2364 } |
| 2343 | 2365 |
| 2344 | 2366 |
| 2345 #undef __ | 2367 #undef __ |
| 2346 | 2368 |
| 2347 } // namespace dart | 2369 } // namespace dart |
| OLD | NEW |