91 #define DEBUG_TYPE "load-store-vectorizer" 93 STATISTIC(NumVectorInstructions,
"Number of vector accesses generated");
94 STATISTIC(NumScalarsVectorized,
"Number of scalar accesses vectorized");
108 using ChainID =
const Value *;
124 :
F(F), AA(AA), DT(DT), SE(SE), TTI(TTI),
130 unsigned getPointerAddressSpace(
Value *
I);
151 bool areConsecutivePointers(
Value *PtrA,
Value *PtrB,
const APInt &PtrDelta,
152 unsigned Depth = 0)
const;
153 bool lookThroughComplexAddresses(
Value *PtrA,
Value *PtrB,
APInt PtrDelta,
154 unsigned Depth)
const;
155 bool lookThroughSelects(
Value *PtrA,
Value *PtrB,
const APInt &PtrDelta,
156 unsigned Depth)
const;
163 std::pair<BasicBlock::iterator, BasicBlock::iterator>
185 std::pair<InstrListMap, InstrListMap> collectInstructions(
BasicBlock *BB);
189 bool vectorizeChains(InstrListMap &Map);
205 bool accessIsMisaligned(
unsigned SzInBytes,
unsigned AddressSpace,
209 class LoadStoreVectorizerLegacyPass :
public FunctionPass {
220 return "GPU Load and Store Vectorizer";
237 "Vectorize load and Store instructions",
false,
false)
247 return new LoadStoreVectorizerLegacyPass();
255 AliasAnalysis &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
256 DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
257 ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
259 getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
261 Vectorizer V(F, AA, DT, SE, TTI);
275 Vectorizer V(F, AA, DT, SE, TTI);
276 bool Changed = V.run();
290 bool Vectorizer::run() {
291 bool Changed =
false;
295 InstrListMap LoadRefs, StoreRefs;
296 std::tie(LoadRefs, StoreRefs) = collectInstructions(BB);
297 Changed |= vectorizeChains(LoadRefs);
298 Changed |= vectorizeChains(StoreRefs);
304 unsigned Vectorizer::getPointerAddressSpace(
Value *
I) {
305 if (
LoadInst *L = dyn_cast<LoadInst>(I))
306 return L->getPointerAddressSpace();
307 if (
StoreInst *S = dyn_cast<StoreInst>(I))
308 return S->getPointerAddressSpace();
316 unsigned ASA = getPointerAddressSpace(A);
317 unsigned ASB = getPointerAddressSpace(B);
320 if (!PtrA || !PtrB || (ASA != ASB))
328 DL.getTypeStoreSize(PtrATy) != DL.getTypeStoreSize(PtrBTy) ||
333 unsigned PtrBitWidth = DL.getPointerSizeInBits(ASA);
334 APInt Size(PtrBitWidth, DL.getTypeStoreSize(PtrATy));
336 return areConsecutivePointers(PtrA, PtrB,
Size);
339 bool Vectorizer::areConsecutivePointers(
Value *PtrA,
Value *PtrB,
340 const APInt &PtrDelta,
341 unsigned Depth)
const {
342 unsigned PtrBitWidth = DL.getPointerTypeSizeInBits(PtrA->
getType());
343 APInt OffsetA(PtrBitWidth, 0);
344 APInt OffsetB(PtrBitWidth, 0);
348 APInt OffsetDelta = OffsetB - OffsetA;
353 return OffsetDelta == PtrDelta;
357 APInt BaseDelta = PtrDelta - OffsetDelta;
360 const SCEV *PtrSCEVA = SE.getSCEV(PtrA);
361 const SCEV *PtrSCEVB = SE.getSCEV(PtrB);
362 const SCEV *
C = SE.getConstant(BaseDelta);
363 const SCEV *
X = SE.getAddExpr(PtrSCEVA, C);
371 const SCEV *Dist = SE.getMinusSCEV(PtrSCEVB, PtrSCEVA);
378 return lookThroughComplexAddresses(PtrA, PtrB, BaseDelta, Depth);
381 bool Vectorizer::lookThroughComplexAddresses(
Value *PtrA,
Value *PtrB,
383 unsigned Depth)
const {
387 return lookThroughSelects(PtrA, PtrB, PtrDelta, Depth);
391 if (GEPA->getNumOperands() != GEPB->getNumOperands() ||
392 GEPA->getPointerOperand() != GEPB->getPointerOperand())
396 for (
unsigned I = 0,
E = GEPA->getNumIndices() - 1; I <
E; ++
I) {
405 if (!OpA || !OpB || OpA->
getOpcode() != OpB->getOpcode() ||
406 OpA->
getType() != OpB->getType())
416 if (PtrDelta.
urem(Stride) != 0)
422 if (!isa<SExtInst>(OpA) && !isa<ZExtInst>(OpA))
425 bool Signed = isa<SExtInst>(OpA);
430 if (!OpB || ValA->getType() != OpB->getType())
438 isa<ConstantInt>(OpB->getOperand(1)) &&
439 IdxDiff.
sle(cast<ConstantInt>(OpB->getOperand(1))->getSExtValue())) {
441 Safe = cast<BinaryOperator>(OpB)->hasNoSignedWrap();
443 Safe = cast<BinaryOperator>(OpB)->hasNoUnsignedWrap();
446 unsigned BitWidth = ValA->getType()->getScalarSizeInBits();
460 BitsAllowedToBeSet.
clearBit(BitWidth - 1);
461 if (BitsAllowedToBeSet.
ult(IdxDiff))
465 const SCEV *OffsetSCEVA = SE.getSCEV(ValA);
466 const SCEV *OffsetSCEVB = SE.getSCEV(OpB);
467 const SCEV *
C = SE.getConstant(IdxDiff.
trunc(BitWidth));
468 const SCEV *
X = SE.getAddExpr(OffsetSCEVA, C);
469 return X == OffsetSCEVB;
472 bool Vectorizer::lookThroughSelects(
Value *PtrA,
Value *PtrB,
473 const APInt &PtrDelta,
474 unsigned Depth)
const {
478 if (
auto *SelectA = dyn_cast<SelectInst>(PtrA)) {
479 if (
auto *SelectB = dyn_cast<SelectInst>(PtrB)) {
480 return SelectA->getCondition() == SelectB->getCondition() &&
481 areConsecutivePointers(SelectA->getTrueValue(),
482 SelectB->getTrueValue(), PtrDelta,
Depth) &&
483 areConsecutivePointers(SelectA->getFalseValue(),
484 SelectB->getFalseValue(), PtrDelta,
Depth);
496 while (!Worklist.
empty()) {
499 for (
int i = 0; i < NumOperands; i++) {
501 if (!IM || IM->
getOpcode() == Instruction::PHI)
509 if (!OBB.dominates(IM, I)) {
510 InstructionsToMove.insert(IM);
519 if (!InstructionsToMove.count(&*BBI))
528 std::pair<BasicBlock::iterator, BasicBlock::iterator>
535 unsigned NumFound = 0;
544 if (NumFound == Chain.
size()) {
551 return std::make_pair(FirstInstr, ++LastInstr);
558 assert(PtrOperand &&
"Instruction must have a pointer operand.");
572 unsigned ElementSizeBits) {
573 unsigned ElementSizeBytes = ElementSizeBits / 8;
574 unsigned SizeBytes = ElementSizeBytes * Chain.
size();
575 unsigned NumLeft = (SizeBytes - (SizeBytes % 4)) / ElementSizeBytes;
576 if (NumLeft == Chain.
size()) {
577 if ((NumLeft & 1) == 0)
581 }
else if (NumLeft == 0)
583 return std::make_pair(Chain.
slice(0, NumLeft), Chain.
slice(NumLeft));
592 bool IsLoadChain = isa<LoadInst>(Chain[0]);
596 assert(isa<LoadInst>(I) &&
597 "All elements of Chain must be loads, or all must be stores.");
599 assert(isa<StoreInst>(I) &&
600 "All elements of Chain must be loads, or all must be stores.");
605 if (isa<LoadInst>(I) || isa<StoreInst>(
I)) {
610 }
else if (isa<IntrinsicInst>(&I) &&
615 LLVM_DEBUG(
dbgs() <<
"LSV: Found may-write/throw operation: " << I
619 LLVM_DEBUG(
dbgs() <<
"LSV: Found may-read/write/throw operation: " << I
628 unsigned ChainInstrIdx = 0;
631 for (
unsigned E = ChainInstrs.
size(); ChainInstrIdx <
E; ++ChainInstrIdx) {
632 Instruction *ChainInstr = ChainInstrs[ChainInstrIdx];
636 if (BarrierMemoryInstr && OBB.
dominates(BarrierMemoryInstr, ChainInstr))
643 if (BarrierMemoryInstr && OBB.
dominates(BarrierMemoryInstr, MemInstr))
648 if (MemLoad && ChainLoad)
653 auto IsInvariantLoad = [](
const LoadInst *LI) ->
bool {
661 if (isa<StoreInst>(MemInstr) && ChainLoad &&
662 (IsInvariantLoad(ChainLoad) || OBB.
dominates(ChainLoad, MemInstr)))
666 if (MemLoad && isa<StoreInst>(ChainInstr) &&
667 (IsInvariantLoad(MemLoad) || OBB.
dominates(MemLoad, ChainInstr)))
673 dbgs() <<
"LSV: Found alias:\n" 674 " Aliasing instruction and pointer:\n" 675 <<
" " << *MemInstr <<
'\n' 677 <<
" Aliased instruction and pointer:\n" 678 <<
" " << *ChainInstr <<
'\n' 683 BarrierMemoryInstr = MemInstr;
691 if (IsLoadChain && BarrierMemoryInstr) {
703 ChainInstrs.
begin(), ChainInstrs.
begin() + ChainInstrIdx);
704 unsigned ChainIdx = 0;
705 for (
unsigned ChainLen = Chain.
size(); ChainIdx < ChainLen; ++ChainIdx) {
706 if (!VectorizableChainInstrs.count(Chain[ChainIdx]))
709 return Chain.
slice(0, ChainIdx);
714 if (
const auto *Sel = dyn_cast<SelectInst>(ObjPtr)) {
721 return Sel->getCondition();
726 std::pair<InstrListMap, InstrListMap>
727 Vectorizer::collectInstructions(
BasicBlock *BB) {
728 InstrListMap LoadRefs;
729 InstrListMap StoreRefs;
735 if (
LoadInst *LI = dyn_cast<LoadInst>(&I)) {
740 if (!TTI.isLegalToVectorizeLoad(LI))
743 Type *Ty = LI->getType();
749 unsigned TySize = DL.getTypeSizeInBits(Ty);
750 if ((TySize % 8) != 0)
760 Value *Ptr = LI->getPointerOperand();
762 unsigned VecRegSize = TTI.getLoadStoreVecRegBitWidth(AS);
764 unsigned VF = VecRegSize / TySize;
768 if (TySize > VecRegSize / 2 ||
769 (VecTy && TTI.getLoadVectorFactor(VF, TySize, TySize / 8, VecTy) == 0))
775 return EEI && isa<ConstantInt>(EEI->
getOperand(1));
781 LoadRefs[
ID].push_back(LI);
782 }
else if (
StoreInst *
SI = dyn_cast<StoreInst>(&I)) {
787 if (!TTI.isLegalToVectorizeStore(
SI))
790 Type *Ty =
SI->getValueOperand()->getType();
803 unsigned TySize = DL.getTypeSizeInBits(Ty);
804 if ((TySize % 8) != 0)
807 Value *Ptr =
SI->getPointerOperand();
809 unsigned VecRegSize = TTI.getLoadStoreVecRegBitWidth(AS);
811 unsigned VF = VecRegSize / TySize;
815 if (TySize > VecRegSize / 2 ||
816 (VecTy && TTI.getStoreVectorFactor(VF, TySize, TySize / 8, VecTy) == 0))
821 return EEI && isa<ConstantInt>(EEI->
getOperand(1));
827 StoreRefs[
ID].push_back(
SI);
831 return {LoadRefs, StoreRefs};
834 bool Vectorizer::vectorizeChains(InstrListMap &Map) {
835 bool Changed =
false;
837 for (
const std::pair<ChainID, InstrList> &Chain : Map) {
838 unsigned Size = Chain.second.
size();
842 LLVM_DEBUG(
dbgs() <<
"LSV: Analyzing a chain of length " << Size <<
".\n");
845 for (
unsigned CI = 0, CE = Size; CI < CE; CI += 64) {
846 unsigned Len = std::min<unsigned>(CE - CI, 64);
848 Changed |= vectorizeInstructions(Chunk);
857 <<
" instructions.\n");
859 int ConsecutiveChain[64];
863 for (
int i = 0, e = Instrs.
size(); i < e; ++i) {
864 ConsecutiveChain[i] = -1;
865 for (
int j = e - 1; j >= 0; --j) {
870 if (ConsecutiveChain[i] != -1) {
871 int CurDistance =
std::abs(ConsecutiveChain[i] - i);
872 int NewDistance =
std::abs(ConsecutiveChain[i] - j);
873 if (j < i || NewDistance > CurDistance)
879 ConsecutiveChain[i] = j;
884 bool Changed =
false;
887 for (
int Head : Heads) {
888 if (InstructionsProcessed.
count(Instrs[Head]))
890 bool LongerChainExists =
false;
891 for (
unsigned TIt = 0; TIt < Tails.size(); TIt++)
892 if (Head == Tails[TIt] &&
893 !InstructionsProcessed.
count(Instrs[Heads[TIt]])) {
894 LongerChainExists =
true;
897 if (LongerChainExists)
905 if (InstructionsProcessed.
count(Instrs[I]))
909 I = ConsecutiveChain[
I];
912 bool Vectorized =
false;
913 if (isa<LoadInst>(*Operands.
begin()))
914 Vectorized = vectorizeLoadChain(Operands, &InstructionsProcessed);
916 Vectorized = vectorizeStoreChain(Operands, &InstructionsProcessed);
918 Changed |= Vectorized;
924 bool Vectorizer::vectorizeStoreChain(
927 StoreInst *S0 = cast<StoreInst>(Chain[0]);
932 StoreTy = cast<StoreInst>(
I)->getValueOperand()->getType();
933 if (StoreTy->isIntOrIntVectorTy())
936 if (StoreTy->isPtrOrPtrVectorTy()) {
938 DL.getTypeSizeInBits(StoreTy));
943 unsigned Sz = DL.getTypeSizeInBits(StoreTy);
945 unsigned VecRegSize = TTI.getLoadStoreVecRegBitWidth(AS);
946 unsigned VF = VecRegSize / Sz;
947 unsigned ChainSize = Chain.size();
951 InstructionsProcessed->
insert(Chain.begin(), Chain.end());
956 if (NewChain.
empty()) {
958 InstructionsProcessed->
insert(Chain.begin(), Chain.end());
961 if (NewChain.
size() == 1) {
969 ChainSize = Chain.size();
973 unsigned EltSzInBytes = Sz / 8;
974 unsigned SzInBytes = EltSzInBytes * ChainSize;
986 unsigned TargetVF = TTI.getStoreVectorFactor(VF, Sz, SzInBytes, VecTy);
987 if (ChainSize > VF || (VF != TargetVF && TargetVF < ChainSize)) {
988 LLVM_DEBUG(
dbgs() <<
"LSV: Chain doesn't match with the vector factor." 989 " Creating two separate arrays.\n");
990 return vectorizeStoreChain(Chain.slice(0, TargetVF),
991 InstructionsProcessed) |
992 vectorizeStoreChain(Chain.slice(TargetVF), InstructionsProcessed);
996 dbgs() <<
"LSV: Stores to vectorize:\n";
998 dbgs() <<
" " << *I <<
"\n";
1003 InstructionsProcessed->
insert(Chain.begin(), Chain.end());
1006 if (accessIsMisaligned(SzInBytes, AS, Alignment)) {
1008 auto Chains = splitOddVectorElts(Chain, Sz);
1009 return vectorizeStoreChain(Chains.first, InstructionsProcessed) |
1010 vectorizeStoreChain(Chains.second, InstructionsProcessed);
1015 DL, S0,
nullptr, &DT);
1017 Alignment = NewAlign;
1020 if (!TTI.isLegalToVectorizeStoreChain(SzInBytes, Alignment, AS)) {
1021 auto Chains = splitOddVectorElts(Chain, Sz);
1022 return vectorizeStoreChain(Chains.first, InstructionsProcessed) |
1023 vectorizeStoreChain(Chains.second, InstructionsProcessed);
1027 std::tie(First, Last) = getBoundaryInstrs(Chain);
1028 Builder.SetInsertPoint(&*Last);
1034 for (
unsigned I = 0,
E = Chain.size(); I !=
E; ++
I) {
1037 unsigned NewIdx = J + I * VecWidth;
1039 Builder.getInt32(J));
1041 Extract = Builder.CreateBitCast(Extract, StoreTy->getScalarType());
1044 Builder.CreateInsertElement(Vec, Extract, Builder.getInt32(NewIdx));
1049 for (
unsigned I = 0,
E = Chain.size(); I !=
E; ++
I) {
1052 if (Extract->getType() != StoreTy->getScalarType())
1054 Builder.CreateBitOrPointerCast(Extract, StoreTy->getScalarType());
1057 Builder.CreateInsertElement(Vec, Extract, Builder.getInt32(I));
1068 eraseInstructions(Chain);
1069 ++NumVectorInstructions;
1070 NumScalarsVectorized += Chain.size();
1074 bool Vectorizer::vectorizeLoadChain(
1077 LoadInst *L0 = cast<LoadInst>(Chain[0]);
1081 for (
const auto &V : Chain) {
1082 LoadTy = cast<LoadInst>(V)->
getType();
1083 if (LoadTy->isIntOrIntVectorTy())
1086 if (LoadTy->isPtrOrPtrVectorTy()) {
1088 DL.getTypeSizeInBits(LoadTy));
1093 unsigned Sz = DL.getTypeSizeInBits(LoadTy);
1095 unsigned VecRegSize = TTI.getLoadStoreVecRegBitWidth(AS);
1096 unsigned VF = VecRegSize / Sz;
1097 unsigned ChainSize = Chain.size();
1101 InstructionsProcessed->
insert(Chain.begin(), Chain.end());
1106 if (NewChain.
empty()) {
1108 InstructionsProcessed->
insert(Chain.begin(), Chain.end());
1111 if (NewChain.
size() == 1) {
1119 ChainSize = Chain.size();
1123 unsigned EltSzInBytes = Sz / 8;
1124 unsigned SzInBytes = EltSzInBytes * ChainSize;
1135 unsigned TargetVF = TTI.getLoadVectorFactor(VF, Sz, SzInBytes, VecTy);
1136 if (ChainSize > VF || (VF != TargetVF && TargetVF < ChainSize)) {
1137 LLVM_DEBUG(
dbgs() <<
"LSV: Chain doesn't match with the vector factor." 1138 " Creating two separate arrays.\n");
1139 return vectorizeLoadChain(Chain.slice(0, TargetVF), InstructionsProcessed) |
1140 vectorizeLoadChain(Chain.slice(TargetVF), InstructionsProcessed);
1145 InstructionsProcessed->
insert(Chain.begin(), Chain.end());
1148 if (accessIsMisaligned(SzInBytes, AS, Alignment)) {
1150 auto Chains = splitOddVectorElts(Chain, Sz);
1151 return vectorizeLoadChain(Chains.first, InstructionsProcessed) |
1152 vectorizeLoadChain(Chains.second, InstructionsProcessed);
1157 DL, L0,
nullptr, &DT);
1159 Alignment = NewAlign;
1161 Alignment = NewAlign;
1164 if (!TTI.isLegalToVectorizeLoadChain(SzInBytes, Alignment, AS)) {
1165 auto Chains = splitOddVectorElts(Chain, Sz);
1166 return vectorizeLoadChain(Chains.first, InstructionsProcessed) |
1167 vectorizeLoadChain(Chains.second, InstructionsProcessed);
1171 dbgs() <<
"LSV: Loads to vectorize:\n";
1180 std::tie(First, Last) = getBoundaryInstrs(Chain);
1181 Builder.SetInsertPoint(&*First);
1185 LoadInst *LI = Builder.CreateAlignedLoad(Bitcast, Alignment);
1192 for (
unsigned I = 0,
E = Chain.size(); I !=
E; ++
I) {
1193 for (
auto Use : Chain[I]->
users()) {
1197 unsigned Idx = cast<ConstantInt>(UI->
getOperand(1))->getZExtValue();
1198 unsigned NewIdx = Idx + I * VecWidth;
1199 Value *V = Builder.CreateExtractElement(LI, Builder.getInt32(NewIdx),
1202 V = Builder.CreateBitCast(V, UI->
getType());
1212 if (
Instruction *BitcastInst = dyn_cast<Instruction>(Bitcast))
1213 reorder(BitcastInst);
1215 for (
auto I : InstrsToErase)
1218 for (
unsigned I = 0,
E = Chain.size(); I !=
E; ++
I) {
1221 Builder.CreateExtractElement(LI, Builder.getInt32(I), CV->
getName());
1223 V = Builder.CreateBitOrPointerCast(V, CV->
getType());
1230 if (
Instruction *BitcastInst = dyn_cast<Instruction>(Bitcast))
1231 reorder(BitcastInst);
1234 eraseInstructions(Chain);
1236 ++NumVectorInstructions;
1237 NumScalarsVectorized += Chain.size();
1241 bool Vectorizer::accessIsMisaligned(
unsigned SzInBytes,
unsigned AddressSpace,
1242 unsigned Alignment) {
1243 if (Alignment % SzInBytes == 0)
1250 LLVM_DEBUG(
dbgs() <<
"LSV: Target said misaligned is allowed? " << Allows
1251 <<
" and fast? " << Fast <<
"\n";);
1252 return !Allows || !
Fast;
Legacy wrapper pass to provide the GlobalsAAResult object.
Pass interface - Implemented by all 'passes'.
const T & front() const
front - Get the first element.
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, OptimizationRemarkEmitter *ORE=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
Value * getValueOperand()
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A parsed version of the target data layout string in and methods for querying it. ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign, const DataLayout &DL, const Instruction *CxtI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr)
Try to ensure that the alignment of V is at least PrefAlign bytes.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
void push_back(const T &Elt)
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
Instruction * propagateMetadata(Instruction *I, ArrayRef< Value *> VL)
Specifically, let Kinds = [MD_tbaa, MD_alias_scope, MD_noalias, MD_fpmath, MD_nontemporal, MD_access_group].
The main scalar evolution driver.
APInt zext(unsigned width) const
Zero extend to a new width.
APInt udiv(const APInt &RHS) const
Unsigned division operation.
bool dominates(const Instruction *A, const Instruction *B)
Find out whether A dominates B, meaning whether A comes before B in BB.
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
Analysis pass providing the TargetTransformInfo.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
This class implements a map that also provides access to all stored values in a deterministic order...
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
APInt trunc(unsigned width) const
Truncate to new width.
STATISTIC(NumFunctions, "Total number of functions")
Analysis pass which computes a DominatorTree.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
An instruction for reading from memory.
bool isVectorTy() const
True if this is an instance of VectorType.
bool sle(const APInt &RHS) const
Signed less or equal comparison.
unsigned getBitWidth() const
Return the number of bits in the APInt.
void dump() const
Support for debugging, callable in GDB: V->dump()
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static uint32_t getAlignment(const MCSectionCOFF &Sec)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Type * getPointerElementType() const
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
LLVMContext & getContext() const
Get the global data context.
APInt zextOrSelf(unsigned width) const
Zero extend or truncate to width.
A Use represents the edge between a Value definition and its users.
LLVMContext & getContext() const
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This file contains the simple types necessary to represent the attributes associated with functions a...
uint64_t getNumElements() const
This file implements a class to represent arbitrary precision integral constant values and operations...
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
Fast - This calling convention attempts to make calls as fast as possible (e.g.
Type * getType() const
All values are typed, get the type of this value.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
static bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Value * getLoadStorePointerOperand(Value *V)
A helper function that returns the pointer operand of a load or store instruction.
Pass * createLoadStoreVectorizerPass()
Create a legacy pass manager instance of the LoadStoreVectorizer pass.
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Value * getOperand(unsigned i) const
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
bool isConsecutiveAccess(Value *A, Value *B, const DataLayout &DL, ScalarEvolution &SE, bool CheckType=true)
Returns true if the memory operations A and B are consecutive.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
bool isNegative() const
Determine sign of this APInt.
static bool runOnFunction(Function &F, bool PostInlining)
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
APInt urem(const APInt &RHS) const
Unsigned remainder operation.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
static const unsigned StackAdjustedAlignment
bool ult(const APInt &RHS) const
Unsigned less than comparison.
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
This file contains the declarations for the subclasses of Constant, which represent the different fla...
A manager for alias analyses.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool mayThrow() const
Return true if this instruction may throw an exception.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Value * getPointerOperand()
iterator_range< po_iterator< T > > post_order(const T &G)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
self_iterator getIterator()
Type * getIndexedType() const
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static wasm::ValType getType(const TargetRegisterClass *RC)
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
static unsigned getIntrinsicID(const SDNode *N)
Legacy wrapper pass to provide the SCEVAAResult object.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
LLVM_NODISCARD T pop_back_val()
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
void negate()
Negate this APInt in place.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Class to represent vector types.
const Value * stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const
Accumulate offsets from stripInBoundsConstantOffsets().
Class for arbitrary precision integers.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array...
Represents analyses that only rely on functions' control flow.
void removeFromParent()
This method unlinks 'this' from the containing basic block, but does not delete it.
Analysis pass that exposes the ScalarEvolution for a function.
unsigned getAlignment() const
Return the alignment of the access that is being performed.
This class represents an analyzed expression in the program.
static ChainID getChainID(const Value *Ptr, const DataLayout &DL)
Value * getOperand() const
LLVM_NODISCARD bool empty() const
This file provides utility analysis objects describing memory locations.
void preserveSet()
Mark an analysis set as preserved.
StringRef getName() const
Return a constant reference to the value's name.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getAlignment() const
Return the alignment of the access that is being performed.
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
INITIALIZE_PASS_BEGIN(LoadStoreVectorizerLegacyPass, DEBUG_TYPE, "Vectorize load and Store instructions", false, false) INITIALIZE_PASS_END(LoadStoreVectorizerLegacyPass
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
static VectorType * get(Type *ElementType, unsigned NumElements)
This static method is the primary way to construct an VectorType.
static const Function * getParent(const Value *V)
void initializeLoadStoreVectorizerLegacyPassPass(PassRegistry &)
StringRef - Represent a constant reference to a string, i.e.
inst_range instructions(Function *F)
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
Value * getPointerOperand()
bool empty() const
empty - Check if the array is empty.
const BasicBlock * getParent() const
gep_type_iterator gep_type_begin(const User *GEP)
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.