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

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

Issue 2748063003: Reland "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/vm/intermediate_language_x64.cc ('k') | runtime/vm/kernel_to_il.cc » ('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 #ifndef DART_PRECOMPILED_RUNTIME 4 #ifndef DART_PRECOMPILED_RUNTIME
5 #include "vm/jit_optimizer.h" 5 #include "vm/jit_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 1317 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 return true; // May deoptimize since we have not identified all 'true' tests. 1328 return true; // May deoptimize since we have not identified all 'true' tests.
1329 } 1329 }
1330 1330
1331 1331
1332 // TODO(srdjan): Use ICData to check if always true or false. 1332 // TODO(srdjan): Use ICData to check if always true or false.
1333 void JitOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { 1333 void JitOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
1334 ASSERT(Token::IsTypeTestOperator(call->token_kind())); 1334 ASSERT(Token::IsTypeTestOperator(call->token_kind()));
1335 Definition* left = call->ArgumentAt(0); 1335 Definition* left = call->ArgumentAt(0);
1336 Definition* type_args = NULL; 1336 Definition* type_args = NULL;
1337 AbstractType& type = AbstractType::ZoneHandle(Z); 1337 AbstractType& type = AbstractType::ZoneHandle(Z);
1338 bool negate = false;
1339 if (call->ArgumentCount() == 2) { 1338 if (call->ArgumentCount() == 2) {
1340 type_args = flow_graph()->constant_null(); 1339 type_args = flow_graph()->constant_null();
1341 if (call->MatchesCoreName(Symbols::_simpleInstanceOf())) { 1340 ASSERT(call->MatchesCoreName(Symbols::_simpleInstanceOf()));
1342 type = 1341 type = AbstractType::Cast(call->ArgumentAt(1)->AsConstant()->value()).raw();
1343 AbstractType::Cast(call->ArgumentAt(1)->AsConstant()->value()).raw();
1344 negate = false; // Just to be sure.
1345 } else {
1346 if (call->MatchesCoreName(Symbols::_instanceOfNum())) {
1347 type = Type::Number();
1348 } else if (call->MatchesCoreName(Symbols::_instanceOfInt())) {
1349 type = Type::IntType();
1350 } else if (call->MatchesCoreName(Symbols::_instanceOfSmi())) {
1351 type = Type::SmiType();
1352 } else if (call->MatchesCoreName(Symbols::_instanceOfDouble())) {
1353 type = Type::Double();
1354 } else if (call->MatchesCoreName(Symbols::_instanceOfString())) {
1355 type = Type::StringType();
1356 } else {
1357 UNIMPLEMENTED();
1358 }
1359 negate =
1360 Bool::Cast(
1361 call->ArgumentAt(1)->OriginalDefinition()->AsConstant()->value())
1362 .value();
1363 }
1364 } else { 1342 } else {
1365 type_args = call->ArgumentAt(1); 1343 type_args = call->ArgumentAt(1);
1366 type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw(); 1344 type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw();
1367 negate =
1368 Bool::Cast(
1369 call->ArgumentAt(3)->OriginalDefinition()->AsConstant()->value())
1370 .value();
1371 } 1345 }
1372 const ICData& unary_checks = 1346 const ICData& unary_checks =
1373 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); 1347 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks());
1374 const intptr_t number_of_checks = unary_checks.NumberOfChecks(); 1348 const intptr_t number_of_checks = unary_checks.NumberOfChecks();
1375 if ((number_of_checks > 0) && 1349 if ((number_of_checks > 0) &&
1376 (number_of_checks <= FLAG_max_polymorphic_checks)) { 1350 (number_of_checks <= FLAG_max_polymorphic_checks)) {
1377 ZoneGrowableArray<intptr_t>* results = 1351 ZoneGrowableArray<intptr_t>* results =
1378 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2); 1352 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2);
1379 Bool& as_bool = 1353 Bool& as_bool =
1380 Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results)); 1354 Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results));
1381 if (as_bool.IsNull()) { 1355 if (as_bool.IsNull()) {
1382 if (results->length() == number_of_checks * 2) { 1356 if (results->length() == number_of_checks * 2) {
1383 const bool can_deopt = TryExpandTestCidsResult(results, type); 1357 const bool can_deopt = TryExpandTestCidsResult(results, type);
1384 TestCidsInstr* test_cids = new (Z) TestCidsInstr( 1358 TestCidsInstr* test_cids = new (Z) TestCidsInstr(
1385 call->token_pos(), negate ? Token::kISNOT : Token::kIS, 1359 call->token_pos(), Token::kIS, new (Z) Value(left), *results,
1386 new (Z) Value(left), *results,
1387 can_deopt ? call->deopt_id() : Thread::kNoDeoptId); 1360 can_deopt ? call->deopt_id() : Thread::kNoDeoptId);
1388 // Remove type. 1361 // Remove type.
1389 ReplaceCall(call, test_cids); 1362 ReplaceCall(call, test_cids);
1390 return; 1363 return;
1391 } 1364 }
1392 } else { 1365 } else {
1393 // TODO(srdjan): Use TestCidsInstr also for this case. 1366 // TODO(srdjan): Use TestCidsInstr also for this case.
1394 // One result only. 1367 // One result only.
1395 AddReceiverCheck(call); 1368 AddReceiverCheck(call);
1396 if (negate) {
1397 as_bool = Bool::Get(!as_bool.value()).raw();
1398 }
1399 ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool); 1369 ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool);
1400 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { 1370 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
1401 PushArgumentInstr* push = call->PushArgumentAt(i); 1371 PushArgumentInstr* push = call->PushArgumentAt(i);
1402 push->ReplaceUsesWith(push->value()->definition()); 1372 push->ReplaceUsesWith(push->value()->definition());
1403 push->RemoveFromGraph(); 1373 push->RemoveFromGraph();
1404 } 1374 }
1405 call->ReplaceUsesWith(bool_const); 1375 call->ReplaceUsesWith(bool_const);
1406 ASSERT(current_iterator()->Current() == call); 1376 ASSERT(current_iterator()->Current() == call);
1407 current_iterator()->RemoveCurrentFromGraph(); 1377 current_iterator()->RemoveCurrentFromGraph();
1408 return; 1378 return;
1409 } 1379 }
1410 } 1380 }
1411 1381
1412 if (TypeCheckAsClassEquality(type)) { 1382 if (TypeCheckAsClassEquality(type)) {
1413 LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left)); 1383 LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left));
1414 InsertBefore(call, left_cid, NULL, FlowGraph::kValue); 1384 InsertBefore(call, left_cid, NULL, FlowGraph::kValue);
1415 const intptr_t type_cid = Class::Handle(Z, type.type_class()).id(); 1385 const intptr_t type_cid = Class::Handle(Z, type.type_class()).id();
1416 ConstantInstr* cid = 1386 ConstantInstr* cid =
1417 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid))); 1387 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid)));
1418 1388
1419 StrictCompareInstr* check_cid = new (Z) StrictCompareInstr( 1389 StrictCompareInstr* check_cid =
1420 call->token_pos(), negate ? Token::kNE_STRICT : Token::kEQ_STRICT, 1390 new (Z) StrictCompareInstr(call->token_pos(), Token::kEQ_STRICT,
1421 new (Z) Value(left_cid), new (Z) Value(cid), 1391 new (Z) Value(left_cid), new (Z) Value(cid),
1422 false); // No number check. 1392 false); // No number check.
1423 ReplaceCall(call, check_cid); 1393 ReplaceCall(call, check_cid);
1424 return; 1394 return;
1425 } 1395 }
1426 1396
1427 InstanceOfInstr* instance_of = new (Z) 1397 InstanceOfInstr* instance_of =
1428 InstanceOfInstr(call->token_pos(), new (Z) Value(left), 1398 new (Z) InstanceOfInstr(call->token_pos(), new (Z) Value(left),
1429 new (Z) Value(type_args), type, negate, call->deopt_id()); 1399 new (Z) Value(type_args), type, call->deopt_id());
1430 ReplaceCall(call, instance_of); 1400 ReplaceCall(call, instance_of);
1431 } 1401 }
1432 1402
1433 1403
1434 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids). 1404 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids).
1435 void JitOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { 1405 void JitOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) {
1436 ASSERT(Token::IsTypeCastOperator(call->token_kind())); 1406 ASSERT(Token::IsTypeCastOperator(call->token_kind()));
1437 Definition* left = call->ArgumentAt(0); 1407 Definition* left = call->ArgumentAt(0);
1438 Definition* type_args = call->ArgumentAt(1); 1408 Definition* type_args = call->ArgumentAt(1);
1439 const AbstractType& type = 1409 const AbstractType& type =
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
1831 // Discard the environment from the original instruction because the store 1801 // Discard the environment from the original instruction because the store
1832 // can't deoptimize. 1802 // can't deoptimize.
1833 instr->RemoveEnvironment(); 1803 instr->RemoveEnvironment();
1834 ReplaceCall(instr, store); 1804 ReplaceCall(instr, store);
1835 return true; 1805 return true;
1836 } 1806 }
1837 1807
1838 1808
1839 } // namespace dart 1809 } // namespace dart
1840 #endif // DART_PRECOMPILED_RUNTIME 1810 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_x64.cc ('k') | runtime/vm/kernel_to_il.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698