Chromium Code Reviews| 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 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 |
| 376 void FlowGraph::ComputeIsReceiverRecursive(PhiInstr* phi, | 376 void FlowGraph::ComputeIsReceiver() const { |
| 377 BitVector* processed) const { | 377 GrowableArray<PhiInstr*> worklist; |
| 378 if (phi->is_receiver() != PhiInstr::kUnknownReceiver) return; | 378 BitVector* processed = |
| 379 if (processed->Contains(phi->ssa_temp_index())) return; | 379 new(zone()) BitVector(zone(), max_virtual_register_number()); |
| 380 processed->Add(phi->ssa_temp_index()); | 380 for (BlockIterator block_it = reverse_postorder_iterator(); |
| 381 for (intptr_t i = 0; i < phi->InputCount(); ++i) { | 381 !block_it.Done(); |
| 382 Definition* def = phi->InputAt(i)->definition(); | 382 block_it.Advance()) { |
| 383 if (def->IsParameter() && (def->AsParameter()->index() == 0)) continue; | 383 BlockEntryInstr* entry = block_it.Current(); |
| 384 if (!def->IsPhi()) { | 384 JoinEntryInstr* join_entry = entry->AsJoinEntry(); |
| 385 phi->set_is_receiver(PhiInstr::kNotReceiver); | 385 if (join_entry != NULL) { |
| 386 return; | 386 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) { |
| 387 } | 387 PhiInstr* phi = it.Current(); |
| 388 ComputeIsReceiverRecursive(def->AsPhi(), processed); | 388 phi->set_is_receiver(PhiInstr::kReceiver); |
| 389 if (def->AsPhi()->is_receiver() == PhiInstr::kNotReceiver) { | 389 for (intptr_t i = 0; i < phi->InputCount(); ++i) { |
| 390 phi->set_is_receiver(PhiInstr::kNotReceiver); | 390 Definition* def = phi->InputAt(i)->definition(); |
| 391 return; | 391 if (def->IsParameter() && (def->AsParameter()->index() == 0)) { |
| 392 continue; | |
| 393 } | |
| 394 if (!def->IsPhi()) { | |
| 395 phi->set_is_receiver(PhiInstr::kNotReceiver); | |
| 396 worklist.Add(phi); | |
| 397 processed->Add(phi->ssa_temp_index()); | |
| 398 break; | |
| 399 } | |
| 400 } | |
| 401 } | |
| 392 } | 402 } |
| 393 } | 403 } |
| 394 phi->set_is_receiver(PhiInstr::kReceiver); | 404 |
| 405 while (!worklist.is_empty()) { | |
| 406 PhiInstr* phi = worklist.RemoveLast(); | |
| 407 for (Value::Iterator it(phi->input_use_list()); | |
| 408 !it.Done(); | |
| 409 it.Advance()) { | |
| 410 PhiInstr* use = it.Current()->instruction()->AsPhi(); | |
| 411 if ((use != NULL) && !processed->Contains(use->ssa_temp_index())) { | |
| 412 use->set_is_receiver(PhiInstr::kNotReceiver); | |
| 413 worklist.Add(use); | |
| 414 processed->Add(use->ssa_temp_index()); | |
| 415 } | |
| 416 } | |
| 417 } | |
| 395 } | 418 } |
| 396 | 419 |
| 397 | 420 |
| 398 bool FlowGraph::IsReceiver(Definition* def) const { | 421 bool FlowGraph::IsReceiver(Definition* def) const { |
| 399 if (def->IsParameter()) return (def->AsParameter()->index() == 0); | 422 if (def->IsParameter()) return (def->AsParameter()->index() == 0); |
| 400 if (!def->IsPhi()) return false; | 423 if (!def->IsPhi()) return false; |
| 401 PhiInstr* phi = def->AsPhi(); | 424 PhiInstr* phi = def->AsPhi(); |
| 402 if (phi->is_receiver() != PhiInstr::kUnknownReceiver) { | 425 if (phi->is_receiver() != PhiInstr::kUnknownReceiver) { |
| 403 return (phi->is_receiver() == PhiInstr::kReceiver); | 426 return (phi->is_receiver() == PhiInstr::kReceiver); |
| 404 } | 427 } |
| 405 // Not known if this phi is the receiver yet. Compute it now. | 428 // Not known if this phi is the receiver yet. Compute it now. |
| 406 BitVector* processed = | 429 ComputeIsReceiver(); |
|
Vyacheslav Egorov (Google)
2016/04/01 11:07:59
I still think it is much better to just fix the ex
| |
| 407 new(zone()) BitVector(zone(), max_virtual_register_number()); | |
| 408 ComputeIsReceiverRecursive(phi, processed); | |
| 409 return (phi->is_receiver() == PhiInstr::kReceiver); | 430 return (phi->is_receiver() == PhiInstr::kReceiver); |
| 410 } | 431 } |
| 411 | 432 |
| 412 | 433 |
| 413 // Use CHA to determine if the call needs a class check: if the callee's | 434 // 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 | 435 // receiver is the same as the caller's receiver and there are no overriden |
| 415 // callee functions, then no class check is needed. | 436 // callee functions, then no class check is needed. |
| 416 bool FlowGraph::InstanceCallNeedsClassCheck(InstanceCallInstr* call, | 437 bool FlowGraph::InstanceCallNeedsClassCheck(InstanceCallInstr* call, |
| 417 RawFunction::Kind kind) const { | 438 RawFunction::Kind kind) const { |
| 418 if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) { | 439 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); | 2064 ReplaceCurrentInstruction(&it, current, replacement); |
| 2044 changed = true; | 2065 changed = true; |
| 2045 } | 2066 } |
| 2046 } | 2067 } |
| 2047 } | 2068 } |
| 2048 return changed; | 2069 return changed; |
| 2049 } | 2070 } |
| 2050 | 2071 |
| 2051 | 2072 |
| 2052 } // namespace dart | 2073 } // namespace dart |
| OLD | NEW |