CIRCT  19.0.0git
PassCommon.cpp
Go to the documentation of this file.
1 //===- PassCommon.cpp - PassCommon ------------------------------*- 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 #include "PassDetails.h"
12 
13 using namespace mlir;
14 using namespace circt;
15 using namespace msft;
16 
17 SmallVector<unsigned> circt::msft::makeSequentialRange(unsigned size) {
18  SmallVector<unsigned> seq;
19  for (size_t i = 0; i < size; ++i)
20  seq.push_back(i);
21  return seq;
22 }
23 
24 StringRef circt::msft::getValueName(Value v, const SymbolCache &syms,
25  std::string &buff) {
26  Operation *defOp = v.getDefiningOp();
27  if (auto inst = dyn_cast_or_null<hw::InstanceOp>(defOp)) {
28  Operation *modOp = syms.getDefinition(inst.getModuleNameAttr());
29  if (modOp) { // If modOp isn't in the cache, it's probably a new module;
30  assert(isa<hw::HWModuleLike>(modOp) && "Instance must point to a module");
31  OpResult instResult = cast<OpResult>(v);
32  auto mod = cast<hw::HWModuleLike>(modOp);
33  buff.clear();
34  llvm::raw_string_ostream os(buff);
35  os << inst.getInstanceName() << ".";
36  StringAttr name = mod.getOutputNameAttr(instResult.getResultNumber());
37  if (name)
38  os << name.getValue();
39  return buff;
40  }
41  }
42  if (auto blockArg = dyn_cast<BlockArgument>(v)) {
43  hw::ModulePortInfo portInfo(
44  cast<hw::PortList>(blockArg.getOwner()->getParent()->getParentOp())
45  .getPortList());
46  return portInfo.atInput(blockArg.getArgNumber()).getName();
47  }
48  if (auto constOp = dyn_cast<hw::ConstantOp>(defOp)) {
49  buff.clear();
50  llvm::raw_string_ostream(buff) << "c" << constOp.getValue();
51  return buff;
52  }
53 
54  return "";
55 }
56 
57 void PassCommon::getAndSortModules(ModuleOp topMod,
58  SmallVectorImpl<hw::HWModuleLike> &mods) {
59  // Add here _before_ we go deeper to prevent infinite recursion.
60  DenseSet<Operation *> modsSeen;
61  mods.clear();
62  moduleInstantiations.clear();
63  topMod.walk([&](hw::HWModuleLike mod) {
64  getAndSortModulesVisitor(mod, mods, modsSeen);
65  });
66 }
67 
68 // Run a post-order DFS.
69 void PassCommon::getAndSortModulesVisitor(
70  hw::HWModuleLike mod, SmallVectorImpl<hw::HWModuleLike> &mods,
71  DenseSet<Operation *> &modsSeen) {
72  if (modsSeen.contains(mod))
73  return;
74  modsSeen.insert(mod);
75 
76  mod.walk([&](igraph::InstanceOpInterface inst) {
77  auto targetNameAttrs = inst.getReferencedModuleNamesAttr();
78  for (auto targetNameAttr : targetNameAttrs) {
79  Operation *modOp =
80  topLevelSyms.getDefinition(cast<StringAttr>(targetNameAttr));
81  assert(modOp);
82  moduleInstantiations[modOp].push_back(inst);
83  if (auto modLike = dyn_cast<hw::HWModuleLike>(modOp))
84  getAndSortModulesVisitor(modLike, mods, modsSeen);
85  }
86  });
87 
88  mods.push_back(mod);
89 }
assert(baseType &&"element must be base type")
Default symbol cache implementation; stores associations between names (StringAttr's) to mlir::Operat...
Definition: SymCache.h:85
mlir::Operation * getDefinition(mlir::Attribute attr) const override
Lookup a definition for 'symbol' in the cache.
Definition: SymCache.h:94
StringRef getValueName(Value v, const SymbolCache &syms, std::string &buff)
Try to get a "good" name for the given Value.
Definition: PassCommon.cpp:24
SmallVector< unsigned > makeSequentialRange(unsigned size)
Utility for creating {0, 1, 2, ..., size}.
Definition: PassCommon.cpp:17
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
Definition: msft.py:1
Definition: seq.py:1
This holds a decoded list of input/inout and output ports for a module or instance.
PortInfo & atInput(size_t idx)
StringRef getName() const