CIRCT  18.0.0git
HWOpInterfaces.cpp
Go to the documentation of this file.
1 //===- HWOpInterfaces.cpp - Implement the HW op interfaces ----------------===//
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 implement the HW operation interfaces.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "circt/Dialect/HW/HWOps.h"
16 #include "circt/Support/LLVM.h"
17 #include "mlir/IR/BuiltinAttributes.h"
18 #include "mlir/IR/BuiltinTypes.h"
19 #include "llvm/ADT/SmallBitVector.h"
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include "llvm/ADT/StringRef.h"
22 
23 using namespace circt;
24 
25 hw::InnerSymAttr hw::PortInfo::getSym() const {
26  if (attrs)
27  return attrs.getAs<::circt::hw::InnerSymAttr>(
28  hw::HWModuleLike::getPortSymbolAttrName());
29  return {};
30 }
31 
32 void hw::PortInfo::setSym(InnerSymAttr sym, MLIRContext *ctx) {
33  auto portSymAttr =
34  StringAttr::get(ctx, hw::HWModuleLike::getPortSymbolAttrName());
35  NamedAttrList pattr(attrs);
36  Attribute oldValue;
37  if (!sym)
38  oldValue = pattr.erase(portSymAttr);
39  else
40  oldValue = pattr.set(portSymAttr, sym);
41  if (oldValue != sym) {
42  attrs = pattr.getDictionary(ctx);
43  }
44 }
45 
46 LogicalResult hw::verifyInnerSymAttr(InnerSymbolOpInterface op) {
47  auto innerSym = op.getInnerSymAttr();
48  // If does not have any inner sym then ignore.
49  if (!innerSym)
50  return success();
51 
52  if (innerSym.empty())
53  return op->emitOpError("has empty list of inner symbols");
54 
55  if (!op.supportsPerFieldSymbols()) {
56  // The inner sym can only be specified on fieldID=0.
57  if (innerSym.size() > 1 || !innerSym.getSymName()) {
58  op->emitOpError("does not support per-field inner symbols");
59  return failure();
60  }
61  return success();
62  }
63 
64  auto result = op.getTargetResult();
65  // If op supports per-field symbols, but does not have a target result,
66  // its up to the operation to verify itself.
67  // (there are no uses for this presently, but be open to this anyway.)
68  if (!result)
69  return success();
70  auto resultType = result.getType();
71  auto maxFields = FieldIdImpl::getMaxFieldID(resultType);
72  llvm::SmallBitVector indices(maxFields + 1);
73  llvm::SmallPtrSet<Attribute, 8> symNames;
74  // Ensure fieldID and symbol names are unique.
75  auto uniqSyms = [&](InnerSymPropertiesAttr p) {
76  if (maxFields < p.getFieldID()) {
77  op->emitOpError("field id:'" + Twine(p.getFieldID()) +
78  "' is greater than the maximum field id:'" +
79  Twine(maxFields) + "'");
80  return false;
81  }
82  if (indices.test(p.getFieldID())) {
83  op->emitOpError("cannot assign multiple symbol names to the field id:'" +
84  Twine(p.getFieldID()) + "'");
85  return false;
86  }
87  indices.set(p.getFieldID());
88  auto it = symNames.insert(p.getName());
89  if (!it.second) {
90  op->emitOpError("cannot reuse symbol name:'" + p.getName().getValue() +
91  "'");
92  return false;
93  }
94  return true;
95  };
96 
97  if (!llvm::all_of(innerSym.getProps(), uniqSyms))
98  return failure();
99 
100  return success();
101 }
102 
103 raw_ostream &circt::hw::operator<<(raw_ostream &printer, PortInfo port) {
104  StringRef dirstr;
105  switch (port.dir) {
107  dirstr = "input";
108  break;
110  dirstr = "output";
111  break;
113  dirstr = "inout";
114  break;
115  }
116  printer << dirstr << " " << port.name << " : " << port.type << " (argnum "
117  << port.argNum << ", sym " << port.getSym() << ", loc " << port.loc
118  << ", args " << port.attrs << ")";
119  return printer;
120 }
121 
122 #include "circt/Dialect/HW/HWOpInterfaces.cpp.inc"
@ Input
Definition: HW.h:32
@ Output
Definition: HW.h:32
@ InOut
Definition: HW.h:32
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:53
uint64_t getMaxFieldID(Type)
raw_ostream & operator<<(raw_ostream &printer, PortInfo port)
LogicalResult verifyInnerSymAttr(InnerSymbolOpInterface op)
Verification hook for verifying InnerSym Attribute.
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
Definition: DebugAnalysis.h:21
mlir::Type type
Definition: HWTypes.h:30
mlir::StringAttr name
Definition: HWTypes.h:29
This holds the name, type, direction of a module's ports.
DictionaryAttr attrs
The optional symbol for this port.
size_t argNum
This is the argument index or the result index depending on the direction.
void setSym(InnerSymAttr sym, MLIRContext *ctx)
InnerSymAttr getSym() const