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

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

Powered by Google App Engine
This is Rietveld 408576698