CIRCT  18.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 = attr.getValue().dyn_cast<TypeAttr>()) {
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 = innerType.dyn_cast<FunctionType>())
49  innerType = convertFunctionType(*typeConverter, funcType);
50  else if (auto modType = innerType.dyn_cast<hw::ModuleType>())
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.startRootUpdate(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  // TypeConverter::SignatureConversion drops argument locations, so we need
82  // to manually copy them over (a verifier in e.g. HWModule checks this).
83  llvm::SmallVector<Location, 4> argLocs;
84  for (auto arg : region.getArguments())
85  argLocs.push_back(arg.getLoc());
86 
87  // Move the region and convert the region args.
88  rewriter.inlineRegionBefore(region, *newRegion, newRegion->begin());
89  TypeConverter::SignatureConversion result(newRegion->getNumArguments());
90  if (failed(typeConverter->convertSignatureArgs(
91  newRegion->getArgumentTypes(), result)))
92  return rewriter.notifyMatchFailure(op->getLoc(),
93  "type conversion failed");
94  rewriter.applySignatureConversion(newRegion, result, typeConverter);
95 
96  // Apply the argument locations.
97  for (auto [arg, loc] : llvm::zip(newRegion->getArguments(), argLocs))
98  arg.setLoc(loc);
99  }
100  rewriter.finalizeRootUpdate(newOp);
101 
102  rewriter.replaceOp(op, newOp->getResults());
103  return success();
104 }
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:53
mlir::Type innerType(mlir::Type type)
Definition: ESITypes.cpp:184
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
Definition: DebugAnalysis.h:21
LogicalResult doTypeConversion(Operation *op, ValueRange operands, ConversionPatternRewriter &rewriter, const TypeConverter *typeConverter)