Commit 8038e5ca authored by Mircea Trofin's avatar Mircea Trofin Committed by Commit Bot

Move phis, if any, when ensuring deferred blocks.

We use Schedule::EnsureDeferredCodeSingleEntryPoint as a helper for 
hand-crafted builtin code, to ensure deferred code isn't entered from a
mix of deferred and non-deferred code (invariant required for hot/cold
allocation, or "splintering").

When we create a "merger" block, it may be the case that the original 
block had a few phi operands. Those need to be moved as well.

This bug was uncovered by both v8:6390, and, earlier, by v8:5998. We 
fixed the earlier one by authoring a the builtin to avoid the need for
EnsureDeferredCodeSingleEntryPoint. I proposed earlier an alternative 
where we'd replace the Ensure... method with a Verify, and throw early
when the builtin is assembled, however, we may want to maintain the 
slightly higher level DSL for authoring builtins, and perform such 
graph adjustments for the lower level constraints afterwards, hence 
this current CL.

Bug: v8:5998 v8:6390
Change-Id: Ia3143f7a66904fe480d8edb5b52bf915b8d185dc
Reviewed-on: https://chromium-review.googlesource.com/505264
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45387}
parent 72ff60a1
......@@ -417,6 +417,21 @@ void Schedule::EnsureDeferredCodeSingleEntryPoint(BasicBlock* block) {
merger->set_deferred(false);
block->predecessors().clear();
block->predecessors().push_back(merger);
MovePhis(block, merger);
}
void Schedule::MovePhis(BasicBlock* from, BasicBlock* to) {
for (size_t i = 0; i < from->NodeCount();) {
Node* node = from->NodeAt(i);
if (node->opcode() == IrOpcode::kPhi) {
to->AddNode(node);
from->RemoveNode(from->begin() + i);
DCHECK_EQ(nodeid_to_block_[node->id()], from);
nodeid_to_block_[node->id()] = to;
} else {
++i;
}
}
}
void Schedule::PropagateDeferredMark() {
......
......@@ -97,6 +97,8 @@ class V8_EXPORT_PRIVATE BasicBlock final
iterator begin() { return nodes_.begin(); }
iterator end() { return nodes_.end(); }
void RemoveNode(iterator it) { nodes_.erase(it); }
typedef NodeVector::const_iterator const_iterator;
const_iterator begin() const { return nodes_.begin(); }
const_iterator end() const { return nodes_.end(); }
......@@ -276,6 +278,8 @@ class V8_EXPORT_PRIVATE Schedule final : public NON_EXPORTED_BASE(ZoneObject) {
void EnsureSplitEdgeForm(BasicBlock* block);
// Ensure entry into a deferred block happens from a single hot block.
void EnsureDeferredCodeSingleEntryPoint(BasicBlock* block);
// Move Phi operands to newly created merger blocks
void MovePhis(BasicBlock* from, BasicBlock* to);
// Copy deferred block markers down as far as possible
void PropagateDeferredMark();
......
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