|
6 | 6 | // |
7 | 7 | //===----------------------------------------------------------------------===// |
8 | 8 | // |
9 | | -// This pass implements IR expansion for vector predication intrinsics, allowing |
| 9 | +// This file implements IR expansion for vector predication intrinsics, allowing |
10 | 10 | // targets to enable vector predication until just before codegen. |
11 | 11 | // |
12 | 12 | //===----------------------------------------------------------------------===// |
|
16 | 16 | #include "llvm/Analysis/TargetTransformInfo.h" |
17 | 17 | #include "llvm/Analysis/ValueTracking.h" |
18 | 18 | #include "llvm/Analysis/VectorUtils.h" |
19 | | -#include "llvm/CodeGen/Passes.h" |
20 | 19 | #include "llvm/IR/Constants.h" |
21 | 20 | #include "llvm/IR/Function.h" |
22 | 21 | #include "llvm/IR/IRBuilder.h" |
23 | 22 | #include "llvm/IR/InstIterator.h" |
24 | 23 | #include "llvm/IR/Instructions.h" |
25 | 24 | #include "llvm/IR/IntrinsicInst.h" |
26 | 25 | #include "llvm/IR/Intrinsics.h" |
27 | | -#include "llvm/InitializePasses.h" |
28 | | -#include "llvm/Pass.h" |
29 | 26 | #include "llvm/Support/CommandLine.h" |
30 | 27 | #include "llvm/Support/Compiler.h" |
31 | 28 | #include "llvm/Support/Debug.h" |
@@ -137,7 +134,6 @@ namespace { |
137 | 134 |
|
138 | 135 | // Expansion pass state at function scope. |
139 | 136 | struct CachingVPExpander { |
140 | | - Function &F; |
141 | 137 | const TargetTransformInfo &TTI; |
142 | 138 |
|
143 | 139 | /// \returns A (fixed length) vector with ascending integer indices |
@@ -207,10 +203,10 @@ struct CachingVPExpander { |
207 | 203 | bool UsingTTIOverrides; |
208 | 204 |
|
209 | 205 | public: |
210 | | - CachingVPExpander(Function &F, const TargetTransformInfo &TTI) |
211 | | - : F(F), TTI(TTI), UsingTTIOverrides(anyExpandVPOverridesSet()) {} |
| 206 | + CachingVPExpander(const TargetTransformInfo &TTI) |
| 207 | + : TTI(TTI), UsingTTIOverrides(anyExpandVPOverridesSet()) {} |
212 | 208 |
|
213 | | - bool expandVectorPredication(); |
| 209 | + bool expandVectorPredication(VPIntrinsic &VPI); |
214 | 210 | }; |
215 | 211 |
|
216 | 212 | //// CachingVPExpander { |
@@ -571,7 +567,7 @@ CachingVPExpander::expandPredicationInMemoryIntrinsic(IRBuilder<> &Builder, |
571 | 567 | VPIntrinsic &VPI) { |
572 | 568 | assert(VPI.canIgnoreVectorLengthParam()); |
573 | 569 |
|
574 | | - const auto &DL = F.getDataLayout(); |
| 570 | + const auto &DL = VPI.getDataLayout(); |
575 | 571 |
|
576 | 572 | Value *MaskParam = VPI.getMaskParam(); |
577 | 573 | Value *PtrParam = VPI.getMemoryPointerParam(); |
@@ -775,15 +771,6 @@ Value *CachingVPExpander::expandPredication(VPIntrinsic &VPI) { |
775 | 771 |
|
776 | 772 | //// } CachingVPExpander |
777 | 773 |
|
778 | | -struct TransformJob { |
779 | | - VPIntrinsic *PI; |
780 | | - TargetTransformInfo::VPLegalization Strategy; |
781 | | - TransformJob(VPIntrinsic *PI, TargetTransformInfo::VPLegalization InitStrat) |
782 | | - : PI(PI), Strategy(InitStrat) {} |
783 | | - |
784 | | - bool isDone() const { return Strategy.shouldDoNothing(); } |
785 | | -}; |
786 | | - |
787 | 774 | void sanitizeStrategy(VPIntrinsic &VPI, VPLegalization &LegalizeStrat) { |
788 | 775 | // Operations with speculatable lanes do not strictly need predication. |
789 | 776 | if (maySpeculateLanes(VPI)) { |
@@ -821,98 +808,43 @@ CachingVPExpander::getVPLegalizationStrategy(const VPIntrinsic &VPI) const { |
821 | 808 | } |
822 | 809 |
|
823 | 810 | /// Expand llvm.vp.* intrinsics as requested by \p TTI. |
824 | | -bool CachingVPExpander::expandVectorPredication() { |
825 | | - SmallVector<TransformJob, 16> Worklist; |
826 | | - |
827 | | - // Collect all VPIntrinsics that need expansion and determine their expansion |
828 | | - // strategy. |
829 | | - for (auto &I : instructions(F)) { |
830 | | - auto *VPI = dyn_cast<VPIntrinsic>(&I); |
831 | | - if (!VPI) |
832 | | - continue; |
833 | | - auto VPStrat = getVPLegalizationStrategy(*VPI); |
834 | | - sanitizeStrategy(*VPI, VPStrat); |
835 | | - if (!VPStrat.shouldDoNothing()) |
836 | | - Worklist.emplace_back(VPI, VPStrat); |
837 | | - } |
838 | | - if (Worklist.empty()) |
839 | | - return false; |
| 811 | +bool CachingVPExpander::expandVectorPredication(VPIntrinsic &VPI) { |
| 812 | + auto Strategy = getVPLegalizationStrategy(VPI); |
| 813 | + sanitizeStrategy(VPI, Strategy); |
840 | 814 |
|
841 | | - // Transform all VPIntrinsics on the worklist. |
842 | | - LLVM_DEBUG(dbgs() << "\n:::: Transforming " << Worklist.size() |
843 | | - << " instructions ::::\n"); |
844 | | - for (TransformJob Job : Worklist) { |
845 | | - // Transform the EVL parameter. |
846 | | - switch (Job.Strategy.EVLParamStrategy) { |
847 | | - case VPLegalization::Legal: |
848 | | - break; |
849 | | - case VPLegalization::Discard: |
850 | | - discardEVLParameter(*Job.PI); |
851 | | - break; |
852 | | - case VPLegalization::Convert: |
853 | | - if (foldEVLIntoMask(*Job.PI)) |
854 | | - ++NumFoldedVL; |
855 | | - break; |
856 | | - } |
857 | | - Job.Strategy.EVLParamStrategy = VPLegalization::Legal; |
| 815 | + // Transform the EVL parameter. |
| 816 | + switch (Strategy.EVLParamStrategy) { |
| 817 | + case VPLegalization::Legal: |
| 818 | + break; |
| 819 | + case VPLegalization::Discard: |
| 820 | + discardEVLParameter(VPI); |
| 821 | + break; |
| 822 | + case VPLegalization::Convert: |
| 823 | + if (foldEVLIntoMask(VPI)) |
| 824 | + ++NumFoldedVL; |
| 825 | + break; |
| 826 | + } |
858 | 827 |
|
859 | | - // Replace with a non-predicated operation. |
860 | | - switch (Job.Strategy.OpStrategy) { |
861 | | - case VPLegalization::Legal: |
862 | | - break; |
863 | | - case VPLegalization::Discard: |
864 | | - llvm_unreachable("Invalid strategy for operators."); |
865 | | - case VPLegalization::Convert: |
866 | | - expandPredication(*Job.PI); |
| 828 | + // Replace with a non-predicated operation. |
| 829 | + switch (Strategy.OpStrategy) { |
| 830 | + case VPLegalization::Legal: |
| 831 | + break; |
| 832 | + case VPLegalization::Discard: |
| 833 | + llvm_unreachable("Invalid strategy for operators."); |
| 834 | + case VPLegalization::Convert: |
| 835 | + if (Value *V = expandPredication(VPI); V != &VPI) { |
867 | 836 | ++NumLoweredVPOps; |
868 | | - break; |
| 837 | + // Return true if and only if the intrinsic was actually removed. |
| 838 | + return true; |
869 | 839 | } |
870 | | - Job.Strategy.OpStrategy = VPLegalization::Legal; |
871 | | - |
872 | | - assert(Job.isDone() && "incomplete transformation"); |
| 840 | + break; |
873 | 841 | } |
874 | 842 |
|
875 | | - return true; |
| 843 | + return false; |
876 | 844 | } |
877 | | -class ExpandVectorPredication : public FunctionPass { |
878 | | -public: |
879 | | - static char ID; |
880 | | - ExpandVectorPredication() : FunctionPass(ID) { |
881 | | - initializeExpandVectorPredicationPass(*PassRegistry::getPassRegistry()); |
882 | | - } |
883 | | - |
884 | | - bool runOnFunction(Function &F) override { |
885 | | - const auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); |
886 | | - CachingVPExpander VPExpander(F, *TTI); |
887 | | - return VPExpander.expandVectorPredication(); |
888 | | - } |
889 | | - |
890 | | - void getAnalysisUsage(AnalysisUsage &AU) const override { |
891 | | - AU.addRequired<TargetTransformInfoWrapperPass>(); |
892 | | - AU.setPreservesCFG(); |
893 | | - } |
894 | | -}; |
895 | 845 | } // namespace |
896 | 846 |
|
897 | | -char ExpandVectorPredication::ID; |
898 | | -INITIALIZE_PASS_BEGIN(ExpandVectorPredication, "expandvp", |
899 | | - "Expand vector predication intrinsics", false, false) |
900 | | -INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) |
901 | | -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) |
902 | | -INITIALIZE_PASS_END(ExpandVectorPredication, "expandvp", |
903 | | - "Expand vector predication intrinsics", false, false) |
904 | | - |
905 | | -FunctionPass *llvm::createExpandVectorPredicationPass() { |
906 | | - return new ExpandVectorPredication(); |
907 | | -} |
908 | | - |
909 | | -PreservedAnalyses |
910 | | -ExpandVectorPredicationPass::run(Function &F, FunctionAnalysisManager &AM) { |
911 | | - const auto &TTI = AM.getResult<TargetIRAnalysis>(F); |
912 | | - CachingVPExpander VPExpander(F, TTI); |
913 | | - if (!VPExpander.expandVectorPredication()) |
914 | | - return PreservedAnalyses::all(); |
915 | | - PreservedAnalyses PA; |
916 | | - PA.preserveSet<CFGAnalyses>(); |
917 | | - return PA; |
| 847 | +bool llvm::expandVectorPredicationIntrinsic(VPIntrinsic &VPI, |
| 848 | + const TargetTransformInfo &TTI) { |
| 849 | + return CachingVPExpander(TTI).expandVectorPredication(VPI); |
918 | 850 | } |
0 commit comments