CIRCT  19.0.0git
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 
12 using namespace circt;
13 
14 // Converts a function type wrt. the given type converter.
15 static 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.
28 static 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 
37 LogicalResult 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  rewriter.applySignatureConversion(newRegion, result, typeConverter);
89  }
90  rewriter.finalizeOpModification(newOp);
91 
92  rewriter.replaceOp(op, newOp->getResults());
93  return success();
94 }
static FunctionType convertFunctionType(const TypeConverter &typeConverter, FunctionType type)
static hw::ModuleType convertModuleType(const TypeConverter &typeConverter, hw::ModuleType type)
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:54
mlir::Type innerType(mlir::Type type)
Definition: ESITypes.cpp:184
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
LogicalResult doTypeConversion(Operation *op, ValueRange operands, ConversionPatternRewriter &rewriter, const TypeConverter *typeConverter)