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

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

Issue 11262025: Check class instruction supports Smi check. This fixes missed inlining of isOdd/isEven (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/intermediate_language.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) 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 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 ic_data.GetOneClassCheckAt(0, &class_id, &target); 420 ic_data.GetOneClassCheckAt(0, &class_id, &target);
421 return class_id; 421 return class_id;
422 } 422 }
423 423
424 424
425 void FlowGraphOptimizer::AddCheckClass(InstanceCallInstr* call, 425 void FlowGraphOptimizer::AddCheckClass(InstanceCallInstr* call,
426 Value* value) { 426 Value* value) {
427 // Type propagation has not run yet, we cannot eliminate the check. 427 // Type propagation has not run yet, we cannot eliminate the check.
428 const ICData& unary_checks = 428 const ICData& unary_checks =
429 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); 429 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks());
430 CheckClassInstr* check = 430 Instruction* check = NULL;
431 new CheckClassInstr(value, call->deopt_id(), unary_checks); 431 if ((unary_checks.NumberOfChecks() == 1) &&
432 (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) {
433 check = new CheckSmiInstr(value, call->deopt_id());
434 } else {
435 check = new CheckClassInstr(value, call->deopt_id(), unary_checks);
436 }
432 InsertBefore(call, check, call->env(), Definition::kEffect); 437 InsertBefore(call, check, call->env(), Definition::kEffect);
433 } 438 }
434 439
435 440
436 static bool ArgIsAlwaysSmi(const ICData& ic_data, intptr_t arg_n) { 441 static bool ArgIsAlwaysSmi(const ICData& ic_data, intptr_t arg_n) {
437 ASSERT(ic_data.num_args_tested() > arg_n); 442 ASSERT(ic_data.num_args_tested() > arg_n);
438 if (ic_data.NumberOfChecks() == 0) return false; 443 if (ic_data.NumberOfChecks() == 0) return false;
439 GrowableArray<intptr_t> class_ids; 444 GrowableArray<intptr_t> class_ids;
440 Function& target = Function::Handle(); 445 Function& target = Function::Handle();
441 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 446 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 InsertBefore(call, elements, NULL, Definition::kValue); 489 InsertBefore(call, elements, NULL, Definition::kValue);
485 *array = new Value(elements); 490 *array = new Value(elements);
486 return kArrayCid; 491 return kArrayCid;
487 } 492 }
488 return class_id; 493 return class_id;
489 } 494 }
490 495
491 496
492 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) { 497 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) {
493 const intptr_t class_id = ReceiverClassId(call); 498 const intptr_t class_id = ReceiverClassId(call);
494 ICData& value_check = ICData::Handle(); 499 ICData& value_check = ICData::ZoneHandle();
495 switch (class_id) { 500 switch (class_id) {
496 case kArrayCid: 501 case kArrayCid:
497 case kGrowableObjectArrayCid: 502 case kGrowableObjectArrayCid:
498 // Acceptable store index classes. 503 // Acceptable store index classes.
499 break; 504 break;
500 case kFloat32ArrayCid: 505 case kFloat32ArrayCid:
501 case kFloat64ArrayCid: { 506 case kFloat64ArrayCid: {
502 // Check that value is always double. 507 // Check that value is always double.
503 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); 508 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2);
504 if ((value_check.NumberOfChecks() != 1) || 509 if ((value_check.NumberOfChecks() != 1) ||
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 const bool call_with_checks = false; 1144 const bool call_with_checks = false;
1140 PolymorphicInstanceCallInstr* call = 1145 PolymorphicInstanceCallInstr* call =
1141 new PolymorphicInstanceCallInstr(instr, unary_checks, 1146 new PolymorphicInstanceCallInstr(instr, unary_checks,
1142 call_with_checks); 1147 call_with_checks);
1143 instr->ReplaceWith(call, current_iterator()); 1148 instr->ReplaceWith(call, current_iterator());
1144 return; 1149 return;
1145 } 1150 }
1146 const intptr_t kMaxChecks = 4; 1151 const intptr_t kMaxChecks = 4;
1147 if (instr->ic_data()->NumberOfChecks() <= kMaxChecks) { 1152 if (instr->ic_data()->NumberOfChecks() <= kMaxChecks) {
1148 bool call_with_checks; 1153 bool call_with_checks;
1149 // TODO(srdjan): Add check class instr for mixed smi/non-smi. 1154 if (unary_checks.HasOneTarget()) {
1150 if (unary_checks.HasOneTarget() &&
1151 (unary_checks.GetReceiverClassIdAt(0) != kSmiCid)) {
1152 // Type propagation has not run yet, we cannot eliminate the check. 1155 // Type propagation has not run yet, we cannot eliminate the check.
1153 AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy()); 1156 AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy());
1154 // Call can still deoptimize, do not detach environment from instr. 1157 // Call can still deoptimize, do not detach environment from instr.
1155 call_with_checks = false; 1158 call_with_checks = false;
1156 } else { 1159 } else {
1157 call_with_checks = true; 1160 call_with_checks = true;
1158 } 1161 }
1159 PolymorphicInstanceCallInstr* call = 1162 PolymorphicInstanceCallInstr* call =
1160 new PolymorphicInstanceCallInstr(instr, unary_checks, 1163 new PolymorphicInstanceCallInstr(instr, unary_checks,
1161 call_with_checks); 1164 call_with_checks);
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1332 1335
1333 // Check if ICDData contains checks with Smi/Null combinations. In that case 1336 // Check if ICDData contains checks with Smi/Null combinations. In that case
1334 // we can still emit the optimized Smi equality operation but need to add 1337 // we can still emit the optimized Smi equality operation but need to add
1335 // checks for null or Smi. 1338 // checks for null or Smi.
1336 // TODO(srdjan): Add it for Double and Mint. 1339 // TODO(srdjan): Add it for Double and Mint.
1337 GrowableArray<intptr_t> smi_or_null(2); 1340 GrowableArray<intptr_t> smi_or_null(2);
1338 smi_or_null.Add(kSmiCid); 1341 smi_or_null.Add(kSmiCid);
1339 smi_or_null.Add(kNullCid); 1342 smi_or_null.Add(kNullCid);
1340 if (ICDataHasOnlyReceiverArgumentClassIds( 1343 if (ICDataHasOnlyReceiverArgumentClassIds(
1341 *comp->ic_data(), smi_or_null, smi_or_null)) { 1344 *comp->ic_data(), smi_or_null, smi_or_null)) {
1342 ICData& unary_checks = 1345 const ICData& unary_checks_0 =
1343 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks()); 1346 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks());
1344 const intptr_t deopt_id = comp->deopt_id(); 1347 const intptr_t deopt_id = comp->deopt_id();
1345 if ((unary_checks.NumberOfChecks() == 1) && 1348 if ((unary_checks_0.NumberOfChecks() == 1) &&
1346 (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) { 1349 (unary_checks_0.GetReceiverClassIdAt(0) == kSmiCid)) {
1347 // Smi only. 1350 // Smi only.
1348 optimizer->InsertBefore( 1351 optimizer->InsertBefore(
1349 instr, 1352 instr,
1350 new CheckSmiInstr(comp->left()->Copy(), deopt_id), 1353 new CheckSmiInstr(comp->left()->Copy(), deopt_id),
1351 instr->env(), 1354 instr->env(),
1352 Definition::kEffect); 1355 Definition::kEffect);
1353 } else { 1356 } else {
1354 // Smi or NULL. 1357 // Smi or NULL.
1355 optimizer->InsertBefore( 1358 optimizer->InsertBefore(
1356 instr, 1359 instr,
1357 new CheckClassInstr(comp->left()->Copy(), deopt_id, unary_checks), 1360 new CheckClassInstr(comp->left()->Copy(), deopt_id, unary_checks_0),
1358 instr->env(), 1361 instr->env(),
1359 Definition::kEffect); 1362 Definition::kEffect);
1360 } 1363 }
1361 1364
1362 unary_checks = comp->ic_data()->AsUnaryClassChecksForArgNr(1); 1365 const ICData& unary_checks_1 =
1363 if ((unary_checks.NumberOfChecks() == 1) && 1366 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecksForArgNr(1));
1364 (unary_checks.GetReceiverClassIdAt(0) == kSmiCid)) { 1367 if ((unary_checks_1.NumberOfChecks() == 1) &&
1368 (unary_checks_1.GetReceiverClassIdAt(0) == kSmiCid)) {
1365 // Smi only. 1369 // Smi only.
1366 optimizer->InsertBefore( 1370 optimizer->InsertBefore(
1367 instr, 1371 instr,
1368 new CheckSmiInstr(comp->right()->Copy(), deopt_id), 1372 new CheckSmiInstr(comp->right()->Copy(), deopt_id),
1369 instr->env(), 1373 instr->env(),
1370 Definition::kEffect); 1374 Definition::kEffect);
1371 } else { 1375 } else {
1372 // Smi or NULL. 1376 // Smi or NULL.
1373 optimizer->InsertBefore( 1377 optimizer->InsertBefore(
1374 instr, 1378 instr,
1375 new CheckClassInstr(comp->right()->Copy(), deopt_id, unary_checks), 1379 new CheckClassInstr(comp->right()->Copy(), deopt_id, unary_checks_1),
1376 instr->env(), 1380 instr->env(),
1377 Definition::kEffect); 1381 Definition::kEffect);
1378 } 1382 }
1379 comp->set_receiver_class_id(kSmiCid); 1383 comp->set_receiver_class_id(kSmiCid);
1380 } 1384 }
1381 } 1385 }
1382 1386
1383 1387
1384 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) { 1388 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareInstr* instr) {
1385 HandleEqualityCompare(this, instr, instr, current_iterator()); 1389 HandleEqualityCompare(this, instr, instr, current_iterator());
(...skipping 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3504 3508
3505 if (FLAG_trace_constant_propagation) { 3509 if (FLAG_trace_constant_propagation) {
3506 OS::Print("\n==== After constant propagation ====\n"); 3510 OS::Print("\n==== After constant propagation ====\n");
3507 FlowGraphPrinter printer(*graph_); 3511 FlowGraphPrinter printer(*graph_);
3508 printer.PrintBlocks(); 3512 printer.PrintBlocks();
3509 } 3513 }
3510 } 3514 }
3511 3515
3512 3516
3513 } // namespace dart 3517 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698