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

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

Issue 12178019: Add a use list iterator that allows mutation of current. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 10 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 ASSERT((replacement == NULL) || current->IsDefinition()); 217 ASSERT((replacement == NULL) || current->IsDefinition());
218 ReplaceCurrentInstruction(&it, current, replacement, flow_graph_); 218 ReplaceCurrentInstruction(&it, current, replacement, flow_graph_);
219 } 219 }
220 } 220 }
221 } 221 }
222 } 222 }
223 223
224 224
225 void FlowGraphOptimizer::InsertConversion(Representation from, 225 void FlowGraphOptimizer::InsertConversion(Representation from,
226 Representation to, 226 Representation to,
227 Instruction* instr,
228 Value* use, 227 Value* use,
229 Definition* def, 228 Instruction* insert_before,
230 Instruction* deopt_target) { 229 Instruction* deopt_target) {
231 Definition* converted = NULL; 230 Definition* converted = NULL;
232 if ((from == kTagged) && (to == kUnboxedMint)) { 231 if ((from == kTagged) && (to == kUnboxedMint)) {
232 ASSERT((deopt_target != NULL) ||
233 (use->definition()->GetPropagatedCid() == kDoubleCid));
233 const intptr_t deopt_id = (deopt_target != NULL) ? 234 const intptr_t deopt_id = (deopt_target != NULL) ?
234 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 235 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
235 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid)); 236 converted = new UnboxIntegerInstr(new Value(use->definition()), deopt_id);
236 converted = new UnboxIntegerInstr(new Value(def), deopt_id);
237 } else if ((from == kUnboxedMint) && (to == kTagged)) { 237 } else if ((from == kUnboxedMint) && (to == kTagged)) {
238 converted = new BoxIntegerInstr(new Value(def)); 238 converted = new BoxIntegerInstr(new Value(use->definition()));
239 } else if (from == kUnboxedMint && to == kUnboxedDouble) { 239 } else if (from == kUnboxedMint && to == kUnboxedDouble) {
240 // Convert by boxing/unboxing. 240 // Convert by boxing/unboxing.
241 // TODO(fschneider): Implement direct unboxed mint-to-double conversion. 241 // TODO(fschneider): Implement direct unboxed mint-to-double conversion.
242 BoxIntegerInstr* boxed = new BoxIntegerInstr(new Value(def)); 242 BoxIntegerInstr* boxed = new BoxIntegerInstr(new Value(use->definition()));
243 InsertBefore(instr, boxed, NULL, Definition::kValue); 243 InsertBefore(insert_before, boxed, NULL, Definition::kValue);
244 const intptr_t deopt_id = (deopt_target != NULL) ? 244 const intptr_t deopt_id = (deopt_target != NULL) ?
245 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 245 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
246 converted = new UnboxDoubleInstr(new Value(boxed), deopt_id); 246 converted = new UnboxDoubleInstr(new Value(boxed), deopt_id);
247 } else if ((from == kUnboxedDouble) && (to == kTagged)) { 247 } else if ((from == kUnboxedDouble) && (to == kTagged)) {
248 converted = new BoxDoubleInstr(new Value(def), NULL); 248 converted = new BoxDoubleInstr(new Value(use->definition()), NULL);
249 } else if ((from == kTagged) && (to == kUnboxedDouble)) { 249 } else if ((from == kTagged) && (to == kUnboxedDouble)) {
250 const intptr_t deopt_id = (deopt_target != NULL) ? 250 const intptr_t deopt_id = (deopt_target != NULL) ?
251 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 251 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
252 ASSERT((deopt_target != NULL) || (def->GetPropagatedCid() == kDoubleCid)); 252 ASSERT((deopt_target != NULL) ||
253 if (def->IsConstant() && def->AsConstant()->value().IsSmi()) { 253 (use->definition()->GetPropagatedCid() == kDoubleCid));
254 const double dbl_val = 254 ConstantInstr* constant = use->definition()->AsConstant();
255 Smi::Cast(def->AsConstant()->value()).AsDoubleValue(); 255 if ((constant != NULL) && constant->value().IsSmi()) {
256 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue();
256 const Double& dbl_obj = 257 const Double& dbl_obj =
257 Double::ZoneHandle(Double::New(dbl_val, Heap::kOld)); 258 Double::ZoneHandle(Double::New(dbl_val, Heap::kOld));
258 ConstantInstr* double_const = new ConstantInstr(dbl_obj); 259 ConstantInstr* double_const = new ConstantInstr(dbl_obj);
259 InsertBefore(instr, double_const, NULL, Definition::kValue); 260 InsertBefore(insert_before, double_const, NULL, Definition::kValue);
260 converted = new UnboxDoubleInstr(new Value(double_const), deopt_id); 261 converted = new UnboxDoubleInstr(new Value(double_const), deopt_id);
261 } else { 262 } else {
262 converted = new UnboxDoubleInstr(new Value(def), deopt_id); 263 converted = new UnboxDoubleInstr(new Value(use->definition()), deopt_id);
263 } 264 }
264 } 265 }
265 ASSERT(converted != NULL); 266 ASSERT(converted != NULL);
266 InsertBefore(instr, converted, use->instruction()->env(), 267 InsertBefore(insert_before, converted, use->instruction()->env(),
267 Definition::kValue); 268 Definition::kValue);
268 use->set_definition(converted); 269 use->set_definition(converted);
269 } 270 }
270 271
271 272
272 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { 273 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) {
273 const Representation from_rep = def->representation(); 274 const Representation from_rep = def->representation();
274 275
275 for (Value* use = def->input_use_list(); 276 for (Value::Iterator it(def->input_use_list());
276 use != NULL; 277 !it.Done();
277 use = use->next_use()) { 278 it.Advance()) {
279 Value* use = it.Current();
278 const Representation to_rep = 280 const Representation to_rep =
279 use->instruction()->RequiredInputRepresentation(use->use_index()); 281 use->instruction()->RequiredInputRepresentation(use->use_index());
280 if (from_rep == to_rep) { 282 if (from_rep == to_rep) {
281 continue; 283 continue;
282 } 284 }
283 285
284 Instruction* deopt_target = NULL; 286 Instruction* insert_before;
285 Instruction* instr = use->instruction(); 287 Instruction* deopt_target;
286 if (instr->IsPhi()) { 288 PhiInstr* phi = use->instruction()->AsPhi();
287 if (!instr->AsPhi()->is_alive()) continue; 289 if (phi != NULL) {
290 if (!phi->is_alive()) continue;
288 291
289 // For phis conversions have to be inserted in the predecessor. 292 // For phis conversions have to be inserted in the predecessor.
290 const BlockEntryInstr* pred = 293 insert_before =
291 instr->AsPhi()->block()->PredecessorAt(use->use_index()); 294 phi->block()->PredecessorAt(use->use_index())->last_instruction();
292 instr = pred->last_instruction(); 295 deopt_target = NULL;
293 } else { 296 } else {
294 deopt_target = instr; 297 deopt_target = insert_before = use->instruction();
295 } 298 }
296 299
297 InsertConversion(from_rep, to_rep, instr, use, def, deopt_target); 300 InsertConversion(from_rep, to_rep, use, insert_before, deopt_target);
298 } 301 }
299 } 302 }
300 303
301 304
302 void FlowGraphOptimizer::SelectRepresentations() { 305 void FlowGraphOptimizer::SelectRepresentations() {
303 // Convervatively unbox all phis that were proven to be of type Double. 306 // Convervatively unbox all phis that were proven to be of type Double.
304 for (intptr_t i = 0; i < block_order_.length(); ++i) { 307 for (intptr_t i = 0; i < block_order_.length(); ++i) {
305 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); 308 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry();
306 if (join_entry == NULL) continue; 309 if (join_entry == NULL) continue;
307 310
(...skipping 1884 matching lines...) Expand 10 before | Expand all | Expand 10 after
2192 return false; 2195 return false;
2193 } 2196 }
2194 2197
2195 return dom_block->Dominates(use_block); 2198 return dom_block->Dominates(use_block);
2196 } 2199 }
2197 2200
2198 2201
2199 void RangeAnalysis::RenameDominatedUses(Definition* def, 2202 void RangeAnalysis::RenameDominatedUses(Definition* def,
2200 Instruction* dom, 2203 Instruction* dom,
2201 Definition* other) { 2204 Definition* other) {
2202 Value* next_use = NULL; 2205 for (Value::Iterator it(def->input_use_list());
2203 for (Value* use = def->input_use_list(); 2206 !it.Done();
2204 use != NULL; 2207 it.Advance()) {
2205 use = next_use) { 2208 Value* use = it.Current();
2206 next_use = use->next_use();
2207 2209
2208 // Skip dead phis. 2210 // Skip dead phis.
2209 PhiInstr* phi = use->instruction()->AsPhi(); 2211 PhiInstr* phi = use->instruction()->AsPhi();
2210 if ((phi != NULL) && !phi->is_alive()) continue; 2212 if ((phi != NULL) && !phi->is_alive()) continue;
2211 2213
2212 if (IsDominatedUse(dom, use)) { 2214 if (IsDominatedUse(dom, use)) {
2213 use->RemoveFromUseList(); 2215 use->RemoveFromUseList();
2214 use->set_definition(other); 2216 use->set_definition(other);
2215 other->AddInputUse(use); 2217 other->AddInputUse(use);
2216 } 2218 }
(...skipping 2342 matching lines...) Expand 10 before | Expand all | Expand 10 after
4559 4561
4560 if (FLAG_trace_constant_propagation) { 4562 if (FLAG_trace_constant_propagation) {
4561 OS::Print("\n==== After constant propagation ====\n"); 4563 OS::Print("\n==== After constant propagation ====\n");
4562 FlowGraphPrinter printer(*graph_); 4564 FlowGraphPrinter printer(*graph_);
4563 printer.PrintBlocks(); 4565 printer.PrintBlocks();
4564 } 4566 }
4565 } 4567 }
4566 4568
4567 4569
4568 } // namespace dart 4570 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698