OLD | NEW |
---|---|
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 Loading... | |
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* CreateConvertion(Representation from, | |
58 Representation to, | |
59 Definition* def, | |
60 Instruction* deopt_target) { | |
srdjan
2012/08/30 17:59:24
s/Convertion/Conversion/
Vyacheslav Egorov (Google)
2012/09/21 12:51:52
Done.
| |
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 CreateConvertion(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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |