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