| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 | 93 |
| 94 // Compute elements based on the other reaching frames. | 94 // Compute elements based on the other reaching frames. |
| 95 if (reaching_frames_.length() > 1) { | 95 if (reaching_frames_.length() > 1) { |
| 96 for (int i = 0; i < length; i++) { | 96 for (int i = 0; i < length; i++) { |
| 97 FrameElement* element = elements[i]; | 97 FrameElement* element = elements[i]; |
| 98 for (int j = 1; j < reaching_frames_.length(); j++) { | 98 for (int j = 1; j < reaching_frames_.length(); j++) { |
| 99 // Element computation is monotonic: new information will not | 99 // Element computation is monotonic: new information will not |
| 100 // change our decision about undetermined or invalid elements. | 100 // change our decision about undetermined or invalid elements. |
| 101 if (element == NULL || !element->is_valid()) break; | 101 if (element == NULL || !element->is_valid()) break; |
| 102 | 102 |
| 103 element = element->Combine(&reaching_frames_[j]->elements_[i]); | |
| 104 | |
| 105 FrameElement* other = &reaching_frames_[j]->elements_[i]; | 103 FrameElement* other = &reaching_frames_[j]->elements_[i]; |
| 104 element = element->Combine(other); |
| 106 if (element != NULL && !element->is_copy()) { | 105 if (element != NULL && !element->is_copy()) { |
| 107 ASSERT(other != NULL); | 106 ASSERT(other != NULL); |
| 108 // We overwrite the number information of one of the incoming frames. | 107 // We overwrite the number information of one of the incoming frames. |
| 109 // This is safe because we only use the frame for emitting merge code. | 108 // This is safe because we only use the frame for emitting merge code. |
| 110 // The number information of incoming frames is not used anymore. | 109 // The number information of incoming frames is not used anymore. |
| 111 element->set_number_info(NumberInfo::Combine(element->number_info(), | 110 element->set_number_info(NumberInfo::Combine(element->number_info(), |
| 112 other->number_info())); | 111 other->number_info())); |
| 113 } | 112 } |
| 114 } | 113 } |
| 115 elements[i] = element; | 114 elements[i] = element; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 129 if (target != NULL) { | 128 if (target != NULL) { |
| 130 entry_frame_->elements_[index] = *target; | 129 entry_frame_->elements_[index] = *target; |
| 131 InitializeEntryElement(index, target); | 130 InitializeEntryElement(index, target); |
| 132 } | 131 } |
| 133 } | 132 } |
| 134 // Then fill in the rest of the frame with new elements. | 133 // Then fill in the rest of the frame with new elements. |
| 135 for (; index < length; index++) { | 134 for (; index < length; index++) { |
| 136 FrameElement* target = elements[index]; | 135 FrameElement* target = elements[index]; |
| 137 if (target == NULL) { | 136 if (target == NULL) { |
| 138 entry_frame_->elements_.Add( | 137 entry_frame_->elements_.Add( |
| 139 FrameElement::MemoryElement(NumberInfo::kUninitialized)); | 138 FrameElement::MemoryElement(NumberInfo::Uninitialized())); |
| 140 } else { | 139 } else { |
| 141 entry_frame_->elements_.Add(*target); | 140 entry_frame_->elements_.Add(*target); |
| 142 InitializeEntryElement(index, target); | 141 InitializeEntryElement(index, target); |
| 143 } | 142 } |
| 144 } | 143 } |
| 145 | 144 |
| 146 // Allocate any still-undetermined frame elements to registers or | 145 // Allocate any still-undetermined frame elements to registers or |
| 147 // memory, from the top down. | 146 // memory, from the top down. |
| 148 for (int i = length - 1; i >= 0; i--) { | 147 for (int i = length - 1; i >= 0; i--) { |
| 149 if (elements[i] == NULL) { | 148 if (elements[i] == NULL) { |
| 150 // Loop over all the reaching frames to check whether the element | 149 // Loop over all the reaching frames to check whether the element |
| 151 // is synced on all frames and to count the registers it occupies. | 150 // is synced on all frames and to count the registers it occupies. |
| 152 bool is_synced = true; | 151 bool is_synced = true; |
| 153 RegisterFile candidate_registers; | 152 RegisterFile candidate_registers; |
| 154 int best_count = kMinInt; | 153 int best_count = kMinInt; |
| 155 int best_reg_num = RegisterAllocator::kInvalidRegister; | 154 int best_reg_num = RegisterAllocator::kInvalidRegister; |
| 156 NumberInfo::Type info = NumberInfo::kUninitialized; | 155 NumberInfo info = NumberInfo::Uninitialized(); |
| 157 | 156 |
| 158 for (int j = 0; j < reaching_frames_.length(); j++) { | 157 for (int j = 0; j < reaching_frames_.length(); j++) { |
| 159 FrameElement element = reaching_frames_[j]->elements_[i]; | 158 FrameElement element = reaching_frames_[j]->elements_[i]; |
| 160 if (direction_ == BIDIRECTIONAL) { | 159 if (direction_ == BIDIRECTIONAL) { |
| 161 info = NumberInfo::kUnknown; | 160 info = NumberInfo::Unknown(); |
| 162 } else if (!element.is_copy()) { | 161 } else if (!element.is_copy()) { |
| 163 info = NumberInfo::Combine(info, element.number_info()); | 162 info = NumberInfo::Combine(info, element.number_info()); |
| 164 } else { | 163 } else { |
| 165 // New elements will not be copies, so get number information from | 164 // New elements will not be copies, so get number information from |
| 166 // backing element in the reaching frame. | 165 // backing element in the reaching frame. |
| 167 info = NumberInfo::Combine(info, | 166 info = NumberInfo::Combine(info, |
| 168 reaching_frames_[j]->elements_[element.index()].number_info()); | 167 reaching_frames_[j]->elements_[element.index()].number_info()); |
| 169 } | 168 } |
| 170 is_synced = is_synced && element.is_synced(); | 169 is_synced = is_synced && element.is_synced(); |
| 171 if (element.is_register() && !entry_frame_->is_used(element.reg())) { | 170 if (element.is_register() && !entry_frame_->is_used(element.reg())) { |
| 172 // Count the register occurrence and remember it if better | 171 // Count the register occurrence and remember it if better |
| 173 // than the previous best. | 172 // than the previous best. |
| 174 int num = RegisterAllocator::ToNumber(element.reg()); | 173 int num = RegisterAllocator::ToNumber(element.reg()); |
| 175 candidate_registers.Use(num); | 174 candidate_registers.Use(num); |
| 176 if (candidate_registers.count(num) > best_count) { | 175 if (candidate_registers.count(num) > best_count) { |
| 177 best_count = candidate_registers.count(num); | 176 best_count = candidate_registers.count(num); |
| 178 best_reg_num = num; | 177 best_reg_num = num; |
| 179 } | 178 } |
| 180 } | 179 } |
| 181 } | 180 } |
| 182 | 181 |
| 183 // We must have a number type information now (not for copied elements). | 182 // We must have a number type information now (not for copied elements). |
| 184 ASSERT(entry_frame_->elements_[i].is_copy() | 183 ASSERT(entry_frame_->elements_[i].is_copy() |
| 185 || info != NumberInfo::kUninitialized); | 184 || !info.IsUninitialized()); |
| 186 | 185 |
| 187 // If the value is synced on all frames, put it in memory. This | 186 // If the value is synced on all frames, put it in memory. This |
| 188 // costs nothing at the merge code but will incur a | 187 // costs nothing at the merge code but will incur a |
| 189 // memory-to-register move when the value is needed later. | 188 // memory-to-register move when the value is needed later. |
| 190 if (is_synced) { | 189 if (is_synced) { |
| 191 // Already recorded as a memory element. | 190 // Already recorded as a memory element. |
| 192 // Set combined number info. | 191 // Set combined number info. |
| 193 entry_frame_->elements_[i].set_number_info(info); | 192 entry_frame_->elements_[i].set_number_info(info); |
| 194 continue; | 193 continue; |
| 195 } | 194 } |
| 196 | 195 |
| 197 // Try to put it in a register. If there was no best choice | 196 // Try to put it in a register. If there was no best choice |
| 198 // consider any free register. | 197 // consider any free register. |
| 199 if (best_reg_num == RegisterAllocator::kInvalidRegister) { | 198 if (best_reg_num == RegisterAllocator::kInvalidRegister) { |
| 200 for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { | 199 for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { |
| 201 if (!entry_frame_->is_used(j)) { | 200 if (!entry_frame_->is_used(j)) { |
| 202 best_reg_num = j; | 201 best_reg_num = j; |
| 203 break; | 202 break; |
| 204 } | 203 } |
| 205 } | 204 } |
| 206 } | 205 } |
| 207 | 206 |
| 208 if (best_reg_num != RegisterAllocator::kInvalidRegister) { | 207 if (best_reg_num != RegisterAllocator::kInvalidRegister) { |
| 209 // If there was a register choice, use it. Preserve the copied | 208 // If there was a register choice, use it. Preserve the copied |
| 210 // flag on the element. | 209 // flag on the element. |
| 211 bool is_copied = entry_frame_->elements_[i].is_copied(); | 210 bool is_copied = entry_frame_->elements_[i].is_copied(); |
| 212 Register reg = RegisterAllocator::ToRegister(best_reg_num); | 211 Register reg = RegisterAllocator::ToRegister(best_reg_num); |
| 213 entry_frame_->elements_[i] = | 212 entry_frame_->elements_[i] = |
| 214 FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED, | 213 FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED, |
| 215 NumberInfo::kUninitialized); | 214 NumberInfo::Uninitialized()); |
| 216 if (is_copied) entry_frame_->elements_[i].set_copied(); | 215 if (is_copied) entry_frame_->elements_[i].set_copied(); |
| 217 entry_frame_->set_register_location(reg, i); | 216 entry_frame_->set_register_location(reg, i); |
| 218 } | 217 } |
| 219 // Set combined number info. | 218 // Set combined number info. |
| 220 entry_frame_->elements_[i].set_number_info(info); | 219 entry_frame_->elements_[i].set_number_info(info); |
| 221 } | 220 } |
| 222 } | 221 } |
| 223 | 222 |
| 224 // If we have incoming backward edges assert we forget all number information. | 223 // If we have incoming backward edges assert we forget all number information. |
| 225 #ifdef DEBUG | 224 #ifdef DEBUG |
| 226 if (direction_ == BIDIRECTIONAL) { | 225 if (direction_ == BIDIRECTIONAL) { |
| 227 for (int i = 0; i < length; ++i) { | 226 for (int i = 0; i < length; ++i) { |
| 228 if (!entry_frame_->elements_[i].is_copy()) { | 227 if (!entry_frame_->elements_[i].is_copy()) { |
| 229 ASSERT(entry_frame_->elements_[i].number_info() == | 228 ASSERT(entry_frame_->elements_[i].number_info().IsUnknown()); |
| 230 NumberInfo::kUnknown); | |
| 231 } | 229 } |
| 232 } | 230 } |
| 233 } | 231 } |
| 234 #endif | 232 #endif |
| 235 | 233 |
| 236 // The stack pointer is at the highest synced element or the base of | 234 // The stack pointer is at the highest synced element or the base of |
| 237 // the expression stack. | 235 // the expression stack. |
| 238 int stack_pointer = length - 1; | 236 int stack_pointer = length - 1; |
| 239 while (stack_pointer >= entry_frame_->expression_base_index() && | 237 while (stack_pointer >= entry_frame_->expression_base_index() && |
| 240 !entry_frame_->elements_[stack_pointer].is_synced()) { | 238 !entry_frame_->elements_[stack_pointer].is_synced()) { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 temp.CopyTo(this); | 414 temp.CopyTo(this); |
| 417 temp.Unuse(); | 415 temp.Unuse(); |
| 418 | 416 |
| 419 #ifdef DEBUG | 417 #ifdef DEBUG |
| 420 is_shadowing_ = false; | 418 is_shadowing_ = false; |
| 421 #endif | 419 #endif |
| 422 } | 420 } |
| 423 | 421 |
| 424 | 422 |
| 425 } } // namespace v8::internal | 423 } } // namespace v8::internal |
| OLD | NEW |