29 if (
auto *SI = llvm::dyn_cast<StoreInst>(&
I))
37 for (
Value *BndlV : Bndl) {
38 auto *BndlI = cast<Instruction>(BndlV);
39 Operands.push_back(BndlI->getOperand(OpIdx));
47 auto *BotI = cast<Instruction>(
48 *std::max_element(Instrs.
begin(), Instrs.
end(), [](
auto *V1,
auto *V2) {
49 return cast<Instruction>(V1)->comesBefore(cast<Instruction>(V2));
52 return std::next(BotI->getIterator());
58 assert(
all_of(Bndl, [](
auto *V) {
return isa<Instruction>(V); }) &&
59 "Expect Instructions!");
60 auto &Ctx = Bndl[0]->getContext();
67 auto Opcode = cast<Instruction>(Bndl[0])->getOpcode();
69 case Instruction::Opcode::ZExt:
70 case Instruction::Opcode::SExt:
71 case Instruction::Opcode::FPToUI:
72 case Instruction::Opcode::FPToSI:
73 case Instruction::Opcode::FPExt:
74 case Instruction::Opcode::PtrToInt:
75 case Instruction::Opcode::IntToPtr:
76 case Instruction::Opcode::SIToFP:
77 case Instruction::Opcode::UIToFP:
78 case Instruction::Opcode::Trunc:
79 case Instruction::Opcode::FPTrunc:
80 case Instruction::Opcode::BitCast: {
84 case Instruction::Opcode::FCmp:
85 case Instruction::Opcode::ICmp: {
86 auto Pred = cast<CmpInst>(Bndl[0])->getPredicate();
89 return cast<CmpInst>(SBV)->getPredicate() == Pred;
91 "Expected same predicate across bundle.");
95 case Instruction::Opcode::Select: {
99 case Instruction::Opcode::FNeg: {
100 auto *UOp0 = cast<UnaryOperator>(Bndl[0]);
101 auto OpC = UOp0->getOpcode();
105 case Instruction::Opcode::Add:
106 case Instruction::Opcode::FAdd:
107 case Instruction::Opcode::Sub:
108 case Instruction::Opcode::FSub:
109 case Instruction::Opcode::Mul:
110 case Instruction::Opcode::FMul:
111 case Instruction::Opcode::UDiv:
112 case Instruction::Opcode::SDiv:
113 case Instruction::Opcode::FDiv:
114 case Instruction::Opcode::URem:
115 case Instruction::Opcode::SRem:
116 case Instruction::Opcode::FRem:
117 case Instruction::Opcode::Shl:
118 case Instruction::Opcode::LShr:
119 case Instruction::Opcode::AShr:
120 case Instruction::Opcode::And:
121 case Instruction::Opcode::Or:
122 case Instruction::Opcode::Xor: {
123 auto *BinOp0 = cast<BinaryOperator>(Bndl[0]);
127 BinOp0, WhereIt, Ctx,
"Vec");
129 case Instruction::Opcode::Load: {
130 auto *Ld0 = cast<LoadInst>(Bndl[0]);
131 Value *
Ptr = Ld0->getPointerOperand();
134 case Instruction::Opcode::Store: {
135 auto Align = cast<StoreInst>(Bndl[0])->getAlign();
140 case Instruction::Opcode::Br:
141 case Instruction::Opcode::Ret:
142 case Instruction::Opcode::PHI:
143 case Instruction::Opcode::AddrSpaceCast:
144 case Instruction::Opcode::Call:
145 case Instruction::Opcode::GetElementPtr:
156void BottomUpVec::tryEraseDeadInstrs() {
158 sort(DeadInstrCandidates,
159 [](Instruction *I1, Instruction *I2) {
return I1->comesBefore(I2); });
160 for (Instruction *
I :
reverse(DeadInstrCandidates)) {
162 I->eraseFromParent();
164 DeadInstrCandidates.clear();
167Value *BottomUpVec::createPack(ArrayRef<Value *> ToPack) {
177 Context &Ctx = ToPack[0]->getContext();
179 unsigned InsertIdx = 0;
180 for (Value *Elm : ToPack) {
183 if (Elm->getType()->isVectorTy()) {
185 cast<FixedVectorType>(Elm->getType())->getNumElements();
186 for (
auto ExtrLane : seq<int>(0, NumElms)) {
193 if (!isa<Constant>(ExtrI))
194 WhereIt = std::next(cast<Instruction>(ExtrI)->getIterator());
199 LastInsert, ExtrI, InsertLaneC, WhereIt, Ctx,
"VPack");
200 if (!isa<Constant>(InsertI)) {
201 LastInsert = InsertI;
202 WhereIt = std::next(cast<Instruction>(LastInsert)->getIterator());
211 WhereIt, Ctx,
"Pack");
212 if (
auto *NewI = dyn_cast<Instruction>(LastInsert))
213 WhereIt = std::next(NewI->getIterator());
219Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl,
unsigned Depth) {
220 Value *NewVec =
nullptr;
221 const auto &LegalityRes = Legality->canVectorize(Bndl);
222 switch (LegalityRes.getSubclassID()) {
224 auto *
I = cast<Instruction>(Bndl[0]);
225 SmallVector<Value *, 2> VecOperands;
226 switch (
I->getOpcode()) {
227 case Instruction::Opcode::Load:
231 case Instruction::Opcode::Store: {
234 VecOperands.push_back(VecOp);
240 for (
auto OpIdx : seq<unsigned>(
I->getNumOperands())) {
242 VecOperands.push_back(VecOp);
246 NewVec = createVectorInstr(Bndl, VecOperands);
249 if (NewVec !=
nullptr) {
250 for (Value *V : Bndl)
251 DeadInstrCandidates.push_back(cast<Instruction>(V));
259 NewVec = createPack(Bndl);
266bool BottomUpVec::tryVectorize(ArrayRef<Value *> Bndl) {
267 DeadInstrCandidates.clear();
268 vectorizeRec(Bndl, 0);
269 tryEraseDeadInstrs();
274 Legality = std::make_unique<LegalityAnalysis>(
275 A.getAA(),
A.getScalarEvolution(),
F.getParent()->getDataLayout(),
285 if (Seeds.size() >= 2)
286 Change |= tryVectorize(Seeds);
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
InstListType::iterator iterator
Instruction iterators...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
LLVM Value Representation.
Contains a list of sandboxir::Instruction's.
static Value * createWithCopiedFlags(Instruction::Opcode Op, Value *LHS, Value *RHS, Value *CopyFrom, InsertPosition Pos, Context &Ctx, const Twine &Name="")
BottomUpVec(StringRef Pipeline)
bool runOnFunction(Function &F, const Analyses &A) final
\Returns true if it modifies F.
static Value * create(Type *DestTy, Opcode Op, Value *Operand, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static CmpInst * create(Predicate Pred, Value *S1, Value *S2, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static Value * create(Value *Vec, Value *Idx, InsertPosition Pos, Context &Ctx, const Twine &Name="")
A pass that runs on a sandbox::Function.
static Value * create(Value *Vec, Value *NewElt, Value *Idx, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx, const Twine &Name="")
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
static Value * create(Value *Cond, Value *True, Value *False, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static StoreInst * create(Value *V, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx)
static Type * getInt32Ty(Context &Ctx)
static 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.
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 unsigned getNumLanes(Type *Ty)
\Returns the number of vector lanes of Ty or 1 if not a vector.
static Type * getWideType(Type *ElemTy, unsigned NumElts)
\Returns <NumElts x ElemTy>.
static Type * getElementType(Type *Ty)
Returns Ty if scalar or its element type if vector.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
@ Widen
ā€¨Collect scalar values.
static BasicBlock::iterator getInsertPointAfterInstrs(ArrayRef< Value * > Instrs)
static SmallVector< Value *, 4 > getOperand(ArrayRef< Value * > Bndl, unsigned OpIdx)
static llvm::SmallVector< Value *, 4 > collectSeeds(BasicBlock &BB)
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.
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)