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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 11092090: Inline indexed load and store of typed array float64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_optimizer.cc
===================================================================
--- runtime/vm/flow_graph_optimizer.cc (revision 13622)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -374,76 +374,100 @@
}
-bool FlowGraphOptimizer::TryReplaceWithArrayOp(InstanceCallInstr* call,
- Token::Kind op_kind) {
+// Returns array to load from.
+Value* FlowGraphOptimizer::PrepareIndexedOp(InstanceCallInstr* call,
+ intptr_t class_id) {
+ Value* array = call->ArgumentAt(0)->value();
+ Value* index = call->ArgumentAt(1)->value();
+ // Insert class check and index smi checks and attach a copy of the
+ // original environment because the operation can still deoptimize.
+ AddCheckClass(call, array->Copy());
+ InsertBefore(call,
+ new CheckSmiInstr(index->Copy(), call->deopt_id()),
+ call->env(),
+ Definition::kEffect);
+ // If both index and array are constants, then the bound check always
+ // succeeded.
+ // TODO(srdjan): Remove once constant propagation lands.
+ if (!(array->BindsToConstant() && index->BindsToConstant())) {
+ // Insert array bounds check.
+ InsertBefore(call,
+ new CheckArrayBoundInstr(array->Copy(),
+ index->Copy(),
+ class_id,
+ call),
+ call->env(),
+ Definition::kEffect);
+ }
+ if (class_id == kGrowableObjectArrayCid) {
+ // Insert data elements load.
+ LoadFieldInstr* elements =
+ new LoadFieldInstr(array->Copy(),
+ GrowableObjectArray::data_offset(),
+ Type::ZoneHandle(Type::DynamicType()));
+ elements->set_result_cid(kArrayCid);
+ InsertBefore(call, elements, NULL, Definition::kValue);
+ array = new Value(elements);
+ }
+ return array;
+}
+
+
+bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) {
// TODO(fschneider): Optimize []= operator in checked mode as well.
- if (op_kind == Token::kASSIGN_INDEX && FLAG_enable_type_checks) return false;
+ if (FLAG_enable_type_checks) return false;
+ const intptr_t class_id = ReceiverClassId(call);
+ switch (class_id) {
+ case kArrayCid:
+ case kGrowableObjectArrayCid:
+ case kFloat64ArrayCid:
+ // Acceptable store index classes.
+ break;
+ default:
+ return false;
+ }
+ Value* array = PrepareIndexedOp(call, class_id);
+ // Check if store barrier is needed.
+ bool needs_store_barrier = true;
+ if (ArgIsAlwaysSmi(*call->ic_data(), 2)) {
+ InsertBefore(call,
+ new CheckSmiInstr(call->ArgumentAt(2)->value()->Copy(),
+ call->deopt_id()),
+ call->env(),
+ Definition::kEffect);
+ needs_store_barrier = false;
+ }
+ Value* index = call->ArgumentAt(1)->value();
+ Value* value = call->ArgumentAt(2)->value();
+ Definition* array_op =
+ new StoreIndexedInstr(array, index, value,
+ needs_store_barrier, class_id, call->deopt_id());
+ call->ReplaceWith(array_op, current_iterator());
+ RemovePushArguments(call);
+ return true;
+}
+
+
+
+bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) {
const intptr_t class_id = ReceiverClassId(call);
switch (class_id) {
+ case kArrayCid:
case kImmutableArrayCid:
- // Stores are only specialized for Array and GrowableObjectArray,
- // not for ImmutableArray.
- if (op_kind == Token::kASSIGN_INDEX) return false;
- // Fall through.
- case kArrayCid:
- case kGrowableObjectArrayCid: {
- Value* array = call->ArgumentAt(0)->value();
- Value* index = call->ArgumentAt(1)->value();
- // Insert class check and index smi checks and attach a copy of the
- // original environment because the operation can still deoptimize.
- AddCheckClass(call, array->Copy());
- InsertBefore(call,
- new CheckSmiInstr(index->Copy(), call->deopt_id()),
- call->env(),
- Definition::kEffect);
- // If both index and array are constants, then the bound check always
- // succeeded.
- // TODO(srdjan): Remove once constant propagation lands.
- if (!(array->BindsToConstant() && index->BindsToConstant())) {
- // Insert array bounds check.
- InsertBefore(call,
- new CheckArrayBoundInstr(array->Copy(),
- index->Copy(),
- class_id,
- call),
- call->env(),
- Definition::kEffect);
- }
- if (class_id == kGrowableObjectArrayCid) {
- // Insert data elements load.
- LoadFieldInstr* elements =
- new LoadFieldInstr(array->Copy(),
- GrowableObjectArray::data_offset(),
- Type::ZoneHandle(Type::DynamicType()));
- elements->set_result_cid(kArrayCid);
- InsertBefore(call, elements, NULL, Definition::kValue);
- array = new Value(elements);
- }
- Definition* array_op = NULL;
- if (op_kind == Token::kINDEX) {
- array_op = new LoadIndexedInstr(array, index);
- } else {
- bool needs_store_barrier = true;
- if (ArgIsAlwaysSmi(*call->ic_data(), 2)) {
- InsertBefore(call,
- new CheckSmiInstr(call->ArgumentAt(2)->value()->Copy(),
- call->deopt_id()),
- call->env(),
- Definition::kEffect);
- needs_store_barrier = false;
- }
- Value* value = call->ArgumentAt(2)->value();
- array_op =
- new StoreIndexedInstr(array, index, value, needs_store_barrier);
- }
- call->ReplaceWith(array_op, current_iterator());
- RemovePushArguments(call);
- return true;
- }
+ case kGrowableObjectArrayCid:
+ case kFloat64ArrayCid:
+ // Acceptable load index classes.
+ break;
default:
return false;
}
+ Value* array = PrepareIndexedOp(call, class_id);
+ Value* index = call->ArgumentAt(1)->value();
+ Definition* array_op = new LoadIndexedInstr(array, index, class_id);
+ call->ReplaceWith(array_op, current_iterator());
+ RemovePushArguments(call);
+ return true;
}
@@ -960,10 +984,13 @@
void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
if (instr->HasICData() && (instr->ic_data()->NumberOfChecks() > 0)) {
const Token::Kind op_kind = instr->token_kind();
- if (Token::IsIndexOperator(op_kind) &&
- TryReplaceWithArrayOp(instr, op_kind)) {
+ if ((op_kind == Token::kASSIGN_INDEX) &&
+ TryReplaceWithStoreIndexed(instr)) {
return;
}
+ if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) {
+ return;
+ }
if (Token::IsBinaryToken(op_kind) &&
TryReplaceWithBinaryOp(instr, op_kind)) {
return;

Powered by Google App Engine
This is Rietveld 408576698