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