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.h" | 5 #include "vm/flow_graph.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 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 // Thus we just assume they are. | 365 // Thus we just assume they are. |
366 ASSERT(instr->IsBlockEntry() || | 366 ASSERT(instr->IsBlockEntry() || |
367 (instr->IsPhi() && instr->AsPhi()->is_alive()) || | 367 (instr->IsPhi() && instr->AsPhi()->is_alive()) || |
368 (instr->previous() != NULL)); | 368 (instr->previous() != NULL)); |
369 prev = curr; | 369 prev = curr; |
370 curr = curr->next_use(); | 370 curr = curr->next_use(); |
371 } | 371 } |
372 } | 372 } |
373 } | 373 } |
374 | 374 |
375 | 375 void FlowGraph::ComputeIsReceiverRecursive( |
376 void FlowGraph::ComputeIsReceiverRecursive(PhiInstr* phi, | 376 PhiInstr* phi, GrowableArray<PhiInstr*>* unmark) const { |
377 BitVector* processed) const { | |
378 if (phi->is_receiver() != PhiInstr::kUnknownReceiver) return; | 377 if (phi->is_receiver() != PhiInstr::kUnknownReceiver) return; |
379 if (processed->Contains(phi->ssa_temp_index())) return; | 378 phi->set_is_receiver(PhiInstr::kReceiver); |
380 processed->Add(phi->ssa_temp_index()); | |
381 for (intptr_t i = 0; i < phi->InputCount(); ++i) { | 379 for (intptr_t i = 0; i < phi->InputCount(); ++i) { |
382 Definition* def = phi->InputAt(i)->definition(); | 380 Definition* def = phi->InputAt(i)->definition(); |
383 if (def->IsParameter() && (def->AsParameter()->index() == 0)) continue; | 381 if (def->IsParameter() && (def->AsParameter()->index() == 0)) continue; |
384 if (!def->IsPhi()) { | 382 if (!def->IsPhi()) { |
385 phi->set_is_receiver(PhiInstr::kNotReceiver); | 383 phi->set_is_receiver(PhiInstr::kNotReceiver); |
386 return; | 384 break; |
387 } | 385 } |
388 ComputeIsReceiverRecursive(def->AsPhi(), processed); | 386 ComputeIsReceiverRecursive(def->AsPhi(), unmark); |
389 if (def->AsPhi()->is_receiver() == PhiInstr::kNotReceiver) { | 387 if (def->AsPhi()->is_receiver() == PhiInstr::kNotReceiver) { |
390 phi->set_is_receiver(PhiInstr::kNotReceiver); | 388 phi->set_is_receiver(PhiInstr::kNotReceiver); |
391 return; | 389 break; |
392 } | 390 } |
393 } | 391 } |
394 phi->set_is_receiver(PhiInstr::kReceiver); | 392 |
| 393 if (phi->is_receiver() == PhiInstr::kNotReceiver) { |
| 394 unmark->Add(phi); |
| 395 } |
| 396 } |
| 397 |
| 398 |
| 399 void FlowGraph::ComputeIsReceiver(PhiInstr* phi) const { |
| 400 GrowableArray<PhiInstr*> unmark; |
| 401 ComputeIsReceiverRecursive(phi, &unmark); |
| 402 |
| 403 // Now drain unmark. |
| 404 while (!unmark.is_empty()) { |
| 405 PhiInstr* phi = unmark.RemoveLast(); |
| 406 for (Value::Iterator it(phi->input_use_list()); !it.Done(); it.Advance()) { |
| 407 PhiInstr* use = it.Current()->instruction()->AsPhi(); |
| 408 if ((use != NULL) && (use->is_receiver() == PhiInstr::kReceiver)) { |
| 409 use->set_is_receiver(PhiInstr::kNotReceiver); |
| 410 unmark.Add(use); |
| 411 } |
| 412 } |
| 413 } |
395 } | 414 } |
396 | 415 |
397 | 416 |
398 bool FlowGraph::IsReceiver(Definition* def) const { | 417 bool FlowGraph::IsReceiver(Definition* def) const { |
399 if (def->IsParameter()) return (def->AsParameter()->index() == 0); | 418 if (def->IsParameter()) return (def->AsParameter()->index() == 0); |
400 if (!def->IsPhi()) return false; | 419 if (!def->IsPhi() || graph_entry()->catch_entries().is_empty()) return false; |
401 PhiInstr* phi = def->AsPhi(); | 420 PhiInstr* phi = def->AsPhi(); |
402 if (phi->is_receiver() != PhiInstr::kUnknownReceiver) { | 421 if (phi->is_receiver() != PhiInstr::kUnknownReceiver) { |
403 return (phi->is_receiver() == PhiInstr::kReceiver); | 422 return (phi->is_receiver() == PhiInstr::kReceiver); |
404 } | 423 } |
405 // Not known if this phi is the receiver yet. Compute it now. | 424 // Not known if this phi is the receiver yet. Compute it now. |
406 BitVector* processed = | 425 ComputeIsReceiver(phi); |
407 new(zone()) BitVector(zone(), max_virtual_register_number()); | |
408 ComputeIsReceiverRecursive(phi, processed); | |
409 return (phi->is_receiver() == PhiInstr::kReceiver); | 426 return (phi->is_receiver() == PhiInstr::kReceiver); |
410 } | 427 } |
411 | 428 |
412 | 429 |
413 // Use CHA to determine if the call needs a class check: if the callee's | 430 // Use CHA to determine if the call needs a class check: if the callee's |
414 // receiver is the same as the caller's receiver and there are no overriden | 431 // receiver is the same as the caller's receiver and there are no overriden |
415 // callee functions, then no class check is needed. | 432 // callee functions, then no class check is needed. |
416 bool FlowGraph::InstanceCallNeedsClassCheck(InstanceCallInstr* call, | 433 bool FlowGraph::InstanceCallNeedsClassCheck(InstanceCallInstr* call, |
417 RawFunction::Kind kind) const { | 434 RawFunction::Kind kind) const { |
418 if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) { | 435 if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) { |
(...skipping 1624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2043 ReplaceCurrentInstruction(&it, current, replacement); | 2060 ReplaceCurrentInstruction(&it, current, replacement); |
2044 changed = true; | 2061 changed = true; |
2045 } | 2062 } |
2046 } | 2063 } |
2047 } | 2064 } |
2048 return changed; | 2065 return changed; |
2049 } | 2066 } |
2050 | 2067 |
2051 | 2068 |
2052 } // namespace dart | 2069 } // namespace dart |
OLD | NEW |