|
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