MCPcopy Create free account
hub / github.com/KhronosGroup/SPIRV-Tools / Process

Method Process

source/opt/loop_fission.cpp:455–519  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

453}
454
455Pass::Status LoopFissionPass::Process() {
456 bool changed = false;
457
458 for (Function& f : *context()->module()) {
459 // We collect all the inner most loops in the function and run the loop
460 // splitting util on each. The reason we do this is to allow us to iterate
461 // over each, as creating new loops will invalidate the loop iterator.
462 std::vector<Loop*> inner_most_loops{};
463 LoopDescriptor& loop_descriptor = *context()->GetLoopDescriptor(&f);
464 for (Loop& loop : loop_descriptor) {
465 if (!loop.HasChildren() && ShouldSplitLoop(loop, context())) {
466 inner_most_loops.push_back(&loop);
467 }
468 }
469
470 // List of new loops which meet the criteria to be split again.
471 std::vector<Loop*> new_loops_to_split{};
472
473 while (!inner_most_loops.empty()) {
474 for (Loop* loop : inner_most_loops) {
475 LoopFissionImpl impl{context(), loop};
476
477 // Group the instructions in the loop into two different sets of related
478 // instructions. If we can't group the instructions into the two sets
479 // then we can't split the loop any further.
480 if (!impl.GroupInstructionsByUseDef()) {
481 continue;
482 }
483
484 if (impl.CanPerformSplit()) {
485 Loop* second_loop = impl.SplitLoop();
486 if (!second_loop) {
487 return Status::Failure;
488 }
489 changed = true;
490 context()->InvalidateAnalysesExceptFor(
491 IRContext::kAnalysisLoopAnalysis);
492
493 // If the newly created loop meets the criteria to be split, split it
494 // again.
495 if (ShouldSplitLoop(*second_loop, context()))
496 new_loops_to_split.push_back(second_loop);
497
498 // If the original loop (now split) still meets the criteria to be
499 // split, split it again.
500 if (ShouldSplitLoop(*loop, context()))
501 new_loops_to_split.push_back(loop);
502 }
503 }
504
505 // If the split multiple times flag has been set add the new loops which
506 // meet the splitting criteria into the list of loops to be split on the
507 // next iteration.
508 if (split_multiple_times_) {
509 inner_most_loops = std::move(new_loops_to_split);
510 new_loops_to_split = {};
511 } else {
512 break;

Callers

nothing calls this directly

Calls 9

HasChildrenMethod · 0.80
CanPerformSplitMethod · 0.80
SplitLoopMethod · 0.80
moduleMethod · 0.45
GetLoopDescriptorMethod · 0.45
push_backMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected