| 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 |