This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push:
new 70823dc117 [REFACTOR][IR] Consolidate pass instrumentation and call
effect headers (#20580)
70823dc117 is described below
commit 70823dc117047c09a0ac68170adaef4da134695c
Author: Tianqi Chen <[email protected]>
AuthorDate: Wed Oct 7 09:00:07 2026 -0400
[REFACTOR][IR] Consolidate pass instrumentation and call effect headers
(#20580)
Consolidate pass instrumentation declarations into the transform header
after the generic pass API. Defer dependent PassContext definitions to
retain complete types while preserving its layout and behavior.
Place shared CallEffectKind declarations beside Call in the expression
header and migrate consumers to the owning headers. Retire the
standalone instrumentation and shared operation-attribute headers while
preserving namespaces, effect values, registration keys and callback
implementations.
---
include/tvm/ir/expr.h | 73 ++++++++-
include/tvm/ir/instrument.h | 158 --------------------
include/tvm/ir/op_attr_types.h | 103 -------------
include/tvm/ir/transform.h | 269 +++++++++++++++++++++++++---------
src/ir/instrument.cc | 1 -
src/ir/prim/builtin.cc | 2 +-
src/relax/utils.cc | 2 +-
src/sym/z3_prover.cc | 2 +-
tests/cpp/tir_analysis_side_effect.cc | 1 -
9 files changed, 272 insertions(+), 339 deletions(-)
diff --git a/include/tvm/ir/expr.h b/include/tvm/ir/expr.h
index 0936618f4d..b91ddc159e 100644
--- a/include/tvm/ir/expr.h
+++ b/include/tvm/ir/expr.h
@@ -26,19 +26,21 @@
#include <tvm/ffi/big_int.h>
#include <tvm/ffi/dtype.h>
+#include <tvm/ffi/error.h>
#include <tvm/ffi/extra/dataclass.h>
#include <tvm/ffi/reflection/registry.h>
#include <tvm/ffi/string.h>
#include <tvm/ir/attrs.h>
#include <tvm/ir/base_expr.h>
#include <tvm/ir/cow.h>
-#include <tvm/ir/op_attr_types.h>
#include <tvm/ir/source_map.h>
#include <algorithm>
+#include <cstdint>
#include <functional>
#include <limits>
#include <optional>
+#include <ostream>
#include <string>
#include <utility>
@@ -531,6 +533,75 @@ class GlobalVar : public Expr {
TVM_DEFINE_OBJECT_REF_COW_METHOD(GlobalVarNode);
};
+/*!
+ * \brief The effect type of the call.
+ */
+enum class CallEffectKind : int {
+ /*! \brief Function corresponds to an annotation(e.g. likely) and can
translate to identity. */
+ kExprAnnotation = 0,
+ /*!
+ * \brief Pure function that do not interacts
+ * with any external state.
+ */
+ kPure = 1,
+ /*!
+ * \brief Function's that may read from states(e.g. RAM)
+ */
+ kReadState = 2,
+ /*!
+ * \brief Function that may read/write from states(e.g. RAM).
+ */
+ kUpdateState = 3,
+ /*!
+ * \brief Opaque function, cannot make any assumption
+ */
+ kOpaque = kUpdateState,
+ /*!
+ * \brief Special intrinsic to annotate call arguments info
+ * only valid as a direct argument to a call.
+ */
+ kSpecialCallArg = 4,
+ /*!
+ * \brief Embed opaque information in the Expr, cannot be codegen.
+ */
+ kEmbedInfo = 5,
+ /*!
+ * \brief Function that changes control flow
+ */
+ kControlJump = 6,
+};
+
+inline std::ostream& operator<<(std::ostream& os, CallEffectKind side_effect) {
+ switch (side_effect) {
+ case CallEffectKind::kExprAnnotation:
+ return os << "kExprAnnotation";
+
+ case CallEffectKind::kPure:
+ return os << "kPure";
+
+ case CallEffectKind::kReadState:
+ return os << "kReadState";
+
+ case CallEffectKind::kUpdateState:
+ return os << "kUpdateState";
+
+ case CallEffectKind::kSpecialCallArg:
+ return os << "kSpecialCallArg";
+
+ case CallEffectKind::kEmbedInfo:
+ return os << "kEmbedInfo";
+
+ case CallEffectKind::kControlJump:
+ return os << "kControlJump";
+
+ default:
+ TVM_FFI_THROW(InternalError) << "Unknown CallEffectKind: " <<
static_cast<int>(side_effect);
+ }
+}
+
+/*! \brief Use integer to record the kind. */
+using TCallEffectKind = int64_t;
+
/*!
* \brief Call corresponds to callable invocation.
*/
diff --git a/include/tvm/ir/instrument.h b/include/tvm/ir/instrument.h
deleted file mode 100644
index 6b3ee7c351..0000000000
--- a/include/tvm/ir/instrument.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * \file tvm/ir/instrument.h
- *
- * This file introduces a pass instrument infrastructure, inspired by LLVM and
MLIR.
- * It inserts instrumentation points around passes.
- */
-#ifndef TVM_IR_INSTRUMENT_H_
-#define TVM_IR_INSTRUMENT_H_
-
-#include <tvm/ffi/reflection/registry.h>
-#include <tvm/ffi/string.h>
-
-#include <utility>
-#include <vector>
-
-namespace tvm {
-
-class IRModule;
-
-// Forward class for PassInstrumentNode methods
-namespace transform {
-class PassInfo;
-} // namespace transform
-
-namespace instrument {
-
-/*!
- * \brief PassInstrumentNode forms an instrument implementation.
- * It provides API for users to register callbacks at different
instrumentation points.
- *
- * Within a PassContext, call sequence of a PassInstrument implementation is
like:
- *
- * with PassContext(instruments=[pi]): # pi = a PassInstrument
implementation
- * pi.EnterPassContext()
- *
- * if pi.ShouldRun(Pass1):
- * pi.RunBeforePass()
- * Pass1()
- * pi.RunAfterPass()
- *
- * if pi.ShouldRun(Pass2):
- * pi.RunBeforePass()
- * Pass2()
- * pi.RunAfterPass()
- *
- * pi.ExitPassContext()
- *
- * `EnterPassContext` and `ExitPassContext` are only called once when
entering/exiting a
- * PassContext. `ShouldRun`, `RunBeforePass` and `RunAfterPass` are called
multiple times depending
- * on how many passes.
- *
- * If there are multiple pass instrumentations provided, the instrument points
are the same.
- * PassInstrument implementations' callbacks are called in order:
- *
- * with PassContext(instruments=[pi1, pi2]): # pi1, pi2 = two distinct
PassInstrument impls
- * pi.EnterPassContext() for pi in instruments
- *
- * should_run = all([pi.ShoudRun(Pass1) for pi in instruments)])
- * if (should_run)
- * pi.RunBeforePass() for pi in instruments
- * Pass1()
- * pi.RunAfterPass() for pi in instruments
- *
- * should_run = all([pi.ShouldRun(Pass2) for pi in instruments)])
- * if (should_run)
- * pi.RunBeforePass() for pi in instruments
- * Pass2()
- * pi.RunAfterPass() for pi in instruments
- *
- * pi.ExitPassContext() for pi in instruments
- *
- * Note:
- * 1. Assume there is no dependency between PassInstrument implementations
in `instruments` .
- * 2. `EnterPassContext` and `ExitPassContext` have `with` behavior (see
PassContext and its FFI):
- * If there is any exception raised in `ShouldRun()`,
`RunBeforePass()`, `RunAfterPass()` and
- * `Pass()`, `ExitPassContext()` is still called.
- * 3. In mutiple PassInstrument instances scenario, callbacks are called in
order:
- * If one throws exceptions, remainings will not be called.
- *
- * \sa PassInstrument
- * \sa src/ir/transform.cc
- */
-class PassInstrumentNode : public ffi::Object {
- public:
- /*! \brief Name of this pass instrument object. */
- ffi::String name;
-
- virtual ~PassInstrumentNode() {}
-
- /*! \brief Instrument when entering PassContext. Called once within a
PassContext. */
- virtual void EnterPassContext() const = 0;
-
- /*! \brief Instrument when exiting PassContext. Called once within a
PassContext. */
- virtual void ExitPassContext() const = 0;
-
- /*!
- * \brief Determine whether to run the pass or not. Called multiple times
depend on number of
- * passes.
- * \param mod The module that an optimization pass runs on.
- * \param info The pass information.
- *
- * \return true to run the pass; false to skip the pass.
- */
- virtual bool ShouldRun(const IRModule& mod, const transform::PassInfo& info)
const = 0;
-
- /*!
- * \brief Instrument before pass run. Called multiple times depend on number
of passes.
- * \param mod The module that an optimization pass runs on.
- * \param info The pass information.
- */
- virtual void RunBeforePass(const IRModule& mod, const transform::PassInfo&
info) const = 0;
-
- /*!
- * \brief Instrument after pass run. Called multiple time depend on number
of passes.
- * \param mod The module that an optimization pass runs on.
- * \param info The pass information.
- */
- virtual void RunAfterPass(const IRModule& mod, const transform::PassInfo&
info) const = 0;
-
- static void RegisterReflection() {
- namespace refl = tvm::ffi::reflection;
- refl::ObjectDef<PassInstrumentNode>().def_ro("name",
&PassInstrumentNode::name);
- }
- TVM_FFI_DECLARE_OBJECT_INFO("instrument.PassInstrument", PassInstrumentNode,
ffi::Object);
-};
-
-/*!
- * \brief Managed reference class for PassInstrumentNode
- * \sa PassInstrumentNode
- */
-class PassInstrument : public ffi::ObjectRef {
- public:
- TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(PassInstrument, ffi::ObjectRef,
PassInstrumentNode);
-};
-
-} // namespace instrument
-} // namespace tvm
-
-#endif // TVM_IR_INSTRUMENT_H_
diff --git a/include/tvm/ir/op_attr_types.h b/include/tvm/ir/op_attr_types.h
deleted file mode 100644
index ed04da5326..0000000000
--- a/include/tvm/ir/op_attr_types.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*! \file tvm/ir/op_attr_types.h
- * \brief Shared expression operator effects.
- */
-#ifndef TVM_IR_OP_ATTR_TYPES_H_
-#define TVM_IR_OP_ATTR_TYPES_H_
-
-#include <tvm/ffi/error.h>
-
-#include <cstdint>
-#include <ostream>
-
-namespace tvm {
-
-/*!
- * \brief The effect type of the call.
- */
-enum class CallEffectKind : int {
- /*! \brief Function corresponds to an annotation(e.g. likely) and can
translate to identity. */
- kExprAnnotation = 0,
- /*!
- * \brief Pure function that do not interacts
- * with any external state.
- */
- kPure = 1,
- /*!
- * \brief Function's that may read from states(e.g. RAM)
- */
- kReadState = 2,
- /*!
- * \brief Function that may read/write from states(e.g. RAM).
- */
- kUpdateState = 3,
- /*!
- * \brief Opaque function, cannot make any assumption
- */
- kOpaque = kUpdateState,
- /*!
- * \brief Special intrinsic to annotate call arguments info
- * only valid as a direct argument to a call.
- */
- kSpecialCallArg = 4,
- /*!
- * \brief Embed opaque information in the Expr, cannot be codegen.
- */
- kEmbedInfo = 5,
- /*!
- * \brief Function that changes control flow
- */
- kControlJump = 6,
-};
-
-inline std::ostream& operator<<(std::ostream& os, CallEffectKind side_effect) {
- switch (side_effect) {
- case CallEffectKind::kExprAnnotation:
- return os << "kExprAnnotation";
-
- case CallEffectKind::kPure:
- return os << "kPure";
-
- case CallEffectKind::kReadState:
- return os << "kReadState";
-
- case CallEffectKind::kUpdateState:
- return os << "kUpdateState";
-
- case CallEffectKind::kSpecialCallArg:
- return os << "kSpecialCallArg";
-
- case CallEffectKind::kEmbedInfo:
- return os << "kEmbedInfo";
-
- case CallEffectKind::kControlJump:
- return os << "kControlJump";
-
- default:
- TVM_FFI_THROW(InternalError) << "Unknown CallEffectKind: " <<
static_cast<int>(side_effect);
- }
-}
-
-/*! \brief Use integer to record the kind. */
-using TCallEffectKind = int64_t;
-
-} // namespace tvm
-#endif // TVM_IR_OP_ATTR_TYPES_H_
diff --git a/include/tvm/ir/transform.h b/include/tvm/ir/transform.h
index 5166f6e01e..0f5df6e6f5 100644
--- a/include/tvm/ir/transform.h
+++ b/include/tvm/ir/transform.h
@@ -61,7 +61,6 @@
#include <tvm/ffi/reflection/creator.h>
#include <tvm/ffi/reflection/registry.h>
#include <tvm/ffi/string.h>
-#include <tvm/ir/instrument.h>
#include <tvm/ir/module.h>
#include <tvm/ir/with_context.h>
@@ -72,68 +71,8 @@
namespace tvm {
namespace transform {
-/*!
- * \brief PassContextNode contains the information that a pass can rely on,
- * such as analysis results.
- * \sa PassContext
- */
-class PassContextNode : public ffi::Object {
- public:
- /*! \brief The default optimization level. */
- int opt_level{2};
-
- /*! \brief The list of required passes. */
- ffi::Array<ffi::String> required_pass;
- /*! \brief The list of disabled passes. */
- ffi::Array<ffi::String> disabled_pass;
- /*! \brief Pass specific configurations. */
- ffi::Map<ffi::String, Any> config;
-
- /*! \brief A list of pass instrument implementations. */
- ffi::Array<instrument::PassInstrument> instruments;
-
- PassContextNode() = default;
-
- /*!
- * \brief Get a config value from the pass context.
- *
- * \param key The config key.
- * \param default_value The default value if the key does not exist,
defaults to nullptr.
- *
- * \return The result
- *
- * \tparam TOBjectRef the expected object type.
- * \throw Error if the key exists but the value does not match TObjectRef.
- */
- template <typename TObjectRef>
- ffi::Optional<TObjectRef> GetConfig(
- const std::string& key,
- ffi::Optional<TObjectRef> default_value =
ffi::Optional<TObjectRef>(std::nullopt)) const {
- if (!config.defined()) return default_value;
- auto it = config.find(key);
- if (it != config.end()) {
- return (*it).second.as_or_throw<ffi::Optional<TObjectRef>>();
- } else {
- return default_value;
- }
- }
- // variant that uses TObjectRef to enable implicit conversion to default
value.
- template <typename TObjectRef>
- ffi::Optional<TObjectRef> GetConfig(const std::string& key, TObjectRef
default_value) const {
- return GetConfig<TObjectRef>(key,
ffi::Optional<TObjectRef>(default_value));
- }
-
- static void RegisterReflection() {
- namespace refl = tvm::ffi::reflection;
- refl::ObjectDef<PassContextNode>()
- .def_ro("opt_level", &PassContextNode::opt_level)
- .def_ro("required_pass", &PassContextNode::required_pass)
- .def_ro("disabled_pass", &PassContextNode::disabled_pass)
- .def_ro("instruments", &PassContextNode::instruments)
- .def_ro("config", &PassContextNode::config);
- }
- TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassContext", PassContextNode,
ffi::Object);
-};
+class PassInfo;
+class PassContextNode;
/*!
* \brief PassContext that is used to configure the pass behavior.
@@ -158,23 +97,17 @@ class PassContext : public ffi::ObjectRef {
/*!
* \brief constructor with ffi::ObjectPtr
*/
- explicit PassContext(ffi::ObjectPtr<PassContextNode> n) : ffi::ObjectRef(n)
{}
+ explicit PassContext(ffi::ObjectPtr<PassContextNode> n);
/*!
* \brief const accessor.
* \return const access pointer.
*/
- const PassContextNode* operator->() const {
- TVM_FFI_ICHECK(get() != nullptr);
- return static_cast<const PassContextNode*>(get());
- }
+ const PassContextNode* operator->() const;
/*!
* \brief mutable accessor.
* \return mutable access pointer.
*/
- PassContextNode* operator->() {
- TVM_FFI_ICHECK(get() != nullptr);
- return static_cast<PassContextNode*>(get_mutable());
- }
+ PassContextNode* operator->();
/*!
* \brief Construct a PassContext containing the default configurations.
@@ -578,6 +511,198 @@ TVM_DLL ffi::Error EnrichPassErrorWithContext(
const ffi::Error& err, const IRModule& mod, ffi::String pass_name,
ffi::Optional<GlobalVar> func = ffi::Optional<GlobalVar>(std::nullopt));
+} // namespace transform
+
+namespace instrument {
+
+/*!
+ * \brief PassInstrumentNode forms an instrument implementation.
+ * It provides API for users to register callbacks at different
instrumentation points.
+ *
+ * Within a PassContext, call sequence of a PassInstrument implementation is
like:
+ *
+ * with PassContext(instruments=[pi]): # pi = a PassInstrument
implementation
+ * pi.EnterPassContext()
+ *
+ * if pi.ShouldRun(Pass1):
+ * pi.RunBeforePass()
+ * Pass1()
+ * pi.RunAfterPass()
+ *
+ * if pi.ShouldRun(Pass2):
+ * pi.RunBeforePass()
+ * Pass2()
+ * pi.RunAfterPass()
+ *
+ * pi.ExitPassContext()
+ *
+ * `EnterPassContext` and `ExitPassContext` are only called once when
entering/exiting a
+ * PassContext. `ShouldRun`, `RunBeforePass` and `RunAfterPass` are called
multiple times depending
+ * on how many passes.
+ *
+ * If there are multiple pass instrumentations provided, the instrument points
are the same.
+ * PassInstrument implementations' callbacks are called in order:
+ *
+ * with PassContext(instruments=[pi1, pi2]): # pi1, pi2 = two distinct
PassInstrument impls
+ * pi.EnterPassContext() for pi in instruments
+ *
+ * should_run = all([pi.ShoudRun(Pass1) for pi in instruments)])
+ * if (should_run)
+ * pi.RunBeforePass() for pi in instruments
+ * Pass1()
+ * pi.RunAfterPass() for pi in instruments
+ *
+ * should_run = all([pi.ShouldRun(Pass2) for pi in instruments)])
+ * if (should_run)
+ * pi.RunBeforePass() for pi in instruments
+ * Pass2()
+ * pi.RunAfterPass() for pi in instruments
+ *
+ * pi.ExitPassContext() for pi in instruments
+ *
+ * Note:
+ * 1. Assume there is no dependency between PassInstrument implementations
in `instruments` .
+ * 2. `EnterPassContext` and `ExitPassContext` have `with` behavior (see
PassContext and its FFI):
+ * If there is any exception raised in `ShouldRun()`,
`RunBeforePass()`, `RunAfterPass()` and
+ * `Pass()`, `ExitPassContext()` is still called.
+ * 3. In mutiple PassInstrument instances scenario, callbacks are called in
order:
+ * If one throws exceptions, remainings will not be called.
+ *
+ * \sa PassInstrument
+ * \sa src/ir/transform.cc
+ */
+class PassInstrumentNode : public ffi::Object {
+ public:
+ /*! \brief Name of this pass instrument object. */
+ ffi::String name;
+
+ virtual ~PassInstrumentNode() {}
+
+ /*! \brief Instrument when entering PassContext. Called once within a
PassContext. */
+ virtual void EnterPassContext() const = 0;
+
+ /*! \brief Instrument when exiting PassContext. Called once within a
PassContext. */
+ virtual void ExitPassContext() const = 0;
+
+ /*!
+ * \brief Determine whether to run the pass or not. Called multiple times
depend on number of
+ * passes.
+ * \param mod The module that an optimization pass runs on.
+ * \param info The pass information.
+ *
+ * \return true to run the pass; false to skip the pass.
+ */
+ virtual bool ShouldRun(const IRModule& mod, const transform::PassInfo& info)
const = 0;
+
+ /*!
+ * \brief Instrument before pass run. Called multiple times depend on number
of passes.
+ * \param mod The module that an optimization pass runs on.
+ * \param info The pass information.
+ */
+ virtual void RunBeforePass(const IRModule& mod, const transform::PassInfo&
info) const = 0;
+
+ /*!
+ * \brief Instrument after pass run. Called multiple time depend on number
of passes.
+ * \param mod The module that an optimization pass runs on.
+ * \param info The pass information.
+ */
+ virtual void RunAfterPass(const IRModule& mod, const transform::PassInfo&
info) const = 0;
+
+ static void RegisterReflection() {
+ namespace refl = tvm::ffi::reflection;
+ refl::ObjectDef<PassInstrumentNode>().def_ro("name",
&PassInstrumentNode::name);
+ }
+ TVM_FFI_DECLARE_OBJECT_INFO("instrument.PassInstrument", PassInstrumentNode,
ffi::Object);
+};
+
+/*!
+ * \brief Managed reference class for PassInstrumentNode
+ * \sa PassInstrumentNode
+ */
+class PassInstrument : public ffi::ObjectRef {
+ public:
+ TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(PassInstrument, ffi::ObjectRef,
PassInstrumentNode);
+};
+
+} // namespace instrument
+
+namespace transform {
+
+/*!
+ * \brief PassContextNode contains the information that a pass can rely on,
+ * such as analysis results.
+ * \sa PassContext
+ */
+class PassContextNode : public ffi::Object {
+ public:
+ /*! \brief The default optimization level. */
+ int opt_level{2};
+
+ /*! \brief The list of required passes. */
+ ffi::Array<ffi::String> required_pass;
+ /*! \brief The list of disabled passes. */
+ ffi::Array<ffi::String> disabled_pass;
+ /*! \brief Pass specific configurations. */
+ ffi::Map<ffi::String, Any> config;
+
+ /*! \brief A list of pass instrument implementations. */
+ ffi::Array<instrument::PassInstrument> instruments;
+
+ PassContextNode() = default;
+
+ /*!
+ * \brief Get a config value from the pass context.
+ *
+ * \param key The config key.
+ * \param default_value The default value if the key does not exist,
defaults to nullptr.
+ *
+ * \return The result
+ *
+ * \tparam TOBjectRef the expected object type.
+ * \throw Error if the key exists but the value does not match TObjectRef.
+ */
+ template <typename TObjectRef>
+ ffi::Optional<TObjectRef> GetConfig(
+ const std::string& key,
+ ffi::Optional<TObjectRef> default_value =
ffi::Optional<TObjectRef>(std::nullopt)) const {
+ if (!config.defined()) return default_value;
+ auto it = config.find(key);
+ if (it != config.end()) {
+ return (*it).second.as_or_throw<ffi::Optional<TObjectRef>>();
+ } else {
+ return default_value;
+ }
+ }
+ // variant that uses TObjectRef to enable implicit conversion to default
value.
+ template <typename TObjectRef>
+ ffi::Optional<TObjectRef> GetConfig(const std::string& key, TObjectRef
default_value) const {
+ return GetConfig<TObjectRef>(key,
ffi::Optional<TObjectRef>(default_value));
+ }
+
+ static void RegisterReflection() {
+ namespace refl = tvm::ffi::reflection;
+ refl::ObjectDef<PassContextNode>()
+ .def_ro("opt_level", &PassContextNode::opt_level)
+ .def_ro("required_pass", &PassContextNode::required_pass)
+ .def_ro("disabled_pass", &PassContextNode::disabled_pass)
+ .def_ro("instruments", &PassContextNode::instruments)
+ .def_ro("config", &PassContextNode::config);
+ }
+ TVM_FFI_DECLARE_OBJECT_INFO_FINAL("transform.PassContext", PassContextNode,
ffi::Object);
+};
+
+inline PassContext::PassContext(ffi::ObjectPtr<PassContextNode> n) :
ffi::ObjectRef(n) {}
+
+inline const PassContextNode* PassContext::operator->() const {
+ TVM_FFI_ICHECK(get() != nullptr);
+ return static_cast<const PassContextNode*>(get());
+}
+
+inline PassContextNode* PassContext::operator->() {
+ TVM_FFI_ICHECK(get() != nullptr);
+ return static_cast<PassContextNode*>(get_mutable());
+}
+
} // namespace transform
} // namespace tvm
diff --git a/src/ir/instrument.cc b/src/ir/instrument.cc
index 42d4ad0fe0..a77dd30a06 100644
--- a/src/ir/instrument.cc
+++ b/src/ir/instrument.cc
@@ -24,7 +24,6 @@
#include <tvm/ffi/extra/dataclass.h>
#include <tvm/ffi/function.h>
#include <tvm/ffi/reflection/registry.h>
-#include <tvm/ir/instrument.h>
#include <tvm/ir/transform.h>
#include <tvm/runtime/logging.h>
diff --git a/src/ir/prim/builtin.cc b/src/ir/prim/builtin.cc
index f4b7e43d57..fbf70bda5b 100644
--- a/src/ir/prim/builtin.cc
+++ b/src/ir/prim/builtin.cc
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-#include <tvm/ir/op_attr_types.h>
+#include <tvm/ir/expr.h>
#include <tvm/ir/prim/builtin.h>
namespace tvm {
diff --git a/src/relax/utils.cc b/src/relax/utils.cc
index e5dbd0a226..bac3fe8c8a 100644
--- a/src/relax/utils.cc
+++ b/src/relax/utils.cc
@@ -22,7 +22,7 @@
#include <tvm/ffi/cast.h>
#include <tvm/ffi/extra/structural_mutate.h>
#include <tvm/ffi/reflection/registry.h>
-#include <tvm/ir/op_attr_types.h>
+#include <tvm/ir/expr.h>
#include <tvm/relax/analysis.h>
#include <tvm/relax/attrs/index.h>
#include <tvm/relax/expr_functor.h>
diff --git a/src/sym/z3_prover.cc b/src/sym/z3_prover.cc
index 6fffc537a2..f51b2c3a76 100644
--- a/src/sym/z3_prover.cc
+++ b/src/sym/z3_prover.cc
@@ -29,8 +29,8 @@
#include <tvm/ffi/extra/structural_equal.h>
#include <tvm/ffi/extra/structural_hash.h>
+#include <tvm/ir/expr.h>
#include <tvm/ir/expr_functor.h>
-#include <tvm/ir/op_attr_types.h>
#include <tvm/ir/prim/builtin.h>
#include <tvm/ir/prim/expr.h>
#include <tvm/ir/prim/op.h>
diff --git a/tests/cpp/tir_analysis_side_effect.cc
b/tests/cpp/tir_analysis_side_effect.cc
index 7f9b181bff..4a9af3c3d5 100644
--- a/tests/cpp/tir_analysis_side_effect.cc
+++ b/tests/cpp/tir_analysis_side_effect.cc
@@ -19,7 +19,6 @@
#include <gtest/gtest.h>
#include <tvm/ir/expr.h>
-#include <tvm/ir/op_attr_types.h>
#include <tvm/ir/prim/builtin.h>
#include <tvm/runtime/logging.h>
#include <tvm/te/operation.h>