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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 10919008: Unbox phis that were proven to be of type Double. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Srdjan's comments Created 8 years, 4 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_optimizer.cc
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 45a2670e554bbd70d2ba864751c7bc3f2ffae6ff..9f67fa2ca1f0785be8960a591f57a520f01f2df3 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -54,6 +54,107 @@ void FlowGraphOptimizer::OptimizeComputations() {
}
+static Computation* CreateConversion(Representation from,
+ Representation to,
+ Definition* def,
+ Instruction* deopt_target) {
+ if ((from == kUnboxedDouble) && (to == kTagged)) {
+ return new BoxDoubleComp(new Value(def), NULL);
+ } else if ((from == kTagged) && (to == kUnboxedDouble)) {
+ const intptr_t deopt_id = (deopt_target != NULL) ?
+ deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
+ ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid));
+ return new UnboxDoubleComp(new Value(def), deopt_id);
+ } else {
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
+void FlowGraphOptimizer::InsertConversionsFor(Definition* def) {
+ const Representation from_rep = def->representation();
+
+ for (Value* use = def->input_use_list();
+ use != NULL;
+ use = use->next_use()) {
+ const Representation to_rep =
+ use->instruction()->RequiredInputRepresentation(use->use_index());
+ if (from_rep == to_rep) {
+ continue;
+ }
+
+ Instruction* deopt_target = NULL;
+ Instruction* instr = use->instruction();
+ if (instr->IsPhi()) {
+ if (!instr->AsPhi()->is_alive()) continue;
+
+ // For phis conversions have to be inserted in the predecessor.
+ const BlockEntryInstr* pred =
+ instr->AsPhi()->block()->PredecessorAt(use->use_index());
+ instr = pred->last_instruction();
+ } else {
+ deopt_target = instr;
+ }
+
+ BindInstr* converted = InsertBefore(
+ instr,
+ CreateConversion(from_rep, to_rep, def, deopt_target),
+ use->instruction()->env(),
+ BindInstr::kUsed);
+
+ use->set_definition(converted);
+ }
+}
+
+void FlowGraphOptimizer::SelectRepresentations() {
+ // Convervatively unbox all phis that were proven to be of type Double.
+ for (intptr_t i = 0; i < block_order_.length(); ++i) {
+ JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry();
+ if (join_entry == NULL) continue;
+
+ if (join_entry->phis() != NULL) {
+ for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
+ PhiInstr* phi = (*join_entry->phis())[i];
+ if ((phi != NULL) && (phi->GetPropagatedCid() == kDoubleCid)) {
+ phi->set_representation(kUnboxedDouble);
+ }
+ }
+ }
+ }
+
+ // Process all instructions and insert conversions where needed.
+ GraphEntryInstr* graph_entry = block_order_[0]->AsGraphEntry();
+
+ // Visit incoming parameters.
+ for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) {
+ Value* val = graph_entry->start_env()->values()[i];
+ InsertConversionsFor(val->definition());
+ }
+
+ for (intptr_t i = 0; i < block_order_.length(); ++i) {
+ BlockEntryInstr* entry = block_order_[i];
+
+ JoinEntryInstr* join_entry = entry->AsJoinEntry();
+ if ((join_entry != NULL) && (join_entry->phis() != NULL)) {
+ for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
+ PhiInstr* phi = (*join_entry->phis())[i];
+ if ((phi != NULL) && (phi->is_alive())) {
+ InsertConversionsFor(phi);
+ }
+ }
+ }
+
+ for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+ Definition* def = it.Current()->AsDefinition();
+ if (def != NULL) {
+ InsertConversionsFor(def);
+ }
+ }
+ }
+}
+
+
static bool ICDataHasReceiverClassId(const ICData& ic_data, intptr_t class_id) {
ASSERT(ic_data.num_args_tested() > 0);
for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
@@ -341,39 +442,20 @@ bool FlowGraphOptimizer::TryReplaceWithBinaryOp(BindInstr* instr,
// Check that either left or right are not a smi. Result or a
// binary operation with two smis is a smi not a double.
InsertBefore(instr,
- new CheckEitherNonSmiComp(left, right, comp),
+ new CheckEitherNonSmiComp(left->Copy(),
+ right->Copy(),
+ comp),
instr->env(),
BindInstr::kUnused);
- // Unbox operands.
- BindInstr* unbox_left = InsertBefore(
- instr,
- new UnboxDoubleComp(left->Copy(), comp),
- instr->env(),
- BindInstr::kUsed);
- BindInstr* unbox_right = InsertBefore(
- instr,
- new UnboxDoubleComp(right->Copy(), comp),
- instr->env(),
- BindInstr::kUsed);
-
UnboxedDoubleBinaryOpComp* double_bin_op =
new UnboxedDoubleBinaryOpComp(op_kind,
- new Value(unbox_left),
- new Value(unbox_right));
+ left->Copy(),
+ right->Copy(),
+ comp);
double_bin_op->set_ic_data(comp->ic_data());
instr->set_computation(double_bin_op);
- if (instr->is_used()) {
- // Box result.
- Value* value = new Value(instr);
- BindInstr* bind = InsertAfter(instr,
- new BoxDoubleComp(value, comp),
- NULL,
- BindInstr::kUsed);
- instr->ReplaceUsesWith(bind);
- }
-
RemovePushArguments(comp);
} else {
BinaryDoubleOpComp* double_bin_op = new BinaryDoubleOpComp(op_kind, comp);
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698