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

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

Issue 1851653002: Fix bug in receiver-phi computation. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698