Refactor JumpTarget::Combine.

Review URL: http://codereview.chromium.org/113329

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1930 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ada3d372
......@@ -471,6 +471,18 @@ class VirtualFrame : public Malloced {
bool Equals(VirtualFrame* other);
// Perform initialization required during entry frame computation
// after setting the virtual frame element at index in frame to be
// target.
void InitializeEntryElement(int index, FrameElement* target) {
elements_[index].clear_copied();
if (target->is_register()) {
register_locations_[target->reg().code()] = index;
} else if (target->is_copy()) {
elements_[target->index()].set_copied();
}
}
friend class JumpTarget;
};
......
......@@ -485,6 +485,18 @@ class VirtualFrame : public Malloced {
bool Equals(VirtualFrame* other);
// Perform initialization required during entry frame computation
// after setting the virtual frame element at index in frame to be
// target.
void InitializeEntryElement(int index, FrameElement* target) {
elements_[index].clear_copied();
if (target->is_register()) {
register_locations_[target->reg().code()] = index;
} else if (target->is_copy()) {
elements_[target->index()].set_copied();
}
}
friend class JumpTarget;
};
......
......@@ -92,69 +92,6 @@ void JumpTarget::Reset() {
}
FrameElement* JumpTarget::Combine(FrameElement* left, FrameElement* right) {
// Given a pair of non-null frame element pointers, return one of
// them as an entry frame candidate or null if they are
// incompatible.
// If either is invalid, the result is.
if (!left->is_valid()) return left;
if (!right->is_valid()) return right;
// If they have the exact same location, the result is in that
// location, otherwise we reallocate. If either is unsynced, the
// result is. The result static type is the merge of the static
// types. It's safe to set it on one of the frame elements, and
// harmless too (because we are only going to merge the reaching
// frames and will ensure that the types are coherent, and changing
// the static type does not emit code).
StaticType type = left->static_type().merge(right->static_type());
if (left->is_memory() && right->is_memory()) {
left->set_static_type(type);
return left;
}
if (left->is_register() && right->is_register() &&
left->reg().is(right->reg())) {
if (!left->is_synced()) {
left->set_static_type(type);
return left;
} else {
right->set_static_type(type);
return right;
}
}
if (left->is_constant() &&
right->is_constant() &&
left->handle().is_identical_to(right->handle())) {
if (!left->is_synced()) {
left->set_static_type(type);
return left;
} else {
right->set_static_type(type);
return right;
}
}
if (left->is_copy() &&
right->is_copy() &&
left->index() == right->index()) {
if (!left->is_synced()) {
left->set_static_type(type);
return left;
} else {
right->set_static_type(type);
return right;
}
}
// Otherwise they are incompatible and we will reallocate them.
return NULL;
}
void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// Given: a collection of frames reaching by forward CFG edges and
// the directionality of the block. Compute: an entry frame for the
......@@ -198,15 +135,15 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// Compute elements based on the other reaching frames.
if (reaching_frames_.length() > 1) {
for (int i = 0; i < length; i++) {
FrameElement* element = elements[i];
for (int j = 1; j < reaching_frames_.length(); j++) {
FrameElement* element = elements[i];
// Element computation is monotonic: new information will not
// change our decision about undetermined or invalid elements.
if (element == NULL || !element->is_valid()) break;
elements[i] = Combine(element, &reaching_frames_[j]->elements_[i]);
element = element->Combine(&reaching_frames_[j]->elements_[i]);
}
elements[i] = element;
}
}
......@@ -216,33 +153,23 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
entry_frame_ = new VirtualFrame(cgen_);
int index = 0;
for (; index < entry_frame_->elements_.length(); index++) {
FrameElement* target = elements[index];
// If the element is determined, set it now. Count registers. Mark
// elements as copied exactly when they have a copy. Undetermined
// elements are initially recorded as if in memory.
if (elements[index] != NULL) {
entry_frame_->elements_[index] = *elements[index];
entry_frame_->elements_[index].clear_copied();
if (elements[index]->is_register()) {
entry_frame_->register_locations_[elements[index]->reg().code()] =
index;
} else if (elements[index]->is_copy()) {
entry_frame_->elements_[elements[index]->index()].set_copied();
}
if (target != NULL) {
entry_frame_->elements_[index] = *target;
entry_frame_->InitializeEntryElement(index, target);
}
}
// Then fill in the rest of the frame with new elements.
for (; index < length; index++) {
if (elements[index] == NULL) {
FrameElement* target = elements[index];
if (target == NULL) {
entry_frame_->elements_.Add(FrameElement::MemoryElement());
} else {
entry_frame_->elements_.Add(*elements[index]);
entry_frame_->elements_[index].clear_copied();
if (elements[index]->is_register()) {
entry_frame_->register_locations_[elements[index]->reg().code()] =
index;
} else if (elements[index]->is_copy()) {
entry_frame_->elements_[elements[index]->index()].set_copied();
}
entry_frame_->elements_.Add(*target);
entry_frame_->InitializeEntryElement(index, target);
}
}
......
......@@ -202,10 +202,6 @@ class JumpTarget : public Malloced { // Shadows are dynamically allocated.
// jump, and a fresh label for its merge code.
void AddReachingFrame(VirtualFrame* frame);
// Choose an element from a pair of frame elements to be in the
// expected frame. Return null if they are incompatible.
FrameElement* Combine(FrameElement* left, FrameElement* right);
// Compute a frame to use for entry to this block. Mergable
// elements is as described for the Bind function.
void ComputeEntryFrame(int mergable_elements);
......
......@@ -121,8 +121,6 @@ class FrameElement BASE_EMBEDDED {
return data_.index_;
}
bool Equals(FrameElement other);
StaticType static_type() { return static_type_; }
void set_static_type(StaticType static_type) {
......@@ -131,6 +129,34 @@ class FrameElement BASE_EMBEDDED {
static_type_ = static_type;
}
// True if the frame elements are identical (all data members).
bool Equals(FrameElement other);
// Given a pair of non-null frame element pointers, return one of them
// as an entry frame candidate or null if they are incompatible.
FrameElement* Combine(FrameElement* other) {
// If either is invalid, the result is.
if (!is_valid()) return this;
if (!other->is_valid()) return other;
// If they do not have the exact same location we reallocate.
bool not_same_location =
(type_ != other->type_) ||
(is_register() && !reg().is(other->reg())) ||
(is_constant() && !handle().is_identical_to(other->handle())) ||
(is_copy() && index() != other->index());
if (not_same_location) return NULL;
// If either is unsynced, the result is. The result static type is
// the merge of the static types. It's safe to set it on one of the
// frame elements, and harmless too (because we are only going to
// merge the reaching frames and will ensure that the types are
// coherent, and changing the static type does not emit code).
FrameElement* result = is_synced() ? other : this;
result->set_static_type(static_type().merge(other->static_type()));
return result;
}
private:
enum Type {
INVALID,
......
......@@ -485,6 +485,18 @@ class VirtualFrame : public Malloced {
bool Equals(VirtualFrame* other);
// Perform initialization required during entry frame computation
// after setting the virtual frame element at index in frame to be
// target.
void InitializeEntryElement(int index, FrameElement* target) {
elements_[index].clear_copied();
if (target->is_register()) {
register_locations_[target->reg().code()] = index;
} else if (target->is_copy()) {
elements_[target->index()].set_copied();
}
}
friend class JumpTarget;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment