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/aot_optimizer.h" | 5 #include "vm/aot_optimizer.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/branch_optimizer.h" | 8 #include "vm/branch_optimizer.h" |
9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
11 #include "vm/cpu.h" | 11 #include "vm/cpu.h" |
12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
13 #include "vm/exceptions.h" | 13 #include "vm/exceptions.h" |
14 #include "vm/flow_graph_builder.h" | 14 #include "vm/flow_graph_builder.h" |
15 #include "vm/flow_graph_compiler.h" | 15 #include "vm/flow_graph_compiler.h" |
16 #include "vm/flow_graph_inliner.h" | 16 #include "vm/flow_graph_inliner.h" |
17 #include "vm/flow_graph_range_analysis.h" | 17 #include "vm/flow_graph_range_analysis.h" |
18 #include "vm/hash_map.h" | 18 #include "vm/hash_map.h" |
19 #include "vm/il_printer.h" | 19 #include "vm/il_printer.h" |
| 20 #include "vm/intermediate_language.h" |
20 #include "vm/jit_optimizer.h" | 21 #include "vm/jit_optimizer.h" |
21 #include "vm/intermediate_language.h" | |
22 #include "vm/object.h" | 22 #include "vm/object.h" |
23 #include "vm/object_store.h" | 23 #include "vm/object_store.h" |
| 24 #include "vm/optimizer.h" |
24 #include "vm/parser.h" | 25 #include "vm/parser.h" |
25 #include "vm/precompiler.h" | 26 #include "vm/precompiler.h" |
26 #include "vm/resolver.h" | 27 #include "vm/resolver.h" |
27 #include "vm/scopes.h" | 28 #include "vm/scopes.h" |
28 #include "vm/stack_frame.h" | 29 #include "vm/stack_frame.h" |
29 #include "vm/symbols.h" | 30 #include "vm/symbols.h" |
30 | 31 |
31 namespace dart { | 32 namespace dart { |
32 | 33 |
33 DEFINE_FLAG(int, | 34 DEFINE_FLAG(int, |
(...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1341 const TypeArguments& type_arguments = | 1342 const TypeArguments& type_arguments = |
1342 TypeArguments::Handle(type.arguments()); | 1343 TypeArguments::Handle(type.arguments()); |
1343 const bool is_raw_type = type_arguments.IsNull() || | 1344 const bool is_raw_type = type_arguments.IsNull() || |
1344 type_arguments.IsRaw(from_index, num_type_params); | 1345 type_arguments.IsRaw(from_index, num_type_params); |
1345 return is_raw_type; | 1346 return is_raw_type; |
1346 } | 1347 } |
1347 return true; | 1348 return true; |
1348 } | 1349 } |
1349 | 1350 |
1350 | 1351 |
1351 static bool CidTestResultsContains(const ZoneGrowableArray<intptr_t>& results, | |
1352 intptr_t test_cid) { | |
1353 for (intptr_t i = 0; i < results.length(); i += 2) { | |
1354 if (results[i] == test_cid) return true; | |
1355 } | |
1356 return false; | |
1357 } | |
1358 | |
1359 | |
1360 static void TryAddTest(ZoneGrowableArray<intptr_t>* results, | |
1361 intptr_t test_cid, | |
1362 bool result) { | |
1363 if (!CidTestResultsContains(*results, test_cid)) { | |
1364 results->Add(test_cid); | |
1365 results->Add(result); | |
1366 } | |
1367 } | |
1368 | |
1369 | |
1370 // Tries to add cid tests to 'results' so that no deoptimization is | |
1371 // necessary. | |
1372 // TODO(srdjan): Do also for other than 'int' type. | |
1373 static bool TryExpandTestCidsResult(ZoneGrowableArray<intptr_t>* results, | |
1374 const AbstractType& type) { | |
1375 ASSERT(results->length() >= 2); // At least on entry. | |
1376 const ClassTable& class_table = *Isolate::Current()->class_table(); | |
1377 if ((*results)[0] != kSmiCid) { | |
1378 const Class& cls = Class::Handle(class_table.At(kSmiCid)); | |
1379 const Class& type_class = Class::Handle(type.type_class()); | |
1380 const bool smi_is_subtype = | |
1381 cls.IsSubtypeOf(Object::null_type_arguments(), type_class, | |
1382 Object::null_type_arguments(), NULL, NULL, Heap::kOld); | |
1383 results->Add((*results)[results->length() - 2]); | |
1384 results->Add((*results)[results->length() - 2]); | |
1385 for (intptr_t i = results->length() - 3; i > 1; --i) { | |
1386 (*results)[i] = (*results)[i - 2]; | |
1387 } | |
1388 (*results)[0] = kSmiCid; | |
1389 (*results)[1] = smi_is_subtype; | |
1390 } | |
1391 | |
1392 ASSERT(type.IsInstantiated() && !type.IsMalformedOrMalbounded()); | |
1393 ASSERT(results->length() >= 2); | |
1394 if (type.IsSmiType()) { | |
1395 ASSERT((*results)[0] == kSmiCid); | |
1396 return false; | |
1397 } else if (type.IsIntType()) { | |
1398 ASSERT((*results)[0] == kSmiCid); | |
1399 TryAddTest(results, kMintCid, true); | |
1400 TryAddTest(results, kBigintCid, true); | |
1401 // Cannot deoptimize since all tests returning true have been added. | |
1402 return false; | |
1403 } else if (type.IsNumberType()) { | |
1404 ASSERT((*results)[0] == kSmiCid); | |
1405 TryAddTest(results, kMintCid, true); | |
1406 TryAddTest(results, kBigintCid, true); | |
1407 TryAddTest(results, kDoubleCid, true); | |
1408 return false; | |
1409 } else if (type.IsDoubleType()) { | |
1410 ASSERT((*results)[0] == kSmiCid); | |
1411 TryAddTest(results, kDoubleCid, true); | |
1412 return false; | |
1413 } | |
1414 return true; // May deoptimize since we have not identified all 'true' tests. | |
1415 } | |
1416 | |
1417 | |
1418 // TODO(srdjan): Use ICData to check if always true or false. | 1352 // TODO(srdjan): Use ICData to check if always true or false. |
1419 void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { | 1353 void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { |
1420 ASSERT(Token::IsTypeTestOperator(call->token_kind())); | 1354 ASSERT(Token::IsTypeTestOperator(call->token_kind())); |
1421 Definition* left = call->ArgumentAt(0); | 1355 Definition* left = call->ArgumentAt(0); |
1422 Definition* instantiator_type_args = NULL; | 1356 Definition* instantiator_type_args = NULL; |
1423 Definition* function_type_args = NULL; | 1357 Definition* function_type_args = NULL; |
1424 AbstractType& type = AbstractType::ZoneHandle(Z); | 1358 AbstractType& type = AbstractType::ZoneHandle(Z); |
1425 ASSERT(call->type_args_len() == 0); | 1359 ASSERT(call->type_args_len() == 0); |
1426 if (call->ArgumentCount() == 2) { | 1360 if (call->ArgumentCount() == 2) { |
1427 instantiator_type_args = flow_graph()->constant_null(); | 1361 instantiator_type_args = flow_graph()->constant_null(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1503 } | 1437 } |
1504 | 1438 |
1505 const ICData& unary_checks = | 1439 const ICData& unary_checks = |
1506 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); | 1440 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); |
1507 const intptr_t number_of_checks = unary_checks.NumberOfChecks(); | 1441 const intptr_t number_of_checks = unary_checks.NumberOfChecks(); |
1508 if (number_of_checks > 0 && number_of_checks <= FLAG_max_polymorphic_checks) { | 1442 if (number_of_checks > 0 && number_of_checks <= FLAG_max_polymorphic_checks) { |
1509 ZoneGrowableArray<intptr_t>* results = | 1443 ZoneGrowableArray<intptr_t>* results = |
1510 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2); | 1444 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2); |
1511 InstanceOfAsBool(unary_checks, type, results); | 1445 InstanceOfAsBool(unary_checks, type, results); |
1512 if (results->length() == number_of_checks * 2) { | 1446 if (results->length() == number_of_checks * 2) { |
1513 const bool can_deopt = TryExpandTestCidsResult(results, type); | 1447 const bool can_deopt = |
| 1448 Optimizer::SpecializeTestCidsForNumericTypes(results, type); |
1514 if (can_deopt && !IsAllowedForInlining(call->deopt_id())) { | 1449 if (can_deopt && !IsAllowedForInlining(call->deopt_id())) { |
1515 // Guard against repeated speculative inlining. | 1450 // Guard against repeated speculative inlining. |
1516 return; | 1451 return; |
1517 } | 1452 } |
1518 TestCidsInstr* test_cids = new (Z) TestCidsInstr( | 1453 TestCidsInstr* test_cids = new (Z) TestCidsInstr( |
1519 call->token_pos(), Token::kIS, new (Z) Value(left), *results, | 1454 call->token_pos(), Token::kIS, new (Z) Value(left), *results, |
1520 can_deopt ? call->deopt_id() : Thread::kNoDeoptId); | 1455 can_deopt ? call->deopt_id() : Thread::kNoDeoptId); |
1521 // Remove type. | 1456 // Remove type. |
1522 ReplaceCall(call, test_cids); | 1457 ReplaceCall(call, test_cids); |
1523 return; | 1458 return; |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2197 FlowGraph::kEffect); | 2132 FlowGraph::kEffect); |
2198 current_iterator()->RemoveCurrentFromGraph(); | 2133 current_iterator()->RemoveCurrentFromGraph(); |
2199 } | 2134 } |
2200 } | 2135 } |
2201 } | 2136 } |
2202 } | 2137 } |
2203 | 2138 |
2204 #endif // DART_PRECOMPILER | 2139 #endif // DART_PRECOMPILER |
2205 | 2140 |
2206 } // namespace dart | 2141 } // namespace dart |
OLD | NEW |