Skip to content

Commit de8ce29

Browse files
authored
[FIRRTL] LowerClasses: drop the IR mapping (#7824)
1 parent a50f19e commit de8ce29

File tree

1 file changed

+20
-74
lines changed

1 file changed

+20
-74
lines changed

lib/Dialect/FIRRTL/Transforms/LowerClasses.cpp

Lines changed: 20 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "circt/Dialect/OM/OMAttributes.h"
2222
#include "circt/Dialect/OM/OMOps.h"
2323
#include "mlir/IR/BuiltinOps.h"
24-
#include "mlir/IR/IRMapping.h"
2524
#include "mlir/IR/PatternMatch.h"
2625
#include "mlir/IR/Threading.h"
2726
#include "mlir/Pass/Pass.h"
@@ -1105,9 +1104,6 @@ void LowerClassesPass::lowerClassLike(FModuleLike moduleLike,
11051104

11061105
void LowerClassesPass::lowerClass(om::ClassOp classOp, FModuleLike moduleLike,
11071106
const PathInfoTable &pathInfoTable) {
1108-
// Map from Values in the FIRRTL Class to Values in the OM Class.
1109-
IRMapping mapping;
1110-
11111107
// Collect information about property ports.
11121108
SmallVector<Property> inputProperties;
11131109
BitVector portsToErase(moduleLike.getNumPorts());
@@ -1132,6 +1128,7 @@ void LowerClassesPass::lowerClass(om::ClassOp classOp, FModuleLike moduleLike,
11321128

11331129
// Construct the OM Class body with block arguments for each input property,
11341130
// updating the mapping to map from the input property to the block argument.
1131+
Block *moduleBody = &moduleLike->getRegion(0).front();
11351132
Block *classBody = &classOp->getRegion(0).emplaceBlock();
11361133
// Every class created from a module gets a base path as its first parameter.
11371134
auto basePathType = BasePathType::get(&getContext());
@@ -1144,76 +1141,35 @@ void LowerClassesPass::lowerClass(om::ClassOp classOp, FModuleLike moduleLike,
11441141
for (size_t i = 0; i < nAltBasePaths; ++i)
11451142
classBody->addArgument(basePathType, unknownLoc);
11461143

1147-
// Mapping from block arguments or instance results to new values.
1148-
DenseMap<Value, Value> valueMapping;
1149-
for (auto inputProperty : inputProperties) {
1150-
BlockArgument parameterValue =
1151-
classBody->addArgument(inputProperty.type, inputProperty.loc);
1152-
BlockArgument inputValue =
1153-
moduleLike->getRegion(0).getArgument(inputProperty.index);
1154-
1155-
valueMapping[inputValue] = parameterValue;
1156-
}
1157-
1158-
// Helper to check if an op is a property op, which should be removed in the
1159-
// module like, or kept in the OM class.
1160-
auto isPropertyOp = [&](Operation &op) {
1161-
// Check if any operand is a property.
1162-
auto propertyOperands = llvm::any_of(op.getOperandTypes(), [](Type type) {
1163-
return isa<PropertyType>(type);
1164-
});
1165-
bool needsClone = false;
1166-
if (auto instance = dyn_cast<InstanceOp>(op))
1167-
needsClone = shouldCreateClass(instance.getReferencedModuleNameAttr());
1168-
1169-
// Check if any result is a property.
1170-
auto propertyResults = llvm::any_of(
1171-
op.getResultTypes(), [](Type type) { return isa<PropertyType>(type); });
1172-
1173-
return needsClone || propertyOperands || propertyResults;
1174-
};
1175-
1176-
// Move operations from the module like to the OM class.
1177-
// We need to clone only instances and register their results to the value
1178-
// mapping. Operands must be remapped using the value mapping.
1179-
for (auto &op : llvm::make_early_inc_range(
1180-
moduleLike->getRegion(0).front().getOperations())) {
1181-
if (!isPropertyOp(op))
1144+
// Move operations from the modulelike to the OM class.
1145+
for (auto &op : llvm::make_early_inc_range(llvm::reverse(*moduleBody))) {
1146+
if (auto instance = dyn_cast<InstanceOp>(op)) {
1147+
if (!shouldCreateClass(instance.getReferencedModuleNameAttr()))
1148+
continue;
1149+
auto *clone = OpBuilder::atBlockBegin(classBody).clone(op);
1150+
for (auto result : instance.getResults()) {
1151+
if (isa<PropertyType>(result.getType()))
1152+
result.replaceAllUsesWith(clone->getResult(result.getResultNumber()));
1153+
}
11821154
continue;
1183-
1184-
Operation *newOp = &op;
1185-
1186-
bool needsMove = true;
1187-
1188-
// Clone instances and register their results to the value mapping.
1189-
if (isa<InstanceOp>(op)) {
1190-
newOp = op.clone();
1191-
for (auto [oldResult, newResult] :
1192-
llvm::zip(op.getResults(), newOp->getResults()))
1193-
valueMapping[oldResult] = newResult;
1194-
classBody->getOperations().insert(classBody->end(), newOp);
1195-
needsMove = false;
11961155
}
11971156

1198-
// Remap operands using the value mapping.
1199-
for (size_t i = 0; i < newOp->getNumOperands(); ++i) {
1200-
auto operand = newOp->getOperand(i);
1201-
auto it = valueMapping.find(operand);
1202-
if (it != valueMapping.end())
1203-
newOp->setOperand(i, it->second);
1204-
}
1157+
auto isProperty = [](auto x) { return isa<PropertyType>(x.getType()); };
1158+
if (llvm::any_of(op.getOperands(), isProperty) ||
1159+
llvm::any_of(op.getResults(), isProperty))
1160+
op.moveBefore(classBody, classBody->begin());
1161+
}
12051162

1206-
// Move the op into the OM class body.
1207-
if (needsMove)
1208-
newOp->moveBefore(classBody, classBody->end());
1163+
// Move property ports from the module to the class.
1164+
for (auto input : inputProperties) {
1165+
auto arg = classBody->addArgument(input.type, input.loc);
1166+
moduleBody->getArgument(input.index).replaceAllUsesWith(arg);
12091167
}
12101168

12111169
llvm::SmallVector<mlir::Location> fieldLocs;
12121170
llvm::SmallVector<mlir::Value> fieldValues;
12131171
for (Operation &op :
12141172
llvm::make_early_inc_range(classOp.getBodyBlock()->getOperations())) {
1215-
assert(isPropertyOp(op));
1216-
12171173
if (auto propAssign = dyn_cast<PropAssignOp>(op)) {
12181174
if (auto blockArg = dyn_cast<BlockArgument>(propAssign.getDest())) {
12191175
// Store any output property assignments into fields op inputs.
@@ -1238,16 +1194,6 @@ void LowerClassesPass::lowerClass(om::ClassOp classOp, FModuleLike moduleLike,
12381194
// If the module-like is a Class, it will be completely erased later.
12391195
// Otherwise, erase just the property ports and ops.
12401196
if (!isa<firrtl::ClassLike>(moduleLike.getOperation())) {
1241-
// Erase ops in use before def order, thanks to FIRRTL's SSA regions.
1242-
for (auto &op :
1243-
llvm::make_early_inc_range(llvm::reverse(moduleLike.getOperation()
1244-
->getRegion(0)
1245-
.getBlocks()
1246-
.front()
1247-
.getOperations())))
1248-
if (isPropertyOp(op) && !isa<InstanceOp>(op))
1249-
op.erase();
1250-
12511197
// Erase property typed ports.
12521198
moduleLike.erasePorts(portsToErase);
12531199
}

0 commit comments

Comments
 (0)