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

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

Issue 12218008: Inline getters of byte array view in the optimized flow graph. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: updated vm.status with new test Created 7 years, 10 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 | Annotate | Revision Log
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/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 766 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 call->deopt_id() : Isolate::kNoDeoptId; 777 call->deopt_id() : Isolate::kNoDeoptId;
778 } 778 }
779 break; 779 break;
780 default: 780 default:
781 return false; 781 return false;
782 } 782 }
783 Value* array = NULL; 783 Value* array = NULL;
784 Value* index = NULL; 784 Value* index = NULL;
785 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); 785 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index);
786 Definition* array_op = 786 Definition* array_op =
787 new LoadIndexedInstr(array, index, array_cid, deopt_id); 787 new LoadIndexedInstr(array,
788 index,
789 FlowGraphCompiler::ElementSizeFor(array_cid),
790 array_cid,
791 deopt_id);
788 call->ReplaceWith(array_op, current_iterator()); 792 call->ReplaceWith(array_op, current_iterator());
789 RemovePushArguments(call); 793 RemovePushArguments(call);
790 return true; 794 return true;
791 } 795 }
792 796
793 797
794 void FlowGraphOptimizer::InsertBefore(Instruction* next, 798 void FlowGraphOptimizer::InsertBefore(Instruction* next,
795 Instruction* instr, 799 Instruction* instr,
796 Environment* env, 800 Environment* env,
797 Definition::UseKind use_kind) { 801 Definition::UseKind use_kind) {
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 length->set_recognized_kind(MethodRecognizer::kStringBaseLength); 1326 length->set_recognized_kind(MethodRecognizer::kStringBaseLength);
1323 InsertBefore(call, length, NULL, Definition::kValue); 1327 InsertBefore(call, length, NULL, Definition::kValue);
1324 InsertBefore(call, 1328 InsertBefore(call,
1325 new CheckArrayBoundInstr(new Value(length), 1329 new CheckArrayBoundInstr(new Value(length),
1326 index->Copy(), 1330 index->Copy(),
1327 cid, 1331 cid,
1328 call), 1332 call),
1329 call->env(), 1333 call->env(),
1330 Definition::kEffect); 1334 Definition::kEffect);
1331 } 1335 }
1332 return new LoadIndexedInstr(str, index, cid, Isolate::kNoDeoptId); 1336 return new LoadIndexedInstr(str,
1337 index,
1338 FlowGraphCompiler::ElementSizeFor(cid),
1339 cid,
1340 Isolate::kNoDeoptId); // Can't deoptimize.
1333 } 1341 }
1334 1342
1335 1343
1336 void FlowGraphOptimizer::ReplaceWithMathCFunction( 1344 void FlowGraphOptimizer::ReplaceWithMathCFunction(
1337 InstanceCallInstr* call, 1345 InstanceCallInstr* call,
1338 MethodRecognizer::Kind recognized_kind) { 1346 MethodRecognizer::Kind recognized_kind) {
1339 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); 1347 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy());
1340 ZoneGrowableArray<Value*>* args = 1348 ZoneGrowableArray<Value*>* args =
1341 new ZoneGrowableArray<Value*>(call->ArgumentCount()); 1349 new ZoneGrowableArray<Value*>(call->ArgumentCount());
1342 for (intptr_t i = 0; i < call->ArgumentCount(); i++) { 1350 for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
1343 args->Add(call->ArgumentAt(i)->value()); 1351 args->Add(call->ArgumentAt(i)->value());
1344 } 1352 }
1345 InvokeMathCFunctionInstr* invoke = 1353 InvokeMathCFunctionInstr* invoke =
1346 new InvokeMathCFunctionInstr(args, call, recognized_kind); 1354 new InvokeMathCFunctionInstr(args, call, recognized_kind);
1347 call->ReplaceWith(invoke, current_iterator()); 1355 call->ReplaceWith(invoke, current_iterator());
1348 RemovePushArguments(call); 1356 RemovePushArguments(call);
1349 } 1357 }
1350 1358
1351 1359
1360 static bool IsSupportedByteArrayCid(intptr_t cid) {
1361 switch (cid) {
1362 case kInt8ArrayCid:
1363 case kUint8ArrayCid:
1364 case kUint8ClampedArrayCid:
1365 case kInt16ArrayCid:
1366 case kUint16ArrayCid:
1367 case kInt32ArrayCid:
1368 case kUint32ArrayCid:
1369 case kFloat32ArrayCid:
1370 case kFloat64ArrayCid:
srdjan 2013/02/06 17:11:16 They may be ordered, i.e., you could check for ran
Florian Schneider 2013/02/14 12:20:51 How can I make sure that they are ordered? It woul
srdjan 2013/02/14 16:36:35 They are ordered but not as we need it, see RawObj
1371 return true;
1372 default:
1373 return false;
1374 }
1375 }
1376
1377
1352 // Inline only simple, frequently called core library methods. 1378 // Inline only simple, frequently called core library methods.
1353 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { 1379 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) {
1354 ASSERT(call->HasICData()); 1380 ASSERT(call->HasICData());
1355 const ICData& ic_data = *call->ic_data(); 1381 const ICData& ic_data = *call->ic_data();
1356 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { 1382 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) {
1357 // No type feedback collected or multiple targets found. 1383 // No type feedback collected or multiple targets found.
1358 return false; 1384 return false;
1359 } 1385 }
1360 Function& target = Function::Handle(); 1386 Function& target = Function::Handle();
1361 GrowableArray<intptr_t> class_ids; 1387 GrowableArray<intptr_t> class_ids;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 call->ReplaceWith(d2d_instr, current_iterator()); 1459 call->ReplaceWith(d2d_instr, current_iterator());
1434 RemovePushArguments(call); 1460 RemovePushArguments(call);
1435 } 1461 }
1436 return true; 1462 return true;
1437 default: 1463 default:
1438 // Unsupported method. 1464 // Unsupported method.
1439 return false; 1465 return false;
1440 } 1466 }
1441 } 1467 }
1442 1468
1469 if (IsSupportedByteArrayCid(class_ids[0]) && ic_data.NumberOfChecks() == 1) {
srdjan 2013/02/06 17:11:16 Add Parenthesis
Florian Schneider 2013/02/14 12:20:51 Done.
1470 Definition* array_op = NULL;
1471 switch (recognized_kind) {
1472 case MethodRecognizer::kByteArrayBaseGetInt8:
1473 array_op = BuildByteArrayViewLoad(call, class_ids[0], kInt8ArrayCid);
1474 break;
1475 case MethodRecognizer::kByteArrayBaseGetUint8:
1476 array_op = BuildByteArrayViewLoad(call, class_ids[0], kUint8ArrayCid);
1477 break;
1478 case MethodRecognizer::kByteArrayBaseGetInt16:
1479 array_op = BuildByteArrayViewLoad(call, class_ids[0], kInt16ArrayCid);
1480 break;
1481 case MethodRecognizer::kByteArrayBaseGetUint16:
1482 array_op = BuildByteArrayViewLoad(call, class_ids[0], kUint16ArrayCid);
1483 break;
1484 case MethodRecognizer::kByteArrayBaseGetInt32:
1485 array_op = BuildByteArrayViewLoad(call, class_ids[0], kInt32ArrayCid);
1486 break;
1487 case MethodRecognizer::kByteArrayBaseGetUint32:
1488 array_op = BuildByteArrayViewLoad(call, class_ids[0], kUint32ArrayCid);
1489 break;
1490 case MethodRecognizer::kByteArrayBaseGetFloat32:
1491 array_op = BuildByteArrayViewLoad(call, class_ids[0], kFloat32ArrayCid);
1492 break;
1493 case MethodRecognizer::kByteArrayBaseGetFloat64:
1494 array_op = BuildByteArrayViewLoad(call, class_ids[0], kFloat64ArrayCid);
1495 break;
1496 default:
1497 // Unsupported method.
1498 return false;
1499 }
1500 ASSERT(array_op != NULL);
1501 call->ReplaceWith(array_op, current_iterator());
1502 RemovePushArguments(call);
1503 return true;
1504 }
1443 return false; 1505 return false;
1444 } 1506 }
1445 1507
1446 1508
1509 LoadIndexedInstr* FlowGraphOptimizer::BuildByteArrayViewLoad(
1510 InstanceCallInstr* call,
1511 intptr_t receiver_cid,
1512 intptr_t view_cid) {
1513 Value* array = call->ArgumentAt(0)->value();
1514 Value* byte_index = call->ArgumentAt(1)->value();
1515
1516 AddCheckClass(call, array->Copy());
1517 const bool is_immutable = true;
1518 LoadFieldInstr* length = new LoadFieldInstr(
1519 array->Copy(),
1520 CheckArrayBoundInstr::LengthOffsetFor(receiver_cid),
1521 Type::ZoneHandle(Type::SmiType()),
1522 is_immutable);
1523 length->set_result_cid(kSmiCid);
1524 length->set_recognized_kind(
1525 LoadFieldInstr::RecognizedKindFromArrayCid(receiver_cid));
1526 InsertBefore(call, length, NULL, Definition::kValue);
1527
1528 // len_in_bytes = length * kBytesPerElement(receiver)
1529 intptr_t element_size = FlowGraphCompiler::ElementSizeFor(receiver_cid);
1530 ConstantInstr* bytes_per_element =
1531 new ConstantInstr(Smi::Handle(Smi::New(element_size)));
1532 InsertBefore(call, bytes_per_element, NULL, Definition::kValue);
1533 BinarySmiOpInstr* len_in_bytes =
1534 new BinarySmiOpInstr(Token::kMUL,
1535 call,
1536 new Value(length),
1537 new Value(bytes_per_element));
1538 InsertBefore(call, len_in_bytes, call->env(), Definition::kValue);
1539
1540 // Check byte_index < len_in_bytes.
1541 InsertBefore(call,
1542 new CheckArrayBoundInstr(new Value(len_in_bytes),
1543 byte_index->Copy(),
1544 receiver_cid,
1545 call),
1546 call->env(),
1547 Definition::kEffect);
1548
1549 // TODO(fschneider): Optimistically build smi load for Int32 and Uint32
1550 // loads on ia32 like we do for normal array loads, and only revert to
1551 // mint case after deoptimizing here.
1552 return new LoadIndexedInstr(array,
1553 byte_index,
1554 1, // Index scale.
1555 view_cid,
1556 Isolate::kNoDeoptId); // Can't deoptimize.
1557 }
1558
1559
1447 // Returns a Boolean constant if all classes in ic_data yield the same type-test 1560 // Returns a Boolean constant if all classes in ic_data yield the same type-test
1448 // result and the type tests do not depend on type arguments. Otherwise return 1561 // result and the type tests do not depend on type arguments. Otherwise return
1449 // Bool::null(). 1562 // Bool::null().
1450 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data, 1563 RawBool* FlowGraphOptimizer::InstanceOfAsBool(const ICData& ic_data,
1451 const AbstractType& type) const { 1564 const AbstractType& type) const {
1452 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only. 1565 ASSERT(ic_data.num_args_tested() == 1); // Unary checks only.
1453 if (!type.IsInstantiated() || type.IsMalformed()) return Bool::null(); 1566 if (!type.IsInstantiated() || type.IsMalformed()) return Bool::null();
1454 const Class& type_class = Class::Handle(type.type_class()); 1567 const Class& type_class = Class::Handle(type.type_class());
1455 if (type_class.HasTypeArguments()) return Bool::null(); 1568 if (type_class.HasTypeArguments()) return Bool::null();
1456 const ClassTable& class_table = *Isolate::Current()->class_table(); 1569 const ClassTable& class_table = *Isolate::Current()->class_table();
(...skipping 3104 matching lines...) Expand 10 before | Expand all | Expand 10 after
4561 4674
4562 if (FLAG_trace_constant_propagation) { 4675 if (FLAG_trace_constant_propagation) {
4563 OS::Print("\n==== After constant propagation ====\n"); 4676 OS::Print("\n==== After constant propagation ====\n");
4564 FlowGraphPrinter printer(*graph_); 4677 FlowGraphPrinter printer(*graph_);
4565 printer.PrintBlocks(); 4678 printer.PrintBlocks();
4566 } 4679 }
4567 } 4680 }
4568 4681
4569 4682
4570 } // namespace dart 4683 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698