Index: src/jump-target.cc |
=================================================================== |
--- src/jump-target.cc (revision 3859) |
+++ src/jump-target.cc (working copy) |
@@ -101,6 +101,17 @@ |
if (element == NULL || !element->is_valid()) break; |
element = element->Combine(&reaching_frames_[j]->elements_[i]); |
+ |
+ FrameElement* other = &reaching_frames_[j]->elements_[i]; |
+ if (element != NULL && !element->is_copy()) { |
+ ASSERT(other != NULL); |
+ ASSERT(!other->is_copy()); |
+ // We overwrite the number information of one of the incoming frames. |
+ // This is safe because we only use the frame for emitting merge code. |
+ // The number information of incoming frames is not used anymore. |
+ element->set_number_info(NumberInfo::Combine(element->number_info(), |
+ other->number_info())); |
+ } |
} |
elements[i] = element; |
} |
@@ -117,6 +128,7 @@ |
// elements as copied exactly when they have a copy. Undetermined |
// elements are initially recorded as if in memory. |
if (target != NULL) { |
+ ASSERT(!target->is_copy()); // These initial elements are never copies. |
entry_frame_->elements_[index] = *target; |
InitializeEntryElement(index, target); |
} |
@@ -125,7 +137,8 @@ |
for (; index < length; index++) { |
FrameElement* target = elements[index]; |
if (target == NULL) { |
- entry_frame_->elements_.Add(FrameElement::MemoryElement()); |
+ entry_frame_->elements_.Add( |
+ FrameElement::MemoryElement(NumberInfo::kUninitialized)); |
} else { |
entry_frame_->elements_.Add(*target); |
InitializeEntryElement(index, target); |
@@ -142,9 +155,20 @@ |
RegisterFile candidate_registers; |
int best_count = kMinInt; |
int best_reg_num = RegisterAllocator::kInvalidRegister; |
+ NumberInfo::Type info = NumberInfo::kUninitialized; |
for (int j = 0; j < reaching_frames_.length(); j++) { |
FrameElement element = reaching_frames_[j]->elements_[i]; |
+ if (direction_ == BIDIRECTIONAL) { |
+ info = NumberInfo::kUnknown; |
+ } else if (!element.is_copy()) { |
+ info = NumberInfo::Combine(info, element.number_info()); |
+ } else { |
+ // New elements will not be copies, so get number information from |
+ // backing element in the reaching frame. |
+ info = NumberInfo::Combine(info, |
+ reaching_frames_[j]->elements_[element.index()].number_info()); |
+ } |
is_synced = is_synced && element.is_synced(); |
if (element.is_register() && !entry_frame_->is_used(element.reg())) { |
// Count the register occurrence and remember it if better |
@@ -158,11 +182,17 @@ |
} |
} |
+ // We must have a number type information now (not for copied elements). |
+ ASSERT(entry_frame_->elements_[i].is_copy() |
+ || info != NumberInfo::kUninitialized); |
+ |
// If the value is synced on all frames, put it in memory. This |
// costs nothing at the merge code but will incur a |
// memory-to-register move when the value is needed later. |
if (is_synced) { |
// Already recorded as a memory element. |
+ // Set combined number info. |
+ entry_frame_->elements_[i].set_number_info(info); |
continue; |
} |
@@ -183,14 +213,28 @@ |
bool is_copied = entry_frame_->elements_[i].is_copied(); |
Register reg = RegisterAllocator::ToRegister(best_reg_num); |
entry_frame_->elements_[i] = |
- FrameElement::RegisterElement(reg, |
- FrameElement::NOT_SYNCED); |
+ FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED, |
+ NumberInfo::kUninitialized); |
if (is_copied) entry_frame_->elements_[i].set_copied(); |
entry_frame_->set_register_location(reg, i); |
} |
+ // Set combined number info. |
+ entry_frame_->elements_[i].set_number_info(info); |
} |
} |
+ // If we have incoming backward edges assert we forget all number information. |
+#ifdef DEBUG |
+ if (direction_ == BIDIRECTIONAL) { |
+ for (int i = 0; i < length; ++i) { |
+ if (!entry_frame_->elements_[i].is_copy()) { |
+ ASSERT(entry_frame_->elements_[i].number_info() == |
+ NumberInfo::kUnknown); |
+ } |
+ } |
+ } |
+#endif |
+ |
// The stack pointer is at the highest synced element or the base of |
// the expression stack. |
int stack_pointer = length - 1; |