Commit 975ef0c6 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by Commit Bot

[wasm] Do not traverse all loop nodes in loop unrolling

The first pass in loop-unrolling aims to process stack check and loop
exit nodes. These nodes are all connected in a known fashion to the loop
header, so there is no need to traverse the whole loop.

Bug: v8:11298
Change-Id: I8336290ce7dddc8967f3fe05d3064b681c1e5c5a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2732007Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73166}
parent 87cc5b3d
...@@ -44,18 +44,21 @@ void UnrollLoop(Node* loop_node, ZoneUnorderedSet<Node*>* loop, uint32_t depth, ...@@ -44,18 +44,21 @@ void UnrollLoop(Node* loop_node, ZoneUnorderedSet<Node*>* loop, uint32_t depth,
#define COPY(node, n) copier.map(node, n) #define COPY(node, n) copier.map(node, n)
#define FOREACH_COPY_INDEX(i) for (uint32_t i = 0; i < unrolling_count; i++) #define FOREACH_COPY_INDEX(i) for (uint32_t i = 0; i < unrolling_count; i++)
for (Node* node : *loop) { for (Node* node : loop_node->uses()) {
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kStackPointerGreaterThan: { case IrOpcode::kBranch: {
/*** Step 1: Remove stack checks from all but the first iteration of the /*** Step 1: Remove stack checks from all but the first iteration of the
loop. ***/ loop. ***/
for (Edge edge : node->use_edges()) { Node* stack_check = node->InputAt(0);
if (edge.from()->opcode() == IrOpcode::kBranch) { if (stack_check->opcode() != IrOpcode::kStackPointerGreaterThan) {
FOREACH_COPY_INDEX(i) { break;
COPY(edge.from(), i) }
->ReplaceInput(0, graph->NewNode(common->Int32Constant(1))); FOREACH_COPY_INDEX(i) {
} COPY(node, i)->ReplaceInput(0,
} else if (edge.from()->opcode() == IrOpcode::kEffectPhi) { graph->NewNode(common->Int32Constant(1)));
}
for (Node* use : stack_check->uses()) {
if (use->opcode() == IrOpcode::kEffectPhi) {
// We now need to remove stack check and the related function call // We now need to remove stack check and the related function call
// from the effect chain. // from the effect chain.
// The effect chain looks like this (* stand for irrelevant nodes): // The effect chain looks like this (* stand for irrelevant nodes):
...@@ -68,24 +71,22 @@ void UnrollLoop(Node* loop_node, ZoneUnorderedSet<Node*>* loop, uint32_t depth, ...@@ -68,24 +71,22 @@ void UnrollLoop(Node* loop_node, ZoneUnorderedSet<Node*>* loop, uint32_t depth,
// | | | | // | | | |
// ( Load ) // ( Load )
// | | // | |
// stack check // stack_check
// | * | * // | * | *
// | | | | // | | | |
// | (call) // | (call)
// | | * // | | *
// | | | // | | |
// stack check effect (that we need to replace) // {use} (stack check effect that we need to replace)
Node* stack_check_effect = edge.from(); DCHECK_EQ(use->InputAt(1)->opcode(), IrOpcode::kCall);
DCHECK_EQ(edge.index(), 0); DCHECK_EQ(use->InputAt(1)->InputAt(1), stack_check);
DCHECK_EQ(stack_check_effect->InputAt(1)->opcode(), DCHECK_EQ(stack_check->InputAt(1)->opcode(), IrOpcode::kLoad);
IrOpcode::kCall); DCHECK_EQ(stack_check->InputAt(1)->InputAt(2)->opcode(),
DCHECK_EQ(stack_check_effect->InputAt(1)->InputAt(1), node); IrOpcode::kLoad);
DCHECK_EQ(node->InputAt(1)->opcode(), IrOpcode::kLoad); Node* replacing_effect =
DCHECK_EQ(node->InputAt(1)->InputAt(2)->opcode(), IrOpcode::kLoad); stack_check->InputAt(1)->InputAt(2)->InputAt(2);
Node* replacing_effect = node->InputAt(1)->InputAt(2)->InputAt(2);
FOREACH_COPY_INDEX(i) { FOREACH_COPY_INDEX(i) {
COPY(stack_check_effect, i) COPY(use, i)->ReplaceUses(COPY(replacing_effect, i));
->ReplaceUses(COPY(replacing_effect, i));
} }
} }
} }
......
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