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

Side by Side 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, 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | 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/cha.h" 7 #include "vm/cha.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/hash_map.h" 9 #include "vm/hash_map.h"
10 #include "vm/il_printer.h" 10 #include "vm/il_printer.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 OS::Print("Removing v%d.\n", instr->ssa_temp_index()); 47 OS::Print("Removing v%d.\n", instr->ssa_temp_index());
48 } 48 }
49 it.RemoveCurrentFromGraph(); 49 it.RemoveCurrentFromGraph();
50 } 50 }
51 } 51 }
52 } 52 }
53 } 53 }
54 } 54 }
55 55
56 56
57 static Computation* CreateConversion(Representation from,
58 Representation to,
59 Definition* def,
60 Instruction* deopt_target) {
61 if ((from == kUnboxedDouble) && (to == kTagged)) {
62 return new BoxDoubleComp(new Value(def), NULL);
63 } else if ((from == kTagged) && (to == kUnboxedDouble)) {
64 const intptr_t deopt_id = (deopt_target != NULL) ?
65 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
66 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid));
67 return new UnboxDoubleComp(new Value(def), deopt_id);
68 } else {
69 UNREACHABLE();
70 return NULL;
71 }
72 }
73
74
75 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) {
76 const Representation from_rep = def->representation();
77
78 for (Value* use = def->input_use_list();
79 use != NULL;
80 use = use->next_use()) {
81 const Representation to_rep =
82 use->instruction()->RequiredInputRepresentation(use->use_index());
83 if (from_rep == to_rep) {
84 continue;
85 }
86
87 Instruction* deopt_target = NULL;
88 Instruction* instr = use->instruction();
89 if (instr->IsPhi()) {
90 if (!instr->AsPhi()->is_alive()) continue;
91
92 // For phis conversions have to be inserted in the predecessor.
93 const BlockEntryInstr* pred =
94 instr->AsPhi()->block()->PredecessorAt(use->use_index());
95 instr = pred->last_instruction();
96 } else {
97 deopt_target = instr;
98 }
99
100 BindInstr* converted = InsertBefore(
101 instr,
102 CreateConversion(from_rep, to_rep, def, deopt_target),
103 use->instruction()->env(),
104 BindInstr::kUsed);
105
106 use->set_definition(converted);
107 }
108 }
109
110 void FlowGraphOptimizer::SelectRepresentations() {
111 // Convervatively unbox all phis that were proven to be of type Double.
112 for (intptr_t i = 0; i < block_order_.length(); ++i) {
113 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry();
114 if (join_entry == NULL) continue;
115
116 if (join_entry->phis() != NULL) {
117 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
118 PhiInstr* phi = (*join_entry->phis())[i];
119 if ((phi != NULL) && (phi->GetPropagatedCid() == kDoubleCid)) {
120 phi->set_representation(kUnboxedDouble);
121 }
122 }
123 }
124 }
125
126 // Process all instructions and insert conversions where needed.
127 GraphEntryInstr* graph_entry = block_order_[0]->AsGraphEntry();
128
129 // Visit incoming parameters.
130 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) {
131 Value* val = graph_entry->start_env()->values()[i];
132 InsertConversionsFor(val->definition());
133 }
134
135 for (intptr_t i = 0; i < block_order_.length(); ++i) {
136 BlockEntryInstr* entry = block_order_[i];
137
138 JoinEntryInstr* join_entry = entry->AsJoinEntry();
139 if ((join_entry != NULL) && (join_entry->phis() != NULL)) {
140 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
141 PhiInstr* phi = (*join_entry->phis())[i];
142 if ((phi != NULL) && (phi->is_alive())) {
143 InsertConversionsFor(phi);
144 }
145 }
146 }
147
148 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
149 Definition* def = it.Current()->AsDefinition();
150 if (def != NULL) {
151 InsertConversionsFor(def);
152 }
153 }
154 }
155 }
156
157
57 static bool ICDataHasReceiverClassId(const ICData& ic_data, intptr_t class_id) { 158 static bool ICDataHasReceiverClassId(const ICData& ic_data, intptr_t class_id) {
58 ASSERT(ic_data.num_args_tested() > 0); 159 ASSERT(ic_data.num_args_tested() > 0);
59 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { 160 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
60 const intptr_t test_class_id = ic_data.GetReceiverClassIdAt(i); 161 const intptr_t test_class_id = ic_data.GetReceiverClassIdAt(i);
61 if (test_class_id == class_id) { 162 if (test_class_id == class_id) {
62 return true; 163 return true;
63 } 164 }
64 } 165 }
65 return false; 166 return false;
66 } 167 }
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 435
335 ASSERT(comp->ArgumentCount() == 2); 436 ASSERT(comp->ArgumentCount() == 2);
336 if (operands_type == kDoubleCid) { 437 if (operands_type == kDoubleCid) {
337 if (FLAG_use_unboxed_doubles) { 438 if (FLAG_use_unboxed_doubles) {
338 Value* left = comp->ArgumentAt(0)->value(); 439 Value* left = comp->ArgumentAt(0)->value();
339 Value* right = comp->ArgumentAt(1)->value(); 440 Value* right = comp->ArgumentAt(1)->value();
340 441
341 // Check that either left or right are not a smi. Result or a 442 // Check that either left or right are not a smi. Result or a
342 // binary operation with two smis is a smi not a double. 443 // binary operation with two smis is a smi not a double.
343 InsertBefore(instr, 444 InsertBefore(instr,
344 new CheckEitherNonSmiComp(left, right, comp), 445 new CheckEitherNonSmiComp(left->Copy(),
446 right->Copy(),
447 comp),
345 instr->env(), 448 instr->env(),
346 BindInstr::kUnused); 449 BindInstr::kUnused);
347 450
348 // Unbox operands.
349 BindInstr* unbox_left = InsertBefore(
350 instr,
351 new UnboxDoubleComp(left->Copy(), comp),
352 instr->env(),
353 BindInstr::kUsed);
354 BindInstr* unbox_right = InsertBefore(
355 instr,
356 new UnboxDoubleComp(right->Copy(), comp),
357 instr->env(),
358 BindInstr::kUsed);
359
360 UnboxedDoubleBinaryOpComp* double_bin_op = 451 UnboxedDoubleBinaryOpComp* double_bin_op =
361 new UnboxedDoubleBinaryOpComp(op_kind, 452 new UnboxedDoubleBinaryOpComp(op_kind,
362 new Value(unbox_left), 453 left->Copy(),
363 new Value(unbox_right)); 454 right->Copy(),
455 comp);
364 double_bin_op->set_ic_data(comp->ic_data()); 456 double_bin_op->set_ic_data(comp->ic_data());
365 instr->set_computation(double_bin_op); 457 instr->set_computation(double_bin_op);
366 458
367 if (instr->is_used()) {
368 // Box result.
369 Value* value = new Value(instr);
370 BindInstr* bind = InsertAfter(instr,
371 new BoxDoubleComp(value, comp),
372 NULL,
373 BindInstr::kUsed);
374 instr->ReplaceUsesWith(bind);
375 }
376
377 RemovePushArguments(comp); 459 RemovePushArguments(comp);
378 } else { 460 } else {
379 BinaryDoubleOpComp* double_bin_op = new BinaryDoubleOpComp(op_kind, comp); 461 BinaryDoubleOpComp* double_bin_op = new BinaryDoubleOpComp(op_kind, comp);
380 double_bin_op->set_ic_data(comp->ic_data()); 462 double_bin_op->set_ic_data(comp->ic_data());
381 instr->set_computation(double_bin_op); 463 instr->set_computation(double_bin_op);
382 } 464 }
383 } else if (operands_type == kMintCid) { 465 } else if (operands_type == kMintCid) {
384 Value* left = comp->ArgumentAt(0)->value(); 466 Value* left = comp->ArgumentAt(0)->value();
385 Value* right = comp->ArgumentAt(1)->value(); 467 Value* right = comp->ArgumentAt(1)->value();
386 BinaryMintOpComp* bin_op = new BinaryMintOpComp(op_kind, 468 BinaryMintOpComp* bin_op = new BinaryMintOpComp(op_kind,
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 DirectChainedHashMap<BindInstr*> child_map(*map); // Copy map. 1148 DirectChainedHashMap<BindInstr*> child_map(*map); // Copy map.
1067 OptimizeRecursive(child, &child_map); 1149 OptimizeRecursive(child, &child_map);
1068 } else { 1150 } else {
1069 OptimizeRecursive(child, map); // Reuse map for the last child. 1151 OptimizeRecursive(child, map); // Reuse map for the last child.
1070 } 1152 }
1071 } 1153 }
1072 } 1154 }
1073 1155
1074 1156
1075 } // namespace dart 1157 } // namespace dart
OLDNEW
« 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