//===- CyclicReplacerCache.h ------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file contains helper classes for caching replacer-like functions that // map values between two domains. They are able to handle replacer logic that // contains self-recursion. // //===----------------------------------------------------------------------===// #ifndef MLIR_SUPPORT_CYCLICREPLACERCACHE_H #define MLIR_SUPPORT_CYCLICREPLACERCACHE_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallVector.h" #include <functional> #include <optional> #include <set> namespace mlir { //===----------------------------------------------------------------------===// // CyclicReplacerCache //===----------------------------------------------------------------------===// /// A cache for replacer-like functions that map values between two domains. The /// difference compared to just using a map to cache in-out pairs is that this /// class is able to handle replacer logic that is self-recursive (and thus may /// cause infinite recursion in the naive case). /// /// This class provides a hook for the user to perform cycle pruning when a /// cycle is identified, and is able to perform context-sensitive caching so /// that the replacement result for an input that is part of a pruned cycle can /// be distinct from the replacement result for the same input when it is not /// part of a cycle. /// /// In addition, this class allows deferring cycle pruning until specific inputs /// are repeated. This is useful for cases where not all elements in a cycle can /// perform pruning. The user still must guarantee that at least one element in /// any given cycle can perform pruning. Even if not, an assertion will /// eventually be tripped instead of infinite recursion (the run-time is /// linearly bounded by the maximum cycle length of its input). /// /// WARNING: This class works best with InT & OutT that are trivial scalar /// types. The input/output elements will be frequently copied and hashed. template <typename InT, typename OutT> class CyclicReplacerCache { … }; template <typename InT, typename OutT> typename CyclicReplacerCache<InT, OutT>::CacheEntry CyclicReplacerCache<InT, OutT>::lookupOrInit(InT element) { … } template <typename InT, typename OutT> void CyclicReplacerCache<InT, OutT>::finalizeReplacement(InT element, OutT result) { … } //===----------------------------------------------------------------------===// // CachedCyclicReplacer //===----------------------------------------------------------------------===// /// A helper class for cases where the input/output types of the replacer /// function is identical to the types stored in the cache. This class wraps /// the user-provided replacer function, and can be used in place of the user /// function. template <typename InT, typename OutT> class CachedCyclicReplacer { … }; } // namespace mlir #endif // MLIR_SUPPORT_CYCLICREPLACERCACHE_H