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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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/constant_propagator.h ('k') | runtime/vm/constants_arm.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/constant_propagator.h" 5 #include "vm/constant_propagator.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/flow_graph_compiler.h" 9 #include "vm/flow_graph_compiler.h"
10 #include "vm/flow_graph_range_analysis.h" 10 #include "vm/flow_graph_range_analysis.h"
11 #include "vm/il_printer.h" 11 #include "vm/il_printer.h"
12 #include "vm/intermediate_language.h" 12 #include "vm/intermediate_language.h"
13 #include "vm/parser.h" 13 #include "vm/parser.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis."); 18 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis.");
19 DEFINE_FLAG(bool, trace_constant_propagation, false, 19 DEFINE_FLAG(bool,
20 "Print constant propagation and useless code elimination."); 20 trace_constant_propagation,
21 false,
22 "Print constant propagation and useless code elimination.");
21 23
22 // Quick access to the current zone and isolate. 24 // Quick access to the current zone and isolate.
23 #define I (isolate()) 25 #define I (isolate())
24 #define Z (graph_->zone()) 26 #define Z (graph_->zone())
25 27
26 28
27 ConstantPropagator::ConstantPropagator( 29 ConstantPropagator::ConstantPropagator(
28 FlowGraph* graph, 30 FlowGraph* graph,
29 const GrowableArray<BlockEntryInstr*>& ignored) 31 const GrowableArray<BlockEntryInstr*>& ignored)
30 : FlowGraphVisitor(ignored), 32 : FlowGraphVisitor(ignored),
31 graph_(graph), 33 graph_(graph),
32 unknown_(Object::unknown_constant()), 34 unknown_(Object::unknown_constant()),
33 non_constant_(Object::non_constant()), 35 non_constant_(Object::non_constant()),
34 reachable_(new(Z) BitVector( 36 reachable_(new (Z) BitVector(Z, graph->preorder().length())),
35 Z, graph->preorder().length())), 37 marked_phis_(new (Z) BitVector(Z, graph->max_virtual_register_number())),
36 marked_phis_(new(Z) BitVector(
37 Z, graph->max_virtual_register_number())),
38 block_worklist_(), 38 block_worklist_(),
39 definition_worklist_(graph, 10) {} 39 definition_worklist_(graph, 10) {}
40 40
41 41
42 void ConstantPropagator::Optimize(FlowGraph* graph) { 42 void ConstantPropagator::Optimize(FlowGraph* graph) {
43 GrowableArray<BlockEntryInstr*> ignored; 43 GrowableArray<BlockEntryInstr*> ignored;
44 ConstantPropagator cp(graph, ignored); 44 ConstantPropagator cp(graph, ignored);
45 cp.Analyze(); 45 cp.Analyze();
46 cp.Transform(); 46 cp.Transform();
47 } 47 }
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 } 228 }
229 } 229 }
230 } 230 }
231 } 231 }
232 232
233 233
234 // -------------------------------------------------------------------------- 234 // --------------------------------------------------------------------------
235 // Analysis of non-definition instructions. They do not have values so they 235 // Analysis of non-definition instructions. They do not have values so they
236 // cannot have constant values. 236 // cannot have constant values.
237 void ConstantPropagator::VisitCheckStackOverflow( 237 void ConstantPropagator::VisitCheckStackOverflow(
238 CheckStackOverflowInstr* instr) { } 238 CheckStackOverflowInstr* instr) {}
239 239
240 240
241 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) { } 241 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) {}
242 242
243 243
244 void ConstantPropagator::VisitCheckClassId(CheckClassIdInstr* instr) { } 244 void ConstantPropagator::VisitCheckClassId(CheckClassIdInstr* instr) {}
245 245
246 246
247 void ConstantPropagator::VisitGuardFieldClass(GuardFieldClassInstr* instr) { } 247 void ConstantPropagator::VisitGuardFieldClass(GuardFieldClassInstr* instr) {}
248 248
249 249
250 void ConstantPropagator::VisitGuardFieldLength(GuardFieldLengthInstr* instr) { } 250 void ConstantPropagator::VisitGuardFieldLength(GuardFieldLengthInstr* instr) {}
251 251
252 252
253 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) { } 253 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) {}
254 254
255 255
256 void ConstantPropagator::VisitGenericCheckBound(GenericCheckBoundInstr* instr) { 256 void ConstantPropagator::VisitGenericCheckBound(GenericCheckBoundInstr* instr) {
257 } 257 }
258 258
259 259
260 void ConstantPropagator::VisitCheckEitherNonSmi( 260 void ConstantPropagator::VisitCheckEitherNonSmi(CheckEitherNonSmiInstr* instr) {
261 CheckEitherNonSmiInstr* instr) { } 261 }
262 262
263 263
264 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) { } 264 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) {}
265 265
266 266
267 void ConstantPropagator::VisitDeoptimize(DeoptimizeInstr* instr) { 267 void ConstantPropagator::VisitDeoptimize(DeoptimizeInstr* instr) {
268 // TODO(vegorov) remove all code after DeoptimizeInstr as dead. 268 // TODO(vegorov) remove all code after DeoptimizeInstr as dead.
269 } 269 }
270 270
271 void ConstantPropagator::VisitGrowRegExpStack(GrowRegExpStackInstr* instr) { } 271 void ConstantPropagator::VisitGrowRegExpStack(GrowRegExpStackInstr* instr) {}
272 272
273 Definition* ConstantPropagator::UnwrapPhi(Definition* defn) { 273 Definition* ConstantPropagator::UnwrapPhi(Definition* defn) {
274 if (defn->IsPhi()) { 274 if (defn->IsPhi()) {
275 JoinEntryInstr* block = defn->AsPhi()->block(); 275 JoinEntryInstr* block = defn->AsPhi()->block();
276 276
277 Definition* input = NULL; 277 Definition* input = NULL;
278 for (intptr_t i = 0; i < defn->InputCount(); ++i) { 278 for (intptr_t i = 0; i < defn->InputCount(); ++i) {
279 if (reachable_->Contains(block->PredecessorAt(i)->preorder_number())) { 279 if (reachable_->Contains(block->PredecessorAt(i)->preorder_number())) {
280 if (input == NULL) { 280 if (input == NULL) {
281 input = defn->InputAt(i)->definition(); 281 input = defn->InputAt(i)->definition();
(...skipping 20 matching lines...) Expand all
302 // Analysis of definitions. Compute the constant value. If it has changed 302 // Analysis of definitions. Compute the constant value. If it has changed
303 // and the definition has input uses, add the definition to the definition 303 // and the definition has input uses, add the definition to the definition
304 // worklist so that the used can be processed. 304 // worklist so that the used can be processed.
305 void ConstantPropagator::VisitPhi(PhiInstr* instr) { 305 void ConstantPropagator::VisitPhi(PhiInstr* instr) {
306 // Compute the join over all the reachable predecessor values. 306 // Compute the join over all the reachable predecessor values.
307 JoinEntryInstr* block = instr->block(); 307 JoinEntryInstr* block = instr->block();
308 Object& value = Object::ZoneHandle(Z, Unknown()); 308 Object& value = Object::ZoneHandle(Z, Unknown());
309 for (intptr_t pred_idx = 0; pred_idx < instr->InputCount(); ++pred_idx) { 309 for (intptr_t pred_idx = 0; pred_idx < instr->InputCount(); ++pred_idx) {
310 if (reachable_->Contains( 310 if (reachable_->Contains(
311 block->PredecessorAt(pred_idx)->preorder_number())) { 311 block->PredecessorAt(pred_idx)->preorder_number())) {
312 Join(&value, 312 Join(&value, instr->InputAt(pred_idx)->definition()->constant_value());
313 instr->InputAt(pred_idx)->definition()->constant_value());
314 } 313 }
315 } 314 }
316 if (!SetValue(instr, value) && 315 if (!SetValue(instr, value) &&
317 marked_phis_->Contains(instr->ssa_temp_index())) { 316 marked_phis_->Contains(instr->ssa_temp_index())) {
318 marked_phis_->Remove(instr->ssa_temp_index()); 317 marked_phis_->Remove(instr->ssa_temp_index());
319 definition_worklist_.Add(instr); 318 definition_worklist_.Add(instr);
320 } 319 }
321 } 320 }
322 321
323 322
324 void ConstantPropagator::VisitRedefinition(RedefinitionInstr* instr) { 323 void ConstantPropagator::VisitRedefinition(RedefinitionInstr* instr) {
325 // Ensure that we never remove redefinition of a constant unless we are also 324 // Ensure that we never remove redefinition of a constant unless we are also
326 // are guaranteed to fold away code paths that correspond to non-matching 325 // are guaranteed to fold away code paths that correspond to non-matching
327 // class ids. Otherwise LICM might potentially hoist incorrect code. 326 // class ids. Otherwise LICM might potentially hoist incorrect code.
328 const Object& value = instr->value()->definition()->constant_value(); 327 const Object& value = instr->value()->definition()->constant_value();
329 if (IsConstant(value) && 328 if (IsConstant(value) && !Field::IsExternalizableCid(value.GetClassId())) {
330 !Field::IsExternalizableCid(value.GetClassId())) {
331 SetValue(instr, value); 329 SetValue(instr, value);
332 } else { 330 } else {
333 SetValue(instr, non_constant_); 331 SetValue(instr, non_constant_);
334 } 332 }
335 } 333 }
336 334
337 335
338 void ConstantPropagator::VisitParameter(ParameterInstr* instr) { 336 void ConstantPropagator::VisitParameter(ParameterInstr* instr) {
339 SetValue(instr, non_constant_); 337 SetValue(instr, non_constant_);
340 } 338 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 419
422 void ConstantPropagator::VisitIfThenElse(IfThenElseInstr* instr) { 420 void ConstantPropagator::VisitIfThenElse(IfThenElseInstr* instr) {
423 instr->comparison()->Accept(this); 421 instr->comparison()->Accept(this);
424 const Object& value = instr->comparison()->constant_value(); 422 const Object& value = instr->comparison()->constant_value();
425 if (IsNonConstant(value)) { 423 if (IsNonConstant(value)) {
426 SetValue(instr, non_constant_); 424 SetValue(instr, non_constant_);
427 } else if (IsConstant(value)) { 425 } else if (IsConstant(value)) {
428 ASSERT(!value.IsNull()); 426 ASSERT(!value.IsNull());
429 ASSERT(value.IsBool()); 427 ASSERT(value.IsBool());
430 bool result = Bool::Cast(value).value(); 428 bool result = Bool::Cast(value).value();
431 SetValue(instr, 429 SetValue(instr, Smi::Handle(Z, Smi::New(result ? instr->if_true()
432 Smi::Handle(Z, Smi::New( 430 : instr->if_false())));
433 result ? instr->if_true() : instr->if_false())));
434 } 431 }
435 } 432 }
436 433
437 434
438 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) { 435 void ConstantPropagator::VisitStrictCompare(StrictCompareInstr* instr) {
439 Definition* left_defn = instr->left()->definition(); 436 Definition* left_defn = instr->left()->definition();
440 Definition* right_defn = instr->right()->definition(); 437 Definition* right_defn = instr->right()->definition();
441 438
442 Definition* unwrapped_left_defn = UnwrapPhi(left_defn); 439 Definition* unwrapped_left_defn = UnwrapPhi(left_defn);
443 Definition* unwrapped_right_defn = UnwrapPhi(right_defn); 440 Definition* unwrapped_right_defn = UnwrapPhi(right_defn);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 SetValue(instr, Bool::Get(result)); 483 SetValue(instr, Bool::Get(result));
487 } 484 }
488 } 485 }
489 486
490 487
491 static bool CompareIntegers(Token::Kind kind, 488 static bool CompareIntegers(Token::Kind kind,
492 const Integer& left, 489 const Integer& left,
493 const Integer& right) { 490 const Integer& right) {
494 const int result = left.CompareWith(right); 491 const int result = left.CompareWith(right);
495 switch (kind) { 492 switch (kind) {
496 case Token::kEQ: return (result == 0); 493 case Token::kEQ:
497 case Token::kNE: return (result != 0); 494 return (result == 0);
498 case Token::kLT: return (result < 0); 495 case Token::kNE:
499 case Token::kGT: return (result > 0); 496 return (result != 0);
500 case Token::kLTE: return (result <= 0); 497 case Token::kLT:
501 case Token::kGTE: return (result >= 0); 498 return (result < 0);
499 case Token::kGT:
500 return (result > 0);
501 case Token::kLTE:
502 return (result <= 0);
503 case Token::kGTE:
504 return (result >= 0);
502 default: 505 default:
503 UNREACHABLE(); 506 UNREACHABLE();
504 return false; 507 return false;
505 } 508 }
506 } 509 }
507 510
508 511
509 // Comparison instruction that is equivalent to the (left & right) == 0 512 // Comparison instruction that is equivalent to the (left & right) == 0
510 // comparison pattern. 513 // comparison pattern.
511 void ConstantPropagator::VisitTestSmi(TestSmiInstr* instr) { 514 void ConstantPropagator::VisitTestSmi(TestSmiInstr* instr) {
512 const Object& left = instr->left()->definition()->constant_value(); 515 const Object& left = instr->left()->definition()->constant_value();
513 const Object& right = instr->right()->definition()->constant_value(); 516 const Object& right = instr->right()->definition()->constant_value();
514 if (IsNonConstant(left) || IsNonConstant(right)) { 517 if (IsNonConstant(left) || IsNonConstant(right)) {
515 SetValue(instr, non_constant_); 518 SetValue(instr, non_constant_);
516 } else if (IsConstant(left) && IsConstant(right)) { 519 } else if (IsConstant(left) && IsConstant(right)) {
517 // BitOp does not work on Bigints. 520 // BitOp does not work on Bigints.
518 if (left.IsInteger() && right.IsInteger() && 521 if (left.IsInteger() && right.IsInteger() && !left.IsBigint() &&
519 !left.IsBigint() && !right.IsBigint()) { 522 !right.IsBigint()) {
520 const bool result = CompareIntegers( 523 const bool result = CompareIntegers(
521 instr->kind(), 524 instr->kind(),
522 Integer::Handle(Z, Integer::Cast(left).BitOp(Token::kBIT_AND, 525 Integer::Handle(Z, Integer::Cast(left).BitOp(Token::kBIT_AND,
523 Integer::Cast(right))), 526 Integer::Cast(right))),
524 Smi::Handle(Z, Smi::New(0))); 527 Smi::Handle(Z, Smi::New(0)));
525 SetValue(instr, result ? Bool::True() : Bool::False()); 528 SetValue(instr, result ? Bool::True() : Bool::False());
526 } else { 529 } else {
527 SetValue(instr, non_constant_); 530 SetValue(instr, non_constant_);
528 } 531 }
529 } 532 }
(...skipping 26 matching lines...) Expand all
556 return; 559 return;
557 } 560 }
558 } 561 }
559 562
560 const Object& left = left_defn->constant_value(); 563 const Object& left = left_defn->constant_value();
561 const Object& right = right_defn->constant_value(); 564 const Object& right = right_defn->constant_value();
562 if (IsNonConstant(left) || IsNonConstant(right)) { 565 if (IsNonConstant(left) || IsNonConstant(right)) {
563 SetValue(instr, non_constant_); 566 SetValue(instr, non_constant_);
564 } else if (IsConstant(left) && IsConstant(right)) { 567 } else if (IsConstant(left) && IsConstant(right)) {
565 if (left.IsInteger() && right.IsInteger()) { 568 if (left.IsInteger() && right.IsInteger()) {
566 const bool result = CompareIntegers(instr->kind(), 569 const bool result = CompareIntegers(instr->kind(), Integer::Cast(left),
567 Integer::Cast(left),
568 Integer::Cast(right)); 570 Integer::Cast(right));
569 SetValue(instr, Bool::Get(result)); 571 SetValue(instr, Bool::Get(result));
570 } else if (left.IsString() && right.IsString()) { 572 } else if (left.IsString() && right.IsString()) {
571 const bool result = String::Cast(left).Equals(String::Cast(right)); 573 const bool result = String::Cast(left).Equals(String::Cast(right));
572 SetValue(instr, Bool::Get((instr->kind() == Token::kEQ) == result)); 574 SetValue(instr, Bool::Get((instr->kind() == Token::kEQ) == result));
573 } else { 575 } else {
574 SetValue(instr, non_constant_); 576 SetValue(instr, non_constant_);
575 } 577 }
576 } 578 }
577 } 579 }
578 580
579 581
580 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) { 582 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) {
581 const Object& left = instr->left()->definition()->constant_value(); 583 const Object& left = instr->left()->definition()->constant_value();
582 const Object& right = instr->right()->definition()->constant_value(); 584 const Object& right = instr->right()->definition()->constant_value();
583 if (IsNonConstant(left) || IsNonConstant(right)) { 585 if (IsNonConstant(left) || IsNonConstant(right)) {
584 SetValue(instr, non_constant_); 586 SetValue(instr, non_constant_);
585 } else if (IsConstant(left) && IsConstant(right)) { 587 } else if (IsConstant(left) && IsConstant(right)) {
586 if (left.IsInteger() && right.IsInteger()) { 588 if (left.IsInteger() && right.IsInteger()) {
587 const bool result = CompareIntegers(instr->kind(), 589 const bool result = CompareIntegers(instr->kind(), Integer::Cast(left),
588 Integer::Cast(left),
589 Integer::Cast(right)); 590 Integer::Cast(right));
590 SetValue(instr, Bool::Get(result)); 591 SetValue(instr, Bool::Get(result));
591 } else if (left.IsDouble() && right.IsDouble()) { 592 } else if (left.IsDouble() && right.IsDouble()) {
592 // TODO(srdjan): Implement. 593 // TODO(srdjan): Implement.
593 SetValue(instr, non_constant_); 594 SetValue(instr, non_constant_);
594 } else { 595 } else {
595 SetValue(instr, non_constant_); 596 SetValue(instr, non_constant_);
596 } 597 }
597 } 598 }
598 } 599 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 if (!index_obj.IsSmi()) { 655 if (!index_obj.IsSmi()) {
655 // Should not occur. 656 // Should not occur.
656 SetValue(instr, non_constant_); 657 SetValue(instr, non_constant_);
657 return; 658 return;
658 } 659 }
659 const intptr_t index = Smi::Cast(index_obj).Value(); 660 const intptr_t index = Smi::Cast(index_obj).Value();
660 if (index >= 0) { 661 if (index >= 0) {
661 if (array_obj.IsString()) { 662 if (array_obj.IsString()) {
662 const String& str = String::Cast(array_obj); 663 const String& str = String::Cast(array_obj);
663 if (str.Length() > index) { 664 if (str.Length() > index) {
664 SetValue(instr, Smi::Handle(Z, 665 SetValue(instr,
665 Smi::New(static_cast<intptr_t>(str.CharAt(index))))); 666 Smi::Handle(
667 Z, Smi::New(static_cast<intptr_t>(str.CharAt(index)))));
666 return; 668 return;
667 } 669 }
668 } else if (array_obj.IsArray()) { 670 } else if (array_obj.IsArray()) {
669 const Array& a = Array::Cast(array_obj); 671 const Array& a = Array::Cast(array_obj);
670 if ((a.Length() > index) && a.IsImmutable()) { 672 if ((a.Length() > index) && a.IsImmutable()) {
671 Instance& result = Instance::Handle(Z); 673 Instance& result = Instance::Handle(Z);
672 result ^= a.At(index); 674 result ^= a.At(index);
673 SetValue(instr, result); 675 SetValue(instr, result);
674 return; 676 return;
675 } 677 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 } else { 759 } else {
758 SetValue(instr, non_constant_); 760 SetValue(instr, non_constant_);
759 } 761 }
760 } else if (IsConstant(value)) { 762 } else if (IsConstant(value)) {
761 if (value.IsInstance()) { 763 if (value.IsInstance()) {
762 const Instance& instance = Instance::Cast(value); 764 const Instance& instance = Instance::Cast(value);
763 const AbstractType& checked_type = instr->type(); 765 const AbstractType& checked_type = instr->type();
764 if (instr->instantiator_type_arguments()->BindsToConstantNull()) { 766 if (instr->instantiator_type_arguments()->BindsToConstantNull()) {
765 const TypeArguments& checked_type_arguments = TypeArguments::Handle(); 767 const TypeArguments& checked_type_arguments = TypeArguments::Handle();
766 Error& bound_error = Error::Handle(); 768 Error& bound_error = Error::Handle();
767 bool is_instance = instance.IsInstanceOf(checked_type, 769 bool is_instance = instance.IsInstanceOf(
768 checked_type_arguments, 770 checked_type, checked_type_arguments, &bound_error);
769 &bound_error);
770 // Can only have bound error with generics. 771 // Can only have bound error with generics.
771 ASSERT(bound_error.IsNull()); 772 ASSERT(bound_error.IsNull());
772 SetValue(instr, Bool::Get(instr->negate_result() 773 SetValue(instr, Bool::Get(instr->negate_result() ? !is_instance
773 ? !is_instance : is_instance)); 774 : is_instance));
774 return; 775 return;
775 } 776 }
776 } 777 }
777 SetValue(instr, non_constant_); 778 SetValue(instr, non_constant_);
778 } 779 }
779 } 780 }
780 781
781 782
782 void ConstantPropagator::VisitCreateArray(CreateArrayInstr* instr) { 783 void ConstantPropagator::VisitCreateArray(CreateArrayInstr* instr) {
783 SetValue(instr, non_constant_); 784 SetValue(instr, non_constant_);
(...skipping 26 matching lines...) Expand all
810 } 811 }
811 } 812 }
812 SetValue(instr, non_constant_); 813 SetValue(instr, non_constant_);
813 } 814 }
814 815
815 816
816 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { 817 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) {
817 Value* instance = instr->instance(); 818 Value* instance = instr->instance();
818 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && 819 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) &&
819 instance->definition()->OriginalDefinition()->IsCreateArray()) { 820 instance->definition()->OriginalDefinition()->IsCreateArray()) {
820 Value* num_elements = instance->definition()->OriginalDefinition() 821 Value* num_elements = instance->definition()
821 ->AsCreateArray()->num_elements(); 822 ->OriginalDefinition()
823 ->AsCreateArray()
824 ->num_elements();
822 if (num_elements->BindsToConstant() && 825 if (num_elements->BindsToConstant() &&
823 num_elements->BoundConstant().IsSmi()) { 826 num_elements->BoundConstant().IsSmi()) {
824 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); 827 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value();
825 const Object& result = Smi::ZoneHandle(Z, Smi::New(length)); 828 const Object& result = Smi::ZoneHandle(Z, Smi::New(length));
826 SetValue(instr, result); 829 SetValue(instr, result);
827 return; 830 return;
828 } 831 }
829 } 832 }
830 833
831 if (instr->IsImmutableLengthLoad()) { 834 if (instr->IsImmutableLengthLoad()) {
832 ConstantInstr* constant = 835 ConstantInstr* constant =
833 instance->definition()->OriginalDefinition()->AsConstant(); 836 instance->definition()->OriginalDefinition()->AsConstant();
834 if (constant != NULL) { 837 if (constant != NULL) {
835 if (constant->value().IsString()) { 838 if (constant->value().IsString()) {
836 SetValue(instr, Smi::ZoneHandle(Z, 839 SetValue(instr,
837 Smi::New(String::Cast(constant->value()).Length()))); 840 Smi::ZoneHandle(
841 Z, Smi::New(String::Cast(constant->value()).Length())));
838 return; 842 return;
839 } 843 }
840 if (constant->value().IsArray()) { 844 if (constant->value().IsArray()) {
841 SetValue(instr, Smi::ZoneHandle(Z, 845 SetValue(instr,
842 Smi::New(Array::Cast(constant->value()).Length()))); 846 Smi::ZoneHandle(
847 Z, Smi::New(Array::Cast(constant->value()).Length())));
843 return; 848 return;
844 } 849 }
845 if (constant->value().IsTypedData()) { 850 if (constant->value().IsTypedData()) {
846 SetValue(instr, Smi::ZoneHandle(Z, 851 SetValue(instr,
847 Smi::New(TypedData::Cast(constant->value()).Length()))); 852 Smi::ZoneHandle(
853 Z, Smi::New(TypedData::Cast(constant->value()).Length())));
848 return; 854 return;
849 } 855 }
850 } 856 }
851 } 857 }
852 SetValue(instr, non_constant_); 858 SetValue(instr, non_constant_);
853 } 859 }
854 860
855 861
856 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) { 862 void ConstantPropagator::VisitInstantiateType(InstantiateTypeInstr* instr) {
857 const Object& object = 863 const Object& object = instr->instantiator()->definition()->constant_value();
858 instr->instantiator()->definition()->constant_value();
859 if (IsNonConstant(object)) { 864 if (IsNonConstant(object)) {
860 SetValue(instr, non_constant_); 865 SetValue(instr, non_constant_);
861 return; 866 return;
862 } 867 }
863 if (IsConstant(object)) { 868 if (IsConstant(object)) {
864 if (instr->type().IsTypeParameter()) { 869 if (instr->type().IsTypeParameter()) {
865 if (object.IsNull()) { 870 if (object.IsNull()) {
866 SetValue(instr, Object::dynamic_type()); 871 SetValue(instr, Object::dynamic_type());
867 return; 872 return;
868 } 873 }
869 // We could try to instantiate the type parameter and return it if no 874 // We could try to instantiate the type parameter and return it if no
870 // malformed error is reported. 875 // malformed error is reported.
871 } 876 }
872 SetValue(instr, non_constant_); 877 SetValue(instr, non_constant_);
873 } 878 }
874 } 879 }
875 880
876 881
877 void ConstantPropagator::VisitInstantiateTypeArguments( 882 void ConstantPropagator::VisitInstantiateTypeArguments(
878 InstantiateTypeArgumentsInstr* instr) { 883 InstantiateTypeArgumentsInstr* instr) {
879 const Object& object = 884 const Object& object = instr->instantiator()->definition()->constant_value();
880 instr->instantiator()->definition()->constant_value();
881 if (IsNonConstant(object)) { 885 if (IsNonConstant(object)) {
882 SetValue(instr, non_constant_); 886 SetValue(instr, non_constant_);
883 return; 887 return;
884 } 888 }
885 if (IsConstant(object)) { 889 if (IsConstant(object)) {
886 const intptr_t len = instr->type_arguments().Length(); 890 const intptr_t len = instr->type_arguments().Length();
887 if (instr->type_arguments().IsRawInstantiatedRaw(len) && 891 if (instr->type_arguments().IsRawInstantiatedRaw(len) && object.IsNull()) {
888 object.IsNull()) {
889 SetValue(instr, object); 892 SetValue(instr, object);
890 return; 893 return;
891 } 894 }
892 if (instr->type_arguments().IsUninstantiatedIdentity() || 895 if (instr->type_arguments().IsUninstantiatedIdentity() ||
893 instr->type_arguments().CanShareInstantiatorTypeArguments( 896 instr->type_arguments().CanShareInstantiatorTypeArguments(
894 instr->instantiator_class())) { 897 instr->instantiator_class())) {
895 SetValue(instr, object); 898 SetValue(instr, object);
896 return; 899 return;
897 } 900 }
898 SetValue(instr, non_constant_); 901 SetValue(instr, non_constant_);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 void ConstantPropagator::VisitUnboxInt64(UnboxInt64Instr* instr) { 989 void ConstantPropagator::VisitUnboxInt64(UnboxInt64Instr* instr) {
987 // TODO(kmillikin): Handle unbox operation. 990 // TODO(kmillikin): Handle unbox operation.
988 SetValue(instr, non_constant_); 991 SetValue(instr, non_constant_);
989 } 992 }
990 993
991 994
992 void ConstantPropagator::VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op) { 995 void ConstantPropagator::VisitUnaryIntegerOp(UnaryIntegerOpInstr* unary_op) {
993 const Object& value = unary_op->value()->definition()->constant_value(); 996 const Object& value = unary_op->value()->definition()->constant_value();
994 if (IsConstant(value) && value.IsInteger()) { 997 if (IsConstant(value) && value.IsInteger()) {
995 const Integer& value_int = Integer::Cast(value); 998 const Integer& value_int = Integer::Cast(value);
996 const Integer& result = 999 const Integer& result = Integer::Handle(Z, unary_op->Evaluate(value_int));
997 Integer::Handle(Z, unary_op->Evaluate(value_int));
998 if (!result.IsNull()) { 1000 if (!result.IsNull()) {
999 SetValue(unary_op, Integer::ZoneHandle(Z, result.raw())); 1001 SetValue(unary_op, Integer::ZoneHandle(Z, result.raw()));
1000 return; 1002 return;
1001 } 1003 }
1002 } 1004 }
1003 1005
1004 SetValue(unary_op, non_constant_); 1006 SetValue(unary_op, non_constant_);
1005 } 1007 }
1006 1008
1007 1009
(...skipping 14 matching lines...) Expand all
1022 } else if (IsConstant(value)) { 1024 } else if (IsConstant(value)) {
1023 // TODO(kmillikin): Handle unary operations. 1025 // TODO(kmillikin): Handle unary operations.
1024 SetValue(instr, non_constant_); 1026 SetValue(instr, non_constant_);
1025 } 1027 }
1026 } 1028 }
1027 1029
1028 1030
1029 void ConstantPropagator::VisitSmiToDouble(SmiToDoubleInstr* instr) { 1031 void ConstantPropagator::VisitSmiToDouble(SmiToDoubleInstr* instr) {
1030 const Object& value = instr->value()->definition()->constant_value(); 1032 const Object& value = instr->value()->definition()->constant_value();
1031 if (IsConstant(value) && value.IsInteger()) { 1033 if (IsConstant(value) && value.IsInteger()) {
1032 SetValue(instr, Double::Handle(Z, 1034 SetValue(instr,
1033 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); 1035 Double::Handle(Z, Double::New(Integer::Cast(value).AsDoubleValue(),
1036 Heap::kOld)));
1034 } else if (!IsUnknown(value)) { 1037 } else if (!IsUnknown(value)) {
1035 SetValue(instr, non_constant_); 1038 SetValue(instr, non_constant_);
1036 } 1039 }
1037 } 1040 }
1038 1041
1039 1042
1040 void ConstantPropagator::VisitMintToDouble(MintToDoubleInstr* instr) { 1043 void ConstantPropagator::VisitMintToDouble(MintToDoubleInstr* instr) {
1041 const Object& value = instr->value()->definition()->constant_value(); 1044 const Object& value = instr->value()->definition()->constant_value();
1042 if (IsConstant(value) && value.IsInteger()) { 1045 if (IsConstant(value) && value.IsInteger()) {
1043 SetValue(instr, Double::Handle(Z, 1046 SetValue(instr,
1044 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); 1047 Double::Handle(Z, Double::New(Integer::Cast(value).AsDoubleValue(),
1048 Heap::kOld)));
1045 } else if (!IsUnknown(value)) { 1049 } else if (!IsUnknown(value)) {
1046 SetValue(instr, non_constant_); 1050 SetValue(instr, non_constant_);
1047 } 1051 }
1048 } 1052 }
1049 1053
1050 1054
1051 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) { 1055 void ConstantPropagator::VisitInt32ToDouble(Int32ToDoubleInstr* instr) {
1052 const Object& value = instr->value()->definition()->constant_value(); 1056 const Object& value = instr->value()->definition()->constant_value();
1053 if (IsConstant(value) && value.IsInteger()) { 1057 if (IsConstant(value) && value.IsInteger()) {
1054 SetValue(instr, Double::Handle(Z, 1058 SetValue(instr,
1055 Double::New(Integer::Cast(value).AsDoubleValue(), Heap::kOld))); 1059 Double::Handle(Z, Double::New(Integer::Cast(value).AsDoubleValue(),
1060 Heap::kOld)));
1056 } else if (!IsUnknown(value)) { 1061 } else if (!IsUnknown(value)) {
1057 SetValue(instr, non_constant_); 1062 SetValue(instr, non_constant_);
1058 } 1063 }
1059 } 1064 }
1060 1065
1061 1066
1062 void ConstantPropagator::VisitDoubleToInteger(DoubleToIntegerInstr* instr) { 1067 void ConstantPropagator::VisitDoubleToInteger(DoubleToIntegerInstr* instr) {
1063 // TODO(kmillikin): Handle conversion. 1068 // TODO(kmillikin): Handle conversion.
1064 SetValue(instr, non_constant_); 1069 SetValue(instr, non_constant_);
1065 } 1070 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 return value.IsInteger() || value.IsDouble(); 1138 return value.IsInteger() || value.IsDouble();
1134 } 1139 }
1135 1140
1136 1141
1137 static double ToDouble(const Object& value) { 1142 static double ToDouble(const Object& value) {
1138 return value.IsInteger() ? Integer::Cast(value).AsDoubleValue() 1143 return value.IsInteger() ? Integer::Cast(value).AsDoubleValue()
1139 : Double::Cast(value).value(); 1144 : Double::Cast(value).value();
1140 } 1145 }
1141 1146
1142 1147
1143 void ConstantPropagator::VisitBinaryDoubleOp( 1148 void ConstantPropagator::VisitBinaryDoubleOp(BinaryDoubleOpInstr* instr) {
1144 BinaryDoubleOpInstr* instr) {
1145 const Object& left = instr->left()->definition()->constant_value(); 1149 const Object& left = instr->left()->definition()->constant_value();
1146 const Object& right = instr->right()->definition()->constant_value(); 1150 const Object& right = instr->right()->definition()->constant_value();
1147 if (IsNonConstant(left) || IsNonConstant(right)) { 1151 if (IsNonConstant(left) || IsNonConstant(right)) {
1148 SetValue(instr, non_constant_); 1152 SetValue(instr, non_constant_);
1149 } else if (left.IsInteger() && right.IsInteger()) { 1153 } else if (left.IsInteger() && right.IsInteger()) {
1150 SetValue(instr, non_constant_); 1154 SetValue(instr, non_constant_);
1151 } else if (IsIntegerOrDouble(left) && IsIntegerOrDouble(right)) { 1155 } else if (IsIntegerOrDouble(left) && IsIntegerOrDouble(right)) {
1152 const double left_val = ToDouble(left); 1156 const double left_val = ToDouble(left);
1153 const double right_val = ToDouble(right); 1157 const double right_val = ToDouble(right);
1154 double result_val = 0.0; 1158 double result_val = 0.0;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 } 1197 }
1194 default: 1198 default:
1195 UNREACHABLE(); 1199 UNREACHABLE();
1196 } 1200 }
1197 } else { 1201 } else {
1198 SetValue(instr, non_constant_); 1202 SetValue(instr, non_constant_);
1199 } 1203 }
1200 } 1204 }
1201 1205
1202 1206
1203 void ConstantPropagator::VisitBinaryFloat32x4Op( 1207 void ConstantPropagator::VisitBinaryFloat32x4Op(BinaryFloat32x4OpInstr* instr) {
1204 BinaryFloat32x4OpInstr* instr) {
1205 const Object& left = instr->left()->definition()->constant_value(); 1208 const Object& left = instr->left()->definition()->constant_value();
1206 const Object& right = instr->right()->definition()->constant_value(); 1209 const Object& right = instr->right()->definition()->constant_value();
1207 if (IsNonConstant(left) || IsNonConstant(right)) { 1210 if (IsNonConstant(left) || IsNonConstant(right)) {
1208 SetValue(instr, non_constant_); 1211 SetValue(instr, non_constant_);
1209 } else if (IsConstant(left) && IsConstant(right)) { 1212 } else if (IsConstant(left) && IsConstant(right)) {
1210 // TODO(kmillikin): Handle binary operation. 1213 // TODO(kmillikin): Handle binary operation.
1211 SetValue(instr, non_constant_); 1214 SetValue(instr, non_constant_);
1212 } 1215 }
1213 } 1216 }
1214 1217
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 SetValue(instr, non_constant_); 1344 SetValue(instr, non_constant_);
1342 } 1345 }
1343 1346
1344 1347
1345 void ConstantPropagator::VisitFloat64x2ToFloat32x4( 1348 void ConstantPropagator::VisitFloat64x2ToFloat32x4(
1346 Float64x2ToFloat32x4Instr* instr) { 1349 Float64x2ToFloat32x4Instr* instr) {
1347 SetValue(instr, non_constant_); 1350 SetValue(instr, non_constant_);
1348 } 1351 }
1349 1352
1350 1353
1351 void ConstantPropagator::VisitFloat64x2Zero( 1354 void ConstantPropagator::VisitFloat64x2Zero(Float64x2ZeroInstr* instr) {
1352 Float64x2ZeroInstr* instr) {
1353 SetValue(instr, non_constant_); 1355 SetValue(instr, non_constant_);
1354 } 1356 }
1355 1357
1356 1358
1357 void ConstantPropagator::VisitFloat64x2Splat( 1359 void ConstantPropagator::VisitFloat64x2Splat(Float64x2SplatInstr* instr) {
1358 Float64x2SplatInstr* instr) {
1359 SetValue(instr, non_constant_); 1360 SetValue(instr, non_constant_);
1360 } 1361 }
1361 1362
1362 1363
1363 void ConstantPropagator::VisitFloat64x2Constructor( 1364 void ConstantPropagator::VisitFloat64x2Constructor(
1364 Float64x2ConstructorInstr* instr) { 1365 Float64x2ConstructorInstr* instr) {
1365 SetValue(instr, non_constant_); 1366 SetValue(instr, non_constant_);
1366 } 1367 }
1367 1368
1368 1369
(...skipping 26 matching lines...) Expand all
1395 if (IsNonConstant(left) || IsNonConstant(right)) { 1396 if (IsNonConstant(left) || IsNonConstant(right)) {
1396 SetValue(instr, non_constant_); 1397 SetValue(instr, non_constant_);
1397 } else if (IsConstant(left) && IsConstant(right)) { 1398 } else if (IsConstant(left) && IsConstant(right)) {
1398 // TODO(srdjan): Handle min and max. 1399 // TODO(srdjan): Handle min and max.
1399 SetValue(instr, non_constant_); 1400 SetValue(instr, non_constant_);
1400 } 1401 }
1401 } 1402 }
1402 1403
1403 1404
1404 void ConstantPropagator::VisitCaseInsensitiveCompareUC16( 1405 void ConstantPropagator::VisitCaseInsensitiveCompareUC16(
1405 CaseInsensitiveCompareUC16Instr *instr) { 1406 CaseInsensitiveCompareUC16Instr* instr) {
1406 SetValue(instr, non_constant_); 1407 SetValue(instr, non_constant_);
1407 } 1408 }
1408 1409
1409 1410
1410 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) { 1411 void ConstantPropagator::VisitUnbox(UnboxInstr* instr) {
1411 const Object& value = instr->value()->definition()->constant_value(); 1412 const Object& value = instr->value()->definition()->constant_value();
1412 if (IsNonConstant(value)) { 1413 if (IsNonConstant(value)) {
1413 SetValue(instr, non_constant_); 1414 SetValue(instr, non_constant_);
1414 } else if (IsConstant(value)) { 1415 } else if (IsConstant(value)) {
1415 // TODO(kmillikin): Handle conversion. 1416 // TODO(kmillikin): Handle conversion.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 } else { 1483 } else {
1483 BlockEntryInstr* block = block_worklist_.RemoveLast(); 1484 BlockEntryInstr* block = block_worklist_.RemoveLast();
1484 block->Accept(this); 1485 block->Accept(this);
1485 } 1486 }
1486 } 1487 }
1487 } 1488 }
1488 1489
1489 1490
1490 static bool IsEmptyBlock(BlockEntryInstr* block) { 1491 static bool IsEmptyBlock(BlockEntryInstr* block) {
1491 return block->next()->IsGoto() && 1492 return block->next()->IsGoto() &&
1492 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) && 1493 (!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)) &&
1493 !block->IsIndirectEntry(); 1494 !block->IsIndirectEntry();
1494 } 1495 }
1495 1496
1496 1497
1497 // Traverses a chain of empty blocks and returns the first reachable non-empty 1498 // Traverses a chain of empty blocks and returns the first reachable non-empty
1498 // block that is not dominated by the start block. The empty blocks are added 1499 // block that is not dominated by the start block. The empty blocks are added
1499 // to the supplied bit vector. 1500 // to the supplied bit vector.
1500 static BlockEntryInstr* FindFirstNonEmptySuccessor( 1501 static BlockEntryInstr* FindFirstNonEmptySuccessor(TargetEntryInstr* block,
1501 TargetEntryInstr* block, 1502 BitVector* empty_blocks) {
1502 BitVector* empty_blocks) {
1503 BlockEntryInstr* current = block; 1503 BlockEntryInstr* current = block;
1504 while (IsEmptyBlock(current) && block->Dominates(current)) { 1504 while (IsEmptyBlock(current) && block->Dominates(current)) {
1505 ASSERT(!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL)); 1505 ASSERT(!block->IsJoinEntry() || (block->AsJoinEntry()->phis() == NULL));
1506 empty_blocks->Add(current->preorder_number()); 1506 empty_blocks->Add(current->preorder_number());
1507 current = current->next()->AsGoto()->successor(); 1507 current = current->next()->AsGoto()->successor();
1508 } 1508 }
1509 return current; 1509 return current;
1510 } 1510 }
1511 1511
1512 1512
1513 void ConstantPropagator::EliminateRedundantBranches() { 1513 void ConstantPropagator::EliminateRedundantBranches() {
1514 // Canonicalize branches that have no side-effects and where true- and 1514 // Canonicalize branches that have no side-effects and where true- and
1515 // false-targets are the same. 1515 // false-targets are the same.
1516 bool changed = false; 1516 bool changed = false;
1517 BitVector* empty_blocks = new(Z) BitVector(Z, 1517 BitVector* empty_blocks = new (Z) BitVector(Z, graph_->preorder().length());
1518 graph_->preorder().length()); 1518 for (BlockIterator b = graph_->postorder_iterator(); !b.Done(); b.Advance()) {
1519 for (BlockIterator b = graph_->postorder_iterator();
1520 !b.Done();
1521 b.Advance()) {
1522 BlockEntryInstr* block = b.Current(); 1519 BlockEntryInstr* block = b.Current();
1523 BranchInstr* branch = block->last_instruction()->AsBranch(); 1520 BranchInstr* branch = block->last_instruction()->AsBranch();
1524 empty_blocks->Clear(); 1521 empty_blocks->Clear();
1525 if ((branch != NULL) && branch->Effects().IsNone()) { 1522 if ((branch != NULL) && branch->Effects().IsNone()) {
1526 ASSERT(branch->previous() != NULL); // Not already eliminated. 1523 ASSERT(branch->previous() != NULL); // Not already eliminated.
1527 BlockEntryInstr* if_true = 1524 BlockEntryInstr* if_true =
1528 FindFirstNonEmptySuccessor(branch->true_successor(), empty_blocks); 1525 FindFirstNonEmptySuccessor(branch->true_successor(), empty_blocks);
1529 BlockEntryInstr* if_false = 1526 BlockEntryInstr* if_false =
1530 FindFirstNonEmptySuccessor(branch->false_successor(), empty_blocks); 1527 FindFirstNonEmptySuccessor(branch->false_successor(), empty_blocks);
1531 if (if_true == if_false) { 1528 if (if_true == if_false) {
1532 // Replace the branch with a jump to the common successor. 1529 // Replace the branch with a jump to the common successor.
1533 // Drop the comparison, which does not have side effects 1530 // Drop the comparison, which does not have side effects
1534 JoinEntryInstr* join = if_true->AsJoinEntry(); 1531 JoinEntryInstr* join = if_true->AsJoinEntry();
1535 if (join->phis() == NULL) { 1532 if (join->phis() == NULL) {
1536 GotoInstr* jump = new(Z) GotoInstr(if_true->AsJoinEntry()); 1533 GotoInstr* jump = new (Z) GotoInstr(if_true->AsJoinEntry());
1537 jump->InheritDeoptTarget(Z, branch); 1534 jump->InheritDeoptTarget(Z, branch);
1538 1535
1539 Instruction* previous = branch->previous(); 1536 Instruction* previous = branch->previous();
1540 branch->set_previous(NULL); 1537 branch->set_previous(NULL);
1541 previous->LinkTo(jump); 1538 previous->LinkTo(jump);
1542 1539
1543 // Remove uses from branch and all the empty blocks that 1540 // Remove uses from branch and all the empty blocks that
1544 // are now unreachable. 1541 // are now unreachable.
1545 branch->UnuseAllInputs(); 1542 branch->UnuseAllInputs();
1546 for (BitVector::Iterator it(empty_blocks); !it.Done(); it.Advance()) { 1543 for (BitVector::Iterator it(empty_blocks); !it.Done(); it.Advance()) {
(...skipping 25 matching lines...) Expand all
1572 void ConstantPropagator::Transform() { 1569 void ConstantPropagator::Transform() {
1573 if (FLAG_trace_constant_propagation && 1570 if (FLAG_trace_constant_propagation &&
1574 FlowGraphPrinter::ShouldPrint(graph_->function())) { 1571 FlowGraphPrinter::ShouldPrint(graph_->function())) {
1575 FlowGraphPrinter::PrintGraph("Before CP", graph_); 1572 FlowGraphPrinter::PrintGraph("Before CP", graph_);
1576 } 1573 }
1577 1574
1578 // We will recompute dominators, block ordering, block ids, block last 1575 // We will recompute dominators, block ordering, block ids, block last
1579 // instructions, previous pointers, predecessors, etc. after eliminating 1576 // instructions, previous pointers, predecessors, etc. after eliminating
1580 // unreachable code. We do not maintain those properties during the 1577 // unreachable code. We do not maintain those properties during the
1581 // transformation. 1578 // transformation.
1582 for (BlockIterator b = graph_->reverse_postorder_iterator(); 1579 for (BlockIterator b = graph_->reverse_postorder_iterator(); !b.Done();
1583 !b.Done();
1584 b.Advance()) { 1580 b.Advance()) {
1585 BlockEntryInstr* block = b.Current(); 1581 BlockEntryInstr* block = b.Current();
1586 if (!reachable_->Contains(block->preorder_number())) { 1582 if (!reachable_->Contains(block->preorder_number())) {
1587 if (FLAG_trace_constant_propagation && 1583 if (FLAG_trace_constant_propagation &&
1588 FlowGraphPrinter::ShouldPrint(graph_->function())) { 1584 FlowGraphPrinter::ShouldPrint(graph_->function())) {
1589 THR_Print("Unreachable B%" Pd "\n", block->block_id()); 1585 THR_Print("Unreachable B%" Pd "\n", block->block_id());
1590 } 1586 }
1591 // Remove all uses in unreachable blocks. 1587 // Remove all uses in unreachable blocks.
1592 block->ClearAllInstructions(); 1588 block->ClearAllInstructions();
1593 continue; 1589 continue;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1642 } 1638 }
1643 } 1639 }
1644 } 1640 }
1645 } 1641 }
1646 1642
1647 for (ForwardInstructionIterator i(block); !i.Done(); i.Advance()) { 1643 for (ForwardInstructionIterator i(block); !i.Done(); i.Advance()) {
1648 Definition* defn = i.Current()->AsDefinition(); 1644 Definition* defn = i.Current()->AsDefinition();
1649 // Replace constant-valued instructions without observable side 1645 // Replace constant-valued instructions without observable side
1650 // effects. Do this for smis only to avoid having to copy other 1646 // effects. Do this for smis only to avoid having to copy other
1651 // objects into the heap's old generation. 1647 // objects into the heap's old generation.
1652 if ((defn != NULL) && 1648 if ((defn != NULL) && IsConstant(defn->constant_value()) &&
1653 IsConstant(defn->constant_value()) &&
1654 (defn->constant_value().IsSmi() || defn->constant_value().IsOld()) && 1649 (defn->constant_value().IsSmi() || defn->constant_value().IsOld()) &&
1655 !defn->IsConstant() && 1650 !defn->IsConstant() && !defn->IsPushArgument() &&
1656 !defn->IsPushArgument() && 1651 !defn->IsStoreIndexed() && !defn->IsStoreInstanceField() &&
1657 !defn->IsStoreIndexed() &&
1658 !defn->IsStoreInstanceField() &&
1659 !defn->IsStoreStaticField()) { 1652 !defn->IsStoreStaticField()) {
1660 if (FLAG_trace_constant_propagation && 1653 if (FLAG_trace_constant_propagation &&
1661 FlowGraphPrinter::ShouldPrint(graph_->function())) { 1654 FlowGraphPrinter::ShouldPrint(graph_->function())) {
1662 THR_Print("Constant v%" Pd " = %s\n", 1655 THR_Print("Constant v%" Pd " = %s\n", defn->ssa_temp_index(),
1663 defn->ssa_temp_index(),
1664 defn->constant_value().ToCString()); 1656 defn->constant_value().ToCString());
1665 } 1657 }
1666 ConstantInstr* constant = graph_->GetConstant(defn->constant_value()); 1658 ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
1667 defn->ReplaceUsesWith(constant); 1659 defn->ReplaceUsesWith(constant);
1668 i.RemoveCurrentFromGraph(); 1660 i.RemoveCurrentFromGraph();
1669 } 1661 }
1670 } 1662 }
1671 1663
1672 // Replace branches where one target is unreachable with jumps. 1664 // Replace branches where one target is unreachable with jumps.
1673 BranchInstr* branch = block->last_instruction()->AsBranch(); 1665 BranchInstr* branch = block->last_instruction()->AsBranch();
1674 if (branch != NULL) { 1666 if (branch != NULL) {
1675 TargetEntryInstr* if_true = branch->true_successor(); 1667 TargetEntryInstr* if_true = branch->true_successor();
1676 TargetEntryInstr* if_false = branch->false_successor(); 1668 TargetEntryInstr* if_false = branch->false_successor();
1677 JoinEntryInstr* join = NULL; 1669 JoinEntryInstr* join = NULL;
1678 Instruction* next = NULL; 1670 Instruction* next = NULL;
1679 1671
1680 if (!reachable_->Contains(if_true->preorder_number())) { 1672 if (!reachable_->Contains(if_true->preorder_number())) {
1681 ASSERT(reachable_->Contains(if_false->preorder_number())); 1673 ASSERT(reachable_->Contains(if_false->preorder_number()));
1682 ASSERT(if_false->parallel_move() == NULL); 1674 ASSERT(if_false->parallel_move() == NULL);
1683 ASSERT(if_false->loop_info() == NULL); 1675 ASSERT(if_false->loop_info() == NULL);
1684 join = new(Z) JoinEntryInstr(if_false->block_id(), 1676 join =
1685 if_false->try_index()); 1677 new (Z) JoinEntryInstr(if_false->block_id(), if_false->try_index());
1686 join->InheritDeoptTarget(Z, if_false); 1678 join->InheritDeoptTarget(Z, if_false);
1687 if_false->UnuseAllInputs(); 1679 if_false->UnuseAllInputs();
1688 next = if_false->next(); 1680 next = if_false->next();
1689 } else if (!reachable_->Contains(if_false->preorder_number())) { 1681 } else if (!reachable_->Contains(if_false->preorder_number())) {
1690 ASSERT(if_true->parallel_move() == NULL); 1682 ASSERT(if_true->parallel_move() == NULL);
1691 ASSERT(if_true->loop_info() == NULL); 1683 ASSERT(if_true->loop_info() == NULL);
1692 join = new(Z) JoinEntryInstr(if_true->block_id(), 1684 join =
1693 if_true->try_index()); 1685 new (Z) JoinEntryInstr(if_true->block_id(), if_true->try_index());
1694 join->InheritDeoptTarget(Z, if_true); 1686 join->InheritDeoptTarget(Z, if_true);
1695 if_true->UnuseAllInputs(); 1687 if_true->UnuseAllInputs();
1696 next = if_true->next(); 1688 next = if_true->next();
1697 } 1689 }
1698 1690
1699 if (join != NULL) { 1691 if (join != NULL) {
1700 // Replace the branch with a jump to the reachable successor. 1692 // Replace the branch with a jump to the reachable successor.
1701 // Drop the comparison, which does not have side effects as long 1693 // Drop the comparison, which does not have side effects as long
1702 // as it is a strict compare (the only one we can determine is 1694 // as it is a strict compare (the only one we can determine is
1703 // constant with the current analysis). 1695 // constant with the current analysis).
1704 GotoInstr* jump = new(Z) GotoInstr(join); 1696 GotoInstr* jump = new (Z) GotoInstr(join);
1705 jump->InheritDeoptTarget(Z, branch); 1697 jump->InheritDeoptTarget(Z, branch);
1706 1698
1707 Instruction* previous = branch->previous(); 1699 Instruction* previous = branch->previous();
1708 branch->set_previous(NULL); 1700 branch->set_previous(NULL);
1709 previous->LinkTo(jump); 1701 previous->LinkTo(jump);
1710 1702
1711 // Replace the false target entry with the new join entry. We will 1703 // Replace the false target entry with the new join entry. We will
1712 // recompute the dominators after this pass. 1704 // recompute the dominators after this pass.
1713 join->LinkTo(next); 1705 join->LinkTo(next);
1714 branch->UnuseAllInputs(); 1706 branch->UnuseAllInputs();
1715 } 1707 }
1716 } 1708 }
1717 } 1709 }
1718 1710
1719 graph_->DiscoverBlocks(); 1711 graph_->DiscoverBlocks();
1720 graph_->MergeBlocks(); 1712 graph_->MergeBlocks();
1721 GrowableArray<BitVector*> dominance_frontier; 1713 GrowableArray<BitVector*> dominance_frontier;
1722 graph_->ComputeDominators(&dominance_frontier); 1714 graph_->ComputeDominators(&dominance_frontier);
1723 1715
1724 if (FLAG_trace_constant_propagation && 1716 if (FLAG_trace_constant_propagation &&
1725 FlowGraphPrinter::ShouldPrint(graph_->function())) { 1717 FlowGraphPrinter::ShouldPrint(graph_->function())) {
1726 FlowGraphPrinter::PrintGraph("After CP", graph_); 1718 FlowGraphPrinter::PrintGraph("After CP", graph_);
1727 } 1719 }
1728 } 1720 }
1729 1721
1730 } // namespace dart 1722 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/constant_propagator.h ('k') | runtime/vm/constants_arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698