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 |