1313#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_LEGALITY_H
1414
1515#include " llvm/ADT/ArrayRef.h"
16+ #include " llvm/Support/Casting.h"
17+ #include " llvm/Support/raw_ostream.h"
1618
1719namespace llvm ::sandboxir {
1820
1921class LegalityAnalysis ;
2022class Value ;
2123
2224enum class LegalityResultID {
25+ Pack, // /> Collect scalar values.
2326 Widen, // /> Vectorize by combining scalars to a vector.
2427};
2528
29+ // / The reason for vectorizing or not vectorizing.
30+ enum class ResultReason {
31+ DiffOpcodes,
32+ DiffTypes,
33+ };
34+
35+ #ifndef NDEBUG
36+ struct ToStr {
37+ static const char *getLegalityResultID (LegalityResultID ID) {
38+ switch (ID) {
39+ case LegalityResultID::Pack:
40+ return " Pack" ;
41+ case LegalityResultID::Widen:
42+ return " Widen" ;
43+ }
44+ }
45+
46+ static const char *getVecReason (ResultReason Reason) {
47+ switch (Reason) {
48+ case ResultReason::DiffOpcodes:
49+ return " DiffOpcodes" ;
50+ case ResultReason::DiffTypes:
51+ return " DiffTypes" ;
52+ }
53+ }
54+ };
55+ #endif // NDEBUG
56+
2657// / The legality outcome is represented by a class rather than an enum class
2758// / because in some cases the legality checks are expensive and look for a
2859// / particular instruction that can be passed along to the vectorizer to avoid
@@ -35,7 +66,34 @@ class LegalityResult {
3566 friend class LegalityAnalysis ;
3667
3768public:
69+ virtual ~LegalityResult () {}
3870 LegalityResultID getSubclassID () const { return ID; }
71+ #ifndef NDEBUG
72+ virtual void print (raw_ostream &OS) const {
73+ OS << ToStr::getLegalityResultID (ID);
74+ }
75+ LLVM_DUMP_METHOD void dump () const ;
76+ friend raw_ostream &operator <<(raw_ostream &OS, const LegalityResult &LR) {
77+ LR.print (OS);
78+ return OS;
79+ }
80+ #endif // NDEBUG
81+ };
82+
83+ // / Base class for results with reason.
84+ class LegalityResultWithReason : public LegalityResult {
85+ ResultReason Reason;
86+ LegalityResultWithReason (LegalityResultID ID, ResultReason Reason)
87+ : LegalityResult(ID), Reason(Reason) {}
88+ friend class Pack ; // For constructor.
89+
90+ public:
91+ #ifndef NDEBUG
92+ void print (raw_ostream &OS) const override {
93+ LegalityResult::print (OS);
94+ OS << " Reason: " << ToStr::getVecReason (Reason);
95+ }
96+ #endif
3997};
4098
4199class Widen final : public LegalityResult {
@@ -48,14 +106,37 @@ class Widen final : public LegalityResult {
48106 }
49107};
50108
109+ class Pack final : public LegalityResultWithReason {
110+ Pack (ResultReason Reason)
111+ : LegalityResultWithReason(LegalityResultID::Pack, Reason) {}
112+ friend class LegalityAnalysis ; // For constructor.
113+
114+ public:
115+ static bool classof (const LegalityResult *From) {
116+ return From->getSubclassID () == LegalityResultID::Pack;
117+ }
118+ };
119+
51120// / Performs the legality analysis and returns a LegalityResult object.
52121class LegalityAnalysis {
122+ // / Owns the legality result objects created by createLegalityResult().
123+ SmallVector<std::unique_ptr<LegalityResult>> ResultPool;
124+ // / Checks opcodes, types and other IR-specifics and returns a ResultReason
125+ // / object if not vectorizable, or nullptr otherwise.
126+ std::optional<ResultReason>
127+ notVectorizableBasedOnOpcodesAndTypes (ArrayRef<Value *> Bndl);
128+
53129public:
54130 LegalityAnalysis () = default ;
55- LegalityResult canVectorize (ArrayRef<Value *> Bndl) {
56- // TODO: For now everything is legal.
57- return Widen ();
131+ // / A LegalityResult factory.
132+ template <typename ResultT, typename ... ArgsT>
133+ ResultT &createLegalityResult (ArgsT... Args) {
134+ ResultPool.push_back (std::unique_ptr<ResultT>(new ResultT (Args...)));
135+ return cast<ResultT>(*ResultPool.back ());
58136 }
137+ // / Checks if it's legal to vectorize the instructions in \p Bndl.
138+ // / \Returns a LegalityResult object owned by LegalityAnalysis.
139+ LegalityResult &canVectorize (ArrayRef<Value *> Bndl);
59140};
60141
61142} // namespace llvm::sandboxir
0 commit comments