CIRCT  19.0.0git
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 
17 using namespace mlir;
18 using namespace circt;
19 using namespace arc;
20 
21 LogicalResult 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 
106 LogicalResult circt::arc::collectModels(mlir::ModuleOp module,
107  SmallVector<ModelInfo> &models) {
108  for (auto modelOp : module.getOps<ModelOp>()) {
109  auto storageArg = modelOp.getBody().getArgument(0);
110  auto storageType = cast<StorageType>(storageArg.getType());
111 
112  SmallVector<StateInfo> states;
113  if (failed(collectStates(storageArg, 0, states)))
114  return failure();
115  llvm::sort(states, [](auto &a, auto &b) { return a.offset < b.offset; });
116 
117  models.emplace_back(std::string(modelOp.getName()), storageType.getSize(),
118  std::move(states));
119  }
120 
121  return success();
122 }
123 
124 void circt::arc::serializeModelInfoToJson(llvm::raw_ostream &outputStream,
125  ArrayRef<ModelInfo> models) {
126  llvm::json::OStream json(outputStream, 2);
127 
128  json.array([&] {
129  for (const ModelInfo &model : models) {
130  json.object([&] {
131  json.attribute("name", model.name);
132  json.attribute("numStateBytes", model.numStateBytes);
133  json.attributeArray("states", [&] {
134  for (const auto &state : model.states) {
135  json.object([&] {
136  json.attribute("name", state.name);
137  json.attribute("offset", state.offset);
138  json.attribute("numBits", state.numBits);
139  auto typeStr = [](StateInfo::Type type) {
140  switch (type) {
141  case StateInfo::Input:
142  return "input";
143  case StateInfo::Output:
144  return "output";
145  case StateInfo::Register:
146  return "register";
147  case StateInfo::Memory:
148  return "memory";
149  case StateInfo::Wire:
150  return "wire";
151  }
152  return "";
153  };
154  json.attribute("type", typeStr(state.type));
155  if (state.type == StateInfo::Memory) {
156  json.attribute("stride", state.memoryStride);
157  json.attribute("depth", state.memoryDepth);
158  }
159  });
160  }
161  });
162  });
163  }
164  });
165 }
@ Input
Definition: HW.h:35
@ Output
Definition: HW.h:35
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.
Definition: DebugAnalysis.h:21
Gathers information about a given Arc model.
Definition: ModelInfo.h:35