xref: /llvm-project/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp (revision 5ea694816b569e010854a861ad58502c056d5a39)
1 //===- Legality.cpp -------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h"
10 #include "llvm/SandboxIR/Instruction.h"
11 #include "llvm/SandboxIR/Utils.h"
12 #include "llvm/SandboxIR/Value.h"
13 #include "llvm/Support/Debug.h"
14 #include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
15 
16 namespace llvm::sandboxir {
17 
18 #define DEBUG_TYPE "SBVec:Legality"
19 
20 #ifndef NDEBUG
21 void LegalityResult::dump() const {
22   print(dbgs());
23   dbgs() << "\n";
24 }
25 #endif // NDEBUG
26 
27 std::optional<ResultReason>
28 LegalityAnalysis::notVectorizableBasedOnOpcodesAndTypes(
29     ArrayRef<Value *> Bndl) {
30   auto *I0 = cast<Instruction>(Bndl[0]);
31   auto Opcode = I0->getOpcode();
32   // If they have different opcodes, then we cannot form a vector (for now).
33   if (any_of(drop_begin(Bndl), [Opcode](Value *V) {
34         return cast<Instruction>(V)->getOpcode() != Opcode;
35       }))
36     return ResultReason::DiffOpcodes;
37 
38   // If not the same scalar type, Pack. This will accept scalars and vectors as
39   // long as the element type is the same.
40   Type *ElmTy0 = VecUtils::getElementType(Utils::getExpectedType(I0));
41   if (any_of(drop_begin(Bndl), [ElmTy0](Value *V) {
42         return VecUtils::getElementType(Utils::getExpectedType(V)) != ElmTy0;
43       }))
44     return ResultReason::DiffTypes;
45 
46   // TODO: Missing checks
47 
48   return std::nullopt;
49 }
50 
51 #ifndef NDEBUG
52 static void dumpBndl(ArrayRef<Value *> Bndl) {
53   for (auto *V : Bndl)
54     dbgs() << *V << "\n";
55 }
56 #endif // NDEBUG
57 
58 const LegalityResult &LegalityAnalysis::canVectorize(ArrayRef<Value *> Bndl) {
59   // If Bndl contains values other than instructions, we need to Pack.
60   if (any_of(Bndl, [](auto *V) { return !isa<Instruction>(V); })) {
61     LLVM_DEBUG(dbgs() << "Not vectorizing: Not Instructions:\n";
62                dumpBndl(Bndl););
63     return createLegalityResult<Pack>(ResultReason::NotInstructions);
64   }
65 
66   if (auto ReasonOpt = notVectorizableBasedOnOpcodesAndTypes(Bndl))
67     return createLegalityResult<Pack>(*ReasonOpt);
68 
69   // TODO: Check for existing vectors containing values in Bndl.
70 
71   // TODO: Check with scheduler.
72 
73   return createLegalityResult<Widen>();
74 }
75 } // namespace llvm::sandboxir
76