LLVM: lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

17

19

20#ifndef NDEBUG

25

30#endif

31

32std::optional

33LegalityAnalysis::notVectorizableBasedOnOpcodesAndTypes(

36 auto Opcode = I0->getOpcode();

37

40 }))

42

43

44

48 }))

50

51

52

53

55 FastMathFlags FMF0 = cast(Bndl[0])->getFastMathFlags();

58 }))

60 }

61

62

63

64 bool CanHaveWrapFlags =

66 if (CanHaveWrapFlags) {

67 bool NUW0 = I0->hasNoUnsignedWrap();

68 bool NSW0 = I0->hasNoSignedWrap();

72 })) {

74 }

75 }

76

77

78 switch (Opcode) {

79 case Instruction::Opcode::ZExt:

80 case Instruction::Opcode::SExt:

81 case Instruction::Opcode::FPToUI:

82 case Instruction::Opcode::FPToSI:

83 case Instruction::Opcode::FPExt:

84 case Instruction::Opcode::PtrToAddr:

85 case Instruction::Opcode::PtrToInt:

86 case Instruction::Opcode::IntToPtr:

87 case Instruction::Opcode::SIToFP:

88 case Instruction::Opcode::UIToFP:

89 case Instruction::Opcode::Trunc:

90 case Instruction::Opcode::FPTrunc:

91 case Instruction::Opcode::BitCast: {

92

94 [Opcode](Value *V) {

96 }) &&

97 "Different opcodes, should have early returned!");

98

102 FromTy0;

103 }))

105 return std::nullopt;

106 }

107 case Instruction::Opcode::FCmp:

108 case Instruction::Opcode::ICmp: {

109

111 bool Same = all_of(Bndl, [Pred0](Value *V) {

112 return cast(V)->getPredicate() == Pred0;

113 });

114 if (Same)

115 return std::nullopt;

117 }

118 case Instruction::Opcode::Select: {

120 auto *Cond0 = Sel0->getCondition();

122

123

125 return std::nullopt;

126 }

127 case Instruction::Opcode::FNeg:

128 case Instruction::Opcode::Add:

129 case Instruction::Opcode::FAdd:

130 case Instruction::Opcode::Sub:

131 case Instruction::Opcode::FSub:

132 case Instruction::Opcode::Mul:

133 case Instruction::Opcode::FMul:

134 case Instruction::Opcode::FRem:

135 case Instruction::Opcode::UDiv:

136 case Instruction::Opcode::SDiv:

137 case Instruction::Opcode::FDiv:

138 case Instruction::Opcode::URem:

139 case Instruction::Opcode::SRem:

140 case Instruction::Opcode::Shl:

141 case Instruction::Opcode::LShr:

142 case Instruction::Opcode::AShr:

143 case Instruction::Opcode::And:

144 case Instruction::Opcode::Or:

145 case Instruction::Opcode::Xor:

146 return std::nullopt;

147 case Instruction::Opcode::Load:

149 return std::nullopt;

151 case Instruction::Opcode::Store:

153 return std::nullopt;

155 case Instruction::Opcode::PHI:

157 case Instruction::Opcode::Opaque:

159 case Instruction::Opcode::Br:

160 case Instruction::Opcode::Ret:

161 case Instruction::Opcode::AddrSpaceCast:

162 case Instruction::Opcode::InsertElement:

163 case Instruction::Opcode::InsertValue:

164 case Instruction::Opcode::ExtractElement:

165 case Instruction::Opcode::ExtractValue:

166 case Instruction::Opcode::ShuffleVector:

167 case Instruction::Opcode::Call:

168 case Instruction::Opcode::GetElementPtr:

169 case Instruction::Opcode::Switch:

171 case Instruction::Opcode::VAArg:

172 case Instruction::Opcode::Freeze:

173 case Instruction::Opcode::Fence:

174 case Instruction::Opcode::Invoke:

175 case Instruction::Opcode::CallBr:

176 case Instruction::Opcode::LandingPad:

177 case Instruction::Opcode::CatchPad:

178 case Instruction::Opcode::CleanupPad:

179 case Instruction::Opcode::CatchRet:

180 case Instruction::Opcode::CleanupRet:

181 case Instruction::Opcode::Resume:

182 case Instruction::Opcode::CatchSwitch:

183 case Instruction::Opcode::AtomicRMW:

184 case Instruction::Opcode::AtomicCmpXchg:

185 case Instruction::Opcode::Alloca:

186 case Instruction::Opcode::Unreachable:

188 }

189

190 return std::nullopt;

191}

192

194LegalityAnalysis::getHowToCollectValues(ArrayRef<Value *> Bndl) const {

196 Vec.reserve(Bndl.size());

197 for (auto [Elm, V] : enumerate(Bndl)) {

198 if (auto *VecOp = IMaps.getVectorForOrig(V)) {

199

200 std::optional ExtractIdxOpt = IMaps.getOrigLane(VecOp, V);

201

202

204 Vec.emplace_back(VecOp, ExtractIdxOpt ? *ExtractIdxOpt + Ln : -1);

205 } else {

206 Vec.emplace_back(V);

207 }

208 }

209 return CollectDescr(std::move(Vec));

210}

211

213 bool SkipScheduling) {

214

217

220 [BB](auto *V) { return cast(V)->getParent() != BB; }))

222

224 if (Unique.size() != Bndl.size())

226

227 auto CollectDescrs = getHowToCollectValues(Bndl);

228 if (CollectDescrs.hasVectorInputs()) {

229 if (auto ValueShuffleOpt = CollectDescrs.getSingleInput()) {

230 auto [Vec, Mask] = *ValueShuffleOpt;

231 if (Mask.isIdentity())

234 }

236 std::move(CollectDescrs));

237 }

238

239 if (auto ReasonOpt = notVectorizableBasedOnOpcodesAndTypes(Bndl))

241

242 if (!SkipScheduling) {

243

246 for (auto *V : Bndl)

248 if (!Sched.trySchedule(IBndl))

250 }

251

253}

254

256 Sched.clear();

257 IMaps.clear();

258}

259}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

void reserve(size_type N)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

Describes how to collect the values needed by each lane.

LLVM_ABI const LegalityResult & canVectorize(ArrayRef< Value * > Bndl, bool SkipScheduling=false)

Checks if it's legal to vectorize the instructions in Bndl.

Definition Legality.cpp:212

ResultT & createLegalityResult(ArgsT &&...Args)

A LegalityResult factory.

LLVM_ABI void clear()

Definition Legality.cpp:255

The legality outcome is represented by a class rather than an enum class because in some cases the le...

LLVM_DUMP_METHOD void dump() const

Definition Legality.cpp:26

virtual void print(raw_ostream &OS) const

void print(raw_ostream &OS) const

LLVM_DUMP_METHOD void dump() const

Definition Legality.cpp:21

static Type * getExpectedType(const Value *V)

\Returns the expected type of Value V.

A SandboxIR Value has users. This is the base class.

static unsigned getNumLanes(Type *Ty)

\Returns the number of vector lanes of Ty or 1 if not a vector.

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 SmallVector< Value *, 4 > getOperand(ArrayRef< Value * > Bndl, unsigned OpIdx)

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

FunctionAddr VTableAddr Value

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,...

constexpr from_range_t from_range

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

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 - Return true if the parameter to the template is an instance of one of the template type argu...

ArrayRef(const T &OneElt) -> ArrayRef< T >

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.