| 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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]); | 103 element = element->Combine(&reaching_frames_[j]->elements_[i]); |
| 104 |
| 105 FrameElement* other = &reaching_frames_[j]->elements_[i]; |
| 106 if (element != NULL && !element->is_copy()) { |
| 107 ASSERT(other != NULL); |
| 108 ASSERT(!other->is_copy()); |
| 109 // We overwrite the number information of one of the incoming frames. |
| 110 // This is safe because we only use the frame for emitting merge code. |
| 111 // The number information of incoming frames is not used anymore. |
| 112 element->set_number_info(NumberInfo::Combine(element->number_info(), |
| 113 other->number_info())); |
| 114 } |
| 104 } | 115 } |
| 105 elements[i] = element; | 116 elements[i] = element; |
| 106 } | 117 } |
| 107 } | 118 } |
| 108 | 119 |
| 109 // Build the new frame. A freshly allocated frame has memory elements | 120 // Build the new frame. A freshly allocated frame has memory elements |
| 110 // for the parameters and some platform-dependent elements (e.g., | 121 // for the parameters and some platform-dependent elements (e.g., |
| 111 // return address). Replace those first. | 122 // return address). Replace those first. |
| 112 entry_frame_ = new VirtualFrame(); | 123 entry_frame_ = new VirtualFrame(); |
| 113 int index = 0; | 124 int index = 0; |
| 114 for (; index < entry_frame_->element_count(); index++) { | 125 for (; index < entry_frame_->element_count(); index++) { |
| 115 FrameElement* target = elements[index]; | 126 FrameElement* target = elements[index]; |
| 116 // If the element is determined, set it now. Count registers. Mark | 127 // If the element is determined, set it now. Count registers. Mark |
| 117 // elements as copied exactly when they have a copy. Undetermined | 128 // elements as copied exactly when they have a copy. Undetermined |
| 118 // elements are initially recorded as if in memory. | 129 // elements are initially recorded as if in memory. |
| 119 if (target != NULL) { | 130 if (target != NULL) { |
| 131 ASSERT(!target->is_copy()); // These initial elements are never copies. |
| 120 entry_frame_->elements_[index] = *target; | 132 entry_frame_->elements_[index] = *target; |
| 121 InitializeEntryElement(index, target); | 133 InitializeEntryElement(index, target); |
| 122 } | 134 } |
| 123 } | 135 } |
| 124 // Then fill in the rest of the frame with new elements. | 136 // Then fill in the rest of the frame with new elements. |
| 125 for (; index < length; index++) { | 137 for (; index < length; index++) { |
| 126 FrameElement* target = elements[index]; | 138 FrameElement* target = elements[index]; |
| 127 if (target == NULL) { | 139 if (target == NULL) { |
| 128 entry_frame_->elements_.Add(FrameElement::MemoryElement()); | 140 entry_frame_->elements_.Add( |
| 141 FrameElement::MemoryElement(NumberInfo::kUninitialized)); |
| 129 } else { | 142 } else { |
| 130 entry_frame_->elements_.Add(*target); | 143 entry_frame_->elements_.Add(*target); |
| 131 InitializeEntryElement(index, target); | 144 InitializeEntryElement(index, target); |
| 132 } | 145 } |
| 133 } | 146 } |
| 134 | 147 |
| 135 // Allocate any still-undetermined frame elements to registers or | 148 // Allocate any still-undetermined frame elements to registers or |
| 136 // memory, from the top down. | 149 // memory, from the top down. |
| 137 for (int i = length - 1; i >= 0; i--) { | 150 for (int i = length - 1; i >= 0; i--) { |
| 138 if (elements[i] == NULL) { | 151 if (elements[i] == NULL) { |
| 139 // Loop over all the reaching frames to check whether the element | 152 // Loop over all the reaching frames to check whether the element |
| 140 // is synced on all frames and to count the registers it occupies. | 153 // is synced on all frames and to count the registers it occupies. |
| 141 bool is_synced = true; | 154 bool is_synced = true; |
| 142 RegisterFile candidate_registers; | 155 RegisterFile candidate_registers; |
| 143 int best_count = kMinInt; | 156 int best_count = kMinInt; |
| 144 int best_reg_num = RegisterAllocator::kInvalidRegister; | 157 int best_reg_num = RegisterAllocator::kInvalidRegister; |
| 158 NumberInfo::Type info = NumberInfo::kUninitialized; |
| 145 | 159 |
| 146 for (int j = 0; j < reaching_frames_.length(); j++) { | 160 for (int j = 0; j < reaching_frames_.length(); j++) { |
| 147 FrameElement element = reaching_frames_[j]->elements_[i]; | 161 FrameElement element = reaching_frames_[j]->elements_[i]; |
| 162 if (direction_ == BIDIRECTIONAL) { |
| 163 info = NumberInfo::kUnknown; |
| 164 } else if (!element.is_copy()) { |
| 165 info = NumberInfo::Combine(info, element.number_info()); |
| 166 } else { |
| 167 // New elements will not be copies, so get number information from |
| 168 // backing element in the reaching frame. |
| 169 info = NumberInfo::Combine(info, |
| 170 reaching_frames_[j]->elements_[element.index()].number_info()); |
| 171 } |
| 148 is_synced = is_synced && element.is_synced(); | 172 is_synced = is_synced && element.is_synced(); |
| 149 if (element.is_register() && !entry_frame_->is_used(element.reg())) { | 173 if (element.is_register() && !entry_frame_->is_used(element.reg())) { |
| 150 // Count the register occurrence and remember it if better | 174 // Count the register occurrence and remember it if better |
| 151 // than the previous best. | 175 // than the previous best. |
| 152 int num = RegisterAllocator::ToNumber(element.reg()); | 176 int num = RegisterAllocator::ToNumber(element.reg()); |
| 153 candidate_registers.Use(num); | 177 candidate_registers.Use(num); |
| 154 if (candidate_registers.count(num) > best_count) { | 178 if (candidate_registers.count(num) > best_count) { |
| 155 best_count = candidate_registers.count(num); | 179 best_count = candidate_registers.count(num); |
| 156 best_reg_num = num; | 180 best_reg_num = num; |
| 157 } | 181 } |
| 158 } | 182 } |
| 159 } | 183 } |
| 160 | 184 |
| 185 // We must have a number type information now (not for copied elements). |
| 186 ASSERT(entry_frame_->elements_[i].is_copy() |
| 187 || info != NumberInfo::kUninitialized); |
| 188 |
| 161 // If the value is synced on all frames, put it in memory. This | 189 // If the value is synced on all frames, put it in memory. This |
| 162 // costs nothing at the merge code but will incur a | 190 // costs nothing at the merge code but will incur a |
| 163 // memory-to-register move when the value is needed later. | 191 // memory-to-register move when the value is needed later. |
| 164 if (is_synced) { | 192 if (is_synced) { |
| 165 // Already recorded as a memory element. | 193 // Already recorded as a memory element. |
| 194 // Set combined number info. |
| 195 entry_frame_->elements_[i].set_number_info(info); |
| 166 continue; | 196 continue; |
| 167 } | 197 } |
| 168 | 198 |
| 169 // Try to put it in a register. If there was no best choice | 199 // Try to put it in a register. If there was no best choice |
| 170 // consider any free register. | 200 // consider any free register. |
| 171 if (best_reg_num == RegisterAllocator::kInvalidRegister) { | 201 if (best_reg_num == RegisterAllocator::kInvalidRegister) { |
| 172 for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { | 202 for (int j = 0; j < RegisterAllocator::kNumRegisters; j++) { |
| 173 if (!entry_frame_->is_used(j)) { | 203 if (!entry_frame_->is_used(j)) { |
| 174 best_reg_num = j; | 204 best_reg_num = j; |
| 175 break; | 205 break; |
| 176 } | 206 } |
| 177 } | 207 } |
| 178 } | 208 } |
| 179 | 209 |
| 180 if (best_reg_num != RegisterAllocator::kInvalidRegister) { | 210 if (best_reg_num != RegisterAllocator::kInvalidRegister) { |
| 181 // If there was a register choice, use it. Preserve the copied | 211 // If there was a register choice, use it. Preserve the copied |
| 182 // flag on the element. | 212 // flag on the element. |
| 183 bool is_copied = entry_frame_->elements_[i].is_copied(); | 213 bool is_copied = entry_frame_->elements_[i].is_copied(); |
| 184 Register reg = RegisterAllocator::ToRegister(best_reg_num); | 214 Register reg = RegisterAllocator::ToRegister(best_reg_num); |
| 185 entry_frame_->elements_[i] = | 215 entry_frame_->elements_[i] = |
| 186 FrameElement::RegisterElement(reg, | 216 FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED, |
| 187 FrameElement::NOT_SYNCED); | 217 NumberInfo::kUninitialized); |
| 188 if (is_copied) entry_frame_->elements_[i].set_copied(); | 218 if (is_copied) entry_frame_->elements_[i].set_copied(); |
| 189 entry_frame_->set_register_location(reg, i); | 219 entry_frame_->set_register_location(reg, i); |
| 190 } | 220 } |
| 221 // Set combined number info. |
| 222 entry_frame_->elements_[i].set_number_info(info); |
| 191 } | 223 } |
| 192 } | 224 } |
| 193 | 225 |
| 226 // If we have incoming backward edges assert we forget all number information. |
| 227 #ifdef DEBUG |
| 228 if (direction_ == BIDIRECTIONAL) { |
| 229 for (int i = 0; i < length; ++i) { |
| 230 if (!entry_frame_->elements_[i].is_copy()) { |
| 231 ASSERT(entry_frame_->elements_[i].number_info() == |
| 232 NumberInfo::kUnknown); |
| 233 } |
| 234 } |
| 235 } |
| 236 #endif |
| 237 |
| 194 // The stack pointer is at the highest synced element or the base of | 238 // The stack pointer is at the highest synced element or the base of |
| 195 // the expression stack. | 239 // the expression stack. |
| 196 int stack_pointer = length - 1; | 240 int stack_pointer = length - 1; |
| 197 while (stack_pointer >= entry_frame_->expression_base_index() && | 241 while (stack_pointer >= entry_frame_->expression_base_index() && |
| 198 !entry_frame_->elements_[stack_pointer].is_synced()) { | 242 !entry_frame_->elements_[stack_pointer].is_synced()) { |
| 199 stack_pointer--; | 243 stack_pointer--; |
| 200 } | 244 } |
| 201 entry_frame_->stack_pointer_ = stack_pointer; | 245 entry_frame_->stack_pointer_ = stack_pointer; |
| 202 } | 246 } |
| 203 | 247 |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 temp.CopyTo(this); | 418 temp.CopyTo(this); |
| 375 temp.Unuse(); | 419 temp.Unuse(); |
| 376 | 420 |
| 377 #ifdef DEBUG | 421 #ifdef DEBUG |
| 378 is_shadowing_ = false; | 422 is_shadowing_ = false; |
| 379 #endif | 423 #endif |
| 380 } | 424 } |
| 381 | 425 |
| 382 | 426 |
| 383 } } // namespace v8::internal | 427 } } // namespace v8::internal |
| OLD | NEW |