OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2138 for (HInstruction* instr = blocks()->at(i)->first(); | 2138 for (HInstruction* instr = blocks()->at(i)->first(); |
2139 instr != NULL; | 2139 instr != NULL; |
2140 instr = instr->next()) { | 2140 instr = instr->next()) { |
2141 instr->FinalizeUniqueValueId(); | 2141 instr->FinalizeUniqueValueId(); |
2142 } | 2142 } |
2143 } | 2143 } |
2144 } | 2144 } |
2145 | 2145 |
2146 | 2146 |
2147 void HGraph::Canonicalize() { | 2147 void HGraph::Canonicalize() { |
2148 if (!FLAG_use_canonicalizing) return; | |
2149 HPhase phase("H_Canonicalize", this); | 2148 HPhase phase("H_Canonicalize", this); |
2150 for (int i = 0; i < blocks()->length(); ++i) { | 2149 for (int i = 0; i < blocks()->length(); ++i) { |
2151 HInstruction* instr = blocks()->at(i)->first(); | 2150 HInstruction* instr = blocks()->at(i)->first(); |
2152 while (instr != NULL) { | 2151 while (instr != NULL) { |
2153 HValue* value = instr->Canonicalize(); | 2152 HValue* value = instr->Canonicalize(); |
2154 if (value != instr) instr->DeleteAndReplaceWith(value); | 2153 if (value != instr) instr->DeleteAndReplaceWith(value); |
2155 instr = instr->next(); | 2154 instr = instr->next(); |
2156 } | 2155 } |
2157 } | 2156 } |
2158 } | 2157 } |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3141 explicit HStackCheckEliminator(HGraph* graph) : graph_(graph) { } | 3140 explicit HStackCheckEliminator(HGraph* graph) : graph_(graph) { } |
3142 | 3141 |
3143 void Process(); | 3142 void Process(); |
3144 | 3143 |
3145 private: | 3144 private: |
3146 HGraph* graph_; | 3145 HGraph* graph_; |
3147 }; | 3146 }; |
3148 | 3147 |
3149 | 3148 |
3150 void HStackCheckEliminator::Process() { | 3149 void HStackCheckEliminator::Process() { |
| 3150 HPhase phase("H_Stack check elimination", graph_); |
3151 // For each loop block walk the dominator tree from the backwards branch to | 3151 // For each loop block walk the dominator tree from the backwards branch to |
3152 // the loop header. If a call instruction is encountered the backwards branch | 3152 // the loop header. If a call instruction is encountered the backwards branch |
3153 // is dominated by a call and the stack check in the backwards branch can be | 3153 // is dominated by a call and the stack check in the backwards branch can be |
3154 // removed. | 3154 // removed. |
3155 for (int i = 0; i < graph_->blocks()->length(); i++) { | 3155 for (int i = 0; i < graph_->blocks()->length(); i++) { |
3156 HBasicBlock* block = graph_->blocks()->at(i); | 3156 HBasicBlock* block = graph_->blocks()->at(i); |
3157 if (block->IsLoopHeader()) { | 3157 if (block->IsLoopHeader()) { |
3158 HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge(); | 3158 HBasicBlock* back_edge = block->loop_information()->GetLastBackEdge(); |
3159 HBasicBlock* dominator = back_edge; | 3159 HBasicBlock* dominator = back_edge; |
3160 while (true) { | 3160 while (true) { |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3903 if (current->representation().IsNone() && | 3903 if (current->representation().IsNone() && |
3904 current->CheckFlag(HInstruction::kFlexibleRepresentation)) { | 3904 current->CheckFlag(HInstruction::kFlexibleRepresentation)) { |
3905 current->ChangeRepresentation(Representation::Tagged()); | 3905 current->ChangeRepresentation(Representation::Tagged()); |
3906 } | 3906 } |
3907 } | 3907 } |
3908 } | 3908 } |
3909 } | 3909 } |
3910 | 3910 |
3911 | 3911 |
3912 void HGraph::MergeRemovableSimulates() { | 3912 void HGraph::MergeRemovableSimulates() { |
| 3913 HPhase phase("H_Merge removable simulates", this); |
3913 ZoneList<HSimulate*> mergelist(2, zone()); | 3914 ZoneList<HSimulate*> mergelist(2, zone()); |
3914 for (int i = 0; i < blocks()->length(); ++i) { | 3915 for (int i = 0; i < blocks()->length(); ++i) { |
3915 HBasicBlock* block = blocks()->at(i); | 3916 HBasicBlock* block = blocks()->at(i); |
3916 // Make sure the merge list is empty at the start of a block. | 3917 // Make sure the merge list is empty at the start of a block. |
3917 ASSERT(mergelist.is_empty()); | 3918 ASSERT(mergelist.is_empty()); |
3918 // Nasty heuristic: Never remove the first simulate in a block. This | 3919 // Nasty heuristic: Never remove the first simulate in a block. This |
3919 // just so happens to have a beneficial effect on register allocation. | 3920 // just so happens to have a beneficial effect on register allocation. |
3920 bool first = true; | 3921 bool first = true; |
3921 for (HInstruction* current = block->first(); | 3922 for (HInstruction* current = block->first(); |
3922 current != NULL; current = current->next()) { | 3923 current != NULL; current = current->next()) { |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4406 } else { | 4407 } else { |
4407 UnmarkPhi(phi, &worklist); | 4408 UnmarkPhi(phi, &worklist); |
4408 } | 4409 } |
4409 } | 4410 } |
4410 phi_count = new_phi_count; | 4411 phi_count = new_phi_count; |
4411 } | 4412 } |
4412 } | 4413 } |
4413 | 4414 |
4414 | 4415 |
4415 void HGraph::ComputeSafeUint32Operations() { | 4416 void HGraph::ComputeSafeUint32Operations() { |
4416 if (!FLAG_opt_safe_uint32_operations || uint32_instructions_ == NULL) { | 4417 HPhase phase("H_Compute safe UInt32 operations", this); |
4417 return; | 4418 if (uint32_instructions_ == NULL) return; |
4418 } | |
4419 | 4419 |
4420 Uint32Analysis analysis(zone()); | 4420 Uint32Analysis analysis(zone()); |
4421 for (int i = 0; i < uint32_instructions_->length(); ++i) { | 4421 for (int i = 0; i < uint32_instructions_->length(); ++i) { |
4422 HInstruction* current = uint32_instructions_->at(i); | 4422 HInstruction* current = uint32_instructions_->at(i); |
4423 if (current->IsLinked() && current->representation().IsInteger32()) { | 4423 if (current->IsLinked() && current->representation().IsInteger32()) { |
4424 analysis.Analyze(current); | 4424 analysis.Analyze(current); |
4425 } | 4425 } |
4426 } | 4426 } |
4427 | 4427 |
4428 // Some phis might have been optimistically marked with kUint32 flag. | 4428 // Some phis might have been optimistically marked with kUint32 flag. |
4429 // Remove this flag from those phis that are unsafe and propagate | 4429 // Remove this flag from those phis that are unsafe and propagate |
4430 // this information transitively potentially clearing kUint32 flag | 4430 // this information transitively potentially clearing kUint32 flag |
4431 // from some non-phi operations that are used as operands to unsafe phis. | 4431 // from some non-phi operations that are used as operands to unsafe phis. |
4432 analysis.UnmarkUnsafePhis(); | 4432 analysis.UnmarkUnsafePhis(); |
4433 } | 4433 } |
4434 | 4434 |
4435 | 4435 |
4436 void HGraph::ComputeMinusZeroChecks() { | 4436 void HGraph::ComputeMinusZeroChecks() { |
| 4437 HPhase phase("H_Compute minus zero checks", this); |
4437 BitVector visited(GetMaximumValueID(), zone()); | 4438 BitVector visited(GetMaximumValueID(), zone()); |
4438 for (int i = 0; i < blocks_.length(); ++i) { | 4439 for (int i = 0; i < blocks_.length(); ++i) { |
4439 for (HInstruction* current = blocks_[i]->first(); | 4440 for (HInstruction* current = blocks_[i]->first(); |
4440 current != NULL; | 4441 current != NULL; |
4441 current = current->next()) { | 4442 current = current->next()) { |
4442 if (current->IsChange()) { | 4443 if (current->IsChange()) { |
4443 HChange* change = HChange::cast(current); | 4444 HChange* change = HChange::cast(current); |
4444 // Propagate flags for negative zero checks upwards from conversions | 4445 // Propagate flags for negative zero checks upwards from conversions |
4445 // int32-to-tagged and int32-to-double. | 4446 // int32-to-tagged and int32-to-double. |
4446 Representation from = change->value()->representation(); | 4447 Representation from = change->value()->representation(); |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4871 int checksum = type_info->own_type_change_checksum(); | 4872 int checksum = type_info->own_type_change_checksum(); |
4872 int composite_checksum = graph()->update_type_change_checksum(checksum); | 4873 int composite_checksum = graph()->update_type_change_checksum(checksum); |
4873 graph()->set_use_optimistic_licm( | 4874 graph()->set_use_optimistic_licm( |
4874 !type_info->matches_inlined_type_change_checksum(composite_checksum)); | 4875 !type_info->matches_inlined_type_change_checksum(composite_checksum)); |
4875 type_info->set_inlined_type_change_checksum(composite_checksum); | 4876 type_info->set_inlined_type_change_checksum(composite_checksum); |
4876 | 4877 |
4877 return true; | 4878 return true; |
4878 } | 4879 } |
4879 | 4880 |
4880 | 4881 |
| 4882 // Perform common subexpression elimination and loop-invariant code motion. |
4881 void HGraph::GlobalValueNumbering() { | 4883 void HGraph::GlobalValueNumbering() { |
4882 // Perform common subexpression elimination and loop-invariant code motion. | 4884 HPhase phase("H_Global value numbering", this); |
4883 if (FLAG_use_gvn) { | 4885 HGlobalValueNumberer gvn(this, info()); |
4884 HPhase phase("H_Global value numbering", this); | 4886 bool removed_side_effects = gvn.Analyze(); |
4885 HGlobalValueNumberer gvn(this, info()); | 4887 // Trigger a second analysis pass to further eliminate duplicate values that |
4886 bool removed_side_effects = gvn.Analyze(); | 4888 // could only be discovered by removing side-effect-generating instructions |
4887 // Trigger a second analysis pass to further eliminate duplicate values that | 4889 // during the first pass. |
4888 // could only be discovered by removing side-effect-generating instructions | 4890 if (FLAG_smi_only_arrays && removed_side_effects) { |
4889 // during the first pass. | 4891 removed_side_effects = gvn.Analyze(); |
4890 if (FLAG_smi_only_arrays && removed_side_effects) { | 4892 ASSERT(!removed_side_effects); |
4891 removed_side_effects = gvn.Analyze(); | |
4892 ASSERT(!removed_side_effects); | |
4893 } | |
4894 } | 4893 } |
4895 } | 4894 } |
4896 | 4895 |
4897 | 4896 |
4898 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { | 4897 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { |
4899 *bailout_reason = SmartArrayPointer<char>(); | 4898 *bailout_reason = SmartArrayPointer<char>(); |
4900 OrderBlocks(); | 4899 OrderBlocks(); |
4901 AssignDominators(); | 4900 AssignDominators(); |
4902 | 4901 |
4903 // We need to create a HConstant "zero" now so that GVN will fold every | 4902 // We need to create a HConstant "zero" now so that GVN will fold every |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4943 MergeRemovableSimulates(); | 4942 MergeRemovableSimulates(); |
4944 | 4943 |
4945 MarkDeoptimizeOnUndefined(); | 4944 MarkDeoptimizeOnUndefined(); |
4946 InsertRepresentationChanges(); | 4945 InsertRepresentationChanges(); |
4947 | 4946 |
4948 InitializeInferredTypes(); | 4947 InitializeInferredTypes(); |
4949 | 4948 |
4950 // Must be performed before canonicalization to ensure that Canonicalize | 4949 // Must be performed before canonicalization to ensure that Canonicalize |
4951 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with | 4950 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with |
4952 // zero. | 4951 // zero. |
4953 ComputeSafeUint32Operations(); | 4952 if (FLAG_opt_safe_uint32_operations) ComputeSafeUint32Operations(); |
4954 | 4953 |
4955 Canonicalize(); | 4954 if (FLAG_use_canonicalizing) Canonicalize(); |
4956 | 4955 |
4957 GlobalValueNumbering(); | 4956 if (FLAG_use_gvn) GlobalValueNumbering(); |
4958 | 4957 |
4959 if (FLAG_use_range) { | 4958 if (FLAG_use_range) { |
4960 HRangeAnalysis rangeAnalysis(this); | 4959 HRangeAnalysis rangeAnalysis(this); |
4961 rangeAnalysis.Analyze(); | 4960 rangeAnalysis.Analyze(); |
4962 } | 4961 } |
4963 ComputeMinusZeroChecks(); | 4962 ComputeMinusZeroChecks(); |
4964 | 4963 |
4965 // Eliminate redundant stack checks on backwards branches. | 4964 // Eliminate redundant stack checks on backwards branches. |
4966 HStackCheckEliminator sce(this); | 4965 HStackCheckEliminator sce(this); |
4967 sce.Process(); | 4966 sce.Process(); |
(...skipping 7460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12428 } | 12427 } |
12429 } | 12428 } |
12430 | 12429 |
12431 #ifdef DEBUG | 12430 #ifdef DEBUG |
12432 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12431 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
12433 if (allocator_ != NULL) allocator_->Verify(); | 12432 if (allocator_ != NULL) allocator_->Verify(); |
12434 #endif | 12433 #endif |
12435 } | 12434 } |
12436 | 12435 |
12437 } } // namespace v8::internal | 12436 } } // namespace v8::internal |
OLD | NEW |