50 #define DEBUG_TYPE "interleaved-access"
53 "lower-interleaved-accesses",
54 cl::desc(
"Enable lowering interleaved accesses to intrinsics"),
74 const char *getPassName()
const override {
return "Interleaved Access Pass"; }
83 bool lowerInterleavedLoad(
LoadInst *LI,
94 "Lower interleaved memory accesses to target specific intrinsics",
98 return new InterleavedAccess(TM);
107 for (Index = 0; Index < Factor; Index++) {
112 for (; i < Mask.
size(); i++)
113 if (Mask[i] >= 0 && static_cast<unsigned>(Mask[i]) != Index + i * Factor)
116 if (i == Mask.
size())
134 for (Factor = 2; Factor <=
MaxFactor; Factor++)
148 unsigned NumElts = Mask.
size();
153 for (Factor = 2; Factor <=
MaxFactor; Factor++) {
154 if (NumElts % Factor)
157 unsigned NumSubElts = NumElts / Factor;
164 for (; i < NumElts; i++)
166 static_cast<unsigned>(Mask[i]) !=
167 (i % Factor) * NumSubElts + i / Factor)
178 bool InterleavedAccess::lowerInterleavedLoad(
188 if (!SVI || !isa<UndefValue>(SVI->
getOperand(1)))
194 if (Shuffles.
empty())
197 unsigned Factor, Index;
207 Type *VecTy = Shuffles[0]->getType();
211 for (
unsigned i = 1; i < Shuffles.
size(); i++) {
212 if (Shuffles[i]->
getType() != VecTy)
222 DEBUG(
dbgs() <<
"IA: Found an interleaved load: " << *LI <<
"\n");
225 if (!TLI->lowerInterleavedLoad(LI, Shuffles, Indices, Factor))
228 for (
auto SVI : Shuffles)
235 bool InterleavedAccess::lowerInterleavedStore(
249 DEBUG(
dbgs() <<
"IA: Found an interleaved store: " << *SI <<
"\n");
252 if (!TLI->lowerInterleavedStore(SI, SVI, Factor))
261 bool InterleavedAccess::runOnFunction(
Function &
F) {
267 TLI =
TM->getSubtargetImpl(F)->getTargetLowering();
268 MaxFactor = TLI->getMaxSupportedInterleaveFactor();
272 bool Changed =
false;
275 if (
LoadInst *LI = dyn_cast<LoadInst>(&
I))
276 Changed |= lowerInterleavedLoad(LI, DeadInsts);
279 Changed |= lowerInterleavedStore(SI, DeadInsts);
282 for (
auto I : DeadInsts)
283 I->eraseFromParent();
static bool isDeInterleaveMask(ArrayRef< int > Mask, unsigned &Factor, unsigned &Index)
Check if the mask is a DE-interleave mask for an interleaved load.
Value * getValueOperand()
static unsigned MaxFactor
void push_back(const T &Elt)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
ShuffleVectorInst - This instruction constructs a fixed permutation of two input vectors.
FunctionPass * createInterleavedAccessPass(const TargetMachine *TM)
InterleavedAccess Pass - This pass identifies and matches interleaved memory accesses to target speci...
LoadInst - an instruction for reading from memory.
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
StringRef getName() const
Return a constant reference to the value's name.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
StoreInst - an instruction for storing to memory.
size_t size() const
size - Get the array size.
initializer< Ty > init(const Ty &Val)
The instances of the Type class are immutable: once they are created, they are never changed...
static cl::opt< bool > LowerInterleavedAccesses("lower-interleaved-accesses", cl::desc("Enable lowering interleaved accesses to intrinsics"), cl::init(false), cl::Hidden)
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
INITIALIZE_TM_PASS(InterleavedAccess,"interleaved-access","Lower interleaved memory accesses to target specific intrinsics", false, false) FunctionPass *llvm
static void initializeInterleavedAccessPass(PassRegistry &)
static bool isReInterleaveMask(ArrayRef< int > Mask, unsigned &Factor)
Check if the mask is RE-interleave mask for an interleaved store.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
iterator_range< inst_iterator > inst_range(Function *F)
bool hasOneUse() const
Return true if there is exactly one user of this value.
user_iterator user_begin()
Primary interface to the complete machine description for the target machine.
bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static bool isDeInterleaveMaskOfFactor(ArrayRef< int > Mask, unsigned Factor, unsigned &Index)
Check if the mask is a DE-interleave mask of the given factor Factor like: <Index, Index+Factor, ..., Index+(NumElts-1)*Factor>
static void getShuffleMask(Constant *Mask, SmallVectorImpl< int > &Result)
getShuffleMask - Return the full mask for this instruction, where each element is the element number ...
This file describes how to lower LLVM code to machine code.