CIRCT  19.0.0git
SymCache.h
Go to the documentation of this file.
1 //===- SymCache.h - Declare Symbol Cache ------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares a Symbol Cache.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef CIRCT_SUPPORT_SYMCACHE_H
14 #define CIRCT_SUPPORT_SYMCACHE_H
15 
16 #include "mlir/IR/SymbolTable.h"
17 #include "llvm/ADT/iterator.h"
18 #include "llvm/Support/Casting.h"
19 
20 namespace circt {
21 
22 /// Base symbol cache class to allow for cache lookup through a pointer to some
23 /// abstract cache. A symbol cache stores lookup tables to make manipulating and
24 /// working with the IR more efficient.
26 public:
27  virtual ~SymbolCacheBase();
28 
29  /// Defines 'op' as associated with the 'symbol' in the cache.
30  virtual void addDefinition(mlir::Attribute symbol, mlir::Operation *op) = 0;
31 
32  /// Adds the symbol-defining 'op' to the cache.
33  void addSymbol(mlir::SymbolOpInterface op) {
34  addDefinition(op.getNameAttr(), op);
35  }
36 
37  /// Populate the symbol cache with all symbol-defining operations within the
38  /// 'top' operation.
39  void addDefinitions(mlir::Operation *top);
40 
41  /// Lookup a definition for 'symbol' in the cache.
42  virtual mlir::Operation *getDefinition(mlir::Attribute symbol) const = 0;
43 
44  /// Lookup a definition for 'symbol' in the cache.
45  mlir::Operation *getDefinition(mlir::FlatSymbolRefAttr symbol) const {
46  return getDefinition(symbol.getAttr());
47  }
48 
49  /// Iterator support through a pointer to some abstract cache.
50  /// The implementing cache must provide an iterator that carries values on the
51  /// form of <mlir::Attribute, mlir::Operation*>.
52  using CacheItem = std::pair<mlir::Attribute, mlir::Operation *>;
54  virtual ~CacheIteratorImpl() {}
55  virtual void operator++() = 0;
56  virtual CacheItem operator*() = 0;
57  virtual bool operator==(CacheIteratorImpl *other) = 0;
58  };
59 
60  struct Iterator
61  : public llvm::iterator_facade_base<Iterator, std::forward_iterator_tag,
62  CacheItem> {
63  Iterator(std::unique_ptr<CacheIteratorImpl> &&impl)
64  : impl(std::move(impl)) {}
65  CacheItem operator*() const { return **impl; }
66  using llvm::iterator_facade_base<Iterator, std::forward_iterator_tag,
67  CacheItem>::operator++;
68  bool operator==(const Iterator &other) const {
69  return *impl == other.impl.get();
70  }
71  void operator++() { impl->operator++(); }
72 
73  private:
74  std::unique_ptr<CacheIteratorImpl> impl;
75  };
76  virtual Iterator begin() = 0;
77  virtual Iterator end() = 0;
78 };
79 
80 /// Default symbol cache implementation; stores associations between names
81 /// (StringAttr's) to mlir::Operation's.
82 /// Adding/getting definitions from the symbol cache is not
83 /// thread safe. If this is required, synchronizing cache acccess should be
84 /// ensured by the caller.
85 class SymbolCache : public SymbolCacheBase {
86 public:
87  /// In the building phase, add symbols.
88  void addDefinition(mlir::Attribute key, mlir::Operation *op) override {
89  symbolCache.try_emplace(key, op);
90  }
91 
92  // Pull in getDefinition(mlir::FlatSymbolRefAttr symbol)
94  mlir::Operation *getDefinition(mlir::Attribute attr) const override {
95  auto it = symbolCache.find(attr);
96  if (it == symbolCache.end())
97  return nullptr;
98  return it->second;
99  }
100 
101 protected:
102  /// This stores a lookup table from symbol attribute to the operation
103  /// that defines it.
104  llvm::DenseMap<mlir::Attribute, mlir::Operation *> symbolCache;
105 
106 private:
107  /// Iterator support: A simple mapping between decltype(symbolCache)::iterator
108  /// to SymbolCacheBase::Iterator.
109  using Iterator = decltype(symbolCache)::iterator;
112  CacheItem operator*() override { return {it->getFirst(), it->getSecond()}; }
113  void operator++() override { it++; }
114  bool operator==(CacheIteratorImpl *other) override {
115  return it == static_cast<SymbolCacheIteratorImpl *>(other)->it;
116  }
118  };
119 
120 public:
123  std::make_unique<SymbolCacheIteratorImpl>(symbolCache.begin()));
124  }
127  std::make_unique<SymbolCacheIteratorImpl>(symbolCache.end()));
128  }
129 };
130 
131 } // namespace circt
132 
133 #endif // CIRCT_SUPPORT_SYMCACHE_H
Base symbol cache class to allow for cache lookup through a pointer to some abstract cache.
Definition: SymCache.h:25
void addDefinitions(mlir::Operation *top)
Populate the symbol cache with all symbol-defining operations within the 'top' operation.
Definition: SymCache.cpp:23
virtual Iterator end()=0
void addSymbol(mlir::SymbolOpInterface op)
Adds the symbol-defining 'op' to the cache.
Definition: SymCache.h:33
virtual ~SymbolCacheBase()
Virtual method anchor.
Definition: SymCache.cpp:21
virtual void addDefinition(mlir::Attribute symbol, mlir::Operation *op)=0
Defines 'op' as associated with the 'symbol' in the cache.
virtual mlir::Operation * getDefinition(mlir::Attribute symbol) const =0
Lookup a definition for 'symbol' in the cache.
virtual Iterator begin()=0
mlir::Operation * getDefinition(mlir::FlatSymbolRefAttr symbol) const
Lookup a definition for 'symbol' in the cache.
Definition: SymCache.h:45
std::pair< mlir::Attribute, mlir::Operation * > CacheItem
Iterator support through a pointer to some abstract cache.
Definition: SymCache.h:52
Default symbol cache implementation; stores associations between names (StringAttr's) to mlir::Operat...
Definition: SymCache.h:85
void addDefinition(mlir::Attribute key, mlir::Operation *op) override
In the building phase, add symbols.
Definition: SymCache.h:88
llvm::DenseMap< mlir::Attribute, mlir::Operation * > symbolCache
This stores a lookup table from symbol attribute to the operation that defines it.
Definition: SymCache.h:104
decltype(symbolCache)::iterator Iterator
Iterator support: A simple mapping between decltype(symbolCache)::iterator to SymbolCacheBase::Iterat...
Definition: SymCache.h:109
SymbolCacheBase::Iterator end() override
Definition: SymCache.h:125
SymbolCacheBase::Iterator begin() override
Definition: SymCache.h:121
mlir::Operation * getDefinition(mlir::Attribute attr) const override
Lookup a definition for 'symbol' in the cache.
Definition: SymCache.h:94
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
virtual bool operator==(CacheIteratorImpl *other)=0
CacheItem operator*() const
Definition: SymCache.h:65
std::unique_ptr< CacheIteratorImpl > impl
Definition: SymCache.h:74
Iterator(std::unique_ptr< CacheIteratorImpl > &&impl)
Definition: SymCache.h:63
bool operator==(const Iterator &other) const
Definition: SymCache.h:68
bool operator==(CacheIteratorImpl *other) override
Definition: SymCache.h:114