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/Operator.h" 12 #include "llvm/SandboxIR/Utils.h" 13 #include "llvm/SandboxIR/Value.h" 14 #include "llvm/Support/Debug.h" 15 #include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h" 16 17 namespace llvm::sandboxir { 18 19 #define DEBUG_TYPE "SBVec:Legality" 20 21 #ifndef NDEBUG 22 void LegalityResult::dump() const { 23 print(dbgs()); 24 dbgs() << "\n"; 25 } 26 #endif // NDEBUG 27 28 std::optional<ResultReason> 29 LegalityAnalysis::notVectorizableBasedOnOpcodesAndTypes( 30 ArrayRef<Value *> Bndl) { 31 auto *I0 = cast<Instruction>(Bndl[0]); 32 auto Opcode = I0->getOpcode(); 33 // If they have different opcodes, then we cannot form a vector (for now). 34 if (any_of(drop_begin(Bndl), [Opcode](Value *V) { 35 return cast<Instruction>(V)->getOpcode() != Opcode; 36 })) 37 return ResultReason::DiffOpcodes; 38 39 // If not the same scalar type, Pack. This will accept scalars and vectors as 40 // long as the element type is the same. 41 Type *ElmTy0 = VecUtils::getElementType(Utils::getExpectedType(I0)); 42 if (any_of(drop_begin(Bndl), [ElmTy0](Value *V) { 43 return VecUtils::getElementType(Utils::getExpectedType(V)) != ElmTy0; 44 })) 45 return ResultReason::DiffTypes; 46 47 // TODO: Allow vectorization of instrs with different flags as long as we 48 // change them to the least common one. 49 // For now pack if differnt FastMathFlags. 50 if (isa<FPMathOperator>(I0)) { 51 FastMathFlags FMF0 = cast<Instruction>(Bndl[0])->getFastMathFlags(); 52 if (any_of(drop_begin(Bndl), [FMF0](auto *V) { 53 return cast<Instruction>(V)->getFastMathFlags() != FMF0; 54 })) 55 return ResultReason::DiffMathFlags; 56 } 57 58 // TODO: Missing checks 59 60 return std::nullopt; 61 } 62 63 #ifndef NDEBUG 64 static void dumpBndl(ArrayRef<Value *> Bndl) { 65 for (auto *V : Bndl) 66 dbgs() << *V << "\n"; 67 } 68 #endif // NDEBUG 69 70 const LegalityResult &LegalityAnalysis::canVectorize(ArrayRef<Value *> Bndl) { 71 // If Bndl contains values other than instructions, we need to Pack. 72 if (any_of(Bndl, [](auto *V) { return !isa<Instruction>(V); })) { 73 LLVM_DEBUG(dbgs() << "Not vectorizing: Not Instructions:\n"; 74 dumpBndl(Bndl);); 75 return createLegalityResult<Pack>(ResultReason::NotInstructions); 76 } 77 78 if (auto ReasonOpt = notVectorizableBasedOnOpcodesAndTypes(Bndl)) 79 return createLegalityResult<Pack>(*ReasonOpt); 80 81 // TODO: Check for existing vectors containing values in Bndl. 82 83 // TODO: Check with scheduler. 84 85 return createLegalityResult<Widen>(); 86 } 87 } // namespace llvm::sandboxir 88