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 |