@@ -320,17 +320,50 @@ class FuncStructInfoNode : public StructInfoNode {
320320 Optional<StructInfoDeriveFunc> derive_func;
321321 /* !
322322 * \brief Whether the function is pure.
323- * \note This parameter should be set to true only if the function is pure on all inputs.
324- * If the function _may_ have visible side effects, set it to false.
323+ *
324+ * There are three possible state for this value.
325+ *
326+ * `Bool(true)`: The function is known to be pure.
327+ * `Bool(false)`: The function is known to be impure.
328+ * `NullOpt`: The function's purity is unknown.
329+ *
330+ * In most cases `Bool(false)` and `NullOpt` should be treated
331+ * equivalently, as they both indicate a function that may contain
332+ * side effects. However, inference of purity may occur when the
333+ * purity is `NullOpt`, based on analysis of a function's body. A
334+ * function with purity of `Bool(false)` is known to be impure, and
335+ * further analysis is unnecessary.
336+ *
337+ * \note This parameter should be set to true only if the function
338+ * is pure on all inputs. If the function _may_ have visible side
339+ * effects, set it to false.
325340 */
326- bool purity;
341+ Optional<Bool> purity;
327342
328343 /* !
329344 * \return Whether the func struct info is opaque.
330345 * \note We define a function as opaque we have no constraints on params.
331346 */
332347 bool IsOpaque () const { return !params.defined (); }
333348
349+ /* ! \brief Whether the FuncStructInfo is known to be pure */
350+ bool IsPure () const {
351+ if (purity.defined ()) {
352+ return purity.value ()->value ;
353+ } else {
354+ return false ;
355+ }
356+ }
357+
358+ /* ! \brief Whether the function is known to be impure. */
359+ bool IsImpure () const {
360+ if (purity.defined ()) {
361+ return !purity.value ()->value ;
362+ } else {
363+ return false ;
364+ }
365+ }
366+
334367 void VisitAttrs (AttrVisitor* v) {
335368 v->Visit (" params" , ¶ms);
336369 v->Visit (" ret" , &ret);
@@ -365,42 +398,82 @@ class FuncStructInfo : public StructInfo {
365398 * \brief Constructor from parameter struct info and return value struct info.
366399 * \param params The struct info of function parameters.
367400 * \param ret The return value struct info.
368- * \param purity The purity of the function (true by default).
401+ * \param purity The purity of the function (unknown by default).
369402 * \param span The span of the AST.
370403 *
371404 * \note If the ret contains variables(tir::Var and relax::Var), they must be deducible from
372405 * params. If you are unsure, you can always erase ret to static.
373406 */
374- TVM_DLL FuncStructInfo (Array<StructInfo> params, StructInfo ret, bool purity = true ,
407+ TVM_DLL FuncStructInfo (Array<StructInfo> params, StructInfo ret, Optional<Bool> purity = NullOpt ,
375408 Span span = Span());
376409
410+ /* !
411+ * \brief Constructor from parameter struct info and return value struct info.
412+ * \param params The struct info of function parameters.
413+ * \param ret The return value struct info.
414+ * \param purity The purity of the function.
415+ * \param span The span of the AST.
416+ *
417+ * \note If the ret contains variables(tir::Var and relax::Var), they must be deducible from
418+ * params. If you are unsure, you can always erase ret to static.
419+ */
420+ TVM_DLL FuncStructInfo (Array<StructInfo> params, StructInfo ret, bool purity, Span span = Span())
421+ : FuncStructInfo(params, ret, Optional<Bool>(Bool(purity)), span) {}
422+
423+ /* !
424+ * \brief Constructing an opaque function struct info using derive_func.
425+ *
426+ * \param derive_func Derivation function.
427+ * \param purity The purity of the function (unknown by default).
428+ * \param span The span of the AST.
429+ *
430+ * \return The FuncStructInfo for opaque packedfunc.
431+ * \note Defaults to an derive func that always return ObjectStructInfo if not specified.
432+ */
433+ TVM_DLL static FuncStructInfo OpaqueFunc (StructInfoDeriveFunc derive_func,
434+ Optional<Bool> purity = NullOpt, Span span = Span());
435+
377436 /* !
378437 * \brief Constructing an opaque function struct info using derive_func.
379438 *
380439 * \param derive_func Derivation function.
381- * \param purity The purity of the function
382- * (false by default: most external functions are not pure).
440+ * \param purity The purity of the function.
441+ * \param span The span of the AST.
442+ *
443+ * \return The FuncStructInfo for opaque packedfunc.
444+ * \note Defaults to an derive func that always return ObjectStructInfo if not specified.
445+ */
446+ TVM_DLL static FuncStructInfo OpaqueFunc (StructInfoDeriveFunc derive_func, bool purity,
447+ Span span = Span()) {
448+ return OpaqueFunc (derive_func, Optional<Bool>(Bool (purity)), span);
449+ }
450+
451+ /* !
452+ * \brief Construct an opaque function using from return struct info.
453+ *
454+ * \param ret The struct info of the return value.
455+ * \param purity The purity of the function (unknown by default).
383456 * \param span The span of the AST.
384457 *
385458 * \return The FuncStructInfo for opaque packedfunc.
386459 * \note Defaults to an derive func that always return ObjectStructInfo if not specified.
387460 */
388- TVM_DLL static FuncStructInfo OpaqueFunc (StructInfoDeriveFunc derive_func, bool purity = false ,
389- Span span = Span());
461+ TVM_DLL static FuncStructInfo OpaqueFunc (StructInfo ret = ObjectStructInfo() ,
462+ Optional<Bool> purity = NullOpt, Span span = Span());
390463
391464 /* !
392465 * \brief Construct an opaque function using from return struct info.
393466 *
394467 * \param ret The struct info of the return value.
395- * \param purity The purity of the function
396- * (false by default: most external functions are not pure).
468+ * \param purity The purity of the function.
397469 * \param span The span of the AST.
398470 *
399471 * \return The FuncStructInfo for opaque packedfunc.
400472 * \note Defaults to an derive func that always return ObjectStructInfo if not specified.
401473 */
402- TVM_DLL static FuncStructInfo OpaqueFunc (StructInfo ret = ObjectStructInfo(), bool purity = false,
403- Span span = Span());
474+ TVM_DLL static FuncStructInfo OpaqueFunc (StructInfo ret, bool purity, Span span = Span()) {
475+ return OpaqueFunc (ret, Optional<Bool>(Bool (purity)), span);
476+ }
404477
405478 TVM_DEFINE_NOTNULLABLE_OBJECT_REF_METHODS (FuncStructInfo, StructInfo, FuncStructInfoNode);
406479};
0 commit comments