[wasm] Fix loop unrolling being skipped
As part of https://crrev.com/c/4200642 loop peeling was enabled for loops containing a getCodeUnit instruction. As a side effect this also affected loop unrolling now only happening if getCodeUnit was used in the loop body which is fixed by this change. Bug: chromium:1412781 Change-Id: I60e3a524340cfbdb907ae2ee5b46cbb6f514775c Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4219103 Auto-Submit: Matthias Liedtke <mliedtke@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Manos Koukoutos <manoskouk@chromium.org> Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/main@{#85671}
This commit is contained in:
parent
81857203e9
commit
65a0aaab04
@ -554,7 +554,7 @@ LoopTree* LoopFinder::BuildLoopTree(Graph* graph, TickCounter* tick_counter,
|
||||
// static
|
||||
ZoneUnorderedSet<Node*>* LoopFinder::FindSmallInnermostLoopFromHeader(
|
||||
Node* loop_header, AllNodes& all_nodes, Zone* zone, size_t max_size,
|
||||
bool calls_are_large) {
|
||||
Purpose purpose) {
|
||||
auto* visited = zone->New<ZoneUnorderedSet<Node*>>(zone);
|
||||
std::vector<Node*> queue;
|
||||
|
||||
@ -598,16 +598,16 @@ ZoneUnorderedSet<Node*>* LoopFinder::FindSmallInnermostLoopFromHeader(
|
||||
}
|
||||
// All uses are outside the loop, do nothing.
|
||||
break;
|
||||
// If {calls_are_large}, call nodes are considered to have unbounded size,
|
||||
// If unrolling, call nodes are considered to have unbounded size,
|
||||
// i.e. >max_size, with the exception of certain wasm builtins.
|
||||
case IrOpcode::kTailCall:
|
||||
case IrOpcode::kJSWasmCall:
|
||||
case IrOpcode::kJSCall:
|
||||
if (calls_are_large) return nullptr;
|
||||
if (purpose == Purpose::kLoopUnrolling) return nullptr;
|
||||
ENQUEUE_USES(use, true)
|
||||
break;
|
||||
case IrOpcode::kCall: {
|
||||
if (!calls_are_large) {
|
||||
if (purpose == Purpose::kLoopPeeling) {
|
||||
ENQUEUE_USES(use, true);
|
||||
break;
|
||||
}
|
||||
@ -679,7 +679,7 @@ ZoneUnorderedSet<Node*>* LoopFinder::FindSmallInnermostLoopFromHeader(
|
||||
// Only peel functions containing instructions for which loop peeling is known
|
||||
// to be useful. TODO(7748): Add more instructions to get more benefits out of
|
||||
// loop peeling.
|
||||
if (!has_instruction_worth_peeling) {
|
||||
if (purpose == Purpose::kLoopPeeling && !has_instruction_worth_peeling) {
|
||||
return nullptr;
|
||||
}
|
||||
return visited;
|
||||
|
@ -181,6 +181,8 @@ class V8_EXPORT_PRIVATE LoopFinder {
|
||||
static bool HasMarkedExits(LoopTree* loop_tree, const LoopTree::Loop* loop);
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
enum class Purpose { kLoopPeeling, kLoopUnrolling };
|
||||
|
||||
// Find all nodes in the loop headed by {loop_header} if it contains no nested
|
||||
// loops.
|
||||
// Assumption: *if* this loop has no nested loops, all exits from the loop are
|
||||
@ -192,7 +194,7 @@ class V8_EXPORT_PRIVATE LoopFinder {
|
||||
// 3) a nested loop is found in the loop.
|
||||
static ZoneUnorderedSet<Node*>* FindSmallInnermostLoopFromHeader(
|
||||
Node* loop_header, AllNodes& all_nodes, Zone* zone, size_t max_size,
|
||||
bool calls_are_large);
|
||||
Purpose purpose);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -1733,7 +1733,8 @@ struct WasmLoopUnrollingPhase {
|
||||
loop_info.header, all_nodes, temp_zone,
|
||||
// Only discover the loop until its size is the maximum unrolled
|
||||
// size for its depth.
|
||||
maximum_unrollable_size(loop_info.nesting_depth), true);
|
||||
maximum_unrollable_size(loop_info.nesting_depth),
|
||||
LoopFinder::Purpose::kLoopUnrolling);
|
||||
if (loop == nullptr) continue;
|
||||
UnrollLoop(loop_info.header, loop, loop_info.nesting_depth, data->graph(),
|
||||
data->common(), temp_zone, data->source_positions(),
|
||||
@ -1755,7 +1756,8 @@ struct WasmLoopPeelingPhase {
|
||||
ZoneUnorderedSet<Node*>* loop =
|
||||
LoopFinder::FindSmallInnermostLoopFromHeader(
|
||||
loop_info.header, all_nodes, temp_zone,
|
||||
v8_flags.wasm_loop_peeling_max_size, false);
|
||||
v8_flags.wasm_loop_peeling_max_size,
|
||||
LoopFinder::Purpose::kLoopPeeling);
|
||||
if (loop == nullptr) continue;
|
||||
PeelWasmLoop(loop_info.header, loop, data->graph(), data->common(),
|
||||
temp_zone, data->source_positions(), data->node_origins());
|
||||
|
Loading…
Reference in New Issue
Block a user