CIRCT 20.0.0git
Loading...
Searching...
No Matches
ConversionPatterns.cpp
Go to the documentation of this file.
1//===- ConversionPatterns.cpp - Common Conversion patterns ------*- C++ -*-===//
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
11
12using namespace circt;
13
14// Converts a function type wrt. the given type converter.
15static FunctionType convertFunctionType(const TypeConverter &typeConverter,
16 FunctionType type) {
17 // Convert the original function types.
18 llvm::SmallVector<Type> res, arg;
19 llvm::transform(type.getResults(), std::back_inserter(res),
20 [&](Type t) { return typeConverter.convertType(t); });
21 llvm::transform(type.getInputs(), std::back_inserter(arg),
22 [&](Type t) { return typeConverter.convertType(t); });
23
24 return FunctionType::get(type.getContext(), arg, res);
25}
26
27// Converts a function type wrt. the given type converter.
28static hw::ModuleType convertModuleType(const TypeConverter &typeConverter,
29 hw::ModuleType type) {
30 // Convert the original function types.
31 SmallVector<hw::ModulePort> ports(type.getPorts());
32 for (auto &p : ports)
33 p.type = typeConverter.convertType(p.type);
34 return hw::ModuleType::get(type.getContext(), ports);
35}
36
37LogicalResult circt::doTypeConversion(Operation *op, ValueRange operands,
38 ConversionPatternRewriter &rewriter,
39 const TypeConverter *typeConverter) {
40 // Convert the TypeAttrs.
41 llvm::SmallVector<NamedAttribute, 4> newAttrs;
42 newAttrs.reserve(op->getAttrs().size());
43 for (auto attr : op->getAttrs()) {
44 if (auto typeAttr = dyn_cast<TypeAttr>(attr.getValue())) {
45 auto innerType = typeAttr.getValue();
46 // TypeConvert::convertType doesn't handle function types, so we need to
47 // handle them manually.
48 if (auto funcType = dyn_cast<FunctionType>(innerType))
49 innerType = convertFunctionType(*typeConverter, funcType);
50 else if (auto modType = dyn_cast<hw::ModuleType>(innerType))
51 innerType = convertModuleType(*typeConverter, modType);
52 else
53 innerType = typeConverter->convertType(innerType);
54 newAttrs.emplace_back(attr.getName(), TypeAttr::get(innerType));
55 } else {
56 newAttrs.push_back(attr);
57 }
58 }
59
60 // Convert the result types.
61 llvm::SmallVector<Type, 4> newResults;
62 if (failed(typeConverter->convertTypes(op->getResultTypes(), newResults)))
63 return rewriter.notifyMatchFailure(op->getLoc(), "type conversion failed");
64
65 // Build the state for the edited clone.
66 OperationState state(op->getLoc(), op->getName().getStringRef(), operands,
67 newResults, newAttrs, op->getSuccessors());
68 for (size_t i = 0, e = op->getNumRegions(); i < e; ++i)
69 state.addRegion();
70
71 // Must create the op before running any modifications on the regions so that
72 // we don't crash with '-debug' and so we have something to 'root update'.
73 Operation *newOp = rewriter.create(state);
74
75 // Move the regions over, converting the signatures as we go.
76 rewriter.startOpModification(newOp);
77 for (size_t i = 0, e = op->getNumRegions(); i < e; ++i) {
78 Region &region = op->getRegion(i);
79 Region *newRegion = &newOp->getRegion(i);
80
81 // Move the region and convert the region args.
82 rewriter.inlineRegionBefore(region, *newRegion, newRegion->begin());
83 TypeConverter::SignatureConversion result(newRegion->getNumArguments());
84 if (failed(typeConverter->convertSignatureArgs(
85 newRegion->getArgumentTypes(), result)))
86 return rewriter.notifyMatchFailure(op->getLoc(),
87 "type conversion failed");
88 if (failed(rewriter.convertRegionTypes(newRegion, *typeConverter, &result)))
89 return failure();
90 }
91 rewriter.finalizeOpModification(newOp);
92
93 rewriter.replaceOp(op, newOp->getResults());
94 return success();
95}
static FunctionType convertFunctionType(const TypeConverter &typeConverter, FunctionType type)
static hw::ModuleType convertModuleType(const TypeConverter &typeConverter, hw::ModuleType type)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
LogicalResult doTypeConversion(Operation *op, ValueRange operands, ConversionPatternRewriter &rewriter, const TypeConverter *typeConverter)