@@ -707,113 +707,6 @@ struct CFGNormalizationPass
707
707
}
708
708
};
709
709
710
- static void legalizeDefUse (IRGlobalValueWithCode* func)
711
- {
712
- auto dom = computeDominatorTree (func);
713
- for (auto block : func->getBlocks ())
714
- {
715
- for (auto inst : block->getModifiableChildren ())
716
- {
717
- // Inspect all uses of `inst` and find the common dominator of all use sites.
718
- IRBlock* commonDominator = block;
719
- for (auto use = inst->firstUse ; use; use = use->nextUse )
720
- {
721
- auto userBlock = as<IRBlock>(use->getUser ()->getParent ());
722
- if (!userBlock)
723
- continue ;
724
- while (commonDominator && !dom->dominates (commonDominator, userBlock))
725
- {
726
- commonDominator = dom->getImmediateDominator (commonDominator);
727
- }
728
- }
729
- SLANG_ASSERT (commonDominator);
730
-
731
- if (commonDominator == block)
732
- continue ;
733
-
734
- // If the common dominator is not `block`, it means we have detected
735
- // uses that is no longer dominated by the current definition, and need
736
- // to be fixed.
737
-
738
- // Normally, we can simply move the definition to the common dominator.
739
- // An exception is when the common dominator is the target block of a
740
- // loop. Note that after normalization, loops are in the form of:
741
- // ```
742
- // loop { if (condition) block; else break; }
743
- // ```
744
- // If we find ourselves needing to make the inst available right before
745
- // the `if`, it means we are seeing uses of the inst outside the loop.
746
- // In this case, we should insert a var/move the inst before the loop
747
- // instead of before the `if`. This situation can occur in the IR if
748
- // the original code is lowered from a `do-while` loop.
749
- for (auto use = commonDominator->firstUse ; use; use = use->nextUse )
750
- {
751
- if (auto loopUser = as<IRLoop>(use->getUser ()))
752
- {
753
- if (loopUser->getTargetBlock () == commonDominator)
754
- {
755
- bool shouldMoveToHeader = false ;
756
- // Check that the break-block dominates any of the uses are past the break
757
- // block
758
- for (auto _use = inst->firstUse ; _use; _use = _use->nextUse )
759
- {
760
- if (dom->dominates (
761
- loopUser->getBreakBlock (),
762
- _use->getUser ()->getParent ()))
763
- {
764
- shouldMoveToHeader = true ;
765
- break ;
766
- }
767
- }
768
-
769
- if (shouldMoveToHeader)
770
- commonDominator = as<IRBlock>(loopUser->getParent ());
771
- break ;
772
- }
773
- }
774
- }
775
- // Now we can legalize uses based on the type of `inst`.
776
- if (auto var = as<IRVar>(inst))
777
- {
778
- // If inst is an var, this is easy, we just move it to the
779
- // common dominator.
780
- var->insertBefore (commonDominator->getTerminator ());
781
- }
782
- else
783
- {
784
- // For all other insts, we need to create a local var for it,
785
- // and replace all uses with a load from the local var.
786
- IRBuilder builder (func);
787
- builder.setInsertBefore (commonDominator->getTerminator ());
788
- IRVar* tempVar = builder.emitVar (inst->getFullType ());
789
- auto defaultVal = builder.emitDefaultConstruct (inst->getFullType ());
790
- builder.emitStore (tempVar, defaultVal);
791
-
792
- builder.setInsertAfter (inst);
793
- builder.emitStore (tempVar, inst);
794
-
795
- traverseUses (
796
- inst,
797
- [&](IRUse* use)
798
- {
799
- auto userBlock = as<IRBlock>(use->getUser ()->getParent ());
800
- if (!userBlock)
801
- return ;
802
- // Only fix the use of the current definition of `inst` does not
803
- // dominate it.
804
- if (!dom->dominates (block, userBlock))
805
- {
806
- // Replace the use with a load of tempVar.
807
- builder.setInsertBefore (use->getUser ());
808
- auto load = builder.emitLoad (tempVar);
809
- builder.replaceOperand (use, load);
810
- }
811
- });
812
- }
813
- }
814
- }
815
- }
816
-
817
710
void normalizeCFG (
818
711
IRModule* module,
819
712
IRGlobalValueWithCode* func,
0 commit comments