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

Side by Side Diff: runtime/vm/aot_optimizer.cc

Issue 2748073002: Revert "VM: Simplify lowering of is-tests." (Closed)
Patch Set: Created 3 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
« no previous file with comments | « runtime/lib/object_patch.dart ('k') | runtime/vm/bootstrap_natives.h » ('j') | 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) 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"
(...skipping 1425 matching lines...) Expand 10 before | Expand all | Expand 10 after
1436 TryAddTest(results, kDoubleCid, true); 1436 TryAddTest(results, kDoubleCid, true);
1437 return false; 1437 return false;
1438 } else if (type.IsDoubleType()) { 1438 } else if (type.IsDoubleType()) {
1439 ASSERT((*results)[0] == kSmiCid); 1439 ASSERT((*results)[0] == kSmiCid);
1440 TryAddTest(results, kDoubleCid, true); 1440 TryAddTest(results, kDoubleCid, true);
1441 return false; 1441 return false;
1442 } 1442 }
1443 return true; // May deoptimize since we have not identified all 'true' tests. 1443 return true; // May deoptimize since we have not identified all 'true' tests.
1444 } 1444 }
1445 1445
1446 // Tells whether the function of the call matches the core private name.
1447 static bool matches_core(InstanceCallInstr* call, const String& name) {
1448 return call->function_name().raw() == Library::PrivateCoreLibName(name).raw();
1449 }
1446 1450
1447 // TODO(srdjan): Use ICData to check if always true or false. 1451 // TODO(srdjan): Use ICData to check if always true or false.
1448 void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { 1452 void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
1449 ASSERT(Token::IsTypeTestOperator(call->token_kind())); 1453 ASSERT(Token::IsTypeTestOperator(call->token_kind()));
1450 Definition* left = call->ArgumentAt(0); 1454 Definition* left = call->ArgumentAt(0);
1451 Definition* type_args = NULL; 1455 Definition* type_args = NULL;
1452 AbstractType& type = AbstractType::ZoneHandle(Z); 1456 AbstractType& type = AbstractType::ZoneHandle(Z);
1457 bool negate = false;
1453 if (call->ArgumentCount() == 2) { 1458 if (call->ArgumentCount() == 2) {
1454 type_args = flow_graph()->constant_null(); 1459 type_args = flow_graph()->constant_null();
1455 ASSERT(call->MatchesCoreName(Symbols::_simpleInstanceOf())); 1460 if (matches_core(call, Symbols::_simpleInstanceOf())) {
1456 type = AbstractType::Cast(call->ArgumentAt(1)->AsConstant()->value()).raw(); 1461 type =
1462 AbstractType::Cast(call->ArgumentAt(1)->AsConstant()->value()).raw();
1463 negate = false; // Just to be sure.
1464 } else {
1465 if (matches_core(call, Symbols::_instanceOfNum())) {
1466 type = Type::Number();
1467 } else if (matches_core(call, Symbols::_instanceOfInt())) {
1468 type = Type::IntType();
1469 } else if (matches_core(call, Symbols::_instanceOfSmi())) {
1470 type = Type::SmiType();
1471 } else if (matches_core(call, Symbols::_instanceOfDouble())) {
1472 type = Type::Double();
1473 } else if (matches_core(call, Symbols::_instanceOfString())) {
1474 type = Type::StringType();
1475 } else {
1476 UNIMPLEMENTED();
1477 }
1478 negate =
1479 Bool::Cast(
1480 call->ArgumentAt(1)->OriginalDefinition()->AsConstant()->value())
1481 .value();
1482 }
1457 } else { 1483 } else {
1458 type_args = call->ArgumentAt(1); 1484 type_args = call->ArgumentAt(1);
1459 type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw(); 1485 type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw();
1486 negate =
1487 Bool::Cast(
1488 call->ArgumentAt(3)->OriginalDefinition()->AsConstant()->value())
1489 .value();
1460 } 1490 }
1461 1491
1462 if (TypeCheckAsClassEquality(type)) { 1492 if (TypeCheckAsClassEquality(type)) {
1463 LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left)); 1493 LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left));
1464 InsertBefore(call, left_cid, NULL, FlowGraph::kValue); 1494 InsertBefore(call, left_cid, NULL, FlowGraph::kValue);
1465 const intptr_t type_cid = Class::Handle(Z, type.type_class()).id(); 1495 const intptr_t type_cid = Class::Handle(Z, type.type_class()).id();
1466 ConstantInstr* cid = 1496 ConstantInstr* cid =
1467 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid))); 1497 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid)));
1468 1498
1469 StrictCompareInstr* check_cid = 1499 StrictCompareInstr* check_cid = new (Z) StrictCompareInstr(
1470 new (Z) StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT, 1500 call->token_pos(), negate ? Token::kNE_STRICT : Token::kEQ_STRICT,
1471 new (Z) Value(left_cid), new (Z) Value(cid), 1501 new (Z) Value(left_cid), new (Z) Value(cid),
1472 false); // No number check. 1502 false); // No number check.
1473 ReplaceCall(call, check_cid); 1503 ReplaceCall(call, check_cid);
1474 return; 1504 return;
1475 } 1505 }
1476 1506
1477 if (precompiler_ != NULL) { 1507 if (precompiler_ != NULL) {
1478 TypeRangeCache* cache = precompiler_->type_range_cache(); 1508 TypeRangeCache* cache = precompiler_->type_range_cache();
1479 intptr_t lower_limit, upper_limit; 1509 intptr_t lower_limit, upper_limit;
1480 if (cache != NULL && 1510 if (cache != NULL &&
1481 cache->InstanceOfHasClassRange(type, &lower_limit, &upper_limit)) { 1511 cache->InstanceOfHasClassRange(type, &lower_limit, &upper_limit)) {
1482 // left.instanceof(type) => 1512 // left.instanceof(type) =>
(...skipping 15 matching lines...) Expand all
1498 args->Add(arg); 1528 args->Add(arg);
1499 arg = new (Z) PushArgumentInstr(new (Z) Value(lower_cid)); 1529 arg = new (Z) PushArgumentInstr(new (Z) Value(lower_cid));
1500 InsertBefore(call, arg, NULL, FlowGraph::kEffect); 1530 InsertBefore(call, arg, NULL, FlowGraph::kEffect);
1501 args->Add(arg); 1531 args->Add(arg);
1502 arg = new (Z) PushArgumentInstr(new (Z) Value(upper_cid)); 1532 arg = new (Z) PushArgumentInstr(new (Z) Value(upper_cid));
1503 InsertBefore(call, arg, NULL, FlowGraph::kEffect); 1533 InsertBefore(call, arg, NULL, FlowGraph::kEffect);
1504 args->Add(arg); 1534 args->Add(arg);
1505 1535
1506 const Library& dart_internal = 1536 const Library& dart_internal =
1507 Library::Handle(Z, Library::InternalLibrary()); 1537 Library::Handle(Z, Library::InternalLibrary());
1508 const String& target_name = Symbols::_classRangeCheck(); 1538 const String& target_name = negate ? Symbols::_classRangeCheckNegative()
1539 : Symbols::_classRangeCheck();
1509 const Function& target = Function::ZoneHandle( 1540 const Function& target = Function::ZoneHandle(
1510 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); 1541 Z, dart_internal.LookupFunctionAllowPrivate(target_name));
1511 ASSERT(!target.IsNull()); 1542 ASSERT(!target.IsNull());
1512 ASSERT(target.IsRecognized() && target.always_inline()); 1543 ASSERT(target.IsRecognized() && target.always_inline());
1513 1544
1514 StaticCallInstr* new_call = 1545 StaticCallInstr* new_call =
1515 new (Z) StaticCallInstr(call->token_pos(), target, 1546 new (Z) StaticCallInstr(call->token_pos(), target,
1516 Object::null_array(), // argument_names 1547 Object::null_array(), // argument_names
1517 args, call->deopt_id()); 1548 args, call->deopt_id());
1518 Environment* copy = call->env()->DeepCopy( 1549 Environment* copy = call->env()->DeepCopy(
(...skipping 14 matching lines...) Expand all
1533 if (number_of_checks > 0 && number_of_checks <= FLAG_max_polymorphic_checks) { 1564 if (number_of_checks > 0 && number_of_checks <= FLAG_max_polymorphic_checks) {
1534 ZoneGrowableArray<intptr_t>* results = 1565 ZoneGrowableArray<intptr_t>* results =
1535 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2); 1566 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2);
1536 InstanceOfAsBool(unary_checks, type, results); 1567 InstanceOfAsBool(unary_checks, type, results);
1537 if (results->length() == number_of_checks * 2) { 1568 if (results->length() == number_of_checks * 2) {
1538 const bool can_deopt = TryExpandTestCidsResult(results, type); 1569 const bool can_deopt = TryExpandTestCidsResult(results, type);
1539 if (can_deopt && !IsAllowedForInlining(call->deopt_id())) { 1570 if (can_deopt && !IsAllowedForInlining(call->deopt_id())) {
1540 // Guard against repeated speculative inlining. 1571 // Guard against repeated speculative inlining.
1541 return; 1572 return;
1542 } 1573 }
1543 TestCidsInstr* test_cids = new (Z) TestCidsInstr( 1574 TestCidsInstr* test_cids = new (Z)
1544 call->token_pos(), Token::kIS, new (Z) Value(left), *results, 1575 TestCidsInstr(call->token_pos(), negate ? Token::kISNOT : Token::kIS,
1545 can_deopt ? call->deopt_id() : Thread::kNoDeoptId); 1576 new (Z) Value(left), *results,
1577 can_deopt ? call->deopt_id() : Thread::kNoDeoptId);
1546 // Remove type. 1578 // Remove type.
1547 ReplaceCall(call, test_cids); 1579 ReplaceCall(call, test_cids);
1548 return; 1580 return;
1549 } 1581 }
1550 } 1582 }
1551 1583
1552 InstanceOfInstr* instance_of = 1584 InstanceOfInstr* instance_of = new (Z)
1553 new (Z) InstanceOfInstr(call->token_pos(), new (Z) Value(left), 1585 InstanceOfInstr(call->token_pos(), new (Z) Value(left),
1554 new (Z) Value(type_args), type, call->deopt_id()); 1586 new (Z) Value(type_args), type, negate, call->deopt_id());
1555 ReplaceCall(call, instance_of); 1587 ReplaceCall(call, instance_of);
1556 } 1588 }
1557 1589
1558 1590
1559 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids). 1591 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids).
1560 void AotOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { 1592 void AotOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) {
1561 ASSERT(Token::IsTypeCastOperator(call->token_kind())); 1593 ASSERT(Token::IsTypeCastOperator(call->token_kind()));
1562 Definition* left = call->ArgumentAt(0); 1594 Definition* left = call->ArgumentAt(0);
1563 Definition* type_args = call->ArgumentAt(1); 1595 Definition* type_args = call->ArgumentAt(1);
1564 const AbstractType& type = 1596 const AbstractType& type =
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 FlowGraph::kEffect); 2162 FlowGraph::kEffect);
2131 current_iterator()->RemoveCurrentFromGraph(); 2163 current_iterator()->RemoveCurrentFromGraph();
2132 } 2164 }
2133 } 2165 }
2134 } 2166 }
2135 } 2167 }
2136 2168
2137 #endif // DART_PRECOMPILER 2169 #endif // DART_PRECOMPILER
2138 2170
2139 } // namespace dart 2171 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/object_patch.dart ('k') | runtime/vm/bootstrap_natives.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698