28#define DEBUG_PREFIX_LOCAL DEBUG_PREFIX "LoadStoreVec: "
40 if (!Sched->trySchedule(Bndl))
46void LoadStoreVec::saveIR(
Region &R) {
49 CostBefore = SB.getAfterCost() - SB.getBeforeCost();
50 Rgn->getContext().save();
53bool LoadStoreVec::acceptOrRevert() {
58 <<
" (After=" << CostAfter <<
" Before=" << CostBefore
60 const VectorizeOptions &Opts =
61 Ctx->getLibraryOptions().get<VectorizeOptions>();
62 if (CostGain > Opts.sbvec_cost_threshold) {
74 Loads, A->getScalarEvolution(), *DL))
76 if (!canVectorize(Loads))
89 if (DestTy->isPointerTy())
90 assert(!DL->isNonIntegralAddressSpace(DestTy->getPointerAddressSpace()) &&
91 "DestTy has no fixed size");
92 Type *SrcTy =
C->getType();
97 if (!SrcTy->isIntegerTy()) {
100 : ConstantExpr::getBitCast(
C, IntTy);
102 if (DestTy->isIntegerTy())
105 : ConstantExpr::getBitCast(AsInt, DestTy);
111 auto *LaneTy = VecTy->getScalarType();
117 "Chain contains a constant which cannot be converted or split");
121 SmallVector<Constant *, 4> ConstantElements;
122 for (Constant *COp : Constants) {
127 for (
Value *Elm : AggrCOp->operands())
131 ConstantElements.push_back(SeqCOp->getElementAsConstant(ElmIdx));
133 auto *ZeroElm =
Zero->getSequentialElement();
134 for ([[maybe_unused]]
auto Cnt :
136 ConstantElements.push_back(ZeroElm);
139 for ([[maybe_unused]]
auto Cnt :
143 ConstantElements.push_back(Elm);
146 for ([[maybe_unused]]
auto Cnt :
150 ConstantElements.push_back(Elm);
154 for ([[maybe_unused]]
auto Cnt :
158 ConstantElements.push_back(Elm);
163 ConstantElements.push_back(COp);
174 LaneTyConstants.reserve(ConstantElements.size());
175 for (Constant *
C : ConstantElements) {
177 if (Bits == LaneBits) {
178 Constant *Lane = getEquivalentConstantWithType(
C, LaneTy);
181 LaneTyConstants.push_back(Lane);
182 }
else if (Bits > LaneBits) {
191 Val = CI->getValue();
193 Val = CFP->getValue().bitcastToAPInt();
196 unsigned NumSlices =
Bits / LaneBits;
198 unsigned EndianAwareSlice =
199 DL->isLittleEndian() ? SliceIdx : NumSlices - 1 - SliceIdx;
203 *Ctx, Val.extractBits(LaneBits, EndianAwareSlice * LaneBits));
204 Constant *SliceC = getEquivalentConstantWithType(SliceCInt, LaneTy);
205 if (SliceC ==
nullptr)
207 LaneTyConstants.push_back(SliceC);
218 Stores, A->getScalarEvolution(), *DL))
220 if (!canVectorize(Stores))
224 for (
auto *
I : Stores) {
237 if (LI->getParent() != BB)
239 if (LI->hasNUsesOrMore(2))
245 if (!AllLoads && !AllConstants)
251 Value *VecOp =
nullptr;
252 SmallVector<Instruction *, 8> Loads;
257 VecOp = createVectorLoad(Loads);
258 if (VecOp ==
nullptr) {
262 }
else if (AllConstants) {
267 VecOp = createConstantVector(Constants);
268 if (VecOp ==
nullptr) {
280 DeadInstrMorgue.collectPotentiallyDeadInstrs(Stores);
282 DeadInstrMorgue.collectPotentiallyDeadInstrs<
Instruction>(Loads);
283 DeadInstrMorgue.tryEraseDeadInstrs();
285 return acceptOrRevert();
291 Loads, A->getScalarEvolution(), *DL))
293 auto VecTy = canVectorize(Loads);
306 auto *
VecLoad = createVectorLoad(Loads);
307 if (VecLoad ==
nullptr) {
315 if (OrigLoad->hasNUses(0))
319 OrigLoad->replaceAllUsesWith(Unpacked);
322 DeadInstrMorgue.collectPotentiallyDeadInstrs(Loads);
323 DeadInstrMorgue.tryEraseDeadInstrs();
325 if (!acceptOrRevert())
334 Function &
F = *Bndl[0]->getParent()->getParent();
335 DL = &
F.getParent()->getDataLayout();
336 Ctx = &
F.getContext();
341 auto Opc = Bndl[0]->getOpcode();
344 "Expected a homogeneous seed slice!");
348 case Instruction::Opcode::Load:
349 Changed = vectorizeLoads(Bndl, Rgn) !=
nullptr;
351 case Instruction::Opcode::Store:
352 Changed = vectorizeStores(Bndl, Rgn);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file defines the DenseSet and SmallDenseSet classes.
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
static constexpr Value * getValue(Ty &ValueOrUse)
#define DEBUG_PREFIX_LOCAL
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
InstListType::iterator iterator
Instruction iterators...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An ArrayRef of Values or Instructions that we can print/dump for debugging.
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty)
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty)
static LLVM_ABI Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
static LLVM_ABI Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
static LLVM_ABI IntegerType * get(Context &C, unsigned NumBits)
static bool areUnique(BndlRef< ValueT * > Values)
static bool differentBlock(BndlRef< ValueT * > Instrs)
static LLVM_ABI LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx, const Twine &Name="")
bool runOnRegion(Region &Rgn, const Analyses &A) final
\Returns true if it modifies R.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
static LLVM_ABI StoreInst * create(Value *V, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx)
Just like llvm::Type these are immutable, unique, never get freed and can only be created via static ...
static unsigned getNumBits(Type *Ty, const DataLayout &DL)
\Returns the number of bits of Ty.
static Instruction * getLowest(ArrayRef< Instruction * > Instrs)
\Returns the instruction in Instrs that is lowest in the BB.
static Value * unpack(Value *FromVec, Type *ExtrTy, unsigned Lane, BasicBlock::iterator WhereIt)
Emits the necessary instruction sequence to extract element of type ExtrTy at Lane from FromVec.
static auto enumerateLanes(const ValueContainerT &Range)
Helper for creating LaneValueEnumerator ranges.
static bool areConsecutive(LoadOrStoreT *I1, LoadOrStoreT *I2, ScalarEvolution &SE, const DataLayout &DL)
\Returns true if I1 and I2 are load/stores accessing consecutive memory addresses.
static Type * getElementType(Type *Ty)
Returns Ty if scalar or its element type if vector.
static Align getVecAlignment(AlignRangeT AlignRange, TypeRangeT TypeRange)
Given the alignments of the instructions before vectorization, this returns the alignment of the vect...
static Type * getCombinedVectorTypeFor(BndlRef< T * > Bndl, const DataLayout &DL)
\Returns the combined vector type for Bndl, even when the element types differ.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
BndlRef(const T &OneElt) -> BndlRef< T >
BasicBlock(llvm::BasicBlock *BB, Context &SBCtx)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.