Loading [MathJax]/extensions/tex2jax.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ModelInfo.cpp
Go to the documentation of this file.
1//===- ModelInfo.cpp - Information about Arc models -----------------------===//
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// Defines and computes information about Arc models.
10//
11//===----------------------------------------------------------------------===//
12
15#include "llvm/Support/JSON.h"
16
17using namespace mlir;
18using namespace circt;
19using namespace arc;
20
21LogicalResult circt::arc::collectStates(Value storage, unsigned offset,
22 SmallVector<StateInfo> &states) {
23 struct StateCollectionJob {
24 mlir::Value::user_iterator nextToProcess;
25 mlir::Value::user_iterator end;
26 unsigned offset;
27
28 StateCollectionJob(Value storage, unsigned offset)
29 : nextToProcess(storage.user_begin()), end(storage.user_end()),
30 offset(offset) {}
31 };
32
33 SmallVector<StateCollectionJob, 4> jobStack{{storage, offset}};
34
35 while (!jobStack.empty()) {
36 StateCollectionJob &job = jobStack.back();
37
38 if (job.nextToProcess == job.end) {
39 jobStack.pop_back();
40 continue;
41 }
42
43 Operation *op = *job.nextToProcess++;
44 unsigned offset = job.offset;
45
46 if (auto substorage = dyn_cast<AllocStorageOp>(op)) {
47 if (!substorage.getOffset().has_value())
48 return substorage.emitOpError(
49 "without allocated offset; run state allocation first");
50 Value substorageOutput = substorage.getOutput();
51 jobStack.emplace_back(substorageOutput, offset + *substorage.getOffset());
52 continue;
53 }
54
55 if (!isa<AllocStateOp, RootInputOp, RootOutputOp, AllocMemoryOp>(op))
56 continue;
57
58 auto opName = op->getAttrOfType<StringAttr>("name");
59 if (!opName || opName.getValue().empty())
60 continue;
61
62 auto opOffset = op->getAttrOfType<IntegerAttr>("offset");
63 if (!opOffset)
64 return op->emitOpError(
65 "without allocated offset; run state allocation first");
66
67 if (isa<AllocStateOp, RootInputOp, RootOutputOp>(op)) {
68 auto result = op->getResult(0);
69 auto &stateInfo = states.emplace_back();
70 stateInfo.type = StateInfo::Register;
71 if (isa<RootInputOp>(op))
72 stateInfo.type = StateInfo::Input;
73 else if (isa<RootOutputOp>(op))
74 stateInfo.type = StateInfo::Output;
75 else if (auto alloc = dyn_cast<AllocStateOp>(op)) {
76 if (alloc.getTap())
77 stateInfo.type = StateInfo::Wire;
78 }
79 stateInfo.name = opName.getValue();
80 stateInfo.offset = opOffset.getValue().getZExtValue() + offset;
81 stateInfo.numBits = cast<StateType>(result.getType()).getBitWidth();
82 continue;
83 }
84
85 if (auto memOp = dyn_cast<AllocMemoryOp>(op)) {
86 auto stride = op->getAttrOfType<IntegerAttr>("stride");
87 if (!stride)
88 return op->emitOpError(
89 "without allocated stride; run state allocation first");
90 auto memType = memOp.getType();
91 auto intType = memType.getWordType();
92 auto &stateInfo = states.emplace_back();
93 stateInfo.type = StateInfo::Memory;
94 stateInfo.name = opName.getValue();
95 stateInfo.offset = opOffset.getValue().getZExtValue() + offset;
96 stateInfo.numBits = intType.getWidth();
97 stateInfo.memoryStride = stride.getValue().getZExtValue();
98 stateInfo.memoryDepth = memType.getNumWords();
99 continue;
100 }
101 }
102
103 return success();
104}
105
106LogicalResult circt::arc::collectModels(mlir::ModuleOp module,
107 SmallVector<ModelInfo> &models) {
108
109 for (auto modelOp : module.getOps<ModelOp>()) {
110 auto storageArg = modelOp.getBody().getArgument(0);
111 auto storageType = cast<StorageType>(storageArg.getType());
112
113 SmallVector<StateInfo> states;
114 if (failed(collectStates(storageArg, 0, states)))
115 return failure();
116 llvm::sort(states, [](auto &a, auto &b) { return a.offset < b.offset; });
117
118 models.emplace_back(std::string(modelOp.getName()), storageType.getSize(),
119 std::move(states), modelOp.getInitialFnAttr(),
120 modelOp.getFinalFnAttr());
121 }
122
123 return success();
124}
125
126void circt::arc::serializeModelInfoToJson(llvm::raw_ostream &outputStream,
127 ArrayRef<ModelInfo> models) {
128 llvm::json::OStream json(outputStream, 2);
129
130 json.array([&] {
131 for (const ModelInfo &model : models) {
132 json.object([&] {
133 json.attribute("name", model.name);
134 json.attribute("numStateBytes", model.numStateBytes);
135 json.attribute("initialFnSym", !model.initialFnSym
136 ? ""
137 : model.initialFnSym.getValue());
138 json.attribute("finalFnSym",
139 !model.finalFnSym ? "" : model.finalFnSym.getValue());
140 json.attributeArray("states", [&] {
141 for (const auto &state : model.states) {
142 json.object([&] {
143 json.attribute("name", state.name);
144 json.attribute("offset", state.offset);
145 json.attribute("numBits", state.numBits);
146 auto typeStr = [](StateInfo::Type type) {
147 switch (type) {
148 case StateInfo::Input:
149 return "input";
151 return "output";
153 return "register";
155 return "memory";
156 case StateInfo::Wire:
157 return "wire";
158 }
159 return "";
160 };
161 json.attribute("type", typeStr(state.type));
162 if (state.type == StateInfo::Memory) {
163 json.attribute("stride", state.memoryStride);
164 json.attribute("depth", state.memoryDepth);
165 }
166 });
167 }
168 });
169 });
170 }
171 });
172}
void serializeModelInfoToJson(llvm::raw_ostream &outputStream, llvm::ArrayRef< ModelInfo > models)
Serializes models to outputStream in JSON format.
mlir::LogicalResult collectModels(mlir::ModuleOp module, llvm::SmallVector< ModelInfo > &models)
Collects information about all Arc models in the provided module, and adds it to models.
mlir::LogicalResult collectStates(mlir::Value storage, unsigned offset, llvm::SmallVector< StateInfo > &states)
Collects information about states within the provided Arc model storage storage, assuming default off...
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Gathers information about a given Arc model.
Definition ModelInfo.h:35