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

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

Issue 345563007: Add Uint32 representation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 5 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('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/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.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/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 26 matching lines...) Expand all
37 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis."); 37 DEFINE_FLAG(bool, remove_redundant_phis, true, "Remove redundant phis.");
38 DEFINE_FLAG(bool, trace_constant_propagation, false, 38 DEFINE_FLAG(bool, trace_constant_propagation, false,
39 "Print constant propagation and useless code elimination."); 39 "Print constant propagation and useless code elimination.");
40 DEFINE_FLAG(bool, trace_load_optimization, false, 40 DEFINE_FLAG(bool, trace_load_optimization, false,
41 "Print live sets for load optimization pass."); 41 "Print live sets for load optimization pass.");
42 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details."); 42 DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details.");
43 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress"); 43 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress");
44 DEFINE_FLAG(bool, truncating_left_shift, true, 44 DEFINE_FLAG(bool, truncating_left_shift, true,
45 "Optimize left shift to truncate if possible"); 45 "Optimize left shift to truncate if possible");
46 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis."); 46 DEFINE_FLAG(bool, use_cha, true, "Use class hierarchy analysis.");
47 DEFINE_FLAG(bool, trace_integer_ir_selection, false,
48 "Print integer IR selection optimization pass.");
47 DECLARE_FLAG(bool, enable_type_checks); 49 DECLARE_FLAG(bool, enable_type_checks);
48 DECLARE_FLAG(bool, source_lines); 50 DECLARE_FLAG(bool, source_lines);
49 DECLARE_FLAG(bool, trace_type_check_elimination); 51 DECLARE_FLAG(bool, trace_type_check_elimination);
50 DECLARE_FLAG(bool, warn_on_javascript_compatibility); 52 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
51 53
52 // Quick access to the locally defined isolate() method. 54 // Quick access to the locally defined isolate() method.
53 #define I (isolate()) 55 #define I (isolate())
54 56
55 static bool ShouldInlineSimd() { 57 static bool ShouldInlineSimd() {
56 return FlowGraphCompiler::SupportsUnboxedSimd128(); 58 return FlowGraphCompiler::SupportsUnboxedSimd128();
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 deopt_target = insert_before = use->instruction(); 603 deopt_target = insert_before = use->instruction();
602 } 604 }
603 605
604 Definition* converted = NULL; 606 Definition* converted = NULL;
605 if ((from == kTagged) && (to == kUnboxedMint)) { 607 if ((from == kTagged) && (to == kUnboxedMint)) {
606 ASSERT((deopt_target != NULL) || 608 ASSERT((deopt_target != NULL) ||
607 (use->Type()->ToCid() == kUnboxedMint)); 609 (use->Type()->ToCid() == kUnboxedMint));
608 const intptr_t deopt_id = (deopt_target != NULL) ? 610 const intptr_t deopt_id = (deopt_target != NULL) ?
609 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 611 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
610 converted = new(I) UnboxIntegerInstr(use->CopyWithType(), deopt_id); 612 converted = new(I) UnboxIntegerInstr(use->CopyWithType(), deopt_id);
611
612 } else if ((from == kUnboxedMint) && (to == kTagged)) { 613 } else if ((from == kUnboxedMint) && (to == kTagged)) {
613 converted = new(I) BoxIntegerInstr(use->CopyWithType()); 614 converted = new(I) BoxIntegerInstr(use->CopyWithType());
614 615 } else if ((from == kUnboxedMint) && (to == kUnboxedUint32)) {
616 converted = new(I) UnboxedIntConverterInstr(from, to, use->CopyWithType());
617 } else if ((from == kUnboxedUint32) && (to == kUnboxedMint)) {
618 converted = new(I) UnboxedIntConverterInstr(from, to, use->CopyWithType());
615 } else if (from == kUnboxedMint && to == kUnboxedDouble) { 619 } else if (from == kUnboxedMint && to == kUnboxedDouble) {
616 ASSERT(CanUnboxDouble()); 620 ASSERT(CanUnboxDouble());
617 // Convert by boxing/unboxing. 621 // Convert by boxing/unboxing.
618 // TODO(fschneider): Implement direct unboxed mint-to-double conversion. 622 // TODO(fschneider): Implement direct unboxed mint-to-double conversion.
619 BoxIntegerInstr* boxed = 623 BoxIntegerInstr* boxed =
620 new(I) BoxIntegerInstr(use->CopyWithType()); 624 new(I) BoxIntegerInstr(use->CopyWithType());
621 use->BindTo(boxed); 625 use->BindTo(boxed);
622 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue); 626 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
623 627
624 const intptr_t deopt_id = (deopt_target != NULL) ? 628 const intptr_t deopt_id = (deopt_target != NULL) ?
(...skipping 3880 matching lines...) Expand 10 before | Expand all | Expand 10 after
4505 } 4509 }
4506 4510
4507 // Discard the environment from the original instruction because the store 4511 // Discard the environment from the original instruction because the store
4508 // can't deoptimize. 4512 // can't deoptimize.
4509 instr->RemoveEnvironment(); 4513 instr->RemoveEnvironment();
4510 ReplaceCall(instr, store); 4514 ReplaceCall(instr, store);
4511 return true; 4515 return true;
4512 } 4516 }
4513 4517
4514 4518
4515 // Range analysis for smi values. 4519 // Replaces Mint IL instructions with Uint32 IL instructions
4520 // when possible. Uses output of RangeAnalysis.
4521 class IntegerInstructionSelector : public ValueObject {
4522 public:
4523 explicit IntegerInstructionSelector(FlowGraph* flow_graph)
4524 : flow_graph_(flow_graph),
4525 isolate_(NULL) {
4526 ASSERT(flow_graph_ != NULL);
4527 isolate_ = flow_graph_->isolate();
4528 ASSERT(isolate_ != NULL);
4529 selected_uint32_defs_ =
4530 new(I) BitVector(flow_graph_->current_ssa_temp_index());
4531 }
4532
4533 void Select();
4534
4535 private:
4536 bool IsPotentialUint32Definition(Definition* def);
4537 void FindPotentialUint32Definitions();
4538 bool IsUint32NarrowingDefinition(Definition* def);
4539 void FindUint32NarrowingDefinitions();
4540 bool AllUsesAreUint32Narrowing(Value* list_head);
4541 bool CanBecomeUint32(Definition* def);
4542 void Propagate();
4543 Definition* ConstructReplacementFor(Definition* def);
4544 void ReplaceInstructions();
4545
4546 Isolate* isolate() const { return isolate_; }
4547
4548 GrowableArray<Definition*> potential_uint32_defs_;
4549 BitVector* selected_uint32_defs_;
4550
4551 FlowGraph* flow_graph_;
4552 Isolate* isolate_;
4553 };
4554
4555
4556 void IntegerInstructionSelector::Select() {
4557 if (FLAG_trace_integer_ir_selection) {
4558 OS::Print("---- starting integer ir selection -------\n");
4559 }
4560 FindPotentialUint32Definitions();
4561 FindUint32NarrowingDefinitions();
4562 Propagate();
4563 ReplaceInstructions();
4564 if (FLAG_trace_integer_ir_selection) {
4565 OS::Print("---- after integer ir selection -------\n");
4566 FlowGraphPrinter printer(*flow_graph_);
4567 printer.PrintBlocks();
4568 }
4569 }
4570
4571
4572 bool IntegerInstructionSelector::IsPotentialUint32Definition(Definition* def) {
4573 // TODO(johnmccutchan): Consider Smi operations, to avoid unnecessary tagging
4574 // & untagged of intermediate results.
4575 // TODO(johnmccutchan): Consider phis.
4576 return def->IsBoxInteger() || // BoxMint.
4577 def->IsUnboxInteger() || // UnboxMint.
4578 def->IsBinaryMintOp() ||
4579 def->IsShiftMintOp() ||
4580 def->IsUnaryMintOp();
4581 }
4582
4583
4584 void IntegerInstructionSelector::FindPotentialUint32Definitions() {
4585 if (FLAG_trace_integer_ir_selection) {
4586 OS::Print("++++ Finding potential Uint32 definitions:\n");
4587 }
4588
4589 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
4590 !block_it.Done();
4591 block_it.Advance()) {
4592 BlockEntryInstr* block = block_it.Current();
4593
4594 for (ForwardInstructionIterator instr_it(block);
4595 !instr_it.Done();
4596 instr_it.Advance()) {
4597 Instruction* current = instr_it.Current();
4598 Definition* defn = current->AsDefinition();
4599 if ((defn != NULL) && (defn->ssa_temp_index() != -1)) {
4600 if (IsPotentialUint32Definition(defn)) {
4601 if (FLAG_trace_integer_ir_selection) {
4602 OS::Print("Adding %s\n", current->ToCString());
4603 }
4604 potential_uint32_defs_.Add(defn);
4605 }
4606 }
4607 }
4608 }
4609 }
4610
4611
4612 // BinaryMintOp masks and stores into unsigned typed arrays that truncate the
4613 // value into a Uint32 range.
4614 bool IntegerInstructionSelector::IsUint32NarrowingDefinition(Definition* def) {
4615 if (def->IsBinaryMintOp()) {
4616 BinaryMintOpInstr* op = def->AsBinaryMintOp();
4617 // Must be a mask operation.
4618 if (op->op_kind() != Token::kBIT_AND) {
4619 return false;
4620 }
4621 Range* range = op->range();
4622 if ((range == NULL) ||
4623 !range->IsWithin(0, static_cast<int64_t>(kMaxUint32))) {
4624 return false;
4625 }
4626 return true;
4627 }
4628 // TODO(johnmccutchan): Add typed array stores.
4629 return false;
4630 }
4631
4632
4633 void IntegerInstructionSelector::FindUint32NarrowingDefinitions() {
4634 ASSERT(selected_uint32_defs_ != NULL);
4635 if (FLAG_trace_integer_ir_selection) {
4636 OS::Print("++++ Selecting Uint32 definitions:\n");
4637 OS::Print("++++ Initial set:\n");
4638 }
4639 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) {
4640 Definition* defn = potential_uint32_defs_[i];
4641 if (IsUint32NarrowingDefinition(defn)) {
4642 if (FLAG_trace_integer_ir_selection) {
4643 OS::Print("Adding %s\n", defn->ToCString());
4644 }
4645 selected_uint32_defs_->Add(defn->ssa_temp_index());
4646 }
4647 }
4648 }
4649
4650
4651 bool IntegerInstructionSelector::AllUsesAreUint32Narrowing(Value* list_head) {
4652 for (Value::Iterator it(list_head);
4653 !it.Done();
4654 it.Advance()) {
4655 Value* use = it.Current();
4656 Definition* defn = use->instruction()->AsDefinition();
4657 if ((defn == NULL) ||
4658 (defn->ssa_temp_index() == -1) ||
4659 !selected_uint32_defs_->Contains(defn->ssa_temp_index())) {
4660 return false;
4661 }
4662 }
4663 return true;
4664 }
4665
4666
4667 bool IntegerInstructionSelector::CanBecomeUint32(Definition* def) {
4668 ASSERT(IsPotentialUint32Definition(def));
4669 if (def->IsBoxInteger()) {
4670 // If a BoxInteger's input is a candidate, the box is a candidate.
4671 BoxIntegerInstr* box = def->AsBoxInteger();
4672 Definition* box_input = box->value()->definition();
4673 return selected_uint32_defs_->Contains(box_input->ssa_temp_index());
4674 }
4675 // A right shift with an input outside of Uint32 range cannot be converted
4676 // because we need the high bits.
4677 if (def->IsShiftMintOp()) {
4678 ShiftMintOpInstr* op = def->AsShiftMintOp();
4679 if (op->op_kind() == Token::kSHR) {
4680 Definition* shift_input = op->left()->definition();
4681 ASSERT(shift_input != NULL);
4682 Range* range = shift_input->range();
4683 if ((range == NULL) ||
4684 !range->IsWithin(0, static_cast<int64_t>(kMaxUint32))) {
4685 return false;
4686 }
4687 }
4688 }
4689 if (!def->HasUses()) {
4690 // No uses, skip.
4691 return false;
4692 }
4693 return AllUsesAreUint32Narrowing(def->input_use_list()) &&
4694 AllUsesAreUint32Narrowing(def->env_use_list());
4695 }
4696
4697
4698 void IntegerInstructionSelector::Propagate() {
4699 ASSERT(selected_uint32_defs_ != NULL);
4700 bool changed = true;
4701 intptr_t iteration = 0;
4702 while (changed) {
4703 if (FLAG_trace_integer_ir_selection) {
4704 OS::Print("+++ Iteration: %" Pd "\n", iteration++);
4705 }
4706 changed = false;
4707 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) {
4708 Definition* defn = potential_uint32_defs_[i];
4709 if (selected_uint32_defs_->Contains(defn->ssa_temp_index())) {
4710 // Already marked as a candidate, skip.
4711 continue;
4712 }
4713 if (defn->IsConstant()) {
4714 // Skip constants.
4715 continue;
4716 }
4717 if (CanBecomeUint32(defn)) {
4718 if (FLAG_trace_integer_ir_selection) {
4719 OS::Print("Adding %s\n", defn->ToCString());
4720 }
4721 // Found a new candidate.
4722 selected_uint32_defs_->Add(defn->ssa_temp_index());
4723 // Haven't reached fixed point yet.
4724 changed = true;
4725 }
4726 }
4727 }
4728 if (FLAG_trace_integer_ir_selection) {
4729 OS::Print("Reached fixed point\n");
4730 }
4731 }
4732
4733
4734 Definition* IntegerInstructionSelector::ConstructReplacementFor(
4735 Definition* def) {
4736 // Should only see mint definitions.
4737 ASSERT(IsPotentialUint32Definition(def));
4738 // Should not see constant instructions.
4739 ASSERT(!def->IsConstant());
4740 if (def->IsBinaryMintOp()) {
4741 BinaryMintOpInstr* op = def->AsBinaryMintOp();
4742 Token::Kind op_kind = op->op_kind();
4743 Value* left = op->left()->CopyWithType();
4744 Value* right = op->right()->CopyWithType();
4745 intptr_t deopt_id = op->DeoptimizationTarget();
4746 return new(I) BinaryUint32OpInstr(op_kind, left, right, deopt_id);
4747 } else if (def->IsBoxInteger()) {
4748 BoxIntegerInstr* box = def->AsBoxInteger();
4749 Value* value = box->value()->CopyWithType();
4750 return new(I) BoxUint32Instr(value);
4751 } else if (def->IsUnboxInteger()) {
4752 UnboxIntegerInstr* unbox = def->AsUnboxInteger();
4753 Value* value = unbox->value()->CopyWithType();
4754 intptr_t deopt_id = unbox->deopt_id();
4755 return new(I) UnboxUint32Instr(value, deopt_id);
4756 } else if (def->IsUnaryMintOp()) {
4757 UnaryMintOpInstr* op = def->AsUnaryMintOp();
4758 Token::Kind op_kind = op->op_kind();
4759 Value* value = op->value()->CopyWithType();
4760 intptr_t deopt_id = op->DeoptimizationTarget();
4761 return new(I) UnaryUint32OpInstr(op_kind, value, deopt_id);
4762 } else if (def->IsShiftMintOp()) {
4763 ShiftMintOpInstr* op = def->AsShiftMintOp();
4764 Token::Kind op_kind = op->op_kind();
4765 Value* left = op->left()->CopyWithType();
4766 Value* right = op->right()->CopyWithType();
4767 intptr_t deopt_id = op->DeoptimizationTarget();
4768 return new(I) ShiftUint32OpInstr(op_kind, left, right, deopt_id);
4769 }
4770 UNREACHABLE();
4771 return NULL;
4772 }
4773
4774
4775 void IntegerInstructionSelector::ReplaceInstructions() {
4776 if (FLAG_trace_integer_ir_selection) {
4777 OS::Print("++++ Replacing instructions:\n");
4778 }
4779 for (intptr_t i = 0; i < potential_uint32_defs_.length(); i++) {
4780 Definition* defn = potential_uint32_defs_[i];
4781 if (!selected_uint32_defs_->Contains(defn->ssa_temp_index())) {
4782 // Not a candidate.
4783 continue;
4784 }
4785 Definition* replacement = ConstructReplacementFor(defn);
4786 ASSERT(replacement != NULL);
4787 if (FLAG_trace_integer_ir_selection) {
4788 OS::Print("Replacing %s with %s\n", defn->ToCString(),
4789 replacement->ToCString());
4790 }
4791 defn->ReplaceWith(replacement, NULL);
4792 ASSERT(flow_graph_->VerifyUseLists());
4793 }
4794 }
4795
4796 void FlowGraphOptimizer::SelectIntegerInstructions() {
4797 IntegerInstructionSelector iis(flow_graph_);
4798 iis.Select();
4799 }
4800
4801
4802 // Range analysis for integer values.
4516 class RangeAnalysis : public ValueObject { 4803 class RangeAnalysis : public ValueObject {
4517 public: 4804 public:
4518 explicit RangeAnalysis(FlowGraph* flow_graph) 4805 explicit RangeAnalysis(FlowGraph* flow_graph)
4519 : flow_graph_(flow_graph), 4806 : flow_graph_(flow_graph),
4520 marked_defns_(NULL) { } 4807 marked_defns_(NULL) { }
4521 4808
4522 // Infer ranges for all values and remove overflow checks from binary smi 4809 // Infer ranges for all values and remove overflow checks from binary smi
4523 // operations when proven redundant. 4810 // operations when proven redundant.
4524 void Analyze(); 4811 void Analyze();
4525 4812
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
4614 BitVector* marked_defns_; 4901 BitVector* marked_defns_;
4615 4902
4616 DISALLOW_COPY_AND_ASSIGN(RangeAnalysis); 4903 DISALLOW_COPY_AND_ASSIGN(RangeAnalysis);
4617 }; 4904 };
4618 4905
4619 4906
4620 void RangeAnalysis::Analyze() { 4907 void RangeAnalysis::Analyze() {
4621 CollectValues(); 4908 CollectValues();
4622 InsertConstraints(); 4909 InsertConstraints();
4623 InferRanges(); 4910 InferRanges();
4911 IntegerInstructionSelector iis(flow_graph_);
4912 iis.Select();
4624 RemoveConstraints(); 4913 RemoveConstraints();
4625 } 4914 }
4626 4915
4627 4916
4628 void RangeAnalysis::CollectValues() { 4917 void RangeAnalysis::CollectValues() {
4629 const GrowableArray<Definition*>& initial = 4918 const GrowableArray<Definition*>& initial =
4630 *flow_graph_->graph_entry()->initial_definitions(); 4919 *flow_graph_->graph_entry()->initial_definitions();
4631 for (intptr_t i = 0; i < initial.length(); ++i) { 4920 for (intptr_t i = 0; i < initial.length(); ++i) {
4632 Definition* current = initial[i]; 4921 Definition* current = initial[i];
4633 if (current->Type()->ToCid() == kSmiCid) { 4922 if (current->Type()->ToCid() == kSmiCid) {
(...skipping 3843 matching lines...) Expand 10 before | Expand all | Expand 10 after
8477 UNREACHABLE(); 8766 UNREACHABLE();
8478 } 8767 }
8479 } else { 8768 } else {
8480 // TODO(kmillikin): support other types. 8769 // TODO(kmillikin): support other types.
8481 SetValue(instr, non_constant_); 8770 SetValue(instr, non_constant_);
8482 } 8771 }
8483 } 8772 }
8484 } 8773 }
8485 8774
8486 8775
8776 void ConstantPropagator::TruncateInteger(Definition* defn, int64_t mask) {
8777 const Object& value = defn->constant_value();
8778 if (IsNonConstant(value)) {
8779 return;
8780 }
8781 ASSERT(IsConstant(value));
8782 if (!value.IsInteger()) {
8783 return;
8784 }
8785 const Integer& value_int = Integer::Cast(value);
8786 int64_t truncated = value_int.AsInt64Value() & mask;
8787 Instance& result = Integer::ZoneHandle(I, Integer::New(truncated));
8788 result = result.CheckAndCanonicalize(NULL);
8789 ASSERT(!result.IsNull());
8790 SetValue(defn, result);
8791 }
8792
8793
8487 void ConstantPropagator::VisitBinarySmiOp(BinarySmiOpInstr* instr) { 8794 void ConstantPropagator::VisitBinarySmiOp(BinarySmiOpInstr* instr) {
8488 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right()); 8795 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
8489 } 8796 }
8490 8797
8491 8798
8492 void ConstantPropagator::VisitBoxInteger(BoxIntegerInstr* instr) { 8799 void ConstantPropagator::VisitBoxInteger(BoxIntegerInstr* instr) {
8493 // TODO(kmillikin): Handle box operation. 8800 // TODO(kmillikin): Handle box operation.
8494 SetValue(instr, non_constant_); 8801 SetValue(instr, non_constant_);
8495 } 8802 }
8496 8803
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
8909 const Object& value = instr->value()->definition()->constant_value(); 9216 const Object& value = instr->value()->definition()->constant_value();
8910 if (IsNonConstant(value)) { 9217 if (IsNonConstant(value)) {
8911 SetValue(instr, non_constant_); 9218 SetValue(instr, non_constant_);
8912 } else if (IsConstant(value)) { 9219 } else if (IsConstant(value)) {
8913 // TODO(kmillikin): Handle conversion. 9220 // TODO(kmillikin): Handle conversion.
8914 SetValue(instr, non_constant_); 9221 SetValue(instr, non_constant_);
8915 } 9222 }
8916 } 9223 }
8917 9224
8918 9225
9226 void ConstantPropagator::VisitBoxUint32(BoxUint32Instr* instr) {
9227 // TODO(kmillikin): Handle box operation.
9228 SetValue(instr, non_constant_);
9229 }
9230
9231
9232 void ConstantPropagator::VisitUnboxUint32(UnboxUint32Instr* instr) {
9233 // TODO(kmillikin): Handle unbox operation.
9234 SetValue(instr, non_constant_);
9235 }
9236
9237
9238 void ConstantPropagator::VisitUnboxedIntConverter(
9239 UnboxedIntConverterInstr* instr) {
9240 SetValue(instr, non_constant_);
9241 }
9242
9243
9244 void ConstantPropagator::VisitBinaryUint32Op(BinaryUint32OpInstr* instr) {
9245 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
9246 TruncateInteger(instr, static_cast<int64_t>(0xFFFFFFFF));
9247 }
9248
9249
9250 void ConstantPropagator::VisitShiftUint32Op(ShiftUint32OpInstr* instr) {
9251 HandleBinaryOp(instr, instr->op_kind(), *instr->left(), *instr->right());
9252 TruncateInteger(instr, static_cast<int64_t>(0xFFFFFFFF));
9253 }
9254
9255
9256 void ConstantPropagator::VisitUnaryUint32Op(UnaryUint32OpInstr* instr) {
9257 // TODO(kmillikin): Handle unary operations.
9258 SetValue(instr, non_constant_);
9259 }
9260
9261
8919 void ConstantPropagator::Analyze() { 9262 void ConstantPropagator::Analyze() {
8920 GraphEntryInstr* entry = graph_->graph_entry(); 9263 GraphEntryInstr* entry = graph_->graph_entry();
8921 reachable_->Add(entry->preorder_number()); 9264 reachable_->Add(entry->preorder_number());
8922 block_worklist_.Add(entry); 9265 block_worklist_.Add(entry);
8923 9266
8924 while (true) { 9267 while (true) {
8925 if (block_worklist_.is_empty()) { 9268 if (block_worklist_.is_empty()) {
8926 if (definition_worklist_.is_empty()) break; 9269 if (definition_worklist_.is_empty()) break;
8927 Definition* definition = definition_worklist_.RemoveLast(); 9270 Definition* definition = definition_worklist_.RemoveLast();
8928 definition_marks_->Remove(definition->ssa_temp_index()); 9271 definition_marks_->Remove(definition->ssa_temp_index());
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after
9782 } 10125 }
9783 10126
9784 // Insert materializations at environment uses. 10127 // Insert materializations at environment uses.
9785 for (intptr_t i = 0; i < exits.length(); i++) { 10128 for (intptr_t i = 0; i < exits.length(); i++) {
9786 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); 10129 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots);
9787 } 10130 }
9788 } 10131 }
9789 10132
9790 10133
9791 } // namespace dart 10134 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698