|
17 | 17 | #include "llvm/SandboxIR/Type.h" |
18 | 18 | #include "llvm/SandboxIR/Utils.h" |
19 | 19 |
|
20 | | -namespace llvm { |
21 | | -/// Traits for DenseMap. |
22 | | -template <> struct DenseMapInfo<SmallVector<sandboxir::Value *>> { |
23 | | - static inline SmallVector<sandboxir::Value *> getEmptyKey() { |
24 | | - return SmallVector<sandboxir::Value *>({(sandboxir::Value *)-1}); |
25 | | - } |
26 | | - static inline SmallVector<sandboxir::Value *> getTombstoneKey() { |
27 | | - return SmallVector<sandboxir::Value *>({(sandboxir::Value *)-2}); |
28 | | - } |
29 | | - static unsigned getHashValue(const SmallVector<sandboxir::Value *> &Vec) { |
30 | | - return hash_combine_range(Vec.begin(), Vec.end()); |
31 | | - } |
32 | | - static bool isEqual(const SmallVector<sandboxir::Value *> &Vec1, |
33 | | - const SmallVector<sandboxir::Value *> &Vec2) { |
34 | | - return Vec1 == Vec2; |
35 | | - } |
36 | | -}; |
37 | | - |
38 | | -namespace sandboxir { |
| 20 | +namespace llvm::sandboxir { |
39 | 21 |
|
40 | 22 | class VecUtils { |
41 | 23 | public: |
@@ -197,79 +179,13 @@ class VecUtils { |
197 | 179 | /// \Returns the first integer power of 2 that is <= Num. |
198 | 180 | static unsigned getFloorPowerOf2(unsigned Num); |
199 | 181 |
|
200 | | - /// Helper struct for `matchPack()`. Describes the instructions and operands |
201 | | - /// of a pack pattern. |
202 | | - struct PackPattern { |
203 | | - /// The insertelement instructions that form the pack pattern in bottom-up |
204 | | - /// order, i.e., the first instruction in `Instrs` is the bottom-most |
205 | | - /// InsertElement instruction of the pack pattern. |
206 | | - /// For example in this simple pack pattern: |
207 | | - /// %Pack0 = insertelement <2 x i8> poison, i8 %v0, i64 0 |
208 | | - /// %Pack1 = insertelement <2 x i8> %Pack0, i8 %v1, i64 1 |
209 | | - /// this is [ %Pack1, %Pack0 ]. |
210 | | - SmallVector<Instruction *> Instrs; |
211 | | - /// The "external" operands of the pack pattern, i.e., the values that get |
212 | | - /// packed into a vector, skipping the ones in `Instrs`. The operands are in |
213 | | - /// bottom-up order, starting from the operands of the bottom-most insert. |
214 | | - /// So in our example this would be [ %v1, %v0 ]. |
215 | | - SmallVector<Value *> Operands; |
216 | | - }; |
217 | | - |
218 | | - /// If \p I is the last instruction of a pack pattern (i.e., an InsertElement |
219 | | - /// into a vector), then this function returns the instructions in the pack |
220 | | - /// and the operands in the pack, else returns nullopt. |
221 | | - /// Here is an example of a matched pattern: |
222 | | - /// %PackA0 = insertelement <2 x i8> poison, i8 %v0, i64 0 |
223 | | - /// %PackA1 = insertelement <2 x i8> %PackA0, i8 %v1, i64 1 |
224 | | - /// TODO: this currently detects only simple canonicalized patterns. |
225 | | - static std::optional<PackPattern> matchPack(Instruction *I) { |
226 | | - // TODO: Support vector pack patterns. |
227 | | - // TODO: Support out-of-order inserts. |
228 | | - |
229 | | - // Early return if `I` is not an Insert. |
230 | | - if (!isa<InsertElementInst>(I)) |
231 | | - return std::nullopt; |
232 | | - auto *BB0 = I->getParent(); |
233 | | - // The pack contains as many instrs as the lanes of the bottom-most Insert |
234 | | - unsigned ExpectedNumInserts = VecUtils::getNumLanes(I); |
235 | | - assert(ExpectedNumInserts >= 2 && "Expected at least 2 inserts!"); |
236 | | - PackPattern Pack; |
237 | | - Pack.Operands.resize(ExpectedNumInserts); |
238 | | - // Collect the inserts by walking up the use-def chain. |
239 | | - Instruction *InsertI = I; |
240 | | - for (auto ExpectedLane : reverse(seq<unsigned>(ExpectedNumInserts))) { |
241 | | - if (InsertI == nullptr) |
242 | | - return std::nullopt; |
243 | | - if (InsertI->getParent() != BB0) |
244 | | - return std::nullopt; |
245 | | - // Check the lane. |
246 | | - auto *LaneC = dyn_cast<ConstantInt>(InsertI->getOperand(2)); |
247 | | - if (LaneC == nullptr || LaneC->getSExtValue() != ExpectedLane) |
248 | | - return std::nullopt; |
249 | | - Pack.Instrs.push_back(InsertI); |
250 | | - Pack.Operands[ExpectedLane] = InsertI->getOperand(1); |
251 | | - |
252 | | - Value *Op = InsertI->getOperand(0); |
253 | | - if (ExpectedLane == 0) { |
254 | | - // Check the topmost insert. The operand should be a Poison. |
255 | | - if (!isa<PoisonValue>(Op)) |
256 | | - return std::nullopt; |
257 | | - } else { |
258 | | - InsertI = dyn_cast<InsertElementInst>(Op); |
259 | | - } |
260 | | - } |
261 | | - return Pack; |
262 | | - } |
263 | | - |
264 | 182 | #ifndef NDEBUG |
265 | 183 | /// Helper dump function for debugging. |
266 | 184 | LLVM_DUMP_METHOD static void dump(ArrayRef<Value *> Bndl); |
267 | 185 | LLVM_DUMP_METHOD static void dump(ArrayRef<Instruction *> Bndl); |
268 | 186 | #endif // NDEBUG |
269 | 187 | }; |
270 | 188 |
|
271 | | -} // namespace sandboxir |
272 | | - |
273 | | -} // namespace llvm |
| 189 | +} // namespace llvm::sandboxir |
274 | 190 |
|
275 | 191 | #endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_VECUTILS_H |
0 commit comments