| OLD | NEW |
| 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 4747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4758 Definition* defn = worklist.definitions()[j]; | 4758 Definition* defn = worklist.definitions()[j]; |
| 4759 | 4759 |
| 4760 if (FLAG_trace_smi_widening) { | 4760 if (FLAG_trace_smi_widening) { |
| 4761 OS::Print("> %s\n", defn->ToCString()); | 4761 OS::Print("> %s\n", defn->ToCString()); |
| 4762 } | 4762 } |
| 4763 | 4763 |
| 4764 if (defn->IsBinarySmiOp() && | 4764 if (defn->IsBinarySmiOp() && |
| 4765 BenefitsFromWidening(defn->AsBinarySmiOp())) { | 4765 BenefitsFromWidening(defn->AsBinarySmiOp())) { |
| 4766 gain++; | 4766 gain++; |
| 4767 if (FLAG_trace_smi_widening) { | 4767 if (FLAG_trace_smi_widening) { |
| 4768 OS::Print("^ [%d] (o) %s\n", gain, defn->ToCString()); | 4768 OS::Print("^ [%" Pd "] (o) %s\n", gain, defn->ToCString()); |
| 4769 } | 4769 } |
| 4770 } | 4770 } |
| 4771 | 4771 |
| 4772 const intptr_t defn_loop = loops[defn->GetBlock()->preorder_number()]; | 4772 const intptr_t defn_loop = loops[defn->GetBlock()->preorder_number()]; |
| 4773 | 4773 |
| 4774 // Process all inputs. | 4774 // Process all inputs. |
| 4775 for (intptr_t k = 0; k < defn->InputCount(); k++) { | 4775 for (intptr_t k = 0; k < defn->InputCount(); k++) { |
| 4776 Definition* input = defn->InputAt(k)->definition(); | 4776 Definition* input = defn->InputAt(k)->definition(); |
| 4777 if (input->IsBinarySmiOp() && | 4777 if (input->IsBinarySmiOp() && |
| 4778 CanBeWidened(input->AsBinarySmiOp())) { | 4778 CanBeWidened(input->AsBinarySmiOp())) { |
| 4779 worklist.Add(input); | 4779 worklist.Add(input); |
| 4780 } else if (input->IsPhi() && input->Type()->ToCid() == kSmiCid) { | 4780 } else if (input->IsPhi() && input->Type()->ToCid() == kSmiCid) { |
| 4781 worklist.Add(input); | 4781 worklist.Add(input); |
| 4782 } else if (input->IsBinaryMintOp()) { | 4782 } else if (input->IsBinaryMintOp()) { |
| 4783 // Mint operation produces untagged result. We avoid tagging. | 4783 // Mint operation produces untagged result. We avoid tagging. |
| 4784 gain++; | 4784 gain++; |
| 4785 if (FLAG_trace_smi_widening) { | 4785 if (FLAG_trace_smi_widening) { |
| 4786 OS::Print("^ [%d] (i) %s\n", gain, input->ToCString()); | 4786 OS::Print("^ [%" Pd "] (i) %s\n", gain, input->ToCString()); |
| 4787 } | 4787 } |
| 4788 } else if (defn_loop == loops[input->GetBlock()->preorder_number()] && | 4788 } else if (defn_loop == loops[input->GetBlock()->preorder_number()] && |
| 4789 (input->Type()->ToCid() == kSmiCid)) { | 4789 (input->Type()->ToCid() == kSmiCid)) { |
| 4790 // Input comes from the same loop, is known to be smi and requires | 4790 // Input comes from the same loop, is known to be smi and requires |
| 4791 // untagging. | 4791 // untagging. |
| 4792 // TODO(vegorov) this heuristic assumes that values that are not | 4792 // TODO(vegorov) this heuristic assumes that values that are not |
| 4793 // known to be smi have to be checked and this check can be | 4793 // known to be smi have to be checked and this check can be |
| 4794 // coalesced with untagging. Start coalescing them. | 4794 // coalesced with untagging. Start coalescing them. |
| 4795 gain--; | 4795 gain--; |
| 4796 if (FLAG_trace_smi_widening) { | 4796 if (FLAG_trace_smi_widening) { |
| 4797 OS::Print("v [%d] (i) %s\n", gain, input->ToCString()); | 4797 OS::Print("v [%" Pd "] (i) %s\n", gain, input->ToCString()); |
| 4798 } | 4798 } |
| 4799 } | 4799 } |
| 4800 } | 4800 } |
| 4801 | 4801 |
| 4802 // Process all uses. | 4802 // Process all uses. |
| 4803 for (Value* use = defn->input_use_list(); | 4803 for (Value* use = defn->input_use_list(); |
| 4804 use != NULL; | 4804 use != NULL; |
| 4805 use = use->next_use()) { | 4805 use = use->next_use()) { |
| 4806 Instruction* instr = use->instruction(); | 4806 Instruction* instr = use->instruction(); |
| 4807 Definition* use_defn = instr->AsDefinition(); | 4807 Definition* use_defn = instr->AsDefinition(); |
| 4808 if (use_defn == NULL) { | 4808 if (use_defn == NULL) { |
| 4809 // We assume that tagging before returning or pushing argument costs | 4809 // We assume that tagging before returning or pushing argument costs |
| 4810 // very little compared to the cost of the return/call itself. | 4810 // very little compared to the cost of the return/call itself. |
| 4811 if (!instr->IsReturn() && !instr->IsPushArgument()) { | 4811 if (!instr->IsReturn() && !instr->IsPushArgument()) { |
| 4812 gain--; | 4812 gain--; |
| 4813 if (FLAG_trace_smi_widening) { | 4813 if (FLAG_trace_smi_widening) { |
| 4814 OS::Print("v [%d] (u) %s\n", | 4814 OS::Print("v [%" Pd "] (u) %s\n", |
| 4815 gain, use->instruction()->ToCString()); | 4815 gain, |
| 4816 use->instruction()->ToCString()); |
| 4816 } | 4817 } |
| 4817 } | 4818 } |
| 4818 continue; | 4819 continue; |
| 4819 } else if (use_defn->IsBinarySmiOp() && | 4820 } else if (use_defn->IsBinarySmiOp() && |
| 4820 CanBeWidened(use_defn->AsBinarySmiOp())) { | 4821 CanBeWidened(use_defn->AsBinarySmiOp())) { |
| 4821 worklist.Add(use_defn); | 4822 worklist.Add(use_defn); |
| 4822 } else if (use_defn->IsPhi() && | 4823 } else if (use_defn->IsPhi() && |
| 4823 use_defn->AsPhi()->Type()->ToCid() == kSmiCid) { | 4824 use_defn->AsPhi()->Type()->ToCid() == kSmiCid) { |
| 4824 worklist.Add(use_defn); | 4825 worklist.Add(use_defn); |
| 4825 } else if (use_defn->IsBinaryMintOp()) { | 4826 } else if (use_defn->IsBinaryMintOp()) { |
| 4826 // BinaryMintOp requires untagging of its inputs. | 4827 // BinaryMintOp requires untagging of its inputs. |
| 4827 // Converting kUnboxedInt32 to kUnboxedMint is essentially zero cost | 4828 // Converting kUnboxedInt32 to kUnboxedMint is essentially zero cost |
| 4828 // sign extension operation. | 4829 // sign extension operation. |
| 4829 gain++; | 4830 gain++; |
| 4830 if (FLAG_trace_smi_widening) { | 4831 if (FLAG_trace_smi_widening) { |
| 4831 OS::Print("^ [%d] (u) %s\n", gain, use->instruction()->ToCString()); | 4832 OS::Print("^ [%" Pd "] (u) %s\n", |
| 4833 gain, |
| 4834 use->instruction()->ToCString()); |
| 4832 } | 4835 } |
| 4833 } else if (defn_loop == loops[instr->GetBlock()->preorder_number()]) { | 4836 } else if (defn_loop == loops[instr->GetBlock()->preorder_number()]) { |
| 4834 gain--; | 4837 gain--; |
| 4835 if (FLAG_trace_smi_widening) { | 4838 if (FLAG_trace_smi_widening) { |
| 4836 OS::Print("v [%d] (u) %s\n", gain, use->instruction()->ToCString()); | 4839 OS::Print("v [%" Pd "] (u) %s\n", |
| 4840 gain, |
| 4841 use->instruction()->ToCString()); |
| 4837 } | 4842 } |
| 4838 } | 4843 } |
| 4839 } | 4844 } |
| 4840 } | 4845 } |
| 4841 | 4846 |
| 4842 processed->AddAll(worklist.contains()); | 4847 processed->AddAll(worklist.contains()); |
| 4843 | 4848 |
| 4844 if (FLAG_trace_smi_widening) { | 4849 if (FLAG_trace_smi_widening) { |
| 4845 OS::Print("~ %s gain %d\n", op->ToCString(), gain); | 4850 OS::Print("~ %s gain %" Pd "\n", op->ToCString(), gain); |
| 4846 } | 4851 } |
| 4847 | 4852 |
| 4848 if (gain > 0) { | 4853 if (gain > 0) { |
| 4849 // We have positive gain from widening. Convert all BinarySmiOpInstr into | 4854 // We have positive gain from widening. Convert all BinarySmiOpInstr into |
| 4850 // BinaryInt32OpInstr and set representation of all phis to kUnboxedInt32. | 4855 // BinaryInt32OpInstr and set representation of all phis to kUnboxedInt32. |
| 4851 for (intptr_t j = 0; j < worklist.definitions().length(); j++) { | 4856 for (intptr_t j = 0; j < worklist.definitions().length(); j++) { |
| 4852 Definition* defn = worklist.definitions()[j]; | 4857 Definition* defn = worklist.definitions()[j]; |
| 4853 ASSERT(defn->IsPhi() || defn->IsBinarySmiOp()); | 4858 ASSERT(defn->IsPhi() || defn->IsBinarySmiOp()); |
| 4854 | 4859 |
| 4855 if (defn->IsBinarySmiOp()) { | 4860 if (defn->IsBinarySmiOp()) { |
| (...skipping 5098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9954 | 9959 |
| 9955 // Insert materializations at environment uses. | 9960 // Insert materializations at environment uses. |
| 9956 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 9961 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 9957 CreateMaterializationAt( | 9962 CreateMaterializationAt( |
| 9958 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); | 9963 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); |
| 9959 } | 9964 } |
| 9960 } | 9965 } |
| 9961 | 9966 |
| 9962 | 9967 |
| 9963 } // namespace dart | 9968 } // namespace dart |
| OLD | NEW |