27 for (
Value *BndlV : Bndl) {
29 Operands.push_back(BndlI->getOperand(OpIdx));
39 "Expect Instructions!");
40 auto &Ctx = Bndl[0]->getContext();
50 case Instruction::Opcode::ZExt:
51 case Instruction::Opcode::SExt:
52 case Instruction::Opcode::FPToUI:
53 case Instruction::Opcode::FPToSI:
54 case Instruction::Opcode::FPExt:
55 case Instruction::Opcode::PtrToInt:
56 case Instruction::Opcode::IntToPtr:
57 case Instruction::Opcode::SIToFP:
58 case Instruction::Opcode::UIToFP:
59 case Instruction::Opcode::Trunc:
60 case Instruction::Opcode::FPTrunc:
61 case Instruction::Opcode::BitCast: {
66 case Instruction::Opcode::FCmp:
67 case Instruction::Opcode::ICmp: {
73 "Expected same predicate across bundle.");
77 case Instruction::Opcode::Select: {
81 case Instruction::Opcode::FNeg: {
83 auto OpC = UOp0->getOpcode();
87 case Instruction::Opcode::Add:
88 case Instruction::Opcode::FAdd:
89 case Instruction::Opcode::Sub:
90 case Instruction::Opcode::FSub:
91 case Instruction::Opcode::Mul:
92 case Instruction::Opcode::FMul:
93 case Instruction::Opcode::UDiv:
94 case Instruction::Opcode::SDiv:
95 case Instruction::Opcode::FDiv:
96 case Instruction::Opcode::URem:
97 case Instruction::Opcode::SRem:
98 case Instruction::Opcode::FRem:
99 case Instruction::Opcode::Shl:
100 case Instruction::Opcode::LShr:
101 case Instruction::Opcode::AShr:
102 case Instruction::Opcode::And:
103 case Instruction::Opcode::Or:
104 case Instruction::Opcode::Xor: {
109 BinOp0->getOpcode(),
LHS,
RHS, BinOp0, WhereIt, Ctx,
"Vec");
111 case Instruction::Opcode::Load: {
114 Value *Ptr = Ld0->getPointerOperand();
117 case Instruction::Opcode::Store: {
123 case Instruction::Opcode::UncondBr:
124 case Instruction::Opcode::CondBr:
125 case Instruction::Opcode::Ret:
126 case Instruction::Opcode::PHI:
127 case Instruction::Opcode::AddrSpaceCast:
128 case Instruction::Opcode::Call:
129 case Instruction::Opcode::GetElementPtr:
140 auto *NewI = CreateVectorInstr(Bndl,
Operands);
150 VecOp->getContext(),
"VShuf");
164 Context &Ctx = ToPack[0]->getContext();
166 unsigned InsertIdx = 0;
167 for (
Value *Elm : ToPack) {
170 if (Elm->getType()->isVectorTy()) {
173 for (
auto ExtrLane :
seq<int>(0, NumElms)) {
186 LastInsert, ExtrI, InsertLaneC, WhereIt, Ctx,
"VPack");
187 LastInsert = InsertI;
197 WhereIt, Ctx,
"Pack");
199 WhereIt = std::next(NewI->getIterator());
208 bool StopForDebug = DebugBndlCnt++ >= Opts->sbvec_stop_bndl &&
212 const auto &LegalityRes = StopForDebug ? Legality.getForcedPackForDebugging()
213 : Legality.canVectorize(Bndl);
225 Action *Action = ActionPtr.get();
226 IMaps->registerVector(Bndl, Action);
227 Actions.push_back(std::move(ActionPtr));
232 SmallPtrSet<Instruction *, 4> Claimed;
233 for (
const auto &NextUserBndl :
235 vectorizeRec(NextUserBndl, Bndl,
Depth + 1, Legality);
242 std::make_unique<Action>(&LegalityRes, Bndl, UserBndl,
Depth);
244 switch (LegalityRes.getSubclassID()) {
247 switch (
I->getOpcode()) {
248 case Instruction::Opcode::Load:
250 case Instruction::Opcode::Store: {
267 IMaps->registerVector(Bndl, ActionPtr.get());
277 ActionPtr->Operands = std::move(
Operands);
278 auto *Action = ActionPtr.get();
279 Actions.push_back(std::move(ActionPtr));
284void BundleVec::ActionsVector::print(raw_ostream &OS)
const {
285 for (
auto [Idx, Action] :
enumerate(Actions)) {
290void BundleVec::ActionsVector::dump()
const {
print(
dbgs()); }
297 WhereIt = std::next(VecI->getIterator());
304 "A widened Bndl should contain instrs!");
319 auto IsExternal = [
this](
const Use &
U) {
320 return !IMaps->isVectorized(
U.getUser());
323 if (
none_of(Elm->uses(), IsExternal))
326 Elm->replaceUsesWithIf(UnpackV, IsExternal);
330Value *BundleVec::emitVectors() {
331 Value *NewVec =
nullptr;
332 for (
const auto &ActionPtr : Actions) {
335 const LegalityResult &LegalityRes = *ActionPtr->LegalityRes;
336 unsigned Depth = ActionPtr->Depth;
337 auto *UserBB = !UserBndl.empty()
341 switch (LegalityRes.getSubclassID()) {
344 SmallVector<Value *, 2> VecOperands;
346 switch (
I->getOpcode()) {
347 case Instruction::Opcode::Load:
350 case Instruction::Opcode::Store:
351 VecOperands.push_back(ActionPtr->Operands[0]->Vec);
355 for (Action *OpA : ActionPtr->Operands)
356 VecOperands.push_back(OpA->Vec);
360 switch (
I->getOpcode()) {
361 case Instruction::Opcode::Load:
364 case Instruction::Opcode::Store: {
366 if (Action *OpA = IMaps->getVectorForOrig(OpBndl[0]))
367 VecOperands.push_back(OpA->Vec);
369 VecOperands.push_back(createPack(OpBndl, UserBB));
374 for (
unsigned OpIdx = 0; OpIdx <
I->getNumOperands(); ++OpIdx) {
376 if (Action *OpA = IMaps->getVectorForOrig(OpBndl[0]))
377 VecOperands.push_back(OpA->Vec);
379 VecOperands.push_back(createPack(OpBndl, UserBB));
384 NewVec = createVectorInstr(ActionPtr->Bndl, VecOperands);
387 if (NewVec !=
nullptr)
388 DeadInstrMorgue.collectPotentiallyDeadInstrs(Bndl);
391 emitUnpacksForExternalUses(ActionPtr->Bndl, NewVec);
400 const ShuffleMask &
Mask =
402 NewVec = createShuffle(VecOp, Mask, UserBB);
403 assert(NewVec->getType() == VecOp->getType() &&
404 "Expected same type! Bad mask ?");
413 SmallVector<Value *, 4> DescrInstrs;
414 for (
const auto &ElmDescr : Descr.getDescrs()) {
415 auto *
V = ElmDescr.needsExtract() ? ElmDescr.getValue()->Vec
416 : ElmDescr.getScalar();
418 DescrInstrs.push_back(
I);
424 Context &Ctx = LastV->getContext();
426 for (
const auto &ElmDescr : Descr.getDescrs()) {
427 Value *VecOp =
nullptr;
428 Value *ValueToInsert;
429 if (ElmDescr.needsExtract()) {
430 VecOp = ElmDescr.getValue()->Vec;
434 VecOp, IdxC, WhereIt, VecOp->getContext(),
"VExt");
436 ValueToInsert = ElmDescr.getScalar();
439 if (NumLanesToInsert == 1) {
444 WhereIt, Ctx,
"VIns");
453 for (
unsigned LnCnt = 0; LnCnt != NumLanesToInsert; ++LnCnt) {
456 WhereIt, Ctx,
"VExt");
457 unsigned InsLane = Lane + LnCnt;
463 Lane += NumLanesToInsert;
472 NewVec = createPack(Bndl, UserBB);
476 if (NewVec !=
nullptr) {
478 ActionPtr->Vec = NewVec;
481 if (Opts->sbvec_always_verify) {
496 LegalityAnalysis &Legality) {
504 vectorizeRec(Bndl, {}, 0, Legality);
506 <<
"Vec: Vectorization Actions:\n";
509 DeadInstrMorgue.tryEraseDeadInstrs();
515 const auto &SeedSlice = Rgn.
getAux();
516 if (SeedSlice.size() < 2)
518 Function &
F = *SeedSlice[0]->getParent()->getParent();
519 IMaps = std::make_unique<InstrMaps>();
521 F.getParent()->getDataLayout(),
A.getTTI(),
522 F.getContext(), *IMaps, Dir);
529 return tryVectorize(SeedSliceVals, Legality);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_UNLIKELY(EXPR)
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
InstListType::iterator iterator
Instruction iterators...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
static LLVM_ABI Value * createWithCopiedFlags(Instruction::Opcode Op, Value *LHS, Value *RHS, Value *CopyFrom, InsertPosition Pos, Context &Ctx, const Twine &Name="")
An ArrayRef of Values or Instructions that we can print/dump for debugging.
bool runOnRegion(Region &Rgn, const Analyses &A) final
\Returns true if it modifies R.
static LLVM_ABI Value * create(Type *DestTy, Opcode Op, Value *Operand, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Value * create(Predicate Pred, Value *S1, Value *S2, InsertPosition Pos, Context &Ctx, const Twine &Name="")
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 ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static LLVM_ABI Value * create(Value *Vec, Value *Idx, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Value * create(Value *Vec, Value *NewElt, Value *Idx, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI BBIterator getIterator() const
\Returns a BasicBlock::iterator for this Instruction.
Performs the legality analysis and returns a LegalityResult object.
static LLVM_ABI LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx, const Twine &Name="")
virtual void print(raw_ostream &OS) const
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Context & getContext() const
const SmallVector< Instruction * > & getAux() const
\Returns the auxiliary vector.
static LLVM_ABI Value * create(Value *Cond, Value *True, Value *False, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Value * create(Value *V1, Value *V2, Value *Mask, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI StoreInst * create(Value *V, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx)
static LLVM_ABI IntegerType * getInt32Ty(Context &Ctx)
static LLVM_ABI Value * createWithCopiedFlags(Instruction::Opcode Op, Value *OpV, Value *CopyFrom, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static Type * getExpectedType(const Value *V)
\Returns the expected type of Value V.
static bool verifyFunction(const Function *F, raw_ostream &OS)
Equivalent to llvm::verifyFunction().
A SandboxIR Value has users. This is the base class.
static Type * getCommonScalarType(ArrayRef< Value * > Bndl)
Similar to tryGetCommonScalarType() but will assert that there is a common type.
static Instruction * getLastPHIOrSelf(Instruction *I)
If I is not a PHI it returns it.
static unsigned getNumLanes(Type *Ty)
\Returns the number of vector lanes of Ty or 1 if not a vector.
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 LLVM_DUMP_METHOD void dump(ArrayRef< Value * > Bndl)
Helper dump function for debugging.
static Type * getWideType(Type *ElemTy, unsigned NumElts)
\Returns <NumElts x ElemTy>.
static auto enumerateLanes(const ValueContainerT &Range)
Helper for creating LaneValueEnumerator ranges.
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 BasicBlock::iterator getInsertPointAfterInstrs(ArrayRef< Value * > Vals, BasicBlock *BB)
\Returns the BB iterator after the lowest instruction in Vals (skipping instructions not in BB),...
static LLVM_ABI SmallVector< BundleTy > getNextUserBundles(ArrayRef< Value * > Bndl, const InstrMaps &IMaps, SmallPtrSet< Instruction *, 4 > &Claimed)
For each user of lane 0 in Bndl, try to form a bundle of matching users for all lanes.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeAddr< UseNode * > Use
BndlRef(const T &OneElt) -> BndlRef< T >
LLVM_ABI Function * getParent() const
StringLiteral schedDirectionToStr(SchedDirection Dir)
@ DiamondReuseWithShuffle
BasicBlock(llvm::BasicBlock *BB, Context &SBCtx)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
static BundleTy getOperand(BndlRef< Value * > Bndl, unsigned OpIdx)
SmallVector< Value *, 4 > BundleTy
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
constexpr unsigned long SBVecStopDisabled
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
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...
const VectorizeOptions & getVectorizeOptions(const LLVMContext &C)
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.