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

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

Issue 10891025: Eliminate class UseVal. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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 | Annotate | Revision Log
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_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/cha.h" 7 #include "vm/cha.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/hash_map.h" 9 #include "vm/hash_map.h"
10 #include "vm/il_printer.h" 10 #include "vm/il_printer.h"
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 static bool HasOnlyTwoDouble(const ICData& ic_data) { 147 static bool HasOnlyTwoDouble(const ICData& ic_data) {
148 return (ic_data.NumberOfChecks() == 1) && 148 return (ic_data.NumberOfChecks() == 1) &&
149 ICDataHasReceiverArgumentClassIds(ic_data, kDoubleCid, kDoubleCid); 149 ICDataHasReceiverArgumentClassIds(ic_data, kDoubleCid, kDoubleCid);
150 } 150 }
151 151
152 152
153 static void RemovePushArguments(InstanceCallComp* comp) { 153 static void RemovePushArguments(InstanceCallComp* comp) {
154 // Remove original push arguments. 154 // Remove original push arguments.
155 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) { 155 for (intptr_t i = 0; i < comp->ArgumentCount(); ++i) {
156 PushArgumentInstr* push = comp->ArgumentAt(i); 156 PushArgumentInstr* push = comp->ArgumentAt(i);
157 push->ReplaceUsesWith(push->value()->AsUse()->definition()); 157 push->ReplaceUsesWith(push->value()->definition());
158 push->RemoveFromGraph(); 158 push->RemoveFromGraph();
159 } 159 }
160 } 160 }
161 161
162 162
163 // Returns true if all targets are the same. 163 // Returns true if all targets are the same.
164 // TODO(srdjan): if targets are native use their C_function to compare. 164 // TODO(srdjan): if targets are native use their C_function to compare.
165 static bool HasOneTarget(const ICData& ic_data) { 165 static bool HasOneTarget(const ICData& ic_data) {
166 ASSERT(ic_data.NumberOfChecks() > 0); 166 ASSERT(ic_data.NumberOfChecks() > 0);
167 const Function& first_target = Function::Handle(ic_data.GetTargetAt(0)); 167 const Function& first_target = Function::Handle(ic_data.GetTargetAt(0));
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // Stores are only specialized for Array and GrowableObjectArray, 217 // Stores are only specialized for Array and GrowableObjectArray,
218 // not for ImmutableArray. 218 // not for ImmutableArray.
219 if (op_kind == Token::kASSIGN_INDEX) return false; 219 if (op_kind == Token::kASSIGN_INDEX) return false;
220 // Fall through. 220 // Fall through.
221 case kArrayCid: 221 case kArrayCid:
222 case kGrowableObjectArrayCid: { 222 case kGrowableObjectArrayCid: {
223 Value* array = comp->ArgumentAt(0)->value(); 223 Value* array = comp->ArgumentAt(0)->value();
224 Value* index = comp->ArgumentAt(1)->value(); 224 Value* index = comp->ArgumentAt(1)->value();
225 // Insert class check and index smi checks and attach a copy of the 225 // Insert class check and index smi checks and attach a copy of the
226 // original environment because the operation can still deoptimize. 226 // original environment because the operation can still deoptimize.
227 AddCheckClass(instr, comp, array->CopyValue()); 227 AddCheckClass(instr, comp, array->Copy());
228 InsertBefore(instr, 228 InsertBefore(instr,
229 new CheckSmiComp(index->CopyValue(), comp), 229 new CheckSmiComp(index->Copy(), comp),
230 instr->env(), 230 instr->env(),
231 BindInstr::kUnused); 231 BindInstr::kUnused);
232 // Insert array bounds check. 232 // Insert array bounds check.
233 InsertBefore(instr, 233 InsertBefore(instr,
234 new CheckArrayBoundComp(array->CopyValue(), 234 new CheckArrayBoundComp(array->Copy(),
235 index->CopyValue(), 235 index->Copy(),
236 class_id, 236 class_id,
237 comp), 237 comp),
238 instr->env(), 238 instr->env(),
239 BindInstr::kUnused); 239 BindInstr::kUnused);
240 Computation* array_op = NULL; 240 Computation* array_op = NULL;
241 if (op_kind == Token::kINDEX) { 241 if (op_kind == Token::kINDEX) {
242 array_op = new LoadIndexedComp(array, index, class_id); 242 array_op = new LoadIndexedComp(array, index, class_id);
243 } else { 243 } else {
244 Value* value = comp->ArgumentAt(2)->value(); 244 Value* value = comp->ArgumentAt(2)->value();
245 array_op = new StoreIndexedComp(array, index, value, class_id); 245 array_op = new StoreIndexedComp(array, index, value, class_id);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 // Check that either left or right are not a smi. Result or a 341 // Check that either left or right are not a smi. Result or a
342 // binary operation with two smis is a smi not a double. 342 // binary operation with two smis is a smi not a double.
343 InsertBefore(instr, 343 InsertBefore(instr,
344 new CheckEitherNonSmiComp(left, right, comp), 344 new CheckEitherNonSmiComp(left, right, comp),
345 instr->env(), 345 instr->env(),
346 BindInstr::kUnused); 346 BindInstr::kUnused);
347 347
348 // Unbox operands. 348 // Unbox operands.
349 BindInstr* unbox_left = InsertBefore( 349 BindInstr* unbox_left = InsertBefore(
350 instr, 350 instr,
351 new UnboxDoubleComp(left->CopyValue(), comp), 351 new UnboxDoubleComp(left->Copy(), comp),
352 instr->env(), 352 instr->env(),
353 BindInstr::kUsed); 353 BindInstr::kUsed);
354 BindInstr* unbox_right = InsertBefore( 354 BindInstr* unbox_right = InsertBefore(
355 instr, 355 instr,
356 new UnboxDoubleComp(right->CopyValue(), comp), 356 new UnboxDoubleComp(right->Copy(), comp),
357 instr->env(), 357 instr->env(),
358 BindInstr::kUsed); 358 BindInstr::kUsed);
359 359
360 UnboxedDoubleBinaryOpComp* double_bin_op = 360 UnboxedDoubleBinaryOpComp* double_bin_op =
361 new UnboxedDoubleBinaryOpComp(op_kind, 361 new UnboxedDoubleBinaryOpComp(op_kind,
362 new UseVal(unbox_left), 362 new Value(unbox_left),
363 new UseVal(unbox_right)); 363 new Value(unbox_right));
364 double_bin_op->set_ic_data(comp->ic_data()); 364 double_bin_op->set_ic_data(comp->ic_data());
365 instr->set_computation(double_bin_op); 365 instr->set_computation(double_bin_op);
366 366
367 if (instr->is_used()) { 367 if (instr->is_used()) {
368 // Box result. 368 // Box result.
369 UseVal* use_val = new UseVal(instr); 369 Value* value = new Value(instr);
370 BindInstr* bind = InsertAfter(instr, 370 BindInstr* bind = InsertAfter(instr,
371 new BoxDoubleComp(use_val, comp), 371 new BoxDoubleComp(value, comp),
372 NULL, 372 NULL,
373 BindInstr::kUsed); 373 BindInstr::kUsed);
374 instr->ReplaceUsesWith(bind); 374 instr->ReplaceUsesWith(bind);
375 } 375 }
376 376
377 RemovePushArguments(comp); 377 RemovePushArguments(comp);
378 } else { 378 } else {
379 BinaryDoubleOpComp* double_bin_op = new BinaryDoubleOpComp(op_kind, comp); 379 BinaryDoubleOpComp* double_bin_op = new BinaryDoubleOpComp(op_kind, comp);
380 double_bin_op->set_ic_data(comp->ic_data()); 380 double_bin_op->set_ic_data(comp->ic_data());
381 instr->set_computation(double_bin_op); 381 instr->set_computation(double_bin_op);
382 } 382 }
383 } else if (operands_type == kMintCid) { 383 } else if (operands_type == kMintCid) {
384 Value* left = comp->ArgumentAt(0)->value(); 384 Value* left = comp->ArgumentAt(0)->value();
385 Value* right = comp->ArgumentAt(1)->value(); 385 Value* right = comp->ArgumentAt(1)->value();
386 BinaryMintOpComp* bin_op = new BinaryMintOpComp(op_kind, 386 BinaryMintOpComp* bin_op = new BinaryMintOpComp(op_kind,
387 comp, 387 comp,
388 left, 388 left,
389 right); 389 right);
390 bin_op->set_ic_data(comp->ic_data()); 390 bin_op->set_ic_data(comp->ic_data());
391 instr->set_computation(bin_op); 391 instr->set_computation(bin_op);
392 RemovePushArguments(comp); 392 RemovePushArguments(comp);
393 } else { 393 } else {
394 ASSERT(operands_type == kSmiCid); 394 ASSERT(operands_type == kSmiCid);
395 Value* left = comp->ArgumentAt(0)->value(); 395 Value* left = comp->ArgumentAt(0)->value();
396 Value* right = comp->ArgumentAt(1)->value(); 396 Value* right = comp->ArgumentAt(1)->value();
397 // Insert two smi checks and attach a copy of the original 397 // Insert two smi checks and attach a copy of the original
398 // environment because the smi operation can still deoptimize. 398 // environment because the smi operation can still deoptimize.
399 InsertBefore(instr, 399 InsertBefore(instr,
400 new CheckSmiComp(left->CopyValue(), comp), 400 new CheckSmiComp(left->Copy(), comp),
401 instr->env(), 401 instr->env(),
402 BindInstr::kUnused); 402 BindInstr::kUnused);
403 InsertBefore(instr, 403 InsertBefore(instr,
404 new CheckSmiComp(right->CopyValue(), comp), 404 new CheckSmiComp(right->Copy(), comp),
405 instr->env(), 405 instr->env(),
406 BindInstr::kUnused); 406 BindInstr::kUnused);
407 BinarySmiOpComp* bin_op = new BinarySmiOpComp(op_kind, 407 BinarySmiOpComp* bin_op = new BinarySmiOpComp(op_kind,
408 comp, 408 comp,
409 left, 409 left,
410 right); 410 right);
411 bin_op->set_ic_data(comp->ic_data()); 411 bin_op->set_ic_data(comp->ic_data());
412 instr->set_computation(bin_op); 412 instr->set_computation(bin_op);
413 RemovePushArguments(comp); 413 RemovePushArguments(comp);
414 } 414 }
415 return true; 415 return true;
416 } 416 }
417 417
418 418
419 bool FlowGraphOptimizer::TryReplaceWithUnaryOp(BindInstr* instr, 419 bool FlowGraphOptimizer::TryReplaceWithUnaryOp(BindInstr* instr,
420 InstanceCallComp* comp, 420 InstanceCallComp* comp,
421 Token::Kind op_kind) { 421 Token::Kind op_kind) {
422 if (comp->ic_data()->NumberOfChecks() != 1) { 422 if (comp->ic_data()->NumberOfChecks() != 1) {
423 // TODO(srdjan): Not yet supported. 423 // TODO(srdjan): Not yet supported.
424 return false; 424 return false;
425 } 425 }
426 ASSERT(comp->ArgumentCount() == 1); 426 ASSERT(comp->ArgumentCount() == 1);
427 Computation* unary_op = NULL; 427 Computation* unary_op = NULL;
428 if (HasOneSmi(*comp->ic_data())) { 428 if (HasOneSmi(*comp->ic_data())) {
429 Value* value = comp->ArgumentAt(0)->value(); 429 Value* value = comp->ArgumentAt(0)->value();
430 InsertBefore(instr, 430 InsertBefore(instr,
431 new CheckSmiComp(value->CopyValue(), comp), 431 new CheckSmiComp(value->Copy(), comp),
432 instr->env(), 432 instr->env(),
433 BindInstr::kUnused); 433 BindInstr::kUnused);
434 unary_op = new UnarySmiOpComp(op_kind, 434 unary_op = new UnarySmiOpComp(op_kind,
435 (op_kind == Token::kNEGATE) ? comp : NULL, 435 (op_kind == Token::kNEGATE) ? comp : NULL,
436 value); 436 value);
437 } else if (HasOneDouble(*comp->ic_data()) && (op_kind == Token::kNEGATE)) { 437 } else if (HasOneDouble(*comp->ic_data()) && (op_kind == Token::kNEGATE)) {
438 unary_op = new NumberNegateComp(comp, comp->ArgumentAt(0)->value()); 438 unary_op = new NumberNegateComp(comp, comp->ArgumentAt(0)->value());
439 } 439 }
440 if (unary_op == NULL) return false; 440 if (unary_op == NULL) return false;
441 441
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 if (!HasOneTarget(ic_data)) { 479 if (!HasOneTarget(ic_data)) {
480 // TODO(srdjan): Implement for mutiple targets. 480 // TODO(srdjan): Implement for mutiple targets.
481 return false; 481 return false;
482 } 482 }
483 // Inline implicit instance getter. 483 // Inline implicit instance getter.
484 const String& field_name = 484 const String& field_name =
485 String::Handle(Field::NameFromGetter(comp->function_name())); 485 String::Handle(Field::NameFromGetter(comp->function_name()));
486 const Field& field = Field::Handle(GetField(class_ids[0], field_name)); 486 const Field& field = Field::Handle(GetField(class_ids[0], field_name));
487 ASSERT(!field.IsNull()); 487 ASSERT(!field.IsNull());
488 488
489 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()->CopyValue()); 489 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()->Copy());
490 // Detach environment from the original instruction because it can't 490 // Detach environment from the original instruction because it can't
491 // deoptimize. 491 // deoptimize.
492 instr->set_env(NULL); 492 instr->set_env(NULL);
493 LoadInstanceFieldComp* load = 493 LoadInstanceFieldComp* load =
494 new LoadInstanceFieldComp(field, comp->ArgumentAt(0)->value()); 494 new LoadInstanceFieldComp(field, comp->ArgumentAt(0)->value());
495 instr->set_computation(load); 495 instr->set_computation(load);
496 RemovePushArguments(comp); 496 RemovePushArguments(comp);
497 return true; 497 return true;
498 } 498 }
499 499
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 } 616 }
617 const intptr_t kMaxChecks = 4; 617 const intptr_t kMaxChecks = 4;
618 if (comp->ic_data()->NumberOfChecks() <= kMaxChecks) { 618 if (comp->ic_data()->NumberOfChecks() <= kMaxChecks) {
619 const ICData& unary_checks = 619 const ICData& unary_checks =
620 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks()); 620 ICData::ZoneHandle(comp->ic_data()->AsUnaryClassChecks());
621 bool call_with_checks; 621 bool call_with_checks;
622 // TODO(srdjan): Add check class comp for mixed smi/non-smi. 622 // TODO(srdjan): Add check class comp for mixed smi/non-smi.
623 if (HasOneTarget(unary_checks) && 623 if (HasOneTarget(unary_checks) &&
624 (unary_checks.GetReceiverClassIdAt(0) != kSmiCid)) { 624 (unary_checks.GetReceiverClassIdAt(0) != kSmiCid)) {
625 // Type propagation has not run yet, we cannot eliminate the check. 625 // Type propagation has not run yet, we cannot eliminate the check.
626 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()->CopyValue()); 626 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()->Copy());
627 // Call can still deoptimize, do not detach environment from instr. 627 // Call can still deoptimize, do not detach environment from instr.
628 call_with_checks = false; 628 call_with_checks = false;
629 } else { 629 } else {
630 call_with_checks = true; 630 call_with_checks = true;
631 } 631 }
632 PolymorphicInstanceCallComp* call = 632 PolymorphicInstanceCallComp* call =
633 new PolymorphicInstanceCallComp(comp, call_with_checks); 633 new PolymorphicInstanceCallComp(comp, call_with_checks);
634 call->set_ic_data(&unary_checks); 634 call->set_ic_data(&unary_checks);
635 instr->set_computation(call); 635 instr->set_computation(call);
636 } 636 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 // Not an implicit setter. 674 // Not an implicit setter.
675 // TODO(srdjan): Inline special setters. 675 // TODO(srdjan): Inline special setters.
676 return false; 676 return false;
677 } 677 }
678 // Inline implicit instance setter. 678 // Inline implicit instance setter.
679 const String& field_name = 679 const String& field_name =
680 String::Handle(Field::NameFromSetter(comp->function_name())); 680 String::Handle(Field::NameFromSetter(comp->function_name()));
681 const Field& field = Field::Handle(GetField(class_id, field_name)); 681 const Field& field = Field::Handle(GetField(class_id, field_name));
682 ASSERT(!field.IsNull()); 682 ASSERT(!field.IsNull());
683 683
684 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()->CopyValue()); 684 AddCheckClass(instr, comp, comp->ArgumentAt(0)->value()->Copy());
685 // Detach environment from the original instruction because it can't 685 // Detach environment from the original instruction because it can't
686 // deoptimize. 686 // deoptimize.
687 instr->set_env(NULL); 687 instr->set_env(NULL);
688 StoreInstanceFieldComp* store = new StoreInstanceFieldComp( 688 StoreInstanceFieldComp* store = new StoreInstanceFieldComp(
689 field, 689 field,
690 comp->ArgumentAt(0)->value(), 690 comp->ArgumentAt(0)->value(),
691 comp->ArgumentAt(1)->value()); 691 comp->ArgumentAt(1)->value());
692 instr->set_computation(store); 692 instr->set_computation(store);
693 RemovePushArguments(comp); 693 RemovePushArguments(comp);
694 return true; 694 return true;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 758
759 759
760 void FlowGraphTypePropagator::VisitAssertAssignable(AssertAssignableComp* comp, 760 void FlowGraphTypePropagator::VisitAssertAssignable(AssertAssignableComp* comp,
761 BindInstr* instr) { 761 BindInstr* instr) {
762 if (FLAG_eliminate_type_checks && 762 if (FLAG_eliminate_type_checks &&
763 !comp->is_eliminated() && 763 !comp->is_eliminated() &&
764 comp->value()->CompileTypeIsMoreSpecificThan(comp->dst_type())) { 764 comp->value()->CompileTypeIsMoreSpecificThan(comp->dst_type())) {
765 // TODO(regis): Remove is_eliminated_ field and support. 765 // TODO(regis): Remove is_eliminated_ field and support.
766 comp->eliminate(); 766 comp->eliminate();
767 767
768 UseVal* use = comp->value()->AsUse(); 768 Value* use = comp->value();
769 ASSERT(use != NULL); 769 ASSERT(use != NULL);
770 Definition* result = use->definition(); 770 Definition* result = use->definition();
771 ASSERT(result != NULL); 771 ASSERT(result != NULL);
772 // Replace uses and remove the current instructions via the iterator. 772 // Replace uses and remove the current instructions via the iterator.
773 instr->ReplaceUsesWith(result); 773 instr->ReplaceUsesWith(result);
774 ASSERT(current_iterator()->Current() == instr); 774 ASSERT(current_iterator()->Current() == instr);
775 current_iterator()->RemoveCurrentFromGraph(); 775 current_iterator()->RemoveCurrentFromGraph();
776 if (FLAG_trace_optimization) { 776 if (FLAG_trace_optimization) {
777 OS::Print("Replacing v%d with v%d\n", 777 OS::Print("Replacing v%d with v%d\n",
778 instr->ssa_temp_index(), 778 instr->ssa_temp_index(),
(...skipping 22 matching lines...) Expand all
801 // type (bool) may still hold null at run time and therefore fail the test. 801 // type (bool) may still hold null at run time and therefore fail the test.
802 if (FLAG_eliminate_type_checks && 802 if (FLAG_eliminate_type_checks &&
803 !comp->is_eliminated() && 803 !comp->is_eliminated() &&
804 comp->value()->BindsToConstant() && 804 comp->value()->BindsToConstant() &&
805 !comp->value()->BindsToConstantNull() && 805 !comp->value()->BindsToConstantNull() &&
806 comp->value()->CompileTypeIsMoreSpecificThan( 806 comp->value()->CompileTypeIsMoreSpecificThan(
807 Type::Handle(Type::BoolType()))) { 807 Type::Handle(Type::BoolType()))) {
808 // TODO(regis): Remove is_eliminated_ field and support. 808 // TODO(regis): Remove is_eliminated_ field and support.
809 comp->eliminate(); 809 comp->eliminate();
810 810
811 UseVal* use = comp->value()->AsUse(); 811 Value* use = comp->value();
812 ASSERT(use != NULL);
813 Definition* result = use->definition(); 812 Definition* result = use->definition();
814 ASSERT(result != NULL); 813 ASSERT(result != NULL);
815 // Replace uses and remove the current instructions via the iterator. 814 // Replace uses and remove the current instructions via the iterator.
816 instr->ReplaceUsesWith(result); 815 instr->ReplaceUsesWith(result);
817 ASSERT(current_iterator()->Current() == instr); 816 ASSERT(current_iterator()->Current() == instr);
818 current_iterator()->RemoveCurrentFromGraph(); 817 current_iterator()->RemoveCurrentFromGraph();
819 if (FLAG_trace_optimization) { 818 if (FLAG_trace_optimization) {
820 OS::Print("Replacing v%d with v%d\n", 819 OS::Print("Replacing v%d with v%d\n",
821 instr->ssa_temp_index(), 820 instr->ssa_temp_index(),
822 result->ssa_temp_index()); 821 result->ssa_temp_index());
(...skipping 19 matching lines...) Expand all
842 841
843 // We can only eliminate an 'instance of' test when the checked value is 842 // We can only eliminate an 'instance of' test when the checked value is
844 // a constant time constant. Indeed, a variable of the proper compile time 843 // a constant time constant. Indeed, a variable of the proper compile time
845 // type may still hold null at run time and therefore fail the test. 844 // type may still hold null at run time and therefore fail the test.
846 // We do not bother checking for Object destination type, since the graph 845 // We do not bother checking for Object destination type, since the graph
847 // builder did already. 846 // builder did already.
848 if (FLAG_eliminate_type_checks && 847 if (FLAG_eliminate_type_checks &&
849 comp->value()->BindsToConstant() && 848 comp->value()->BindsToConstant() &&
850 !comp->value()->BindsToConstantNull() && 849 !comp->value()->BindsToConstantNull() &&
851 comp->value()->CompileTypeIsMoreSpecificThan(comp->type())) { 850 comp->value()->CompileTypeIsMoreSpecificThan(comp->type())) {
852 UseVal* use = comp->value()->AsUse(); 851 Value* use = comp->value();
853 ASSERT(use != NULL);
854 Definition* result = use->definition(); 852 Definition* result = use->definition();
855 ASSERT(result != NULL); 853 ASSERT(result != NULL);
856 // Replace uses and remove the current instructions via the iterator. 854 // Replace uses and remove the current instructions via the iterator.
857 instr->ReplaceUsesWith(result); 855 instr->ReplaceUsesWith(result);
858 ASSERT(current_iterator()->Current() == instr); 856 ASSERT(current_iterator()->Current() == instr);
859 current_iterator()->RemoveCurrentFromGraph(); 857 current_iterator()->RemoveCurrentFromGraph();
860 if (FLAG_trace_optimization) { 858 if (FLAG_trace_optimization) {
861 OS::Print("Replacing v%d with v%d\n", 859 OS::Print("Replacing v%d with v%d\n",
862 instr->ssa_temp_index(), 860 instr->ssa_temp_index(),
863 result->ssa_temp_index()); 861 result->ssa_temp_index());
(...skipping 12 matching lines...) Expand all
876 } 874 }
877 875
878 876
879 void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) { 877 void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) {
880 if (graph_entry->start_env() == NULL) { 878 if (graph_entry->start_env() == NULL) {
881 return; 879 return;
882 } 880 }
883 // Visit incoming parameters. 881 // Visit incoming parameters.
884 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) { 882 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) {
885 Value* val = graph_entry->start_env()->values()[i]; 883 Value* val = graph_entry->start_env()->values()[i];
886 if (val->IsUse()) { 884 ParameterInstr* param = val->definition()->AsParameter();
887 ParameterInstr* param = val->AsUse()->definition()->AsParameter(); 885 if (param != NULL) {
888 if (param != NULL) { 886 ASSERT(param->index() == i);
889 ASSERT(param->index() == i); 887 VisitParameter(param);
890 VisitParameter(param);
891 }
892 } 888 }
893 } 889 }
894 } 890 }
895 891
896 892
897 void FlowGraphTypePropagator::VisitJoinEntry(JoinEntryInstr* join_entry) { 893 void FlowGraphTypePropagator::VisitJoinEntry(JoinEntryInstr* join_entry) {
898 if (join_entry->phis() != NULL) { 894 if (join_entry->phis() != NULL) {
899 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { 895 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
900 PhiInstr* phi = (*join_entry->phis())[i]; 896 PhiInstr* phi = (*join_entry->phis())[i];
901 if (phi != NULL) { 897 if (phi != NULL) {
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 DirectChainedHashMap<BindInstr*> child_map(*map); // Copy map. 1065 DirectChainedHashMap<BindInstr*> child_map(*map); // Copy map.
1070 OptimizeRecursive(child, &child_map); 1066 OptimizeRecursive(child, &child_map);
1071 } else { 1067 } else {
1072 OptimizeRecursive(child, map); // Reuse map for the last child. 1068 OptimizeRecursive(child, map); // Reuse map for the last child.
1073 } 1069 }
1074 } 1070 }
1075 } 1071 }
1076 1072
1077 1073
1078 } // namespace dart 1074 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698