13 #include "llvm/ADT/SmallSet.h"
14 #include "llvm/Support/Debug.h"
16 #define DEBUG_TYPE "hw-reductions"
19 using namespace circt;
28 void clear() { moduleSizes.clear(); }
32 if (
auto it = moduleSizes.find(module); it != moduleSizes.end())
35 module->walk([&](Operation *op) {
37 if (
auto instOp = dyn_cast<HWInstanceLike>(op)) {
38 for (
auto moduleName : instOp.getReferencedModuleNamesAttr()) {
39 auto *node = instanceGraph.lookup(moduleName.cast<StringAttr>());
41 dyn_cast_or_null<hw::HWModuleLike>(*node->getModule()))
42 size += getModuleSize(instModule, instanceGraph);
46 moduleSizes.insert({module, size});
51 llvm::DenseMap<Operation *, uint64_t> moduleSizes;
61 instanceGraph = std::make_unique<InstanceGraph>(op);
66 return moduleSizes.getModuleSize(op, *instanceGraph);
72 op.getPortList(), StringRef(),
78 std::string
getName()
const override {
return "hw-module-externalizer"; }
87 template <
unsigned OpNum>
89 uint64_t
match(Operation *op)
override {
90 if (op->getNumResults() != 1 || op->getNumOperands() < 2 ||
91 OpNum >= op->getNumOperands())
93 auto resultTy = op->getResult(0).getType().dyn_cast<IntegerType>();
94 auto opTy = op->getOperand(OpNum).getType().dyn_cast<IntegerType>();
95 return resultTy && opTy && resultTy == opTy &&
96 op->getResult(0) != op->getOperand(OpNum);
98 LogicalResult
rewrite(Operation *op)
override {
100 ImplicitLocOpBuilder
builder(op->getLoc(), op);
101 auto result = op->getResult(0);
102 auto operand = op->getOperand(OpNum);
103 LLVM_DEBUG(llvm::dbgs()
104 <<
"Forwarding " << operand <<
" in " << *op <<
"\n");
105 result.replaceAllUsesWith(operand);
110 return (
"hw-operand" + Twine(OpNum) +
"-forwarder").str();
117 uint64_t
match(Operation *op)
override {
118 if (op->getNumResults() == 0 || op->getNumOperands() == 0)
120 return llvm::all_of(op->getResults(), [](Value result) {
121 return result.getType().isa<IntegerType>();
124 LogicalResult
rewrite(Operation *op)
override {
127 for (
auto result : op->getResults()) {
128 auto type = result.getType().cast<IntegerType>();
130 result.replaceAllUsesWith(newOp);
135 std::string
getName()
const override {
return "hw-constantifier"; }
142 void HWReducePatternDialectInterface::populateReducePatterns(
157 mlir::DialectRegistry ®istry) {
158 registry.addExtension(+[](MLIRContext *ctx, HWDialect *dialect) {
assert(baseType &&"element must be base type")
void registerReducePatternDialectInterface(mlir::DialectRegistry ®istry)
Register the Arc Reduction pattern dialect interface to the given registry.
std::map< std::string, std::set< std::string > > InstanceGraph
Iterates over the handshake::FuncOp's in the program to build an instance graph.
void pruneUnusedOps(Operation *initialOp, Reduction &reduction)
Starting at the given op, traverse through it and its operands and erase operations that have no more...
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
A sample reduction pattern that replaces integer operations with a constant zero of their type.
uint64_t match(Operation *op) override
Check if the reduction can apply to a specific operation.
std::string getName() const override
Return a human-readable name for this reduction pattern.
LogicalResult rewrite(Operation *op) override
Apply the reduction to a specific operation.
A sample reduction pattern that replaces all uses of an operation with one of its operands.
LogicalResult rewrite(Operation *op) override
Apply the reduction to a specific operation.
uint64_t match(Operation *op) override
Check if the reduction can apply to a specific operation.
std::string getName() const override
Return a human-readable name for this reduction pattern.
A sample reduction pattern that maps hw.module to hw.module.extern.
std::string getName() const override
Return a human-readable name for this reduction pattern.
LogicalResult rewrite(HWModuleOp op) override
std::unique_ptr< InstanceGraph > instanceGraph
void beforeReduction(mlir::ModuleOp op) override
Called before the reduction is applied to a new subset of operations.
uint64_t match(HWModuleOp op) override
ModuleSizeCache moduleSizes
Utility to track the transitive size of modules.
uint64_t getModuleSize(HWModuleLike module, hw::InstanceGraph &instanceGraph)
An abstract reduction pattern.
A dialect interface to provide reduction patterns to a reducer tool.