CIRCT 23.0.0git
Loading...
Searching...
No Matches
SimTypes.cpp
Go to the documentation of this file.
1//===- SimTypes.cpp -------------------------------------------------------===//
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
12#include "mlir/IR/Builders.h"
13#include "mlir/IR/DialectImplementation.h"
14#include "llvm/ADT/TypeSwitch.h"
15
16// Include the generated enum definitions (DPIDirection).
17#include "circt/Dialect/Sim/SimEnums.h.inc"
18
19using namespace circt;
20using namespace sim;
21using namespace mlir;
22
23//===----------------------------------------------------------------------===//
24// DPIDirection helpers
25//===----------------------------------------------------------------------===//
26
27StringRef sim::stringifyDPIDirectionKeyword(DPIDirection dir) {
28 switch (dir) {
29 case DPIDirection::Input:
30 return "in";
31 case DPIDirection::Output:
32 return "out";
33 case DPIDirection::InOut:
34 return "inout";
35 case DPIDirection::Return:
36 return "return";
37 case DPIDirection::Ref:
38 return "ref";
39 }
40 llvm_unreachable("unknown DPIDirection");
41}
42
43std::optional<DPIDirection> sim::parseDPIDirectionKeyword(StringRef keyword) {
44 return llvm::StringSwitch<std::optional<DPIDirection>>(keyword)
45 .Case("in", DPIDirection::Input)
46 .Case("out", DPIDirection::Output)
47 .Case("inout", DPIDirection::InOut)
48 .Case("return", DPIDirection::Return)
49 .Case("ref", DPIDirection::Ref)
50 .Default(std::nullopt);
51}
52
53bool sim::isCallOperandDir(DPIDirection dir) {
54 return dir == DPIDirection::Input || dir == DPIDirection::InOut ||
55 dir == DPIDirection::Ref;
56}
57
58#define GET_TYPEDEF_CLASSES
59#include "circt/Dialect/Sim/SimTypes.cpp.inc"
60
61void SimDialect::registerTypes() {
62 addTypes<
63#define GET_TYPEDEF_LIST
64#include "circt/Dialect/Sim/SimTypes.cpp.inc"
65 >();
66}
67
68//===----------------------------------------------------------------------===//
69// DPIFunctionType storage
70//===----------------------------------------------------------------------===//
71
73 ArrayRef<DPIArgument> dpiArgs)
74 : arguments(dpiArgs) {
75 for (auto [idx, a] : llvm::enumerate(arguments)) {
76 if (a.dir == DPIDirection::Input || a.dir == DPIDirection::InOut ||
77 a.dir == DPIDirection::Ref)
78 inputToAbs.push_back(idx);
79 if (a.dir == DPIDirection::Output || a.dir == DPIDirection::InOut ||
80 a.dir == DPIDirection::Return)
81 resultToAbs.push_back(idx);
82 }
83}
84
86sim::detail::DPIFunctionTypeStorage::construct(TypeStorageAllocator &allocator,
87 const KeyTy &key) {
88 auto *storage = new (allocator.allocate<DPIFunctionTypeStorage>())
90 // Compute and cache the MLIR FunctionType.
91 SmallVector<Type> inputs, results;
92 for (auto &arg : storage->arguments) {
93 if (arg.dir == DPIDirection::Input || arg.dir == DPIDirection::InOut ||
94 arg.dir == DPIDirection::Ref)
95 inputs.push_back(arg.type);
96 if (arg.dir == DPIDirection::Output || arg.dir == DPIDirection::InOut ||
97 arg.dir == DPIDirection::Return)
98 results.push_back(arg.type);
99 }
100 MLIRContext *ctx = nullptr;
101 if (!storage->arguments.empty()) {
102 ctx = storage->arguments[0].type.getContext();
103 assert(ctx && "DPIArgument types must have a valid MLIRContext");
104 }
105 if (ctx)
106 storage->cachedFuncType = FunctionType::get(ctx, inputs, results);
107 return storage;
108}
109
110//===----------------------------------------------------------------------===//
111// DPIFunctionType methods
112//===----------------------------------------------------------------------===//
113
114ArrayRef<DPIArgument> DPIFunctionType::getArguments() const {
115 return getImpl()->getArguments();
116}
117
118size_t DPIFunctionType::getNumArguments() const {
119 return getImpl()->arguments.size();
120}
121
122SmallVector<DPIArgument> DPIFunctionType::getInputArguments() const {
123 SmallVector<DPIArgument> result;
124 for (auto idx : getImpl()->inputToAbs)
125 result.push_back(getImpl()->arguments[idx]);
126 return result;
127}
128
129SmallVector<DPIArgument> DPIFunctionType::getResultArguments() const {
130 SmallVector<DPIArgument> result;
131 for (auto idx : getImpl()->resultToAbs)
132 result.push_back(getImpl()->arguments[idx]);
133 return result;
134}
135
136const DPIArgument *DPIFunctionType::getReturnArgument() const {
137 auto &args = getImpl()->arguments;
138 if (!args.empty() && args.back().dir == DPIDirection::Return)
139 return &args.back();
140 return nullptr;
141}
142
143FunctionType DPIFunctionType::getFunctionType() const {
144 auto cached = getImpl()->getCachedFunctionType();
145 if (cached)
146 return cached;
147 // Empty argument list — context unavailable during storage construction.
148 return FunctionType::get(getContext(), {}, {});
149}
150
151LogicalResult
152DPIFunctionType::verify(function_ref<InFlightDiagnostic()> emitError) const {
153 auto dpiArgs = getArguments();
154 unsigned returnCount = 0;
155 for (auto [i, arg] : llvm::enumerate(dpiArgs)) {
156 if (arg.dir == DPIDirection::Return) {
157 ++returnCount;
158 if (i != dpiArgs.size() - 1)
159 return emitError() << "'return' argument must be the last argument";
160 }
161 }
162 if (returnCount > 1)
163 return emitError() << "must have at most one 'return' argument";
164 return success();
165}
166
167//===----------------------------------------------------------------------===//
168// DPIFunctionType parser/printer
169//===----------------------------------------------------------------------===//
170
171/// Parse: !sim.dpi_functy<input "a" : i32, output "b" : i32>
172Type DPIFunctionType::parse(AsmParser &parser) {
173 SmallVector<DPIArgument> args;
174 if (parser.parseLess())
175 return {};
176
177 // Handle empty argument list.
178 if (succeeded(parser.parseOptionalGreater()))
179 return get(parser.getContext(), args);
180
181 auto parseOneArg = [&]() -> ParseResult {
182 StringRef dirKeyword;
183 if (parser.parseKeyword(&dirKeyword))
184 return failure();
185 auto dir = parseDPIDirectionKeyword(dirKeyword);
186 if (!dir) {
187 parser.emitError(parser.getCurrentLocation(),
188 "expected DPI argument direction keyword");
189 return failure();
190 }
191 std::string name;
192 if (parser.parseString(&name))
193 return failure();
194 Type type;
195 if (parser.parseColonType(type))
196 return failure();
197 args.push_back({StringAttr::get(parser.getContext(), name), type, *dir});
198 return success();
199 };
200
201 if (parser.parseCommaSeparatedList(parseOneArg) || parser.parseGreater())
202 return {};
203 return get(parser.getContext(), args);
204}
205
206/// Print: !sim.dpi_functy<input "a" : i32, output "b" : i32>
207void DPIFunctionType::print(AsmPrinter &printer) const {
208 printer << '<';
209 llvm::interleaveComma(getArguments(), printer, [&](const DPIArgument &arg) {
210 printer << stringifyDPIDirectionKeyword(arg.dir) << ' ';
211 printer << '"' << arg.name.getValue() << '"';
212 printer << " : ";
213 printer.printType(arg.type);
214 });
215 printer << '>';
216}
assert(baseType &&"element must be base type")
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition CalyxOps.cpp:55
llvm::StringRef stringifyDPIDirectionKeyword(DPIDirection dir)
Return the keyword string for a DPIDirection (e.g. "in", "return").
Definition SimTypes.cpp:27
std::optional< DPIDirection > parseDPIDirectionKeyword(llvm::StringRef keyword)
Parse a keyword string to a DPIDirection. Returns std::nullopt on failure.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition sim.py:1
llvm::SmallVector< DPIArgument > arguments
Definition SimTypes.h:75
DPIFunctionTypeStorage(llvm::ArrayRef< DPIArgument > args)
Definition SimTypes.cpp:72
llvm::SmallVector< size_t > inputToAbs
Definition SimTypes.h:76
llvm::SmallVector< size_t > resultToAbs
Definition SimTypes.h:77
static DPIFunctionTypeStorage * construct(mlir::TypeStorageAllocator &allocator, const KeyTy &key)
Definition SimTypes.cpp:86
llvm::ArrayRef< DPIArgument > KeyTy
Definition SimTypes.h:54