MLIR Pattern 基类解析

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;
};
posted @ 2026-07-20 14:03  judesongd  阅读(6)  评论(0)    收藏  举报