CIRCT 22.0.0git
Loading...
Searching...
No Matches
ArcTypes.cpp
Go to the documentation of this file.
1//===- ArcTypes.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
13#include "mlir/IR/Builders.h"
14#include "mlir/IR/DialectImplementation.h"
15#include "llvm/ADT/TypeSwitch.h"
16
17using namespace circt;
18using namespace arc;
19using namespace mlir;
20
21#define GET_TYPEDEF_CLASSES
22#include "circt/Dialect/Arc/ArcTypes.cpp.inc"
23
24/// Compute the bit width a type will have when allocated as part of the
25/// simulator's storage. This includes any padding and alignment that may be
26/// necessary once the type has been mapped to LLVM. The idea is for this
27/// function to be conservative, such that we provide sufficient storage bytes
28/// for any type.
29static std::optional<uint64_t> computeLLVMBitWidth(Type type) {
30 if (isa<seq::ClockType>(type))
31 return 1;
32
33 if (auto intType = dyn_cast<IntegerType>(type))
34 return intType.getWidth();
35
36 if (auto arrayType = dyn_cast<hw::ArrayType>(type)) {
37 // Compute element width.
38 auto maybeWidth = computeLLVMBitWidth(arrayType.getElementType());
39 if (!maybeWidth)
40 return {};
41 // Each element must be at least one byte.
42 auto width = std::max<uint64_t>(*maybeWidth, 8);
43 // Align elements to their own size, up to 16 bytes.
44 auto alignment = llvm::bit_ceil(std::min<uint64_t>(width, 16 * 8));
45 auto alignedWidth = llvm::alignToPowerOf2(width, alignment);
46 // Multiply by the number of elements in the array.
47 return arrayType.getNumElements() * alignedWidth;
48 }
49
50 if (auto structType = dyn_cast<hw::StructType>(type)) {
51 uint64_t structWidth = 0;
52 uint64_t structAlignment = 8;
53 for (auto element : structType.getElements()) {
54 // Compute element width.
55 auto maybeWidth = computeLLVMBitWidth(element.type);
56 if (!maybeWidth)
57 return {};
58 // Each element must be at least one byte.
59 auto width = std::max<uint64_t>(*maybeWidth, 8);
60 // Align elements to their own size, up to 16 bytes.
61 auto alignment = llvm::bit_ceil(std::min<uint64_t>(width, 16 * 8));
62 auto alignedWidth = llvm::alignToPowerOf2(width, alignment);
63 // Pad the struct size to align the element to its alignment need, and add
64 // the element.
65 structWidth = llvm::alignToPowerOf2(structWidth, alignment);
66 structWidth += alignedWidth;
67 // Keep track of the struct's alignment need.
68 structAlignment = std::max<uint64_t>(alignment, structAlignment);
69 }
70 // Pad the struct size to align its end with the alignment.
71 return llvm::alignToPowerOf2(structWidth, structAlignment);
72 }
73
74 // We don't know anything about any other types.
75 return {};
76}
77
78unsigned StateType::getBitWidth() { return *computeLLVMBitWidth(getType()); }
79
80LogicalResult
81StateType::verify(llvm::function_ref<InFlightDiagnostic()> emitError,
82 Type innerType) {
83 if (!computeLLVMBitWidth(innerType))
84 return emitError() << "state type must have a known bit width; got "
85 << innerType;
86 return success();
87}
88
89unsigned MemoryType::getStride() {
90 unsigned stride = (getWordType().getWidth() + 7) / 8;
91 return llvm::alignToPowerOf2(stride, llvm::bit_ceil(std::min(stride, 16U)));
92}
93
94void ArcDialect::registerTypes() {
95 addTypes<
96#define GET_TYPEDEF_LIST
97#include "circt/Dialect/Arc/ArcTypes.cpp.inc"
98 >();
99}
static std::optional< uint64_t > computeLLVMBitWidth(Type type)
Compute the bit width a type will have when allocated as part of the simulator's storage.
Definition ArcTypes.cpp:29
mlir::Type innerType(mlir::Type type)
Definition ESITypes.cpp:227
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.