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

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

Issue 10910224: Using type feedback, eliminate store barriers for indexed stores. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 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) 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/hash_map.h" 10 #include "vm/hash_map.h"
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 void FlowGraphOptimizer::AddCheckClass(InstanceCallInstr* call, 320 void FlowGraphOptimizer::AddCheckClass(InstanceCallInstr* call,
321 Value* value) { 321 Value* value) {
322 // Type propagation has not run yet, we cannot eliminate the check. 322 // Type propagation has not run yet, we cannot eliminate the check.
323 const ICData& unary_checks = 323 const ICData& unary_checks =
324 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); 324 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks());
325 CheckClassInstr* check = new CheckClassInstr(value, call, unary_checks); 325 CheckClassInstr* check = new CheckClassInstr(value, call, unary_checks);
326 InsertBefore(call, check, call->env(), Definition::kEffect); 326 InsertBefore(call, check, call->env(), Definition::kEffect);
327 } 327 }
328 328
329 329
330 static bool ArgIsAlwaysSmi(const ICData& ic_data, intptr_t arg_n) {
331 ASSERT(ic_data.num_args_tested() > arg_n);
332 if (ic_data.NumberOfChecks() == 0) return false;
333 GrowableArray<intptr_t> class_ids;
334 Function& target = Function::Handle();
335 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
336 ic_data.GetCheckAt(i, &class_ids, &target);
337 if (class_ids[arg_n] != kSmiCid) return false;
338 }
339 return true;
340 }
341
342
330 bool FlowGraphOptimizer::TryReplaceWithArrayOp(InstanceCallInstr* call, 343 bool FlowGraphOptimizer::TryReplaceWithArrayOp(InstanceCallInstr* call,
331 Token::Kind op_kind) { 344 Token::Kind op_kind) {
332 // TODO(fschneider): Optimize []= operator in checked mode as well. 345 // TODO(fschneider): Optimize []= operator in checked mode as well.
333 if (op_kind == Token::kASSIGN_INDEX && FLAG_enable_type_checks) return false; 346 if (op_kind == Token::kASSIGN_INDEX && FLAG_enable_type_checks) return false;
334 347
335 const intptr_t class_id = ReceiverClassId(call); 348 const intptr_t class_id = ReceiverClassId(call);
336 switch (class_id) { 349 switch (class_id) {
337 case kImmutableArrayCid: 350 case kImmutableArrayCid:
338 // Stores are only specialized for Array and GrowableObjectArray, 351 // Stores are only specialized for Array and GrowableObjectArray,
339 // not for ImmutableArray. 352 // not for ImmutableArray.
(...skipping 25 matching lines...) Expand all
365 GrowableObjectArray::data_offset(), 378 GrowableObjectArray::data_offset(),
366 Type::ZoneHandle(Type::DynamicType())); 379 Type::ZoneHandle(Type::DynamicType()));
367 elements->set_result_cid(kArrayCid); 380 elements->set_result_cid(kArrayCid);
368 InsertBefore(call, elements, NULL, Definition::kValue); 381 InsertBefore(call, elements, NULL, Definition::kValue);
369 array = new Value(elements); 382 array = new Value(elements);
370 } 383 }
371 Definition* array_op = NULL; 384 Definition* array_op = NULL;
372 if (op_kind == Token::kINDEX) { 385 if (op_kind == Token::kINDEX) {
373 array_op = new LoadIndexedInstr(array, index); 386 array_op = new LoadIndexedInstr(array, index);
374 } else { 387 } else {
388 bool needs_store_barrier = true;
389 if (ArgIsAlwaysSmi(*call->ic_data(), 2)) {
390 InsertBefore(call,
391 new CheckSmiInstr(call->ArgumentAt(2)->value()->Copy(),
392 call->deopt_id()),
393 call->env(),
394 Definition::kEffect);
395 needs_store_barrier = false;
396 }
375 Value* value = call->ArgumentAt(2)->value(); 397 Value* value = call->ArgumentAt(2)->value();
376 array_op = new StoreIndexedInstr(array, index, value); 398 array_op =
399 new StoreIndexedInstr(array, index, value, needs_store_barrier);
377 } 400 }
378 call->ReplaceWith(array_op, current_iterator()); 401 call->ReplaceWith(array_op, current_iterator());
379 RemovePushArguments(call); 402 RemovePushArguments(call);
380 return true; 403 return true;
381 } 404 }
382 default: 405 default:
383 return false; 406 return false;
384 } 407 }
385 } 408 }
386 409
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 MethodRecognizer::Kind recognized_kind = 826 MethodRecognizer::Kind recognized_kind =
804 MethodRecognizer::RecognizeKind(call->function()); 827 MethodRecognizer::RecognizeKind(call->function());
805 if (recognized_kind == MethodRecognizer::kMathSqrt) { 828 if (recognized_kind == MethodRecognizer::kMathSqrt) {
806 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call); 829 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call);
807 call->ReplaceWith(sqrt, current_iterator()); 830 call->ReplaceWith(sqrt, current_iterator());
808 RemovePushArguments(call); 831 RemovePushArguments(call);
809 } 832 }
810 } 833 }
811 834
812 835
813 static bool ArgIsAlwaysSmi(const ICData& ic_data, intptr_t arg_n) {
814 ASSERT(ic_data.num_args_tested() > arg_n);
815 if (ic_data.NumberOfChecks() == 0) return false;
816 GrowableArray<intptr_t> class_ids;
817 Function& target = Function::Handle();
818 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
819 ic_data.GetCheckAt(i, &class_ids, &target);
820 if (class_ids[arg_n] != kSmiCid) return false;
821 }
822 return true;
823 }
824
825
826 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr) { 836 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr) {
827 if (FLAG_enable_type_checks) { 837 if (FLAG_enable_type_checks) {
828 // TODO(srdjan): Add assignable check node if --enable_type_checks. 838 // TODO(srdjan): Add assignable check node if --enable_type_checks.
829 return false; 839 return false;
830 } 840 }
831 841
832 ASSERT(instr->HasICData()); 842 ASSERT(instr->HasICData());
833 const ICData& unary_ic_data = 843 const ICData& unary_ic_data =
834 ICData::Handle(instr->ic_data()->AsUnaryClassChecks()); 844 ICData::Handle(instr->ic_data()->AsUnaryClassChecks());
835 if (unary_ic_data.NumberOfChecks() == 0) { 845 if (unary_ic_data.NumberOfChecks() == 0) {
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. 1427 DirectChainedHashMap<Definition*> child_map(*map); // Copy map.
1418 OptimizeRecursive(child, &child_map); 1428 OptimizeRecursive(child, &child_map);
1419 } else { 1429 } else {
1420 OptimizeRecursive(child, map); // Reuse map for the last child. 1430 OptimizeRecursive(child, map); // Reuse map for the last child.
1421 } 1431 }
1422 } 1432 }
1423 } 1433 }
1424 1434
1425 1435
1426 } // namespace dart 1436 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698