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

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

Issue 1314673008: Migrate logging infrastructure Isolate->Thread (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix test. Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 Instruction* replacement, 630 Instruction* replacement,
631 FlowGraph* graph) { 631 FlowGraph* graph) {
632 Definition* current_defn = current->AsDefinition(); 632 Definition* current_defn = current->AsDefinition();
633 if ((replacement != NULL) && (current_defn != NULL)) { 633 if ((replacement != NULL) && (current_defn != NULL)) {
634 Definition* replacement_defn = replacement->AsDefinition(); 634 Definition* replacement_defn = replacement->AsDefinition();
635 ASSERT(replacement_defn != NULL); 635 ASSERT(replacement_defn != NULL);
636 current_defn->ReplaceUsesWith(replacement_defn); 636 current_defn->ReplaceUsesWith(replacement_defn);
637 EnsureSSATempIndex(graph, current_defn, replacement_defn); 637 EnsureSSATempIndex(graph, current_defn, replacement_defn);
638 638
639 if (FLAG_trace_optimization) { 639 if (FLAG_trace_optimization) {
640 ISL_Print("Replacing v%" Pd " with v%" Pd "\n", 640 THR_Print("Replacing v%" Pd " with v%" Pd "\n",
641 current_defn->ssa_temp_index(), 641 current_defn->ssa_temp_index(),
642 replacement_defn->ssa_temp_index()); 642 replacement_defn->ssa_temp_index());
643 } 643 }
644 } else if (FLAG_trace_optimization) { 644 } else if (FLAG_trace_optimization) {
645 if (current_defn == NULL) { 645 if (current_defn == NULL) {
646 ISL_Print("Removing %s\n", current->DebugName()); 646 THR_Print("Removing %s\n", current->DebugName());
647 } else { 647 } else {
648 ASSERT(!current_defn->HasUses()); 648 ASSERT(!current_defn->HasUses());
649 ISL_Print("Removing v%" Pd ".\n", current_defn->ssa_temp_index()); 649 THR_Print("Removing v%" Pd ".\n", current_defn->ssa_temp_index());
650 } 650 }
651 } 651 }
652 iterator->RemoveCurrentFromGraph(); 652 iterator->RemoveCurrentFromGraph();
653 } 653 }
654 654
655 655
656 bool FlowGraphOptimizer::Canonicalize() { 656 bool FlowGraphOptimizer::Canonicalize() {
657 bool changed = false; 657 bool changed = false;
658 for (intptr_t i = 0; i < block_order_.length(); ++i) { 658 for (intptr_t i = 0; i < block_order_.length(); ++i) {
659 BlockEntryInstr* entry = block_order_[i]; 659 BlockEntryInstr* entry = block_order_[i];
(...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after
2330 const Function& function = flow_graph_->function(); 2330 const Function& function = flow_graph_->function();
2331 if (function.IsDynamicFunction() && 2331 if (function.IsDynamicFunction() &&
2332 callee_receiver->IsParameter() && 2332 callee_receiver->IsParameter() &&
2333 (callee_receiver->AsParameter()->index() == 0)) { 2333 (callee_receiver->AsParameter()->index() == 0)) {
2334 const String& name = (kind == RawFunction::kMethodExtractor) 2334 const String& name = (kind == RawFunction::kMethodExtractor)
2335 ? String::Handle(Z, Field::NameFromGetter(call->function_name())) 2335 ? String::Handle(Z, Field::NameFromGetter(call->function_name()))
2336 : call->function_name(); 2336 : call->function_name();
2337 const Class& cls = Class::Handle(Z, function.Owner()); 2337 const Class& cls = Class::Handle(Z, function.Owner());
2338 if (!thread()->cha()->HasOverride(cls, name)) { 2338 if (!thread()->cha()->HasOverride(cls, name)) {
2339 if (FLAG_trace_cha) { 2339 if (FLAG_trace_cha) {
2340 ISL_Print(" **(CHA) Instance call needs no check, " 2340 THR_Print(" **(CHA) Instance call needs no check, "
2341 "no overrides of '%s' '%s'\n", 2341 "no overrides of '%s' '%s'\n",
2342 name.ToCString(), cls.ToCString()); 2342 name.ToCString(), cls.ToCString());
2343 } 2343 }
2344 thread()->cha()->AddToLeafClasses(cls); 2344 thread()->cha()->AddToLeafClasses(cls);
2345 return false; 2345 return false;
2346 } 2346 }
2347 } 2347 }
2348 return true; 2348 return true;
2349 } 2349 }
2350 2350
(...skipping 1678 matching lines...) Expand 10 before | Expand all | Expand 10 after
4029 if (CHA::IsImplemented(type_class)) return false; 4029 if (CHA::IsImplemented(type_class)) return false;
4030 // Check if there are subclasses. 4030 // Check if there are subclasses.
4031 if (CHA::HasSubclasses(type_class)) { 4031 if (CHA::HasSubclasses(type_class)) {
4032 return false; 4032 return false;
4033 } 4033 }
4034 4034
4035 // Private classes cannot be subclassed by later loaded libs. 4035 // Private classes cannot be subclassed by later loaded libs.
4036 if (!type_class.IsPrivate()) { 4036 if (!type_class.IsPrivate()) {
4037 if (FLAG_use_cha_deopt) { 4037 if (FLAG_use_cha_deopt) {
4038 if (FLAG_trace_cha) { 4038 if (FLAG_trace_cha) {
4039 ISL_Print(" **(CHA) Typecheck as class equality since no " 4039 THR_Print(" **(CHA) Typecheck as class equality since no "
4040 "subclasses: %s\n", 4040 "subclasses: %s\n",
4041 type_class.ToCString()); 4041 type_class.ToCString());
4042 } 4042 }
4043 thread()->cha()->AddToLeafClasses(type_class); 4043 thread()->cha()->AddToLeafClasses(type_class);
4044 } else { 4044 } else {
4045 return false; 4045 return false;
4046 } 4046 }
4047 } 4047 }
4048 const intptr_t num_type_args = type_class.NumTypeArguments(); 4048 const intptr_t num_type_args = type_class.NumTypeArguments();
4049 if (num_type_args > 0) { 4049 if (num_type_args > 0) {
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
4613 if (field.is_double_initialized()) { 4613 if (field.is_double_initialized()) {
4614 unboxed_field = true; 4614 unboxed_field = true;
4615 } else if ((setter.usage_counter() > 0) && 4615 } else if ((setter.usage_counter() > 0) &&
4616 ((FLAG_getter_setter_ratio * setter.usage_counter()) >= 4616 ((FLAG_getter_setter_ratio * setter.usage_counter()) >=
4617 getter.usage_counter())) { 4617 getter.usage_counter())) {
4618 unboxed_field = true; 4618 unboxed_field = true;
4619 } 4619 }
4620 } 4620 }
4621 if (!unboxed_field) { 4621 if (!unboxed_field) {
4622 if (FLAG_trace_optimization || FLAG_trace_field_guards) { 4622 if (FLAG_trace_optimization || FLAG_trace_field_guards) {
4623 ISL_Print("Disabling unboxing of %s\n", field.ToCString()); 4623 THR_Print("Disabling unboxing of %s\n", field.ToCString());
4624 if (!setter.IsNull()) { 4624 if (!setter.IsNull()) {
4625 OS::Print(" setter usage count: %" Pd "\n", setter.usage_counter()); 4625 OS::Print(" setter usage count: %" Pd "\n", setter.usage_counter());
4626 } 4626 }
4627 if (!getter.IsNull()) { 4627 if (!getter.IsNull()) {
4628 OS::Print(" getter usage count: %" Pd "\n", getter.usage_counter()); 4628 OS::Print(" getter usage count: %" Pd "\n", getter.usage_counter());
4629 } 4629 }
4630 } 4630 }
4631 field.set_is_unboxing_candidate(false); 4631 field.set_is_unboxing_candidate(false);
4632 field.DeoptimizeDependentCode(); 4632 field.DeoptimizeDependentCode();
4633 } else { 4633 } else {
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
4842 4842
4843 // Worklist used to collect dependency graph. 4843 // Worklist used to collect dependency graph.
4844 DefinitionWorklist worklist(flow_graph_, candidates.length()); 4844 DefinitionWorklist worklist(flow_graph_, candidates.length());
4845 for (intptr_t i = 0; i < candidates.length(); i++) { 4845 for (intptr_t i = 0; i < candidates.length(); i++) {
4846 BinarySmiOpInstr* op = candidates[i]; 4846 BinarySmiOpInstr* op = candidates[i];
4847 if (op->WasEliminated() || processed->Contains(op->ssa_temp_index())) { 4847 if (op->WasEliminated() || processed->Contains(op->ssa_temp_index())) {
4848 continue; 4848 continue;
4849 } 4849 }
4850 4850
4851 if (FLAG_trace_smi_widening) { 4851 if (FLAG_trace_smi_widening) {
4852 ISL_Print("analysing candidate: %s\n", op->ToCString()); 4852 THR_Print("analysing candidate: %s\n", op->ToCString());
4853 } 4853 }
4854 worklist.Clear(); 4854 worklist.Clear();
4855 worklist.Add(op); 4855 worklist.Add(op);
4856 4856
4857 // Collect dependency graph. Note: more items are added to worklist 4857 // Collect dependency graph. Note: more items are added to worklist
4858 // inside this loop. 4858 // inside this loop.
4859 intptr_t gain = 0; 4859 intptr_t gain = 0;
4860 for (intptr_t j = 0; j < worklist.definitions().length(); j++) { 4860 for (intptr_t j = 0; j < worklist.definitions().length(); j++) {
4861 Definition* defn = worklist.definitions()[j]; 4861 Definition* defn = worklist.definitions()[j];
4862 4862
4863 if (FLAG_trace_smi_widening) { 4863 if (FLAG_trace_smi_widening) {
4864 ISL_Print("> %s\n", defn->ToCString()); 4864 THR_Print("> %s\n", defn->ToCString());
4865 } 4865 }
4866 4866
4867 if (defn->IsBinarySmiOp() && 4867 if (defn->IsBinarySmiOp() &&
4868 BenefitsFromWidening(defn->AsBinarySmiOp())) { 4868 BenefitsFromWidening(defn->AsBinarySmiOp())) {
4869 gain++; 4869 gain++;
4870 if (FLAG_trace_smi_widening) { 4870 if (FLAG_trace_smi_widening) {
4871 ISL_Print("^ [%" Pd "] (o) %s\n", gain, defn->ToCString()); 4871 THR_Print("^ [%" Pd "] (o) %s\n", gain, defn->ToCString());
4872 } 4872 }
4873 } 4873 }
4874 4874
4875 const intptr_t defn_loop = loops[defn->GetBlock()->preorder_number()]; 4875 const intptr_t defn_loop = loops[defn->GetBlock()->preorder_number()];
4876 4876
4877 // Process all inputs. 4877 // Process all inputs.
4878 for (intptr_t k = 0; k < defn->InputCount(); k++) { 4878 for (intptr_t k = 0; k < defn->InputCount(); k++) {
4879 Definition* input = defn->InputAt(k)->definition(); 4879 Definition* input = defn->InputAt(k)->definition();
4880 if (input->IsBinarySmiOp() && 4880 if (input->IsBinarySmiOp() &&
4881 CanBeWidened(input->AsBinarySmiOp())) { 4881 CanBeWidened(input->AsBinarySmiOp())) {
4882 worklist.Add(input); 4882 worklist.Add(input);
4883 } else if (input->IsPhi() && (input->Type()->ToCid() == kSmiCid)) { 4883 } else if (input->IsPhi() && (input->Type()->ToCid() == kSmiCid)) {
4884 worklist.Add(input); 4884 worklist.Add(input);
4885 } else if (input->IsBinaryMintOp()) { 4885 } else if (input->IsBinaryMintOp()) {
4886 // Mint operation produces untagged result. We avoid tagging. 4886 // Mint operation produces untagged result. We avoid tagging.
4887 gain++; 4887 gain++;
4888 if (FLAG_trace_smi_widening) { 4888 if (FLAG_trace_smi_widening) {
4889 ISL_Print("^ [%" Pd "] (i) %s\n", gain, input->ToCString()); 4889 THR_Print("^ [%" Pd "] (i) %s\n", gain, input->ToCString());
4890 } 4890 }
4891 } else if (defn_loop == loops[input->GetBlock()->preorder_number()] && 4891 } else if (defn_loop == loops[input->GetBlock()->preorder_number()] &&
4892 (input->Type()->ToCid() == kSmiCid)) { 4892 (input->Type()->ToCid() == kSmiCid)) {
4893 // Input comes from the same loop, is known to be smi and requires 4893 // Input comes from the same loop, is known to be smi and requires
4894 // untagging. 4894 // untagging.
4895 // TODO(vegorov) this heuristic assumes that values that are not 4895 // TODO(vegorov) this heuristic assumes that values that are not
4896 // known to be smi have to be checked and this check can be 4896 // known to be smi have to be checked and this check can be
4897 // coalesced with untagging. Start coalescing them. 4897 // coalesced with untagging. Start coalescing them.
4898 gain--; 4898 gain--;
4899 if (FLAG_trace_smi_widening) { 4899 if (FLAG_trace_smi_widening) {
4900 ISL_Print("v [%" Pd "] (i) %s\n", gain, input->ToCString()); 4900 THR_Print("v [%" Pd "] (i) %s\n", gain, input->ToCString());
4901 } 4901 }
4902 } 4902 }
4903 } 4903 }
4904 4904
4905 // Process all uses. 4905 // Process all uses.
4906 for (Value* use = defn->input_use_list(); 4906 for (Value* use = defn->input_use_list();
4907 use != NULL; 4907 use != NULL;
4908 use = use->next_use()) { 4908 use = use->next_use()) {
4909 Instruction* instr = use->instruction(); 4909 Instruction* instr = use->instruction();
4910 Definition* use_defn = instr->AsDefinition(); 4910 Definition* use_defn = instr->AsDefinition();
4911 if (use_defn == NULL) { 4911 if (use_defn == NULL) {
4912 // We assume that tagging before returning or pushing argument costs 4912 // We assume that tagging before returning or pushing argument costs
4913 // very little compared to the cost of the return/call itself. 4913 // very little compared to the cost of the return/call itself.
4914 if (!instr->IsReturn() && !instr->IsPushArgument()) { 4914 if (!instr->IsReturn() && !instr->IsPushArgument()) {
4915 gain--; 4915 gain--;
4916 if (FLAG_trace_smi_widening) { 4916 if (FLAG_trace_smi_widening) {
4917 ISL_Print("v [%" Pd "] (u) %s\n", 4917 THR_Print("v [%" Pd "] (u) %s\n",
4918 gain, 4918 gain,
4919 use->instruction()->ToCString()); 4919 use->instruction()->ToCString());
4920 } 4920 }
4921 } 4921 }
4922 continue; 4922 continue;
4923 } else if (use_defn->IsBinarySmiOp() && 4923 } else if (use_defn->IsBinarySmiOp() &&
4924 CanBeWidened(use_defn->AsBinarySmiOp())) { 4924 CanBeWidened(use_defn->AsBinarySmiOp())) {
4925 worklist.Add(use_defn); 4925 worklist.Add(use_defn);
4926 } else if (use_defn->IsPhi() && 4926 } else if (use_defn->IsPhi() &&
4927 use_defn->AsPhi()->Type()->ToCid() == kSmiCid) { 4927 use_defn->AsPhi()->Type()->ToCid() == kSmiCid) {
4928 worklist.Add(use_defn); 4928 worklist.Add(use_defn);
4929 } else if (use_defn->IsBinaryMintOp()) { 4929 } else if (use_defn->IsBinaryMintOp()) {
4930 // BinaryMintOp requires untagging of its inputs. 4930 // BinaryMintOp requires untagging of its inputs.
4931 // Converting kUnboxedInt32 to kUnboxedMint is essentially zero cost 4931 // Converting kUnboxedInt32 to kUnboxedMint is essentially zero cost
4932 // sign extension operation. 4932 // sign extension operation.
4933 gain++; 4933 gain++;
4934 if (FLAG_trace_smi_widening) { 4934 if (FLAG_trace_smi_widening) {
4935 ISL_Print("^ [%" Pd "] (u) %s\n", 4935 THR_Print("^ [%" Pd "] (u) %s\n",
4936 gain, 4936 gain,
4937 use->instruction()->ToCString()); 4937 use->instruction()->ToCString());
4938 } 4938 }
4939 } else if (defn_loop == loops[instr->GetBlock()->preorder_number()]) { 4939 } else if (defn_loop == loops[instr->GetBlock()->preorder_number()]) {
4940 gain--; 4940 gain--;
4941 if (FLAG_trace_smi_widening) { 4941 if (FLAG_trace_smi_widening) {
4942 ISL_Print("v [%" Pd "] (u) %s\n", 4942 THR_Print("v [%" Pd "] (u) %s\n",
4943 gain, 4943 gain,
4944 use->instruction()->ToCString()); 4944 use->instruction()->ToCString());
4945 } 4945 }
4946 } 4946 }
4947 } 4947 }
4948 } 4948 }
4949 4949
4950 processed->AddAll(worklist.contains_vector()); 4950 processed->AddAll(worklist.contains_vector());
4951 4951
4952 if (FLAG_trace_smi_widening) { 4952 if (FLAG_trace_smi_widening) {
4953 ISL_Print("~ %s gain %" Pd "\n", op->ToCString(), gain); 4953 THR_Print("~ %s gain %" Pd "\n", op->ToCString(), gain);
4954 } 4954 }
4955 4955
4956 if (gain > 0) { 4956 if (gain > 0) {
4957 // We have positive gain from widening. Convert all BinarySmiOpInstr into 4957 // We have positive gain from widening. Convert all BinarySmiOpInstr into
4958 // BinaryInt32OpInstr and set representation of all phis to kUnboxedInt32. 4958 // BinaryInt32OpInstr and set representation of all phis to kUnboxedInt32.
4959 for (intptr_t j = 0; j < worklist.definitions().length(); j++) { 4959 for (intptr_t j = 0; j < worklist.definitions().length(); j++) {
4960 Definition* defn = worklist.definitions()[j]; 4960 Definition* defn = worklist.definitions()[j];
4961 ASSERT(defn->IsPhi() || defn->IsBinarySmiOp()); 4961 ASSERT(defn->IsPhi() || defn->IsBinarySmiOp());
4962 4962
4963 if (defn->IsBinarySmiOp()) { 4963 if (defn->IsBinarySmiOp()) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
5071 if (current->IsCheckClass()) { 5071 if (current->IsCheckClass()) {
5072 current->AsCheckClass()->set_licm_hoisted(true); 5072 current->AsCheckClass()->set_licm_hoisted(true);
5073 } else if (current->IsCheckSmi()) { 5073 } else if (current->IsCheckSmi()) {
5074 current->AsCheckSmi()->set_licm_hoisted(true); 5074 current->AsCheckSmi()->set_licm_hoisted(true);
5075 } else if (current->IsCheckEitherNonSmi()) { 5075 } else if (current->IsCheckEitherNonSmi()) {
5076 current->AsCheckEitherNonSmi()->set_licm_hoisted(true); 5076 current->AsCheckEitherNonSmi()->set_licm_hoisted(true);
5077 } else if (current->IsCheckArrayBound()) { 5077 } else if (current->IsCheckArrayBound()) {
5078 current->AsCheckArrayBound()->set_licm_hoisted(true); 5078 current->AsCheckArrayBound()->set_licm_hoisted(true);
5079 } 5079 }
5080 if (FLAG_trace_optimization) { 5080 if (FLAG_trace_optimization) {
5081 ISL_Print("Hoisting instruction %s:%" Pd " from B%" Pd " to B%" Pd "\n", 5081 THR_Print("Hoisting instruction %s:%" Pd " from B%" Pd " to B%" Pd "\n",
5082 current->DebugName(), 5082 current->DebugName(),
5083 current->GetDeoptId(), 5083 current->GetDeoptId(),
5084 current->GetBlock()->block_id(), 5084 current->GetBlock()->block_id(),
5085 pre_header->block_id()); 5085 pre_header->block_id());
5086 } 5086 }
5087 // Move the instruction out of the loop. 5087 // Move the instruction out of the loop.
5088 current->RemoveEnvironment(); 5088 current->RemoveEnvironment();
5089 if (it != NULL) { 5089 if (it != NULL) {
5090 it->RemoveCurrentFromGraph(); 5090 it->RemoveCurrentFromGraph();
5091 } else { 5091 } else {
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
5888 Place* LookupCanonical(Place* place) const { 5888 Place* LookupCanonical(Place* place) const {
5889 return places_map_->Lookup(place); 5889 return places_map_->Lookup(place);
5890 } 5890 }
5891 5891
5892 void PrintSet(BitVector* set) { 5892 void PrintSet(BitVector* set) {
5893 bool comma = false; 5893 bool comma = false;
5894 for (BitVector::Iterator it(set); 5894 for (BitVector::Iterator it(set);
5895 !it.Done(); 5895 !it.Done();
5896 it.Advance()) { 5896 it.Advance()) {
5897 if (comma) { 5897 if (comma) {
5898 ISL_Print(", "); 5898 THR_Print(", ");
5899 } 5899 }
5900 ISL_Print("%s", places_[it.Current()]->ToCString()); 5900 THR_Print("%s", places_[it.Current()]->ToCString());
5901 comma = true; 5901 comma = true;
5902 } 5902 }
5903 } 5903 }
5904 5904
5905 const PhiPlaceMoves* phi_moves() const { return phi_moves_; } 5905 const PhiPlaceMoves* phi_moves() const { return phi_moves_; }
5906 5906
5907 void RollbackAliasedIdentites() { 5907 void RollbackAliasedIdentites() {
5908 for (intptr_t i = 0; i < identity_rollback_.length(); ++i) { 5908 for (intptr_t i = 0; i < identity_rollback_.length(); ++i) {
5909 identity_rollback_[i]->SetIdentity(AliasIdentity::Unknown()); 5909 identity_rollback_[i]->SetIdentity(AliasIdentity::Unknown());
5910 } 5910 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
5985 5985
5986 void ComputeKillSets() { 5986 void ComputeKillSets() {
5987 for (intptr_t i = 0; i < aliases_.length(); ++i) { 5987 for (intptr_t i = 0; i < aliases_.length(); ++i) {
5988 const Place* alias = aliases_[i]; 5988 const Place* alias = aliases_[i];
5989 // Add all representatives to the kill set. 5989 // Add all representatives to the kill set.
5990 AddAllRepresentatives(alias->id(), alias->id()); 5990 AddAllRepresentatives(alias->id(), alias->id());
5991 ComputeKillSet(alias); 5991 ComputeKillSet(alias);
5992 } 5992 }
5993 5993
5994 if (FLAG_trace_load_optimization) { 5994 if (FLAG_trace_load_optimization) {
5995 ISL_Print("Aliases KILL sets:\n"); 5995 THR_Print("Aliases KILL sets:\n");
5996 for (intptr_t i = 0; i < aliases_.length(); ++i) { 5996 for (intptr_t i = 0; i < aliases_.length(); ++i) {
5997 const Place* alias = aliases_[i]; 5997 const Place* alias = aliases_[i];
5998 BitVector* kill = GetKilledSet(alias->id()); 5998 BitVector* kill = GetKilledSet(alias->id());
5999 5999
6000 ISL_Print("%s: ", alias->ToCString()); 6000 THR_Print("%s: ", alias->ToCString());
6001 if (kill != NULL) { 6001 if (kill != NULL) {
6002 PrintSet(kill); 6002 PrintSet(kill);
6003 } 6003 }
6004 ISL_Print("\n"); 6004 THR_Print("\n");
6005 } 6005 }
6006 } 6006 }
6007 } 6007 }
6008 6008
6009 void InsertAlias(const Place* alias) { 6009 void InsertAlias(const Place* alias) {
6010 aliases_map_.Insert(alias); 6010 aliases_map_.Insert(alias);
6011 aliases_.Add(alias); 6011 aliases_.Add(alias);
6012 } 6012 }
6013 6013
6014 const Place* CanonicalizeAlias(const Place& alias) { 6014 const Place* CanonicalizeAlias(const Place& alias) {
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
6381 PhiPlaceMoves* phi_moves = new(zone) PhiPlaceMoves(); 6381 PhiPlaceMoves* phi_moves = new(zone) PhiPlaceMoves();
6382 6382
6383 for (intptr_t i = 0; i < places->length(); i++) { 6383 for (intptr_t i = 0; i < places->length(); i++) {
6384 Place* place = (*places)[i]; 6384 Place* place = (*places)[i];
6385 6385
6386 if (IsPhiDependentPlace(place)) { 6386 if (IsPhiDependentPlace(place)) {
6387 PhiInstr* phi = place->instance()->AsPhi(); 6387 PhiInstr* phi = place->instance()->AsPhi();
6388 BlockEntryInstr* block = phi->GetBlock(); 6388 BlockEntryInstr* block = phi->GetBlock();
6389 6389
6390 if (FLAG_trace_optimization) { 6390 if (FLAG_trace_optimization) {
6391 ISL_Print("phi dependent place %s\n", place->ToCString()); 6391 THR_Print("phi dependent place %s\n", place->ToCString());
6392 } 6392 }
6393 6393
6394 Place input_place(*place); 6394 Place input_place(*place);
6395 for (intptr_t j = 0; j < phi->InputCount(); j++) { 6395 for (intptr_t j = 0; j < phi->InputCount(); j++) {
6396 input_place.set_instance(phi->InputAt(j)->definition()); 6396 input_place.set_instance(phi->InputAt(j)->definition());
6397 6397
6398 Place* result = map->Lookup(&input_place); 6398 Place* result = map->Lookup(&input_place);
6399 if (result == NULL) { 6399 if (result == NULL) {
6400 result = Place::Wrap(zone, input_place, places->length()); 6400 result = Place::Wrap(zone, input_place, places->length());
6401 map->Insert(result); 6401 map->Insert(result);
6402 places->Add(result); 6402 places->Add(result);
6403 if (FLAG_trace_optimization) { 6403 if (FLAG_trace_optimization) {
6404 ISL_Print(" adding place %s as %" Pd "\n", 6404 THR_Print(" adding place %s as %" Pd "\n",
6405 result->ToCString(), 6405 result->ToCString(),
6406 result->id()); 6406 result->id());
6407 } 6407 }
6408 } 6408 }
6409 phi_moves->CreateOutgoingMove(zone, 6409 phi_moves->CreateOutgoingMove(zone,
6410 block->PredecessorAt(j), 6410 block->PredecessorAt(j),
6411 result->id(), 6411 result->id(),
6412 place->id()); 6412 place->id());
6413 } 6413 }
6414 } 6414 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
6450 continue; 6450 continue;
6451 } 6451 }
6452 6452
6453 Place* result = map->Lookup(&place); 6453 Place* result = map->Lookup(&place);
6454 if (result == NULL) { 6454 if (result == NULL) {
6455 result = Place::Wrap(zone, place, places->length()); 6455 result = Place::Wrap(zone, place, places->length());
6456 map->Insert(result); 6456 map->Insert(result);
6457 places->Add(result); 6457 places->Add(result);
6458 6458
6459 if (FLAG_trace_optimization) { 6459 if (FLAG_trace_optimization) {
6460 ISL_Print("numbering %s as %" Pd "\n", 6460 THR_Print("numbering %s as %" Pd "\n",
6461 result->ToCString(), 6461 result->ToCString(),
6462 result->id()); 6462 result->id());
6463 } 6463 }
6464 } 6464 }
6465 6465
6466 instr->set_place_id(result->id()); 6466 instr->set_place_id(result->id());
6467 } 6467 }
6468 } 6468 }
6469 6469
6470 if ((mode == kOptimizeLoads) && !has_loads) { 6470 if ((mode == kOptimizeLoads) && !has_loads) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
6719 } 6719 }
6720 6720
6721 const intptr_t place_id = defn->place_id(); 6721 const intptr_t place_id = defn->place_id();
6722 if (gen->Contains(place_id)) { 6722 if (gen->Contains(place_id)) {
6723 // This is a locally redundant load. 6723 // This is a locally redundant load.
6724 ASSERT((out_values != NULL) && ((*out_values)[place_id] != NULL)); 6724 ASSERT((out_values != NULL) && ((*out_values)[place_id] != NULL));
6725 6725
6726 Definition* replacement = (*out_values)[place_id]; 6726 Definition* replacement = (*out_values)[place_id];
6727 EnsureSSATempIndex(graph_, defn, replacement); 6727 EnsureSSATempIndex(graph_, defn, replacement);
6728 if (FLAG_trace_optimization) { 6728 if (FLAG_trace_optimization) {
6729 ISL_Print("Replacing load v%" Pd " with v%" Pd "\n", 6729 THR_Print("Replacing load v%" Pd " with v%" Pd "\n",
6730 defn->ssa_temp_index(), 6730 defn->ssa_temp_index(),
6731 replacement->ssa_temp_index()); 6731 replacement->ssa_temp_index());
6732 } 6732 }
6733 6733
6734 defn->ReplaceUsesWith(replacement); 6734 defn->ReplaceUsesWith(replacement);
6735 instr_it.RemoveCurrentFromGraph(); 6735 instr_it.RemoveCurrentFromGraph();
6736 forwarded_ = true; 6736 forwarded_ = true;
6737 continue; 6737 continue;
6738 } else if (!kill->Contains(place_id)) { 6738 } else if (!kill->Contains(place_id)) {
6739 // This is an exposed load: it is the first representative of a 6739 // This is an exposed load: it is the first representative of a
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
6927 for (intptr_t i = 0; i < phi_moves->length(); i++) { 6927 for (intptr_t i = 0; i < phi_moves->length(); i++) {
6928 const intptr_t from = (*phi_moves)[i].from(); 6928 const intptr_t from = (*phi_moves)[i].from();
6929 const intptr_t to = (*phi_moves)[i].to(); 6929 const intptr_t to = (*phi_moves)[i].to();
6930 if (from == to) continue; 6930 if (from == to) continue;
6931 6931
6932 (*block_out_values)[to] = (*temp_forwarded_values)[to]; 6932 (*block_out_values)[to] = (*temp_forwarded_values)[to];
6933 } 6933 }
6934 } 6934 }
6935 6935
6936 if (FLAG_trace_load_optimization) { 6936 if (FLAG_trace_load_optimization) {
6937 ISL_Print("B%" Pd "\n", block->block_id()); 6937 THR_Print("B%" Pd "\n", block->block_id());
6938 ISL_Print(" IN: "); 6938 THR_Print(" IN: ");
6939 aliased_set_->PrintSet(in_[preorder_number]); 6939 aliased_set_->PrintSet(in_[preorder_number]);
6940 ISL_Print("\n"); 6940 THR_Print("\n");
6941 6941
6942 ISL_Print(" KILL: "); 6942 THR_Print(" KILL: ");
6943 aliased_set_->PrintSet(kill_[preorder_number]); 6943 aliased_set_->PrintSet(kill_[preorder_number]);
6944 ISL_Print("\n"); 6944 THR_Print("\n");
6945 6945
6946 ISL_Print(" OUT: "); 6946 THR_Print(" OUT: ");
6947 aliased_set_->PrintSet(out_[preorder_number]); 6947 aliased_set_->PrintSet(out_[preorder_number]);
6948 ISL_Print("\n"); 6948 THR_Print("\n");
6949 } 6949 }
6950 } 6950 }
6951 6951
6952 // All blocks were visited. Fill pending phis with inputs 6952 // All blocks were visited. Fill pending phis with inputs
6953 // that flow on back edges. 6953 // that flow on back edges.
6954 for (intptr_t i = 0; i < pending_phis.length(); i++) { 6954 for (intptr_t i = 0; i < pending_phis.length(); i++) {
6955 FillPhiInputs(pending_phis[i]); 6955 FillPhiInputs(pending_phis[i]);
6956 } 6956 }
6957 } 6957 }
6958 6958
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
6991 6991
6992 for (BitVector::Iterator loop_it(header->loop_info()); 6992 for (BitVector::Iterator loop_it(header->loop_info());
6993 !loop_it.Done(); 6993 !loop_it.Done();
6994 loop_it.Advance()) { 6994 loop_it.Advance()) {
6995 const intptr_t preorder_number = loop_it.Current(); 6995 const intptr_t preorder_number = loop_it.Current();
6996 loop_gen->RemoveAll(kill_[preorder_number]); 6996 loop_gen->RemoveAll(kill_[preorder_number]);
6997 } 6997 }
6998 6998
6999 if (FLAG_trace_optimization) { 6999 if (FLAG_trace_optimization) {
7000 for (BitVector::Iterator it(loop_gen); !it.Done(); it.Advance()) { 7000 for (BitVector::Iterator it(loop_gen); !it.Done(); it.Advance()) {
7001 ISL_Print("place %s is loop invariant for B%" Pd "\n", 7001 THR_Print("place %s is loop invariant for B%" Pd "\n",
7002 aliased_set_->places()[it.Current()]->ToCString(), 7002 aliased_set_->places()[it.Current()]->ToCString(),
7003 header->block_id()); 7003 header->block_id());
7004 } 7004 }
7005 } 7005 }
7006 7006
7007 invariant_loads->Add(loop_gen); 7007 invariant_loads->Add(loop_gen);
7008 } 7008 }
7009 7009
7010 graph_->set_loop_invariant_loads(invariant_loads); 7010 graph_->set_loop_invariant_loads(invariant_loads);
7011 } 7011 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
7062 Definition* replacement = (*pred_out_values)[place_id]->Replacement(); 7062 Definition* replacement = (*pred_out_values)[place_id]->Replacement();
7063 Value* input = new(Z) Value(replacement); 7063 Value* input = new(Z) Value(replacement);
7064 phi->SetInputAt(i, input); 7064 phi->SetInputAt(i, input);
7065 replacement->AddInputUse(input); 7065 replacement->AddInputUse(input);
7066 } 7066 }
7067 7067
7068 phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index()); 7068 phi->set_ssa_temp_index(graph_->alloc_ssa_temp_index());
7069 phis_.Add(phi); // Postpone phi insertion until after load forwarding. 7069 phis_.Add(phi); // Postpone phi insertion until after load forwarding.
7070 7070
7071 if (FLAG_trace_load_optimization) { 7071 if (FLAG_trace_load_optimization) {
7072 ISL_Print("created pending phi %s for %s at B%" Pd "\n", 7072 THR_Print("created pending phi %s for %s at B%" Pd "\n",
7073 phi->ToCString(), 7073 phi->ToCString(),
7074 aliased_set_->places()[place_id]->ToCString(), 7074 aliased_set_->places()[place_id]->ToCString(),
7075 block->block_id()); 7075 block->block_id());
7076 } 7076 }
7077 } 7077 }
7078 7078
7079 // Iterate over basic blocks and replace exposed loads with incoming 7079 // Iterate over basic blocks and replace exposed loads with incoming
7080 // values. 7080 // values.
7081 void ForwardLoads() { 7081 void ForwardLoads() {
7082 for (BlockIterator block_it = graph_->reverse_postorder_iterator(); 7082 for (BlockIterator block_it = graph_->reverse_postorder_iterator();
(...skipping 18 matching lines...) Expand all
7101 // they might contain values that were replace and removed 7101 // they might contain values that were replace and removed
7102 // from the graph by this iteration. 7102 // from the graph by this iteration.
7103 // To prevent using them we additionally mark definitions themselves 7103 // To prevent using them we additionally mark definitions themselves
7104 // as replaced and store a pointer to the replacement. 7104 // as replaced and store a pointer to the replacement.
7105 replacement = replacement->Replacement(); 7105 replacement = replacement->Replacement();
7106 7106
7107 if (load != replacement) { 7107 if (load != replacement) {
7108 EnsureSSATempIndex(graph_, load, replacement); 7108 EnsureSSATempIndex(graph_, load, replacement);
7109 7109
7110 if (FLAG_trace_optimization) { 7110 if (FLAG_trace_optimization) {
7111 ISL_Print("Replacing load v%" Pd " with v%" Pd "\n", 7111 THR_Print("Replacing load v%" Pd " with v%" Pd "\n",
7112 load->ssa_temp_index(), 7112 load->ssa_temp_index(),
7113 replacement->ssa_temp_index()); 7113 replacement->ssa_temp_index());
7114 } 7114 }
7115 7115
7116 load->ReplaceUsesWith(replacement); 7116 load->ReplaceUsesWith(replacement);
7117 load->RemoveFromGraph(); 7117 load->RemoveFromGraph();
7118 load->SetReplacement(replacement); 7118 load->SetReplacement(replacement);
7119 forwarded_ = true; 7119 forwarded_ = true;
7120 } 7120 }
7121 } 7121 }
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
7290 if (!a->IsPhi()) { 7290 if (!a->IsPhi()) {
7291 if (Dominates(a, b)) { 7291 if (Dominates(a, b)) {
7292 Definition* t = a; 7292 Definition* t = a;
7293 a = b; 7293 a = b;
7294 b = t; 7294 b = t;
7295 } 7295 }
7296 ASSERT(Dominates(b, a)); 7296 ASSERT(Dominates(b, a));
7297 } 7297 }
7298 7298
7299 if (FLAG_trace_load_optimization) { 7299 if (FLAG_trace_load_optimization) {
7300 ISL_Print("Replacing %s with congruent %s\n", 7300 THR_Print("Replacing %s with congruent %s\n",
7301 a->ToCString(), 7301 a->ToCString(),
7302 b->ToCString()); 7302 b->ToCString());
7303 } 7303 }
7304 7304
7305 a->ReplaceUsesWith(b); 7305 a->ReplaceUsesWith(b);
7306 if (a->IsPhi()) { 7306 if (a->IsPhi()) {
7307 // We might be replacing a phi introduced by the load forwarding 7307 // We might be replacing a phi introduced by the load forwarding
7308 // that is not inserted in the graph yet. 7308 // that is not inserted in the graph yet.
7309 ASSERT(b->IsPhi()); 7309 ASSERT(b->IsPhi());
7310 PhiInstr* phi_a = a->AsPhi(); 7310 PhiInstr* phi_a = a->AsPhi();
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
7496 // Loads/stores of final fields do not participate. 7496 // Loads/stores of final fields do not participate.
7497 continue; 7497 continue;
7498 } 7498 }
7499 7499
7500 // Handle stores. 7500 // Handle stores.
7501 if (is_store) { 7501 if (is_store) {
7502 if (kill->Contains(instr->place_id())) { 7502 if (kill->Contains(instr->place_id())) {
7503 if (!live_in->Contains(instr->place_id()) && 7503 if (!live_in->Contains(instr->place_id()) &&
7504 CanEliminateStore(instr)) { 7504 CanEliminateStore(instr)) {
7505 if (FLAG_trace_optimization) { 7505 if (FLAG_trace_optimization) {
7506 ISL_Print( 7506 THR_Print(
7507 "Removing dead store to place %" Pd " in block B%" Pd "\n", 7507 "Removing dead store to place %" Pd " in block B%" Pd "\n",
7508 instr->place_id(), block->block_id()); 7508 instr->place_id(), block->block_id());
7509 } 7509 }
7510 instr_it.RemoveCurrentFromGraph(); 7510 instr_it.RemoveCurrentFromGraph();
7511 } 7511 }
7512 } else if (!live_in->Contains(instr->place_id())) { 7512 } else if (!live_in->Contains(instr->place_id())) {
7513 // Mark this store as down-ward exposed: They are the only 7513 // Mark this store as down-ward exposed: They are the only
7514 // candidates for the global store elimination. 7514 // candidates for the global store elimination.
7515 if (exposed_stores == NULL) { 7515 if (exposed_stores == NULL) {
7516 const intptr_t kMaxExposedStoresInitialSize = 5; 7516 const intptr_t kMaxExposedStoresInitialSize = 5;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
7549 if ((defn != NULL) && IsLoadEliminationCandidate(defn)) { 7549 if ((defn != NULL) && IsLoadEliminationCandidate(defn)) {
7550 const intptr_t alias = aliased_set_->LookupAliasId(place.ToAlias()); 7550 const intptr_t alias = aliased_set_->LookupAliasId(place.ToAlias());
7551 live_in->AddAll(aliased_set_->GetKilledSet(alias)); 7551 live_in->AddAll(aliased_set_->GetKilledSet(alias));
7552 continue; 7552 continue;
7553 } 7553 }
7554 } 7554 }
7555 exposed_stores_[postorder_number] = exposed_stores; 7555 exposed_stores_[postorder_number] = exposed_stores;
7556 } 7556 }
7557 if (FLAG_trace_load_optimization) { 7557 if (FLAG_trace_load_optimization) {
7558 Dump(); 7558 Dump();
7559 ISL_Print("---\n"); 7559 THR_Print("---\n");
7560 } 7560 }
7561 } 7561 }
7562 7562
7563 void EliminateDeadStores() { 7563 void EliminateDeadStores() {
7564 // Iteration order does not matter here. 7564 // Iteration order does not matter here.
7565 for (BlockIterator block_it = graph_->postorder_iterator(); 7565 for (BlockIterator block_it = graph_->postorder_iterator();
7566 !block_it.Done(); 7566 !block_it.Done();
7567 block_it.Advance()) { 7567 block_it.Advance()) {
7568 BlockEntryInstr* block = block_it.Current(); 7568 BlockEntryInstr* block = block_it.Current();
7569 const intptr_t postorder_number = block->postorder_number(); 7569 const intptr_t postorder_number = block->postorder_number();
(...skipping 13 matching lines...) Expand all
7583 ASSERT(!is_load && is_store); 7583 ASSERT(!is_load && is_store);
7584 if (place.IsFinalField()) { 7584 if (place.IsFinalField()) {
7585 // Final field do not participate in dead store elimination. 7585 // Final field do not participate in dead store elimination.
7586 continue; 7586 continue;
7587 } 7587 }
7588 // Eliminate a downward exposed store if the corresponding place is not 7588 // Eliminate a downward exposed store if the corresponding place is not
7589 // in live-out. 7589 // in live-out.
7590 if (!live_out->Contains(instr->place_id()) && 7590 if (!live_out->Contains(instr->place_id()) &&
7591 CanEliminateStore(instr)) { 7591 CanEliminateStore(instr)) {
7592 if (FLAG_trace_optimization) { 7592 if (FLAG_trace_optimization) {
7593 ISL_Print("Removing dead store to place %" Pd " block B%" Pd "\n", 7593 THR_Print("Removing dead store to place %" Pd " block B%" Pd "\n",
7594 instr->place_id(), block->block_id()); 7594 instr->place_id(), block->block_id());
7595 } 7595 }
7596 instr->RemoveFromGraph(/* ignored */ false); 7596 instr->RemoveFromGraph(/* ignored */ false);
7597 } 7597 }
7598 } 7598 }
7599 } 7599 }
7600 } 7600 }
7601 7601
7602 FlowGraph* graph_; 7602 FlowGraph* graph_;
7603 DirectChainedHashMap<PointerKeyValueTrait<Place> >* map_; 7603 DirectChainedHashMap<PointerKeyValueTrait<Place> >* map_;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
7677 // Eliminate dead phis and compact the phis_ array of the block. 7677 // Eliminate dead phis and compact the phis_ array of the block.
7678 intptr_t to_index = 0; 7678 intptr_t to_index = 0;
7679 for (intptr_t i = 0; i < join->phis_->length(); ++i) { 7679 for (intptr_t i = 0; i < join->phis_->length(); ++i) {
7680 PhiInstr* phi = (*join->phis_)[i]; 7680 PhiInstr* phi = (*join->phis_)[i];
7681 if (phi != NULL) { 7681 if (phi != NULL) {
7682 if (!phi->is_alive()) { 7682 if (!phi->is_alive()) {
7683 phi->ReplaceUsesWith(flow_graph->constant_null()); 7683 phi->ReplaceUsesWith(flow_graph->constant_null());
7684 phi->UnuseAllInputs(); 7684 phi->UnuseAllInputs();
7685 (*join->phis_)[i] = NULL; 7685 (*join->phis_)[i] = NULL;
7686 if (FLAG_trace_optimization) { 7686 if (FLAG_trace_optimization) {
7687 ISL_Print("Removing dead phi v%" Pd "\n", phi->ssa_temp_index()); 7687 THR_Print("Removing dead phi v%" Pd "\n", phi->ssa_temp_index());
7688 } 7688 }
7689 } else if (phi->IsRedundant()) { 7689 } else if (phi->IsRedundant()) {
7690 phi->ReplaceUsesWith(phi->InputAt(0)->definition()); 7690 phi->ReplaceUsesWith(phi->InputAt(0)->definition());
7691 phi->UnuseAllInputs(); 7691 phi->UnuseAllInputs();
7692 (*join->phis_)[i] = NULL; 7692 (*join->phis_)[i] = NULL;
7693 if (FLAG_trace_optimization) { 7693 if (FLAG_trace_optimization) {
7694 ISL_Print("Removing redundant phi v%" Pd "\n", 7694 THR_Print("Removing redundant phi v%" Pd "\n",
7695 phi->ssa_temp_index()); 7695 phi->ssa_temp_index());
7696 } 7696 }
7697 } else { 7697 } else {
7698 (*join->phis_)[to_index++] = phi; 7698 (*join->phis_)[to_index++] = phi;
7699 } 7699 }
7700 } 7700 }
7701 } 7701 }
7702 if (to_index == 0) { 7702 if (to_index == 0) {
7703 join->phis_ = NULL; 7703 join->phis_ = NULL;
7704 } else { 7704 } else {
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
8227 // deoptimization exit. So candidate should only be used in StoreInstanceField 8227 // deoptimization exit. So candidate should only be used in StoreInstanceField
8228 // instructions that write into fields of the allocated object. 8228 // instructions that write into fields of the allocated object.
8229 // We do not support materialization of the object that has type arguments. 8229 // We do not support materialization of the object that has type arguments.
8230 static bool IsAllocationSinkingCandidate(Definition* alloc, 8230 static bool IsAllocationSinkingCandidate(Definition* alloc,
8231 SafeUseCheck check_type) { 8231 SafeUseCheck check_type) {
8232 for (Value* use = alloc->input_use_list(); 8232 for (Value* use = alloc->input_use_list();
8233 use != NULL; 8233 use != NULL;
8234 use = use->next_use()) { 8234 use = use->next_use()) {
8235 if (!IsSafeUse(use, check_type)) { 8235 if (!IsSafeUse(use, check_type)) {
8236 if (FLAG_trace_optimization) { 8236 if (FLAG_trace_optimization) {
8237 ISL_Print("use of %s at %s is unsafe for allocation sinking\n", 8237 THR_Print("use of %s at %s is unsafe for allocation sinking\n",
8238 alloc->ToCString(), 8238 alloc->ToCString(),
8239 use->instruction()->ToCString()); 8239 use->instruction()->ToCString());
8240 } 8240 }
8241 return false; 8241 return false;
8242 } 8242 }
8243 } 8243 }
8244 8244
8245 return true; 8245 return true;
8246 } 8246 }
8247 8247
8248 8248
8249 // If the given use is a store into an object then return an object we are 8249 // If the given use is a store into an object then return an object we are
8250 // storing into. 8250 // storing into.
8251 static Definition* StoreInto(Value* use) { 8251 static Definition* StoreInto(Value* use) {
8252 StoreInstanceFieldInstr* store = use->instruction()->AsStoreInstanceField(); 8252 StoreInstanceFieldInstr* store = use->instruction()->AsStoreInstanceField();
8253 if (store != NULL) { 8253 if (store != NULL) {
8254 return store->instance()->definition(); 8254 return store->instance()->definition();
8255 } 8255 }
8256 8256
8257 return NULL; 8257 return NULL;
8258 } 8258 }
8259 8259
8260 8260
8261 // Remove the given allocation from the graph. It is not observable. 8261 // Remove the given allocation from the graph. It is not observable.
8262 // If deoptimization occurs the object will be materialized. 8262 // If deoptimization occurs the object will be materialized.
8263 void AllocationSinking::EliminateAllocation(Definition* alloc) { 8263 void AllocationSinking::EliminateAllocation(Definition* alloc) {
8264 ASSERT(IsAllocationSinkingCandidate(alloc, kStrictCheck)); 8264 ASSERT(IsAllocationSinkingCandidate(alloc, kStrictCheck));
8265 8265
8266 if (FLAG_trace_optimization) { 8266 if (FLAG_trace_optimization) {
8267 ISL_Print("removing allocation from the graph: v%" Pd "\n", 8267 THR_Print("removing allocation from the graph: v%" Pd "\n",
8268 alloc->ssa_temp_index()); 8268 alloc->ssa_temp_index());
8269 } 8269 }
8270 8270
8271 // As an allocation sinking candidate it is only used in stores to its own 8271 // As an allocation sinking candidate it is only used in stores to its own
8272 // fields. Remove these stores. 8272 // fields. Remove these stores.
8273 for (Value* use = alloc->input_use_list(); 8273 for (Value* use = alloc->input_use_list();
8274 use != NULL; 8274 use != NULL;
8275 use = alloc->input_use_list()) { 8275 use = alloc->input_use_list()) {
8276 use->instruction()->RemoveFromGraph(); 8276 use->instruction()->RemoveFromGraph();
8277 } 8277 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
8338 } 8338 }
8339 } 8339 }
8340 } while (changed); 8340 } while (changed);
8341 8341
8342 // Shrink the list of candidates removing all unmarked ones. 8342 // Shrink the list of candidates removing all unmarked ones.
8343 intptr_t j = 0; 8343 intptr_t j = 0;
8344 for (intptr_t i = 0; i < candidates_.length(); i++) { 8344 for (intptr_t i = 0; i < candidates_.length(); i++) {
8345 Definition* alloc = candidates_[i]; 8345 Definition* alloc = candidates_[i];
8346 if (alloc->Identity().IsAllocationSinkingCandidate()) { 8346 if (alloc->Identity().IsAllocationSinkingCandidate()) {
8347 if (FLAG_trace_optimization) { 8347 if (FLAG_trace_optimization) {
8348 ISL_Print("discovered allocation sinking candidate: v%" Pd "\n", 8348 THR_Print("discovered allocation sinking candidate: v%" Pd "\n",
8349 alloc->ssa_temp_index()); 8349 alloc->ssa_temp_index());
8350 } 8350 }
8351 8351
8352 if (j != i) { 8352 if (j != i) {
8353 candidates_[j] = alloc; 8353 candidates_[j] = alloc;
8354 } 8354 }
8355 j++; 8355 j++;
8356 } 8356 }
8357 } 8357 }
8358 candidates_.TruncateTo(j); 8358 candidates_.TruncateTo(j);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
8433 } 8433 }
8434 } 8434 }
8435 } while (changed); 8435 } while (changed);
8436 8436
8437 // Remove all failed candidates from the candidates list. 8437 // Remove all failed candidates from the candidates list.
8438 intptr_t j = 0; 8438 intptr_t j = 0;
8439 for (intptr_t i = 0; i < candidates_.length(); i++) { 8439 for (intptr_t i = 0; i < candidates_.length(); i++) {
8440 Definition* alloc = candidates_[i]; 8440 Definition* alloc = candidates_[i];
8441 if (!alloc->Identity().IsAllocationSinkingCandidate()) { 8441 if (!alloc->Identity().IsAllocationSinkingCandidate()) {
8442 if (FLAG_trace_optimization) { 8442 if (FLAG_trace_optimization) {
8443 ISL_Print("allocation v%" Pd " can't be eliminated\n", 8443 THR_Print("allocation v%" Pd " can't be eliminated\n",
8444 alloc->ssa_temp_index()); 8444 alloc->ssa_temp_index());
8445 } 8445 }
8446 8446
8447 #ifdef DEBUG 8447 #ifdef DEBUG
8448 for (Value* use = alloc->env_use_list(); 8448 for (Value* use = alloc->env_use_list();
8449 use != NULL; 8449 use != NULL;
8450 use = use->next_use()) { 8450 use = use->next_use()) {
8451 ASSERT(use->instruction()->IsMaterializeObject()); 8451 ASSERT(use->instruction()->IsMaterializeObject());
8452 } 8452 }
8453 #endif 8453 #endif
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
8782 8782
8783 // Insert materializations at environment uses. 8783 // Insert materializations at environment uses.
8784 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { 8784 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) {
8785 CreateMaterializationAt( 8785 CreateMaterializationAt(
8786 exits_collector_.exits()[i], alloc, *slots); 8786 exits_collector_.exits()[i], alloc, *slots);
8787 } 8787 }
8788 } 8788 }
8789 8789
8790 8790
8791 } // namespace dart 8791 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698