class Pattern {
enum class RootKind {
Any, // 任意类型
OperationName, // 标记 op 的名字
InterfaceID, // 标记 op 具有某一组方法
TraitID // 标记 op 具有什么特性
};
public:
ArrayRef<OperationName> getGeneratedOps() const { return generatedOps; }
std::optional<OperationName> getRootKind() const {
if (rootKind == RootKind::OperationName)
return OperationName::getFromOpaquePointer(rootValue);
return std::nullopt; // 标记为空的 optional
}
std::optional<TypeID> getRootInterfaceID() const {
if (rootKind == RootKind::InterfaceID)
return TypeID::getFromOpaquePointer(rootValue);
return std::nullopt; // 标记为空的 optional
}
std::optional<TypeID> getRootTraitID() const {
if (rootKind == RootKind::TraitID)
return TypeID::getFromOpaquePointer(rootValue);
return std::nullopt; // 标记为空的 optional
}
PatternBenefit getBenefit() const { return benefit; }
bool hasBoundedRewriteRecursion() const {
// `contextAndHasBoundedRecursion` 是 `llvm::PointerIntPair<MLIRContext *, 1, bool>` 类型
// 用最后一个 bit 表示 bool
return contextAndHasBoundedRecursion.getInt();
}
MLIRContext *getContext() const {
return contextAndHasBoundedRecursion.getPointer();
}
StringRef getDebugName() const { return debugName; }
void setDebugName(StringRef name) { debugName = name; }
ArrayRef<StringRef> getDebugLabels() const { return debugLabels; }
void addDebugLabels(ArrayRef<StringRef> labels) {
debugLabels.append(labels.begin(), labels.end());
}
void addDebugLabels(StringRef label) { debugLabels.push_back(label); }
protected:
// Tag Dispatch,用来解决函数重载冲突,标记调用哪个构造函数
struct MatchAnyOpTypeTag {};
struct MatchInterfaceOpTypeTag {};
struct MatchTraitOpTypeTag {};
Pattern(StringRef rootName, PatternBenefit benefit, MLIRContext *context,
ArrayRef<StringRef> generatedNames = {});
Pattern(MatchAnyOpTypeTag tag, PatternBenefit benefit, MLIRContext *context,
ArrayRef<StringRef> generatedNames = {});
Pattern(MatchInterfaceOpTypeTag tag, TypeID interfaceID,
PatternBenefit benefit, MLIRContext *context,
ArrayRef<StringRef> generatedNames = {});
Pattern(MatchTraitOpTypeTag tag, TypeID traitID, PatternBenefit benefit,
MLIRContext *context, ArrayRef<StringRef> generatedNames = {});
void setHasBoundedRewriteRecursion(bool hasBoundedRecursionArg = true) {
contextAndHasBoundedRecursion.setInt(hasBoundedRecursionArg);
}
private:
Pattern(const void *rootValue, RootKind rootKind,
ArrayRef<StringRef> generatedNames, PatternBenefit benefit,
MLIRContext *context);
// 采用通用不透明句柄(Opaque Handle),保障ABI稳定、兼容C语言绑定
// 三种场景选型规范:
// 1. 仅单一独立类型,无需跨类型统一传递:对该类型前向声明,直接使用类型原生指针
// 2. 多类型存在继承关系、需C++多态调用且无需C兼容:前向声明公共基类,使用基类指针
// 3. 多类型无公共继承、需要统一容器/回调/C接口流通:使用 const void* 通用不透明指针
// 本字段 rootValue 需要承载多种无继承关系的IR对象句柄,因此选用 void* 不透明句柄
const void *rootValue;
RootKind rootKind;
// `PatternBenefit` 标记 Pass 优先级,当多个 Pass 的 Pattern 都匹配时,决定谁先执行
const PatternBenefit benefit;
llvm::PointerIntPair<MLIRContext *, 1, bool> contextAndHasBoundedRecursion;
SmallVector<OperationName, 2> generatedOps;
StringRef debugName;
SmallVector<StringRef, 0> debugLabels;
};