|
16 | 16 | #include "llvm/ADT/DenseMap.h"
|
17 | 17 | #include "llvm/ADT/STLExtras.h"
|
18 | 18 | #include "llvm/ADT/ScopeExit.h"
|
19 |
| -#include "llvm/ADT/SmallVector.h" |
20 | 19 | #include "llvm/ADT/Statistic.h"
|
21 | 20 | #include "llvm/Analysis/AssumptionCache.h"
|
22 | 21 | #include "llvm/Analysis/BasicAliasAnalysis.h"
|
|
30 | 29 | #include "llvm/IR/Dominators.h"
|
31 | 30 | #include "llvm/IR/Function.h"
|
32 | 31 | #include "llvm/IR/IRBuilder.h"
|
33 |
| -#include "llvm/IR/Instructions.h" |
34 | 32 | #include "llvm/IR/PatternMatch.h"
|
35 | 33 | #include "llvm/Support/CommandLine.h"
|
36 | 34 | #include "llvm/Transforms/Utils/Local.h"
|
37 | 35 | #include "llvm/Transforms/Utils/LoopUtils.h"
|
38 | 36 | #include <numeric>
|
39 |
| -#include <optional> |
40 | 37 | #include <queue>
|
41 | 38 | #include <set>
|
42 |
| -#include <tuple> |
43 | 39 |
|
44 | 40 | #define DEBUG_TYPE "vector-combine"
|
45 | 41 | #include "llvm/Transforms/Utils/InstructionWorklist.h"
|
@@ -141,7 +137,6 @@ class VectorCombine {
|
141 | 137 | bool foldSelectShuffle(Instruction &I, bool FromReduction = false);
|
142 | 138 | bool foldInterleaveIntrinsics(Instruction &I);
|
143 | 139 | bool shrinkType(Instruction &I);
|
144 |
| - bool shrinkLoadForShuffles(Instruction &I); |
145 | 140 |
|
146 | 141 | void replaceValue(Value &Old, Value &New) {
|
147 | 142 | LLVM_DEBUG(dbgs() << "VC: Replacing: " << Old << '\n');
|
@@ -3866,126 +3861,6 @@ bool VectorCombine::foldInterleaveIntrinsics(Instruction &I) {
|
3866 | 3861 | return true;
|
3867 | 3862 | }
|
3868 | 3863 |
|
3869 |
| -// Attempt to shrink loads that are only used by shufflevector instructions. |
3870 |
| -bool VectorCombine::shrinkLoadForShuffles(Instruction &I) { |
3871 |
| - auto *OldLoad = dyn_cast<LoadInst>(&I); |
3872 |
| - if (!OldLoad || !OldLoad->isSimple()) |
3873 |
| - return false; |
3874 |
| - |
3875 |
| - auto *OldLoadTy = dyn_cast<FixedVectorType>(OldLoad->getType()); |
3876 |
| - if (!OldLoadTy) |
3877 |
| - return false; |
3878 |
| - |
3879 |
| - unsigned const OldNumElements = OldLoadTy->getNumElements(); |
3880 |
| - |
3881 |
| - // Search all uses of load. If all uses are shufflevector instructions, and |
3882 |
| - // the second operands are all poison values, find the minimum and maximum |
3883 |
| - // indices of the vector elements referenced by all shuffle masks. |
3884 |
| - // Otherwise return `std::nullopt`. |
3885 |
| - using IndexRange = std::pair<int, int>; |
3886 |
| - auto GetIndexRangeInShuffles = [&]() -> std::optional<IndexRange> { |
3887 |
| - IndexRange OutputRange = IndexRange(OldNumElements, -1); |
3888 |
| - for (llvm::Use &Use : I.uses()) { |
3889 |
| - // Ensure all uses match the required pattern. |
3890 |
| - User *Shuffle = Use.getUser(); |
3891 |
| - ArrayRef<int> Mask; |
3892 |
| - |
3893 |
| - if (!match(Shuffle, |
3894 |
| - m_Shuffle(m_Specific(OldLoad), m_Undef(), m_Mask(Mask)))) |
3895 |
| - return std::nullopt; |
3896 |
| - |
3897 |
| - // Ignore shufflevector instructions that have no uses. |
3898 |
| - if (Shuffle->use_empty()) |
3899 |
| - continue; |
3900 |
| - |
3901 |
| - // Find the min and max indices used by the shufflevector instruction. |
3902 |
| - for (int Index : Mask) { |
3903 |
| - if (Index >= 0 && Index < static_cast<int>(OldNumElements)) { |
3904 |
| - OutputRange.first = std::min(Index, OutputRange.first); |
3905 |
| - OutputRange.second = std::max(Index, OutputRange.second); |
3906 |
| - } |
3907 |
| - } |
3908 |
| - } |
3909 |
| - |
3910 |
| - if (OutputRange.second < OutputRange.first) |
3911 |
| - return std::nullopt; |
3912 |
| - |
3913 |
| - return OutputRange; |
3914 |
| - }; |
3915 |
| - |
3916 |
| - // Get the range of vector elements used by shufflevector instructions. |
3917 |
| - if (std::optional<IndexRange> Indices = GetIndexRangeInShuffles()) { |
3918 |
| - unsigned const NewNumElements = Indices->second + 1u; |
3919 |
| - |
3920 |
| - // If the range of vector elements is smaller than the full load, attempt |
3921 |
| - // to create a smaller load. |
3922 |
| - if (NewNumElements < OldNumElements) { |
3923 |
| - IRBuilder Builder(&I); |
3924 |
| - Builder.SetCurrentDebugLocation(I.getDebugLoc()); |
3925 |
| - |
3926 |
| - // Calculate costs of old and new ops. |
3927 |
| - Type *ElemTy = OldLoadTy->getElementType(); |
3928 |
| - FixedVectorType *NewLoadTy = FixedVectorType::get(ElemTy, NewNumElements); |
3929 |
| - Value *PtrOp = OldLoad->getPointerOperand(); |
3930 |
| - |
3931 |
| - InstructionCost OldCost = TTI.getMemoryOpCost( |
3932 |
| - Instruction::Load, OldLoad->getType(), OldLoad->getAlign(), |
3933 |
| - OldLoad->getPointerAddressSpace(), CostKind); |
3934 |
| - InstructionCost NewCost = |
3935 |
| - TTI.getMemoryOpCost(Instruction::Load, NewLoadTy, OldLoad->getAlign(), |
3936 |
| - OldLoad->getPointerAddressSpace(), CostKind); |
3937 |
| - |
3938 |
| - using UseEntry = std::pair<ShuffleVectorInst *, std::vector<int>>; |
3939 |
| - SmallVector<UseEntry, 4u> NewUses; |
3940 |
| - |
3941 |
| - for (llvm::Use &Use : I.uses()) { |
3942 |
| - auto *Shuffle = cast<ShuffleVectorInst>(Use.getUser()); |
3943 |
| - ArrayRef<int> OldMask = Shuffle->getShuffleMask(); |
3944 |
| - |
3945 |
| - // Create entry for new use. |
3946 |
| - NewUses.push_back({Shuffle, OldMask}); |
3947 |
| - |
3948 |
| - // Update costs. |
3949 |
| - OldCost += |
3950 |
| - TTI.getShuffleCost(TTI::SK_PermuteSingleSrc, Shuffle->getType(), |
3951 |
| - OldLoadTy, OldMask, CostKind); |
3952 |
| - NewCost += |
3953 |
| - TTI.getShuffleCost(TTI::SK_PermuteSingleSrc, Shuffle->getType(), |
3954 |
| - NewLoadTy, OldMask, CostKind); |
3955 |
| - } |
3956 |
| - |
3957 |
| - LLVM_DEBUG( |
3958 |
| - dbgs() << "Found a load used only by shufflevector instructions: " |
3959 |
| - << I << "\n OldCost: " << OldCost |
3960 |
| - << " vs NewCost: " << NewCost << "\n"); |
3961 |
| - |
3962 |
| - if (OldCost < NewCost || !NewCost.isValid()) |
3963 |
| - return false; |
3964 |
| - |
3965 |
| - // Create new load of smaller vector. |
3966 |
| - auto *NewLoad = cast<LoadInst>( |
3967 |
| - Builder.CreateAlignedLoad(NewLoadTy, PtrOp, OldLoad->getAlign())); |
3968 |
| - NewLoad->copyMetadata(I); |
3969 |
| - |
3970 |
| - // Replace all uses. |
3971 |
| - for (UseEntry &Use : NewUses) { |
3972 |
| - ShuffleVectorInst *Shuffle = Use.first; |
3973 |
| - std::vector<int> &NewMask = Use.second; |
3974 |
| - |
3975 |
| - Builder.SetInsertPoint(Shuffle); |
3976 |
| - Builder.SetCurrentDebugLocation(Shuffle->getDebugLoc()); |
3977 |
| - Value *NewShuffle = Builder.CreateShuffleVector( |
3978 |
| - NewLoad, PoisonValue::get(NewLoadTy), NewMask); |
3979 |
| - |
3980 |
| - replaceValue(*Shuffle, *NewShuffle); |
3981 |
| - } |
3982 |
| - |
3983 |
| - return true; |
3984 |
| - } |
3985 |
| - } |
3986 |
| - return false; |
3987 |
| -} |
3988 |
| - |
3989 | 3864 | /// This is the entry point for all transforms. Pass manager differences are
|
3990 | 3865 | /// handled in the callers of this function.
|
3991 | 3866 | bool VectorCombine::run() {
|
@@ -4062,9 +3937,6 @@ bool VectorCombine::run() {
|
4062 | 3937 | MadeChange |= foldSelectShuffle(I);
|
4063 | 3938 | MadeChange |= foldShuffleToIdentity(I);
|
4064 | 3939 | break;
|
4065 |
| - case Instruction::Load: |
4066 |
| - MadeChange |= shrinkLoadForShuffles(I); |
4067 |
| - break; |
4068 | 3940 | case Instruction::BitCast:
|
4069 | 3941 | MadeChange |= foldBitcastShuffle(I);
|
4070 | 3942 | break;
|
|
0 commit comments