Update to new builder format. (#8785)

Basically did

set(CMAKE_CXX_CLANG_TIDY local/clang-tidy -checks=-*,llvm-use-new-mlir-op-builder -fix)

and then fixed cases where temporary OpBuilders were used (as passed in
by reference now).
This commit is contained in:
Jacques Pienaar 2025-07-26 13:55:06 +02:00 committed by GitHub
parent fce6984ba5
commit 7f1c3399e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
243 changed files with 4513 additions and 4358 deletions

View File

@ -165,8 +165,9 @@ void mlirMSFTAddPhysLocationAttr(MlirOperation cOp, const char *entityName,
PhysLocationAttr loc = PhysLocationAttr::get( PhysLocationAttr loc = PhysLocationAttr::get(
ctxt, PrimitiveTypeAttr::get(ctxt, type), x, y, num); ctxt, PrimitiveTypeAttr::get(ctxt, type), x, y, num);
StringAttr entity = StringAttr::get(ctxt, entityName); StringAttr entity = StringAttr::get(ctxt, entityName);
OpBuilder(op).create<PDPhysLocationOp>(op->getLoc(), loc, entity, auto builder = OpBuilder(op);
FlatSymbolRefAttr::get(op)); PDPhysLocationOp::create(builder, op->getLoc(), loc, entity,
FlatSymbolRefAttr::get(op));
op->setAttr(entity, loc); op->setAttr(entity, loc);
} }

View File

@ -39,7 +39,7 @@ struct AIGAndInverterOpConversion : OpConversionPattern<aig::AndInverterOp> {
// Convert to comb.and + comb.xor + hw.constant // Convert to comb.and + comb.xor + hw.constant
auto width = op.getResult().getType().getIntOrFloatBitWidth(); auto width = op.getResult().getType().getIntOrFloatBitWidth();
auto allOnes = auto allOnes =
rewriter.create<hw::ConstantOp>(op.getLoc(), APInt::getAllOnes(width)); hw::ConstantOp::create(rewriter, op.getLoc(), APInt::getAllOnes(width));
SmallVector<Value> operands; SmallVector<Value> operands;
operands.reserve(op.getNumOperands()); operands.reserve(op.getNumOperands());
for (auto [input, inverted] : llvm::zip(op.getOperands(), op.getInverted())) for (auto [input, inverted] : llvm::zip(op.getOperands(), op.getInverted()))

View File

@ -432,8 +432,8 @@ LogicalResult AffineToLoopSchedule::createLoopSchedulePipeline(
Value lowerBound = lowerAffineLowerBound(innerLoop, builder); Value lowerBound = lowerAffineLowerBound(innerLoop, builder);
Value upperBound = lowerAffineUpperBound(innerLoop, builder); Value upperBound = lowerAffineUpperBound(innerLoop, builder);
int64_t stepValue = innerLoop.getStep().getSExtValue(); int64_t stepValue = innerLoop.getStep().getSExtValue();
auto step = builder.create<arith::ConstantOp>( auto step = arith::ConstantOp::create(
IntegerAttr::get(builder.getIndexType(), stepValue)); builder, IntegerAttr::get(builder.getIndexType(), stepValue));
// Create the pipeline op, with the same result types as the inner loop. An // Create the pipeline op, with the same result types as the inner loop. An
// iter arg is created for the induction variable. // iter arg is created for the induction variable.
@ -451,16 +451,16 @@ LogicalResult AffineToLoopSchedule::createLoopSchedulePipeline(
if (auto tripCount = getConstantTripCount(forOp)) if (auto tripCount = getConstantTripCount(forOp))
tripCountAttr = builder.getI64IntegerAttr(*tripCount); tripCountAttr = builder.getI64IntegerAttr(*tripCount);
auto pipeline = builder.create<LoopSchedulePipelineOp>( auto pipeline = LoopSchedulePipelineOp::create(builder, resultTypes, ii,
resultTypes, ii, tripCountAttr, iterArgs); tripCountAttr, iterArgs);
// Create the condition, which currently just compares the induction variable // Create the condition, which currently just compares the induction variable
// to the upper bound. // to the upper bound.
Block &condBlock = pipeline.getCondBlock(); Block &condBlock = pipeline.getCondBlock();
builder.setInsertionPointToStart(&condBlock); builder.setInsertionPointToStart(&condBlock);
auto cmpResult = builder.create<arith::CmpIOp>( auto cmpResult = arith::CmpIOp::create(builder, builder.getI1Type(),
builder.getI1Type(), arith::CmpIPredicate::ult, condBlock.getArgument(0), arith::CmpIPredicate::ult,
upperBound); condBlock.getArgument(0), upperBound);
condBlock.getTerminator()->insertOperands(0, {cmpResult}); condBlock.getTerminator()->insertOperands(0, {cmpResult});
// Add the non-yield operations to their start time groups. // Add the non-yield operations to their start time groups.
@ -581,7 +581,7 @@ LogicalResult AffineToLoopSchedule::createLoopSchedulePipeline(
auto startTimeAttr = builder.getIntegerAttr( auto startTimeAttr = builder.getIntegerAttr(
builder.getIntegerType(64, /*isSigned=*/true), startTime); builder.getIntegerType(64, /*isSigned=*/true), startTime);
auto stage = auto stage =
builder.create<LoopSchedulePipelineStageOp>(stageTypes, startTimeAttr); LoopSchedulePipelineStageOp::create(builder, stageTypes, startTimeAttr);
auto &stageBlock = stage.getBodyBlock(); auto &stageBlock = stage.getBodyBlock();
auto *stageTerminator = stageBlock.getTerminator(); auto *stageTerminator = stageBlock.getTerminator();
builder.setInsertionPointToStart(&stageBlock); builder.setInsertionPointToStart(&stageBlock);
@ -620,7 +620,7 @@ LogicalResult AffineToLoopSchedule::createLoopSchedulePipeline(
// Add the induction variable increment to the first stage. // Add the induction variable increment to the first stage.
if (startTime == 0) { if (startTime == 0) {
auto incResult = auto incResult =
builder.create<arith::AddIOp>(stagesBlock.getArgument(0), step); arith::AddIOp::create(builder, stagesBlock.getArgument(0), step);
stageTerminator->insertOperands(stageTerminator->getNumOperands(), stageTerminator->insertOperands(stageTerminator->getNumOperands(),
incResult->getResults()); incResult->getResults());
} }

View File

@ -64,14 +64,14 @@ struct ModelOpLowering : public OpConversionPattern<arc::ModelOp> {
{ {
IRRewriter::InsertionGuard guard(rewriter); IRRewriter::InsertionGuard guard(rewriter);
rewriter.setInsertionPointToEnd(&op.getBodyBlock()); rewriter.setInsertionPointToEnd(&op.getBodyBlock());
rewriter.create<func::ReturnOp>(op.getLoc()); func::ReturnOp::create(rewriter, op.getLoc());
} }
auto funcName = auto funcName =
rewriter.getStringAttr(evalSymbolFromModelName(op.getName())); rewriter.getStringAttr(evalSymbolFromModelName(op.getName()));
auto funcType = auto funcType =
rewriter.getFunctionType(op.getBody().getArgumentTypes(), {}); rewriter.getFunctionType(op.getBody().getArgumentTypes(), {});
auto func = auto func =
rewriter.create<mlir::func::FuncOp>(op.getLoc(), funcName, funcType); mlir::func::FuncOp::create(rewriter, op.getLoc(), funcName, funcType);
rewriter.inlineRegionBefore(op.getRegion(), func.getBody(), func.end()); rewriter.inlineRegionBefore(op.getRegion(), func.getBody(), func.end());
rewriter.eraseOp(op); rewriter.eraseOp(op);
return success(); return success();
@ -107,9 +107,9 @@ struct AllocStateLikeOpLowering : public OpConversionPattern<ConcreteOp> {
auto offsetAttr = op->template getAttrOfType<IntegerAttr>("offset"); auto offsetAttr = op->template getAttrOfType<IntegerAttr>("offset");
if (!offsetAttr) if (!offsetAttr)
return failure(); return failure();
Value ptr = rewriter.create<LLVM::GEPOp>( Value ptr = LLVM::GEPOp::create(
op->getLoc(), adaptor.getStorage().getType(), rewriter.getI8Type(), rewriter, op->getLoc(), adaptor.getStorage().getType(),
adaptor.getStorage(), rewriter.getI8Type(), adaptor.getStorage(),
LLVM::GEPArg(offsetAttr.getValue().getZExtValue())); LLVM::GEPArg(offsetAttr.getValue().getZExtValue()));
rewriter.replaceOp(op, ptr); rewriter.replaceOp(op, ptr);
return success(); return success();
@ -135,9 +135,9 @@ struct StateWriteOpLowering : public OpConversionPattern<arc::StateWriteOp> {
if (adaptor.getCondition()) { if (adaptor.getCondition()) {
rewriter.replaceOpWithNewOp<scf::IfOp>( rewriter.replaceOpWithNewOp<scf::IfOp>(
op, adaptor.getCondition(), [&](auto &builder, auto loc) { op, adaptor.getCondition(), [&](auto &builder, auto loc) {
builder.template create<LLVM::StoreOp>(loc, adaptor.getValue(), LLVM::StoreOp::create(builder, loc, adaptor.getValue(),
adaptor.getState()); adaptor.getState());
builder.template create<scf::YieldOp>(loc); scf::YieldOp::create(builder, loc);
}); });
} else { } else {
rewriter.replaceOpWithNewOp<LLVM::StoreOp>(op, adaptor.getValue(), rewriter.replaceOpWithNewOp<LLVM::StoreOp>(op, adaptor.getValue(),
@ -155,9 +155,9 @@ struct AllocMemoryOpLowering : public OpConversionPattern<arc::AllocMemoryOp> {
auto offsetAttr = op->getAttrOfType<IntegerAttr>("offset"); auto offsetAttr = op->getAttrOfType<IntegerAttr>("offset");
if (!offsetAttr) if (!offsetAttr)
return failure(); return failure();
Value ptr = rewriter.create<LLVM::GEPOp>( Value ptr = LLVM::GEPOp::create(
op.getLoc(), adaptor.getStorage().getType(), rewriter.getI8Type(), rewriter, op.getLoc(), adaptor.getStorage().getType(),
adaptor.getStorage(), rewriter.getI8Type(), adaptor.getStorage(),
LLVM::GEPArg(offsetAttr.getValue().getZExtValue())); LLVM::GEPArg(offsetAttr.getValue().getZExtValue()));
rewriter.replaceOp(op, ptr); rewriter.replaceOp(op, ptr);
@ -170,11 +170,11 @@ struct StorageGetOpLowering : public OpConversionPattern<arc::StorageGetOp> {
LogicalResult LogicalResult
matchAndRewrite(arc::StorageGetOp op, OpAdaptor adaptor, matchAndRewrite(arc::StorageGetOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
Value offset = rewriter.create<LLVM::ConstantOp>( Value offset = LLVM::ConstantOp::create(
op.getLoc(), rewriter.getI32Type(), op.getOffsetAttr()); rewriter, op.getLoc(), rewriter.getI32Type(), op.getOffsetAttr());
Value ptr = rewriter.create<LLVM::GEPOp>( Value ptr = LLVM::GEPOp::create(
op.getLoc(), adaptor.getStorage().getType(), rewriter.getI8Type(), rewriter, op.getLoc(), adaptor.getStorage().getType(),
adaptor.getStorage(), offset); rewriter.getI8Type(), adaptor.getStorage(), offset);
rewriter.replaceOp(op, ptr); rewriter.replaceOp(op, ptr);
return success(); return success();
} }
@ -190,13 +190,14 @@ static MemoryAccess prepareMemoryAccess(Location loc, Value memory,
ConversionPatternRewriter &rewriter) { ConversionPatternRewriter &rewriter) {
auto zextAddrType = rewriter.getIntegerType( auto zextAddrType = rewriter.getIntegerType(
cast<IntegerType>(address.getType()).getWidth() + 1); cast<IntegerType>(address.getType()).getWidth() + 1);
Value addr = rewriter.create<LLVM::ZExtOp>(loc, zextAddrType, address); Value addr = LLVM::ZExtOp::create(rewriter, loc, zextAddrType, address);
Value addrLimit = rewriter.create<LLVM::ConstantOp>( Value addrLimit =
loc, zextAddrType, rewriter.getI32IntegerAttr(type.getNumWords())); LLVM::ConstantOp::create(rewriter, loc, zextAddrType,
Value withinBounds = rewriter.create<LLVM::ICmpOp>( rewriter.getI32IntegerAttr(type.getNumWords()));
loc, LLVM::ICmpPredicate::ult, addr, addrLimit); Value withinBounds = LLVM::ICmpOp::create(
Value ptr = rewriter.create<LLVM::GEPOp>( rewriter, loc, LLVM::ICmpPredicate::ult, addr, addrLimit);
loc, LLVM::LLVMPointerType::get(memory.getContext()), Value ptr = LLVM::GEPOp::create(
rewriter, loc, LLVM::LLVMPointerType::get(memory.getContext()),
rewriter.getIntegerType(type.getStride() * 8), memory, ValueRange{addr}); rewriter.getIntegerType(type.getStride() * 8), memory, ValueRange{addr});
return {ptr, withinBounds}; return {ptr, withinBounds};
} }
@ -217,14 +218,14 @@ struct MemoryReadOpLowering : public OpConversionPattern<arc::MemoryReadOp> {
rewriter.replaceOpWithNewOp<scf::IfOp>( rewriter.replaceOpWithNewOp<scf::IfOp>(
op, access.withinBounds, op, access.withinBounds,
[&](auto &builder, auto loc) { [&](auto &builder, auto loc) {
Value loadOp = builder.template create<LLVM::LoadOp>( Value loadOp = LLVM::LoadOp::create(
loc, memoryType.getWordType(), access.ptr); builder, loc, memoryType.getWordType(), access.ptr);
builder.template create<scf::YieldOp>(loc, loadOp); scf::YieldOp::create(builder, loc, loadOp);
}, },
[&](auto &builder, auto loc) { [&](auto &builder, auto loc) {
Value zeroValue = builder.template create<LLVM::ConstantOp>( Value zeroValue = LLVM::ConstantOp::create(
loc, type, builder.getI64IntegerAttr(0)); builder, loc, type, builder.getI64IntegerAttr(0));
builder.template create<scf::YieldOp>(loc, zeroValue); scf::YieldOp::create(builder, loc, zeroValue);
}); });
return success(); return success();
} }
@ -240,15 +241,14 @@ struct MemoryWriteOpLowering : public OpConversionPattern<arc::MemoryWriteOp> {
cast<MemoryType>(op.getMemory().getType()), rewriter); cast<MemoryType>(op.getMemory().getType()), rewriter);
auto enable = access.withinBounds; auto enable = access.withinBounds;
if (adaptor.getEnable()) if (adaptor.getEnable())
enable = rewriter.create<LLVM::AndOp>(op.getLoc(), adaptor.getEnable(), enable = LLVM::AndOp::create(rewriter, op.getLoc(), adaptor.getEnable(),
enable); enable);
// Only attempt to write the memory if the address is within bounds. // Only attempt to write the memory if the address is within bounds.
rewriter.replaceOpWithNewOp<scf::IfOp>( rewriter.replaceOpWithNewOp<scf::IfOp>(
op, enable, [&](auto &builder, auto loc) { op, enable, [&](auto &builder, auto loc) {
builder.template create<LLVM::StoreOp>(loc, adaptor.getData(), LLVM::StoreOp::create(builder, loc, adaptor.getData(), access.ptr);
access.ptr); scf::YieldOp::create(builder, loc);
builder.template create<scf::YieldOp>(loc);
}); });
return success(); return success();
} }
@ -272,8 +272,8 @@ struct ClockInvOpLowering : public OpConversionPattern<seq::ClockInverterOp> {
LogicalResult LogicalResult
matchAndRewrite(seq::ClockInverterOp op, OpAdaptor adaptor, matchAndRewrite(seq::ClockInverterOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
auto constTrue = rewriter.create<LLVM::ConstantOp>(op->getLoc(), auto constTrue = LLVM::ConstantOp::create(rewriter, op->getLoc(),
rewriter.getI1Type(), 1); rewriter.getI1Type(), 1);
rewriter.replaceOpWithNewOp<LLVM::XOrOp>(op, adaptor.getInput(), constTrue); rewriter.replaceOpWithNewOp<LLVM::XOrOp>(op, adaptor.getInput(), constTrue);
return success(); return success();
} }
@ -348,9 +348,9 @@ protected:
Value createPtrToPortState(ConversionPatternRewriter &rewriter, Location loc, Value createPtrToPortState(ConversionPatternRewriter &rewriter, Location loc,
Value state, const StateInfo &port) const { Value state, const StateInfo &port) const {
MLIRContext *ctx = rewriter.getContext(); MLIRContext *ctx = rewriter.getContext();
return rewriter.create<LLVM::GEPOp>(loc, LLVM::LLVMPointerType::get(ctx), return LLVM::GEPOp::create(rewriter, loc, LLVM::LLVMPointerType::get(ctx),
IntegerType::get(ctx, 8), state, IntegerType::get(ctx, 8), state,
LLVM::GEPArg(port.offset)); LLVM::GEPArg(port.offset));
} }
llvm::DenseMap<StringRef, ModelInfoMap> &modelInfo; llvm::DenseMap<StringRef, ModelInfoMap> &modelInfo;
@ -392,23 +392,23 @@ struct SimInstantiateOpLowering
return freeFunc; return freeFunc;
Location loc = op.getLoc(); Location loc = op.getLoc();
Value numStateBytes = rewriter.create<LLVM::ConstantOp>( Value numStateBytes = LLVM::ConstantOp::create(
loc, convertedIndex, model.numStateBytes); rewriter, loc, convertedIndex, model.numStateBytes);
Value allocated = rewriter Value allocated = LLVM::CallOp::create(rewriter, loc, mallocFunc.value(),
.create<LLVM::CallOp>(loc, mallocFunc.value(), ValueRange{numStateBytes})
ValueRange{numStateBytes})
.getResult(); .getResult();
Value zero = Value zero =
rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI8Type(), 0); LLVM::ConstantOp::create(rewriter, loc, rewriter.getI8Type(), 0);
rewriter.create<LLVM::MemsetOp>(loc, allocated, zero, numStateBytes, false); LLVM::MemsetOp::create(rewriter, loc, allocated, zero, numStateBytes,
false);
// Call the model's 'initial' function if present. // Call the model's 'initial' function if present.
if (model.initialFnSymbol) { if (model.initialFnSymbol) {
auto initialFnType = LLVM::LLVMFunctionType::get( auto initialFnType = LLVM::LLVMFunctionType::get(
LLVM::LLVMVoidType::get(op.getContext()), LLVM::LLVMVoidType::get(op.getContext()),
{LLVM::LLVMPointerType::get(op.getContext())}); {LLVM::LLVMPointerType::get(op.getContext())});
rewriter.create<LLVM::CallOp>(loc, initialFnType, model.initialFnSymbol, LLVM::CallOp::create(rewriter, loc, initialFnType, model.initialFnSymbol,
ValueRange{allocated}); ValueRange{allocated});
} }
// Execute the body. // Execute the body.
@ -420,11 +420,12 @@ struct SimInstantiateOpLowering
auto finalFnType = LLVM::LLVMFunctionType::get( auto finalFnType = LLVM::LLVMFunctionType::get(
LLVM::LLVMVoidType::get(op.getContext()), LLVM::LLVMVoidType::get(op.getContext()),
{LLVM::LLVMPointerType::get(op.getContext())}); {LLVM::LLVMPointerType::get(op.getContext())});
rewriter.create<LLVM::CallOp>(loc, finalFnType, model.finalFnSymbol, LLVM::CallOp::create(rewriter, loc, finalFnType, model.finalFnSymbol,
ValueRange{allocated}); ValueRange{allocated});
} }
rewriter.create<LLVM::CallOp>(loc, freeFunc.value(), ValueRange{allocated}); LLVM::CallOp::create(rewriter, loc, freeFunc.value(),
ValueRange{allocated});
rewriter.eraseOp(op); rewriter.eraseOp(op);
return success(); return success();
@ -543,14 +544,14 @@ struct SimEmitValueOpLowering
sizeOfSizeT.getFixedValue() <= std::numeric_limits<unsigned>::max()); sizeOfSizeT.getFixedValue() <= std::numeric_limits<unsigned>::max());
bool truncated = false; bool truncated = false;
if (valueType.getWidth() > sizeOfSizeT) { if (valueType.getWidth() > sizeOfSizeT) {
toPrint = rewriter.create<LLVM::TruncOp>( toPrint = LLVM::TruncOp::create(
loc, IntegerType::get(getContext(), sizeOfSizeT.getFixedValue()), rewriter, loc,
toPrint); IntegerType::get(getContext(), sizeOfSizeT.getFixedValue()), toPrint);
truncated = true; truncated = true;
} else if (valueType.getWidth() < sizeOfSizeT) } else if (valueType.getWidth() < sizeOfSizeT)
toPrint = rewriter.create<LLVM::ZExtOp>( toPrint = LLVM::ZExtOp::create(
loc, IntegerType::get(getContext(), sizeOfSizeT.getFixedValue()), rewriter, loc,
toPrint); IntegerType::get(getContext(), sizeOfSizeT.getFixedValue()), toPrint);
// Lookup of create printf function symbol. // Lookup of create printf function symbol.
auto printfFunc = LLVM::lookupOrCreateFn( auto printfFunc = LLVM::lookupOrCreateFn(
@ -579,14 +580,15 @@ struct SimEmitValueOpLowering
rewriter.setInsertionPointToStart(moduleOp.getBody()); rewriter.setInsertionPointToStart(moduleOp.getBody());
auto globalType = auto globalType =
LLVM::LLVMArrayType::get(rewriter.getI8Type(), formatStrVec.size()); LLVM::LLVMArrayType::get(rewriter.getI8Type(), formatStrVec.size());
formatStrGlobal = rewriter.create<LLVM::GlobalOp>( formatStrGlobal = LLVM::GlobalOp::create(
loc, globalType, /*isConstant=*/true, LLVM::Linkage::Internal, rewriter, loc, globalType, /*isConstant=*/true,
LLVM::Linkage::Internal,
/*name=*/formatStrName, rewriter.getStringAttr(formatStrVec), /*name=*/formatStrName, rewriter.getStringAttr(formatStrVec),
/*alignment=*/0); /*alignment=*/0);
} }
Value formatStrGlobalPtr = Value formatStrGlobalPtr =
rewriter.create<LLVM::AddressOfOp>(loc, formatStrGlobal); LLVM::AddressOfOp::create(rewriter, loc, formatStrGlobal);
rewriter.replaceOpWithNewOp<LLVM::CallOp>( rewriter.replaceOpWithNewOp<LLVM::CallOp>(
op, printfFunc.value(), ValueRange{formatStrGlobalPtr, toPrint}); op, printfFunc.value(), ValueRange{formatStrGlobalPtr, toPrint});

View File

@ -305,14 +305,15 @@ HandshakeLowering::insertMerge(Block *block, Value val,
// argument. Taking this step out should have no impact on functionality // argument. Taking this step out should have no impact on functionality
// but would make the resulting IR less "regular" // but would make the resulting IR less "regular"
operands.push_back(val); operands.push_back(val);
mergeOp = rewriter.create<handshake::MergeOp>(insertLoc, operands); mergeOp = handshake::MergeOp::create(rewriter, insertLoc, operands);
} else { } else {
for (unsigned i = 0; i < numPredecessors; i++) { for (unsigned i = 0; i < numPredecessors; i++) {
auto edge = edgeBuilder.get(rewriter.getNoneType()); auto edge = edgeBuilder.get(rewriter.getNoneType());
dataEdges.push_back(edge); dataEdges.push_back(edge);
operands.push_back(Value(edge)); operands.push_back(Value(edge));
} }
mergeOp = rewriter.create<handshake::ControlMergeOp>(insertLoc, operands); mergeOp =
handshake::ControlMergeOp::create(rewriter, insertLoc, operands);
} }
setBlockEntryControl(block, mergeOp->getResult(0)); setBlockEntryControl(block, mergeOp->getResult(0));
return MergeOpInfo{mergeOp, val, dataEdges}; return MergeOpInfo{mergeOp, val, dataEdges};
@ -336,7 +337,7 @@ HandshakeLowering::insertMerge(Block *block, Value val,
dataEdges.push_back(edge); dataEdges.push_back(edge);
operands.push_back(Value(edge)); operands.push_back(Value(edge));
} }
auto merge = rewriter.create<handshake::MergeOp>(insertLoc, operands); auto merge = handshake::MergeOp::create(rewriter, insertLoc, operands);
return MergeOpInfo{merge, val, dataEdges}; return MergeOpInfo{merge, val, dataEdges};
} }
@ -351,7 +352,7 @@ HandshakeLowering::insertMerge(Block *block, Value val,
operands.push_back(Value(edge)); operands.push_back(Value(edge));
} }
auto mux = auto mux =
rewriter.create<handshake::MuxOp>(insertLoc, Value(indexEdge), operands); handshake::MuxOp::create(rewriter, insertLoc, Value(indexEdge), operands);
return MergeOpInfo{mux, val, dataEdges, indexEdge}; return MergeOpInfo{mux, val, dataEdges, indexEdge};
} }
@ -725,8 +726,8 @@ BufferOp FeedForwardNetworkRewriter::buildSplitNetwork(
// TODO how to size these? // TODO how to size these?
// Longest path in a CFG-DAG would be O(#blocks) // Longest path in a CFG-DAG would be O(#blocks)
return rewriter.create<handshake::BufferOp>(loc, cond, bufferSize, return handshake::BufferOp::create(rewriter, loc, cond, bufferSize,
BufferTypeEnum::fifo); BufferTypeEnum::fifo);
} }
LogicalResult FeedForwardNetworkRewriter::buildMergeNetwork( LogicalResult FeedForwardNetworkRewriter::buildMergeNetwork(
@ -752,22 +753,22 @@ LogicalResult FeedForwardNetworkRewriter::buildMergeNetwork(
else else
muxOperands = llvm::to_vector(ctrlMerge.getOperands()); muxOperands = llvm::to_vector(ctrlMerge.getOperands());
Value newCtrl = rewriter.create<handshake::MuxOp>(loc, buf, muxOperands); Value newCtrl = handshake::MuxOp::create(rewriter, loc, buf, muxOperands);
Value cond = buf.getResult(); Value cond = buf.getResult();
if (requiresFlip) { if (requiresFlip) {
// As the mux operand order is the flipped cmerge input order, the index // As the mux operand order is the flipped cmerge input order, the index
// which replaces the output of the cmerge has to be flipped/negated as // which replaces the output of the cmerge has to be flipped/negated as
// well. // well.
cond = rewriter.create<arith::XOrIOp>( cond = arith::XOrIOp::create(
loc, cond.getType(), cond, rewriter, loc, cond.getType(), cond,
rewriter.create<arith::ConstantOp>( arith::ConstantOp::create(
loc, rewriter.getIntegerAttr(rewriter.getI1Type(), 1))); rewriter, loc, rewriter.getIntegerAttr(rewriter.getI1Type(), 1)));
} }
// Require a cast to index to stick to the type of the mux input. // Require a cast to index to stick to the type of the mux input.
Value condAsIndex = Value condAsIndex =
rewriter.create<arith::IndexCastOp>(loc, rewriter.getIndexType(), cond); arith::IndexCastOp::create(rewriter, loc, rewriter.getIndexType(), cond);
hl.setBlockEntryControl(mergeBlock, newCtrl); hl.setBlockEntryControl(mergeBlock, newCtrl);
@ -1149,10 +1150,10 @@ HandshakeLowering::addBranchOps(ConversionPatternRewriter &rewriter) {
Operation *newOp = nullptr; Operation *newOp = nullptr;
if (auto condBranchOp = dyn_cast<mlir::cf::CondBranchOp>(termOp)) if (auto condBranchOp = dyn_cast<mlir::cf::CondBranchOp>(termOp))
newOp = rewriter.create<handshake::ConditionalBranchOp>( newOp = handshake::ConditionalBranchOp::create(
termOp->getLoc(), condBranchOp.getCondition(), val); rewriter, termOp->getLoc(), condBranchOp.getCondition(), val);
else if (isa<mlir::cf::BranchOp>(termOp)) else if (isa<mlir::cf::BranchOp>(termOp))
newOp = rewriter.create<handshake::BranchOp>(termOp->getLoc(), val); newOp = handshake::BranchOp::create(rewriter, termOp->getLoc(), val);
if (newOp == nullptr) if (newOp == nullptr)
continue; continue;
@ -1189,8 +1190,8 @@ LogicalResult HandshakeLowering::connectConstantsToControl(
auto value = constantOp.getValue(); auto value = constantOp.getValue();
rewriter.replaceOpWithNewOp<handshake::ConstantOp>( rewriter.replaceOpWithNewOp<handshake::ConstantOp>(
constantOp, value.getType(), value, constantOp, value.getType(), value,
rewriter.create<handshake::SourceOp>(constantOp.getLoc(), handshake::SourceOp::create(rewriter, constantOp.getLoc(),
rewriter.getNoneType())); rewriter.getNoneType()));
} }
} else { } else {
for (Block &block : r) { for (Block &block : r) {
@ -1301,8 +1302,8 @@ HandshakeLowering::replaceMemoryOps(ConversionPatternRewriter &rewriter,
// This will add all operands except alloc // This will add all operands except alloc
SmallVector<Value, 8> operands(loadOp.getIndices()); SmallVector<Value, 8> operands(loadOp.getIndices());
newOp = newOp = handshake::LoadOp::create(rewriter, op.getLoc(), memref,
rewriter.create<handshake::LoadOp>(op.getLoc(), memref, operands); operands);
op.getResult(0).replaceAllUsesWith(newOp->getResult(0)); op.getResult(0).replaceAllUsesWith(newOp->getResult(0));
}) })
.Case<memref::StoreOp>([&](auto storeOp) { .Case<memref::StoreOp>([&](auto storeOp) {
@ -1311,8 +1312,8 @@ HandshakeLowering::replaceMemoryOps(ConversionPatternRewriter &rewriter,
SmallVector<Value, 8> operands(storeOp.getIndices()); SmallVector<Value, 8> operands(storeOp.getIndices());
// Create new op where operands are store data and address indices // Create new op where operands are store data and address indices
newOp = rewriter.create<handshake::StoreOp>( newOp = handshake::StoreOp::create(
op.getLoc(), storeOp.getValueToStore(), operands); rewriter, op.getLoc(), storeOp.getValueToStore(), operands);
}) })
.Case<AffineReadOpInterface, AffineWriteOpInterface>([&](auto) { .Case<AffineReadOpInterface, AffineWriteOpInterface>([&](auto) {
// Get essential memref access inforamtion. // Get essential memref access inforamtion.
@ -1339,13 +1340,13 @@ HandshakeLowering::replaceMemoryOps(ConversionPatternRewriter &rewriter,
"cannot be reduced."); "cannot be reduced.");
if (isa<AffineReadOpInterface>(op)) { if (isa<AffineReadOpInterface>(op)) {
auto loadOp = rewriter.create<handshake::LoadOp>( auto loadOp = handshake::LoadOp::create(rewriter, op.getLoc(),
op.getLoc(), access.memref, *operands); access.memref, *operands);
newOp = loadOp; newOp = loadOp;
op.getResult(0).replaceAllUsesWith(loadOp.getDataResult()); op.getResult(0).replaceAllUsesWith(loadOp.getDataResult());
} else { } else {
newOp = rewriter.create<handshake::StoreOp>( newOp = handshake::StoreOp::create(rewriter, op.getLoc(),
op.getLoc(), op.getOperand(0), *operands); op.getOperand(0), *operands);
} }
}) })
.Default([&](auto) { .Default([&](auto) {
@ -1417,7 +1418,7 @@ static void addJoinOps(ConversionPatternRewriter &rewriter,
// Insert only single join per block // Insert only single join per block
if (!isa<JoinOp>(srcOp)) { if (!isa<JoinOp>(srcOp)) {
rewriter.setInsertionPointAfter(srcOp); rewriter.setInsertionPointAfter(srcOp);
Operation *newJoin = rewriter.create<JoinOp>(srcOp->getLoc(), ctrl); Operation *newJoin = JoinOp::create(rewriter, srcOp->getLoc(), ctrl);
op->replaceUsesOfWith(ctrl, newJoin->getResult(0)); op->replaceUsesOfWith(ctrl, newJoin->getResult(0));
} }
} }
@ -1503,7 +1504,7 @@ void HandshakeLowering::setMemOpControlInputs(
else { else {
rewriter.setInsertionPoint(currOp); rewriter.setInsertionPoint(currOp);
Operation *joinOp = Operation *joinOp =
rewriter.create<JoinOp>(currOp->getLoc(), controlOperands); JoinOp::create(rewriter, currOp->getLoc(), controlOperands);
addValueToOperands(currOp, joinOp->getResult(0)); addValueToOperands(currOp, joinOp->getResult(0));
} }
} }
@ -1583,13 +1584,13 @@ HandshakeLowering::connectToMemory(ConversionPatternRewriter &rewriter,
// Place memory op next to the alloc op // Place memory op next to the alloc op
Operation *newOp = nullptr; Operation *newOp = nullptr;
if (isExternalMemory) if (isExternalMemory)
newOp = rewriter.create<ExternalMemoryOp>( newOp = ExternalMemoryOp::create(rewriter, entryBlock->front().getLoc(),
entryBlock->front().getLoc(), memrefOperand, operands, ld_count, memrefOperand, operands, ld_count,
cntrl_count - ld_count, mem_count++); cntrl_count - ld_count, mem_count++);
else else
newOp = rewriter.create<MemoryOp>(entryBlock->front().getLoc(), operands, newOp = MemoryOp::create(rewriter, entryBlock->front().getLoc(), operands,
ld_count, cntrl_count, lsq, mem_count++, ld_count, cntrl_count, lsq, mem_count++,
memrefOperand); memrefOperand);
setLoadDataInputs(memory.second, newOp); setLoadDataInputs(memory.second, newOp);
@ -1636,9 +1637,9 @@ HandshakeLowering::replaceCallOps(ConversionPatternRewriter &rewriter) {
llvm::copy(callOp.getOperands(), std::back_inserter(operands)); llvm::copy(callOp.getOperands(), std::back_inserter(operands));
operands.push_back(blockEntryControl); operands.push_back(blockEntryControl);
rewriter.setInsertionPoint(callOp); rewriter.setInsertionPoint(callOp);
auto instanceOp = rewriter.create<handshake::InstanceOp>( auto instanceOp = handshake::InstanceOp::create(
callOp.getLoc(), callOp.getCallee(), callOp.getResultTypes(), rewriter, callOp.getLoc(), callOp.getCallee(),
operands); callOp.getResultTypes(), operands);
// Replace all results of the source callOp. // Replace all results of the source callOp.
for (auto it : llvm::zip(callOp.getResults(), instanceOp.getResults())) for (auto it : llvm::zip(callOp.getResults(), instanceOp.getResults()))
std::get<0>(it).replaceAllUsesWith(std::get<1>(it)); std::get<0>(it).replaceAllUsesWith(std::get<1>(it));
@ -1705,8 +1706,9 @@ static LogicalResult lowerFuncOp(func::FuncOp funcOp, MLIRContext *ctx,
resTypes.push_back(noneType); resTypes.push_back(noneType);
argTypes.push_back(noneType); argTypes.push_back(noneType);
auto func_type = rewriter.getFunctionType(argTypes, resTypes); auto func_type = rewriter.getFunctionType(argTypes, resTypes);
newFuncOp = rewriter.create<handshake::FuncOp>( newFuncOp = handshake::FuncOp::create(rewriter, funcOp.getLoc(),
funcOp.getLoc(), funcOp.getName(), func_type, attributes); funcOp.getName(), func_type,
attributes);
rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(), rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(),
newFuncOp.end()); newFuncOp.end());
if (!newFuncOp.isExternal()) { if (!newFuncOp.isExternal()) {

View File

@ -260,7 +260,7 @@ LogicalResult CompileFSMVisitor::visit(StateOp currentState, EnableOp enableOp,
// callers iterating over nested ops safer. // callers iterating over nested ops safer.
OpBuilder::InsertionGuard g(builder); OpBuilder::InsertionGuard g(builder);
builder.setInsertionPointToStart(&currentState.getOutput().front()); builder.setInsertionPointToStart(&currentState.getOutput().front());
builder.create<calyx::EnableOp>(enableOp.getLoc(), enableOp.getGroupName()); calyx::EnableOp::create(builder, enableOp.getLoc(), enableOp.getGroupName());
if (nextState) if (nextState)
graph.createTransition(builder, enableOp.getLoc(), currentState, nextState); graph.createTransition(builder, enableOp.getLoc(), currentState, nextState);
@ -319,31 +319,31 @@ void CompileInvoke::lowerInvokeOp(InvokeOp invokeOp) {
// Create a ConstantOp to assign a value to the go port. // Create a ConstantOp to assign a value to the go port.
Operation *prevNode = component.getWiresOp().getOperation()->getPrevNode(); Operation *prevNode = component.getWiresOp().getOperation()->getPrevNode();
builder.setInsertionPointAfter(prevNode); builder.setInsertionPointAfter(prevNode);
hw::ConstantOp constantOp = builder.create<hw::ConstantOp>( hw::ConstantOp constantOp = hw::ConstantOp::create(
prevNode->getLoc(), builder.getI1Type(), 1); builder, prevNode->getLoc(), builder.getI1Type(), 1);
Location loc = component.getWiresOp().getLoc(); Location loc = component.getWiresOp().getLoc();
// Set the insertion point at the end of the wires block. // Set the insertion point at the end of the wires block.
builder.setInsertionPointToEnd(component.getWiresOp().getBodyBlock()); builder.setInsertionPointToEnd(component.getWiresOp().getBodyBlock());
std::string transitionName = getTransitionName(invokeOp); std::string transitionName = getTransitionName(invokeOp);
GroupOp groupOp = builder.create<GroupOp>(loc, transitionName); GroupOp groupOp = GroupOp::create(builder, loc, transitionName);
builder.setInsertionPointToStart(groupOp.getBodyBlock()); builder.setInsertionPointToStart(groupOp.getBodyBlock());
Value go = invokeOp.getInstGoValue(); Value go = invokeOp.getInstGoValue();
// Assign a value to the go port. // Assign a value to the go port.
builder.create<AssignOp>(loc, go, constantOp); AssignOp::create(builder, loc, go, constantOp);
auto ports = invokeOp.getPorts(); auto ports = invokeOp.getPorts();
auto inputs = invokeOp.getInputs(); auto inputs = invokeOp.getInputs();
// Generate a series of assignment operations from a list of parameters. // Generate a series of assignment operations from a list of parameters.
for (auto [port, input] : llvm::zip(ports, inputs)) for (auto [port, input] : llvm::zip(ports, inputs))
builder.create<AssignOp>(loc, port, input); AssignOp::create(builder, loc, port, input);
Value done = invokeOp.getInstDoneValue(); Value done = invokeOp.getInstDoneValue();
// Generate a group_done operation with the instance's done port. // Generate a group_done operation with the instance's done port.
builder.create<calyx::GroupDoneOp>(loc, done); calyx::GroupDoneOp::create(builder, loc, done);
builder.setInsertionPointAfter(invokeOp.getOperation()); builder.setInsertionPointAfter(invokeOp.getOperation());
builder.create<EnableOp>(invokeOp.getLoc(), transitionName); EnableOp::create(builder, invokeOp.getLoc(), transitionName);
invokeOp.erase(); invokeOp.erase();
} }
@ -369,9 +369,8 @@ void CalyxToFSMPass::runOnOperation() {
// outlining the FSM (materializing FSM I/O) at a later point. // outlining the FSM (materializing FSM I/O) at a later point.
auto machineName = ("control_" + component.getName()).str(); auto machineName = ("control_" + component.getName()).str();
auto funcType = FunctionType::get(&getContext(), {}, {}); auto funcType = FunctionType::get(&getContext(), {}, {});
auto machine = auto machine = MachineOp::create(builder, ctrlOp.getLoc(), machineName,
builder.create<MachineOp>(ctrlOp.getLoc(), machineName, /*initialState=*/"fsm_entry", funcType);
/*initialState=*/"fsm_entry", funcType);
auto graph = FSMGraph(machine); auto graph = FSMGraph(machine);
SymbolCache sc; SymbolCache sc;

View File

@ -87,7 +87,7 @@ struct MaterializeCalyxToFSMPass
guardConjunction = guards.front(); guardConjunction = guards.front();
else else
guardConjunction = guardConjunction =
b.create<comb::AndOp>(transition.getLoc(), guards, false); comb::AndOp::create(b, transition.getLoc(), guards, false);
guardOp.setOperand(guardConjunction); guardOp.setOperand(guardConjunction);
} }
} }
@ -99,7 +99,7 @@ struct MaterializeCalyxToFSMPass
OpBuilder::InsertionGuard g(b); OpBuilder::InsertionGuard g(b);
b.setInsertionPointToStart(&machineOp.getBody().front()); b.setInsertionPointToStart(&machineOp.getBody().front());
auto constantOp = b.create<hw::ConstantOp>(machineOp.getLoc(), value); auto constantOp = hw::ConstantOp::create(b, machineOp.getLoc(), value);
constants[value] = constantOp; constants[value] = constantOp;
return constantOp; return constantOp;
} }

View File

@ -53,8 +53,8 @@ struct ConvertComponentOp : public OpConversionPattern<ComponentOp> {
ModulePortInfo hwPortInfo(hwInputInfo); ModulePortInfo hwPortInfo(hwInputInfo);
SmallVector<Value> argValues; SmallVector<Value> argValues;
auto hwMod = rewriter.create<HWModuleOp>( auto hwMod = HWModuleOp::create(
component.getLoc(), component.getNameAttr(), hwPortInfo, rewriter, component.getLoc(), component.getNameAttr(), hwPortInfo,
[&](OpBuilder &b, HWModulePortAccessor &ports) { [&](OpBuilder &b, HWModulePortAccessor &ports) {
for (auto [name, type, direction, _] : portInfo) { for (auto [name, type, direction, _] : portInfo) {
switch (direction) { switch (direction) {
@ -63,9 +63,9 @@ struct ConvertComponentOp : public OpConversionPattern<ComponentOp> {
argValues.push_back(ports.getInput(name)); argValues.push_back(ports.getInput(name));
break; break;
case calyx::Direction::Output: case calyx::Direction::Output:
auto wire = b.create<sv::WireOp>(component.getLoc(), type, name); auto wire = sv::WireOp::create(b, component.getLoc(), type, name);
auto wireRead = auto wireRead =
b.create<sv::ReadInOutOp>(component.getLoc(), wire); sv::ReadInOutOp::create(b, component.getLoc(), wire);
argValues.push_back(wireRead); argValues.push_back(wireRead);
ports.setOutput(name, wireRead); ports.setOutput(name, wireRead);
break; break;
@ -131,15 +131,15 @@ struct ConvertAssignOp : public OpConversionPattern<calyx::AssignOp> {
Value src = adaptor.getSrc(); Value src = adaptor.getSrc();
if (auto guard = adaptor.getGuard()) { if (auto guard = adaptor.getGuard()) {
auto zero = auto zero =
rewriter.create<hw::ConstantOp>(assign.getLoc(), src.getType(), 0); hw::ConstantOp::create(rewriter, assign.getLoc(), src.getType(), 0);
src = rewriter.create<MuxOp>(assign.getLoc(), guard, src, zero); src = MuxOp::create(rewriter, assign.getLoc(), guard, src, zero);
for (Operation *destUser : for (Operation *destUser :
llvm::make_early_inc_range(assign.getDest().getUsers())) { llvm::make_early_inc_range(assign.getDest().getUsers())) {
if (destUser == assign) if (destUser == assign)
continue; continue;
if (auto otherAssign = dyn_cast<calyx::AssignOp>(destUser)) { if (auto otherAssign = dyn_cast<calyx::AssignOp>(destUser)) {
src = rewriter.create<MuxOp>(assign.getLoc(), otherAssign.getGuard(), src = MuxOp::create(rewriter, assign.getLoc(), otherAssign.getGuard(),
otherAssign.getSrc(), src); otherAssign.getSrc(), src);
rewriter.eraseOp(destUser); rewriter.eraseOp(destUser);
} }
} }
@ -250,7 +250,7 @@ private:
auto fal = wireIn(op.getFal(), op.instanceName(), auto fal = wireIn(op.getFal(), op.instanceName(),
op.portName(op.getFal()), b); op.portName(op.getFal()), b);
auto mux = b.create<MuxOp>(sel, tru, fal); auto mux = MuxOp::create(b, sel, tru, fal);
auto out = auto out =
wireOut(mux, op.instanceName(), op.portName(op.getOut()), b); wireOut(mux, op.instanceName(), op.portName(op.getOut()), b);
@ -282,12 +282,12 @@ private:
op.portName(op.getClk()), b); op.portName(op.getClk()), b);
auto reset = wireIn(op.getReset(), op.instanceName(), auto reset = wireIn(op.getReset(), op.instanceName(),
op.portName(op.getReset()), b); op.portName(op.getReset()), b);
auto seqClk = b.create<seq::ToClockOp>(clk); auto seqClk = seq::ToClockOp::create(b, clk);
auto doneReg = auto doneReg =
reg(writeEn, seqClk, reset, op.instanceName() + "_done_reg", b); reg(writeEn, seqClk, reset, op.instanceName() + "_done_reg", b);
auto done = auto done =
wireOut(doneReg, op.instanceName(), op.portName(op.getDone()), b); wireOut(doneReg, op.instanceName(), op.portName(op.getDone()), b);
auto clockEn = b.create<AndOp>(writeEn, createOrFoldNot(done, b)); auto clockEn = AndOp::create(b, writeEn, createOrFoldNot(done, b));
auto outReg = auto outReg =
regCe(in, seqClk, clockEn, reset, op.instanceName() + "_reg", b); regCe(in, seqClk, clockEn, reset, op.instanceName() + "_reg", b);
auto out = wireOut(outReg, op.instanceName(), "", b); auto out = wireOut(outReg, op.instanceName(), "", b);
@ -300,7 +300,7 @@ private:
wireIn(op.getIn(), op.instanceName(), op.portName(op.getIn()), b); wireIn(op.getIn(), op.instanceName(), op.portName(op.getIn()), b);
auto outWidth = op.getOut().getType().getIntOrFloatBitWidth(); auto outWidth = op.getOut().getType().getIntOrFloatBitWidth();
auto extract = b.create<ExtractOp>(in, 0, outWidth); auto extract = ExtractOp::create(b, in, 0, outWidth);
auto out = auto out =
wireOut(extract, op.instanceName(), op.portName(op.getOut()), b); wireOut(extract, op.instanceName(), op.portName(op.getOut()), b);
@ -321,7 +321,7 @@ private:
wires.append({wire.getInput(), wire}); wires.append({wire.getInput(), wire});
}) })
.Case([&](UndefLibOp op) { .Case([&](UndefLibOp op) {
auto undef = b.create<sv::ConstantXOp>(op.getType()); auto undef = sv::ConstantXOp::create(b, op.getType());
wires.append({undef}); wires.append({undef});
}) })
.Case([&](PadLibOp op) { .Case([&](PadLibOp op) {
@ -329,8 +329,8 @@ private:
wireIn(op.getIn(), op.instanceName(), op.portName(op.getIn()), b); wireIn(op.getIn(), op.instanceName(), op.portName(op.getIn()), b);
auto srcWidth = in.getType().getIntOrFloatBitWidth(); auto srcWidth = in.getType().getIntOrFloatBitWidth();
auto destWidth = op.getOut().getType().getIntOrFloatBitWidth(); auto destWidth = op.getOut().getType().getIntOrFloatBitWidth();
auto zero = b.create<hw::ConstantOp>(op.getLoc(), auto zero = hw::ConstantOp::create(b, op.getLoc(),
APInt(destWidth - srcWidth, 0)); APInt(destWidth - srcWidth, 0));
auto padded = wireOut(b.createOrFold<comb::ConcatOp>(zero, in), auto padded = wireOut(b.createOrFold<comb::ConcatOp>(zero, in),
op.instanceName(), op.portName(op.getOut()), b); op.instanceName(), op.portName(op.getOut()), b);
wires.append({in.getInput(), padded}); wires.append({in.getInput(), padded});
@ -354,7 +354,7 @@ private:
auto right = auto right =
wireIn(op.getRight(), op.instanceName(), op.portName(op.getRight()), b); wireIn(op.getRight(), op.instanceName(), op.portName(op.getRight()), b);
auto add = b.create<ResultTy>(left, right, false); auto add = ResultTy::create(b, left, right, false);
auto out = wireOut(add, op.instanceName(), op.portName(op.getOut()), b); auto out = wireOut(add, op.instanceName(), op.portName(op.getOut()), b);
wires.append({left.getInput(), right.getInput(), out}); wires.append({left.getInput(), right.getInput(), out});
@ -369,7 +369,7 @@ private:
auto right = auto right =
wireIn(op.getRight(), op.instanceName(), op.portName(op.getRight()), b); wireIn(op.getRight(), op.instanceName(), op.portName(op.getRight()), b);
auto add = b.create<ICmpOp>(pred, left, right, false); auto add = ICmpOp::create(b, pred, left, right, false);
auto out = wireOut(add, op.instanceName(), op.portName(op.getOut()), b); auto out = wireOut(add, op.instanceName(), op.portName(op.getOut()), b);
wires.append({left.getInput(), right.getInput(), out}); wires.append({left.getInput(), right.getInput(), out});
@ -395,11 +395,11 @@ private:
auto done = auto done =
wireOut(doneReg, op.instanceName(), op.portName(op.getDone()), b); wireOut(doneReg, op.instanceName(), op.portName(op.getDone()), b);
auto targetOp = b.create<TargetOpTy>(left, right, false); auto targetOp = TargetOpTy::create(b, left, right, false);
for (auto &&[targetRes, sourceRes] : for (auto &&[targetRes, sourceRes] :
llvm::zip(targetOp->getResults(), op.getOutputPorts())) { llvm::zip(targetOp->getResults(), op.getOutputPorts())) {
auto portName = op.portName(sourceRes); auto portName = op.portName(sourceRes);
auto clockEn = b.create<AndOp>(go, createOrFoldNot(done, b)); auto clockEn = AndOp::create(b, go, createOrFoldNot(done, b));
auto resReg = regCe(targetRes, clk, clockEn, reset, auto resReg = regCe(targetRes, clk, clockEn, reset,
createName(op.instanceName(), portName), b); createName(op.instanceName(), portName), b);
wires.push_back(wireOut(resReg, op.instanceName(), portName, b)); wires.push_back(wireOut(resReg, op.instanceName(), portName, b));
@ -410,31 +410,31 @@ private:
ReadInOutOp wireIn(Value source, StringRef instanceName, StringRef portName, ReadInOutOp wireIn(Value source, StringRef instanceName, StringRef portName,
ImplicitLocOpBuilder &b) const { ImplicitLocOpBuilder &b) const {
auto wire = b.create<sv::WireOp>(source.getType(), auto wire = sv::WireOp::create(b, source.getType(),
createName(instanceName, portName)); createName(instanceName, portName));
return b.create<ReadInOutOp>(wire); return ReadInOutOp::create(b, wire);
} }
ReadInOutOp wireOut(Value source, StringRef instanceName, StringRef portName, ReadInOutOp wireOut(Value source, StringRef instanceName, StringRef portName,
ImplicitLocOpBuilder &b) const { ImplicitLocOpBuilder &b) const {
auto wire = b.create<sv::WireOp>(source.getType(), auto wire = sv::WireOp::create(b, source.getType(),
createName(instanceName, portName)); createName(instanceName, portName));
b.create<sv::AssignOp>(wire, source); sv::AssignOp::create(b, wire, source);
return b.create<ReadInOutOp>(wire); return ReadInOutOp::create(b, wire);
} }
CompRegOp reg(Value source, Value clock, Value reset, const Twine &name, CompRegOp reg(Value source, Value clock, Value reset, const Twine &name,
ImplicitLocOpBuilder &b) const { ImplicitLocOpBuilder &b) const {
auto resetValue = b.create<hw::ConstantOp>(source.getType(), 0); auto resetValue = hw::ConstantOp::create(b, source.getType(), 0);
return b.create<CompRegOp>(source, clock, reset, resetValue, name.str()); return CompRegOp::create(b, source, clock, reset, resetValue, name.str());
} }
CompRegClockEnabledOp regCe(Value source, Value clock, Value ce, Value reset, CompRegClockEnabledOp regCe(Value source, Value clock, Value ce, Value reset,
const Twine &name, const Twine &name,
ImplicitLocOpBuilder &b) const { ImplicitLocOpBuilder &b) const {
auto resetValue = b.create<hw::ConstantOp>(source.getType(), 0); auto resetValue = hw::ConstantOp::create(b, source.getType(), 0);
return b.create<CompRegClockEnabledOp>(source, clock, ce, reset, resetValue, return CompRegClockEnabledOp::create(b, source, clock, ce, reset,
name.str()); resetValue, name.str());
} }
std::string createName(StringRef instanceName, StringRef portName) const { std::string createName(StringRef instanceName, StringRef portName) const {

View File

@ -88,8 +88,8 @@ static Value createShiftLogic(ConversionPatternRewriter &rewriter, Location loc,
// Add bounds checking // Add bounds checking
auto inBound = rewriter.createOrFold<comb::ICmpOp>( auto inBound = rewriter.createOrFold<comb::ICmpOp>(
loc, ICmpPredicate::ult, shiftAmount, loc, ICmpPredicate::ult, shiftAmount,
rewriter.create<hw::ConstantOp>(loc, shiftAmount.getType(), hw::ConstantOp::create(rewriter, loc, shiftAmount.getType(),
maxShiftAmount)); maxShiftAmount));
return rewriter.createOrFold<comb::MuxOp>(loc, inBound, result, return rewriter.createOrFold<comb::MuxOp>(loc, inBound, result,
outOfBoundsValue); outOfBoundsValue);
@ -196,7 +196,7 @@ static LogicalResult emulateBinaryOpForUnknownBits(
auto it = constantPool.find(attr); auto it = constantPool.find(attr);
if (it != constantPool.end()) if (it != constantPool.end())
return it->second; return it->second;
auto constant = rewriter.create<hw::ConstantOp>(loc, value); auto constant = hw::ConstantOp::create(rewriter, loc, value);
constantPool[attr] = constant; constantPool[attr] = constant;
return constant; return constant;
}; };
@ -261,8 +261,8 @@ struct CombOrOpConversion : OpConversionPattern<OrOp> {
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
// Implement Or using And and invert flags: a | b = ~(~a & ~b) // Implement Or using And and invert flags: a | b = ~(~a & ~b)
SmallVector<bool> allInverts(adaptor.getInputs().size(), true); SmallVector<bool> allInverts(adaptor.getInputs().size(), true);
auto andOp = rewriter.create<aig::AndInverterOp>( auto andOp = aig::AndInverterOp::create(rewriter, op.getLoc(),
op.getLoc(), adaptor.getInputs(), allInverts); adaptor.getInputs(), allInverts);
replaceOpWithNewOpAndCopyNamehint<aig::AndInverterOp>(rewriter, op, andOp, replaceOpWithNewOpAndCopyNamehint<aig::AndInverterOp>(rewriter, op, andOp,
/*invert=*/true); /*invert=*/true);
return success(); return success();
@ -287,9 +287,9 @@ struct CombXorOpConversion : OpConversionPattern<XorOp> {
SmallVector<bool> allNotInverts(inputs.size(), false); SmallVector<bool> allNotInverts(inputs.size(), false);
auto notAAndNotB = auto notAAndNotB =
rewriter.create<aig::AndInverterOp>(op.getLoc(), inputs, allInverts); aig::AndInverterOp::create(rewriter, op.getLoc(), inputs, allInverts);
auto aAndB = auto aAndB = aig::AndInverterOp::create(rewriter, op.getLoc(), inputs,
rewriter.create<aig::AndInverterOp>(op.getLoc(), inputs, allNotInverts); allNotInverts);
replaceOpWithNewOpAndCopyNamehint<aig::AndInverterOp>(rewriter, op, replaceOpWithNewOpAndCopyNamehint<aig::AndInverterOp>(rewriter, op,
notAAndNotB, aAndB, notAAndNotB, aAndB,
@ -323,14 +323,14 @@ struct CombLowerVariadicOp : OpConversionPattern<OpTy> {
case 2: case 2:
lhs = operands[0]; lhs = operands[0];
rhs = operands[1]; rhs = operands[1];
return rewriter.create<OpTy>(op.getLoc(), ValueRange{lhs, rhs}, true); return OpTy::create(rewriter, op.getLoc(), ValueRange{lhs, rhs}, true);
default: default:
auto firstHalf = operands.size() / 2; auto firstHalf = operands.size() / 2;
lhs = lhs =
lowerFullyAssociativeOp(op, operands.take_front(firstHalf), rewriter); lowerFullyAssociativeOp(op, operands.take_front(firstHalf), rewriter);
rhs = rhs =
lowerFullyAssociativeOp(op, operands.drop_front(firstHalf), rewriter); lowerFullyAssociativeOp(op, operands.drop_front(firstHalf), rewriter);
return rewriter.create<OpTy>(op.getLoc(), ValueRange{lhs, rhs}, true); return OpTy::create(rewriter, op.getLoc(), ValueRange{lhs, rhs}, true);
} }
} }
}; };
@ -352,26 +352,26 @@ struct CombMuxOpConversion : OpConversionPattern<MuxOp> {
// If the type of the mux is not integer, bitcast the operands first. // If the type of the mux is not integer, bitcast the operands first.
auto widthType = rewriter.getIntegerType(hw::getBitWidth(op.getType())); auto widthType = rewriter.getIntegerType(hw::getBitWidth(op.getType()));
trueVal = trueVal =
rewriter.create<hw::BitcastOp>(op->getLoc(), widthType, trueVal); hw::BitcastOp::create(rewriter, op->getLoc(), widthType, trueVal);
falseVal = falseVal =
rewriter.create<hw::BitcastOp>(op->getLoc(), widthType, falseVal); hw::BitcastOp::create(rewriter, op->getLoc(), widthType, falseVal);
} }
// Replicate condition if needed // Replicate condition if needed
if (!trueVal.getType().isInteger(1)) if (!trueVal.getType().isInteger(1))
cond = rewriter.create<comb::ReplicateOp>(op.getLoc(), trueVal.getType(), cond = comb::ReplicateOp::create(rewriter, op.getLoc(), trueVal.getType(),
cond); cond);
// c ? a : b => (replicate(c) & a) | (~replicate(c) & b) // c ? a : b => (replicate(c) & a) | (~replicate(c) & b)
auto lhs = rewriter.create<aig::AndInverterOp>(op.getLoc(), cond, trueVal); auto lhs = aig::AndInverterOp::create(rewriter, op.getLoc(), cond, trueVal);
auto rhs = rewriter.create<aig::AndInverterOp>(op.getLoc(), cond, falseVal, auto rhs = aig::AndInverterOp::create(rewriter, op.getLoc(), cond, falseVal,
true, false); true, false);
Value result = rewriter.create<comb::OrOp>(op.getLoc(), lhs, rhs); Value result = comb::OrOp::create(rewriter, op.getLoc(), lhs, rhs);
// Insert the bitcast if the type of the mux is not integer. // Insert the bitcast if the type of the mux is not integer.
if (result.getType() != op.getType()) if (result.getType() != op.getType())
result = result =
rewriter.create<hw::BitcastOp>(op.getLoc(), op.getType(), result); hw::BitcastOp::create(rewriter, op.getLoc(), op.getType(), result);
replaceOpAndCopyNamehint(rewriter, op, result); replaceOpAndCopyNamehint(rewriter, op, result);
return success(); return success();
} }
@ -423,27 +423,27 @@ struct CombAddOpConversion : OpConversionPattern<AddOp> {
// sum[i] = xor(carry[i-1], a[i], b[i]) // sum[i] = xor(carry[i-1], a[i], b[i])
// NOTE: The result is stored in reverse order. // NOTE: The result is stored in reverse order.
results[width - i - 1] = results[width - i - 1] =
rewriter.create<comb::XorOp>(op.getLoc(), xorOperands, true); comb::XorOp::create(rewriter, op.getLoc(), xorOperands, true);
// If this is the last bit, we are done. // If this is the last bit, we are done.
if (i == width - 1) if (i == width - 1)
break; break;
// carry[i] = (carry[i-1] & (a[i] ^ b[i])) | (a[i] & b[i]) // carry[i] = (carry[i-1] & (a[i] ^ b[i])) | (a[i] & b[i])
Value nextCarry = rewriter.create<comb::AndOp>( Value nextCarry = comb::AndOp::create(
op.getLoc(), ValueRange{aBits[i], bBits[i]}, true); rewriter, op.getLoc(), ValueRange{aBits[i], bBits[i]}, true);
if (!carry) { if (!carry) {
// This is the first bit, so the carry is the next carry. // This is the first bit, so the carry is the next carry.
carry = nextCarry; carry = nextCarry;
continue; continue;
} }
auto aXnorB = rewriter.create<comb::XorOp>( auto aXnorB = comb::XorOp::create(rewriter, op.getLoc(),
op.getLoc(), ValueRange{aBits[i], bBits[i]}, true); ValueRange{aBits[i], bBits[i]}, true);
auto andOp = rewriter.create<comb::AndOp>( auto andOp = comb::AndOp::create(rewriter, op.getLoc(),
op.getLoc(), ValueRange{carry, aXnorB}, true); ValueRange{carry, aXnorB}, true);
carry = rewriter.create<comb::OrOp>(op.getLoc(), carry = comb::OrOp::create(rewriter, op.getLoc(),
ValueRange{andOp, nextCarry}, true); ValueRange{andOp, nextCarry}, true);
} }
LLVM_DEBUG(llvm::dbgs() << "Lower comb.add to Ripple-Carry Adder of width " LLVM_DEBUG(llvm::dbgs() << "Lower comb.add to Ripple-Carry Adder of width "
<< width << "\n"); << width << "\n");
@ -467,9 +467,9 @@ struct CombAddOpConversion : OpConversionPattern<AddOp> {
for (auto [aBit, bBit] : llvm::zip(aBits, bBits)) { for (auto [aBit, bBit] : llvm::zip(aBits, bBits)) {
// p_i = a_i XOR b_i // p_i = a_i XOR b_i
p.push_back(rewriter.create<comb::XorOp>(op.getLoc(), aBit, bBit)); p.push_back(comb::XorOp::create(rewriter, op.getLoc(), aBit, bBit));
// g_i = a_i AND b_i // g_i = a_i AND b_i
g.push_back(rewriter.create<comb::AndOp>(op.getLoc(), aBit, bBit)); g.push_back(comb::AndOp::create(rewriter, op.getLoc(), aBit, bBit));
} }
LLVM_DEBUG({ LLVM_DEBUG({
@ -503,7 +503,7 @@ struct CombAddOpConversion : OpConversionPattern<AddOp> {
// The carry into position i is the group generate from position i-1 // The carry into position i is the group generate from position i-1
for (int64_t i = 1; i < width; ++i) for (int64_t i = 1; i < width; ++i)
results[width - 1 - i] = results[width - 1 - i] =
rewriter.create<comb::XorOp>(op.getLoc(), p[i], gPrefix[i - 1]); comb::XorOp::create(rewriter, op.getLoc(), p[i], gPrefix[i - 1]);
replaceOpWithNewOpAndCopyNamehint<comb::ConcatOp>(rewriter, op, results); replaceOpWithNewOpAndCopyNamehint<comb::ConcatOp>(rewriter, op, results);
@ -530,13 +530,13 @@ struct CombAddOpConversion : OpConversionPattern<AddOp> {
int64_t j = i - stride; int64_t j = i - stride;
// Group generate: g_i OR (p_i AND g_j) // Group generate: g_i OR (p_i AND g_j)
Value andPG = Value andPG =
rewriter.create<comb::AndOp>(op.getLoc(), pPrefix[i], gPrefix[j]); comb::AndOp::create(rewriter, op.getLoc(), pPrefix[i], gPrefix[j]);
gPrefix[i] = gPrefix[i] =
rewriter.create<comb::OrOp>(op.getLoc(), gPrefix[i], andPG); comb::OrOp::create(rewriter, op.getLoc(), gPrefix[i], andPG);
// Group propagate: p_i AND p_j // Group propagate: p_i AND p_j
pPrefix[i] = pPrefix[i] =
rewriter.create<comb::AndOp>(op.getLoc(), pPrefix[i], pPrefix[j]); comb::AndOp::create(rewriter, op.getLoc(), pPrefix[i], pPrefix[j]);
} }
} }
LLVM_DEBUG({ LLVM_DEBUG({
@ -579,13 +579,13 @@ struct CombAddOpConversion : OpConversionPattern<AddOp> {
// Group generate: g_i OR (p_i AND g_j) // Group generate: g_i OR (p_i AND g_j)
Value andPG = Value andPG =
rewriter.create<comb::AndOp>(op.getLoc(), pPrefix[i], gPrefix[j]); comb::AndOp::create(rewriter, op.getLoc(), pPrefix[i], gPrefix[j]);
gPrefix[i] = gPrefix[i] =
rewriter.create<comb::OrOp>(op.getLoc(), gPrefix[i], andPG); comb::OrOp::create(rewriter, op.getLoc(), gPrefix[i], andPG);
// Group propagate: p_i AND p_j // Group propagate: p_i AND p_j
pPrefix[i] = pPrefix[i] =
rewriter.create<comb::AndOp>(op.getLoc(), pPrefix[i], pPrefix[j]); comb::AndOp::create(rewriter, op.getLoc(), pPrefix[i], pPrefix[j]);
} }
} }
@ -596,12 +596,12 @@ struct CombAddOpConversion : OpConversionPattern<AddOp> {
// Group generate: g_i OR (p_i AND g_j) // Group generate: g_i OR (p_i AND g_j)
Value andPG = Value andPG =
rewriter.create<comb::AndOp>(op.getLoc(), pPrefix[i], gPrefix[j]); comb::AndOp::create(rewriter, op.getLoc(), pPrefix[i], gPrefix[j]);
gPrefix[i] = rewriter.create<OrOp>(op.getLoc(), gPrefix[i], andPG); gPrefix[i] = OrOp::create(rewriter, op.getLoc(), gPrefix[i], andPG);
// Group propagate: p_i AND p_j // Group propagate: p_i AND p_j
pPrefix[i] = pPrefix[i] =
rewriter.create<comb::AndOp>(op.getLoc(), pPrefix[i], pPrefix[j]); comb::AndOp::create(rewriter, op.getLoc(), pPrefix[i], pPrefix[j]);
} }
} }
@ -659,9 +659,9 @@ struct CombSubOpConversion : OpConversionPattern<SubOp> {
// Since `-rhs = ~rhs + 1` holds, rewrite `sub(lhs, rhs)` to: // Since `-rhs = ~rhs + 1` holds, rewrite `sub(lhs, rhs)` to:
// sub(lhs, rhs) => add(lhs, -rhs) => add(lhs, add(~rhs, 1)) // sub(lhs, rhs) => add(lhs, -rhs) => add(lhs, add(~rhs, 1))
// => add(lhs, ~rhs, 1) // => add(lhs, ~rhs, 1)
auto notRhs = rewriter.create<aig::AndInverterOp>(op.getLoc(), rhs, auto notRhs = aig::AndInverterOp::create(rewriter, op.getLoc(), rhs,
/*invert=*/true); /*invert=*/true);
auto one = rewriter.create<hw::ConstantOp>(op.getLoc(), op.getType(), 1); auto one = hw::ConstantOp::create(rewriter, op.getLoc(), op.getType(), 1);
replaceOpWithNewOpAndCopyNamehint<comb::AddOp>( replaceOpWithNewOpAndCopyNamehint<comb::AddOp>(
rewriter, op, ValueRange{lhs, notRhs, one}, true); rewriter, op, ValueRange{lhs, notRhs, one}, true);
return success(); return success();
@ -692,7 +692,7 @@ struct CombMulOpConversion : OpConversionPattern<MulOp> {
SmallVector<Value> aBits = extractBits(rewriter, a); SmallVector<Value> aBits = extractBits(rewriter, a);
SmallVector<Value> bBits = extractBits(rewriter, b); SmallVector<Value> bBits = extractBits(rewriter, b);
auto falseValue = rewriter.create<hw::ConstantOp>(loc, APInt(1, 0)); auto falseValue = hw::ConstantOp::create(rewriter, loc, APInt(1, 0));
// Generate partial products // Generate partial products
SmallVector<SmallVector<Value>> partialProducts; SmallVector<SmallVector<Value>> partialProducts;
@ -718,7 +718,7 @@ struct CombMulOpConversion : OpConversionPattern<MulOp> {
auto addends = auto addends =
comb::wallaceReduction(rewriter, loc, width, 2, partialProducts); comb::wallaceReduction(rewriter, loc, width, 2, partialProducts);
// Sum the two addends using a carry-propagate adder // Sum the two addends using a carry-propagate adder
auto newAdd = rewriter.create<comb::AddOp>(loc, addends, true); auto newAdd = comb::AddOp::create(rewriter, loc, addends, true);
replaceOpAndCopyNamehint(rewriter, op, newAdd); replaceOpAndCopyNamehint(rewriter, op, newAdd);
return success(); return success();
} }
@ -749,8 +749,8 @@ struct CombDivUOpConversion : DivModOpConversionBase<DivUOp> {
Value upperBits = rewriter.createOrFold<comb::ExtractOp>( Value upperBits = rewriter.createOrFold<comb::ExtractOp>(
op.getLoc(), adaptor.getLhs(), extractAmount, op.getLoc(), adaptor.getLhs(), extractAmount,
width - extractAmount); width - extractAmount);
Value constZero = rewriter.create<hw::ConstantOp>( Value constZero = hw::ConstantOp::create(rewriter, op.getLoc(),
op.getLoc(), APInt::getZero(extractAmount)); APInt::getZero(extractAmount));
replaceOpWithNewOpAndCopyNamehint<comb::ConcatOp>( replaceOpWithNewOpAndCopyNamehint<comb::ConcatOp>(
rewriter, op, op.getType(), ArrayRef<Value>{constZero, upperBits}); rewriter, op, op.getType(), ArrayRef<Value>{constZero, upperBits});
return success(); return success();
@ -782,8 +782,8 @@ struct CombModUOpConversion : DivModOpConversionBase<ModUOp> {
size_t width = op.getType().getIntOrFloatBitWidth(); size_t width = op.getType().getIntOrFloatBitWidth();
Value lowerBits = rewriter.createOrFold<comb::ExtractOp>( Value lowerBits = rewriter.createOrFold<comb::ExtractOp>(
op.getLoc(), adaptor.getLhs(), 0, extractAmount); op.getLoc(), adaptor.getLhs(), 0, extractAmount);
Value constZero = rewriter.create<hw::ConstantOp>( Value constZero = hw::ConstantOp::create(
op.getLoc(), APInt::getZero(width - extractAmount)); rewriter, op.getLoc(), APInt::getZero(width - extractAmount));
replaceOpWithNewOpAndCopyNamehint<comb::ConcatOp>( replaceOpWithNewOpAndCopyNamehint<comb::ConcatOp>(
rewriter, op, op.getType(), ArrayRef<Value>{constZero, lowerBits}); rewriter, op, op.getType(), ArrayRef<Value>{constZero, lowerBits});
return success(); return success();
@ -851,7 +851,7 @@ struct CombICmpOpConversion : OpConversionPattern<ICmpOp> {
// a >= b ==> ( a[n] & ~b[n]) | (a[n] == b[n] & a[n-1:0] >= b[n-1:0]) // a >= b ==> ( a[n] & ~b[n]) | (a[n] == b[n] & a[n-1:0] >= b[n-1:0])
// a > b ==> ( a[n] & ~b[n]) | (a[n] == b[n] & a[n-1:0] > b[n-1:0]) // a > b ==> ( a[n] & ~b[n]) | (a[n] == b[n] & a[n-1:0] > b[n-1:0])
Value acc = Value acc =
rewriter.create<hw::ConstantOp>(op.getLoc(), op.getType(), includeEq); hw::ConstantOp::create(rewriter, op.getLoc(), op.getType(), includeEq);
for (auto [aBit, bBit] : llvm::zip(aBits, bBits)) { for (auto [aBit, bBit] : llvm::zip(aBits, bBits)) {
auto aBitXorBBit = auto aBitXorBBit =
@ -941,7 +941,7 @@ struct CombICmpOpConversion : OpConversionPattern<ICmpOp> {
// XOR of signs: true if signs are different // XOR of signs: true if signs are different
auto signsDiffer = auto signsDiffer =
rewriter.create<comb::XorOp>(op.getLoc(), signA, signB); comb::XorOp::create(rewriter, op.getLoc(), signA, signB);
// Result when signs are different // Result when signs are different
Value diffSignResult = isLess ? signA : signB; Value diffSignResult = isLess ? signA : signB;

View File

@ -123,11 +123,11 @@ struct ExtractOpConversion : OpConversionPattern<ExtractOp> {
matchAndRewrite(ExtractOp op, OpAdaptor adaptor, matchAndRewrite(ExtractOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
Value lowBit = rewriter.create<arith::ConstantOp>( Value lowBit = arith::ConstantOp::create(
op.getLoc(), rewriter, op.getLoc(),
IntegerAttr::get(adaptor.getInput().getType(), adaptor.getLowBit())); IntegerAttr::get(adaptor.getInput().getType(), adaptor.getLowBit()));
Value shifted = Value shifted =
rewriter.create<ShRUIOp>(op.getLoc(), adaptor.getInput(), lowBit); ShRUIOp::create(rewriter, op.getLoc(), adaptor.getInput(), lowBit);
rewriter.replaceOpWithNewOp<TruncIOp>(op, op.getResult().getType(), rewriter.replaceOpWithNewOp<TruncIOp>(op, op.getResult().getType(),
shifted); shifted);
return success(); return success();
@ -162,8 +162,8 @@ struct ConcatOpConversion : OpConversionPattern<ConcatOp> {
unsigned offset = type.getIntOrFloatBitWidth(); unsigned offset = type.getIntOrFloatBitWidth();
for (auto operand : adaptor.getOperands().drop_back()) { for (auto operand : adaptor.getOperands().drop_back()) {
offset -= operand.getType().getIntOrFloatBitWidth(); offset -= operand.getType().getIntOrFloatBitWidth();
auto offsetConst = rewriter.create<arith::ConstantOp>( auto offsetConst = arith::ConstantOp::create(
loc, IntegerAttr::get(type, offset)); rewriter, loc, IntegerAttr::get(type, offset));
auto extended = rewriter.createOrFold<ExtUIOp>(loc, type, operand); auto extended = rewriter.createOrFold<ExtUIOp>(loc, type, operand);
auto shifted = rewriter.createOrFold<ShLIOp>(loc, extended, offsetConst); auto shifted = rewriter.createOrFold<ShLIOp>(loc, extended, offsetConst);
aggregate = rewriter.createOrFold<OrIOp>(loc, aggregate, shifted); aggregate = rewriter.createOrFold<OrIOp>(loc, aggregate, shifted);
@ -201,14 +201,14 @@ struct DivOpConversion : OpConversionPattern<SourceOp> {
matchAndRewrite(SourceOp op, OpAdaptor adaptor, matchAndRewrite(SourceOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
Location loc = op.getLoc(); Location loc = op.getLoc();
Value zero = rewriter.create<arith::ConstantOp>( Value zero = arith::ConstantOp::create(
loc, rewriter.getIntegerAttr(adaptor.getRhs().getType(), 0)); rewriter, loc, rewriter.getIntegerAttr(adaptor.getRhs().getType(), 0));
Value one = rewriter.create<arith::ConstantOp>( Value one = arith::ConstantOp::create(
loc, rewriter.getIntegerAttr(adaptor.getRhs().getType(), 1)); rewriter, loc, rewriter.getIntegerAttr(adaptor.getRhs().getType(), 1));
Value isZero = rewriter.create<arith::CmpIOp>(loc, CmpIPredicate::eq, Value isZero = arith::CmpIOp::create(rewriter, loc, CmpIPredicate::eq,
adaptor.getRhs(), zero); adaptor.getRhs(), zero);
Value divisor = Value divisor =
rewriter.create<arith::SelectOp>(loc, isZero, one, adaptor.getRhs()); arith::SelectOp::create(rewriter, loc, isZero, one, adaptor.getRhs());
rewriter.replaceOpWithNewOp<TargetOp>(op, adaptor.getLhs(), divisor); rewriter.replaceOpWithNewOp<TargetOp>(op, adaptor.getLhs(), divisor);
return success(); return success();
} }
@ -229,7 +229,7 @@ struct VariadicOpConversion : OpConversionPattern<SourceOp> {
Value runner = operands[0]; Value runner = operands[0];
for (Value operand : for (Value operand :
llvm::make_range(operands.begin() + 1, operands.end())) { llvm::make_range(operands.begin() + 1, operands.end())) {
runner = rewriter.create<TargetOp>(op.getLoc(), runner, operand); runner = TargetOp::create(rewriter, op.getLoc(), runner, operand);
} }
rewriter.replaceOp(op, runner); rewriter.replaceOp(op, runner);
return success(); return success();
@ -254,10 +254,10 @@ struct LogicalShiftConversion : OpConversionPattern<SourceOp> {
unsigned shifteeWidth = unsigned shifteeWidth =
hw::type_cast<IntegerType>(adaptor.getLhs().getType()) hw::type_cast<IntegerType>(adaptor.getLhs().getType())
.getIntOrFloatBitWidth(); .getIntOrFloatBitWidth();
auto zeroConstOp = rewriter.create<arith::ConstantOp>( auto zeroConstOp = arith::ConstantOp::create(
op.getLoc(), IntegerAttr::get(adaptor.getLhs().getType(), 0)); rewriter, op.getLoc(), IntegerAttr::get(adaptor.getLhs().getType(), 0));
auto maxShamtConstOp = rewriter.create<arith::ConstantOp>( auto maxShamtConstOp = arith::ConstantOp::create(
op.getLoc(), rewriter, op.getLoc(),
IntegerAttr::get(adaptor.getLhs().getType(), shifteeWidth)); IntegerAttr::get(adaptor.getLhs().getType(), shifteeWidth));
auto shiftOp = rewriter.createOrFold<TargetOp>( auto shiftOp = rewriter.createOrFold<TargetOp>(
op.getLoc(), adaptor.getLhs(), adaptor.getRhs()); op.getLoc(), adaptor.getLhs(), adaptor.getRhs());
@ -281,8 +281,8 @@ struct ShrSOpConversion : OpConversionPattern<ShrSOp> {
hw::type_cast<IntegerType>(adaptor.getLhs().getType()) hw::type_cast<IntegerType>(adaptor.getLhs().getType())
.getIntOrFloatBitWidth(); .getIntOrFloatBitWidth();
// Clamp the shift amount to shifteeWidth - 1 // Clamp the shift amount to shifteeWidth - 1
auto maxShamtMinusOneConstOp = rewriter.create<arith::ConstantOp>( auto maxShamtMinusOneConstOp = arith::ConstantOp::create(
op.getLoc(), rewriter, op.getLoc(),
IntegerAttr::get(adaptor.getLhs().getType(), shifteeWidth - 1)); IntegerAttr::get(adaptor.getLhs().getType(), shifteeWidth - 1));
auto shamtOp = rewriter.createOrFold<MinUIOp>(op.getLoc(), adaptor.getRhs(), auto shamtOp = rewriter.createOrFold<MinUIOp>(op.getLoc(), adaptor.getRhs(),
maxShamtMinusOneConstOp); maxShamtMinusOneConstOp);

View File

@ -45,8 +45,8 @@ struct CombAddOpConversion : OpConversionPattern<AddOp> {
} }
// Reduce to two values (carry,save) // Reduce to two values (carry,save)
auto results = auto results = datapath::CompressOp::create(rewriter, op.getLoc(),
rewriter.create<datapath::CompressOp>(op.getLoc(), op.getOperands(), 2); op.getOperands(), 2);
// carry+saved // carry+saved
rewriter.replaceOpWithNewOp<AddOp>(op, results.getResults(), true); rewriter.replaceOpWithNewOp<AddOp>(op, results.getResults(), true);
return success(); return success();
@ -66,8 +66,8 @@ struct CombMulOpConversion : OpConversionPattern<MulOp> {
auto width = op.getType().getIntOrFloatBitWidth(); auto width = op.getType().getIntOrFloatBitWidth();
// Create partial product rows - number of rows == width // Create partial product rows - number of rows == width
auto pp = rewriter.create<datapath::PartialProductOp>( auto pp = datapath::PartialProductOp::create(rewriter, op.getLoc(),
op.getLoc(), op.getInputs(), width); op.getInputs(), width);
// Sum partial products // Sum partial products
rewriter.replaceOpWithNewOp<AddOp>(op, pp.getResults(), true); rewriter.replaceOpWithNewOp<AddOp>(op, pp.getResults(), true);
return success(); return success();

View File

@ -36,7 +36,7 @@ struct CombParityOpConversion : public ConvertToLLVMPattern {
auto parityOp = cast<comb::ParityOp>(op); auto parityOp = cast<comb::ParityOp>(op);
auto popCount = auto popCount =
rewriter.create<LLVM::CtPopOp>(op->getLoc(), parityOp.getInput()); LLVM::CtPopOp::create(rewriter, op->getLoc(), parityOp.getInput());
rewriter.replaceOpWithNewOp<LLVM::TruncOp>( rewriter.replaceOpWithNewOp<LLVM::TruncOp>(
op, IntegerType::get(rewriter.getContext(), 1), popCount); op, IntegerType::get(rewriter.getContext(), 1), popCount);

View File

@ -59,11 +59,11 @@ struct IcmpOpConversion : OpConversionPattern<ICmpOp> {
Value result; Value result;
if (adaptor.getPredicate() == ICmpPredicate::eq) { if (adaptor.getPredicate() == ICmpPredicate::eq) {
result = rewriter.create<smt::EqOp>(op.getLoc(), adaptor.getLhs(), result = smt::EqOp::create(rewriter, op.getLoc(), adaptor.getLhs(),
adaptor.getRhs()); adaptor.getRhs());
} else if (adaptor.getPredicate() == ICmpPredicate::ne) { } else if (adaptor.getPredicate() == ICmpPredicate::ne) {
result = rewriter.create<smt::DistinctOp>(op.getLoc(), adaptor.getLhs(), result = smt::DistinctOp::create(rewriter, op.getLoc(), adaptor.getLhs(),
adaptor.getRhs()); adaptor.getRhs());
} else { } else {
smt::BVCmpPredicate pred; smt::BVCmpPredicate pred;
switch (adaptor.getPredicate()) { switch (adaptor.getPredicate()) {
@ -95,8 +95,8 @@ struct IcmpOpConversion : OpConversionPattern<ICmpOp> {
llvm_unreachable("all cases handled above"); llvm_unreachable("all cases handled above");
} }
result = rewriter.create<smt::BVCmpOp>( result = smt::BVCmpOp::create(rewriter, op.getLoc(), pred,
op.getLoc(), pred, adaptor.getLhs(), adaptor.getRhs()); adaptor.getLhs(), adaptor.getRhs());
} }
Value convVal = typeConverter->materializeTargetConversion( Value convVal = typeConverter->materializeTargetConversion(
@ -148,7 +148,8 @@ struct SubOpConversion : OpConversionPattern<SubOp> {
LogicalResult LogicalResult
matchAndRewrite(SubOp op, OpAdaptor adaptor, matchAndRewrite(SubOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
Value negRhs = rewriter.create<smt::BVNegOp>(op.getLoc(), adaptor.getRhs()); Value negRhs =
smt::BVNegOp::create(rewriter, op.getLoc(), adaptor.getRhs());
rewriter.replaceOpWithNewOp<smt::BVAddOp>(op, adaptor.getLhs(), negRhs); rewriter.replaceOpWithNewOp<smt::BVAddOp>(op, adaptor.getLhs(), negRhs);
return success(); return success();
} }
@ -169,11 +170,11 @@ struct ParityOpConversion : OpConversionPattern<ParityOp> {
// the type conversion should already fail. // the type conversion should already fail.
Type oneBitTy = smt::BitVectorType::get(getContext(), 1); Type oneBitTy = smt::BitVectorType::get(getContext(), 1);
Value runner = Value runner =
rewriter.create<smt::ExtractOp>(loc, oneBitTy, 0, adaptor.getInput()); smt::ExtractOp::create(rewriter, loc, oneBitTy, 0, adaptor.getInput());
for (unsigned i = 1; i < bitwidth; ++i) { for (unsigned i = 1; i < bitwidth; ++i) {
Value ext = Value ext = smt::ExtractOp::create(rewriter, loc, oneBitTy, i,
rewriter.create<smt::ExtractOp>(loc, oneBitTy, i, adaptor.getInput()); adaptor.getInput());
runner = rewriter.create<smt::BVXOrOp>(loc, runner, ext); runner = smt::BVXOrOp::create(rewriter, loc, runner, ext);
} }
rewriter.replaceOp(op, runner); rewriter.replaceOp(op, runner);
@ -218,11 +219,11 @@ struct DivisionOpConversion : OpConversionPattern<SourceOp> {
auto resultType = OpConversionPattern<SourceOp>::typeConverter->convertType( auto resultType = OpConversionPattern<SourceOp>::typeConverter->convertType(
op.getResult().getType()); op.getResult().getType());
Value zero = Value zero =
rewriter.create<smt::BVConstantOp>(loc, APInt(type.getWidth(), 0)); smt::BVConstantOp::create(rewriter, loc, APInt(type.getWidth(), 0));
Value isZero = rewriter.create<smt::EqOp>(loc, adaptor.getRhs(), zero); Value isZero = smt::EqOp::create(rewriter, loc, adaptor.getRhs(), zero);
Value symbolicVal = rewriter.create<smt::DeclareFunOp>(loc, resultType); Value symbolicVal = smt::DeclareFunOp::create(rewriter, loc, resultType);
Value division = Value division =
rewriter.create<TargetOp>(loc, resultType, adaptor.getOperands()); TargetOp::create(rewriter, loc, resultType, adaptor.getOperands());
rewriter.replaceOpWithNewOp<smt::IteOp>(op, isZero, symbolicVal, division); rewriter.replaceOpWithNewOp<smt::IteOp>(op, isZero, symbolicVal, division);
return success(); return success();
} }
@ -245,7 +246,7 @@ struct VariadicToBinaryOpConversion : OpConversionPattern<SourceOp> {
Value runner = operands[0]; Value runner = operands[0];
for (Value operand : operands.drop_front()) for (Value operand : operands.drop_front())
runner = rewriter.create<TargetOp>(op.getLoc(), runner, operand); runner = TargetOp::create(rewriter, op.getLoc(), runner, operand);
rewriter.replaceOp(op, runner); rewriter.replaceOp(op, runner);
return success(); return success();

View File

@ -39,8 +39,8 @@ static LogicalResult convertInitialValue(seq::CompRegOp reg,
// Use from_immutable cast to convert the seq.immutable type to the reg's // Use from_immutable cast to convert the seq.immutable type to the reg's
// type. // type.
OpBuilder builder(reg); OpBuilder builder(reg);
auto init = builder.create<seq::FromImmutableOp>(reg.getLoc(), reg.getType(), auto init = seq::FromImmutableOp::create(builder, reg.getLoc(), reg.getType(),
reg.getInitialValue()); reg.getInitialValue());
values.push_back(init); values.push_back(init);
return success(); return success();
@ -255,21 +255,21 @@ void Converter::extractArcs(HWModuleOp module) {
} }
} }
assert(lastOp); assert(lastOp);
builder.create<arc::OutputOp>(lastOp->getLoc(), outputs); arc::OutputOp::create(builder, lastOp->getLoc(), outputs);
// Create the arc definition. // Create the arc definition.
builder.setInsertionPoint(module); builder.setInsertionPoint(module);
auto defOp = builder.create<DefineOp>( auto defOp =
lastOp->getLoc(), DefineOp::create(builder, lastOp->getLoc(),
builder.getStringAttr( builder.getStringAttr(globalNamespace.newName(
globalNamespace.newName(module.getModuleName() + "_arc")), module.getModuleName() + "_arc")),
builder.getFunctionType(inputTypes, outputTypes)); builder.getFunctionType(inputTypes, outputTypes));
defOp.getBody().push_back(block.release()); defOp.getBody().push_back(block.release());
// Create the call to the arc definition to replace the operations that // Create the call to the arc definition to replace the operations that
// we have just extracted. // we have just extracted.
builder.setInsertionPoint(module.getBodyBlock()->getTerminator()); builder.setInsertionPoint(module.getBodyBlock()->getTerminator());
auto arcOp = builder.create<CallOp>(lastOp->getLoc(), defOp, inputs); auto arcOp = CallOp::create(builder, lastOp->getLoc(), defOp, inputs);
arcUses.push_back(arcOp); arcUses.push_back(arcOp);
for (auto [use, resultIdx] : externalUses) for (auto [use, resultIdx] : externalUses)
use->set(arcOp.getResult(resultIdx)); use->set(arcOp.getResult(resultIdx));
@ -448,14 +448,13 @@ LogicalResult Converter::absorbRegs(HWModuleOp module) {
} }
auto loc = regOps.back().getLoc(); auto loc = regOps.back().getLoc();
builder.create<arc::OutputOp>(loc, outputs); arc::OutputOp::create(builder, loc, outputs);
builder.setInsertionPoint(module); builder.setInsertionPoint(module);
auto defOp = auto defOp = DefineOp::create(builder, loc,
builder.create<DefineOp>(loc, builder.getStringAttr(globalNamespace.newName(
builder.getStringAttr(globalNamespace.newName( module.getModuleName() + "_arc")),
module.getModuleName() + "_arc")), builder.getFunctionType(types, types));
builder.getFunctionType(types, types));
defOp.getBody().push_back(block.release()); defOp.getBody().push_back(block.release());
builder.setInsertionPoint(module.getBodyBlock()->getTerminator()); builder.setInsertionPoint(module.getBodyBlock()->getTerminator());
@ -473,8 +472,8 @@ LogicalResult Converter::absorbRegs(HWModuleOp module) {
} }
auto arcOp = auto arcOp =
builder.create<StateOp>(loc, defOp, std::get<0>(clockAndResetAndOp), StateOp::create(builder, loc, defOp, std::get<0>(clockAndResetAndOp),
/*enable=*/Value{}, 1, inputs, initialValues); /*enable=*/Value{}, 1, inputs, initialValues);
auto reset = std::get<1>(clockAndResetAndOp); auto reset = std::get<1>(clockAndResetAndOp);
if (reset) if (reset)
arcOp.getResetMutable().assign(reset); arcOp.getResetMutable().assign(reset);

View File

@ -117,8 +117,8 @@ public:
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
@ -128,8 +128,8 @@ public:
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
} }
@ -230,7 +230,7 @@ struct RTLBuilder {
return it->second; return it->second;
} }
auto cval = b.create<hw::ConstantOp>(loc, apv); auto cval = hw::ConstantOp::create(b, loc, apv);
if (!isZeroWidth) if (!isZeroWidth)
constants[apv] = cval; constants[apv] = cval;
return cval; return cval;
@ -241,12 +241,12 @@ struct RTLBuilder {
APInt(width, value, /*isSigned=*/false, /*implicitTrunc=*/true)); APInt(width, value, /*isSigned=*/false, /*implicitTrunc=*/true));
} }
std::pair<Value, Value> wrap(Value data, Value valid, StringRef name = {}) { std::pair<Value, Value> wrap(Value data, Value valid, StringRef name = {}) {
auto wrapOp = b.create<esi::WrapValidReadyOp>(loc, data, valid); auto wrapOp = esi::WrapValidReadyOp::create(b, loc, data, valid);
return {wrapOp.getResult(0), wrapOp.getResult(1)}; return {wrapOp.getResult(0), wrapOp.getResult(1)};
} }
std::pair<Value, Value> unwrap(Value channel, Value ready, std::pair<Value, Value> unwrap(Value channel, Value ready,
StringRef name = {}) { StringRef name = {}) {
auto unwrapOp = b.create<esi::UnwrapValidReadyOp>(loc, channel, ready); auto unwrapOp = esi::UnwrapValidReadyOp::create(b, loc, channel, ready);
return {unwrapOp.getResult(0), unwrapOp.getResult(1)}; return {unwrapOp.getResult(0), unwrapOp.getResult(1)};
} }
@ -262,13 +262,13 @@ struct RTLBuilder {
"No global reset provided to this RTLBuilder - a reset " "No global reset provided to this RTLBuilder - a reset "
"signal must be provided to the reg(...) function."); "signal must be provided to the reg(...) function.");
return b.create<seq::CompRegOp>(loc, in, resolvedClk, resolvedRst, rstValue, return seq::CompRegOp::create(b, loc, in, resolvedClk, resolvedRst,
name); rstValue, name);
} }
Value cmp(Value lhs, Value rhs, comb::ICmpPredicate predicate, Value cmp(Value lhs, Value rhs, comb::ICmpPredicate predicate,
StringRef name = {}) { StringRef name = {}) {
return b.create<comb::ICmpOp>(loc, predicate, lhs, rhs); return comb::ICmpOp::create(b, loc, predicate, lhs, rhs);
} }
Value buildNamedOp(llvm::function_ref<Value()> f, StringRef name) { Value buildNamedOp(llvm::function_ref<Value()> f, StringRef name) {
@ -285,13 +285,13 @@ struct RTLBuilder {
/// Bitwise 'and'. /// Bitwise 'and'.
Value bitAnd(ValueRange values, StringRef name = {}) { Value bitAnd(ValueRange values, StringRef name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::AndOp>(loc, values, false); }, name); [&]() { return comb::AndOp::create(b, loc, values, false); }, name);
} }
// Bitwise 'or'. // Bitwise 'or'.
Value bitOr(ValueRange values, StringRef name = {}) { Value bitOr(ValueRange values, StringRef name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::OrOp>(loc, values, false); }, name); [&]() { return comb::OrOp::create(b, loc, values, false); }, name);
} }
/// Bitwise 'not'. /// Bitwise 'not'.
@ -308,23 +308,23 @@ struct RTLBuilder {
} }
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::XorOp>(loc, value, allOnes); }, name); [&]() { return comb::XorOp::create(b, loc, value, allOnes); }, name);
} }
Value shl(Value value, Value shift, StringRef name = {}) { Value shl(Value value, Value shift, StringRef name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::ShlOp>(loc, value, shift); }, name); [&]() { return comb::ShlOp::create(b, loc, value, shift); }, name);
} }
Value concat(ValueRange values, StringRef name = {}) { Value concat(ValueRange values, StringRef name = {}) {
return buildNamedOp([&]() { return b.create<comb::ConcatOp>(loc, values); }, return buildNamedOp(
name); [&]() { return comb::ConcatOp::create(b, loc, values); }, name);
} }
llvm::SmallVector<Value> extractBits(Value v, StringRef name = {}) { llvm::SmallVector<Value> extractBits(Value v, StringRef name = {}) {
llvm::SmallVector<Value> bits; llvm::SmallVector<Value> bits;
for (unsigned i = 0, e = v.getType().getIntOrFloatBitWidth(); i != e; ++i) for (unsigned i = 0, e = v.getType().getIntOrFloatBitWidth(); i != e; ++i)
bits.push_back(b.create<comb::ExtractOp>(loc, v, i, /*bitWidth=*/1)); bits.push_back(comb::ExtractOp::create(b, loc, v, i, /*bitWidth=*/1));
return bits; return bits;
} }
@ -337,7 +337,7 @@ struct RTLBuilder {
Value extract(Value v, unsigned lo, unsigned hi, StringRef name = {}) { Value extract(Value v, unsigned lo, unsigned hi, StringRef name = {}) {
unsigned width = hi - lo + 1; unsigned width = hi - lo + 1;
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::ExtractOp>(loc, v, lo, width); }, name); [&]() { return comb::ExtractOp::create(b, loc, v, lo, width); }, name);
} }
/// Truncates 'value' to its lower 'width' bits. /// Truncates 'value' to its lower 'width' bits.
@ -366,13 +366,13 @@ struct RTLBuilder {
/// Creates a hw.array of the given values. /// Creates a hw.array of the given values.
Value arrayCreate(ValueRange values, StringRef name = {}) { Value arrayCreate(ValueRange values, StringRef name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<hw::ArrayCreateOp>(loc, values); }, name); [&]() { return hw::ArrayCreateOp::create(b, loc, values); }, name);
} }
/// Extract the 'index'th value from the input array. /// Extract the 'index'th value from the input array.
Value arrayGet(Value array, Value index, StringRef name = {}) { Value arrayGet(Value array, Value index, StringRef name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<hw::ArrayGetOp>(loc, array, index); }, name); [&]() { return hw::ArrayGetOp::create(b, loc, array, index); }, name);
} }
/// Muxes a range of values. /// Muxes a range of values.
@ -382,7 +382,7 @@ struct RTLBuilder {
if (values.size() == 2) { if (values.size() == 2) {
return buildNamedOp( return buildNamedOp(
[&]() { [&]() {
return b.create<comb::MuxOp>(loc, index, values[1], values[0]); return comb::MuxOp::create(b, loc, index, values[1], values[0]);
}, },
name); name);
} }
@ -447,7 +447,7 @@ static UnwrappedIO unwrapIO(Location loc, ValueRange operands,
if (isZeroWidthType(innerType)) { if (isZeroWidthType(innerType)) {
// Feed the ESI wrap with an i0 constant. // Feed the ESI wrap with an i0 constant.
data = data =
rewriter.create<hw::ConstantOp>(loc, rewriter.getIntegerType(0), 0); hw::ConstantOp::create(rewriter, loc, rewriter.getIntegerType(0), 0);
} else { } else {
// Create a backedge for the unresolved data. // Create a backedge for the unresolved data.
auto dataBackedge = bb.get(innerType); auto dataBackedge = bb.get(innerType);

View File

@ -49,9 +49,9 @@ struct DatapathCompressOpAddConversion : OpConversionPattern<CompressOp> {
auto inputs = op.getOperands(); auto inputs = op.getOperands();
unsigned width = inputs[0].getType().getIntOrFloatBitWidth(); unsigned width = inputs[0].getType().getIntOrFloatBitWidth();
// Sum all the inputs - set that to result value 0 // Sum all the inputs - set that to result value 0
auto addOp = rewriter.create<comb::AddOp>(loc, inputs, true); auto addOp = comb::AddOp::create(rewriter, loc, inputs, true);
// Replace remaining results with zeros // Replace remaining results with zeros
auto zeroOp = rewriter.create<hw::ConstantOp>(loc, APInt(width, 0)); auto zeroOp = hw::ConstantOp::create(rewriter, loc, APInt(width, 0));
SmallVector<Value> results(op.getNumResults() - 1, zeroOp); SmallVector<Value> results(op.getNumResults() - 1, zeroOp);
results.push_back(addOp); results.push_back(addOp);
rewriter.replaceOp(op, results); rewriter.replaceOp(op, results);
@ -134,10 +134,10 @@ private:
"Cannot return more results than the operator width"); "Cannot return more results than the operator width");
for (unsigned i = 0; i < op.getNumResults(); ++i) { for (unsigned i = 0; i < op.getNumResults(); ++i) {
auto repl = rewriter.create<comb::ReplicateOp>(loc, bBits[i], width); auto repl = comb::ReplicateOp::create(rewriter, loc, bBits[i], width);
auto ppRow = rewriter.create<comb::AndOp>(loc, repl, a); auto ppRow = comb::AndOp::create(rewriter, loc, repl, a);
auto shiftBy = rewriter.create<hw::ConstantOp>(loc, APInt(width, i)); auto shiftBy = hw::ConstantOp::create(rewriter, loc, APInt(width, i));
auto ppAlign = rewriter.create<comb::ShlOp>(loc, ppRow, shiftBy); auto ppAlign = comb::ShlOp::create(rewriter, loc, ppRow, shiftBy);
partialProducts.push_back(ppAlign); partialProducts.push_back(ppAlign);
} }
@ -149,10 +149,10 @@ private:
Value a, Value b, PartialProductOp op, Value a, Value b, PartialProductOp op,
unsigned width) { unsigned width) {
Location loc = op.getLoc(); Location loc = op.getLoc();
auto zeroFalse = rewriter.create<hw::ConstantOp>(loc, APInt(1, 0)); auto zeroFalse = hw::ConstantOp::create(rewriter, loc, APInt(1, 0));
auto zeroWidth = rewriter.create<hw::ConstantOp>(loc, APInt(width, 0)); auto zeroWidth = hw::ConstantOp::create(rewriter, loc, APInt(width, 0));
auto oneWidth = rewriter.create<hw::ConstantOp>(loc, APInt(width, 1)); auto oneWidth = hw::ConstantOp::create(rewriter, loc, APInt(width, 1));
Value twoA = rewriter.create<comb::ShlOp>(loc, a, oneWidth); Value twoA = comb::ShlOp::create(rewriter, loc, a, oneWidth);
SmallVector<Value> bBits = extractBits(rewriter, b); SmallVector<Value> bBits = extractBits(rewriter, b);
@ -176,30 +176,33 @@ private:
// Is the encoding zero or negative (an approximation) // Is the encoding zero or negative (an approximation)
Value encNeg = bip1; Value encNeg = bip1;
// Is the encoding one = b[i] xor b[i-1] // Is the encoding one = b[i] xor b[i-1]
Value encOne = rewriter.create<comb::XorOp>(loc, bi, bim1, true); Value encOne = comb::XorOp::create(rewriter, loc, bi, bim1, true);
// Is the encoding two = (bip1 & ~bi & ~bim1) | (~bip1 & bi & bim1) // Is the encoding two = (bip1 & ~bi & ~bim1) | (~bip1 & bi & bim1)
Value constOne = rewriter.create<hw::ConstantOp>(loc, APInt(1, 1)); Value constOne = hw::ConstantOp::create(rewriter, loc, APInt(1, 1));
Value biInv = rewriter.create<comb::XorOp>(loc, bi, constOne, true); Value biInv = comb::XorOp::create(rewriter, loc, bi, constOne, true);
Value bip1Inv = rewriter.create<comb::XorOp>(loc, bip1, constOne, true); Value bip1Inv = comb::XorOp::create(rewriter, loc, bip1, constOne, true);
Value bim1Inv = rewriter.create<comb::XorOp>(loc, bim1, constOne, true); Value bim1Inv = comb::XorOp::create(rewriter, loc, bim1, constOne, true);
Value andLeft = rewriter.create<comb::AndOp>( Value andLeft = comb::AndOp::create(rewriter, loc,
loc, ValueRange{bip1Inv, bi, bim1}, true); ValueRange{bip1Inv, bi, bim1}, true);
Value andRight = rewriter.create<comb::AndOp>( Value andRight = comb::AndOp::create(
loc, ValueRange{bip1, biInv, bim1Inv}, true); rewriter, loc, ValueRange{bip1, biInv, bim1Inv}, true);
Value encTwo = rewriter.create<comb::OrOp>(loc, andLeft, andRight, true); Value encTwo = comb::OrOp::create(rewriter, loc, andLeft, andRight, true);
Value encNegRepl = rewriter.create<comb::ReplicateOp>(loc, encNeg, width); Value encNegRepl =
Value encOneRepl = rewriter.create<comb::ReplicateOp>(loc, encOne, width); comb::ReplicateOp::create(rewriter, loc, encNeg, width);
Value encTwoRepl = rewriter.create<comb::ReplicateOp>(loc, encTwo, width); Value encOneRepl =
comb::ReplicateOp::create(rewriter, loc, encOne, width);
Value encTwoRepl =
comb::ReplicateOp::create(rewriter, loc, encTwo, width);
// Select between 2*a or 1*a or 0*a // Select between 2*a or 1*a or 0*a
Value selTwoA = rewriter.create<comb::AndOp>(loc, encTwoRepl, twoA); Value selTwoA = comb::AndOp::create(rewriter, loc, encTwoRepl, twoA);
Value selOneA = rewriter.create<comb::AndOp>(loc, encOneRepl, a); Value selOneA = comb::AndOp::create(rewriter, loc, encOneRepl, a);
Value magA = rewriter.create<comb::OrOp>(loc, selTwoA, selOneA, true); Value magA = comb::OrOp::create(rewriter, loc, selTwoA, selOneA, true);
// Conditionally invert the row // Conditionally invert the row
Value ppRow = rewriter.create<comb::XorOp>(loc, magA, encNegRepl, true); Value ppRow = comb::XorOp::create(rewriter, loc, magA, encNegRepl, true);
// No sign-correction in the first row // No sign-correction in the first row
if (i == 0) { if (i == 0) {
@ -211,12 +214,13 @@ private:
// Insert a sign-correction from the previous row // Insert a sign-correction from the previous row
assert(i >= 2 && "Expected i to be at least 2 for sign correction"); assert(i >= 2 && "Expected i to be at least 2 for sign correction");
// {ppRow, 0, encNegPrev} << 2*(i-1) // {ppRow, 0, encNegPrev} << 2*(i-1)
Value withSignCorrection = rewriter.create<comb::ConcatOp>( Value withSignCorrection = comb::ConcatOp::create(
loc, ValueRange{ppRow, zeroFalse, encNegPrev}); rewriter, loc, ValueRange{ppRow, zeroFalse, encNegPrev});
Value ppAlignPre = Value ppAlignPre =
rewriter.create<comb::ExtractOp>(loc, withSignCorrection, 0, width); comb::ExtractOp::create(rewriter, loc, withSignCorrection, 0, width);
Value shiftBy = rewriter.create<hw::ConstantOp>(loc, APInt(width, i - 2)); Value shiftBy =
Value ppAlign = rewriter.create<comb::ShlOp>(loc, ppAlignPre, shiftBy); hw::ConstantOp::create(rewriter, loc, APInt(width, i - 2));
Value ppAlign = comb::ShlOp::create(rewriter, loc, ppAlignPre, shiftBy);
partialProducts.push_back(ppAlign); partialProducts.push_back(ppAlign);
encNegPrev = encNeg; encNegPrev = encNeg;

View File

@ -46,14 +46,14 @@ struct CompressOpConversion : OpConversionPattern<CompressOp> {
Value operandRunner = operands[0]; Value operandRunner = operands[0];
for (Value operand : operands.drop_front()) for (Value operand : operands.drop_front())
operandRunner = operandRunner =
rewriter.create<smt::BVAddOp>(op.getLoc(), operandRunner, operand); smt::BVAddOp::create(rewriter, op.getLoc(), operandRunner, operand);
// Create free variables // Create free variables
SmallVector<Value, 2> newResults; SmallVector<Value, 2> newResults;
newResults.reserve(results.size()); newResults.reserve(results.size());
for (Value result : results) { for (Value result : results) {
auto declareFunOp = rewriter.create<smt::DeclareFunOp>( auto declareFunOp = smt::DeclareFunOp::create(
op.getLoc(), typeConverter->convertType(result.getType())); rewriter, op.getLoc(), typeConverter->convertType(result.getType()));
newResults.push_back(declareFunOp.getResult()); newResults.push_back(declareFunOp.getResult());
} }
@ -61,13 +61,13 @@ struct CompressOpConversion : OpConversionPattern<CompressOp> {
Value resultRunner = newResults.front(); Value resultRunner = newResults.front();
for (auto freeVar : llvm::drop_begin(newResults, 1)) for (auto freeVar : llvm::drop_begin(newResults, 1))
resultRunner = resultRunner =
rewriter.create<smt::BVAddOp>(op.getLoc(), resultRunner, freeVar); smt::BVAddOp::create(rewriter, op.getLoc(), resultRunner, freeVar);
// Assert sum operands == sum results (free variables) // Assert sum operands == sum results (free variables)
auto premise = auto premise =
rewriter.create<smt::EqOp>(op.getLoc(), operandRunner, resultRunner); smt::EqOp::create(rewriter, op.getLoc(), operandRunner, resultRunner);
// Encode via an assertion (could be relaxed to an assumption). // Encode via an assertion (could be relaxed to an assumption).
rewriter.create<smt::AssertOp>(op.getLoc(), premise); smt::AssertOp::create(rewriter, op.getLoc(), premise);
if (newResults.size() != results.size()) if (newResults.size() != results.size())
return rewriter.notifyMatchFailure(op, "expected same number of results"); return rewriter.notifyMatchFailure(op, "expected same number of results");
@ -93,14 +93,14 @@ struct PartialProductOpConversion : OpConversionPattern<PartialProductOp> {
// Multiply the operands // Multiply the operands
auto mulResult = auto mulResult =
rewriter.create<smt::BVMulOp>(op.getLoc(), operands[0], operands[1]); smt::BVMulOp::create(rewriter, op.getLoc(), operands[0], operands[1]);
// Create free variables // Create free variables
SmallVector<Value, 2> newResults; SmallVector<Value, 2> newResults;
newResults.reserve(results.size()); newResults.reserve(results.size());
for (Value result : results) { for (Value result : results) {
auto declareFunOp = rewriter.create<smt::DeclareFunOp>( auto declareFunOp = smt::DeclareFunOp::create(
op.getLoc(), typeConverter->convertType(result.getType())); rewriter, op.getLoc(), typeConverter->convertType(result.getType()));
newResults.push_back(declareFunOp.getResult()); newResults.push_back(declareFunOp.getResult());
} }
@ -108,13 +108,13 @@ struct PartialProductOpConversion : OpConversionPattern<PartialProductOp> {
Value resultRunner = newResults.front(); Value resultRunner = newResults.front();
for (auto freeVar : llvm::drop_begin(newResults, 1)) for (auto freeVar : llvm::drop_begin(newResults, 1))
resultRunner = resultRunner =
rewriter.create<smt::BVAddOp>(op.getLoc(), resultRunner, freeVar); smt::BVAddOp::create(rewriter, op.getLoc(), resultRunner, freeVar);
// Assert product of operands == sum results (free variables) // Assert product of operands == sum results (free variables)
auto premise = auto premise =
rewriter.create<smt::EqOp>(op.getLoc(), mulResult, resultRunner); smt::EqOp::create(rewriter, op.getLoc(), mulResult, resultRunner);
// Encode via an assertion (could be relaxed to an assumption). // Encode via an assertion (could be relaxed to an assumption).
rewriter.create<smt::AssertOp>(op.getLoc(), premise); smt::AssertOp::create(rewriter, op.getLoc(), premise);
if (newResults.size() != results.size()) if (newResults.size() != results.size())
return rewriter.notifyMatchFailure(op, "expected same number of results"); return rewriter.notifyMatchFailure(op, "expected same number of results");

View File

@ -83,20 +83,20 @@ LogicalResult ExportVerilog::lowerHWInstanceChoices(mlir::ModuleOp module) {
auto symName = ns.newName(name); auto symName = ns.newName(name);
auto symNameAttr = declBuilder.getStringAttr(symName); auto symNameAttr = declBuilder.getStringAttr(symName);
auto symRef = FlatSymbolRefAttr::get(symNameAttr); auto symRef = FlatSymbolRefAttr::get(symNameAttr);
declBuilder.create<MacroDeclOp>(inst.getLoc(), symNameAttr, MacroDeclOp::create(declBuilder, inst.getLoc(), symNameAttr,
/*args=*/ArrayAttr{}, /*args=*/ArrayAttr{},
/*verilogName=*/StringAttr{}); /*verilogName=*/StringAttr{});
// This pass now generates the macros and attaches them to the instance // This pass now generates the macros and attaches them to the instance
// choice as an attribute. As a better solution, this pass should be moved // choice as an attribute. As a better solution, this pass should be moved
// out of the umbrella of ExportVerilog and it should lower the `hw` // out of the umbrella of ExportVerilog and it should lower the `hw`
// instance choices to a better SV-level representation of the operation. // instance choices to a better SV-level representation of the operation.
ImplicitLocOpBuilder builder(inst.getLoc(), inst); ImplicitLocOpBuilder builder(inst.getLoc(), inst);
builder.create<sv::IfDefOp>( sv::IfDefOp::create(
symName, [&] {}, builder, symName, [&] {},
[&] { [&] {
builder.create<sv::MacroDefOp>( sv::MacroDefOp::create(
symRef, builder.getStringAttr("{{0}}"), builder, symRef, builder.getStringAttr("{{0}}"),
builder.getArrayAttr( builder.getArrayAttr(
{FlatSymbolRefAttr::get(defaultModuleOp.getNameAttr())})); {FlatSymbolRefAttr::get(defaultModuleOp.getNameAttr())}));
}); });

View File

@ -34,7 +34,7 @@ struct LegalizeAnonEnums
auto topLevel = getOperation(); auto topLevel = getOperation();
if (!typeScope) { if (!typeScope) {
auto builder = OpBuilder::atBlockBegin(&topLevel.getRegion().front()); auto builder = OpBuilder::atBlockBegin(&topLevel.getRegion().front());
typeScope = builder.create<TypeScopeOp>(topLevel.getLoc(), "Enums"); typeScope = TypeScopeOp::create(builder, topLevel.getLoc(), "Enums");
typeScope.getBodyRegion().push_back(new Block()); typeScope.getBodyRegion().push_back(new Block());
mlir::SymbolTable symbolTable(topLevel); mlir::SymbolTable symbolTable(topLevel);
symbolTable.insert(typeScope); symbolTable.insert(typeScope);
@ -52,7 +52,7 @@ struct LegalizeAnonEnums
auto typeScope = getTypeScope(); auto typeScope = getTypeScope();
auto builder = OpBuilder::atBlockEnd(&typeScope.getRegion().front()); auto builder = OpBuilder::atBlockEnd(&typeScope.getRegion().front());
auto declName = StringAttr::get(context, "enum" + Twine(enumCount++)); auto declName = StringAttr::get(context, "enum" + Twine(enumCount++));
builder.create<TypedeclOp>(loc, declName, TypeAttr::get(type), nullptr); TypedeclOp::create(builder, loc, declName, TypeAttr::get(type), nullptr);
auto symRef = SymbolRefAttr::get(typeScope.getSymNameAttr(), auto symRef = SymbolRefAttr::get(typeScope.getSymNameAttr(),
FlatSymbolRefAttr::get(declName)); FlatSymbolRefAttr::get(declName));
typeAlias = TypeAliasType::get(symRef, type); typeAlias = TypeAliasType::get(symRef, type);

View File

@ -99,9 +99,9 @@ static void spillWiresForInstanceInputs(HWInstanceLike op) {
else else
nameTmp += std::to_string(opNum); nameTmp += std::to_string(opNum);
auto newWire = builder.create<sv::WireOp>(src.getType(), nameTmp); auto newWire = sv::WireOp::create(builder, src.getType(), nameTmp);
auto newWireRead = builder.create<ReadInOutOp>(newWire); auto newWireRead = ReadInOutOp::create(builder, newWire);
auto connect = builder.create<AssignOp>(newWire, src); auto connect = AssignOp::create(builder, newWire, src);
newWireRead->moveBefore(op); newWireRead->moveBefore(op);
connect->moveBefore(op); connect->moveBefore(op);
op->setOperand(opNum, newWireRead); op->setOperand(opNum, newWireRead);
@ -118,14 +118,14 @@ static void replacePortWithWire(ImplicitLocOpBuilder &builder, Operation *op,
Value newTarget; Value newTarget;
if (isProcedural) { if (isProcedural) {
newTarget = builder.create<sv::LogicOp>(result.getType(), newTarget = sv::LogicOp::create(builder, result.getType(),
builder.getStringAttr(name)); builder.getStringAttr(name));
} else { } else {
newTarget = builder.create<sv::WireOp>(result.getType(), name); newTarget = sv::WireOp::create(builder, result.getType(), name);
} }
while (!result.use_empty()) { while (!result.use_empty()) {
auto newRead = builder.create<sv::ReadInOutOp>(newTarget); auto newRead = sv::ReadInOutOp::create(builder, newTarget);
OpOperand &use = *result.getUses().begin(); OpOperand &use = *result.getUses().begin();
use.set(newRead); use.set(newRead);
newRead->moveBefore(use.getOwner()); newRead->moveBefore(use.getOwner());
@ -133,9 +133,9 @@ static void replacePortWithWire(ImplicitLocOpBuilder &builder, Operation *op,
Operation *connect; Operation *connect;
if (isProcedural) { if (isProcedural) {
connect = builder.create<sv::BPAssignOp>(newTarget, result); connect = sv::BPAssignOp::create(builder, newTarget, result);
} else { } else {
connect = builder.create<sv::AssignOp>(newTarget, result); connect = sv::AssignOp::create(builder, newTarget, result);
} }
connect->moveAfter(op); connect->moveAfter(op);
} }
@ -180,16 +180,16 @@ static void lowerInstanceResults(HWInstanceLike op) {
nameTmp += n.getValue().str(); nameTmp += n.getValue().str();
else else
nameTmp += std::to_string(resNum); nameTmp += std::to_string(resNum);
Value newWire = builder.create<sv::WireOp>(result.getType(), nameTmp); Value newWire = sv::WireOp::create(builder, result.getType(), nameTmp);
while (!result.use_empty()) { while (!result.use_empty()) {
auto newWireRead = builder.create<ReadInOutOp>(newWire); auto newWireRead = ReadInOutOp::create(builder, newWire);
OpOperand &use = *result.getUses().begin(); OpOperand &use = *result.getUses().begin();
use.set(newWireRead); use.set(newWireRead);
newWireRead->moveBefore(use.getOwner()); newWireRead->moveBefore(use.getOwner());
} }
auto connect = builder.create<AssignOp>(newWire, result); auto connect = AssignOp::create(builder, newWire, result);
connect->moveAfter(op); connect->moveAfter(op);
} }
} }
@ -246,9 +246,9 @@ static void lowerUsersToTemporaryWire(Operation &op,
// If the op is in a procedural region, use logic op. // If the op is in a procedural region, use logic op.
if (isProceduralRegion) if (isProceduralRegion)
newWire = builder.create<LogicOp>(wireElementType, name); newWire = LogicOp::create(builder, wireElementType, name);
else else
newWire = builder.create<sv::WireOp>(wireElementType, name); newWire = sv::WireOp::create(builder, wireElementType, name);
// Replace all uses with newWire. Wrap in ReadInOutOp if required. // Replace all uses with newWire. Wrap in ReadInOutOp if required.
while (!result.use_empty()) { while (!result.use_empty()) {
@ -256,7 +256,7 @@ static void lowerUsersToTemporaryWire(Operation &op,
if (isResultInOut) { if (isResultInOut) {
use.set(newWire); use.set(newWire);
} else { } else {
auto newWireRead = builder.create<ReadInOutOp>(newWire); auto newWireRead = ReadInOutOp::create(builder, newWire);
use.set(newWireRead); use.set(newWireRead);
newWireRead->moveBefore(use.getOwner()); newWireRead->moveBefore(use.getOwner());
} }
@ -267,14 +267,14 @@ static void lowerUsersToTemporaryWire(Operation &op,
ReadInOutOp resultRead; ReadInOutOp resultRead;
if (isResultInOut) if (isResultInOut)
resultRead = builder.create<ReadInOutOp>(result); resultRead = ReadInOutOp::create(builder, result);
if (isProceduralRegion) if (isProceduralRegion)
connect = builder.create<BPAssignOp>( connect = BPAssignOp::create(
newWire, isResultInOut ? resultRead.getResult() : result); builder, newWire, isResultInOut ? resultRead.getResult() : result);
else else
connect = builder.create<AssignOp>( connect = AssignOp::create(
newWire, isResultInOut ? resultRead.getResult() : result); builder, newWire, isResultInOut ? resultRead.getResult() : result);
connect->moveAfter(&op); connect->moveAfter(&op);
if (resultRead) if (resultRead)
@ -427,9 +427,9 @@ static Operation *rewriteAddWithNegativeConstant(comb::AddOp add,
ImplicitLocOpBuilder builder(add.getLoc(), add); ImplicitLocOpBuilder builder(add.getLoc(), add);
// Get the positive constant. // Get the positive constant.
auto negCst = builder.create<hw::ConstantOp>(-rhsCst.getValue()); auto negCst = hw::ConstantOp::create(builder, -rhsCst.getValue());
auto sub = auto sub = comb::SubOp::create(builder, add.getOperand(0), negCst,
builder.create<comb::SubOp>(add.getOperand(0), negCst, add.getTwoState()); add.getTwoState());
add.getResult().replaceAllUsesWith(sub); add.getResult().replaceAllUsesWith(sub);
add.erase(); add.erase();
if (rhsCst.use_empty()) if (rhsCst.use_empty())
@ -446,7 +446,7 @@ static Operation *lowerStructExplodeOp(hw::StructExplodeOp op) {
for (auto [res, field] : for (auto [res, field] :
llvm::zip(op.getResults(), structType.getElements())) { llvm::zip(op.getResults(), structType.getElements())) {
auto extract = auto extract =
builder.create<hw::StructExtractOp>(op.getInput(), field.name); hw::StructExtractOp::create(builder, op.getInput(), field.name);
if (!firstOp) if (!firstOp)
firstOp = extract; firstOp = extract;
res.replaceAllUsesWith(extract); res.replaceAllUsesWith(extract);
@ -493,16 +493,16 @@ static bool rewriteSideEffectingExpr(Operation *op) {
// Scan to the top of the region tree to find out where to insert the reg. // Scan to the top of the region tree to find out where to insert the reg.
Operation *parentOp = findParentInNonProceduralRegion(op); Operation *parentOp = findParentInNonProceduralRegion(op);
OpBuilder builder(parentOp); OpBuilder builder(parentOp);
auto reg = builder.create<RegOp>(op->getLoc(), opValue.getType()); auto reg = RegOp::create(builder, op->getLoc(), opValue.getType());
// Everything using the expr now uses a read_inout of the reg. // Everything using the expr now uses a read_inout of the reg.
auto value = builder.create<ReadInOutOp>(op->getLoc(), reg); auto value = ReadInOutOp::create(builder, op->getLoc(), reg);
opValue.replaceAllUsesWith(value); opValue.replaceAllUsesWith(value);
// We assign the side effect expr to the reg immediately after that expression // We assign the side effect expr to the reg immediately after that expression
// is computed. // is computed.
builder.setInsertionPointAfter(op); builder.setInsertionPointAfter(op);
builder.create<BPAssignOp>(op->getLoc(), reg, opValue); BPAssignOp::create(builder, op->getLoc(), reg, opValue);
return true; return true;
} }
@ -715,7 +715,7 @@ static bool reuseExistingInOut(Operation *op, const LoweringOptions &options) {
ImplicitLocOpBuilder builder(assign.getDest().getLoc(), op->getContext()); ImplicitLocOpBuilder builder(assign.getDest().getLoc(), op->getContext());
for (OpOperand *use : uses) { for (OpOperand *use : uses) {
builder.setInsertionPoint(use->getOwner()); builder.setInsertionPoint(use->getOwner());
auto read = builder.create<ReadInOutOp>(assign.getDest()); auto read = ReadInOutOp::create(builder, assign.getDest());
use->set(read); use->set(read);
} }
if (auto *destOp = assign.getDest().getDefiningOp()) if (auto *destOp = assign.getDest().getDefiningOp())
@ -852,12 +852,13 @@ static void applyWireLowerings(Block &block,
ImplicitLocOpBuilder builder(hwWireOp.getLoc(), &block, declarePoint); ImplicitLocOpBuilder builder(hwWireOp.getLoc(), &block, declarePoint);
Value decl; Value decl;
if (isProceduralRegion) { if (isProceduralRegion) {
decl = builder.create<LogicOp>(hwWireOp.getType(), hwWireOp.getNameAttr(),
hwWireOp.getInnerSymAttr());
} else {
decl = decl =
builder.create<sv::WireOp>(hwWireOp.getType(), hwWireOp.getNameAttr(), LogicOp::create(builder, hwWireOp.getType(), hwWireOp.getNameAttr(),
hwWireOp.getInnerSymAttr()); hwWireOp.getInnerSymAttr());
} else {
decl = sv::WireOp::create(builder, hwWireOp.getType(),
hwWireOp.getNameAttr(),
hwWireOp.getInnerSymAttr());
} }
// Carry attributes over to the lowered operation. // Carry attributes over to the lowered operation.
@ -873,9 +874,9 @@ static void applyWireLowerings(Block &block,
if (assignPoint != declarePoint) if (assignPoint != declarePoint)
builder.setInsertionPoint(&block, assignPoint); builder.setInsertionPoint(&block, assignPoint);
if (isProceduralRegion) if (isProceduralRegion)
builder.create<BPAssignOp>(decl, hwWireOp.getInput()); BPAssignOp::create(builder, decl, hwWireOp.getInput());
else else
builder.create<AssignOp>(decl, hwWireOp.getInput()); AssignOp::create(builder, decl, hwWireOp.getInput());
// Create the read. If we have created the assignment at a different point // Create the read. If we have created the assignment at a different point
// than the declaration, reposition the builder to immediately after the // than the declaration, reposition the builder to immediately after the
@ -883,7 +884,7 @@ static void applyWireLowerings(Block &block,
// assignment. // assignment.
if (assignPoint != declarePoint) if (assignPoint != declarePoint)
builder.setInsertionPointAfterValue(decl); builder.setInsertionPointAfterValue(decl);
auto readOp = builder.create<sv::ReadInOutOp>(decl); auto readOp = sv::ReadInOutOp::create(builder, decl);
// Replace the HW wire. // Replace the HW wire.
hwWireOp.replaceAllUsesWith(readOp.getResult()); hwWireOp.replaceAllUsesWith(readOp.getResult());
@ -1035,15 +1036,15 @@ static LogicalResult legalizeHWModule(Block &block,
llvm::zip(aggregateConstantOp.getFieldsAttr(), llvm::zip(aggregateConstantOp.getFieldsAttr(),
structType.getElements())) { structType.getElements())) {
if (auto arrayAttr = dyn_cast<mlir::ArrayAttr>(value)) if (auto arrayAttr = dyn_cast<mlir::ArrayAttr>(value))
operands.push_back( operands.push_back(hw::AggregateConstantOp::create(
builder.create<hw::AggregateConstantOp>(field.type, arrayAttr)); builder, field.type, arrayAttr));
else else
operands.push_back(builder.create<hw::ConstantOp>( operands.push_back(hw::ConstantOp::create(
field.type, cast<mlir::IntegerAttr>(value))); builder, field.type, cast<mlir::IntegerAttr>(value)));
} }
auto structCreate = auto structCreate =
builder.create<hw::StructCreateOp>(structType, operands); hw::StructCreateOp::create(builder, structType, operands);
aggregateConstantOp.getResult().replaceAllUsesWith(structCreate); aggregateConstantOp.getResult().replaceAllUsesWith(structCreate);
// Reset the iterator. // Reset the iterator.
opIterator = std::next(op.getIterator()); opIterator = std::next(op.getIterator());
@ -1063,23 +1064,23 @@ static LogicalResult legalizeHWModule(Block &block,
cast<hw::StructType>(structCreateOp.getResult().getType()); cast<hw::StructType>(structCreateOp.getResult().getType());
bool procedural = op.getParentOp()->hasTrait<ProceduralRegion>(); bool procedural = op.getParentOp()->hasTrait<ProceduralRegion>();
if (procedural) if (procedural)
wireOp = builder.create<LogicOp>(structType); wireOp = LogicOp::create(builder, structType);
else else
wireOp = builder.create<sv::WireOp>(structType); wireOp = sv::WireOp::create(builder, structType);
for (auto [input, field] : for (auto [input, field] :
llvm::zip(structCreateOp.getInput(), structType.getElements())) { llvm::zip(structCreateOp.getInput(), structType.getElements())) {
auto target = auto target =
builder.create<sv::StructFieldInOutOp>(wireOp, field.name); sv::StructFieldInOutOp::create(builder, wireOp, field.name);
if (procedural) if (procedural)
builder.create<BPAssignOp>(target, input); BPAssignOp::create(builder, target, input);
else else
builder.create<AssignOp>(target, input); AssignOp::create(builder, target, input);
} }
// Have to create a separate read for each use to keep things legal. // Have to create a separate read for each use to keep things legal.
for (auto &use : for (auto &use :
llvm::make_early_inc_range(structCreateOp.getResult().getUses())) llvm::make_early_inc_range(structCreateOp.getResult().getUses()))
use.set(builder.create<ReadInOutOp>(wireOp)); use.set(ReadInOutOp::create(builder, wireOp));
structCreateOp.erase(); structCreateOp.erase();
continue; continue;
@ -1092,26 +1093,26 @@ static LogicalResult legalizeHWModule(Block &block,
ImplicitLocOpBuilder builder(op.getLoc(), &op); ImplicitLocOpBuilder builder(op.getLoc(), &op);
Value decl; Value decl;
if (procedural) if (procedural)
decl = builder.create<LogicOp>(arrayInjectOp.getType()); decl = LogicOp::create(builder, arrayInjectOp.getType());
else else
decl = builder.create<sv::RegOp>(arrayInjectOp.getType()); decl = sv::RegOp::create(builder, arrayInjectOp.getType());
for (auto &use : llvm::make_early_inc_range(arrayInjectOp->getUses())) for (auto &use : llvm::make_early_inc_range(arrayInjectOp->getUses()))
use.set(builder.create<ReadInOutOp>(decl)); use.set(ReadInOutOp::create(builder, decl));
// Make sure we have a procedural region where we can first copy the input // Make sure we have a procedural region where we can first copy the input
// array into `decl`, and then overwrite a single index. // array into `decl`, and then overwrite a single index.
if (!procedural) { if (!procedural) {
auto alwaysOp = builder.create<sv::AlwaysCombOp>(); auto alwaysOp = sv::AlwaysCombOp::create(builder);
builder.setInsertionPointToStart(alwaysOp.getBodyBlock()); builder.setInsertionPointToStart(alwaysOp.getBodyBlock());
} }
// Copy the input array into `decl`. // Copy the input array into `decl`.
builder.create<sv::BPAssignOp>(decl, arrayInjectOp.getInput()); sv::BPAssignOp::create(builder, decl, arrayInjectOp.getInput());
// Overwrite the injected value. // Overwrite the injected value.
auto target = auto target = sv::ArrayIndexInOutOp::create(builder, decl,
builder.create<sv::ArrayIndexInOutOp>(decl, arrayInjectOp.getIndex()); arrayInjectOp.getIndex());
builder.create<sv::BPAssignOp>(target, arrayInjectOp.getElement()); sv::BPAssignOp::create(builder, target, arrayInjectOp.getElement());
arrayInjectOp.erase(); arrayInjectOp.erase();
continue; continue;
@ -1141,13 +1142,13 @@ static LogicalResult legalizeHWModule(Block &block,
auto type = op.getOperand(1).getType(); auto type = op.getOperand(1).getType();
const auto *name = "_GEN_ARRAY_IDX"; const auto *name = "_GEN_ARRAY_IDX";
if (op.getParentOp()->hasTrait<ProceduralRegion>()) { if (op.getParentOp()->hasTrait<ProceduralRegion>()) {
wireOp = builder.create<LogicOp>(type, name); wireOp = LogicOp::create(builder, type, name);
builder.create<BPAssignOp>(wireOp, op.getOperand(1)); BPAssignOp::create(builder, wireOp, op.getOperand(1));
} else { } else {
wireOp = builder.create<sv::WireOp>(type, name); wireOp = sv::WireOp::create(builder, type, name);
builder.create<AssignOp>(wireOp, op.getOperand(1)); AssignOp::create(builder, wireOp, op.getOperand(1));
} }
readOp = builder.create<ReadInOutOp>(wireOp); readOp = ReadInOutOp::create(builder, wireOp);
} }
op.setOperand(1, readOp); op.setOperand(1, readOp);
@ -1349,16 +1350,16 @@ static void fixUpEmptyModules(hw::HWEmittableModuleLike module) {
return; // Not empty so no need to fix up. return; // Not empty so no need to fix up.
OpBuilder builder(module->getContext()); OpBuilder builder(module->getContext());
builder.setInsertionPoint(outputOp); builder.setInsertionPoint(outputOp);
auto constant = builder.create<hw::ConstantOp>(module.getLoc(), auto constant = hw::ConstantOp::create(builder, module.getLoc(),
builder.getBoolAttr(true)); builder.getBoolAttr(true));
auto wire = builder.create<sv::WireOp>(module.getLoc(), builder.getI1Type()); auto wire = sv::WireOp::create(builder, module.getLoc(), builder.getI1Type());
sv::setSVAttributes(wire, sv::setSVAttributes(wire,
sv::SVAttributeAttr::get( sv::SVAttributeAttr::get(
builder.getContext(), builder.getContext(),
"This wire is added to avoid emitting empty modules. " "This wire is added to avoid emitting empty modules. "
"See `fixUpEmptyModules` lowering option in CIRCT.", "See `fixUpEmptyModules` lowering option in CIRCT.",
/*emitAsComment=*/true)); /*emitAsComment=*/true));
builder.create<sv::AssignOp>(module.getLoc(), wire, constant); sv::AssignOp::create(builder, module.getLoc(), wire, constant);
} }
// NOLINTNEXTLINE(misc-no-recursion) // NOLINTNEXTLINE(misc-no-recursion)

View File

@ -133,8 +133,8 @@ static Value castToFIRRTLType(Value val, Type type,
val = builder.createOrFold<HWStructCastOp>(bundle.getPassiveType(), val); val = builder.createOrFold<HWStructCastOp>(bundle.getPassiveType(), val);
if (type != val.getType()) if (type != val.getType())
val = builder.create<mlir::UnrealizedConversionCastOp>(type, val).getResult( val = mlir::UnrealizedConversionCastOp::create(builder, type, val)
0); .getResult(0);
return val; return val;
} }
@ -145,17 +145,16 @@ static Value castFromFIRRTLType(Value val, Type type,
if (hw::StructType structTy = dyn_cast<hw::StructType>(type)) { if (hw::StructType structTy = dyn_cast<hw::StructType>(type)) {
// Strip off Flip type if needed. // Strip off Flip type if needed.
val = val = mlir::UnrealizedConversionCastOp::create(
builder builder,
.create<mlir::UnrealizedConversionCastOp>( type_cast<FIRRTLBaseType>(val.getType()).getPassiveType(), val)
type_cast<FIRRTLBaseType>(val.getType()).getPassiveType(), val) .getResult(0);
.getResult(0);
val = builder.createOrFold<HWStructCastOp>(type, val); val = builder.createOrFold<HWStructCastOp>(type, val);
return val; return val;
} }
val = val =
builder.create<mlir::UnrealizedConversionCastOp>(type, val).getResult(0); mlir::UnrealizedConversionCastOp::create(builder, type, val).getResult(0);
return val; return val;
} }
@ -480,8 +479,8 @@ private:
auto b = ImplicitLocOpBuilder::atBlockBegin( auto b = ImplicitLocOpBuilder::atBlockBegin(
circuitOp.getLoc(), circuitOp.getLoc(),
&circuitOp->getParentRegion()->getBlocks().back()); &circuitOp->getParentRegion()->getBlocks().back());
typeScope = b.create<hw::TypeScopeOp>( typeScope = hw::TypeScopeOp::create(
b.getStringAttr(circuitOp.getName() + "__TYPESCOPE_")); b, b.getStringAttr(circuitOp.getName() + "__TYPESCOPE_"));
typeScope.getBodyRegion().push_back(new Block()); typeScope.getBodyRegion().push_back(new Block());
} }
auto typeName = firAlias.getName(); auto typeName = firAlias.getName();
@ -494,8 +493,8 @@ private:
auto typeScopeBuilder = auto typeScopeBuilder =
ImplicitLocOpBuilder::atBlockEnd(typeLoc, typeScope.getBodyBlock()); ImplicitLocOpBuilder::atBlockEnd(typeLoc, typeScope.getBodyBlock());
auto typeDecl = typeScopeBuilder.create<hw::TypedeclOp>(typeLoc, typeName, auto typeDecl = hw::TypedeclOp::create(typeScopeBuilder, typeLoc,
rawType, nullptr); typeName, rawType, nullptr);
auto hwAlias = hw::TypeAliasType::get( auto hwAlias = hw::TypeAliasType::get(
SymbolRefAttr::get(typeScope.getSymNameAttr(), SymbolRefAttr::get(typeScope.getSymNameAttr(),
{FlatSymbolRefAttr::get(typeDecl)}), {FlatSymbolRefAttr::get(typeDecl)}),
@ -706,9 +705,9 @@ void FIRRTLModuleLowering::runOnOperation() {
}) })
.Case<FormalOp>([&](auto oldOp) { .Case<FormalOp>([&](auto oldOp) {
auto builder = OpBuilder::atBlockEnd(topLevelModule); auto builder = OpBuilder::atBlockEnd(topLevelModule);
auto newOp = builder.create<verif::FormalOp>( auto newOp = verif::FormalOp::create(builder, oldOp.getLoc(),
oldOp.getLoc(), oldOp.getNameAttr(), oldOp.getNameAttr(),
oldOp.getParametersAttr()); oldOp.getParametersAttr());
newOp.getBody().emplaceBlock(); newOp.getBody().emplaceBlock();
state.recordModuleMapping(oldOp, newOp); state.recordModuleMapping(oldOp, newOp);
opsToProcess.push_back(newOp); opsToProcess.push_back(newOp);
@ -717,8 +716,8 @@ void FIRRTLModuleLowering::runOnOperation() {
.Case<SimulationOp>([&](auto oldOp) { .Case<SimulationOp>([&](auto oldOp) {
auto loc = oldOp.getLoc(); auto loc = oldOp.getLoc();
auto builder = OpBuilder::atBlockEnd(topLevelModule); auto builder = OpBuilder::atBlockEnd(topLevelModule);
auto newOp = builder.create<verif::SimulationOp>( auto newOp = verif::SimulationOp::create(
loc, oldOp.getNameAttr(), oldOp.getParametersAttr()); builder, loc, oldOp.getNameAttr(), oldOp.getParametersAttr());
auto &body = newOp.getRegion().emplaceBlock(); auto &body = newOp.getRegion().emplaceBlock();
body.addArgument(seq::ClockType::get(builder.getContext()), loc); body.addArgument(seq::ClockType::get(builder.getContext()), loc);
body.addArgument(builder.getI1Type(), loc); body.addArgument(builder.getI1Type(), loc);
@ -811,7 +810,7 @@ void FIRRTLModuleLowering::runOnOperation() {
if (!state.macroDeclNames.empty()) { if (!state.macroDeclNames.empty()) {
ImplicitLocOpBuilder b(UnknownLoc::get(&getContext()), circuit); ImplicitLocOpBuilder b(UnknownLoc::get(&getContext()), circuit);
for (auto name : state.macroDeclNames) { for (auto name : state.macroDeclNames) {
b.create<sv::MacroDeclOp>(name); sv::MacroDeclOp::create(b, name);
} }
} }
@ -836,23 +835,23 @@ void FIRRTLModuleLowering::lowerFileHeader(CircuitOp op,
StringRef defineFalse = StringRef()) { StringRef defineFalse = StringRef()) {
if (!defineFalse.data()) { if (!defineFalse.data()) {
assert(defineTrue.data() && "didn't define anything"); assert(defineTrue.data() && "didn't define anything");
b.create<sv::IfDefOp>( sv::IfDefOp::create(
guard, [&]() { b.create<sv::MacroDefOp>(defName, defineTrue); }); b, guard, [&]() { sv::MacroDefOp::create(b, defName, defineTrue); });
} else { } else {
b.create<sv::IfDefOp>( sv::IfDefOp::create(
guard, b, guard,
[&]() { [&]() {
if (defineTrue.data()) if (defineTrue.data())
b.create<sv::MacroDefOp>(defName, defineTrue); sv::MacroDefOp::create(b, defName, defineTrue);
}, },
[&]() { b.create<sv::MacroDefOp>(defName, defineFalse); }); [&]() { sv::MacroDefOp::create(b, defName, defineFalse); });
} }
}; };
// Helper function to emit #ifndef guard. // Helper function to emit #ifndef guard.
auto emitGuard = [&](const char *guard, llvm::function_ref<void(void)> body) { auto emitGuard = [&](const char *guard, llvm::function_ref<void(void)> body) {
b.create<sv::IfDefOp>( sv::IfDefOp::create(
guard, []() {}, body); b, guard, []() {}, body);
}; };
if (state.usedFileDescriptorLib) { if (state.usedFileDescriptorLib) {
@ -885,8 +884,8 @@ void FIRRTLModuleLowering::lowerFileHeader(CircuitOp op,
DictionaryAttr::get(b.getContext(), perArgumentsAttr)}; DictionaryAttr::get(b.getContext(), perArgumentsAttr)};
// Create the function declaration // Create the function declaration
auto func = b.create<sv::FuncOp>( auto func = sv::FuncOp::create(
/*sym_name=*/ b, /*sym_name=*/
"__circt_lib_logging::FileDescriptor::get", moduleType, "__circt_lib_logging::FileDescriptor::get", moduleType,
/*perArgumentAttrs=*/ /*perArgumentAttrs=*/
b.getArrayAttr( b.getArrayAttr(
@ -899,11 +898,11 @@ void FIRRTLModuleLowering::lowerFileHeader(CircuitOp op,
b.getStringAttr("__circt_lib_logging::FileDescriptor::get")); b.getStringAttr("__circt_lib_logging::FileDescriptor::get"));
func.setPrivate(); func.setPrivate();
b.create<sv::MacroDeclOp>("__CIRCT_LIB_LOGGING"); sv::MacroDeclOp::create(b, "__CIRCT_LIB_LOGGING");
// Create the fragment containing the FileDescriptor class. // Create the fragment containing the FileDescriptor class.
b.create<emit::FragmentOp>("CIRCT_LIB_LOGGING_FRAGMENT", [&] { emit::FragmentOp::create(b, "CIRCT_LIB_LOGGING_FRAGMENT", [&] {
emitGuard("__CIRCT_LIB_LOGGING", [&]() { emitGuard("__CIRCT_LIB_LOGGING", [&]() {
b.create<sv::VerbatimOp>(R"(// CIRCT Logging Library sv::VerbatimOp::create(b, R"(// CIRCT Logging Library
package __circt_lib_logging; package __circt_lib_logging;
class FileDescriptor; class FileDescriptor;
static int global_id [string]; static int global_id [string];
@ -919,18 +918,18 @@ package __circt_lib_logging;
endpackage endpackage
)"); )");
b.create<sv::MacroDefOp>("__CIRCT_LIB_LOGGING", ""); sv::MacroDefOp::create(b, "__CIRCT_LIB_LOGGING", "");
}); });
}); });
} }
if (state.usedPrintf) { if (state.usedPrintf) {
b.create<sv::MacroDeclOp>("PRINTF_COND"); sv::MacroDeclOp::create(b, "PRINTF_COND");
b.create<sv::MacroDeclOp>("PRINTF_COND_"); sv::MacroDeclOp::create(b, "PRINTF_COND_");
b.create<emit::FragmentOp>("PRINTF_COND_FRAGMENT", [&] { emit::FragmentOp::create(b, "PRINTF_COND_FRAGMENT", [&] {
b.create<sv::VerbatimOp>( sv::VerbatimOp::create(
"\n// Users can define 'PRINTF_COND' to add an extra gate to " b, "\n// Users can define 'PRINTF_COND' to add an extra gate to "
"prints."); "prints.");
emitGuard("PRINTF_COND_", [&]() { emitGuard("PRINTF_COND_", [&]() {
emitGuardedDefine("PRINTF_COND", "PRINTF_COND_", "(`PRINTF_COND)", "1"); emitGuardedDefine("PRINTF_COND", "PRINTF_COND_", "(`PRINTF_COND)", "1");
}); });
@ -938,12 +937,12 @@ endpackage
} }
if (state.usedAssertVerboseCond) { if (state.usedAssertVerboseCond) {
b.create<sv::MacroDeclOp>("ASSERT_VERBOSE_COND"); sv::MacroDeclOp::create(b, "ASSERT_VERBOSE_COND");
b.create<sv::MacroDeclOp>("ASSERT_VERBOSE_COND_"); sv::MacroDeclOp::create(b, "ASSERT_VERBOSE_COND_");
b.create<emit::FragmentOp>("ASSERT_VERBOSE_COND_FRAGMENT", [&] { emit::FragmentOp::create(b, "ASSERT_VERBOSE_COND_FRAGMENT", [&] {
b.create<sv::VerbatimOp>( sv::VerbatimOp::create(
"\n// Users can define 'ASSERT_VERBOSE_COND' to add an extra " b, "\n// Users can define 'ASSERT_VERBOSE_COND' to add an extra "
"gate to assert error printing."); "gate to assert error printing.");
emitGuard("ASSERT_VERBOSE_COND_", [&]() { emitGuard("ASSERT_VERBOSE_COND_", [&]() {
emitGuardedDefine("ASSERT_VERBOSE_COND", "ASSERT_VERBOSE_COND_", emitGuardedDefine("ASSERT_VERBOSE_COND", "ASSERT_VERBOSE_COND_",
"(`ASSERT_VERBOSE_COND)", "1"); "(`ASSERT_VERBOSE_COND)", "1");
@ -952,12 +951,12 @@ endpackage
} }
if (state.usedStopCond) { if (state.usedStopCond) {
b.create<sv::MacroDeclOp>("STOP_COND"); sv::MacroDeclOp::create(b, "STOP_COND");
b.create<sv::MacroDeclOp>("STOP_COND_"); sv::MacroDeclOp::create(b, "STOP_COND_");
b.create<emit::FragmentOp>("STOP_COND_FRAGMENT", [&] { emit::FragmentOp::create(b, "STOP_COND_FRAGMENT", [&] {
b.create<sv::VerbatimOp>( sv::VerbatimOp::create(
"\n// Users can define 'STOP_COND' to add an extra gate " b, "\n// Users can define 'STOP_COND' to add an extra gate "
"to stop conditions."); "to stop conditions.");
emitGuard("STOP_COND_", [&]() { emitGuard("STOP_COND_", [&]() {
emitGuardedDefine("STOP_COND", "STOP_COND_", "(`STOP_COND)", "1"); emitGuardedDefine("STOP_COND", "STOP_COND_", "(`STOP_COND)", "1");
}); });
@ -1161,8 +1160,8 @@ FIRRTLModuleLowering::lowerExtModule(FExtModuleOp oldModule,
// no known default values in the extmodule. This ensures that the // no known default values in the extmodule. This ensures that the
// hw.instance will print all the parameters when generating verilog. // hw.instance will print all the parameters when generating verilog.
auto parameters = getHWParameters(oldModule, /*ignoreValues=*/true); auto parameters = getHWParameters(oldModule, /*ignoreValues=*/true);
auto newModule = builder.create<hw::HWModuleExternOp>( auto newModule = hw::HWModuleExternOp::create(
oldModule.getLoc(), nameAttr, ports, verilogName, parameters); builder, oldModule.getLoc(), nameAttr, ports, verilogName, parameters);
SymbolTable::setSymbolVisibility(newModule, SymbolTable::setSymbolVisibility(newModule,
SymbolTable::getSymbolVisibility(oldModule)); SymbolTable::getSymbolVisibility(oldModule));
@ -1194,8 +1193,8 @@ FIRRTLModuleLowering::lowerMemModule(FMemModuleOp oldModule,
// Build the new hw.module op. // Build the new hw.module op.
auto builder = OpBuilder::atBlockEnd(topLevelModule); auto builder = OpBuilder::atBlockEnd(topLevelModule);
auto newModule = builder.create<hw::HWModuleExternOp>( auto newModule = hw::HWModuleExternOp::create(
oldModule.getLoc(), oldModule.getModuleNameAttr(), ports, builder, oldModule.getLoc(), oldModule.getModuleNameAttr(), ports,
oldModule.getModuleNameAttr()); oldModule.getModuleNameAttr());
loweringState.processRemainingAnnotations(oldModule, loweringState.processRemainingAnnotations(oldModule,
AnnotationSet(oldModule)); AnnotationSet(oldModule));
@ -1217,7 +1216,7 @@ FIRRTLModuleLowering::lowerModule(FModuleOp oldModule, Block *topLevelModule,
auto builder = OpBuilder::atBlockEnd(topLevelModule); auto builder = OpBuilder::atBlockEnd(topLevelModule);
auto nameAttr = builder.getStringAttr(oldModule.getName()); auto nameAttr = builder.getStringAttr(oldModule.getName());
auto newModule = auto newModule =
builder.create<hw::HWModuleOp>(oldModule.getLoc(), nameAttr, ports); hw::HWModuleOp::create(builder, oldModule.getLoc(), nameAttr, ports);
if (auto comment = oldModule->getAttrOfType<StringAttr>("comment")) if (auto comment = oldModule->getAttrOfType<StringAttr>("comment"))
newModule.setCommentAttr(comment); newModule.setCommentAttr(comment);
@ -1357,12 +1356,12 @@ tryEliminatingConnectsToValue(Value flipValue, Operation *insertPoint,
// Convert fliped sources to passive sources. // Convert fliped sources to passive sources.
if (!type_cast<FIRRTLBaseType>(connectSrc.getType()).isPassive()) if (!type_cast<FIRRTLBaseType>(connectSrc.getType()).isPassive())
connectSrc = builder connectSrc =
.create<mlir::UnrealizedConversionCastOp>( mlir::UnrealizedConversionCastOp::create(
type_cast<FIRRTLBaseType>(connectSrc.getType()) builder,
.getPassiveType(), type_cast<FIRRTLBaseType>(connectSrc.getType()).getPassiveType(),
connectSrc) connectSrc)
.getResult(0); .getResult(0);
// We know it must be the destination operand due to the types, but the // We know it must be the destination operand due to the types, but the
// source may not match the destination width. // source may not match the destination width.
@ -1421,7 +1420,7 @@ LogicalResult FIRRTLModuleLowering::lowerModulePortsAndMoveBody(
// move the new function body to. This is important because we insert some // move the new function body to. This is important because we insert some
// ops at the start of the function and some at the end, and the body is // ops at the start of the function and some at the end, and the body is
// currently empty to avoid iterator invalidation. // currently empty to avoid iterator invalidation.
auto cursor = bodyBuilder.create<hw::ConstantOp>(APInt(1, 1)); auto cursor = hw::ConstantOp::create(bodyBuilder, APInt(1, 1));
bodyBuilder.setInsertionPoint(cursor); bodyBuilder.setInsertionPoint(cursor);
// Insert argument casts, and re-vector users in the old body to use them. // Insert argument casts, and re-vector users in the old body to use them.
@ -1463,10 +1462,10 @@ LogicalResult FIRRTLModuleLowering::lowerModulePortsAndMoveBody(
// We lower zero width inout and outputs to a wire that isn't connected to // We lower zero width inout and outputs to a wire that isn't connected to
// anything outside the module. Inputs are lowered to zero. // anything outside the module. Inputs are lowered to zero.
if (isZeroWidth && port.isInput()) { if (isZeroWidth && port.isInput()) {
Value newArg = bodyBuilder Value newArg =
.create<WireOp>(port.type, "." + port.getName().str() + WireOp::create(bodyBuilder, port.type,
".0width_input") "." + port.getName().str() + ".0width_input")
.getResult(); .getResult();
oldArg.replaceAllUsesWith(newArg); oldArg.replaceAllUsesWith(newArg);
continue; continue;
} }
@ -1482,8 +1481,8 @@ LogicalResult FIRRTLModuleLowering::lowerModulePortsAndMoveBody(
// Outputs need a temporary wire so they can be connect'd to, which we // Outputs need a temporary wire so they can be connect'd to, which we
// then return. // then return.
auto newArg = bodyBuilder.create<WireOp>( auto newArg = WireOp::create(bodyBuilder, port.type,
port.type, "." + port.getName().str() + ".output"); "." + port.getName().str() + ".output");
// Switch all uses of the old operands to the new ones. // Switch all uses of the old operands to the new ones.
oldArg.replaceAllUsesWith(newArg.getResult()); oldArg.replaceAllUsesWith(newArg.getResult());
@ -1538,11 +1537,11 @@ FIRRTLModuleLowering::lowerFormalBody(verif::FormalOp newOp,
SmallVector<Value> symbolicInputs; SmallVector<Value> symbolicInputs;
for (auto arg : newModule.getBody().getArguments()) for (auto arg : newModule.getBody().getArguments())
symbolicInputs.push_back( symbolicInputs.push_back(
builder.create<verif::SymbolicValueOp>(arg.getLoc(), arg.getType())); verif::SymbolicValueOp::create(builder, arg.getLoc(), arg.getType()));
// Instantiate the module with the given symbolic inputs. // Instantiate the module with the given symbolic inputs.
builder.create<hw::InstanceOp>(newOp.getLoc(), newModule, hw::InstanceOp::create(builder, newOp.getLoc(), newModule,
newModule.getNameAttr(), symbolicInputs); newModule.getNameAttr(), symbolicInputs);
return success(); return success();
} }
@ -1565,9 +1564,9 @@ FIRRTLModuleLowering::lowerSimulationBody(verif::SimulationOp newOp,
// and yield the module's outputs. // and yield the module's outputs.
SmallVector<Value> inputs(newOp.getBody()->args_begin(), SmallVector<Value> inputs(newOp.getBody()->args_begin(),
newOp.getBody()->args_end()); newOp.getBody()->args_end());
auto instOp = builder.create<hw::InstanceOp>(newOp.getLoc(), newModule, auto instOp = hw::InstanceOp::create(builder, newOp.getLoc(), newModule,
newModule.getNameAttr(), inputs); newModule.getNameAttr(), inputs);
builder.create<verif::YieldOp>(newOp.getLoc(), instOp.getResults()); verif::YieldOp::create(builder, newOp.getLoc(), instOp.getResults());
return success(); return success();
} }
@ -2016,7 +2015,7 @@ LogicalResult FIRRTLModuleLowering::lowerFileBody(emit::FileOp fileOp) {
fileOp->walk([&](Operation *op) { fileOp->walk([&](Operation *op) {
if (auto bindOp = dyn_cast<BindOp>(op)) { if (auto bindOp = dyn_cast<BindOp>(op)) {
b.setInsertionPointAfter(bindOp); b.setInsertionPointAfter(bindOp);
b.create<sv::BindOp>(bindOp.getLoc(), bindOp.getInstanceAttr()); sv::BindOp::create(b, bindOp.getLoc(), bindOp.getInstanceAttr());
bindOp->erase(); bindOp->erase();
} }
}); });
@ -2133,8 +2132,8 @@ LogicalResult FIRRTLLowering::run() {
continue; continue;
if (!zeroI0) { if (!zeroI0) {
auto builder = OpBuilder::atBlockBegin(theModule.getBodyBlock()); auto builder = OpBuilder::atBlockBegin(theModule.getBodyBlock());
zeroI0 = builder.create<hw::ConstantOp>(op->getLoc(), zeroI0 = hw::ConstantOp::create(builder, op->getLoc(),
builder.getIntegerType(0), 0); builder.getIntegerType(0), 0);
maybeUnusedValues.insert(zeroI0); maybeUnusedValues.insert(zeroI0);
} }
result.replaceAllUsesWith(zeroI0); result.replaceAllUsesWith(zeroI0);
@ -2188,7 +2187,7 @@ Value FIRRTLLowering::getOrCreateClockConstant(seq::ClockConst clock) {
return entry; return entry;
OpBuilder entryBuilder(&theModule.getBodyBlock()->front()); OpBuilder entryBuilder(&theModule.getBodyBlock()->front());
entry = entryBuilder.create<seq::ConstClockOp>(builder.getLoc(), attr); entry = seq::ConstClockOp::create(entryBuilder, builder.getLoc(), attr);
return entry; return entry;
} }
@ -2203,7 +2202,7 @@ Value FIRRTLLowering::getOrCreateIntConstant(const APInt &value) {
return entry; return entry;
OpBuilder entryBuilder(&theModule.getBodyBlock()->front()); OpBuilder entryBuilder(&theModule.getBodyBlock()->front());
entry = entryBuilder.create<hw::ConstantOp>(builder.getLoc(), attr); entry = hw::ConstantOp::create(entryBuilder, builder.getLoc(), attr);
return entry; return entry;
} }
@ -2262,8 +2261,8 @@ Value FIRRTLLowering::getOrCreateXConstant(unsigned numBits) {
return entry; return entry;
OpBuilder entryBuilder(&theModule.getBodyBlock()->front()); OpBuilder entryBuilder(&theModule.getBodyBlock()->front());
entry = entryBuilder.create<sv::ConstantXOp>( entry = sv::ConstantXOp::create(entryBuilder, builder.getLoc(),
builder.getLoc(), entryBuilder.getIntegerType(numBits)); entryBuilder.getIntegerType(numBits));
return entry; return entry;
} }
@ -2271,7 +2270,7 @@ Value FIRRTLLowering::getOrCreateZConstant(Type type) {
auto &entry = hwConstantZMap[type]; auto &entry = hwConstantZMap[type];
if (!entry) { if (!entry) {
OpBuilder entryBuilder(&theModule.getBodyBlock()->front()); OpBuilder entryBuilder(&theModule.getBodyBlock()->front());
entry = entryBuilder.create<sv::ConstantZOp>(builder.getLoc(), type); entry = sv::ConstantZOp::create(entryBuilder, builder.getLoc(), type);
} }
return entry; return entry;
} }
@ -2365,7 +2364,7 @@ Value FIRRTLLowering::getExtOrTruncAggregateValue(Value array,
destVectorType.getNumElements()); destVectorType.getNumElements());
i != e; ++i) { i != e; ++i) {
auto iIdx = getOrCreateIntConstant(indexWidth, i); auto iIdx = getOrCreateIntConstant(indexWidth, i);
auto arrayIndex = builder.create<hw::ArrayGetOp>(src, iIdx); auto arrayIndex = hw::ArrayGetOp::create(builder, src, iIdx);
if (failed(recurse(arrayIndex, srcVectorType.getElementType(), if (failed(recurse(arrayIndex, srcVectorType.getElementType(),
destVectorType.getElementType()))) destVectorType.getElementType())))
return failure(); return failure();
@ -2387,7 +2386,7 @@ Value FIRRTLLowering::getExtOrTruncAggregateValue(Value array,
for (auto elem : llvm::enumerate(destStructType)) { for (auto elem : llvm::enumerate(destStructType)) {
auto structExtract = auto structExtract =
builder.create<hw::StructExtractOp>(src, elem.value().name); hw::StructExtractOp::create(builder, src, elem.value().name);
if (failed(recurse(structExtract, if (failed(recurse(structExtract,
srcStructType.getElementType(elem.index()), srcStructType.getElementType(elem.index()),
destStructType.getElementType(elem.index())))) destStructType.getElementType(elem.index()))))
@ -2581,7 +2580,7 @@ std::optional<Value> FIRRTLLowering::getLoweredFmtOperand(Value operand) {
// Handle special substitutions. // Handle special substitutions.
if (type_isa<FStringType>(operand.getType())) { if (type_isa<FStringType>(operand.getType())) {
if (isa<TimeOp>(operand.getDefiningOp())) if (isa<TimeOp>(operand.getDefiningOp()))
return builder.create<sv::TimeOp>(); return sv::TimeOp::create(builder);
if (isa<HierarchicalModuleNameOp>(operand.getDefiningOp())) if (isa<HierarchicalModuleNameOp>(operand.getDefiningOp()))
return {nullptr}; return {nullptr};
} }
@ -2598,8 +2597,8 @@ std::optional<Value> FIRRTLLowering::getLoweredFmtOperand(Value operand) {
// it as signed decimal and have to wrap it in $signed(). // it as signed decimal and have to wrap it in $signed().
if (auto intTy = firrtl::type_cast<IntType>(operand.getType())) if (auto intTy = firrtl::type_cast<IntType>(operand.getType()))
if (intTy.isSigned()) if (intTy.isSigned())
loweredValue = builder.create<sv::SystemFunctionOp>( loweredValue = sv::SystemFunctionOp::create(
loweredValue.getType(), "signed", loweredValue); builder, loweredValue.getType(), "signed", loweredValue);
return loweredValue; return loweredValue;
} }
@ -2636,7 +2635,7 @@ LogicalResult FIRRTLLowering::lowerStatementWithFd(
Value ifCond = cond; Value ifCond = cond;
if (usePrintfCond) { if (usePrintfCond) {
ifCond = ifCond =
builder.create<sv::MacroRefExprOp>(cond.getType(), "PRINTF_COND_"); sv::MacroRefExprOp::create(builder, cond.getType(), "PRINTF_COND_");
ifCond = builder.createOrFold<comb::AndOp>(ifCond, cond, true); ifCond = builder.createOrFold<comb::AndOp>(ifCond, cond, true);
} }
@ -2646,7 +2645,7 @@ LogicalResult FIRRTLLowering::lowerStatementWithFd(
Value fd; Value fd;
if (fileDescriptor.isDefaultFd()) { if (fileDescriptor.isDefaultFd()) {
// Emit the sv.fwrite, writing to stderr by default. // Emit the sv.fwrite, writing to stderr by default.
fd = builder.create<hw::ConstantOp>(APInt(32, 0x80000002)); fd = hw::ConstantOp::create(builder, APInt(32, 0x80000002));
} else { } else {
// Call the library function to get the FD. // Call the library function to get the FD.
auto fdOrError = callFileDescriptorLib(fileDescriptor); auto fdOrError = callFileDescriptorLib(fileDescriptor);
@ -2674,21 +2673,19 @@ FIRRTLLowering::callFileDescriptorLib(const FileDescriptorInfo &info) {
if (failed(loweredFmtOperands(info.getSubstitutions(), fileNameOperands))) if (failed(loweredFmtOperands(info.getSubstitutions(), fileNameOperands)))
return failure(); return failure();
fileName = builder fileName = sv::SFormatFOp::create(builder, info.getOutputFileFormat(),
.create<sv::SFormatFOp>(info.getOutputFileFormat(), fileNameOperands)
fileNameOperands)
.getResult(); .getResult();
} else { } else {
// If substitution is not required, just use the output file name. // If substitution is not required, just use the output file name.
fileName = builder.create<sv::ConstantStrOp>(info.getOutputFileFormat()) fileName = sv::ConstantStrOp::create(builder, info.getOutputFileFormat())
.getResult(); .getResult();
} }
return builder return sv::FuncCallProceduralOp::create(
.create<sv::FuncCallProceduralOp>( builder, mlir::TypeRange{builder.getIntegerType(32)},
mlir::TypeRange{builder.getIntegerType(32)}, builder.getStringAttr("__circt_lib_logging::FileDescriptor::get"),
builder.getStringAttr("__circt_lib_logging::FileDescriptor::get"), ValueRange{fileName})
ValueRange{fileName})
->getResult(0); ->getResult(0);
} }
@ -2861,7 +2858,7 @@ Value FIRRTLLowering::getNonClockValue(Value v) {
if (it.second) { if (it.second) {
ImplicitLocOpBuilder builder(v.getLoc(), v.getContext()); ImplicitLocOpBuilder builder(v.getLoc(), v.getContext());
builder.setInsertionPointAfterValue(v); builder.setInsertionPointAfterValue(v);
it.first->second = builder.create<seq::FromClockOp>(v); it.first->second = seq::FromClockOp::create(builder, v);
} }
return it.first->second; return it.first->second;
} }
@ -2895,24 +2892,24 @@ void FIRRTLLowering::addToAlwaysBlock(
auto createIfOp = [&]() { auto createIfOp = [&]() {
// It is weird but intended. Here we want to create an empty sv.if // It is weird but intended. Here we want to create an empty sv.if
// with an else block. // with an else block.
insideIfOp = builder.create<sv::IfOp>( insideIfOp = sv::IfOp::create(
reset, []() {}, []() {}); builder, reset, []() {}, []() {});
}; };
if (resetStyle == sv::ResetType::AsyncReset) { if (resetStyle == sv::ResetType::AsyncReset) {
sv::EventControl events[] = {clockEdge, resetEdge}; sv::EventControl events[] = {clockEdge, resetEdge};
Value clocks[] = {clock, reset}; Value clocks[] = {clock, reset};
alwaysOp = builder.create<sv::AlwaysOp>(events, clocks, [&]() { alwaysOp = sv::AlwaysOp::create(builder, events, clocks, [&]() {
if (resetEdge == sv::EventControl::AtNegEdge) if (resetEdge == sv::EventControl::AtNegEdge)
llvm_unreachable("negative edge for reset is not expected"); llvm_unreachable("negative edge for reset is not expected");
createIfOp(); createIfOp();
}); });
} else { } else {
alwaysOp = builder.create<sv::AlwaysOp>(clockEdge, clock, createIfOp); alwaysOp = sv::AlwaysOp::create(builder, clockEdge, clock, createIfOp);
} }
} else { } else {
assert(!resetBody); assert(!resetBody);
alwaysOp = builder.create<sv::AlwaysOp>(clockEdge, clock); alwaysOp = sv::AlwaysOp::create(builder, clockEdge, clock);
insideIfOp = nullptr; insideIfOp = nullptr;
} }
alwaysBlocks[key] = {alwaysOp, insideIfOp}; alwaysBlocks[key] = {alwaysOp, insideIfOp};
@ -2969,7 +2966,7 @@ void FIRRTLLowering::addToIfDefBlock(StringRef cond,
op->moveBefore(builder.getInsertionBlock(), builder.getInsertionPoint()); op->moveBefore(builder.getInsertionBlock(), builder.getInsertionPoint());
} else { } else {
ifdefBlocks[{builder.getBlock(), condAttr}] = ifdefBlocks[{builder.getBlock(), condAttr}] =
builder.create<sv::IfDefOp>(condAttr, thenCtor, elseCtor); sv::IfDefOp::create(builder, condAttr, thenCtor, elseCtor);
} }
} }
@ -2983,7 +2980,7 @@ void FIRRTLLowering::addToInitialBlock(std::function<void(void)> body) {
// are defined ahead of the uses, which leads to better generated Verilog. // are defined ahead of the uses, which leads to better generated Verilog.
op->moveBefore(builder.getInsertionBlock(), builder.getInsertionPoint()); op->moveBefore(builder.getInsertionBlock(), builder.getInsertionPoint());
} else { } else {
initialBlocks[builder.getBlock()] = builder.create<sv::InitialOp>(body); initialBlocks[builder.getBlock()] = sv::InitialOp::create(builder, body);
} }
} }
@ -3002,7 +2999,7 @@ void FIRRTLLowering::addIfProceduralBlock(Value cond,
} }
} }
builder.create<sv::IfOp>(cond, thenCtor, elseCtor); sv::IfOp::create(builder, cond, thenCtor, elseCtor);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -3230,10 +3227,10 @@ LogicalResult FIRRTLLowering::visitExpr(FEnumCreateOp op) {
if (auto structType = dyn_cast<hw::StructType>(newType)) { if (auto structType = dyn_cast<hw::StructType>(newType)) {
auto tagType = structType.getFieldType("tag"); auto tagType = structType.getFieldType("tag");
auto tagValue = IntegerAttr::get(tagType, element.value.getValue()); auto tagValue = IntegerAttr::get(tagType, element.value.getValue());
auto tag = builder.create<sv::LocalParamOp>(op.getLoc(), tagType, tagValue, auto tag = sv::LocalParamOp::create(builder, op.getLoc(), tagType, tagValue,
tagName); tagName);
auto bodyType = structType.getFieldType("body"); auto bodyType = structType.getFieldType("body");
auto body = builder.create<hw::UnionCreateOp>(bodyType, tagName, input); auto body = hw::UnionCreateOp::create(builder, bodyType, tagName, input);
SmallVector<Value> operands = {tag.getResult(), body.getResult()}; SmallVector<Value> operands = {tag.getResult(), body.getResult()};
return setLoweringTo<hw::StructCreateOp>(op, structType, operands); return setLoweringTo<hw::StructCreateOp>(op, structType, operands);
} }
@ -3255,15 +3252,15 @@ LogicalResult FIRRTLLowering::visitExpr(IsTagOp op) {
auto tagName = op.getFieldNameAttr(); auto tagName = op.getFieldNameAttr();
auto lhs = getLoweredValue(op.getInput()); auto lhs = getLoweredValue(op.getInput());
if (isa<hw::StructType>(lhs.getType())) if (isa<hw::StructType>(lhs.getType()))
lhs = builder.create<hw::StructExtractOp>(lhs, "tag"); lhs = hw::StructExtractOp::create(builder, lhs, "tag");
auto index = op.getFieldIndex(); auto index = op.getFieldIndex();
auto enumType = op.getInput().getType().base(); auto enumType = op.getInput().getType().base();
auto tagValue = enumType.getElementValueAttr(index); auto tagValue = enumType.getElementValueAttr(index);
auto tagValueType = IntegerType::get(op.getContext(), enumType.getTagWidth()); auto tagValueType = IntegerType::get(op.getContext(), enumType.getTagWidth());
auto loweredTagValue = IntegerAttr::get(tagValueType, tagValue.getValue()); auto loweredTagValue = IntegerAttr::get(tagValueType, tagValue.getValue());
auto rhs = builder.create<sv::LocalParamOp>(op.getLoc(), tagValueType, auto rhs = sv::LocalParamOp::create(builder, op.getLoc(), tagValueType,
loweredTagValue, tagName); loweredTagValue, tagName);
Type resultType = builder.getIntegerType(1); Type resultType = builder.getIntegerType(1);
return setLoweringTo<comb::ICmpOp>(op, resultType, ICmpPredicate::eq, lhs, return setLoweringTo<comb::ICmpOp>(op, resultType, ICmpPredicate::eq, lhs,
@ -3277,7 +3274,7 @@ LogicalResult FIRRTLLowering::visitExpr(SubtagOp op) {
auto tagName = op.getFieldNameAttr(); auto tagName = op.getFieldNameAttr();
auto input = getLoweredValue(op.getInput()); auto input = getLoweredValue(op.getInput());
auto field = builder.create<hw::StructExtractOp>(input, "body"); auto field = hw::StructExtractOp::create(builder, input, "body");
return setLoweringTo<hw::UnionExtractOp>(op, field, tagName); return setLoweringTo<hw::UnionExtractOp>(op, field, tagName);
} }
@ -3331,8 +3328,8 @@ LogicalResult FIRRTLLowering::visitDecl(WireOp op) {
auto name = op.getNameAttr(); auto name = op.getNameAttr();
// This is not a temporary wire created by the compiler, so attach a symbol // This is not a temporary wire created by the compiler, so attach a symbol
// name. // name.
auto wire = builder.create<hw::WireOp>( auto wire = hw::WireOp::create(
op.getLoc(), getOrCreateZConstant(resultType), name, innerSym); builder, op.getLoc(), getOrCreateZConstant(resultType), name, innerSym);
if (auto svAttrs = sv::getSVAttributes(op)) if (auto svAttrs = sv::getSVAttributes(op))
sv::setSVAttributes(wire, svAttrs); sv::setSVAttributes(wire, svAttrs);
@ -3382,12 +3379,12 @@ LogicalResult FIRRTLLowering::visitDecl(NodeOp op) {
auto innerSym = lowerInnerSymbol(op); auto innerSym = lowerInnerSymbol(op);
if (innerSym) if (innerSym)
operand = builder.create<hw::WireOp>(operand, name, innerSym); operand = hw::WireOp::create(builder, operand, name, innerSym);
// Move SV attributes. // Move SV attributes.
if (auto svAttrs = sv::getSVAttributes(op)) { if (auto svAttrs = sv::getSVAttributes(op)) {
if (!innerSym) if (!innerSym)
operand = builder.create<hw::WireOp>(operand, name); operand = hw::WireOp::create(builder, operand, name);
sv::setSVAttributes(operand.getDefiningOp(), svAttrs); sv::setSVAttributes(operand.getDefiningOp(), svAttrs);
} }
@ -3408,8 +3405,8 @@ LogicalResult FIRRTLLowering::visitDecl(RegOp op) {
// Create a reg op, wiring itself to its input. // Create a reg op, wiring itself to its input.
auto innerSym = lowerInnerSymbol(op); auto innerSym = lowerInnerSymbol(op);
Backedge inputEdge = backedgeBuilder.get(resultType); Backedge inputEdge = backedgeBuilder.get(resultType);
auto reg = builder.create<seq::FirRegOp>(inputEdge, clockVal, auto reg = seq::FirRegOp::create(builder, inputEdge, clockVal,
op.getNameAttr(), innerSym); op.getNameAttr(), innerSym);
// Pass along the start and end random initialization bits for this register. // Pass along the start and end random initialization bits for this register.
if (auto randomRegister = op->getAttr("firrtl.random_init_register")) if (auto randomRegister = op->getAttr("firrtl.random_init_register"))
@ -3449,8 +3446,8 @@ LogicalResult FIRRTLLowering::visitDecl(RegResetOp op) {
bool isAsync = type_isa<AsyncResetType>(op.getResetSignal().getType()); bool isAsync = type_isa<AsyncResetType>(op.getResetSignal().getType());
Backedge inputEdge = backedgeBuilder.get(resultType); Backedge inputEdge = backedgeBuilder.get(resultType);
auto reg = auto reg =
builder.create<seq::FirRegOp>(inputEdge, clockVal, op.getNameAttr(), seq::FirRegOp::create(builder, inputEdge, clockVal, op.getNameAttr(),
resetSignal, resetValue, innerSym, isAsync); resetSignal, resetValue, innerSym, isAsync);
// Pass along the start and end random initialization bits for this register. // Pass along the start and end random initialization bits for this register.
if (auto randomRegister = op->getAttr("firrtl.random_init_register")) if (auto randomRegister = op->getAttr("firrtl.random_init_register"))
@ -3494,8 +3491,8 @@ LogicalResult FIRRTLLowering::visitDecl(MemOp op) {
memInit = seq::FirMemInitAttr::get(init.getContext(), init.getFilename(), memInit = seq::FirMemInitAttr::get(init.getContext(), init.getFilename(),
init.getIsBinary(), init.getIsInline()); init.getIsBinary(), init.getIsInline());
auto memDecl = builder.create<seq::FirMemOp>( auto memDecl = seq::FirMemOp::create(
memType, memSummary.readLatency, memSummary.writeLatency, builder, memType, memSummary.readLatency, memSummary.writeLatency,
memSummary.readUnderWrite, memSummary.writeUnderWrite, op.getNameAttr(), memSummary.readUnderWrite, memSummary.writeUnderWrite, op.getNameAttr(),
op.getInnerSymAttr(), memInit, op.getPrefixAttr(), Attribute{}); op.getInnerSymAttr(), memInit, op.getPrefixAttr(), Attribute{});
@ -3556,7 +3553,7 @@ LogicalResult FIRRTLLowering::visitDecl(MemOp op) {
auto addr = addInputPort("addr", op.getAddrBits()); auto addr = addInputPort("addr", op.getAddrBits());
auto en = addInputPort("en", 1); auto en = addInputPort("en", 1);
auto clk = addClock("clk"); auto clk = addClock("clk");
auto data = builder.create<seq::FirMemReadOp>(memDecl, addr, clk, en); auto data = seq::FirMemReadOp::create(builder, memDecl, addr, clk, en);
addOutput("data", memSummary.dataWidth, data); addOutput("data", memSummary.dataWidth, data);
} else if (memportKind == MemOp::PortKind::ReadWrite) { } else if (memportKind == MemOp::PortKind::ReadWrite) {
auto addr = addInputPort("addr", op.getAddrBits()); auto addr = addInputPort("addr", op.getAddrBits());
@ -3573,8 +3570,8 @@ LogicalResult FIRRTLLowering::visitDecl(MemOp op) {
Value mask; Value mask;
if (memSummary.isMasked) if (memSummary.isMasked)
mask = addInputPort("wmask", memSummary.maskBits); mask = addInputPort("wmask", memSummary.maskBits);
auto rdata = builder.create<seq::FirMemReadWriteOp>( auto rdata = seq::FirMemReadWriteOp::create(builder, memDecl, addr, clk,
memDecl, addr, clk, en, wdata, mode, mask); en, wdata, mode, mask);
addOutput("rdata", memSummary.dataWidth, rdata); addOutput("rdata", memSummary.dataWidth, rdata);
} else { } else {
auto addr = addInputPort("addr", op.getAddrBits()); auto addr = addInputPort("addr", op.getAddrBits());
@ -3590,7 +3587,7 @@ LogicalResult FIRRTLLowering::visitDecl(MemOp op) {
Value mask; Value mask;
if (memSummary.isMasked) if (memSummary.isMasked)
mask = addInputPort("mask", memSummary.maskBits); mask = addInputPort("mask", memSummary.maskBits);
builder.create<seq::FirMemWriteOp>(memDecl, addr, clk, en, data, mask); seq::FirMemWriteOp::create(builder, memDecl, addr, clk, en, data, mask);
} }
} }
@ -3668,8 +3665,8 @@ LogicalResult FIRRTLLowering::visitDecl(InstanceOp oldInstance) {
// Create a wire for each inout operand, so there is something to connect // Create a wire for each inout operand, so there is something to connect
// to. The instance becomes the sole driver of this wire. // to. The instance becomes the sole driver of this wire.
auto wire = builder.create<sv::WireOp>( auto wire = sv::WireOp::create(builder, portType,
portType, "." + port.getName().str() + ".wire"); "." + port.getName().str() + ".wire");
// Know that the argument FIRRTL value is equal to this wire, allowing // Know that the argument FIRRTL value is equal to this wire, allowing
// connects to it to be lowered. // connects to it to be lowered.
@ -3689,8 +3686,8 @@ LogicalResult FIRRTLLowering::visitDecl(InstanceOp oldInstance) {
oldInstance.getContext(), oldInstance.getInnerSymAttr(), 0, oldInstance.getContext(), oldInstance.getInnerSymAttr(), 0,
[&]() -> hw::InnerSymbolNamespace & { return moduleNamespace; }); [&]() -> hw::InnerSymbolNamespace & { return moduleNamespace; });
auto bindOp = builder.create<sv::BindOp>(theModule.getNameAttr(), auto bindOp = sv::BindOp::create(builder, theModule.getNameAttr(),
innerSym.getSymName()); innerSym.getSymName());
// If the lowered op already had output file information, then use that. // If the lowered op already had output file information, then use that.
// Otherwise, generate some default bind information. // Otherwise, generate some default bind information.
if (auto outputFile = oldInstance->getAttr("output_file")) if (auto outputFile = oldInstance->getAttr("output_file"))
@ -3701,8 +3698,9 @@ LogicalResult FIRRTLLowering::visitDecl(InstanceOp oldInstance) {
} }
// Create the new hw.instance operation. // Create the new hw.instance operation.
auto newInstance = builder.create<hw::InstanceOp>( auto newInstance =
newModule, oldInstance.getNameAttr(), operands, parameters, innerSym); hw::InstanceOp::create(builder, newModule, oldInstance.getNameAttr(),
operands, parameters, innerSym);
if (oldInstance.getLowerToBind() || oldInstance.getDoNotPrint()) if (oldInstance.getLowerToBind() || oldInstance.getDoNotPrint())
newInstance.setDoNotPrintAttr(builder.getUnitAttr()); newInstance.setDoNotPrintAttr(builder.getUnitAttr());
@ -3741,7 +3739,7 @@ LogicalResult FIRRTLLowering::visitDecl(ContractOp oldOp) {
types.push_back(lowered.getType()); types.push_back(lowered.getType());
} }
auto newOp = builder.create<verif::ContractOp>(types, inputs); auto newOp = verif::ContractOp::create(builder, types, inputs);
newOp->setDiscardableAttrs(oldOp->getDiscardableAttrDictionary()); newOp->setDiscardableAttrs(oldOp->getDiscardableAttrDictionary());
auto &body = newOp.getBody().emplaceBlock(); auto &body = newOp.getBody().emplaceBlock();
@ -4127,7 +4125,7 @@ LogicalResult FIRRTLLowering::visitExpr(IsXIntrinsicOp op) {
LogicalResult FIRRTLLowering::visitStmt(FPGAProbeIntrinsicOp op) { LogicalResult FIRRTLLowering::visitStmt(FPGAProbeIntrinsicOp op) {
auto operand = getLoweredValue(op.getInput()); auto operand = getLoweredValue(op.getInput());
builder.create<hw::WireOp>(operand); hw::WireOp::create(builder, operand);
return success(); return success();
} }
@ -4141,8 +4139,8 @@ LogicalResult FIRRTLLowering::visitExpr(PlusArgsValueIntrinsicOp op) {
if (!type) if (!type)
return failure(); return failure();
auto valueOp = builder.create<sim::PlusArgsValueOp>( auto valueOp = sim::PlusArgsValueOp::create(
builder.getIntegerType(1), type, op.getFormatStringAttr()); builder, builder.getIntegerType(1), type, op.getFormatStringAttr());
if (failed(setLowering(op.getResult(), valueOp.getResult()))) if (failed(setLowering(op.getResult(), valueOp.getResult())))
return failure(); return failure();
if (failed(setLowering(op.getFound(), valueOp.getFound()))) if (failed(setLowering(op.getFound(), valueOp.getFound())))
@ -4249,7 +4247,7 @@ template <typename TargetOp, typename IntrinsicOp>
LogicalResult FIRRTLLowering::lowerVerifIntrinsicOp(IntrinsicOp op) { LogicalResult FIRRTLLowering::lowerVerifIntrinsicOp(IntrinsicOp op) {
auto property = getLoweredValue(op.getProperty()); auto property = getLoweredValue(op.getProperty());
auto enable = op.getEnable() ? getLoweredValue(op.getEnable()) : Value(); auto enable = op.getEnable() ? getLoweredValue(op.getEnable()) : Value();
builder.create<TargetOp>(property, enable, op.getLabelAttr()); TargetOp::create(builder, property, enable, op.getLabelAttr());
return success(); return success();
} }
@ -4337,7 +4335,7 @@ LogicalResult FIRRTLLowering::visitExpr(InvalidValueOp op) {
auto constant = getOrCreateIntConstant(*bitwidth, 0); auto constant = getOrCreateIntConstant(*bitwidth, 0);
// If the result is an aggregate value, we have to bitcast the constant. // If the result is an aggregate value, we have to bitcast the constant.
if (!type_isa<IntegerType>(resultTy)) if (!type_isa<IntegerType>(resultTy))
constant = builder.create<hw::BitcastOp>(resultTy, constant); constant = hw::BitcastOp::create(builder, resultTy, constant);
return setLowering(op, constant); return setLowering(op, constant);
} }
@ -4429,8 +4427,8 @@ LogicalResult FIRRTLLowering::visitExpr(Mux2CellIntrinsicOp op) {
if (!cond || !ifTrue || !ifFalse) if (!cond || !ifTrue || !ifFalse)
return failure(); return failure();
auto val = builder.create<comb::MuxOp>(ifTrue.getType(), cond, ifTrue, auto val = comb::MuxOp::create(builder, ifTrue.getType(), cond, ifTrue,
ifFalse, true); ifFalse, true);
return setLowering(op, createValueWithMuxAnnotation(val, true)); return setLowering(op, createValueWithMuxAnnotation(val, true));
} }
@ -4443,8 +4441,8 @@ LogicalResult FIRRTLLowering::visitExpr(Mux4CellIntrinsicOp op) {
if (!sel || !v3 || !v2 || !v1 || !v0) if (!sel || !v3 || !v2 || !v1 || !v0)
return failure(); return failure();
Value array[] = {v3, v2, v1, v0}; Value array[] = {v3, v2, v1, v0};
auto create = builder.create<hw::ArrayCreateOp>(array); auto create = hw::ArrayCreateOp::create(builder, array);
auto val = builder.create<hw::ArrayGetOp>(create, sel); auto val = hw::ArrayGetOp::create(builder, create, sel);
return setLowering(op, createValueWithMuxAnnotation(val, false)); return setLowering(op, createValueWithMuxAnnotation(val, false));
} }
@ -4467,7 +4465,7 @@ LogicalResult FIRRTLLowering::visitExpr(Mux4CellIntrinsicOp op) {
Value FIRRTLLowering::createValueWithMuxAnnotation(Operation *op, bool isMux2) { Value FIRRTLLowering::createValueWithMuxAnnotation(Operation *op, bool isMux2) {
assert(op->getNumResults() == 1 && "only expect a single result"); assert(op->getNumResults() == 1 && "only expect a single result");
auto val = op->getResult(0); auto val = op->getResult(0);
auto valWire = builder.create<sv::WireOp>(val.getType()); auto valWire = sv::WireOp::create(builder, val.getType());
// Use SV attributes to annotate pragmas. // Use SV attributes to annotate pragmas.
circt::sv::setSVAttributes( circt::sv::setSVAttributes(
op, sv::SVAttributeAttr::get(builder.getContext(), "cadence map_to_mux", op, sv::SVAttributeAttr::get(builder.getContext(), "cadence map_to_mux",
@ -4485,17 +4483,17 @@ Value FIRRTLLowering::createValueWithMuxAnnotation(Operation *op, bool isMux2) {
op->getContext(), /*attr=*/nullptr, 0, op->getContext(), /*attr=*/nullptr, 0,
[&]() -> hw::InnerSymbolNamespace & { return moduleNamespace; }); [&]() -> hw::InnerSymbolNamespace & { return moduleNamespace; });
auto wire = auto wire =
builder.create<hw::WireOp>(operand, namehint + Twine(idx), innerSym); hw::WireOp::create(builder, operand, namehint + Twine(idx), innerSym);
op->setOperand(idx, wire); op->setOperand(idx, wire);
} }
} }
auto assignOp = builder.create<sv::AssignOp>(valWire, val); auto assignOp = sv::AssignOp::create(builder, valWire, val);
sv::setSVAttributes(assignOp, sv::setSVAttributes(assignOp,
sv::SVAttributeAttr::get(builder.getContext(), sv::SVAttributeAttr::get(builder.getContext(),
"synopsys infer_mux_override", "synopsys infer_mux_override",
/*emitAsComment=*/true)); /*emitAsComment=*/true));
return builder.create<sv::ReadInOutOp>(valWire); return sv::ReadInOutOp::create(builder, valWire);
} }
Value FIRRTLLowering::createArrayIndexing(Value array, Value index) { Value FIRRTLLowering::createArrayIndexing(Value array, Value index) {
@ -4507,14 +4505,14 @@ Value FIRRTLLowering::createArrayIndexing(Value array, Value index) {
// optimization. // optimization.
if (!llvm::isPowerOf2_64(size)) { if (!llvm::isPowerOf2_64(size)) {
auto extElem = getOrCreateIntConstant(APInt(llvm::Log2_64_Ceil(size), 0)); auto extElem = getOrCreateIntConstant(APInt(llvm::Log2_64_Ceil(size), 0));
auto extValue = builder.create<hw::ArrayGetOp>(array, extElem); auto extValue = hw::ArrayGetOp::create(builder, array, extElem);
SmallVector<Value> temp(llvm::NextPowerOf2(size) - size, extValue); SmallVector<Value> temp(llvm::NextPowerOf2(size) - size, extValue);
auto ext = builder.create<hw::ArrayCreateOp>(temp); auto ext = hw::ArrayCreateOp::create(builder, temp);
Value temp2[] = {ext.getResult(), array}; Value temp2[] = {ext.getResult(), array};
array = builder.create<hw::ArrayConcatOp>(temp2); array = hw::ArrayConcatOp::create(builder, temp2);
} }
Value inBoundsRead = builder.create<hw::ArrayGetOp>(array, index); Value inBoundsRead = hw::ArrayGetOp::create(builder, array, index);
return inBoundsRead; return inBoundsRead;
} }
@ -4537,7 +4535,7 @@ LogicalResult FIRRTLLowering::visitExpr(MultibitMuxOp op) {
loweredInputs.push_back(lowered); loweredInputs.push_back(lowered);
} }
Value array = builder.create<hw::ArrayCreateOp>(loweredInputs); Value array = hw::ArrayCreateOp::create(builder, loweredInputs);
return setLowering(op, createArrayIndexing(array, index)); return setLowering(op, createArrayIndexing(array, index));
} }
@ -4588,8 +4586,8 @@ LogicalResult FIRRTLLowering::visitExpr(XMRDerefOp op) {
else else
xmrType = lowerType(op.getType()); xmrType = lowerType(op.getType());
auto xmr = builder.create<sv::XMRRefOp>( auto xmr = sv::XMRRefOp::create(builder, sv::InOutType::get(xmrType),
sv::InOutType::get(xmrType), op.getRef(), op.getVerbatimSuffixAttr()); op.getRef(), op.getVerbatimSuffixAttr());
auto readXmr = getReadValue(xmr); auto readXmr = getReadValue(xmr);
if (!isa<ClockType>(op.getType())) if (!isa<ClockType>(op.getType()))
return setLowering(op, readXmr); return setLowering(op, readXmr);
@ -4624,7 +4622,7 @@ FailureOr<bool> FIRRTLLowering::lowerConnect(Value destVal, Value srcVal) {
auto dstType = destVal.getType(); auto dstType = destVal.getType();
if (srcType != dstType && if (srcType != dstType &&
(isa<hw::TypeAliasType>(srcType) || isa<hw::TypeAliasType>(dstType))) { (isa<hw::TypeAliasType>(srcType) || isa<hw::TypeAliasType>(dstType))) {
srcVal = builder.create<hw::BitcastOp>(destVal.getType(), srcVal); srcVal = hw::BitcastOp::create(builder, destVal.getType(), srcVal);
} }
return TypeSwitch<Operation *, FailureOr<bool>>(destVal.getDefiningOp()) return TypeSwitch<Operation *, FailureOr<bool>>(destVal.getDefiningOp())
.Case<hw::WireOp>([&](auto op) { .Case<hw::WireOp>([&](auto op) {
@ -4672,7 +4670,7 @@ LogicalResult FIRRTLLowering::visitStmt(ConnectOp op) {
if (!isa<hw::InOutType>(destVal.getType())) if (!isa<hw::InOutType>(destVal.getType()))
return op.emitError("destination isn't an inout type"); return op.emitError("destination isn't an inout type");
builder.create<sv::AssignOp>(destVal, srcVal); sv::AssignOp::create(builder, destVal, srcVal);
return success(); return success();
} }
@ -4700,7 +4698,7 @@ LogicalResult FIRRTLLowering::visitStmt(MatchingConnectOp op) {
if (!isa<hw::InOutType>(destVal.getType())) if (!isa<hw::InOutType>(destVal.getType()))
return op.emitError("destination isn't an inout type"); return op.emitError("destination isn't an inout type");
builder.create<sv::AssignOp>(destVal, srcVal); sv::AssignOp::create(builder, destVal, srcVal);
return success(); return success();
} }
@ -4719,7 +4717,7 @@ LogicalResult FIRRTLLowering::visitStmt(ForceOp op) {
// #ifndef SYNTHESIS // #ifndef SYNTHESIS
circuitState.addMacroDecl(builder.getStringAttr("SYNTHESIS")); circuitState.addMacroDecl(builder.getStringAttr("SYNTHESIS"));
addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() { addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() {
addToInitialBlock([&]() { builder.create<sv::ForceOp>(destVal, srcVal); }); addToInitialBlock([&]() { sv::ForceOp::create(builder, destVal, srcVal); });
}); });
return success(); return success();
} }
@ -4740,7 +4738,7 @@ LogicalResult FIRRTLLowering::visitStmt(RefForceOp op) {
addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() { addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() {
addToAlwaysBlock(clock, [&]() { addToAlwaysBlock(clock, [&]() {
addIfProceduralBlock( addIfProceduralBlock(
pred, [&]() { builder.create<sv::ForceOp>(destVal, src); }); pred, [&]() { sv::ForceOp::create(builder, destVal, src); });
}); });
}); });
return success(); return success();
@ -4760,7 +4758,7 @@ LogicalResult FIRRTLLowering::visitStmt(RefForceInitialOp op) {
addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() { addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() {
addToInitialBlock([&]() { addToInitialBlock([&]() {
addIfProceduralBlock( addIfProceduralBlock(
pred, [&]() { builder.create<sv::ForceOp>(destVal, src); }); pred, [&]() { sv::ForceOp::create(builder, destVal, src); });
}); });
}); });
return success(); return success();
@ -4780,7 +4778,7 @@ LogicalResult FIRRTLLowering::visitStmt(RefReleaseOp op) {
addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() { addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() {
addToAlwaysBlock(clock, [&]() { addToAlwaysBlock(clock, [&]() {
addIfProceduralBlock(pred, addIfProceduralBlock(pred,
[&]() { builder.create<sv::ReleaseOp>(destVal); }); [&]() { sv::ReleaseOp::create(builder, destVal); });
}); });
}); });
return success(); return success();
@ -4796,7 +4794,7 @@ LogicalResult FIRRTLLowering::visitStmt(RefReleaseInitialOp op) {
addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() { addToIfDefBlock("SYNTHESIS", std::function<void()>(), [&]() {
addToInitialBlock([&]() { addToInitialBlock([&]() {
addIfProceduralBlock(pred, addIfProceduralBlock(pred,
[&]() { builder.create<sv::ReleaseOp>(destVal); }); [&]() { sv::ReleaseOp::create(builder, destVal); });
}); });
}); });
return success(); return success();
@ -4905,7 +4903,7 @@ LogicalResult FIRRTLLowering::visitPrintfLike(
SmallVector<Value> operands; SmallVector<Value> operands;
if (failed(loweredFmtOperands(op.getSubstitutions(), operands))) if (failed(loweredFmtOperands(op.getSubstitutions(), operands)))
return failure(); return failure();
builder.create<sv::FWriteOp>(op.getLoc(), fd, formatString, operands); sv::FWriteOp::create(builder, op.getLoc(), fd, formatString, operands);
return success(); return success();
}; };
@ -4933,7 +4931,7 @@ LogicalResult FIRRTLLowering::visitStmt(FFlushOp op) {
return failure(); return failure();
auto fn = [&](Value fd) { auto fn = [&](Value fd) {
builder.create<sv::FFlushOp>(op.getLoc(), fd); sv::FFlushOp::create(builder, op.getLoc(), fd);
return success(); return success();
}; };
@ -4965,13 +4963,13 @@ LogicalResult FIRRTLLowering::visitStmt(StopOp op) {
circuitState.addFragment(theModule, "STOP_COND_FRAGMENT"); circuitState.addFragment(theModule, "STOP_COND_FRAGMENT");
Value stopCond = Value stopCond =
builder.create<sv::MacroRefExprOp>(cond.getType(), "STOP_COND_"); sv::MacroRefExprOp::create(builder, cond.getType(), "STOP_COND_");
Value exitCond = builder.createOrFold<comb::AndOp>(stopCond, cond, true); Value exitCond = builder.createOrFold<comb::AndOp>(stopCond, cond, true);
if (op.getExitCode()) if (op.getExitCode())
builder.create<sim::FatalOp>(clock, exitCond); sim::FatalOp::create(builder, clock, exitCond);
else else
builder.create<sim::FinishOp>(clock, exitCond); sim::FinishOp::create(builder, clock, exitCond);
return success(); return success();
} }
@ -4983,11 +4981,11 @@ template <typename... Args>
static Operation *buildImmediateVerifOp(ImplicitLocOpBuilder &builder, static Operation *buildImmediateVerifOp(ImplicitLocOpBuilder &builder,
StringRef opName, Args &&...args) { StringRef opName, Args &&...args) {
if (opName == "assert") if (opName == "assert")
return builder.create<sv::AssertOp>(std::forward<Args>(args)...); return sv::AssertOp::create(builder, std::forward<Args>(args)...);
if (opName == "assume") if (opName == "assume")
return builder.create<sv::AssumeOp>(std::forward<Args>(args)...); return sv::AssumeOp::create(builder, std::forward<Args>(args)...);
if (opName == "cover") if (opName == "cover")
return builder.create<sv::CoverOp>(std::forward<Args>(args)...); return sv::CoverOp::create(builder, std::forward<Args>(args)...);
llvm_unreachable("unknown verification op"); llvm_unreachable("unknown verification op");
} }
@ -4998,11 +4996,11 @@ template <typename... Args>
static Operation *buildConcurrentVerifOp(ImplicitLocOpBuilder &builder, static Operation *buildConcurrentVerifOp(ImplicitLocOpBuilder &builder,
StringRef opName, Args &&...args) { StringRef opName, Args &&...args) {
if (opName == "assert") if (opName == "assert")
return builder.create<sv::AssertConcurrentOp>(std::forward<Args>(args)...); return sv::AssertConcurrentOp::create(builder, std::forward<Args>(args)...);
if (opName == "assume") if (opName == "assume")
return builder.create<sv::AssumeConcurrentOp>(std::forward<Args>(args)...); return sv::AssumeConcurrentOp::create(builder, std::forward<Args>(args)...);
if (opName == "cover") if (opName == "cover")
return builder.create<sv::CoverConcurrentOp>(std::forward<Args>(args)...); return sv::CoverConcurrentOp::create(builder, std::forward<Args>(args)...);
llvm_unreachable("unknown verification op"); llvm_unreachable("unknown verification op");
} }
@ -5086,7 +5084,7 @@ LogicalResult FIRRTLLowering::lowerVerificationStatement(
// assertion triggers. (See SystemVerilog 2017 spec section 16.9.3 for // assertion triggers. (See SystemVerilog 2017 spec section 16.9.3 for
// more information.) // more information.)
for (auto &loweredValue : messageOps) for (auto &loweredValue : messageOps)
loweredValue = builder.create<sv::SampledOp>(loweredValue); loweredValue = sv::SampledOp::create(builder, loweredValue);
} }
} }
@ -5123,12 +5121,12 @@ LogicalResult FIRRTLLowering::lowerVerificationStatement(
circuitState.addFragment(theModule, "ASSERT_VERBOSE_COND_FRAGMENT"); circuitState.addFragment(theModule, "ASSERT_VERBOSE_COND_FRAGMENT");
addIfProceduralBlock( addIfProceduralBlock(
builder.create<sv::MacroRefExprOp>(boolType, sv::MacroRefExprOp::create(builder, boolType,
"ASSERT_VERBOSE_COND_"), "ASSERT_VERBOSE_COND_"),
[&]() { builder.create<sv::ErrorOp>(message, messageOps); }); [&]() { sv::ErrorOp::create(builder, message, messageOps); });
addIfProceduralBlock( addIfProceduralBlock(
builder.create<sv::MacroRefExprOp>(boolType, "STOP_COND_"), sv::MacroRefExprOp::create(builder, boolType, "STOP_COND_"),
[&]() { builder.create<sv::FatalOp>(); }); [&]() { sv::FatalOp::create(builder); });
}); });
}); });
}); });
@ -5234,8 +5232,9 @@ LogicalResult FIRRTLLowering::visitStmt(UnclockedAssumeIntrinsicOp op) {
messageOps.push_back(loweredValue); messageOps.push_back(loweredValue);
} }
return emitGuards(op.getLoc(), guards, [&]() { return emitGuards(op.getLoc(), guards, [&]() {
builder.create<sv::AlwaysOp>( sv::AlwaysOp::create(
ArrayRef(sv::EventControl::AtEdge), ArrayRef(predicate), [&]() { builder, ArrayRef(sv::EventControl::AtEdge), ArrayRef(predicate),
[&]() {
if (op.getMessageAttr().getValue().empty()) if (op.getMessageAttr().getValue().empty())
buildImmediateVerifOp( buildImmediateVerifOp(
builder, "assume", predicate, builder, "assume", predicate,
@ -5311,28 +5310,29 @@ LogicalResult FIRRTLLowering::visitStmt(AttachOp op) {
for (size_t i1 = 0, e = inoutValues.size(); i1 != e; ++i1) { for (size_t i1 = 0, e = inoutValues.size(); i1 != e; ++i1) {
for (size_t i2 = 0; i2 != e; ++i2) for (size_t i2 = 0; i2 != e; ++i2)
if (i1 != i2) if (i1 != i2)
builder.create<sv::AssignOp>(inoutValues[i1], values[i2]); sv::AssignOp::create(builder, inoutValues[i1], values[i2]);
} }
}, },
// In the non-synthesis case, we emit a SystemVerilog alias // In the non-synthesis case, we emit a SystemVerilog alias
// statement. // statement.
[&]() { [&]() {
builder.create<sv::IfDefOp>( sv::IfDefOp::create(
"VERILATOR", builder, "VERILATOR",
[&]() { [&]() {
builder.create<sv::VerbatimOp>( sv::VerbatimOp::create(
builder,
"`error \"Verilator does not support alias and thus " "`error \"Verilator does not support alias and thus "
"cannot " "cannot "
"arbitrarily connect bidirectional wires and ports\""); "arbitrarily connect bidirectional wires and ports\"");
}, },
[&]() { builder.create<sv::AliasOp>(inoutValues); }); [&]() { sv::AliasOp::create(builder, inoutValues); });
}); });
return success(); return success();
} }
LogicalResult FIRRTLLowering::visitStmt(BindOp op) { LogicalResult FIRRTLLowering::visitStmt(BindOp op) {
builder.create<sv::BindOp>(op.getInstanceAttr()); sv::BindOp::create(builder, op.getInstanceAttr());
return success(); return success();
} }

View File

@ -152,8 +152,8 @@ StateEncoding::StateEncoding(OpBuilder &b, hw::TypeScopeOp typeScope,
OpBuilder::InsertionGuard guard(b); OpBuilder::InsertionGuard guard(b);
b.setInsertionPointToStart(&typeScope.getBodyRegion().front()); b.setInsertionPointToStart(&typeScope.getBodyRegion().front());
auto typedeclEnumType = b.create<hw::TypedeclOp>( auto typedeclEnumType = hw::TypedeclOp::create(
loc, b.getStringAttr(hwModule.getName() + "_state_t"), b, loc, b.getStringAttr(hwModule.getName() + "_state_t"),
TypeAttr::get(rawEnumType), nullptr); TypeAttr::get(rawEnumType), nullptr);
stateType = hw::TypeAliasType::get( stateType = hw::TypeAliasType::get(
@ -166,8 +166,8 @@ StateEncoding::StateEncoding(OpBuilder &b, hw::TypeScopeOp typeScope,
for (auto state : machine.getBody().getOps<StateOp>()) { for (auto state : machine.getBody().getOps<StateOp>()) {
auto fieldAttr = hw::EnumFieldAttr::get( auto fieldAttr = hw::EnumFieldAttr::get(
loc, b.getStringAttr(state.getName()), stateType); loc, b.getStringAttr(state.getName()), stateType);
auto enumConstantOp = b.create<hw::EnumConstantOp>( auto enumConstantOp = hw::EnumConstantOp::create(
loc, fieldAttr.getType().getValue(), fieldAttr); b, loc, fieldAttr.getType().getValue(), fieldAttr);
setEncoding(state, enumConstantOp, setEncoding(state, enumConstantOp,
/*wire=*/true); /*wire=*/true);
} }
@ -203,11 +203,11 @@ void StateEncoding::setEncoding(StateOp state, Value v, bool wire) {
if (wire) { if (wire) {
auto loc = machine.getLoc(); auto loc = machine.getLoc();
auto stateType = getStateType(); auto stateType = getStateType();
auto stateEncodingWire = b.create<sv::RegOp>( auto stateEncodingWire = sv::RegOp::create(
loc, stateType, b.getStringAttr("to_" + state.getName()), b, loc, stateType, b.getStringAttr("to_" + state.getName()),
hw::InnerSymAttr::get(state.getNameAttr())); hw::InnerSymAttr::get(state.getNameAttr()));
b.create<sv::AssignOp>(loc, stateEncodingWire, v); sv::AssignOp::create(b, loc, stateEncodingWire, v);
encodedValue = b.create<sv::ReadInOutOp>(loc, stateEncodingWire); encodedValue = sv::ReadInOutOp::create(b, loc, stateEncodingWire);
} else } else
encodedValue = v; encodedValue = v;
stateToValue[state] = encodedValue; stateToValue[state] = encodedValue;
@ -368,13 +368,13 @@ void MachineOpConverter::buildStateCaseMux(
// Default assignments. // Default assignments.
for (auto &assignment : assignments) { for (auto &assignment : assignments) {
if (assignment.defaultValue) if (assignment.defaultValue)
b.create<sv::BPAssignOp>(assignment.wire.getLoc(), assignment.wire, sv::BPAssignOp::create(b, assignment.wire.getLoc(), assignment.wire,
*assignment.defaultValue); *assignment.defaultValue);
} }
// Case assignments. // Case assignments.
caseMux = b.create<sv::CaseOp>( caseMux = sv::CaseOp::create(
machineOp.getLoc(), CaseStmtType::CaseStmt, b, machineOp.getLoc(), CaseStmtType::CaseStmt,
/*sv::ValidationQualifierTypeEnum::ValidationQualifierUnique, */ select, /*sv::ValidationQualifierTypeEnum::ValidationQualifierUnique, */ select,
/*numCases=*/machineOp.getNumStates() + 1, [&](size_t caseIdx) { /*numCases=*/machineOp.getNumStates() + 1, [&](size_t caseIdx) {
// Make Verilator happy for sized enums. // Make Verilator happy for sized enums.
@ -395,7 +395,7 @@ void MachineOpConverter::buildStateCaseMux(
continue; continue;
b.setInsertionPointToEnd(caseInfo.block); b.setInsertionPointToEnd(caseInfo.block);
if (auto v = std::get_if<Value>(&assignmentInState->second); v) { if (auto v = std::get_if<Value>(&assignmentInState->second); v) {
b.create<sv::BPAssignOp>(machineOp.getLoc(), assignment.wire, *v); sv::BPAssignOp::create(b, machineOp.getLoc(), assignment.wire, *v);
} else { } else {
// Nested case statement. // Nested case statement.
llvm::SmallVector<CaseMuxItem, 4> nestedAssignments; llvm::SmallVector<CaseMuxItem, 4> nestedAssignments;
@ -420,7 +420,8 @@ LogicalResult MachineOpConverter::dispatch() {
// 1) Get the port info of the machine and create a new HW module for it. // 1) Get the port info of the machine and create a new HW module for it.
SmallVector<hw::PortInfo, 16> ports; SmallVector<hw::PortInfo, 16> ports;
auto clkRstIdxs = getMachinePortInfo(ports, machineOp, b); auto clkRstIdxs = getMachinePortInfo(ports, machineOp, b);
hwModuleOp = b.create<hw::HWModuleOp>(loc, machineOp.getSymNameAttr(), ports); hwModuleOp =
hw::HWModuleOp::create(b, loc, machineOp.getSymNameAttr(), ports);
hwModuleOp->setAttr(emit::getFragmentsAttrName(), hwModuleOp->setAttr(emit::getFragmentsAttrName(),
b.getArrayAttr({headerName})); b.getArrayAttr({headerName}));
b.setInsertionPointToStart(hwModuleOp.getBodyBlock()); b.setInsertionPointToStart(hwModuleOp.getBodyBlock());
@ -443,10 +444,10 @@ LogicalResult MachineOpConverter::dispatch() {
auto stateType = encoding->getStateType(); auto stateType = encoding->getStateType();
auto nextStateWire = auto nextStateWire =
b.create<sv::RegOp>(loc, stateType, b.getStringAttr("state_next")); sv::RegOp::create(b, loc, stateType, b.getStringAttr("state_next"));
auto nextStateWireRead = b.create<sv::ReadInOutOp>(loc, nextStateWire); auto nextStateWireRead = sv::ReadInOutOp::create(b, loc, nextStateWire);
stateReg = b.create<seq::CompRegOp>( stateReg = seq::CompRegOp::create(
loc, nextStateWireRead, clock, reset, b, loc, nextStateWireRead, clock, reset,
/*reset value=*/encoding->encode(machineOp.getInitialStateOp()), /*reset value=*/encoding->encode(machineOp.getInitialStateOp()),
"state_reg"); "state_reg");
@ -458,12 +459,12 @@ LogicalResult MachineOpConverter::dispatch() {
"for the initial value."; "for the initial value.";
Type varType = variableOp.getType(); Type varType = variableOp.getType();
auto varLoc = variableOp.getLoc(); auto varLoc = variableOp.getLoc();
auto varNextState = b.create<sv::RegOp>( auto varNextState = sv::RegOp::create(
varLoc, varType, b.getStringAttr(variableOp.getName() + "_next")); b, varLoc, varType, b.getStringAttr(variableOp.getName() + "_next"));
auto varResetVal = b.create<hw::ConstantOp>(varLoc, initValueAttr); auto varResetVal = hw::ConstantOp::create(b, varLoc, initValueAttr);
auto variableReg = b.create<seq::CompRegOp>( auto variableReg = seq::CompRegOp::create(
varLoc, b.create<sv::ReadInOutOp>(varLoc, varNextState), clock, reset, b, varLoc, sv::ReadInOutOp::create(b, varLoc, varNextState), clock,
varResetVal, b.getStringAttr(variableOp.getName() + "_reg")); reset, varResetVal, b.getStringAttr(variableOp.getName() + "_reg"));
variableToRegister[variableOp] = variableReg; variableToRegister[variableOp] = variableReg;
variableNextStateWires[variableOp] = varNextState; variableNextStateWires[variableOp] = varNextState;
// Postpone value replacement until all logic has been created. // Postpone value replacement until all logic has been created.
@ -500,8 +501,8 @@ LogicalResult MachineOpConverter::dispatch() {
continue; continue;
auto outputPortType = port.type; auto outputPortType = port.type;
CaseMuxItem outputAssignment; CaseMuxItem outputAssignment;
outputAssignment.wire = b.create<sv::RegOp>( outputAssignment.wire = sv::RegOp::create(
machineOp.getLoc(), outputPortType, b, machineOp.getLoc(), outputPortType,
b.getStringAttr("output_" + std::to_string(portIndex))); b.getStringAttr("output_" + std::to_string(portIndex)));
outputAssignment.select = stateReg; outputAssignment.select = stateReg;
for (auto &state : orderedStates) for (auto &state : orderedStates)
@ -563,7 +564,7 @@ LogicalResult MachineOpConverter::dispatch() {
outputCaseAssignments.end()); outputCaseAssignments.end());
{ {
auto alwaysCombOp = b.create<sv::AlwaysCombOp>(loc); auto alwaysCombOp = sv::AlwaysCombOp::create(b, loc);
OpBuilder::InsertionGuard g(b); OpBuilder::InsertionGuard g(b);
b.setInsertionPointToStart(alwaysCombOp.getBodyBlock()); b.setInsertionPointToStart(alwaysCombOp.getBodyBlock());
buildStateCaseMux(nextStateCaseAssignments); buildStateCaseMux(nextStateCaseAssignments);
@ -577,12 +578,12 @@ LogicalResult MachineOpConverter::dispatch() {
llvm::SmallVector<Value> outputPortAssignments; llvm::SmallVector<Value> outputPortAssignments;
for (auto outputAssignment : outputCaseAssignments) for (auto outputAssignment : outputCaseAssignments)
outputPortAssignments.push_back( outputPortAssignments.push_back(
b.create<sv::ReadInOutOp>(machineOp.getLoc(), outputAssignment.wire)); sv::ReadInOutOp::create(b, machineOp.getLoc(), outputAssignment.wire));
// Delete the default created output op and replace it with the output // Delete the default created output op and replace it with the output
// muxes. // muxes.
auto *oldOutputOp = hwModuleOp.getBodyBlock()->getTerminator(); auto *oldOutputOp = hwModuleOp.getBodyBlock()->getTerminator();
b.create<hw::OutputOp>(loc, outputPortAssignments); hw::OutputOp::create(b, loc, outputPortAssignments);
oldOutputOp->erase(); oldOutputOp->erase();
// Erase the original machine op. // Erase the original machine op.
@ -640,8 +641,8 @@ MachineOpConverter::convertTransitions( // NOLINT(misc-no-recursion)
convertTransitions(currentState, transitions.drop_front()); convertTransitions(currentState, transitions.drop_front());
if (failed(otherNextState)) if (failed(otherNextState))
return failure(); return failure();
comb::MuxOp nextStateMux = b.create<comb::MuxOp>( comb::MuxOp nextStateMux = comb::MuxOp::create(
transition.getLoc(), guard, nextState, *otherNextState, false); b, transition.getLoc(), guard, nextState, *otherNextState, false);
nextState = nextStateMux; nextState = nextStateMux;
} }
} }
@ -707,15 +708,15 @@ void FSMToSVPass::runOnOperation() {
// typedefs. // typedefs.
b.setInsertionPointToStart(module.getBody()); b.setInsertionPointToStart(module.getBody());
hw::TypeScopeOp typeScope = hw::TypeScopeOp typeScope =
b.create<hw::TypeScopeOp>(loc, b.getStringAttr("fsm_enum_typedecls")); hw::TypeScopeOp::create(b, loc, b.getStringAttr("fsm_enum_typedecls"));
typeScope.getBodyRegion().push_back(new Block()); typeScope.getBodyRegion().push_back(new Block());
auto file = b.create<emit::FileOp>(loc, "fsm_enum_typedefs.sv", [&] { auto file = emit::FileOp::create(b, loc, "fsm_enum_typedefs.sv", [&] {
b.create<emit::RefOp>(loc, emit::RefOp::create(b, loc,
FlatSymbolRefAttr::get(typeScope.getSymNameAttr())); FlatSymbolRefAttr::get(typeScope.getSymNameAttr()));
}); });
auto fragment = b.create<emit::FragmentOp>(loc, "FSM_ENUM_TYPEDEFS", [&] { auto fragment = emit::FragmentOp::create(b, loc, "FSM_ENUM_TYPEDEFS", [&] {
b.create<sv::VerbatimOp>(loc, "`include \"" + file.getFileName() + "\""); sv::VerbatimOp::create(b, loc, "`include \"" + file.getFileName() + "\"");
}); });
auto headerName = FlatSymbolRefAttr::get(fragment.getSymNameAttr()); auto headerName = FlatSymbolRefAttr::get(fragment.getSymNameAttr());
@ -743,8 +744,8 @@ void FSMToSVPass::runOnOperation() {
llvm::SmallVector<Value, 4> operands; llvm::SmallVector<Value, 4> operands;
llvm::transform(instance.getOperands(), std::back_inserter(operands), llvm::transform(instance.getOperands(), std::back_inserter(operands),
[&](auto operand) { return operand; }); [&](auto operand) { return operand; });
auto hwInstance = b.create<hw::InstanceOp>( auto hwInstance = hw::InstanceOp::create(
instance.getLoc(), fsmHWModule, b.getStringAttr(instance.getName()), b, instance.getLoc(), fsmHWModule, b.getStringAttr(instance.getName()),
operands, nullptr); operands, nullptr);
instance.replaceAllUsesWith(hwInstance); instance.replaceAllUsesWith(hwInstance);
instance.erase(); instance.erase();

View File

@ -90,13 +90,13 @@ static Value extendTypeWidth(OpBuilder &builder, Location loc, Value value,
builder.createOrFold<comb::ReplicateOp>(loc, highBit, extensionLength); builder.createOrFold<comb::ReplicateOp>(loc, highBit, extensionLength);
} else { } else {
// Zero extension // Zero extension
extensionBits = builder extensionBits =
.create<hw::ConstantOp>( hw::ConstantOp::create(builder, loc,
loc, builder.getIntegerType(extensionLength), 0) builder.getIntegerType(extensionLength), 0)
->getOpResult(0); ->getOpResult(0);
} }
auto extOp = builder.create<comb::ConcatOp>(loc, extensionBits, value); auto extOp = comb::ConcatOp::create(builder, loc, extensionBits, value);
improveNamehint(value, extOp, [&](StringRef oldNamehint) { improveNamehint(value, extOp, [&](StringRef oldNamehint) {
return (oldNamehint + "_" + (signExtension ? "sext_" : "zext_") + return (oldNamehint + "_" + (signExtension ? "sext_" : "zext_") +
std::to_string(targetWidth)) std::to_string(targetWidth))
@ -210,10 +210,10 @@ struct DivOpLowering : public OpConversionPattern<DivOp> {
Value divResult; Value divResult;
if (signedDivision) if (signedDivision)
divResult = rewriter.create<comb::DivSOp>(loc, lhsValue, rhsValue, false) divResult = comb::DivSOp::create(rewriter, loc, lhsValue, rhsValue, false)
->getOpResult(0); ->getOpResult(0);
else else
divResult = rewriter.create<comb::DivUOp>(loc, lhsValue, rhsValue, false) divResult = comb::DivUOp::create(rewriter, loc, lhsValue, rhsValue, false)
->getOpResult(0); ->getOpResult(0);
// Carry over any attributes from the original div op. // Carry over any attributes from the original div op.
@ -313,8 +313,8 @@ struct ICmpOpLowering : public OpConversionPattern<ICmpOp> {
Value rhsValue = extendTypeWidth(rewriter, loc, adaptor.getRhs(), cmpWidth, Value rhsValue = extendTypeWidth(rewriter, loc, adaptor.getRhs(), cmpWidth,
rhsType.isSigned()); rhsType.isSigned());
auto newOp = rewriter.create<comb::ICmpOp>(op->getLoc(), combPred, lhsValue, auto newOp = comb::ICmpOp::create(rewriter, op->getLoc(), combPred,
rhsValue, false); lhsValue, rhsValue, false);
rewriter.modifyOpInPlace( rewriter.modifyOpInPlace(
newOp, [&]() { newOp->setDialectAttrs(op->getDialectAttrs()); }); newOp, [&]() { newOp->setDialectAttrs(op->getDialectAttrs()); });
rewriter.replaceOp(op, newOp); rewriter.replaceOp(op, newOp);
@ -343,7 +343,7 @@ struct BinaryOpLowering : public OpConversionPattern<BinOp> {
Value rhsValue = extendTypeWidth(rewriter, loc, adaptor.getInputs()[1], Value rhsValue = extendTypeWidth(rewriter, loc, adaptor.getInputs()[1],
targetWidth, isRhsTypeSigned); targetWidth, isRhsTypeSigned);
auto newOp = auto newOp =
rewriter.create<ReplaceOp>(op.getLoc(), lhsValue, rhsValue, false); ReplaceOp::create(rewriter, op.getLoc(), lhsValue, rhsValue, false);
rewriter.modifyOpInPlace( rewriter.modifyOpInPlace(
newOp, [&]() { newOp->setDialectAttrs(op->getDialectAttrs()); }); newOp, [&]() { newOp->setDialectAttrs(op->getDialectAttrs()); });
rewriter.replaceOp(op, newOp); rewriter.replaceOp(op, newOp);
@ -404,8 +404,8 @@ HWArithToHWTypeConverter::HWArithToHWTypeConverter() {
mlir::Location loc) -> mlir::Value { mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
@ -414,8 +414,8 @@ HWArithToHWTypeConverter::HWArithToHWTypeConverter() {
mlir::Location loc) -> mlir::Value { mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
} }

View File

@ -76,7 +76,7 @@ static Value zextByOne(Location loc, ConversionPatternRewriter &rewriter,
auto valueTy = value.getType(); auto valueTy = value.getType();
auto zextTy = IntegerType::get(valueTy.getContext(), auto zextTy = IntegerType::get(valueTy.getContext(),
valueTy.getIntOrFloatBitWidth() + 1); valueTy.getIntOrFloatBitWidth() + 1);
return rewriter.create<LLVM::ZExtOp>(loc, zextTy, value); return LLVM::ZExtOp::create(rewriter, loc, zextTy, value);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -103,8 +103,8 @@ struct StructExplodeOpConversion
.size(); .size();
i < e; ++i) i < e; ++i)
replacements.push_back(rewriter.create<LLVM::ExtractValueOp>( replacements.push_back(LLVM::ExtractValueOp::create(
op->getLoc(), adaptor.getInput(), rewriter, op->getLoc(), adaptor.getInput(),
HWToLLVMEndianessConverter::convertToLLVMEndianess( HWToLLVMEndianessConverter::convertToLLVMEndianess(
op.getInput().getType(), i))); op.getInput().getType(), i)));
@ -152,14 +152,15 @@ struct ArrayGetOpConversion : public ConvertOpToLLVMPattern<hw::ArrayGetOp> {
// just grab that address instead of reallocating the array on the stack. // just grab that address instead of reallocating the array on the stack.
arrPtr = load.getAddr(); arrPtr = load.getAddr();
} else { } else {
auto oneC = rewriter.create<LLVM::ConstantOp>( auto oneC = LLVM::ConstantOp::create(
op->getLoc(), IntegerType::get(rewriter.getContext(), 32), rewriter, op->getLoc(), IntegerType::get(rewriter.getContext(), 32),
rewriter.getI32IntegerAttr(1)); rewriter.getI32IntegerAttr(1));
arrPtr = rewriter.create<LLVM::AllocaOp>( arrPtr = LLVM::AllocaOp::create(
op->getLoc(), LLVM::LLVMPointerType::get(rewriter.getContext()), rewriter, op->getLoc(),
LLVM::LLVMPointerType::get(rewriter.getContext()),
adaptor.getInput().getType(), oneC, adaptor.getInput().getType(), oneC,
/*alignment=*/4); /*alignment=*/4);
rewriter.create<LLVM::StoreOp>(op->getLoc(), adaptor.getInput(), arrPtr); LLVM::StoreOp::create(rewriter, op->getLoc(), adaptor.getInput(), arrPtr);
} }
auto arrTy = typeConverter->convertType(op.getInput().getType()); auto arrTy = typeConverter->convertType(op.getInput().getType());
@ -169,9 +170,10 @@ struct ArrayGetOpConversion : public ConvertOpToLLVMPattern<hw::ArrayGetOp> {
// During the ongoing migration to opaque types, use the constructor that // During the ongoing migration to opaque types, use the constructor that
// accepts an element type when the array pointer type is opaque, and // accepts an element type when the array pointer type is opaque, and
// otherwise use the typed pointer constructor. // otherwise use the typed pointer constructor.
auto gep = rewriter.create<LLVM::GEPOp>( auto gep = LLVM::GEPOp::create(
op->getLoc(), LLVM::LLVMPointerType::get(rewriter.getContext()), arrTy, rewriter, op->getLoc(),
arrPtr, ArrayRef<LLVM::GEPArg>{0, zextIndex}); LLVM::LLVMPointerType::get(rewriter.getContext()), arrTy, arrPtr,
ArrayRef<LLVM::GEPArg>{0, zextIndex});
rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, elemTy, gep); rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, elemTy, gep);
return success(); return success();
@ -193,24 +195,27 @@ struct ArraySliceOpConversion
auto dstTy = typeConverter->convertType(op.getDst().getType()); auto dstTy = typeConverter->convertType(op.getDst().getType());
auto oneC = rewriter.create<LLVM::ConstantOp>( auto oneC =
op->getLoc(), rewriter.getI32Type(), rewriter.getI32IntegerAttr(1)); LLVM::ConstantOp::create(rewriter, op->getLoc(), rewriter.getI32Type(),
rewriter.getI32IntegerAttr(1));
auto arrPtr = rewriter.create<LLVM::AllocaOp>( auto arrPtr = LLVM::AllocaOp::create(
op->getLoc(), LLVM::LLVMPointerType::get(rewriter.getContext()), rewriter, op->getLoc(),
LLVM::LLVMPointerType::get(rewriter.getContext()),
adaptor.getInput().getType(), oneC, adaptor.getInput().getType(), oneC,
/*alignment=*/4); /*alignment=*/4);
rewriter.create<LLVM::StoreOp>(op->getLoc(), adaptor.getInput(), arrPtr); LLVM::StoreOp::create(rewriter, op->getLoc(), adaptor.getInput(), arrPtr);
auto zextIndex = zextByOne(op->getLoc(), rewriter, op.getLowIndex()); auto zextIndex = zextByOne(op->getLoc(), rewriter, op.getLowIndex());
// During the ongoing migration to opaque types, use the constructor that // During the ongoing migration to opaque types, use the constructor that
// accepts an element type when the array pointer type is opaque, and // accepts an element type when the array pointer type is opaque, and
// otherwise use the typed pointer constructor. // otherwise use the typed pointer constructor.
auto gep = rewriter.create<LLVM::GEPOp>( auto gep = LLVM::GEPOp::create(
op->getLoc(), LLVM::LLVMPointerType::get(rewriter.getContext()), dstTy, rewriter, op->getLoc(),
arrPtr, ArrayRef<LLVM::GEPArg>{0, zextIndex}); LLVM::LLVMPointerType::get(rewriter.getContext()), dstTy, arrPtr,
ArrayRef<LLVM::GEPArg>{0, zextIndex});
rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, dstTy, gep); rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, dstTy, gep);
@ -263,15 +268,16 @@ struct ArrayConcatOpConversion
hw::ArrayType arrTy = cast<hw::ArrayType>(op.getResult().getType()); hw::ArrayType arrTy = cast<hw::ArrayType>(op.getResult().getType());
Type resultTy = typeConverter->convertType(arrTy); Type resultTy = typeConverter->convertType(arrTy);
Value arr = rewriter.create<LLVM::UndefOp>(op->getLoc(), resultTy); Value arr = LLVM::UndefOp::create(rewriter, op->getLoc(), resultTy);
// Attention: j is hardcoded for little endian machines. // Attention: j is hardcoded for little endian machines.
size_t j = op.getInputs().size() - 1, k = 0; size_t j = op.getInputs().size() - 1, k = 0;
for (size_t i = 0, e = arrTy.getNumElements(); i < e; ++i) { for (size_t i = 0, e = arrTy.getNumElements(); i < e; ++i) {
Value element = rewriter.create<LLVM::ExtractValueOp>( Value element = LLVM::ExtractValueOp::create(rewriter, op->getLoc(),
op->getLoc(), adaptor.getInputs()[j], k); adaptor.getInputs()[j], k);
arr = rewriter.create<LLVM::InsertValueOp>(op->getLoc(), arr, element, i); arr =
LLVM::InsertValueOp::create(rewriter, op->getLoc(), arr, element, i);
++k; ++k;
if (k >= if (k >=
@ -308,12 +314,13 @@ struct BitcastOpConversion : public ConvertOpToLLVMPattern<hw::BitcastOp> {
auto oneC = rewriter.createOrFold<LLVM::ConstantOp>( auto oneC = rewriter.createOrFold<LLVM::ConstantOp>(
op->getLoc(), rewriter.getI32Type(), rewriter.getI32IntegerAttr(1)); op->getLoc(), rewriter.getI32Type(), rewriter.getI32IntegerAttr(1));
auto ptr = rewriter.create<LLVM::AllocaOp>( auto ptr = LLVM::AllocaOp::create(
op->getLoc(), LLVM::LLVMPointerType::get(rewriter.getContext()), rewriter, op->getLoc(),
LLVM::LLVMPointerType::get(rewriter.getContext()),
adaptor.getInput().getType(), oneC, adaptor.getInput().getType(), oneC,
/*alignment=*/4); /*alignment=*/4);
rewriter.create<LLVM::StoreOp>(op->getLoc(), adaptor.getInput(), ptr); LLVM::StoreOp::create(rewriter, op->getLoc(), adaptor.getInput(), ptr);
rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, resultTy, ptr); rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, resultTy, ptr);
@ -362,13 +369,13 @@ struct HWDynamicArrayCreateOpConversion
auto arrayTy = typeConverter->convertType(op->getResult(0).getType()); auto arrayTy = typeConverter->convertType(op->getResult(0).getType());
assert(arrayTy); assert(arrayTy);
Value arr = rewriter.create<LLVM::UndefOp>(op->getLoc(), arrayTy); Value arr = LLVM::UndefOp::create(rewriter, op->getLoc(), arrayTy);
for (size_t i = 0, e = op.getInputs().size(); i < e; ++i) { for (size_t i = 0, e = op.getInputs().size(); i < e; ++i) {
Value input = Value input =
adaptor adaptor
.getInputs()[HWToLLVMEndianessConverter::convertToLLVMEndianess( .getInputs()[HWToLLVMEndianessConverter::convertToLLVMEndianess(
op.getResult().getType(), i)]; op.getResult().getType(), i)];
arr = rewriter.create<LLVM::InsertValueOp>(op->getLoc(), arr, input, i); arr = LLVM::InsertValueOp::create(rewriter, op->getLoc(), arr, input, i);
} }
rewriter.replaceOp(op, arr); rewriter.replaceOp(op, arr);
@ -430,13 +437,13 @@ struct HWStructCreateOpConversion
auto resTy = typeConverter->convertType(op.getResult().getType()); auto resTy = typeConverter->convertType(op.getResult().getType());
Value tup = rewriter.create<LLVM::UndefOp>(op->getLoc(), resTy); Value tup = LLVM::UndefOp::create(rewriter, op->getLoc(), resTy);
for (size_t i = 0, e = cast<LLVM::LLVMStructType>(resTy).getBody().size(); for (size_t i = 0, e = cast<LLVM::LLVMStructType>(resTy).getBody().size();
i < e; ++i) { i < e; ++i) {
Value input = Value input =
adaptor.getInput()[HWToLLVMEndianessConverter::convertToLLVMEndianess( adaptor.getInput()[HWToLLVMEndianessConverter::convertToLLVMEndianess(
op.getResult().getType(), i)]; op.getResult().getType(), i)];
tup = rewriter.create<LLVM::InsertValueOp>(op->getLoc(), tup, input, i); tup = LLVM::InsertValueOp::create(rewriter, op->getLoc(), tup, input, i);
} }
rewriter.replaceOp(op, tup); rewriter.replaceOp(op, tup);
@ -517,10 +524,10 @@ Value AggregateConstantOpConversion::constructAggregate(
return TypeSwitch<Type, Value>(type) return TypeSwitch<Type, Value>(type)
.Case<IntegerType>([&](auto ty) { .Case<IntegerType>([&](auto ty) {
return builder.create<LLVM::ConstantOp>(loc, cast<TypedAttr>(data)); return LLVM::ConstantOp::create(builder, loc, cast<TypedAttr>(data));
}) })
.Case<hw::ArrayType, hw::StructType>([&](auto ty) { .Case<hw::ArrayType, hw::StructType>([&](auto ty) {
Value aggVal = builder.create<LLVM::UndefOp>(loc, llvmType); Value aggVal = LLVM::UndefOp::create(builder, loc, llvmType);
auto arrayAttr = cast<ArrayAttr>(data); auto arrayAttr = cast<ArrayAttr>(data);
for (size_t i = 0, e = arrayAttr.size(); i < e; ++i) { for (size_t i = 0, e = arrayAttr.size(); i < e; ++i) {
size_t currIdx = size_t currIdx =
@ -530,7 +537,8 @@ Value AggregateConstantOpConversion::constructAggregate(
Value element = constructAggregate(builder, typeConverter, loc, Value element = constructAggregate(builder, typeConverter, loc,
elementType, input); elementType, input);
aggVal = builder.create<LLVM::InsertValueOp>(loc, aggVal, element, i); aggVal =
LLVM::InsertValueOp::create(builder, loc, aggVal, element, i);
} }
return aggVal; return aggVal;
@ -572,12 +580,13 @@ LogicalResult AggregateConstantOpConversion::matchAndRewrite(
dims, cast<IntegerAttr>(ints.front()).getType()); dims, cast<IntegerAttr>(ints.front()).getType());
auto denseAttr = DenseElementsAttr::get(shapedType, ints); auto denseAttr = DenseElementsAttr::get(shapedType, ints);
constAggregateGlobalsMap[typeAttrPair] = rewriter.create<LLVM::GlobalOp>( constAggregateGlobalsMap[typeAttrPair] =
op.getLoc(), llvmTy, true, LLVM::Linkage::Internal, name, denseAttr); LLVM::GlobalOp::create(rewriter, op.getLoc(), llvmTy, true,
LLVM::Linkage::Internal, name, denseAttr);
} else { } else {
auto global = rewriter.create<LLVM::GlobalOp>(op.getLoc(), llvmTy, false, auto global =
LLVM::Linkage::Internal, LLVM::GlobalOp::create(rewriter, op.getLoc(), llvmTy, false,
name, Attribute()); LLVM::Linkage::Internal, name, Attribute());
Block *blk = new Block(); Block *blk = new Block();
global.getInitializerRegion().push_back(blk); global.getInitializerRegion().push_back(blk);
rewriter.setInsertionPointToStart(blk); rewriter.setInsertionPointToStart(blk);
@ -585,7 +594,7 @@ LogicalResult AggregateConstantOpConversion::matchAndRewrite(
Value aggregate = Value aggregate =
constructAggregate(rewriter, *typeConverter, op.getLoc(), constructAggregate(rewriter, *typeConverter, op.getLoc(),
aggregateType, adaptor.getFields()); aggregateType, adaptor.getFields());
rewriter.create<LLVM::ReturnOp>(op.getLoc(), aggregate); LLVM::ReturnOp::create(rewriter, op.getLoc(), aggregate);
constAggregateGlobalsMap[typeAttrPair] = global; constAggregateGlobalsMap[typeAttrPair] = global;
} }
@ -593,8 +602,8 @@ LogicalResult AggregateConstantOpConversion::matchAndRewrite(
} }
// Get the global array address and load it to return an array value. // Get the global array address and load it to return an array value.
auto addr = rewriter.create<LLVM::AddressOfOp>( auto addr = LLVM::AddressOfOp::create(rewriter, op->getLoc(),
op->getLoc(), constAggregateGlobalsMap[typeAttrPair]); constAggregateGlobalsMap[typeAttrPair]);
rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, llvmTy, addr); rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, llvmTy, addr);
return success(); return success();

View File

@ -59,8 +59,8 @@ struct HWModuleOpConversion : OpConversionPattern<HWModuleOp> {
return failure(); return failure();
if (failed(rewriter.convertRegionTypes(&op.getBody(), *typeConverter))) if (failed(rewriter.convertRegionTypes(&op.getBody(), *typeConverter)))
return failure(); return failure();
auto funcOp = rewriter.create<mlir::func::FuncOp>( auto funcOp = mlir::func::FuncOp::create(
op.getLoc(), adaptor.getSymNameAttr(), rewriter, op.getLoc(), adaptor.getSymNameAttr(),
rewriter.getFunctionType(inputTypes, resultTypes)); rewriter.getFunctionType(inputTypes, resultTypes));
rewriter.inlineRegionBefore(op.getBody(), funcOp.getBody(), funcOp.end()); rewriter.inlineRegionBefore(op.getBody(), funcOp.getBody(), funcOp.end());
rewriter.eraseOp(op); rewriter.eraseOp(op);
@ -112,11 +112,11 @@ struct ArrayCreateOpConversion : OpConversionPattern<ArrayCreateOp> {
unsigned width = adaptor.getInputs().size(); unsigned width = adaptor.getInputs().size();
Value arr = rewriter.create<mlir::smt::DeclareFunOp>(loc, arrTy); Value arr = mlir::smt::DeclareFunOp::create(rewriter, loc, arrTy);
for (auto [i, el] : llvm::enumerate(adaptor.getInputs())) { for (auto [i, el] : llvm::enumerate(adaptor.getInputs())) {
Value idx = rewriter.create<mlir::smt::BVConstantOp>( Value idx = mlir::smt::BVConstantOp::create(rewriter, loc, width - i - 1,
loc, width - i - 1, llvm::Log2_64_Ceil(width)); llvm::Log2_64_Ceil(width));
arr = rewriter.create<mlir::smt::ArrayStoreOp>(loc, arr, idx, el); arr = mlir::smt::ArrayStoreOp::create(rewriter, loc, arr, idx, el);
} }
rewriter.replaceOp(op, arr); rewriter.replaceOp(op, arr);
@ -140,14 +140,14 @@ struct ArrayGetOpConversion : OpConversionPattern<ArrayGetOp> {
return rewriter.notifyMatchFailure(op.getLoc(), return rewriter.notifyMatchFailure(op.getLoc(),
"unsupported array element type"); "unsupported array element type");
Value oobVal = rewriter.create<mlir::smt::DeclareFunOp>(loc, type); Value oobVal = mlir::smt::DeclareFunOp::create(rewriter, loc, type);
Value numElementsVal = rewriter.create<mlir::smt::BVConstantOp>( Value numElementsVal = mlir::smt::BVConstantOp::create(
loc, numElements - 1, llvm::Log2_64_Ceil(numElements)); rewriter, loc, numElements - 1, llvm::Log2_64_Ceil(numElements));
Value inBounds = Value inBounds = mlir::smt::BVCmpOp::create(
rewriter.create<mlir::smt::BVCmpOp>(loc, mlir::smt::BVCmpPredicate::ule, rewriter, loc, mlir::smt::BVCmpPredicate::ule, adaptor.getIndex(),
adaptor.getIndex(), numElementsVal); numElementsVal);
Value indexed = rewriter.create<mlir::smt::ArraySelectOp>( Value indexed = mlir::smt::ArraySelectOp::create(
loc, adaptor.getInput(), adaptor.getIndex()); rewriter, loc, adaptor.getInput(), adaptor.getIndex());
rewriter.replaceOpWithNewOp<mlir::smt::IteOp>(op, inBounds, indexed, rewriter.replaceOpWithNewOp<mlir::smt::IteOp>(op, inBounds, indexed,
oobVal); oobVal);
return success(); return success();
@ -170,15 +170,16 @@ struct ArrayInjectOpConversion : OpConversionPattern<ArrayInjectOp> {
return rewriter.notifyMatchFailure(op.getLoc(), "unsupported array type"); return rewriter.notifyMatchFailure(op.getLoc(), "unsupported array type");
// Check if the index is within bounds // Check if the index is within bounds
Value numElementsVal = rewriter.create<mlir::smt::BVConstantOp>( Value numElementsVal = mlir::smt::BVConstantOp::create(
loc, numElements - 1, llvm::Log2_64_Ceil(numElements)); rewriter, loc, numElements - 1, llvm::Log2_64_Ceil(numElements));
Value inBounds = Value inBounds = mlir::smt::BVCmpOp::create(
rewriter.create<mlir::smt::BVCmpOp>(loc, mlir::smt::BVCmpPredicate::ule, rewriter, loc, mlir::smt::BVCmpPredicate::ule, adaptor.getIndex(),
adaptor.getIndex(), numElementsVal); numElementsVal);
// Store the element at the given index // Store the element at the given index
Value stored = rewriter.create<mlir::smt::ArrayStoreOp>( Value stored = mlir::smt::ArrayStoreOp::create(
loc, adaptor.getInput(), adaptor.getIndex(), adaptor.getElement()); rewriter, loc, adaptor.getInput(), adaptor.getIndex(),
adaptor.getElement());
// Return the original array if out of bounds, otherwise return the new // Return the original array if out of bounds, otherwise return the new
// array // array
@ -245,8 +246,8 @@ void circt::populateHWToSMTTypeConverter(TypeConverter &converter) {
converter.addTargetMaterialization([&](OpBuilder &builder, Type resultType, converter.addTargetMaterialization([&](OpBuilder &builder, Type resultType,
ValueRange inputs, ValueRange inputs,
Location loc) -> Value { Location loc) -> Value {
return builder return mlir::UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<mlir::UnrealizedConversionCastOp>(loc, resultType, inputs) inputs)
->getResult(0); ->getResult(0);
}); });
@ -262,10 +263,11 @@ void circt::populateHWToSMTTypeConverter(TypeConverter &converter) {
unsigned width = resultType.getWidth(); unsigned width = resultType.getWidth();
Value constZero = Value constZero =
builder.create<mlir::smt::BVConstantOp>(loc, 0, width); mlir::smt::BVConstantOp::create(builder, loc, 0, width);
Value constOne = builder.create<mlir::smt::BVConstantOp>(loc, 1, width); Value constOne =
return builder.create<mlir::smt::IteOp>(loc, inputs[0], constOne, mlir::smt::BVConstantOp::create(builder, loc, 1, width);
constZero); return mlir::smt::IteOp::create(builder, loc, inputs[0], constOne,
constZero);
}); });
// Convert an unrealized conversion cast from 'smt.bool' to i1 // Convert an unrealized conversion cast from 'smt.bool' to i1
@ -288,10 +290,10 @@ void circt::populateHWToSMTTypeConverter(TypeConverter &converter) {
if (!isa<mlir::smt::BoolType>(castOp.getInputs()[0].getType())) if (!isa<mlir::smt::BoolType>(castOp.getInputs()[0].getType()))
return Value(); return Value();
Value constZero = builder.create<mlir::smt::BVConstantOp>(loc, 0, 1); Value constZero = mlir::smt::BVConstantOp::create(builder, loc, 0, 1);
Value constOne = builder.create<mlir::smt::BVConstantOp>(loc, 1, 1); Value constOne = mlir::smt::BVConstantOp::create(builder, loc, 1, 1);
return builder.create<mlir::smt::IteOp>(loc, castOp.getInputs()[0], return mlir::smt::IteOp::create(builder, loc, castOp.getInputs()[0],
constOne, constZero); constOne, constZero);
}); });
// Convert a 'smt.bv<1>'-typed value to a 'smt.bool'-typed value // Convert a 'smt.bv<1>'-typed value to a 'smt.bool'-typed value
@ -305,8 +307,8 @@ void circt::populateHWToSMTTypeConverter(TypeConverter &converter) {
if (!bvType || bvType.getWidth() != 1) if (!bvType || bvType.getWidth() != 1)
return Value(); return Value();
Value constOne = builder.create<mlir::smt::BVConstantOp>(loc, 1, 1); Value constOne = mlir::smt::BVConstantOp::create(builder, loc, 1, 1);
return builder.create<mlir::smt::EqOp>(loc, inputs[0], constOne); return mlir::smt::EqOp::create(builder, loc, inputs[0], constOne);
}); });
// Default source materialization to convert from illegal types to legal // Default source materialization to convert from illegal types to legal
@ -314,8 +316,8 @@ void circt::populateHWToSMTTypeConverter(TypeConverter &converter) {
converter.addSourceMaterialization([&](OpBuilder &builder, Type resultType, converter.addSourceMaterialization([&](OpBuilder &builder, Type resultType,
ValueRange inputs, ValueRange inputs,
Location loc) -> Value { Location loc) -> Value {
return builder return mlir::UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<mlir::UnrealizedConversionCastOp>(loc, resultType, inputs) inputs)
->getResult(0); ->getResult(0);
}); });
} }

View File

@ -50,8 +50,8 @@ struct TriggeredOpConversionPattern : public OpConversionPattern<TriggeredOp> {
LogicalResult LogicalResult
matchAndRewrite(TriggeredOp op, OpAdaptor operands, matchAndRewrite(TriggeredOp op, OpAdaptor operands,
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
auto alwaysOp = rewriter.create<AlwaysOp>( auto alwaysOp = AlwaysOp::create(
op.getLoc(), rewriter, op.getLoc(),
llvm::SmallVector<sv::EventControl>{hwToSvEventControl(op.getEvent())}, llvm::SmallVector<sv::EventControl>{hwToSvEventControl(op.getEvent())},
llvm::SmallVector<Value>{op.getTrigger()}); llvm::SmallVector<Value>{op.getTrigger()});
rewriter.mergeBlocks(op.getBodyBlock(), alwaysOp.getBodyBlock(), rewriter.mergeBlocks(op.getBodyBlock(), alwaysOp.getBodyBlock(),

View File

@ -58,8 +58,8 @@ struct ConvertHWModule : public OpConversionPattern<HWModuleOp> {
for (size_t i = 0; i < ports.size(); ++i) for (size_t i = 0; i < ports.size(); ++i)
ports[i].type = typeConverter->convertType(ports[i].type); ports[i].type = typeConverter->convertType(ports[i].type);
auto scModule = rewriter.create<SCModuleOp>(module.getLoc(), auto scModule = SCModuleOp::create(rewriter, module.getLoc(),
module.getNameAttr(), ports); module.getNameAttr(), ports);
auto *outputOp = module.getBodyBlock()->getTerminator(); auto *outputOp = module.getBodyBlock()->getTerminator();
scModule.setVisibility(module.getVisibility()); scModule.setVisibility(module.getVisibility());
@ -70,8 +70,8 @@ struct ConvertHWModule : public OpConversionPattern<HWModuleOp> {
// Create a systemc.func operation inside the module after the ctor. // Create a systemc.func operation inside the module after the ctor.
// TODO: implement logic to extract a better name and properly unique it. // TODO: implement logic to extract a better name and properly unique it.
rewriter.setInsertionPointToStart(scModule.getBodyBlock()); rewriter.setInsertionPointToStart(scModule.getBodyBlock());
auto scFunc = rewriter.create<SCFuncOp>( auto scFunc = SCFuncOp::create(rewriter, module.getLoc(),
module.getLoc(), rewriter.getStringAttr("innerLogic")); rewriter.getStringAttr("innerLogic"));
// Inline the HW module body into the systemc.func body. // Inline the HW module body into the systemc.func body.
// TODO: do some dominance analysis to detect use-before-def and cycles in // TODO: do some dominance analysis to detect use-before-def and cycles in
@ -84,7 +84,7 @@ struct ConvertHWModule : public OpConversionPattern<HWModuleOp> {
// Register the systemc.func inside the systemc.ctor // Register the systemc.func inside the systemc.ctor
rewriter.setInsertionPointToStart( rewriter.setInsertionPointToStart(
scModule.getOrCreateCtor().getBodyBlock()); scModule.getOrCreateCtor().getBodyBlock());
rewriter.create<MethodOp>(scModule.getLoc(), scFunc.getHandle()); MethodOp::create(rewriter, scModule.getLoc(), scFunc.getHandle());
// Register the sensitivities of above SC_METHOD registration. // Register the sensitivities of above SC_METHOD registration.
SmallVector<Value> sensitivityValues( SmallVector<Value> sensitivityValues(
@ -92,17 +92,16 @@ struct ConvertHWModule : public OpConversionPattern<HWModuleOp> {
return !isa<OutputType>(arg.getType()); return !isa<OutputType>(arg.getType());
})); }));
if (!sensitivityValues.empty()) if (!sensitivityValues.empty())
rewriter.create<SensitiveOp>(scModule.getLoc(), sensitivityValues); SensitiveOp::create(rewriter, scModule.getLoc(), sensitivityValues);
// Move the block arguments of the systemc.func (that we got from the // Move the block arguments of the systemc.func (that we got from the
// hw.module) to the systemc.module // hw.module) to the systemc.module
rewriter.setInsertionPointToStart(scFunc.getBodyBlock()); rewriter.setInsertionPointToStart(scFunc.getBodyBlock());
auto portsLocal = module.getPortList(); auto portsLocal = module.getPortList();
for (size_t i = 0, e = scFunc.getRegion().getNumArguments(); i < e; ++i) { for (size_t i = 0, e = scFunc.getRegion().getNumArguments(); i < e; ++i) {
auto inputRead = auto inputRead = SignalReadOp::create(rewriter, scFunc.getLoc(),
rewriter scModule.getArgument(i))
.create<SignalReadOp>(scFunc.getLoc(), scModule.getArgument(i)) .getResult();
.getResult();
auto converted = typeConverter->materializeSourceConversion( auto converted = typeConverter->materializeSourceConversion(
rewriter, scModule.getLoc(), portsLocal[i].type, inputRead); rewriter, scModule.getLoc(), portsLocal[i].type, inputRead);
scFuncBody.getArgument(0).replaceAllUsesWith(converted); scFuncBody.getArgument(0).replaceAllUsesWith(converted);
@ -124,7 +123,7 @@ struct ConvertHWModule : public OpConversionPattern<HWModuleOp> {
auto converted = typeConverter->materializeTargetConversion( auto converted = typeConverter->materializeTargetConversion(
rewriter, scModule.getLoc(), getSignalBaseType(portValue.getType()), rewriter, scModule.getLoc(), getSignalBaseType(portValue.getType()),
std::get<1>(args)); std::get<1>(args));
rewriter.create<SignalWriteOp>(outputOp->getLoc(), portValue, converted); SignalWriteOp::create(rewriter, outputOp->getLoc(), portValue, converted);
} }
// Erase the HW OutputOp. // Erase the HW OutputOp.
@ -192,8 +191,8 @@ public:
auto instModuleName = instanceOp.getModuleNameAttr(); auto instModuleName = instanceOp.getModuleNameAttr();
// Declare the instance. // Declare the instance.
auto instDecl = stateBuilder.create<InstanceDeclOp>( auto instDecl = InstanceDeclOp::create(stateBuilder, loc, instanceName,
loc, instanceName, instModuleName, portInfo); instModuleName, portInfo);
// Bind the input ports. // Bind the input ports.
for (size_t i = 0, numInputs = adaptor.getInputs().size(); i < numInputs; for (size_t i = 0, numInputs = adaptor.getInputs().size(); i < numInputs;
@ -206,16 +205,16 @@ public:
if (auto readOp = input.getDefiningOp<SignalReadOp>()) { if (auto readOp = input.getDefiningOp<SignalReadOp>()) {
// Use the read channel directly without adding an // Use the read channel directly without adding an
// intermediate signal. // intermediate signal.
initBuilder.create<BindPortOp>(loc, instDecl, portId, BindPortOp::create(initBuilder, loc, instDecl, portId,
readOp.getInput()); readOp.getInput());
continue; continue;
} }
// Otherwise, create an intermediate signal to bind the instance port to. // Otherwise, create an intermediate signal to bind the instance port to.
Type sigType = SignalType::get(getSignalBaseType(portInfo[i].type)); Type sigType = SignalType::get(getSignalBaseType(portInfo[i].type));
Value channel = stateBuilder.create<SignalOp>(loc, sigType, signalName); Value channel = SignalOp::create(stateBuilder, loc, sigType, signalName);
initBuilder.create<BindPortOp>(loc, instDecl, portId, channel); BindPortOp::create(initBuilder, loc, instDecl, portId, channel);
rewriter.create<SignalWriteOp>(loc, channel, input); SignalWriteOp::create(rewriter, loc, channel, input);
} }
// Bind the output ports. // Bind the output ports.
@ -236,8 +235,8 @@ public:
// we cannot insert multiple bind statements for one submodule port. // we cannot insert multiple bind statements for one submodule port.
// It is also necessary to bind it to an intermediate signal when it // It is also necessary to bind it to an intermediate signal when it
// has no uses as every port has to be bound to a channel. // has no uses as every port has to be bound to a channel.
initBuilder.create<BindPortOp>(loc, instDecl, portId, BindPortOp::create(initBuilder, loc, instDecl, portId,
writeOp.getDest()); writeOp.getDest());
writeOp->erase(); writeOp->erase();
continue; continue;
} }
@ -246,9 +245,9 @@ public:
// Otherwise, create an intermediate signal. // Otherwise, create an intermediate signal.
Type sigType = Type sigType =
SignalType::get(getSignalBaseType(portInfo[i + numInputs].type)); SignalType::get(getSignalBaseType(portInfo[i + numInputs].type));
Value channel = stateBuilder.create<SignalOp>(loc, sigType, signalName); Value channel = SignalOp::create(stateBuilder, loc, sigType, signalName);
initBuilder.create<BindPortOp>(loc, instDecl, portId, channel); BindPortOp::create(initBuilder, loc, instDecl, portId, channel);
auto instOut = rewriter.create<SignalReadOp>(loc, channel); auto instOut = SignalReadOp::create(rewriter, loc, channel);
output.replaceAllUsesWith(instOut); output.replaceAllUsesWith(instOut);
} }
@ -317,14 +316,14 @@ static void populateTypeConversion(TypeConverter &converter) {
converter.addSourceMaterialization( converter.addSourceMaterialization(
[](OpBuilder &builder, Type type, ValueRange values, Location loc) { [](OpBuilder &builder, Type type, ValueRange values, Location loc) {
assert(values.size() == 1); assert(values.size() == 1);
auto op = builder.create<ConvertOp>(loc, type, values[0]); auto op = ConvertOp::create(builder, loc, type, values[0]);
return op.getResult(); return op.getResult();
}); });
converter.addTargetMaterialization( converter.addTargetMaterialization(
[](OpBuilder &builder, Type type, ValueRange values, Location loc) { [](OpBuilder &builder, Type type, ValueRange values, Location loc) {
assert(values.size() == 1); assert(values.size() == 1);
auto op = builder.create<ConvertOp>(loc, type, values[0]); auto op = ConvertOp::create(builder, loc, type, values[0]);
return op.getResult(); return op.getResult();
}); });
} }
@ -353,7 +352,7 @@ void HWToSystemCPass::runOnOperation() {
// Create the include operation here to have exactly one 'systemc' include at // Create the include operation here to have exactly one 'systemc' include at
// the top instead of one per module. // the top instead of one per module.
OpBuilder builder(module.getRegion()); OpBuilder builder(module.getRegion());
builder.create<emitc::IncludeOp>(module->getLoc(), "systemc.h", true); emitc::IncludeOp::create(builder, module->getLoc(), "systemc.h", true);
ConversionTarget target(context); ConversionTarget target(context);
TypeConverter typeConverter; TypeConverter typeConverter;

View File

@ -54,7 +54,7 @@ struct DCTuple {
// Unpack a !dc.value<...> into a DCTuple. // Unpack a !dc.value<...> into a DCTuple.
static DCTuple unpack(OpBuilder &b, Value v) { static DCTuple unpack(OpBuilder &b, Value v) {
if (isa<dc::ValueType>(v.getType())) if (isa<dc::ValueType>(v.getType()))
return DCTuple(b.create<dc::UnpackOp>(v.getLoc(), v)); return DCTuple(dc::UnpackOp::create(b, v.getLoc(), v));
assert(isa<dc::TokenType>(v.getType()) && "Expected a dc::TokenType"); assert(isa<dc::TokenType>(v.getType()) && "Expected a dc::TokenType");
return DCTuple(v, {}); return DCTuple(v, {});
} }
@ -62,7 +62,7 @@ static DCTuple unpack(OpBuilder &b, Value v) {
static Value pack(OpBuilder &b, Value token, Value data = {}) { static Value pack(OpBuilder &b, Value token, Value data = {}) {
if (!data) if (!data)
return token; return token;
return b.create<dc::PackOp>(token.getLoc(), token, data); return dc::PackOp::create(b, token.getLoc(), token, data);
} }
// NOLINTNEXTLINE(misc-no-recursion) // NOLINTNEXTLINE(misc-no-recursion)
@ -113,8 +113,8 @@ public:
if (vt && !vt.getInnerType()) if (vt && !vt.getInnerType())
return pack(builder, inputs.front()); return pack(builder, inputs.front());
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
@ -134,8 +134,8 @@ public:
if (vt && !vt.getInnerType()) if (vt && !vt.getInnerType())
return pack(builder, inputs.front()); return pack(builder, inputs.front());
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
} }
@ -168,14 +168,14 @@ public:
auto data = unpack(rewriter, adaptor.getDataOperand()); auto data = unpack(rewriter, adaptor.getDataOperand());
// Join the token of the condition and the input. // Join the token of the condition and the input.
auto join = rewriter.create<dc::JoinOp>( auto join = dc::JoinOp::create(rewriter, op.getLoc(),
op.getLoc(), ValueRange{condition.token, data.token}); ValueRange{condition.token, data.token});
// Pack that together with the condition data. // Pack that together with the condition data.
auto packedCondition = pack(rewriter, join, condition.data); auto packedCondition = pack(rewriter, join, condition.data);
// Branch on the input data and the joined control input. // Branch on the input data and the joined control input.
auto branch = rewriter.create<dc::BranchOp>(op.getLoc(), packedCondition); auto branch = dc::BranchOp::create(rewriter, op.getLoc(), packedCondition);
// Pack the branch output tokens with the input data, and replace the uses. // Pack the branch output tokens with the input data, and replace the uses.
llvm::SmallVector<Value, 4> packed; llvm::SmallVector<Value, 4> packed;
@ -197,8 +197,8 @@ public:
matchAndRewrite(handshake::ForkOp op, OpAdaptor adaptor, matchAndRewrite(handshake::ForkOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
auto input = unpack(rewriter, adaptor.getOperand()); auto input = unpack(rewriter, adaptor.getOperand());
auto forkOut = rewriter.create<dc::ForkOp>(op.getLoc(), input.token, auto forkOut = dc::ForkOp::create(rewriter, op.getLoc(), input.token,
op.getNumResults()); op.getNumResults());
// Pack the fork result tokens with the input data, and replace the uses. // Pack the fork result tokens with the input data, and replace the uses.
llvm::SmallVector<Value, 4> packed; llvm::SmallVector<Value, 4> packed;
@ -248,14 +248,14 @@ public:
} }
// Control side // Control side
Value selectedIndex = rewriter.create<dc::MergeOp>(op.getLoc(), tokens); Value selectedIndex = dc::MergeOp::create(rewriter, op.getLoc(), tokens);
auto selectedIndexUnpacked = unpack(rewriter, selectedIndex); auto selectedIndexUnpacked = unpack(rewriter, selectedIndex);
Value mergeOutput; Value mergeOutput;
if (!data.empty()) { if (!data.empty()) {
// Data-merge; mux the selected input. // Data-merge; mux the selected input.
auto dataMux = rewriter.create<arith::SelectOp>( auto dataMux = arith::SelectOp::create(
op.getLoc(), selectedIndexUnpacked.data, data[0], data[1]); rewriter, op.getLoc(), selectedIndexUnpacked.data, data[0], data[1]);
convertedOps->insert(dataMux); convertedOps->insert(dataMux);
// Pack the data mux with the control token. // Pack the data mux with the control token.
@ -290,11 +290,11 @@ public:
inputData.push_back(dct.data); inputData.push_back(dct.data);
} }
auto join = rewriter.create<dc::JoinOp>(op.getLoc(), inputTokens); auto join = dc::JoinOp::create(rewriter, op.getLoc(), inputTokens);
StructType structType = StructType structType =
tupleToStruct(cast<TupleType>(op.getResult().getType())); tupleToStruct(cast<TupleType>(op.getResult().getType()));
auto packedData = auto packedData = hw::StructCreateOp::create(rewriter, op.getLoc(),
rewriter.create<hw::StructCreateOp>(op.getLoc(), structType, inputData); structType, inputData);
convertedOps->insert(packedData); convertedOps->insert(packedData);
rewriter.replaceOp(op, pack(rewriter, join, packedData)); rewriter.replaceOp(op, pack(rewriter, join, packedData));
return success(); return success();
@ -313,7 +313,7 @@ public:
// values. // values.
DCTuple unpackedInput = unpack(rewriter, adaptor.getInput()); DCTuple unpackedInput = unpack(rewriter, adaptor.getInput());
auto unpackedData = auto unpackedData =
rewriter.create<hw::StructExplodeOp>(op.getLoc(), unpackedInput.data); hw::StructExplodeOp::create(rewriter, op.getLoc(), unpackedInput.data);
convertedOps->insert(unpackedData); convertedOps->insert(unpackedData);
// Re-pack each of the tuple elements with the token. // Re-pack each of the tuple elements with the token.
llvm::SmallVector<Value, 4> repackedInputs; llvm::SmallVector<Value, 4> repackedInputs;
@ -349,15 +349,15 @@ public:
bool isIndexType = isa<IndexType>(op.getIndex().getType()); bool isIndexType = isa<IndexType>(op.getIndex().getType());
// control-side // control-side
Value selectedIndex = rewriter.create<dc::MergeOp>(op.getLoc(), tokens); Value selectedIndex = dc::MergeOp::create(rewriter, op.getLoc(), tokens);
auto mergeOpUnpacked = unpack(rewriter, selectedIndex); auto mergeOpUnpacked = unpack(rewriter, selectedIndex);
auto selValue = mergeOpUnpacked.data; auto selValue = mergeOpUnpacked.data;
Value dataSide = selectedIndex; Value dataSide = selectedIndex;
if (!data.empty()) { if (!data.empty()) {
// Data side mux using the selected input. // Data side mux using the selected input.
auto dataMux = rewriter.create<arith::SelectOp>(op.getLoc(), selValue, auto dataMux = arith::SelectOp::create(rewriter, op.getLoc(), selValue,
data[0], data[1]); data[0], data[1]);
convertedOps->insert(dataMux); convertedOps->insert(dataMux);
// Pack the data mux with the control token. // Pack the data mux with the control token.
auto packed = pack(rewriter, mergeOpUnpacked.token, dataMux); auto packed = pack(rewriter, mergeOpUnpacked.token, dataMux);
@ -368,15 +368,15 @@ public:
// if the original op used `index` as the select operand type, we need to // if the original op used `index` as the select operand type, we need to
// index-cast the unpacked select operand // index-cast the unpacked select operand
if (isIndexType) { if (isIndexType) {
selValue = rewriter.create<arith::IndexCastOp>( selValue = arith::IndexCastOp::create(rewriter, op.getLoc(),
op.getLoc(), rewriter.getIndexType(), selValue); rewriter.getIndexType(), selValue);
convertedOps->insert(selValue.getDefiningOp()); convertedOps->insert(selValue.getDefiningOp());
selectedIndex = pack(rewriter, mergeOpUnpacked.token, selValue); selectedIndex = pack(rewriter, mergeOpUnpacked.token, selValue);
} else { } else {
// The cmerge had a specific type defined for the index type. dc.merge // The cmerge had a specific type defined for the index type. dc.merge
// provides an i1 operand for the selected index, so we need to cast it. // provides an i1 operand for the selected index, so we need to cast it.
selValue = rewriter.create<arith::ExtUIOp>( selValue = arith::ExtUIOp::create(rewriter, op.getLoc(),
op.getLoc(), op.getIndex().getType(), selValue); op.getIndex().getType(), selValue);
convertedOps->insert(selValue.getDefiningOp()); convertedOps->insert(selValue.getDefiningOp());
selectedIndex = pack(rewriter, mergeOpUnpacked.token, selValue); selectedIndex = pack(rewriter, mergeOpUnpacked.token, selValue);
} }
@ -402,7 +402,7 @@ public:
inputData.push_back(unpacked.data); inputData.push_back(unpacked.data);
} }
auto syncToken = rewriter.create<dc::JoinOp>(op.getLoc(), inputTokens); auto syncToken = dc::JoinOp::create(rewriter, op.getLoc(), inputTokens);
// Wrap all outputs with the synchronization token // Wrap all outputs with the synchronization token
llvm::SmallVector<Value, 4> wrappedInputs; llvm::SmallVector<Value, 4> wrappedInputs;
@ -425,9 +425,9 @@ public:
matchAndRewrite(handshake::ConstantOp op, OpAdaptor adaptor, matchAndRewrite(handshake::ConstantOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
// Wrap the constant with a token. // Wrap the constant with a token.
auto token = rewriter.create<dc::SourceOp>(op.getLoc()); auto token = dc::SourceOp::create(rewriter, op.getLoc());
auto cst = auto cst =
rewriter.create<arith::ConstantOp>(op.getLoc(), adaptor.getValue()); arith::ConstantOp::create(rewriter, op.getLoc(), adaptor.getValue());
convertedOps->insert(cst); convertedOps->insert(cst);
rewriter.replaceOp(op, pack(rewriter, token, cst)); rewriter.replaceOp(op, pack(rewriter, token, cst));
return success(); return success();
@ -458,7 +458,7 @@ public:
// Constant-like operation; assume the token can be represented as a // Constant-like operation; assume the token can be represented as a
// constant `dc.source`. // constant `dc.source`.
outToken = rewriter.create<dc::SourceOp>(op->getLoc()); outToken = dc::SourceOp::create(rewriter, op->getLoc());
} else { } else {
llvm::SmallVector<Value> inputTokens; llvm::SmallVector<Value> inputTokens;
for (auto input : operands) { for (auto input : operands) {
@ -468,7 +468,7 @@ public:
} }
// Join the tokens of the inputs. // Join the tokens of the inputs.
assert(!inputTokens.empty() && "Expected at least one input token"); assert(!inputTokens.empty() && "Expected at least one input token");
outToken = rewriter.create<dc::JoinOp>(op->getLoc(), inputTokens); outToken = dc::JoinOp::create(rewriter, op->getLoc(), inputTokens);
} }
// Patchwork to fix bad IR design in Handshake. // Patchwork to fix bad IR design in Handshake.
@ -600,15 +600,17 @@ public:
Value inputData = input.data; Value inputData = input.data;
Value inputControl = input.token; Value inputControl = input.token;
if (isIndexType) { if (isIndexType) {
cmpIndex = rewriter.create<arith::ConstantIndexOp>(op.getLoc(), i); cmpIndex = arith::ConstantIndexOp::create(rewriter, op.getLoc(), i);
} else { } else {
size_t width = cast<IntegerType>(selectData.getType()).getWidth(); size_t width = cast<IntegerType>(selectData.getType()).getWidth();
cmpIndex = rewriter.create<arith::ConstantIntOp>(op.getLoc(), i, width); cmpIndex =
arith::ConstantIntOp::create(rewriter, op.getLoc(), i, width);
} }
auto inputSelected = rewriter.create<arith::CmpIOp>( auto inputSelected =
op.getLoc(), arith::CmpIPredicate::eq, selectData, cmpIndex); arith::CmpIOp::create(rewriter, op.getLoc(), arith::CmpIPredicate::eq,
dataMux = rewriter.create<arith::SelectOp>(op.getLoc(), inputSelected, selectData, cmpIndex);
inputData, dataMux); dataMux = arith::SelectOp::create(rewriter, op.getLoc(), inputSelected,
inputData, dataMux);
// Legalize the newly created operations. // Legalize the newly created operations.
convertedOps->insert(cmpIndex.getDefiningOp()); convertedOps->insert(cmpIndex.getDefiningOp());
@ -619,8 +621,9 @@ public:
// select value that has it's control from the original select token + // select value that has it's control from the original select token +
// the inputSelected value. // the inputSelected value.
auto inputSelectedControl = pack(rewriter, selectToken, inputSelected); auto inputSelectedControl = pack(rewriter, selectToken, inputSelected);
controlMux = rewriter.create<dc::SelectOp>( controlMux =
op.getLoc(), inputSelectedControl, inputControl, controlMux); dc::SelectOp::create(rewriter, op.getLoc(), inputSelectedControl,
inputControl, controlMux);
convertedOps->insert(controlMux.getDefiningOp()); convertedOps->insert(controlMux.getDefiningOp());
} }
@ -671,12 +674,12 @@ public:
ModulePortInfo ports = getModulePortInfoHS(*getTypeConverter(), op); ModulePortInfo ports = getModulePortInfoHS(*getTypeConverter(), op);
if (op.isExternal()) { if (op.isExternal()) {
auto mod = rewriter.create<hw::HWModuleExternOp>( auto mod = hw::HWModuleExternOp::create(
op.getLoc(), rewriter.getStringAttr(op.getName()), ports); rewriter, op.getLoc(), rewriter.getStringAttr(op.getName()), ports);
convertedOps->insert(mod); convertedOps->insert(mod);
} else { } else {
auto hwModule = rewriter.create<hw::HWModuleOp>( auto hwModule = hw::HWModuleOp::create(
op.getLoc(), rewriter.getStringAttr(op.getName()), ports); rewriter, op.getLoc(), rewriter.getStringAttr(op.getName()), ports);
auto &region = op->getRegions().front(); auto &region = op->getRegions().front();
@ -712,18 +715,18 @@ public:
for (size_t i = ESIInstanceOp::NumFixedOperands, e = op.getNumOperands(); for (size_t i = ESIInstanceOp::NumFixedOperands, e = op.getNumOperands();
i < e; ++i) i < e; ++i)
operands.push_back( operands.push_back(
rewriter.create<dc::FromESIOp>(loc, adaptor.getOperands()[i])); dc::FromESIOp::create(rewriter, loc, adaptor.getOperands()[i]));
operands.push_back(adaptor.getClk()); operands.push_back(adaptor.getClk());
operands.push_back(adaptor.getRst()); operands.push_back(adaptor.getRst());
// Locate the lowered module so the instance builder can get all the // Locate the lowered module so the instance builder can get all the
// metadata. // metadata.
Operation *targetModule = symCache.getDefinition(op.getModuleAttr()); Operation *targetModule = symCache.getDefinition(op.getModuleAttr());
// And replace the op with an instance of the target module. // And replace the op with an instance of the target module.
auto inst = rewriter.create<hw::InstanceOp>(loc, targetModule, auto inst = hw::InstanceOp::create(rewriter, loc, targetModule,
op.getInstNameAttr(), operands); op.getInstNameAttr(), operands);
SmallVector<Value> esiResults( SmallVector<Value> esiResults(
llvm::map_range(inst.getResults(), [&](Value v) { llvm::map_range(inst.getResults(), [&](Value v) {
return rewriter.create<dc::ToESIOp>(loc, v); return dc::ToESIOp::create(rewriter, loc, v);
})); }));
rewriter.replaceOp(op, esiResults); rewriter.replaceOp(op, esiResults);
return success(); return success();

View File

@ -71,8 +71,8 @@ public:
mlir::Location loc) -> mlir::Value { mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
@ -81,8 +81,8 @@ public:
mlir::Location loc) -> mlir::Value { mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
} }
@ -350,8 +350,8 @@ static LogicalResult convertExtMemoryOps(HWModuleOp mod) {
auto newInPort = mod.getArgumentForInput(i); auto newInPort = mod.getArgumentForInput(i);
// Replace the extmemory submodule outputs with the newly created inputs. // Replace the extmemory submodule outputs with the newly created inputs.
b.setInsertionPointToStart(mod.getBodyBlock()); b.setInsertionPointToStart(mod.getBodyBlock());
auto newInPortExploded = b.create<hw::StructExplodeOp>( auto newInPortExploded = hw::StructExplodeOp::create(
arg.getLoc(), extmemMod.getOutputTypes(), newInPort); b, arg.getLoc(), extmemMod.getOutputTypes(), newInPort);
extmemInstance.replaceAllUsesWith(newInPortExploded.getResults()); extmemInstance.replaceAllUsesWith(newInPortExploded.getResults());
// Add memory output - this is the inputs of the extmemory op (without the // Add memory output - this is the inputs of the extmemory op (without the
@ -364,8 +364,8 @@ static LogicalResult convertExtMemoryOps(HWModuleOp mod) {
auto memOutputArgs = extmemInstance.getOperands().drop_front(); auto memOutputArgs = extmemInstance.getOperands().drop_front();
b.setInsertionPoint(mod.getBodyBlock()->getTerminator()); b.setInsertionPoint(mod.getBodyBlock()->getTerminator());
auto memOutputStruct = b.create<hw::StructCreateOp>( auto memOutputStruct = hw::StructCreateOp::create(
arg.getLoc(), outPortInfo.type, memOutputArgs); b, arg.getLoc(), outPortInfo.type, memOutputArgs);
mod.appendOutputs({{outPortInfo.name, memOutputStruct}}); mod.appendOutputs({{outPortInfo.name, memOutputStruct}});
// Erase the extmemory submodule instace since the i/o has now been // Erase the extmemory submodule instace since the i/o has now been
@ -476,7 +476,7 @@ struct RTLBuilder {
return it->second; return it->second;
} }
auto cval = b.create<hw::ConstantOp>(loc, apv); auto cval = hw::ConstantOp::create(b, loc, apv);
if (!isZeroWidth) if (!isZeroWidth)
constants[apv] = cval; constants[apv] = cval;
return cval; return cval;
@ -489,12 +489,12 @@ struct RTLBuilder {
} }
std::pair<Value, Value> wrap(Value data, Value valid, std::pair<Value, Value> wrap(Value data, Value valid,
std::optional<StringRef> name = {}) { std::optional<StringRef> name = {}) {
auto wrapOp = b.create<esi::WrapValidReadyOp>(loc, data, valid); auto wrapOp = esi::WrapValidReadyOp::create(b, loc, data, valid);
return {wrapOp.getResult(0), wrapOp.getResult(1)}; return {wrapOp.getResult(0), wrapOp.getResult(1)};
} }
std::pair<Value, Value> unwrap(Value channel, Value ready, std::pair<Value, Value> unwrap(Value channel, Value ready,
std::optional<StringRef> name = {}) { std::optional<StringRef> name = {}) {
auto unwrapOp = b.create<esi::UnwrapValidReadyOp>(loc, channel, ready); auto unwrapOp = esi::UnwrapValidReadyOp::create(b, loc, channel, ready);
return {unwrapOp.getResult(0), unwrapOp.getResult(1)}; return {unwrapOp.getResult(0), unwrapOp.getResult(1)};
} }
@ -510,13 +510,13 @@ struct RTLBuilder {
"No global reset provided to this RTLBuilder - a reset " "No global reset provided to this RTLBuilder - a reset "
"signal must be provided to the reg(...) function."); "signal must be provided to the reg(...) function.");
return b.create<seq::CompRegOp>(loc, in, resolvedClk, resolvedRst, rstValue, return seq::CompRegOp::create(b, loc, in, resolvedClk, resolvedRst,
name); rstValue, name);
} }
Value cmp(Value lhs, Value rhs, comb::ICmpPredicate predicate, Value cmp(Value lhs, Value rhs, comb::ICmpPredicate predicate,
std::optional<StringRef> name = {}) { std::optional<StringRef> name = {}) {
return b.create<comb::ICmpOp>(loc, predicate, lhs, rhs); return comb::ICmpOp::create(b, loc, predicate, lhs, rhs);
} }
Value buildNamedOp(llvm::function_ref<Value()> f, Value buildNamedOp(llvm::function_ref<Value()> f,
@ -534,12 +534,12 @@ struct RTLBuilder {
// Bitwise 'and'. // Bitwise 'and'.
Value bAnd(ValueRange values, std::optional<StringRef> name = {}) { Value bAnd(ValueRange values, std::optional<StringRef> name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::AndOp>(loc, values, false); }, name); [&]() { return comb::AndOp::create(b, loc, values, false); }, name);
} }
Value bOr(ValueRange values, std::optional<StringRef> name = {}) { Value bOr(ValueRange values, std::optional<StringRef> name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::OrOp>(loc, values, false); }, name); [&]() { return comb::OrOp::create(b, loc, values, false); }, name);
} }
// Bitwise 'not'. // Bitwise 'not'.
@ -556,19 +556,19 @@ struct RTLBuilder {
} }
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::XorOp>(loc, value, allOnes); }, name); [&]() { return comb::XorOp::create(b, loc, value, allOnes); }, name);
return b.createOrFold<comb::XorOp>(loc, value, allOnes, false); return b.createOrFold<comb::XorOp>(loc, value, allOnes, false);
} }
Value shl(Value value, Value shift, std::optional<StringRef> name = {}) { Value shl(Value value, Value shift, std::optional<StringRef> name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::ShlOp>(loc, value, shift); }, name); [&]() { return comb::ShlOp::create(b, loc, value, shift); }, name);
} }
Value concat(ValueRange values, std::optional<StringRef> name = {}) { Value concat(ValueRange values, std::optional<StringRef> name = {}) {
return buildNamedOp([&]() { return b.create<comb::ConcatOp>(loc, values); }, return buildNamedOp(
name); [&]() { return comb::ConcatOp::create(b, loc, values); }, name);
} }
// Packs a list of values into a hw.struct. // Packs a list of values into a hw.struct.
@ -577,7 +577,9 @@ struct RTLBuilder {
if (!structType) if (!structType)
structType = tupleToStruct(values.getTypes()); structType = tupleToStruct(values.getTypes());
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<hw::StructCreateOp>(loc, structType, values); }, [&]() {
return hw::StructCreateOp::create(b, loc, structType, values);
},
name); name);
} }
@ -586,13 +588,13 @@ struct RTLBuilder {
auto structType = cast<hw::StructType>(value.getType()); auto structType = cast<hw::StructType>(value.getType());
llvm::SmallVector<Type> innerTypes; llvm::SmallVector<Type> innerTypes;
structType.getInnerTypes(innerTypes); structType.getInnerTypes(innerTypes);
return b.create<hw::StructExplodeOp>(loc, innerTypes, value).getResults(); return hw::StructExplodeOp::create(b, loc, innerTypes, value).getResults();
} }
llvm::SmallVector<Value> toBits(Value v, std::optional<StringRef> name = {}) { llvm::SmallVector<Value> toBits(Value v, std::optional<StringRef> name = {}) {
llvm::SmallVector<Value> bits; llvm::SmallVector<Value> bits;
for (unsigned i = 0, e = v.getType().getIntOrFloatBitWidth(); i != e; ++i) for (unsigned i = 0, e = v.getType().getIntOrFloatBitWidth(); i != e; ++i)
bits.push_back(b.create<comb::ExtractOp>(loc, v, i, /*bitWidth=*/1)); bits.push_back(comb::ExtractOp::create(b, loc, v, i, /*bitWidth=*/1));
return bits; return bits;
} }
@ -606,7 +608,7 @@ struct RTLBuilder {
std::optional<StringRef> name = {}) { std::optional<StringRef> name = {}) {
unsigned width = hi - lo + 1; unsigned width = hi - lo + 1;
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<comb::ExtractOp>(loc, v, lo, width); }, name); [&]() { return comb::ExtractOp::create(b, loc, v, lo, width); }, name);
} }
// Truncates 'value' to its lower 'width' bits. // Truncates 'value' to its lower 'width' bits.
@ -638,13 +640,13 @@ struct RTLBuilder {
// Creates a hw.array of the given values. // Creates a hw.array of the given values.
Value arrayCreate(ValueRange values, std::optional<StringRef> name = {}) { Value arrayCreate(ValueRange values, std::optional<StringRef> name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<hw::ArrayCreateOp>(loc, values); }, name); [&]() { return hw::ArrayCreateOp::create(b, loc, values); }, name);
} }
// Extract the 'index'th value from the input array. // Extract the 'index'th value from the input array.
Value arrayGet(Value array, Value index, std::optional<StringRef> name = {}) { Value arrayGet(Value array, Value index, std::optional<StringRef> name = {}) {
return buildNamedOp( return buildNamedOp(
[&]() { return b.create<hw::ArrayGetOp>(loc, array, index); }, name); [&]() { return hw::ArrayGetOp::create(b, loc, array, index); }, name);
} }
// Muxes a range of values. // Muxes a range of values.
@ -653,7 +655,7 @@ struct RTLBuilder {
Value mux(Value index, ValueRange values, Value mux(Value index, ValueRange values,
std::optional<StringRef> name = {}) { std::optional<StringRef> name = {}) {
if (values.size() == 2) if (values.size() == 2)
return b.create<comb::MuxOp>(loc, index, values[1], values[0]); return comb::MuxOp::create(b, loc, index, values[1], values[0]);
return arrayGet(arrayCreate(values), index, name); return arrayGet(arrayCreate(values), index, name);
} }
@ -702,7 +704,7 @@ static Value createZeroDataConst(RTLBuilder &s, Location loc, Type type) {
SmallVector<Value> zeroValues; SmallVector<Value> zeroValues;
for (auto field : structType.getElements()) for (auto field : structType.getElements())
zeroValues.push_back(createZeroDataConst(s, loc, field.type)); zeroValues.push_back(createZeroDataConst(s, loc, field.type));
return s.b.create<hw::StructCreateOp>(loc, structType, zeroValues); return hw::StructCreateOp::create(s.b, loc, structType, zeroValues);
}) })
.Default([&](Type) -> Value { .Default([&](Type) -> Value {
emitError(loc) << "unsupported type for zero value: " << type; emitError(loc) << "unsupported type for zero value: " << type;
@ -748,9 +750,10 @@ public:
auto portInfo = ModulePortInfo(getPortInfoForOp(op)); auto portInfo = ModulePortInfo(getPortInfoForOp(op));
submoduleBuilder.setInsertionPoint(op->getParentOp()); submoduleBuilder.setInsertionPoint(op->getParentOp());
implModule = submoduleBuilder.create<hw::HWModuleOp>( implModule = hw::HWModuleOp::create(
op.getLoc(), submoduleBuilder.getStringAttr(getSubModuleName(op)), submoduleBuilder, op.getLoc(),
portInfo, [&](OpBuilder &b, hw::HWModulePortAccessor &ports) { submoduleBuilder.getStringAttr(getSubModuleName(op)), portInfo,
[&](OpBuilder &b, hw::HWModulePortAccessor &ports) {
// if 'op' has clock trait, extract these and provide them to the // if 'op' has clock trait, extract these and provide them to the
// RTL builder. // RTL builder.
Value clk, rst; Value clk, rst;
@ -1122,8 +1125,8 @@ public:
// constructs from the input data signals of TIn. // constructs from the input data signals of TIn.
// To disambiguate ambiguous builders with default arguments (e.g., // To disambiguate ambiguous builders with default arguments (e.g.,
// twoState UnitAttr), specify attribute array explicitly. // twoState UnitAttr), specify attribute array explicitly.
return s.b.create<TOut>(op.getLoc(), inputs, return TOut::create(s.b, op.getLoc(), inputs,
/* attributes */ ArrayRef<NamedAttribute>{}); /* attributes */ ArrayRef<NamedAttribute>{});
}); });
}; };
}; };
@ -1217,8 +1220,8 @@ public:
auto unwrappedIO = this->unwrapIO(s, bb, ports); auto unwrappedIO = this->unwrapIO(s, bb, ports);
auto buildCompareLogic = [&](comb::ICmpPredicate predicate) { auto buildCompareLogic = [&](comb::ICmpPredicate predicate) {
return buildUnitRateJoinLogic(s, unwrappedIO, [&](ValueRange inputs) { return buildUnitRateJoinLogic(s, unwrappedIO, [&](ValueRange inputs) {
return s.b.create<comb::ICmpOp>(op.getLoc(), predicate, inputs[0], return comb::ICmpOp::create(s.b, op.getLoc(), predicate, inputs[0],
inputs[1]); inputs[1]);
}); });
}; };
@ -1537,16 +1540,17 @@ public:
auto c0I0 = s.constant(0, 0); auto c0I0 = s.constant(0, 0);
auto cl2dim = llvm::Log2_64_Ceil(op.getMemRefType().getShape()[0]); auto cl2dim = llvm::Log2_64_Ceil(op.getMemRefType().getShape()[0]);
auto hlmem = s.b.create<seq::HLMemOp>( auto hlmem = seq::HLMemOp::create(
loc, s.clk, s.rst, "_handshake_memory_" + std::to_string(op.getId()), s.b, loc, s.clk, s.rst,
"_handshake_memory_" + std::to_string(op.getId()),
op.getMemRefType().getShape(), op.getMemRefType().getElementType()); op.getMemRefType().getShape(), op.getMemRefType().getElementType());
// Create load ports... // Create load ports...
for (auto &ld : loadPorts) { for (auto &ld : loadPorts) {
llvm::SmallVector<Value> addresses = {s.truncate(ld.addr.data, cl2dim)}; llvm::SmallVector<Value> addresses = {s.truncate(ld.addr.data, cl2dim)};
auto readData = s.b.create<seq::ReadPortOp>(loc, hlmem.getHandle(), auto readData = seq::ReadPortOp::create(s.b, loc, hlmem.getHandle(),
addresses, ld.addr.valid, addresses, ld.addr.valid,
/*latency=*/0); /*latency=*/0);
ld.data.data->setValue(readData); ld.data.data->setValue(readData);
ld.done.data->setValue(c0I0); ld.done.data->setValue(c0I0);
// Create control fork for the load address valid and ready signals. // Create control fork for the load address valid and ready signals.
@ -1591,9 +1595,9 @@ public:
// Instantiate the write port operation - truncate address width to memory // Instantiate the write port operation - truncate address width to memory
// width. // width.
llvm::SmallVector<Value> addresses = {s.truncate(st.addr.data, cl2dim)}; llvm::SmallVector<Value> addresses = {s.truncate(st.addr.data, cl2dim)};
s.b.create<seq::WritePortOp>(loc, hlmem.getHandle(), addresses, seq::WritePortOp::create(s.b, loc, hlmem.getHandle(), addresses,
st.data.data, writeValid, st.data.data, writeValid,
/*latency=*/1); /*latency=*/1);
} }
} }
}; // namespace }; // namespace
@ -1851,11 +1855,11 @@ public:
HWModuleLike hwModule; HWModuleLike hwModule;
if (op.isExternal()) { if (op.isExternal()) {
hwModule = rewriter.create<hw::HWModuleExternOp>( hwModule = hw::HWModuleExternOp::create(
op.getLoc(), rewriter.getStringAttr(op.getName()), ports); rewriter, op.getLoc(), rewriter.getStringAttr(op.getName()), ports);
} else { } else {
auto hwModuleOp = rewriter.create<hw::HWModuleOp>( auto hwModuleOp = hw::HWModuleOp::create(
op.getLoc(), rewriter.getStringAttr(op.getName()), ports); rewriter, op.getLoc(), rewriter.getStringAttr(op.getName()), ports);
auto args = hwModuleOp.getBodyBlock()->getArguments().drop_back(2); auto args = hwModuleOp.getBodyBlock()->getArguments().drop_back(2);
rewriter.inlineBlockBefore(&op.getBody().front(), rewriter.inlineBlockBefore(&op.getBody().front(),
hwModuleOp.getBodyBlock()->getTerminator(), hwModuleOp.getBodyBlock()->getTerminator(),

View File

@ -723,15 +723,15 @@ Value AIGERParser::getLiteralValue(unsigned literal,
// Handle constants // Handle constants
if (literal == 0) { if (literal == 0) {
// FALSE constant // FALSE constant
return builder.create<hw::ConstantOp>( return hw::ConstantOp::create(
loc, builder.getI1Type(), builder, loc, builder.getI1Type(),
builder.getIntegerAttr(builder.getI1Type(), 0)); builder.getIntegerAttr(builder.getI1Type(), 0));
} }
if (literal == 1) { if (literal == 1) {
// TRUE constant // TRUE constant
return builder.create<hw::ConstantOp>( return hw::ConstantOp::create(
loc, builder.getI1Type(), builder, loc, builder.getI1Type(),
builder.getIntegerAttr(builder.getI1Type(), 1)); builder.getIntegerAttr(builder.getI1Type(), 1));
} }
@ -770,8 +770,8 @@ Value AIGERParser::getLiteralValue(unsigned literal,
if (inverted) { if (inverted) {
// Create an inverter using aig.and_inv with single input // Create an inverter using aig.and_inv with single input
SmallVector<bool> inverts = {true}; SmallVector<bool> inverts = {true};
return builder.create<aig::AndInverterOp>(loc, builder.getI1Type(), return aig::AndInverterOp::create(builder, loc, builder.getI1Type(),
ValueRange{baseValue}, inverts); ValueRange{baseValue}, inverts);
} }
return baseValue; return baseValue;
@ -825,8 +825,9 @@ ParseResult AIGERParser::createModule() {
} }
// Create the HW module // Create the HW module
auto hwModule = builder.create<hw::HWModuleOp>( auto hwModule =
builder.getUnknownLoc(), builder.getStringAttr(moduleName), ports); hw::HWModuleOp::create(builder, builder.getUnknownLoc(),
builder.getStringAttr(moduleName), ports);
// Set insertion point inside the module // Set insertion point inside the module
builder.setInsertionPointToStart(hwModule.getBodyBlock()); builder.setInsertionPointToStart(hwModule.getBodyBlock());
@ -865,8 +866,8 @@ ParseResult AIGERParser::createModule() {
auto nextBackedge = bb.get(builder.getI1Type()); auto nextBackedge = bb.get(builder.getI1Type());
// Create the register with the backedge as input // Create the register with the backedge as input
auto regValue = builder.create<seq::CompRegOp>( auto regValue = seq::CompRegOp::create(
lexer.translateLocation(loc), (Value)nextBackedge, clockValue); builder, lexer.translateLocation(loc), (Value)nextBackedge, clockValue);
if (auto name = symbolTable.lookup({SymbolKind::Latch, i})) if (auto name = symbolTable.lookup({SymbolKind::Latch, i}))
regValue.setNameAttr(name); regValue.setNameAttr(name);
@ -889,9 +890,9 @@ ParseResult AIGERParser::createModule() {
static_cast<bool>(rhs1 % 2)}; static_cast<bool>(rhs1 % 2)};
// Create AND gate with potential inversions // Create AND gate with potential inversions
auto andResult = builder.create<aig::AndInverterOp>( auto andResult =
location, builder.getI1Type(), ValueRange{rhs0Value, rhs1Value}, aig::AndInverterOp::create(builder, location, builder.getI1Type(),
inverts); ValueRange{rhs0Value, rhs1Value}, inverts);
// Set the backedge for this AND gate's result // Set the backedge for this AND gate's result
backedges[lhs].setValue(andResult); backedges[lhs].setValue(andResult);

View File

@ -65,14 +65,14 @@ struct AssertionExprVisitor {
switch (repetition.kind) { switch (repetition.kind) {
case SequenceRepetition::Consecutive: case SequenceRepetition::Consecutive:
return builder.create<ltl::RepeatOp>(loc, inputSequence, minRepetitions, return ltl::RepeatOp::create(builder, loc, inputSequence, minRepetitions,
repetitionRange); repetitionRange);
case SequenceRepetition::Nonconsecutive: case SequenceRepetition::Nonconsecutive:
return builder.create<ltl::NonConsecutiveRepeatOp>( return ltl::NonConsecutiveRepeatOp::create(
loc, inputSequence, minRepetitions, repetitionRange); builder, loc, inputSequence, minRepetitions, repetitionRange);
case SequenceRepetition::GoTo: case SequenceRepetition::GoTo:
return builder.create<ltl::GoToRepeatOp>(loc, inputSequence, return ltl::GoToRepeatOp::create(builder, loc, inputSequence,
minRepetitions, repetitionRange); minRepetitions, repetitionRange);
} }
llvm_unreachable("All enum values handled in switch"); llvm_unreachable("All enum values handled in switch");
} }
@ -120,8 +120,8 @@ struct AssertionExprVisitor {
auto [delayMin, delayRange] = auto [delayMin, delayRange] =
convertRangeToAttrs(concatElement.delay.min, concatElement.delay.max); convertRangeToAttrs(concatElement.delay.min, concatElement.delay.max);
auto delayedSequence = builder.create<ltl::DelayOp>(loc, sequenceValue, auto delayedSequence = ltl::DelayOp::create(builder, loc, sequenceValue,
delayMin, delayRange); delayMin, delayRange);
sequenceElements.push_back(delayedSequence); sequenceElements.push_back(delayedSequence);
} }
@ -135,13 +135,13 @@ struct AssertionExprVisitor {
using slang::ast::UnaryAssertionOperator; using slang::ast::UnaryAssertionOperator;
switch (expr.op) { switch (expr.op) {
case UnaryAssertionOperator::Not: case UnaryAssertionOperator::Not:
return builder.create<ltl::NotOp>(loc, value); return ltl::NotOp::create(builder, loc, value);
case UnaryAssertionOperator::SEventually: case UnaryAssertionOperator::SEventually:
if (expr.range.has_value()) { if (expr.range.has_value()) {
mlir::emitError(loc, "Strong eventually with range not supported"); mlir::emitError(loc, "Strong eventually with range not supported");
return {}; return {};
} else { } else {
return builder.create<ltl::EventuallyOp>(loc, value); return ltl::EventuallyOp::create(builder, loc, value);
} }
case UnaryAssertionOperator::Always: { case UnaryAssertionOperator::Always: {
std::pair<mlir::IntegerAttr, mlir::IntegerAttr> attr = { std::pair<mlir::IntegerAttr, mlir::IntegerAttr> attr = {
@ -150,15 +150,16 @@ struct AssertionExprVisitor {
attr = attr =
convertRangeToAttrs(expr.range.value().min, expr.range.value().max); convertRangeToAttrs(expr.range.value().min, expr.range.value().max);
} }
return builder.create<ltl::RepeatOp>(loc, value, attr.first, attr.second); return ltl::RepeatOp::create(builder, loc, value, attr.first,
attr.second);
} }
case UnaryAssertionOperator::NextTime: { case UnaryAssertionOperator::NextTime: {
auto minRepetitions = builder.getI64IntegerAttr(1); auto minRepetitions = builder.getI64IntegerAttr(1);
if (expr.range.has_value()) { if (expr.range.has_value()) {
minRepetitions = builder.getI64IntegerAttr(expr.range.value().min); minRepetitions = builder.getI64IntegerAttr(expr.range.value().min);
} }
return builder.create<ltl::DelayOp>(loc, value, minRepetitions, return ltl::DelayOp::create(builder, loc, value, minRepetitions,
builder.getI64IntegerAttr(0)); builder.getI64IntegerAttr(0));
} }
case UnaryAssertionOperator::Eventually: case UnaryAssertionOperator::Eventually:
case UnaryAssertionOperator::SNextTime: case UnaryAssertionOperator::SNextTime:
@ -179,81 +180,86 @@ struct AssertionExprVisitor {
using slang::ast::BinaryAssertionOperator; using slang::ast::BinaryAssertionOperator;
switch (expr.op) { switch (expr.op) {
case BinaryAssertionOperator::And: case BinaryAssertionOperator::And:
return builder.create<ltl::AndOp>(loc, operands); return ltl::AndOp::create(builder, loc, operands);
case BinaryAssertionOperator::Or: case BinaryAssertionOperator::Or:
return builder.create<ltl::OrOp>(loc, operands); return ltl::OrOp::create(builder, loc, operands);
case BinaryAssertionOperator::Intersect: case BinaryAssertionOperator::Intersect:
return builder.create<ltl::IntersectOp>(loc, operands); return ltl::IntersectOp::create(builder, loc, operands);
case BinaryAssertionOperator::Throughout: { case BinaryAssertionOperator::Throughout: {
auto lhsRepeat = builder.create<ltl::RepeatOp>( auto lhsRepeat = ltl::RepeatOp::create(
loc, lhs, builder.getI64IntegerAttr(0), mlir::IntegerAttr{}); builder, loc, lhs, builder.getI64IntegerAttr(0), mlir::IntegerAttr{});
return builder.create<ltl::IntersectOp>( return ltl::IntersectOp::create(builder, loc,
loc, SmallVector<Value, 2>{lhsRepeat, rhs}); SmallVector<Value, 2>{lhsRepeat, rhs});
} }
case BinaryAssertionOperator::Within: { case BinaryAssertionOperator::Within: {
auto constOne = auto constOne =
builder.create<hw::ConstantOp>(loc, builder.getI1Type(), 1); hw::ConstantOp::create(builder, loc, builder.getI1Type(), 1);
auto oneRepeat = builder.create<ltl::RepeatOp>( auto oneRepeat = ltl::RepeatOp::create(builder, loc, constOne,
loc, constOne, builder.getI64IntegerAttr(0), mlir::IntegerAttr{}); builder.getI64IntegerAttr(0),
auto repeatDelay = builder.create<ltl::DelayOp>( mlir::IntegerAttr{});
loc, oneRepeat, builder.getI64IntegerAttr(1), auto repeatDelay = ltl::DelayOp::create(builder, loc, oneRepeat,
builder.getI64IntegerAttr(0)); builder.getI64IntegerAttr(1),
auto lhsDelay = builder.create<ltl::DelayOp>( builder.getI64IntegerAttr(0));
loc, lhs, builder.getI64IntegerAttr(1), builder.getI64IntegerAttr(0)); auto lhsDelay =
auto combined = builder.create<ltl::ConcatOp>( ltl::DelayOp::create(builder, loc, lhs, builder.getI64IntegerAttr(1),
loc, SmallVector<Value, 3>{repeatDelay, lhsDelay, constOne}); builder.getI64IntegerAttr(0));
return builder.create<ltl::IntersectOp>( auto combined = ltl::ConcatOp::create(
loc, SmallVector<Value, 2>{combined, rhs}); builder, loc, SmallVector<Value, 3>{repeatDelay, lhsDelay, constOne});
return ltl::IntersectOp::create(builder, loc,
SmallVector<Value, 2>{combined, rhs});
} }
case BinaryAssertionOperator::Iff: { case BinaryAssertionOperator::Iff: {
auto ored = builder.create<ltl::OrOp>(loc, operands); auto ored = ltl::OrOp::create(builder, loc, operands);
auto notOred = builder.create<ltl::NotOp>(loc, ored); auto notOred = ltl::NotOp::create(builder, loc, ored);
auto anded = builder.create<ltl::AndOp>(loc, operands); auto anded = ltl::AndOp::create(builder, loc, operands);
return builder.create<ltl::OrOp>(loc, return ltl::OrOp::create(builder, loc,
SmallVector<Value, 2>{notOred, anded}); SmallVector<Value, 2>{notOred, anded});
} }
case BinaryAssertionOperator::Until: case BinaryAssertionOperator::Until:
return builder.create<ltl::UntilOp>(loc, operands); return ltl::UntilOp::create(builder, loc, operands);
case BinaryAssertionOperator::UntilWith: { case BinaryAssertionOperator::UntilWith: {
auto untilOp = builder.create<ltl::UntilOp>(loc, operands); auto untilOp = ltl::UntilOp::create(builder, loc, operands);
auto andOp = builder.create<ltl::AndOp>(loc, operands); auto andOp = ltl::AndOp::create(builder, loc, operands);
auto notUntil = builder.create<ltl::NotOp>(loc, untilOp); auto notUntil = ltl::NotOp::create(builder, loc, untilOp);
return builder.create<ltl::OrOp>(loc, return ltl::OrOp::create(builder, loc,
SmallVector<Value, 2>{notUntil, andOp}); SmallVector<Value, 2>{notUntil, andOp});
} }
case BinaryAssertionOperator::Implies: { case BinaryAssertionOperator::Implies: {
auto notLhs = builder.create<ltl::NotOp>(loc, lhs); auto notLhs = ltl::NotOp::create(builder, loc, lhs);
return builder.create<ltl::OrOp>(loc, SmallVector<Value, 2>{notLhs, rhs}); return ltl::OrOp::create(builder, loc,
SmallVector<Value, 2>{notLhs, rhs});
} }
case BinaryAssertionOperator::OverlappedImplication: case BinaryAssertionOperator::OverlappedImplication:
return builder.create<ltl::ImplicationOp>(loc, operands); return ltl::ImplicationOp::create(builder, loc, operands);
case BinaryAssertionOperator::NonOverlappedImplication: { case BinaryAssertionOperator::NonOverlappedImplication: {
auto constOne = auto constOne =
builder.create<hw::ConstantOp>(loc, builder.getI1Type(), 1); hw::ConstantOp::create(builder, loc, builder.getI1Type(), 1);
auto lhsDelay = builder.create<ltl::DelayOp>( auto lhsDelay =
loc, lhs, builder.getI64IntegerAttr(1), builder.getI64IntegerAttr(0)); ltl::DelayOp::create(builder, loc, lhs, builder.getI64IntegerAttr(1),
auto antecedent = builder.create<ltl::ConcatOp>( builder.getI64IntegerAttr(0));
loc, SmallVector<Value, 2>{lhsDelay, constOne}); auto antecedent = ltl::ConcatOp::create(
return builder.create<ltl::ImplicationOp>( builder, loc, SmallVector<Value, 2>{lhsDelay, constOne});
loc, SmallVector<Value, 2>{antecedent, rhs}); return ltl::ImplicationOp::create(builder, loc,
SmallVector<Value, 2>{antecedent, rhs});
} }
case BinaryAssertionOperator::OverlappedFollowedBy: { case BinaryAssertionOperator::OverlappedFollowedBy: {
auto notRhs = builder.create<ltl::NotOp>(loc, rhs); auto notRhs = ltl::NotOp::create(builder, loc, rhs);
auto implication = builder.create<ltl::ImplicationOp>( auto implication = ltl::ImplicationOp::create(
loc, SmallVector<Value, 2>{lhs, notRhs}); builder, loc, SmallVector<Value, 2>{lhs, notRhs});
return builder.create<ltl::NotOp>(loc, implication); return ltl::NotOp::create(builder, loc, implication);
} }
case BinaryAssertionOperator::NonOverlappedFollowedBy: { case BinaryAssertionOperator::NonOverlappedFollowedBy: {
auto constOne = auto constOne =
builder.create<hw::ConstantOp>(loc, builder.getI1Type(), 1); hw::ConstantOp::create(builder, loc, builder.getI1Type(), 1);
auto notRhs = builder.create<ltl::NotOp>(loc, rhs); auto notRhs = ltl::NotOp::create(builder, loc, rhs);
auto lhsDelay = builder.create<ltl::DelayOp>( auto lhsDelay =
loc, lhs, builder.getI64IntegerAttr(1), builder.getI64IntegerAttr(0)); ltl::DelayOp::create(builder, loc, lhs, builder.getI64IntegerAttr(1),
auto antecedent = builder.create<ltl::ConcatOp>( builder.getI64IntegerAttr(0));
loc, SmallVector<Value, 2>{lhsDelay, constOne}); auto antecedent = ltl::ConcatOp::create(
auto implication = builder.create<ltl::ImplicationOp>( builder, loc, SmallVector<Value, 2>{lhsDelay, constOne});
loc, SmallVector<Value, 2>{antecedent, notRhs}); auto implication = ltl::ImplicationOp::create(
return builder.create<ltl::NotOp>(loc, implication); builder, loc, SmallVector<Value, 2>{antecedent, notRhs});
return ltl::NotOp::create(builder, loc, implication);
} }
case BinaryAssertionOperator::SUntil: case BinaryAssertionOperator::SUntil:
case BinaryAssertionOperator::SUntilWith: case BinaryAssertionOperator::SUntilWith:
@ -303,6 +309,6 @@ Value Context::convertToI1(Value value) {
return {}; return {};
} }
return builder.create<moore::ConversionOp>(value.getLoc(), return moore::ConversionOp::create(builder, value.getLoc(),
builder.getI1Type(), value); builder.getI1Type(), value);
} }

View File

@ -45,8 +45,9 @@ static Value getSelectIndex(OpBuilder &builder, Location loc, Value index,
Value newIndex = Value newIndex =
builder.createOrFold<moore::ConversionOp>(loc, intType, index); builder.createOrFold<moore::ConversionOp>(loc, intType, index);
Value offset = builder.create<moore::ConstantOp>( Value offset =
loc, intType, range.lower(), /*isSigned = */ range.lower() < 0); moore::ConstantOp::create(builder, loc, intType, range.lower(),
/*isSigned = */ range.lower() < 0);
return builder.createOrFold<moore::SubOp>(loc, newIndex, offset); return builder.createOrFold<moore::SubOp>(loc, newIndex, offset);
} }
@ -55,8 +56,8 @@ static Value getSelectIndex(OpBuilder &builder, Location loc, Value index,
Value newIndex = Value newIndex =
builder.createOrFold<moore::ConversionOp>(loc, intType, index); builder.createOrFold<moore::ConversionOp>(loc, intType, index);
Value offset = builder.create<moore::ConstantOp>( Value offset = moore::ConstantOp::create(builder, loc, intType, range.upper(),
loc, intType, range.upper(), /* isSigned = */ range.upper() < 0); /* isSigned = */ range.upper() < 0);
return builder.createOrFold<moore::SubOp>(loc, offset, newIndex); return builder.createOrFold<moore::SubOp>(loc, offset, newIndex);
} }
@ -97,22 +98,22 @@ struct ExprVisitor {
auto lowBit = constValue->integer().as<uint32_t>().value(); auto lowBit = constValue->integer().as<uint32_t>().value();
if (isLvalue) if (isLvalue)
return builder.create<moore::ExtractRefOp>( return moore::ExtractRefOp::create(builder, loc, resultType, value,
loc, resultType, value, range.translateIndex(lowBit)); range.translateIndex(lowBit));
else else
return builder.create<moore::ExtractOp>(loc, resultType, value, return moore::ExtractOp::create(builder, loc, resultType, value,
range.translateIndex(lowBit)); range.translateIndex(lowBit));
} }
auto lowBit = context.convertRvalueExpression(expr.selector()); auto lowBit = context.convertRvalueExpression(expr.selector());
if (!lowBit) if (!lowBit)
return {}; return {};
lowBit = getSelectIndex(builder, loc, lowBit, range); lowBit = getSelectIndex(builder, loc, lowBit, range);
if (isLvalue) if (isLvalue)
return builder.create<moore::DynExtractRefOp>(loc, resultType, value, return moore::DynExtractRefOp::create(builder, loc, resultType, value,
lowBit); lowBit);
else else
return builder.create<moore::DynExtractOp>(loc, resultType, value, return moore::DynExtractOp::create(builder, loc, resultType, value,
lowBit); lowBit);
} }
/// Handle range bit selections. /// Handle range bit selections.
@ -200,10 +201,11 @@ struct ExprVisitor {
// Adjust the offset such that it matches the right bound of the range. // Adjust the offset such that it matches the right bound of the range.
if (offsetAdd != 0) { if (offsetAdd != 0) {
if (offsetDyn) if (offsetDyn)
offsetDyn = builder.create<moore::AddOp>( offsetDyn = moore::AddOp::create(
loc, offsetDyn, builder, loc, offsetDyn,
builder.create<moore::ConstantOp>( moore::ConstantOp::create(
loc, cast<moore::IntType>(offsetDyn.getType()), offsetAdd, builder, loc, cast<moore::IntType>(offsetDyn.getType()),
offsetAdd,
/*isSigned=*/offsetAdd < 0)); /*isSigned=*/offsetAdd < 0));
else else
offsetConst += offsetAdd; offsetConst += offsetAdd;
@ -222,20 +224,20 @@ struct ExprVisitor {
if (offsetDyn) { if (offsetDyn) {
offsetDyn = getSelectIndex(builder, loc, offsetDyn, range); offsetDyn = getSelectIndex(builder, loc, offsetDyn, range);
if (isLvalue) { if (isLvalue) {
return builder.create<moore::DynExtractRefOp>(loc, resultType, value, return moore::DynExtractRefOp::create(builder, loc, resultType, value,
offsetDyn); offsetDyn);
} else { } else {
return builder.create<moore::DynExtractOp>(loc, resultType, value, return moore::DynExtractOp::create(builder, loc, resultType, value,
offsetDyn); offsetDyn);
} }
} else { } else {
offsetConst = range.translateIndex(offsetConst); offsetConst = range.translateIndex(offsetConst);
if (isLvalue) { if (isLvalue) {
return builder.create<moore::ExtractRefOp>(loc, resultType, value, return moore::ExtractRefOp::create(builder, loc, resultType, value,
offsetConst); offsetConst);
} else { } else {
return builder.create<moore::ExtractOp>(loc, resultType, value, return moore::ExtractOp::create(builder, loc, resultType, value,
offsetConst); offsetConst);
} }
} }
} }
@ -257,9 +259,9 @@ struct ExprVisitor {
operands.push_back(value); operands.push_back(value);
} }
if (isLvalue) if (isLvalue)
return builder.create<moore::ConcatRefOp>(loc, operands); return moore::ConcatRefOp::create(builder, loc, operands);
else else
return builder.create<moore::ConcatOp>(loc, operands); return moore::ConcatOp::create(builder, loc, operands);
} }
/// Handle member accesses. /// Handle member accesses.
@ -277,21 +279,21 @@ struct ExprVisitor {
// Handle structs. // Handle structs.
if (valueType->isStruct()) { if (valueType->isStruct()) {
if (isLvalue) if (isLvalue)
return builder.create<moore::StructExtractRefOp>(loc, resultType, return moore::StructExtractRefOp::create(builder, loc, resultType,
memberName, value); memberName, value);
else else
return builder.create<moore::StructExtractOp>(loc, resultType, return moore::StructExtractOp::create(builder, loc, resultType,
memberName, value); memberName, value);
} }
// Handle unions. // Handle unions.
if (valueType->isPackedUnion() || valueType->isUnpackedUnion()) { if (valueType->isPackedUnion() || valueType->isUnpackedUnion()) {
if (isLvalue) if (isLvalue)
return builder.create<moore::UnionExtractRefOp>(loc, resultType, return moore::UnionExtractRefOp::create(builder, loc, resultType,
memberName, value); memberName, value);
else else
return builder.create<moore::UnionExtractOp>(loc, type, memberName, return moore::UnionExtractOp::create(builder, loc, type, memberName,
value); value);
} }
mlir::emitError(loc, "expression of type ") mlir::emitError(loc, "expression of type ")
@ -316,14 +318,14 @@ struct RvalueExprVisitor : public ExprVisitor {
Value visit(const slang::ast::LValueReferenceExpression &expr) { Value visit(const slang::ast::LValueReferenceExpression &expr) {
assert(!context.lvalueStack.empty() && "parent assignments push lvalue"); assert(!context.lvalueStack.empty() && "parent assignments push lvalue");
auto lvalue = context.lvalueStack.back(); auto lvalue = context.lvalueStack.back();
return builder.create<moore::ReadOp>(loc, lvalue); return moore::ReadOp::create(builder, loc, lvalue);
} }
// Handle named values, such as references to declared variables. // Handle named values, such as references to declared variables.
Value visit(const slang::ast::NamedValueExpression &expr) { Value visit(const slang::ast::NamedValueExpression &expr) {
if (auto value = context.valueSymbols.lookup(&expr.symbol)) { if (auto value = context.valueSymbols.lookup(&expr.symbol)) {
if (isa<moore::RefType>(value.getType())) { if (isa<moore::RefType>(value.getType())) {
auto readOp = builder.create<moore::ReadOp>(loc, value); auto readOp = moore::ReadOp::create(builder, loc, value);
if (context.rvalueReadCallback) if (context.rvalueReadCallback)
context.rvalueReadCallback(readOp); context.rvalueReadCallback(readOp);
value = readOp.getResult(); value = readOp.getResult();
@ -349,7 +351,7 @@ struct RvalueExprVisitor : public ExprVisitor {
auto hierLoc = context.convertLocation(expr.symbol.location); auto hierLoc = context.convertLocation(expr.symbol.location);
if (auto value = context.valueSymbols.lookup(&expr.symbol)) { if (auto value = context.valueSymbols.lookup(&expr.symbol)) {
if (isa<moore::RefType>(value.getType())) { if (isa<moore::RefType>(value.getType())) {
auto readOp = builder.create<moore::ReadOp>(hierLoc, value); auto readOp = moore::ReadOp::create(builder, hierLoc, value);
if (context.rvalueReadCallback) if (context.rvalueReadCallback)
context.rvalueReadCallback(readOp); context.rvalueReadCallback(readOp);
value = readOp.getResult(); value = readOp.getResult();
@ -394,9 +396,9 @@ struct RvalueExprVisitor : public ExprVisitor {
} }
if (expr.isNonBlocking()) if (expr.isNonBlocking())
builder.create<moore::NonBlockingAssignOp>(loc, lhs, rhs); moore::NonBlockingAssignOp::create(builder, loc, lhs, rhs);
else else
builder.create<moore::BlockingAssignOp>(loc, lhs, rhs); moore::BlockingAssignOp::create(builder, loc, lhs, rhs);
return rhs; return rhs;
} }
@ -407,21 +409,21 @@ struct RvalueExprVisitor : public ExprVisitor {
arg = context.convertToSimpleBitVector(arg); arg = context.convertToSimpleBitVector(arg);
if (!arg) if (!arg)
return {}; return {};
Value result = builder.create<ConcreteOp>(loc, arg); Value result = ConcreteOp::create(builder, loc, arg);
if (invert) if (invert)
result = builder.create<moore::NotOp>(loc, result); result = moore::NotOp::create(builder, loc, result);
return result; return result;
} }
// Helper function to create pre and post increments and decrements. // Helper function to create pre and post increments and decrements.
Value createIncrement(Value arg, bool isInc, bool isPost) { Value createIncrement(Value arg, bool isInc, bool isPost) {
auto preValue = builder.create<moore::ReadOp>(loc, arg); auto preValue = moore::ReadOp::create(builder, loc, arg);
auto one = builder.create<moore::ConstantOp>( auto one = moore::ConstantOp::create(
loc, cast<moore::IntType>(preValue.getType()), 1); builder, loc, cast<moore::IntType>(preValue.getType()), 1);
auto postValue = auto postValue =
isInc ? builder.create<moore::AddOp>(loc, preValue, one).getResult() isInc ? moore::AddOp::create(builder, loc, preValue, one).getResult()
: builder.create<moore::SubOp>(loc, preValue, one).getResult(); : moore::SubOp::create(builder, loc, preValue, one).getResult();
builder.create<moore::BlockingAssignOp>(loc, arg, postValue); moore::BlockingAssignOp::create(builder, loc, arg, postValue);
if (isPost) if (isPost)
return preValue; return preValue;
return postValue; return postValue;
@ -451,13 +453,13 @@ struct RvalueExprVisitor : public ExprVisitor {
arg = context.convertToSimpleBitVector(arg); arg = context.convertToSimpleBitVector(arg);
if (!arg) if (!arg)
return {}; return {};
return builder.create<moore::NegOp>(loc, arg); return moore::NegOp::create(builder, loc, arg);
case UnaryOperator::BitwiseNot: case UnaryOperator::BitwiseNot:
arg = context.convertToSimpleBitVector(arg); arg = context.convertToSimpleBitVector(arg);
if (!arg) if (!arg)
return {}; return {};
return builder.create<moore::NotOp>(loc, arg); return moore::NotOp::create(builder, loc, arg);
case UnaryOperator::BitwiseAnd: case UnaryOperator::BitwiseAnd:
return createReduction<moore::ReduceAndOp>(arg, false); return createReduction<moore::ReduceAndOp>(arg, false);
@ -476,7 +478,7 @@ struct RvalueExprVisitor : public ExprVisitor {
arg = context.convertToBool(arg); arg = context.convertToBool(arg);
if (!arg) if (!arg)
return {}; return {};
return builder.create<moore::NotOp>(loc, arg); return moore::NotOp::create(builder, loc, arg);
case UnaryOperator::Preincrement: case UnaryOperator::Preincrement:
return createIncrement(arg, true, false); return createIncrement(arg, true, false);
@ -502,7 +504,7 @@ struct RvalueExprVisitor : public ExprVisitor {
rhs = context.convertToSimpleBitVector(rhs); rhs = context.convertToSimpleBitVector(rhs);
if (!rhs) if (!rhs)
return {}; return {};
return builder.create<ConcreteOp>(loc, lhs, rhs); return ConcreteOp::create(builder, loc, lhs, rhs);
} }
// Handle binary operators. // Handle binary operators.
@ -544,7 +546,7 @@ struct RvalueExprVisitor : public ExprVisitor {
// maintain uniform types across operands and results, cast the RHS to // maintain uniform types across operands and results, cast the RHS to
// that four-valued type as well. // that four-valued type as well.
auto rhsCast = auto rhsCast =
builder.create<moore::ConversionOp>(loc, lhs.getType(), rhs); moore::ConversionOp::create(builder, loc, lhs.getType(), rhs);
if (expr.type->isSigned()) if (expr.type->isSigned())
return createBinary<moore::PowSOp>(lhs, rhsCast); return createBinary<moore::PowSOp>(lhs, rhsCast);
else else
@ -561,25 +563,25 @@ struct RvalueExprVisitor : public ExprVisitor {
auto result = createBinary<moore::XorOp>(lhs, rhs); auto result = createBinary<moore::XorOp>(lhs, rhs);
if (!result) if (!result)
return {}; return {};
return builder.create<moore::NotOp>(loc, result); return moore::NotOp::create(builder, loc, result);
} }
case BinaryOperator::Equality: case BinaryOperator::Equality:
if (isa<moore::UnpackedArrayType>(lhs.getType())) if (isa<moore::UnpackedArrayType>(lhs.getType()))
return builder.create<moore::UArrayCmpOp>( return moore::UArrayCmpOp::create(
loc, moore::UArrayCmpPredicate::eq, lhs, rhs); builder, loc, moore::UArrayCmpPredicate::eq, lhs, rhs);
else if (isa<moore::StringType>(lhs.getType())) else if (isa<moore::StringType>(lhs.getType()))
return builder.create<moore::StringCmpOp>( return moore::StringCmpOp::create(
loc, moore::StringCmpPredicate::eq, lhs, rhs); builder, loc, moore::StringCmpPredicate::eq, lhs, rhs);
else else
return createBinary<moore::EqOp>(lhs, rhs); return createBinary<moore::EqOp>(lhs, rhs);
case BinaryOperator::Inequality: case BinaryOperator::Inequality:
if (isa<moore::UnpackedArrayType>(lhs.getType())) if (isa<moore::UnpackedArrayType>(lhs.getType()))
return builder.create<moore::UArrayCmpOp>( return moore::UArrayCmpOp::create(
loc, moore::UArrayCmpPredicate::ne, lhs, rhs); builder, loc, moore::UArrayCmpPredicate::ne, lhs, rhs);
else if (isa<moore::StringType>(lhs.getType())) else if (isa<moore::StringType>(lhs.getType()))
return builder.create<moore::StringCmpOp>( return moore::StringCmpOp::create(
loc, moore::StringCmpPredicate::ne, lhs, rhs); builder, loc, moore::StringCmpPredicate::ne, lhs, rhs);
else else
return createBinary<moore::NeOp>(lhs, rhs); return createBinary<moore::NeOp>(lhs, rhs);
case BinaryOperator::CaseEquality: case BinaryOperator::CaseEquality:
@ -595,32 +597,32 @@ struct RvalueExprVisitor : public ExprVisitor {
if (expr.left().type->isSigned()) if (expr.left().type->isSigned())
return createBinary<moore::SgeOp>(lhs, rhs); return createBinary<moore::SgeOp>(lhs, rhs);
else if (isa<moore::StringType>(lhs.getType())) else if (isa<moore::StringType>(lhs.getType()))
return builder.create<moore::StringCmpOp>( return moore::StringCmpOp::create(
loc, moore::StringCmpPredicate::ge, lhs, rhs); builder, loc, moore::StringCmpPredicate::ge, lhs, rhs);
else else
return createBinary<moore::UgeOp>(lhs, rhs); return createBinary<moore::UgeOp>(lhs, rhs);
case BinaryOperator::GreaterThan: case BinaryOperator::GreaterThan:
if (expr.left().type->isSigned()) if (expr.left().type->isSigned())
return createBinary<moore::SgtOp>(lhs, rhs); return createBinary<moore::SgtOp>(lhs, rhs);
else if (isa<moore::StringType>(lhs.getType())) else if (isa<moore::StringType>(lhs.getType()))
return builder.create<moore::StringCmpOp>( return moore::StringCmpOp::create(
loc, moore::StringCmpPredicate::gt, lhs, rhs); builder, loc, moore::StringCmpPredicate::gt, lhs, rhs);
else else
return createBinary<moore::UgtOp>(lhs, rhs); return createBinary<moore::UgtOp>(lhs, rhs);
case BinaryOperator::LessThanEqual: case BinaryOperator::LessThanEqual:
if (expr.left().type->isSigned()) if (expr.left().type->isSigned())
return createBinary<moore::SleOp>(lhs, rhs); return createBinary<moore::SleOp>(lhs, rhs);
else if (isa<moore::StringType>(lhs.getType())) else if (isa<moore::StringType>(lhs.getType()))
return builder.create<moore::StringCmpOp>( return moore::StringCmpOp::create(
loc, moore::StringCmpPredicate::le, lhs, rhs); builder, loc, moore::StringCmpPredicate::le, lhs, rhs);
else else
return createBinary<moore::UleOp>(lhs, rhs); return createBinary<moore::UleOp>(lhs, rhs);
case BinaryOperator::LessThan: case BinaryOperator::LessThan:
if (expr.left().type->isSigned()) if (expr.left().type->isSigned())
return createBinary<moore::SltOp>(lhs, rhs); return createBinary<moore::SltOp>(lhs, rhs);
else if (isa<moore::StringType>(lhs.getType())) else if (isa<moore::StringType>(lhs.getType()))
return builder.create<moore::StringCmpOp>( return moore::StringCmpOp::create(
loc, moore::StringCmpPredicate::lt, lhs, rhs); builder, loc, moore::StringCmpPredicate::lt, lhs, rhs);
else else
return createBinary<moore::UltOp>(lhs, rhs); return createBinary<moore::UltOp>(lhs, rhs);
@ -634,7 +636,7 @@ struct RvalueExprVisitor : public ExprVisitor {
rhs = context.convertToBool(rhs, domain); rhs = context.convertToBool(rhs, domain);
if (!rhs) if (!rhs)
return {}; return {};
return builder.create<moore::AndOp>(loc, lhs, rhs); return moore::AndOp::create(builder, loc, lhs, rhs);
} }
case BinaryOperator::LogicalOr: { case BinaryOperator::LogicalOr: {
// TODO: This should short-circuit. Put the RHS code into a separate // TODO: This should short-circuit. Put the RHS code into a separate
@ -645,7 +647,7 @@ struct RvalueExprVisitor : public ExprVisitor {
rhs = context.convertToBool(rhs, domain); rhs = context.convertToBool(rhs, domain);
if (!rhs) if (!rhs)
return {}; return {};
return builder.create<moore::OrOp>(loc, lhs, rhs); return moore::OrOp::create(builder, loc, lhs, rhs);
} }
case BinaryOperator::LogicalImplication: { case BinaryOperator::LogicalImplication: {
// `(lhs -> rhs)` equivalent to `(!lhs || rhs)`. // `(lhs -> rhs)` equivalent to `(!lhs || rhs)`.
@ -655,8 +657,8 @@ struct RvalueExprVisitor : public ExprVisitor {
rhs = context.convertToBool(rhs, domain); rhs = context.convertToBool(rhs, domain);
if (!rhs) if (!rhs)
return {}; return {};
auto notLHS = builder.create<moore::NotOp>(loc, lhs); auto notLHS = moore::NotOp::create(builder, loc, lhs);
return builder.create<moore::OrOp>(loc, notLHS, rhs); return moore::OrOp::create(builder, loc, notLHS, rhs);
} }
case BinaryOperator::LogicalEquivalence: { case BinaryOperator::LogicalEquivalence: {
// `(lhs <-> rhs)` equivalent to `(lhs && rhs) || (!lhs && !rhs)`. // `(lhs <-> rhs)` equivalent to `(lhs && rhs) || (!lhs && !rhs)`.
@ -666,11 +668,11 @@ struct RvalueExprVisitor : public ExprVisitor {
rhs = context.convertToBool(rhs, domain); rhs = context.convertToBool(rhs, domain);
if (!rhs) if (!rhs)
return {}; return {};
auto notLHS = builder.create<moore::NotOp>(loc, lhs); auto notLHS = moore::NotOp::create(builder, loc, lhs);
auto notRHS = builder.create<moore::NotOp>(loc, rhs); auto notRHS = moore::NotOp::create(builder, loc, rhs);
auto both = builder.create<moore::AndOp>(loc, lhs, rhs); auto both = moore::AndOp::create(builder, loc, lhs, rhs);
auto notBoth = builder.create<moore::AndOp>(loc, notLHS, notRHS); auto notBoth = moore::AndOp::create(builder, loc, notLHS, notRHS);
return builder.create<moore::OrOp>(loc, both, notBoth); return moore::OrOp::create(builder, loc, both, notBoth);
} }
case BinaryOperator::LogicalShiftLeft: case BinaryOperator::LogicalShiftLeft:
@ -687,8 +689,8 @@ struct RvalueExprVisitor : public ExprVisitor {
if (!lhs || !rhs) if (!lhs || !rhs)
return {}; return {};
if (expr.type->isSigned()) if (expr.type->isSigned())
return builder.create<moore::AShrOp>(loc, lhs, rhs); return moore::AShrOp::create(builder, loc, lhs, rhs);
return builder.create<moore::ShrOp>(loc, lhs, rhs); return moore::ShrOp::create(builder, loc, lhs, rhs);
} }
} }
@ -712,7 +714,7 @@ struct RvalueExprVisitor : public ExprVisitor {
auto value = context.convertRvalueExpression(expr.concat()); auto value = context.convertRvalueExpression(expr.concat());
if (!value) if (!value)
return {}; return {};
return builder.create<moore::ReplicateOp>(loc, type, value); return moore::ReplicateOp::create(builder, loc, type, value);
} }
// Handle set membership operator. // Handle set membership operator.
@ -743,17 +745,17 @@ struct RvalueExprVisitor : public ExprVisitor {
// within the range. // within the range.
if (openRange->left().type->isSigned() || if (openRange->left().type->isSigned() ||
expr.left().type->isSigned()) { expr.left().type->isSigned()) {
leftValue = builder.create<moore::SgeOp>(loc, lhs, lowBound); leftValue = moore::SgeOp::create(builder, loc, lhs, lowBound);
} else { } else {
leftValue = builder.create<moore::UgeOp>(loc, lhs, lowBound); leftValue = moore::UgeOp::create(builder, loc, lhs, lowBound);
} }
if (openRange->right().type->isSigned() || if (openRange->right().type->isSigned() ||
expr.left().type->isSigned()) { expr.left().type->isSigned()) {
rightValue = builder.create<moore::SleOp>(loc, lhs, highBound); rightValue = moore::SleOp::create(builder, loc, lhs, highBound);
} else { } else {
rightValue = builder.create<moore::UleOp>(loc, lhs, highBound); rightValue = moore::UleOp::create(builder, loc, lhs, highBound);
} }
cond = builder.create<moore::AndOp>(loc, leftValue, rightValue); cond = moore::AndOp::create(builder, loc, leftValue, rightValue);
} else { } else {
// Handle expressions. // Handle expressions.
if (!listExpr->type->isIntegral()) { if (!listExpr->type->isIntegral()) {
@ -771,7 +773,7 @@ struct RvalueExprVisitor : public ExprVisitor {
context.convertRvalueExpression(*listExpr)); context.convertRvalueExpression(*listExpr));
if (!value) if (!value)
return {}; return {};
cond = builder.create<moore::WildcardEqOp>(loc, lhs, value); cond = moore::WildcardEqOp::create(builder, loc, lhs, value);
} }
conditions.push_back(cond); conditions.push_back(cond);
} }
@ -780,7 +782,7 @@ struct RvalueExprVisitor : public ExprVisitor {
auto result = conditions.back(); auto result = conditions.back();
conditions.pop_back(); conditions.pop_back();
while (!conditions.empty()) { while (!conditions.empty()) {
result = builder.create<moore::OrOp>(loc, conditions.back(), result); result = moore::OrOp::create(builder, loc, conditions.back(), result);
conditions.pop_back(); conditions.pop_back();
} }
return result; return result;
@ -805,7 +807,8 @@ struct RvalueExprVisitor : public ExprVisitor {
context.convertToBool(context.convertRvalueExpression(*cond.expr)); context.convertToBool(context.convertRvalueExpression(*cond.expr));
if (!value) if (!value)
return {}; return {};
auto conditionalOp = builder.create<moore::ConditionalOp>(loc, type, value); auto conditionalOp =
moore::ConditionalOp::create(builder, loc, type, value);
// Create blocks for true region and false region. // Create blocks for true region and false region.
auto &trueBlock = conditionalOp.getTrueRegion().emplaceBlock(); auto &trueBlock = conditionalOp.getTrueRegion().emplaceBlock();
@ -818,14 +821,14 @@ struct RvalueExprVisitor : public ExprVisitor {
auto trueValue = context.convertRvalueExpression(expr.left(), type); auto trueValue = context.convertRvalueExpression(expr.left(), type);
if (!trueValue) if (!trueValue)
return {}; return {};
builder.create<moore::YieldOp>(loc, trueValue); moore::YieldOp::create(builder, loc, trueValue);
// Handle right expression. // Handle right expression.
builder.setInsertionPointToStart(&falseBlock); builder.setInsertionPointToStart(&falseBlock);
auto falseValue = context.convertRvalueExpression(expr.right(), type); auto falseValue = context.convertRvalueExpression(expr.right(), type);
if (!falseValue) if (!falseValue)
return {}; return {};
builder.create<moore::YieldOp>(loc, falseValue); moore::YieldOp::create(builder, loc, falseValue);
return conditionalOp.getResult(); return conditionalOp.getResult();
} }
@ -880,15 +883,15 @@ struct RvalueExprVisitor : public ExprVisitor {
// Create the call. // Create the call.
auto callOp = auto callOp =
builder.create<mlir::func::CallOp>(loc, lowering->op, arguments); mlir::func::CallOp::create(builder, loc, lowering->op, arguments);
// For calls to void functions we need to have a value to return from this // For calls to void functions we need to have a value to return from this
// function. Create a dummy `unrealized_conversion_cast`, which will get // function. Create a dummy `unrealized_conversion_cast`, which will get
// deleted again later on. // deleted again later on.
if (callOp.getNumResults() == 0) if (callOp.getNumResults() == 0)
return builder return mlir::UnrealizedConversionCastOp::create(
.create<mlir::UnrealizedConversionCastOp>( builder, loc, moore::VoidType::get(context.getContext()),
loc, moore::VoidType::get(context.getContext()), ValueRange{}) ValueRange{})
.getResult(0); .getResult(0);
return callOp.getResult(0); return callOp.getResult(0);
@ -919,13 +922,13 @@ struct RvalueExprVisitor : public ExprVisitor {
/// Handle string literals. /// Handle string literals.
Value visit(const slang::ast::StringLiteral &expr) { Value visit(const slang::ast::StringLiteral &expr) {
auto type = context.convertType(*expr.type); auto type = context.convertType(*expr.type);
return builder.create<moore::StringConstantOp>(loc, type, expr.getValue()); return moore::StringConstantOp::create(builder, loc, type, expr.getValue());
} }
/// Handle real literals. /// Handle real literals.
Value visit(const slang::ast::RealLiteral &expr) { Value visit(const slang::ast::RealLiteral &expr) {
return builder.create<moore::RealLiteralOp>( return moore::RealLiteralOp::create(
loc, builder.getF64FloatAttr(expr.getValue())); builder, loc, builder.getF64FloatAttr(expr.getValue()));
} }
/// Handle assignment patterns. /// Handle assignment patterns.
@ -952,31 +955,31 @@ struct RvalueExprVisitor : public ExprVisitor {
if (auto intType = dyn_cast<moore::IntType>(type)) { if (auto intType = dyn_cast<moore::IntType>(type)) {
assert(intType.getWidth() == elements.size()); assert(intType.getWidth() == elements.size());
std::reverse(elements.begin(), elements.end()); std::reverse(elements.begin(), elements.end());
return builder.create<moore::ConcatOp>(loc, intType, elements); return moore::ConcatOp::create(builder, loc, intType, elements);
} }
// Handle packed structs. // Handle packed structs.
if (auto structType = dyn_cast<moore::StructType>(type)) { if (auto structType = dyn_cast<moore::StructType>(type)) {
assert(structType.getMembers().size() == elements.size()); assert(structType.getMembers().size() == elements.size());
return builder.create<moore::StructCreateOp>(loc, structType, elements); return moore::StructCreateOp::create(builder, loc, structType, elements);
} }
// Handle unpacked structs. // Handle unpacked structs.
if (auto structType = dyn_cast<moore::UnpackedStructType>(type)) { if (auto structType = dyn_cast<moore::UnpackedStructType>(type)) {
assert(structType.getMembers().size() == elements.size()); assert(structType.getMembers().size() == elements.size());
return builder.create<moore::StructCreateOp>(loc, structType, elements); return moore::StructCreateOp::create(builder, loc, structType, elements);
} }
// Handle packed arrays. // Handle packed arrays.
if (auto arrayType = dyn_cast<moore::ArrayType>(type)) { if (auto arrayType = dyn_cast<moore::ArrayType>(type)) {
assert(arrayType.getSize() == elements.size()); assert(arrayType.getSize() == elements.size());
return builder.create<moore::ArrayCreateOp>(loc, arrayType, elements); return moore::ArrayCreateOp::create(builder, loc, arrayType, elements);
} }
// Handle unpacked arrays. // Handle unpacked arrays.
if (auto arrayType = dyn_cast<moore::UnpackedArrayType>(type)) { if (auto arrayType = dyn_cast<moore::UnpackedArrayType>(type)) {
assert(arrayType.getSize() == elements.size()); assert(arrayType.getSize() == elements.size());
return builder.create<moore::ArrayCreateOp>(loc, arrayType, elements); return moore::ArrayCreateOp::create(builder, loc, arrayType, elements);
} }
mlir::emitError(loc) << "unsupported assignment pattern with type " << type; mlir::emitError(loc) << "unsupported assignment pattern with type " << type;
@ -1032,7 +1035,7 @@ struct RvalueExprVisitor : public ExprVisitor {
// error. // error.
value = operands.front(); value = operands.front();
} else { } else {
value = builder.create<moore::ConcatOp>(loc, operands).getResult(); value = moore::ConcatOp::create(builder, loc, operands).getResult();
} }
if (expr.sliceSize == 0) { if (expr.sliceSize == 0) {
@ -1048,8 +1051,8 @@ struct RvalueExprVisitor : public ExprVisitor {
auto extractResultType = moore::IntType::get( auto extractResultType = moore::IntType::get(
context.getContext(), expr.sliceSize, type.getDomain()); context.getContext(), expr.sliceSize, type.getDomain());
auto extracted = builder.create<moore::ExtractOp>( auto extracted = moore::ExtractOp::create(builder, loc, extractResultType,
loc, extractResultType, value, i * expr.sliceSize); value, i * expr.sliceSize);
slicedOperands.push_back(extracted); slicedOperands.push_back(extracted);
} }
// Handle other wire // Handle other wire
@ -1057,12 +1060,12 @@ struct RvalueExprVisitor : public ExprVisitor {
auto extractResultType = moore::IntType::get( auto extractResultType = moore::IntType::get(
context.getContext(), remainSize, type.getDomain()); context.getContext(), remainSize, type.getDomain());
auto extracted = builder.create<moore::ExtractOp>( auto extracted = moore::ExtractOp::create(
loc, extractResultType, value, iterMax * expr.sliceSize); builder, loc, extractResultType, value, iterMax * expr.sliceSize);
slicedOperands.push_back(extracted); slicedOperands.push_back(extracted);
} }
return builder.create<moore::ConcatOp>(loc, slicedOperands); return moore::ConcatOp::create(builder, loc, slicedOperands);
} }
Value visit(const slang::ast::AssertionInstanceExpression &expr) { Value visit(const slang::ast::AssertionInstanceExpression &expr) {
@ -1151,7 +1154,7 @@ struct LvalueExprVisitor : public ExprVisitor {
// error. // error.
value = operands.front(); value = operands.front();
} else { } else {
value = builder.create<moore::ConcatRefOp>(loc, operands).getResult(); value = moore::ConcatRefOp::create(builder, loc, operands).getResult();
} }
if (expr.sliceSize == 0) { if (expr.sliceSize == 0) {
@ -1170,8 +1173,8 @@ struct LvalueExprVisitor : public ExprVisitor {
auto extractResultType = moore::RefType::get( auto extractResultType = moore::RefType::get(
moore::IntType::get(context.getContext(), expr.sliceSize, domain)); moore::IntType::get(context.getContext(), expr.sliceSize, domain));
auto extracted = builder.create<moore::ExtractRefOp>( auto extracted = moore::ExtractRefOp::create(
loc, extractResultType, value, i * expr.sliceSize); builder, loc, extractResultType, value, i * expr.sliceSize);
slicedOperands.push_back(extracted); slicedOperands.push_back(extracted);
} }
// Handle other wire // Handle other wire
@ -1179,12 +1182,12 @@ struct LvalueExprVisitor : public ExprVisitor {
auto extractResultType = moore::RefType::get( auto extractResultType = moore::RefType::get(
moore::IntType::get(context.getContext(), remainSize, domain)); moore::IntType::get(context.getContext(), remainSize, domain));
auto extracted = builder.create<moore::ExtractRefOp>( auto extracted = moore::ExtractRefOp::create(
loc, extractResultType, value, iterMax * expr.sliceSize); builder, loc, extractResultType, value, iterMax * expr.sliceSize);
slicedOperands.push_back(extracted); slicedOperands.push_back(extracted);
} }
return builder.create<moore::ConcatRefOp>(loc, slicedOperands); return moore::ConcatRefOp::create(builder, loc, slicedOperands);
} }
/// Emit an error for all other expressions. /// Emit an error for all other expressions.
@ -1228,7 +1231,7 @@ Value Context::convertToBool(Value value) {
if (type.getBitSize() == 1) if (type.getBitSize() == 1)
return value; return value;
if (auto type = dyn_cast_or_null<moore::UnpackedType>(value.getType())) if (auto type = dyn_cast_or_null<moore::UnpackedType>(value.getType()))
return builder.create<moore::BoolCastOp>(value.getLoc(), value); return moore::BoolCastOp::create(builder, value.getLoc(), value);
mlir::emitError(value.getLoc(), "expression of type ") mlir::emitError(value.getLoc(), "expression of type ")
<< value.getType() << " cannot be cast to a boolean"; << value.getType() << " cannot be cast to a boolean";
return {}; return {};
@ -1250,9 +1253,9 @@ Value Context::materializeSVInt(const slang::SVInt &svint,
fvint.hasUnknown() || typeIsFourValued fvint.hasUnknown() || typeIsFourValued
? moore::Domain::FourValued ? moore::Domain::FourValued
: moore::Domain::TwoValued); : moore::Domain::TwoValued);
Value result = builder.create<moore::ConstantOp>(loc, intType, fvint); Value result = moore::ConstantOp::create(builder, loc, intType, fvint);
if (result.getType() != type) if (result.getType() != type)
result = builder.create<moore::ConversionOp>(loc, type, result); result = moore::ConversionOp::create(builder, loc, type, result);
return result; return result;
} }
@ -1280,7 +1283,7 @@ Value Context::convertToBool(Value value, Domain domain) {
auto type = moore::IntType::get(getContext(), 1, domain); auto type = moore::IntType::get(getContext(), 1, domain);
if (value.getType() == type) if (value.getType() == type)
return value; return value;
return builder.create<moore::ConversionOp>(value.getLoc(), type, value); return moore::ConversionOp::create(builder, value.getLoc(), type, value);
} }
Value Context::convertToSimpleBitVector(Value value) { Value Context::convertToSimpleBitVector(Value value) {
@ -1297,8 +1300,8 @@ Value Context::convertToSimpleBitVector(Value value) {
if (auto bits = packed.getBitSize()) { if (auto bits = packed.getBitSize()) {
auto sbvType = auto sbvType =
moore::IntType::get(value.getContext(), *bits, packed.getDomain()); moore::IntType::get(value.getContext(), *bits, packed.getDomain());
return builder.create<moore::ConversionOp>(value.getLoc(), sbvType, return moore::ConversionOp::create(builder, value.getLoc(), sbvType,
value); value);
} }
} }
@ -1325,25 +1328,25 @@ Value Context::materializeConversion(Type type, Value value, bool isSigned,
auto srcWidthType = moore::IntType::get(value.getContext(), srcWidth, auto srcWidthType = moore::IntType::get(value.getContext(), srcWidth,
srcPacked.getDomain()); srcPacked.getDomain());
if (value.getType() != srcWidthType) if (value.getType() != srcWidthType)
value = builder.create<moore::ConversionOp>(value.getLoc(), srcWidthType, value = moore::ConversionOp::create(builder, value.getLoc(), srcWidthType,
value); value);
// Create truncation or sign/zero extension ops depending on the source and // Create truncation or sign/zero extension ops depending on the source and
// destination width. // destination width.
auto dstWidthType = moore::IntType::get(value.getContext(), dstWidth, auto dstWidthType = moore::IntType::get(value.getContext(), dstWidth,
srcPacked.getDomain()); srcPacked.getDomain());
if (dstWidth < srcWidth) { if (dstWidth < srcWidth) {
value = builder.create<moore::TruncOp>(loc, dstWidthType, value); value = moore::TruncOp::create(builder, loc, dstWidthType, value);
} else if (dstWidth > srcWidth) { } else if (dstWidth > srcWidth) {
if (isSigned) if (isSigned)
value = builder.create<moore::SExtOp>(loc, dstWidthType, value); value = moore::SExtOp::create(builder, loc, dstWidthType, value);
else else
value = builder.create<moore::ZExtOp>(loc, dstWidthType, value); value = moore::ZExtOp::create(builder, loc, dstWidthType, value);
} }
} }
if (value.getType() != type) if (value.getType() != type)
value = builder.create<moore::ConversionOp>(loc, type, value); value = moore::ConversionOp::create(builder, loc, type, value);
return value; return value;
} }
@ -1362,79 +1365,79 @@ Context::convertSystemCallArity1(const slang::ast::SystemSubroutine &subroutine,
value = convertToSimpleBitVector(value); value = convertToSimpleBitVector(value);
if (!value) if (!value)
return failure(); return failure();
return (Value)builder.create<moore::Clog2BIOp>(loc, value); return (Value)moore::Clog2BIOp::create(builder, loc, value);
}) })
.Case("$ln", .Case("$ln",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::LnBIOp>(loc, value); return moore::LnBIOp::create(builder, loc, value);
}) })
.Case("$log10", .Case("$log10",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::Log10BIOp>(loc, value); return moore::Log10BIOp::create(builder, loc, value);
}) })
.Case("$sin", .Case("$sin",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::SinBIOp>(loc, value); return moore::SinBIOp::create(builder, loc, value);
}) })
.Case("$cos", .Case("$cos",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::CosBIOp>(loc, value); return moore::CosBIOp::create(builder, loc, value);
}) })
.Case("$tan", .Case("$tan",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::TanBIOp>(loc, value); return moore::TanBIOp::create(builder, loc, value);
}) })
.Case("$exp", .Case("$exp",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::ExpBIOp>(loc, value); return moore::ExpBIOp::create(builder, loc, value);
}) })
.Case("$sqrt", .Case("$sqrt",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::SqrtBIOp>(loc, value); return moore::SqrtBIOp::create(builder, loc, value);
}) })
.Case("$floor", .Case("$floor",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::FloorBIOp>(loc, value); return moore::FloorBIOp::create(builder, loc, value);
}) })
.Case("$ceil", .Case("$ceil",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::CeilBIOp>(loc, value); return moore::CeilBIOp::create(builder, loc, value);
}) })
.Case("$asin", .Case("$asin",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::AsinBIOp>(loc, value); return moore::AsinBIOp::create(builder, loc, value);
}) })
.Case("$acos", .Case("$acos",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::AcosBIOp>(loc, value); return moore::AcosBIOp::create(builder, loc, value);
}) })
.Case("$atan", .Case("$atan",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::AtanBIOp>(loc, value); return moore::AtanBIOp::create(builder, loc, value);
}) })
.Case("$sinh", .Case("$sinh",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::SinhBIOp>(loc, value); return moore::SinhBIOp::create(builder, loc, value);
}) })
.Case("$cosh", .Case("$cosh",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::CoshBIOp>(loc, value); return moore::CoshBIOp::create(builder, loc, value);
}) })
.Case("$tanh", .Case("$tanh",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::TanhBIOp>(loc, value); return moore::TanhBIOp::create(builder, loc, value);
}) })
.Case("$asinh", .Case("$asinh",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::AsinhBIOp>(loc, value); return moore::AsinhBIOp::create(builder, loc, value);
}) })
.Case("$acosh", .Case("$acosh",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::AcoshBIOp>(loc, value); return moore::AcoshBIOp::create(builder, loc, value);
}) })
.Case("$atanh", .Case("$atanh",
[&]() -> Value { [&]() -> Value {
return builder.create<moore::AtanhBIOp>(loc, value); return moore::AtanhBIOp::create(builder, loc, value);
}) })
.Default([&]() -> Value { return {}; }); .Default([&]() -> Value { return {}; });
return systemCallRes(); return systemCallRes();

View File

@ -65,7 +65,7 @@ struct FormatStringParser {
return Value{}; return Value{};
if (fragments.size() == 1) if (fragments.size() == 1)
return fragments[0]; return fragments[0];
return builder.create<moore::FormatConcatOp>(loc, fragments).getResult(); return moore::FormatConcatOp::create(builder, loc, fragments).getResult();
} }
/// Parse a format string literal and consume and format the arguments /// Parse a format string literal and consume and format the arguments
@ -93,7 +93,7 @@ struct FormatStringParser {
/// Emit a string literal that requires no additional formatting. /// Emit a string literal that requires no additional formatting.
void emitLiteral(StringRef literal) { void emitLiteral(StringRef literal) {
fragments.push_back(builder.create<moore::FormatLiteralOp>(loc, literal)); fragments.push_back(moore::FormatLiteralOp::create(builder, loc, literal));
} }
/// Consume the next argument from the list and emit it according to the given /// Consume the next argument from the list and emit it according to the given
@ -177,8 +177,8 @@ struct FormatStringParser {
auto padding = auto padding =
format == IntFormat::Decimal ? IntPadding::Space : IntPadding::Zero; format == IntFormat::Decimal ? IntPadding::Space : IntPadding::Zero;
fragments.push_back(builder.create<moore::FormatIntOp>( fragments.push_back(moore::FormatIntOp::create(builder, loc, value, format,
loc, value, format, width, alignment, padding)); width, alignment, padding));
return success(); return success();
} }

View File

@ -56,30 +56,30 @@ struct StmtVisitor {
if (!type) if (!type)
return failure(); return failure();
Value initial = builder.create<moore::ConstantOp>( Value initial = moore::ConstantOp::create(
loc, cast<moore::IntType>(type), loopDim.range->lower()); builder, loc, cast<moore::IntType>(type), loopDim.range->lower());
// Create loop varirable in this dimension // Create loop varirable in this dimension
Value varOp = builder.create<moore::VariableOp>( Value varOp = moore::VariableOp::create(
loc, moore::RefType::get(cast<moore::UnpackedType>(type)), builder, loc, moore::RefType::get(cast<moore::UnpackedType>(type)),
builder.getStringAttr(iter->name), initial); builder.getStringAttr(iter->name), initial);
context.valueSymbols.insertIntoScope(context.valueSymbols.getCurScope(), context.valueSymbols.insertIntoScope(context.valueSymbols.getCurScope(),
iter, varOp); iter, varOp);
builder.create<cf::BranchOp>(loc, &checkBlock); cf::BranchOp::create(builder, loc, &checkBlock);
builder.setInsertionPointToEnd(&checkBlock); builder.setInsertionPointToEnd(&checkBlock);
// When the loop variable is greater than the upper bound, goto exit // When the loop variable is greater than the upper bound, goto exit
auto upperBound = builder.create<moore::ConstantOp>( auto upperBound = moore::ConstantOp::create(
loc, cast<moore::IntType>(type), loopDim.range->upper()); builder, loc, cast<moore::IntType>(type), loopDim.range->upper());
auto var = builder.create<moore::ReadOp>(loc, varOp); auto var = moore::ReadOp::create(builder, loc, varOp);
Value cond = builder.create<moore::SleOp>(loc, var, upperBound); Value cond = moore::SleOp::create(builder, loc, var, upperBound);
if (!cond) if (!cond)
return failure(); return failure();
cond = builder.createOrFold<moore::BoolCastOp>(loc, cond); cond = builder.createOrFold<moore::BoolCastOp>(loc, cond);
cond = builder.create<moore::ConversionOp>(loc, builder.getI1Type(), cond); cond = moore::ConversionOp::create(builder, loc, builder.getI1Type(), cond);
builder.create<cf::CondBranchOp>(loc, cond, &bodyBlock, &exitBlock); cf::CondBranchOp::create(builder, loc, cond, &bodyBlock, &exitBlock);
builder.setInsertionPointToEnd(&bodyBlock); builder.setInsertionPointToEnd(&bodyBlock);
@ -101,17 +101,17 @@ struct StmtVisitor {
return failure(); return failure();
} }
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &stepBlock); cf::BranchOp::create(builder, loc, &stepBlock);
builder.setInsertionPointToEnd(&stepBlock); builder.setInsertionPointToEnd(&stepBlock);
// add one to loop variable // add one to loop variable
var = builder.create<moore::ReadOp>(loc, varOp); var = moore::ReadOp::create(builder, loc, varOp);
auto one = auto one =
builder.create<moore::ConstantOp>(loc, cast<moore::IntType>(type), 1); moore::ConstantOp::create(builder, loc, cast<moore::IntType>(type), 1);
auto postValue = builder.create<moore::AddOp>(loc, var, one).getResult(); auto postValue = moore::AddOp::create(builder, loc, var, one).getResult();
builder.create<moore::BlockingAssignOp>(loc, varOp, postValue); moore::BlockingAssignOp::create(builder, loc, varOp, postValue);
builder.create<cf::BranchOp>(loc, &checkBlock); cf::BranchOp::create(builder, loc, &checkBlock);
if (exitBlock.hasNoPredecessors()) { if (exitBlock.hasNoPredecessors()) {
exitBlock.erase(); exitBlock.erase();
@ -193,8 +193,8 @@ struct StmtVisitor {
} }
// Collect local temporary variables. // Collect local temporary variables.
auto varOp = builder.create<moore::VariableOp>( auto varOp = moore::VariableOp::create(
loc, moore::RefType::get(cast<moore::UnpackedType>(type)), builder, loc, moore::RefType::get(cast<moore::UnpackedType>(type)),
builder.getStringAttr(var.name), initial); builder.getStringAttr(var.name), initial);
context.valueSymbols.insertIntoScope(context.valueSymbols.getCurScope(), context.valueSymbols.insertIntoScope(context.valueSymbols.getCurScope(),
&var, varOp); &var, varOp);
@ -215,27 +215,27 @@ struct StmtVisitor {
return failure(); return failure();
cond = builder.createOrFold<moore::BoolCastOp>(loc, cond); cond = builder.createOrFold<moore::BoolCastOp>(loc, cond);
if (allConds) if (allConds)
allConds = builder.create<moore::AndOp>(loc, allConds, cond); allConds = moore::AndOp::create(builder, loc, allConds, cond);
else else
allConds = cond; allConds = cond;
} }
assert(allConds && "slang guarantees at least one condition"); assert(allConds && "slang guarantees at least one condition");
allConds = allConds = moore::ConversionOp::create(builder, loc, builder.getI1Type(),
builder.create<moore::ConversionOp>(loc, builder.getI1Type(), allConds); allConds);
// Create the blocks for the true and false branches, and the exit block. // Create the blocks for the true and false branches, and the exit block.
Block &exitBlock = createBlock(); Block &exitBlock = createBlock();
Block *falseBlock = stmt.ifFalse ? &createBlock() : nullptr; Block *falseBlock = stmt.ifFalse ? &createBlock() : nullptr;
Block &trueBlock = createBlock(); Block &trueBlock = createBlock();
builder.create<cf::CondBranchOp>(loc, allConds, &trueBlock, cf::CondBranchOp::create(builder, loc, allConds, &trueBlock,
falseBlock ? falseBlock : &exitBlock); falseBlock ? falseBlock : &exitBlock);
// Generate the true branch. // Generate the true branch.
builder.setInsertionPointToEnd(&trueBlock); builder.setInsertionPointToEnd(&trueBlock);
if (failed(context.convertStatement(stmt.ifTrue))) if (failed(context.convertStatement(stmt.ifTrue)))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &exitBlock); cf::BranchOp::create(builder, loc, &exitBlock);
// Generate the false branch if present. // Generate the false branch if present.
if (stmt.ifFalse) { if (stmt.ifFalse) {
@ -243,7 +243,7 @@ struct StmtVisitor {
if (failed(context.convertStatement(*stmt.ifFalse))) if (failed(context.convertStatement(*stmt.ifFalse)))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &exitBlock); cf::BranchOp::create(builder, loc, &exitBlock);
} }
// If control never reaches the exit block, remove it and mark control flow // If control never reaches the exit block, remove it and mark control flow
@ -298,26 +298,26 @@ struct StmtVisitor {
Value cond; Value cond;
switch (caseStmt.condition) { switch (caseStmt.condition) {
case CaseStatementCondition::Normal: case CaseStatementCondition::Normal:
cond = builder.create<moore::CaseEqOp>(itemLoc, caseExpr, value); cond = moore::CaseEqOp::create(builder, itemLoc, caseExpr, value);
break; break;
case CaseStatementCondition::WildcardXOrZ: case CaseStatementCondition::WildcardXOrZ:
cond = builder.create<moore::CaseXZEqOp>(itemLoc, caseExpr, value); cond = moore::CaseXZEqOp::create(builder, itemLoc, caseExpr, value);
break; break;
case CaseStatementCondition::WildcardJustZ: case CaseStatementCondition::WildcardJustZ:
cond = builder.create<moore::CaseZEqOp>(itemLoc, caseExpr, value); cond = moore::CaseZEqOp::create(builder, itemLoc, caseExpr, value);
break; break;
case CaseStatementCondition::Inside: case CaseStatementCondition::Inside:
mlir::emitError(loc, "unsupported set membership case statement"); mlir::emitError(loc, "unsupported set membership case statement");
return failure(); return failure();
} }
cond = builder.create<moore::ConversionOp>(itemLoc, builder.getI1Type(), cond = moore::ConversionOp::create(builder, itemLoc,
cond); builder.getI1Type(), cond);
// If the condition matches, branch to the match block. Otherwise // If the condition matches, branch to the match block. Otherwise
// continue checking the next expression in a new block. // continue checking the next expression in a new block.
auto &nextBlock = createBlock(); auto &nextBlock = createBlock();
builder.create<mlir::cf::CondBranchOp>(itemLoc, cond, &matchBlock, mlir::cf::CondBranchOp::create(builder, itemLoc, cond, &matchBlock,
&nextBlock); &nextBlock);
builder.setInsertionPointToEnd(&nextBlock); builder.setInsertionPointToEnd(&nextBlock);
} }
@ -333,7 +333,7 @@ struct StmtVisitor {
return failure(); return failure();
if (!isTerminated()) { if (!isTerminated()) {
auto loc = context.convertLocation(item.stmt->sourceRange); auto loc = context.convertLocation(item.stmt->sourceRange);
builder.create<mlir::cf::BranchOp>(loc, &exitBlock); mlir::cf::BranchOp::create(builder, loc, &exitBlock);
} }
} }
@ -385,14 +385,14 @@ struct StmtVisitor {
if ((twoStateExhaustive || (hasFullCaseAttr && !caseStmt.defaultCase)) && if ((twoStateExhaustive || (hasFullCaseAttr && !caseStmt.defaultCase)) &&
lastMatchBlock && lastMatchBlock &&
caseStmt.condition == CaseStatementCondition::Normal) { caseStmt.condition == CaseStatementCondition::Normal) {
builder.create<mlir::cf::BranchOp>(loc, lastMatchBlock); mlir::cf::BranchOp::create(builder, loc, lastMatchBlock);
} else { } else {
// Generate the default case if present. // Generate the default case if present.
if (caseStmt.defaultCase) if (caseStmt.defaultCase)
if (failed(context.convertStatement(*caseStmt.defaultCase))) if (failed(context.convertStatement(*caseStmt.defaultCase)))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<mlir::cf::BranchOp>(loc, &exitBlock); mlir::cf::BranchOp::create(builder, loc, &exitBlock);
} }
// If control never reaches the exit block, remove it and mark control flow // If control never reaches the exit block, remove it and mark control flow
@ -418,7 +418,7 @@ struct StmtVisitor {
auto &stepBlock = createBlock(); auto &stepBlock = createBlock();
auto &bodyBlock = createBlock(); auto &bodyBlock = createBlock();
auto &checkBlock = createBlock(); auto &checkBlock = createBlock();
builder.create<cf::BranchOp>(loc, &checkBlock); cf::BranchOp::create(builder, loc, &checkBlock);
// Push the blocks onto the loop stack such that we can continue and break. // Push the blocks onto the loop stack such that we can continue and break.
context.loopStack.push_back({&stepBlock, &exitBlock}); context.loopStack.push_back({&stepBlock, &exitBlock});
@ -430,15 +430,15 @@ struct StmtVisitor {
if (!cond) if (!cond)
return failure(); return failure();
cond = builder.createOrFold<moore::BoolCastOp>(loc, cond); cond = builder.createOrFold<moore::BoolCastOp>(loc, cond);
cond = builder.create<moore::ConversionOp>(loc, builder.getI1Type(), cond); cond = moore::ConversionOp::create(builder, loc, builder.getI1Type(), cond);
builder.create<cf::CondBranchOp>(loc, cond, &bodyBlock, &exitBlock); cf::CondBranchOp::create(builder, loc, cond, &bodyBlock, &exitBlock);
// Generate the loop body. // Generate the loop body.
builder.setInsertionPointToEnd(&bodyBlock); builder.setInsertionPointToEnd(&bodyBlock);
if (failed(context.convertStatement(stmt.body))) if (failed(context.convertStatement(stmt.body)))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &stepBlock); cf::BranchOp::create(builder, loc, &stepBlock);
// Generate the step expressions. // Generate the step expressions.
builder.setInsertionPointToEnd(&stepBlock); builder.setInsertionPointToEnd(&stepBlock);
@ -446,7 +446,7 @@ struct StmtVisitor {
if (!context.convertRvalueExpression(*stepExpr)) if (!context.convertRvalueExpression(*stepExpr))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &checkBlock); cf::BranchOp::create(builder, loc, &checkBlock);
// If control never reaches the exit block, remove it and mark control flow // If control never reaches the exit block, remove it and mark control flow
// as terminated. Otherwise we continue inserting ops in the exit block. // as terminated. Otherwise we continue inserting ops in the exit block.
@ -479,7 +479,7 @@ struct StmtVisitor {
auto &bodyBlock = createBlock(); auto &bodyBlock = createBlock();
auto &checkBlock = createBlock(); auto &checkBlock = createBlock();
auto currentCount = checkBlock.addArgument(count.getType(), count.getLoc()); auto currentCount = checkBlock.addArgument(count.getType(), count.getLoc());
builder.create<cf::BranchOp>(loc, &checkBlock, count); cf::BranchOp::create(builder, loc, &checkBlock, count);
// Push the blocks onto the loop stack such that we can continue and break. // Push the blocks onto the loop stack such that we can continue and break.
context.loopStack.push_back({&stepBlock, &exitBlock}); context.loopStack.push_back({&stepBlock, &exitBlock});
@ -488,23 +488,23 @@ struct StmtVisitor {
// Generate the loop condition check. // Generate the loop condition check.
builder.setInsertionPointToEnd(&checkBlock); builder.setInsertionPointToEnd(&checkBlock);
auto cond = builder.createOrFold<moore::BoolCastOp>(loc, currentCount); auto cond = builder.createOrFold<moore::BoolCastOp>(loc, currentCount);
cond = builder.create<moore::ConversionOp>(loc, builder.getI1Type(), cond); cond = moore::ConversionOp::create(builder, loc, builder.getI1Type(), cond);
builder.create<cf::CondBranchOp>(loc, cond, &bodyBlock, &exitBlock); cf::CondBranchOp::create(builder, loc, cond, &bodyBlock, &exitBlock);
// Generate the loop body. // Generate the loop body.
builder.setInsertionPointToEnd(&bodyBlock); builder.setInsertionPointToEnd(&bodyBlock);
if (failed(context.convertStatement(stmt.body))) if (failed(context.convertStatement(stmt.body)))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &stepBlock); cf::BranchOp::create(builder, loc, &stepBlock);
// Decrement the current count and branch back to the check block. // Decrement the current count and branch back to the check block.
builder.setInsertionPointToEnd(&stepBlock); builder.setInsertionPointToEnd(&stepBlock);
auto one = builder.create<moore::ConstantOp>( auto one = moore::ConstantOp::create(
count.getLoc(), cast<moore::IntType>(count.getType()), 1); builder, count.getLoc(), cast<moore::IntType>(count.getType()), 1);
Value nextCount = Value nextCount =
builder.create<moore::SubOp>(count.getLoc(), currentCount, one); moore::SubOp::create(builder, count.getLoc(), currentCount, one);
builder.create<cf::BranchOp>(loc, &checkBlock, nextCount); cf::BranchOp::create(builder, loc, &checkBlock, nextCount);
// If control never reaches the exit block, remove it and mark control flow // If control never reaches the exit block, remove it and mark control flow
// as terminated. Otherwise we continue inserting ops in the exit block. // as terminated. Otherwise we continue inserting ops in the exit block.
@ -525,7 +525,7 @@ struct StmtVisitor {
auto &exitBlock = createBlock(); auto &exitBlock = createBlock();
auto &bodyBlock = createBlock(); auto &bodyBlock = createBlock();
auto &checkBlock = createBlock(); auto &checkBlock = createBlock();
builder.create<cf::BranchOp>(loc, atLeastOnce ? &bodyBlock : &checkBlock); cf::BranchOp::create(builder, loc, atLeastOnce ? &bodyBlock : &checkBlock);
if (atLeastOnce) if (atLeastOnce)
bodyBlock.moveBefore(&checkBlock); bodyBlock.moveBefore(&checkBlock);
@ -539,15 +539,15 @@ struct StmtVisitor {
if (!cond) if (!cond)
return failure(); return failure();
cond = builder.createOrFold<moore::BoolCastOp>(loc, cond); cond = builder.createOrFold<moore::BoolCastOp>(loc, cond);
cond = builder.create<moore::ConversionOp>(loc, builder.getI1Type(), cond); cond = moore::ConversionOp::create(builder, loc, builder.getI1Type(), cond);
builder.create<cf::CondBranchOp>(loc, cond, &bodyBlock, &exitBlock); cf::CondBranchOp::create(builder, loc, cond, &bodyBlock, &exitBlock);
// Generate the loop body. // Generate the loop body.
builder.setInsertionPointToEnd(&bodyBlock); builder.setInsertionPointToEnd(&bodyBlock);
if (failed(context.convertStatement(bodyStmt))) if (failed(context.convertStatement(bodyStmt)))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &checkBlock); cf::BranchOp::create(builder, loc, &checkBlock);
// If control never reaches the exit block, remove it and mark control flow // If control never reaches the exit block, remove it and mark control flow
// as terminated. Otherwise we continue inserting ops in the exit block. // as terminated. Otherwise we continue inserting ops in the exit block.
@ -573,7 +573,7 @@ struct StmtVisitor {
// Create the blocks for the loop body and exit. // Create the blocks for the loop body and exit.
auto &exitBlock = createBlock(); auto &exitBlock = createBlock();
auto &bodyBlock = createBlock(); auto &bodyBlock = createBlock();
builder.create<cf::BranchOp>(loc, &bodyBlock); cf::BranchOp::create(builder, loc, &bodyBlock);
// Push the blocks onto the loop stack such that we can continue and break. // Push the blocks onto the loop stack such that we can continue and break.
context.loopStack.push_back({&bodyBlock, &exitBlock}); context.loopStack.push_back({&bodyBlock, &exitBlock});
@ -584,7 +584,7 @@ struct StmtVisitor {
if (failed(context.convertStatement(stmt.body))) if (failed(context.convertStatement(stmt.body)))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &bodyBlock); cf::BranchOp::create(builder, loc, &bodyBlock);
// If control never reaches the exit block, remove it and mark control flow // If control never reaches the exit block, remove it and mark control flow
// as terminated. Otherwise we continue inserting ops in the exit block. // as terminated. Otherwise we continue inserting ops in the exit block.
@ -608,9 +608,9 @@ struct StmtVisitor {
auto expr = context.convertRvalueExpression(*stmt.expr); auto expr = context.convertRvalueExpression(*stmt.expr);
if (!expr) if (!expr)
return failure(); return failure();
builder.create<mlir::func::ReturnOp>(loc, expr); mlir::func::ReturnOp::create(builder, loc, expr);
} else { } else {
builder.create<mlir::func::ReturnOp>(loc); mlir::func::ReturnOp::create(builder, loc);
} }
setTerminated(); setTerminated();
return success(); return success();
@ -621,7 +621,7 @@ struct StmtVisitor {
if (context.loopStack.empty()) if (context.loopStack.empty())
return mlir::emitError(loc, return mlir::emitError(loc,
"cannot `continue` without a surrounding loop"); "cannot `continue` without a surrounding loop");
builder.create<cf::BranchOp>(loc, context.loopStack.back().continueBlock); cf::BranchOp::create(builder, loc, context.loopStack.back().continueBlock);
setTerminated(); setTerminated();
return success(); return success();
} }
@ -630,7 +630,7 @@ struct StmtVisitor {
LogicalResult visit(const slang::ast::BreakStatement &stmt) { LogicalResult visit(const slang::ast::BreakStatement &stmt) {
if (context.loopStack.empty()) if (context.loopStack.empty())
return mlir::emitError(loc, "cannot `break` without a surrounding loop"); return mlir::emitError(loc, "cannot `break` without a surrounding loop");
builder.create<cf::BranchOp>(loc, context.loopStack.back().breakBlock); cf::BranchOp::create(builder, loc, context.loopStack.back().breakBlock);
setTerminated(); setTerminated();
return success(); return success();
} }
@ -652,13 +652,13 @@ struct StmtVisitor {
switch (stmt.assertionKind) { switch (stmt.assertionKind) {
case slang::ast::AssertionKind::Assert: case slang::ast::AssertionKind::Assert:
builder.create<moore::AssertOp>(loc, defer, cond, StringAttr{}); moore::AssertOp::create(builder, loc, defer, cond, StringAttr{});
return success(); return success();
case slang::ast::AssertionKind::Assume: case slang::ast::AssertionKind::Assume:
builder.create<moore::AssumeOp>(loc, defer, cond, StringAttr{}); moore::AssumeOp::create(builder, loc, defer, cond, StringAttr{});
return success(); return success();
case slang::ast::AssertionKind::CoverProperty: case slang::ast::AssertionKind::CoverProperty:
builder.create<moore::CoverOp>(loc, defer, cond, StringAttr{}); moore::CoverOp::create(builder, loc, defer, cond, StringAttr{});
return success(); return success();
default: default:
break; break;
@ -669,21 +669,21 @@ struct StmtVisitor {
} }
// Regard assertion statements with an action block as the "if-else". // Regard assertion statements with an action block as the "if-else".
cond = builder.create<moore::ConversionOp>(loc, builder.getI1Type(), cond); cond = moore::ConversionOp::create(builder, loc, builder.getI1Type(), cond);
// Create the blocks for the true and false branches, and the exit block. // Create the blocks for the true and false branches, and the exit block.
Block &exitBlock = createBlock(); Block &exitBlock = createBlock();
Block *falseBlock = stmt.ifFalse ? &createBlock() : nullptr; Block *falseBlock = stmt.ifFalse ? &createBlock() : nullptr;
Block &trueBlock = createBlock(); Block &trueBlock = createBlock();
builder.create<cf::CondBranchOp>(loc, cond, &trueBlock, cf::CondBranchOp::create(builder, loc, cond, &trueBlock,
falseBlock ? falseBlock : &exitBlock); falseBlock ? falseBlock : &exitBlock);
// Generate the true branch. // Generate the true branch.
builder.setInsertionPointToEnd(&trueBlock); builder.setInsertionPointToEnd(&trueBlock);
if (stmt.ifTrue && failed(context.convertStatement(*stmt.ifTrue))) if (stmt.ifTrue && failed(context.convertStatement(*stmt.ifTrue)))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &exitBlock); cf::BranchOp::create(builder, loc, &exitBlock);
if (stmt.ifFalse) { if (stmt.ifFalse) {
// Generate the false branch if present. // Generate the false branch if present.
@ -691,7 +691,7 @@ struct StmtVisitor {
if (failed(context.convertStatement(*stmt.ifFalse))) if (failed(context.convertStatement(*stmt.ifFalse)))
return failure(); return failure();
if (!isTerminated()) if (!isTerminated())
builder.create<cf::BranchOp>(loc, &exitBlock); cf::BranchOp::create(builder, loc, &exitBlock);
} }
// If control never reaches the exit block, remove it and mark control flow // If control never reaches the exit block, remove it and mark control flow
@ -716,10 +716,10 @@ struct StmtVisitor {
if (stmt.ifTrue && stmt.ifTrue->as_if<slang::ast::EmptyStatement>()) { if (stmt.ifTrue && stmt.ifTrue->as_if<slang::ast::EmptyStatement>()) {
switch (stmt.assertionKind) { switch (stmt.assertionKind) {
case slang::ast::AssertionKind::Assert: case slang::ast::AssertionKind::Assert:
builder.create<verif::AssertOp>(loc, property, Value(), StringAttr{}); verif::AssertOp::create(builder, loc, property, Value(), StringAttr{});
return success(); return success();
case slang::ast::AssertionKind::Assume: case slang::ast::AssertionKind::Assume:
builder.create<verif::AssumeOp>(loc, property, Value(), StringAttr{}); verif::AssumeOp::create(builder, loc, property, Value(), StringAttr{});
return success(); return success();
default: default:
break; break;
@ -749,14 +749,14 @@ struct StmtVisitor {
if (subroutine.name == "$stop") { if (subroutine.name == "$stop") {
createFinishMessage(args.size() >= 1 ? args[0] : nullptr); createFinishMessage(args.size() >= 1 ? args[0] : nullptr);
builder.create<moore::StopBIOp>(loc); moore::StopBIOp::create(builder, loc);
return true; return true;
} }
if (subroutine.name == "$finish") { if (subroutine.name == "$finish") {
createFinishMessage(args.size() >= 1 ? args[0] : nullptr); createFinishMessage(args.size() >= 1 ? args[0] : nullptr);
builder.create<moore::FinishBIOp>(loc, 0); moore::FinishBIOp::create(builder, loc, 0);
builder.create<moore::UnreachableOp>(loc); moore::UnreachableOp::create(builder, loc);
setTerminated(); setTerminated();
return true; return true;
} }
@ -802,7 +802,7 @@ struct StmtVisitor {
return failure(); return failure();
if (*message == Value{}) if (*message == Value{})
return true; return true;
builder.create<moore::DisplayBIOp>(loc, *message); moore::DisplayBIOp::create(builder, loc, *message);
return true; return true;
} }
@ -831,15 +831,15 @@ struct StmtVisitor {
if (failed(message)) if (failed(message))
return failure(); return failure();
if (*message == Value{}) if (*message == Value{})
*message = builder.create<moore::FormatLiteralOp>(loc, ""); *message = moore::FormatLiteralOp::create(builder, loc, "");
builder.create<moore::SeverityBIOp>(loc, *severity, *message); moore::SeverityBIOp::create(builder, loc, *severity, *message);
// Handle the `$fatal` case which behaves like a `$finish`. // Handle the `$fatal` case which behaves like a `$finish`.
if (severity == Severity::Fatal) { if (severity == Severity::Fatal) {
createFinishMessage(verbosityExpr); createFinishMessage(verbosityExpr);
builder.create<moore::FinishBIOp>(loc, 1); moore::FinishBIOp::create(builder, loc, 1);
builder.create<moore::UnreachableOp>(loc); moore::UnreachableOp::create(builder, loc);
setTerminated(); setTerminated();
} }
return true; return true;
@ -861,7 +861,7 @@ struct StmtVisitor {
} }
if (verbosity == 0) if (verbosity == 0)
return; return;
builder.create<moore::FinishMessageBIOp>(loc, verbosity > 1); moore::FinishMessageBIOp::create(builder, loc, verbosity > 1);
} }
/// Emit an error for all other statements. /// Emit an error for all other statements.

View File

@ -108,8 +108,8 @@ struct BaseVisitor {
guessNamespacePrefix(param.getParentScope()->asSymbol(), paramName); guessNamespacePrefix(param.getParentScope()->asSymbol(), paramName);
paramName += param.name; paramName += param.name;
builder.create<debug::VariableOp>(loc, builder.getStringAttr(paramName), debug::VariableOp::create(builder, loc, builder.getStringAttr(paramName),
value, Value{}); value, Value{});
} }
}; };
} // namespace } // namespace
@ -296,18 +296,19 @@ struct ModuleVisitor : public BaseVisitor {
if (const auto *net = if (const auto *net =
port->internalSymbol->as_if<slang::ast::NetSymbol>()) { port->internalSymbol->as_if<slang::ast::NetSymbol>()) {
auto netOp = builder.create<moore::NetOp>( auto netOp = moore::NetOp::create(
loc, refType, StringAttr::get(builder.getContext(), net->name), builder, loc, refType,
StringAttr::get(builder.getContext(), net->name),
convertNetKind(net->netType.netKind), nullptr); convertNetKind(net->netType.netKind), nullptr);
auto readOp = builder.create<moore::ReadOp>(loc, netOp); auto readOp = moore::ReadOp::create(builder, loc, netOp);
portValues.insert({port, readOp}); portValues.insert({port, readOp});
} else if (const auto *var = } else if (const auto *var =
port->internalSymbol port->internalSymbol
->as_if<slang::ast::VariableSymbol>()) { ->as_if<slang::ast::VariableSymbol>()) {
auto varOp = builder.create<moore::VariableOp>( auto varOp = moore::VariableOp::create(
loc, refType, StringAttr::get(builder.getContext(), var->name), builder, loc, refType,
nullptr); StringAttr::get(builder.getContext(), var->name), nullptr);
auto readOp = builder.create<moore::ReadOp>(loc, varOp); auto readOp = moore::ReadOp::create(builder, loc, varOp);
portValues.insert({port, readOp}); portValues.insert({port, readOp});
} else { } else {
return mlir::emitError(loc) return mlir::emitError(loc)
@ -369,12 +370,13 @@ struct ModuleVisitor : public BaseVisitor {
auto sliceType = context.convertType(port->getType()); auto sliceType = context.convertType(port->getType());
if (!sliceType) if (!sliceType)
return failure(); return failure();
Value slice = builder.create<moore::ExtractRefOp>( Value slice = moore::ExtractRefOp::create(
loc, moore::RefType::get(cast<moore::UnpackedType>(sliceType)), builder, loc,
value, offset); moore::RefType::get(cast<moore::UnpackedType>(sliceType)), value,
offset);
// Create the "ReadOp" for input ports. // Create the "ReadOp" for input ports.
if (port->direction == ArgumentDirection::In) if (port->direction == ArgumentDirection::In)
slice = builder.create<moore::ReadOp>(loc, slice); slice = moore::ReadOp::create(builder, loc, slice);
portValues.insert({port, slice}); portValues.insert({port, slice});
offset += width; offset += width;
} }
@ -406,7 +408,7 @@ struct ModuleVisitor : public BaseVisitor {
llvm::zip(inputValues, moduleType.getInputTypes())) llvm::zip(inputValues, moduleType.getInputTypes()))
if (value.getType() != type) if (value.getType() != type)
value = value =
builder.create<moore::ConversionOp>(value.getLoc(), type, value); moore::ConversionOp::create(builder, value.getLoc(), type, value);
// Here we use the hierarchical value recorded in `Context::valueSymbols`. // Here we use the hierarchical value recorded in `Context::valueSymbols`.
// Then we pass it as the input port with the ref<T> type of the instance. // Then we pass it as the input port with the ref<T> type of the instance.
@ -418,8 +420,8 @@ struct ModuleVisitor : public BaseVisitor {
// Create the instance op itself. // Create the instance op itself.
auto inputNames = builder.getArrayAttr(moduleType.getInputNames()); auto inputNames = builder.getArrayAttr(moduleType.getInputNames());
auto outputNames = builder.getArrayAttr(moduleType.getOutputNames()); auto outputNames = builder.getArrayAttr(moduleType.getOutputNames());
auto inst = builder.create<moore::InstanceOp>( auto inst = moore::InstanceOp::create(
loc, moduleType.getOutputTypes(), builder, loc, moduleType.getOutputTypes(),
builder.getStringAttr(Twine(blockNamePrefix) + instNode.name), builder.getStringAttr(Twine(blockNamePrefix) + instNode.name),
FlatSymbolRefAttr::get(module.getSymNameAttr()), inputValues, FlatSymbolRefAttr::get(module.getSymNameAttr()), inputValues,
inputNames, outputNames); inputNames, outputNames);
@ -437,8 +439,8 @@ struct ModuleVisitor : public BaseVisitor {
Value rvalue = output; Value rvalue = output;
auto dstType = cast<moore::RefType>(lvalue.getType()).getNestedType(); auto dstType = cast<moore::RefType>(lvalue.getType()).getNestedType();
if (dstType != rvalue.getType()) if (dstType != rvalue.getType())
rvalue = builder.create<moore::ConversionOp>(loc, dstType, rvalue); rvalue = moore::ConversionOp::create(builder, loc, dstType, rvalue);
builder.create<moore::ContinuousAssignOp>(loc, lvalue, rvalue); moore::ContinuousAssignOp::create(builder, loc, lvalue, rvalue);
} }
return success(); return success();
@ -457,8 +459,9 @@ struct ModuleVisitor : public BaseVisitor {
return failure(); return failure();
} }
auto varOp = builder.create<moore::VariableOp>( auto varOp = moore::VariableOp::create(
loc, moore::RefType::get(cast<moore::UnpackedType>(loweredType)), builder, loc,
moore::RefType::get(cast<moore::UnpackedType>(loweredType)),
builder.getStringAttr(Twine(blockNamePrefix) + varNode.name), initial); builder.getStringAttr(Twine(blockNamePrefix) + varNode.name), initial);
context.valueSymbols.insert(&varNode, varOp); context.valueSymbols.insert(&varNode, varOp);
return success(); return success();
@ -484,8 +487,9 @@ struct ModuleVisitor : public BaseVisitor {
return mlir::emitError(loc, "unsupported net kind `") return mlir::emitError(loc, "unsupported net kind `")
<< netNode.netType.name << "`"; << netNode.netType.name << "`";
auto netOp = builder.create<moore::NetOp>( auto netOp = moore::NetOp::create(
loc, moore::RefType::get(cast<moore::UnpackedType>(loweredType)), builder, loc,
moore::RefType::get(cast<moore::UnpackedType>(loweredType)),
builder.getStringAttr(Twine(blockNamePrefix) + netNode.name), netkind, builder.getStringAttr(Twine(blockNamePrefix) + netNode.name), netkind,
assignment); assignment);
context.valueSymbols.insert(&netNode, netOp); context.valueSymbols.insert(&netNode, netOp);
@ -511,21 +515,21 @@ struct ModuleVisitor : public BaseVisitor {
if (!rhs) if (!rhs)
return failure(); return failure();
builder.create<moore::ContinuousAssignOp>(loc, lhs, rhs); moore::ContinuousAssignOp::create(builder, loc, lhs, rhs);
return success(); return success();
} }
// Handle procedures. // Handle procedures.
LogicalResult convertProcedure(moore::ProcedureKind kind, LogicalResult convertProcedure(moore::ProcedureKind kind,
const slang::ast::Statement &body) { const slang::ast::Statement &body) {
auto procOp = builder.create<moore::ProcedureOp>(loc, kind); auto procOp = moore::ProcedureOp::create(builder, loc, kind);
OpBuilder::InsertionGuard guard(builder); OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPointToEnd(&procOp.getBody().emplaceBlock()); builder.setInsertionPointToEnd(&procOp.getBody().emplaceBlock());
Context::ValueSymbolScope scope(context.valueSymbols); Context::ValueSymbolScope scope(context.valueSymbols);
if (failed(context.convertStatement(body))) if (failed(context.convertStatement(body)))
return failure(); return failure();
if (builder.getBlock()) if (builder.getBlock())
builder.create<moore::ReturnOp>(loc); moore::ReturnOp::create(builder, loc);
return success(); return success();
} }
@ -835,7 +839,7 @@ Context::convertModuleHeader(const slang::ast::InstanceBodySymbol *module) {
// Create an empty module that corresponds to this module. // Create an empty module that corresponds to this module.
auto moduleOp = auto moduleOp =
builder.create<moore::SVModuleOp>(loc, module->name, moduleType); moore::SVModuleOp::create(builder, loc, module->name, moduleType);
orderedRootOps.insert(it, {module->location, moduleOp}); orderedRootOps.insert(it, {module->location, moduleOp});
moduleOp.getBodyRegion().push_back(block.release()); moduleOp.getBodyRegion().push_back(block.release());
lowering.op = moduleOp; lowering.op = moduleOp;
@ -900,7 +904,7 @@ Context::convertModuleBody(const slang::ast::InstanceBodySymbol *module) {
// Collect output port values to be returned in the terminator. // Collect output port values to be returned in the terminator.
if (port.ast.direction == slang::ast::ArgumentDirection::Out) { if (port.ast.direction == slang::ast::ArgumentDirection::Out) {
if (isa<moore::RefType>(value.getType())) if (isa<moore::RefType>(value.getType()))
value = builder.create<moore::ReadOp>(value.getLoc(), value); value = moore::ReadOp::create(builder, value.getLoc(), value);
outputs.push_back(value); outputs.push_back(value);
continue; continue;
} }
@ -909,8 +913,8 @@ Context::convertModuleBody(const slang::ast::InstanceBodySymbol *module) {
// of that port. // of that port.
Value portArg = port.arg; Value portArg = port.arg;
if (port.ast.direction != slang::ast::ArgumentDirection::In) if (port.ast.direction != slang::ast::ArgumentDirection::In)
portArg = builder.create<moore::ReadOp>(port.loc, port.arg); portArg = moore::ReadOp::create(builder, port.loc, port.arg);
builder.create<moore::ContinuousAssignOp>(port.loc, value, portArg); moore::ContinuousAssignOp::create(builder, port.loc, value, portArg);
} }
// Ensure the number of operands of this module's terminator and the number of // Ensure the number of operands of this module's terminator and the number of
@ -920,7 +924,7 @@ Context::convertModuleBody(const slang::ast::InstanceBodySymbol *module) {
if (hierPath.direction == slang::ast::ArgumentDirection::Out) if (hierPath.direction == slang::ast::ArgumentDirection::Out)
outputs.push_back(hierValue); outputs.push_back(hierValue);
builder.create<moore::OutputOp>(lowering.op.getLoc(), outputs); moore::OutputOp::create(builder, lowering.op.getLoc(), outputs);
return success(); return success();
} }
@ -1000,7 +1004,7 @@ Context::declareFunction(const slang::ast::SubroutineSymbol &subroutine) {
funcName += subroutine.name; funcName += subroutine.name;
// Create a function declaration. // Create a function declaration.
auto funcOp = builder.create<mlir::func::FuncOp>(loc, funcName, funcType); auto funcOp = mlir::func::FuncOp::create(builder, loc, funcName, funcType);
SymbolTable::setSymbolVisibility(funcOp, SymbolTable::Visibility::Private); SymbolTable::setSymbolVisibility(funcOp, SymbolTable::Visibility::Private);
orderedRootOps.insert(it, {subroutine.location, funcOp}); orderedRootOps.insert(it, {subroutine.location, funcOp});
lowering->op = funcOp; lowering->op = funcOp;
@ -1037,8 +1041,8 @@ Context::convertFunction(const slang::ast::SubroutineSymbol &subroutine) {
OpBuilder::InsertionGuard g(builder); OpBuilder::InsertionGuard g(builder);
builder.setInsertionPointToEnd(&block); builder.setInsertionPointToEnd(&block);
auto shadowArg = builder.create<moore::VariableOp>( auto shadowArg = moore::VariableOp::create(
loc, moore::RefType::get(cast<moore::UnpackedType>(type)), builder, loc, moore::RefType::get(cast<moore::UnpackedType>(type)),
StringAttr{}, blockArg); StringAttr{}, blockArg);
valueSymbols.insert(astArg, shadowArg); valueSymbols.insert(astArg, shadowArg);
argVariables.push_back(shadowArg); argVariables.push_back(shadowArg);
@ -1054,8 +1058,8 @@ Context::convertFunction(const slang::ast::SubroutineSymbol &subroutine) {
auto type = convertType(*subroutine.returnValVar->getDeclaredType()); auto type = convertType(*subroutine.returnValVar->getDeclaredType());
if (!type) if (!type)
return failure(); return failure();
returnVar = builder.create<moore::VariableOp>( returnVar = moore::VariableOp::create(
lowering->op.getLoc(), builder, lowering->op.getLoc(),
moore::RefType::get(cast<moore::UnpackedType>(type)), StringAttr{}, moore::RefType::get(cast<moore::UnpackedType>(type)), StringAttr{},
Value{}); Value{});
valueSymbols.insert(subroutine.returnValVar, returnVar); valueSymbols.insert(subroutine.returnValVar, returnVar);
@ -1068,10 +1072,12 @@ Context::convertFunction(const slang::ast::SubroutineSymbol &subroutine) {
// default one. // default one.
if (builder.getBlock()) { if (builder.getBlock()) {
if (returnVar && !subroutine.getReturnType().isVoid()) { if (returnVar && !subroutine.getReturnType().isVoid()) {
Value read = builder.create<moore::ReadOp>(returnVar.getLoc(), returnVar); Value read =
builder.create<mlir::func::ReturnOp>(lowering->op.getLoc(), read); moore::ReadOp::create(builder, returnVar.getLoc(), returnVar);
mlir::func::ReturnOp::create(builder, lowering->op.getLoc(), read);
} else { } else {
builder.create<mlir::func::ReturnOp>(lowering->op.getLoc(), ValueRange{}); mlir::func::ReturnOp::create(builder, lowering->op.getLoc(),
ValueRange{});
} }
} }
if (returnVar && returnVar.use_empty()) if (returnVar && returnVar.use_empty())

View File

@ -67,7 +67,7 @@ struct EventControlVisitor {
if (!condition) if (!condition)
return failure(); return failure();
} }
builder.create<moore::DetectEventOp>(loc, edge, expr, condition); moore::DetectEventOp::create(builder, loc, edge, expr, condition);
return success(); return success();
} }
@ -125,7 +125,7 @@ struct LTLClockControlVisitor {
expr = context.convertToI1(expr); expr = context.convertToI1(expr);
if (!expr) if (!expr)
return Value{}; return Value{};
return builder.create<ltl::ClockOp>(loc, seqOrPro, edge, expr); return ltl::ClockOp::create(builder, loc, seqOrPro, edge, expr);
} }
template <typename T> template <typename T>
@ -168,13 +168,13 @@ static LogicalResult handleRoot(Context &context,
// empty wait op and let `Context::convertTimingControl` populate it once // empty wait op and let `Context::convertTimingControl` populate it once
// the statement has been lowered. // the statement has been lowered.
case TimingControlKind::ImplicitEvent: case TimingControlKind::ImplicitEvent:
implicitWaitOp = builder.create<moore::WaitEventOp>(loc); implicitWaitOp = moore::WaitEventOp::create(builder, loc);
return success(); return success();
// Handle event control. // Handle event control.
case TimingControlKind::SignalEvent: case TimingControlKind::SignalEvent:
case TimingControlKind::EventList: { case TimingControlKind::EventList: {
auto waitOp = builder.create<moore::WaitEventOp>(loc); auto waitOp = moore::WaitEventOp::create(builder, loc);
OpBuilder::InsertionGuard guard(builder); OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPointToStart(&waitOp.getBody().emplaceBlock()); builder.setInsertionPointToStart(&waitOp.getBody().emplaceBlock());
EventControlVisitor visitor{context, loc, builder}; EventControlVisitor visitor{context, loc, builder};
@ -242,9 +242,9 @@ Context::convertTimingControl(const slang::ast::TimingControl &ctrl,
builder.setInsertionPointToStart(&implicitWaitOp.getBody().emplaceBlock()); builder.setInsertionPointToStart(&implicitWaitOp.getBody().emplaceBlock());
for (auto readValue : readValues) { for (auto readValue : readValues) {
auto value = auto value =
builder.create<moore::ReadOp>(implicitWaitOp.getLoc(), readValue); moore::ReadOp::create(builder, implicitWaitOp.getLoc(), readValue);
builder.create<moore::DetectEventOp>( moore::DetectEventOp::create(builder, implicitWaitOp.getLoc(),
implicitWaitOp.getLoc(), moore::Edge::AnyChange, value, Value{}); moore::Edge::AnyChange, value, Value{});
} }
} }

View File

@ -57,7 +57,7 @@ struct HasBeenResetOpConversion : OpConversionPattern<verif::HasBeenResetOp> {
rewriter, op->getLoc(), rewriter.getIntegerAttr(i1, 0)); rewriter, op->getLoc(), rewriter.getIntegerAttr(i1, 0));
// Generate the constant used to negate the reset value // Generate the constant used to negate the reset value
Value constOne = rewriter.create<hw::ConstantOp>(op.getLoc(), i1, 1); Value constOne = hw::ConstantOp::create(rewriter, op.getLoc(), i1, 1);
// Create a backedge for the register to be used in the OrOp // Create a backedge for the register to be used in the OrOp
circt::BackedgeBuilder bb(rewriter, op.getLoc()); circt::BackedgeBuilder bb(rewriter, op.getLoc());
@ -66,15 +66,15 @@ struct HasBeenResetOpConversion : OpConversionPattern<verif::HasBeenResetOp> {
// Generate an or between the reset and the register's value to store // Generate an or between the reset and the register's value to store
// whether or not the reset has been active at least once // whether or not the reset has been active at least once
Value orReset = Value orReset =
rewriter.create<comb::OrOp>(op.getLoc(), adaptor.getReset(), reg); comb::OrOp::create(rewriter, op.getLoc(), adaptor.getReset(), reg);
// This register should not be reset, so we give it dummy reset and resetval // This register should not be reset, so we give it dummy reset and resetval
// operands to fit the build signature // operands to fit the build signature
Value reset, resetval; Value reset, resetval;
// Finally generate the register to set the backedge // Finally generate the register to set the backedge
reg.setValue(rewriter.create<seq::CompRegOp>( reg.setValue(seq::CompRegOp::create(
op.getLoc(), orReset, rewriter, op.getLoc(), orReset,
rewriter.createOrFold<seq::ToClockOp>(op.getLoc(), adaptor.getClock()), rewriter.createOrFold<seq::ToClockOp>(op.getLoc(), adaptor.getClock()),
rewriter.getStringAttr("hbr"), reset, resetval, constZero, rewriter.getStringAttr("hbr"), reset, resetval, constZero,
InnerSymAttr{} // inner_sym InnerSymAttr{} // inner_sym
@ -83,8 +83,8 @@ struct HasBeenResetOpConversion : OpConversionPattern<verif::HasBeenResetOp> {
// We also need to consider the case where we are currently in a reset cycle // We also need to consider the case where we are currently in a reset cycle
// in which case our hbr register should be down- // in which case our hbr register should be down-
// Practically this means converting it to (and hbr (not reset)) // Practically this means converting it to (and hbr (not reset))
Value notReset = Value notReset = comb::XorOp::create(rewriter, op.getLoc(),
rewriter.create<comb::XorOp>(op.getLoc(), adaptor.getReset(), constOne); adaptor.getReset(), constOne);
rewriter.replaceOpWithNewOp<comb::AndOp>(op, reg, notReset); rewriter.replaceOpWithNewOp<comb::AndOp>(op, reg, notReset);
return success(); return success();
@ -137,8 +137,8 @@ void LowerLTLToCorePass::runOnOperation() {
mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value { mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
@ -147,8 +147,8 @@ void LowerLTLToCorePass::runOnOperation() {
mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value { mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });

View File

@ -160,11 +160,11 @@ public:
auto stages = pipelinePrologue[op]; auto stages = pipelinePrologue[op];
for (size_t i = 0, e = stages.size(); i < e; ++i) { for (size_t i = 0, e = stages.size(); i < e; ++i) {
PatternRewriter::InsertionGuard g(rewriter); PatternRewriter::InsertionGuard g(rewriter);
auto parOp = rewriter.create<calyx::ParOp>(op->getLoc()); auto parOp = calyx::ParOp::create(rewriter, op->getLoc());
rewriter.setInsertionPointToStart(parOp.getBodyBlock()); rewriter.setInsertionPointToStart(parOp.getBodyBlock());
for (size_t j = 0; j < i + 1; ++j) for (size_t j = 0; j < i + 1; ++j)
for (auto group : stages[j]) for (auto group : stages[j])
rewriter.create<calyx::EnableOp>(op->getLoc(), group); calyx::EnableOp::create(rewriter, op->getLoc(), group);
} }
} }
@ -173,11 +173,11 @@ public:
auto stages = pipelineEpilogue[op]; auto stages = pipelineEpilogue[op];
for (size_t i = 0, e = stages.size(); i < e; ++i) { for (size_t i = 0, e = stages.size(); i < e; ++i) {
PatternRewriter::InsertionGuard g(rewriter); PatternRewriter::InsertionGuard g(rewriter);
auto parOp = rewriter.create<calyx::ParOp>(op->getLoc()); auto parOp = calyx::ParOp::create(rewriter, op->getLoc());
rewriter.setInsertionPointToStart(parOp.getBodyBlock()); rewriter.setInsertionPointToStart(parOp.getBodyBlock());
for (size_t j = i, f = stages.size(); j < f; ++j) for (size_t j = i, f = stages.size(); j < f; ++j)
for (auto group : stages[j]) for (auto group : stages[j])
rewriter.create<calyx::EnableOp>(op->getLoc(), group); calyx::EnableOp::create(rewriter, op->getLoc(), group);
} }
} }
@ -326,7 +326,7 @@ private:
getState<ComponentLoweringState>().getPipelineRegister(srcOp); getState<ComponentLoweringState>().getPipelineRegister(srcOp);
if (pipelineRegister.has_value()) if (pipelineRegister.has_value())
srcOp = pipelineRegister->getOut(); srcOp = pipelineRegister->getOut();
rewriter.create<calyx::AssignOp>(op.getLoc(), dstOp.value(), srcOp); calyx::AssignOp::create(rewriter, op.getLoc(), dstOp.value(), srcOp);
} }
/// Replace the result values of the source operator with the new operator. /// Replace the result values of the source operator with the new operator.
@ -376,17 +376,17 @@ private:
group); group);
rewriter.setInsertionPointToEnd(group.getBodyBlock()); rewriter.setInsertionPointToEnd(group.getBodyBlock());
rewriter.create<calyx::AssignOp>(loc, opPipe.getLeft(), op.getLhs()); calyx::AssignOp::create(rewriter, loc, opPipe.getLeft(), op.getLhs());
rewriter.create<calyx::AssignOp>(loc, opPipe.getRight(), op.getRhs()); calyx::AssignOp::create(rewriter, loc, opPipe.getRight(), op.getRhs());
// Write the output to this register. // Write the output to this register.
rewriter.create<calyx::AssignOp>(loc, reg.getIn(), out); calyx::AssignOp::create(rewriter, loc, reg.getIn(), out);
// The write enable port is high when the pipeline is done. // The write enable port is high when the pipeline is done.
rewriter.create<calyx::AssignOp>(loc, reg.getWriteEn(), opPipe.getDone()); calyx::AssignOp::create(rewriter, loc, reg.getWriteEn(), opPipe.getDone());
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
loc, opPipe.getGo(), rewriter, loc, opPipe.getGo(),
createConstant(loc, rewriter, getComponent(), 1, 1)); createConstant(loc, rewriter, getComponent(), 1, 1));
// The group is done when the register write is complete. // The group is done when the register write is complete.
rewriter.create<calyx::GroupDoneOp>(loc, reg.getDone()); calyx::GroupDoneOp::create(rewriter, loc, reg.getDone());
// Register the values for the pipeline. // Register the values for the pipeline.
getState<ComponentLoweringState>().registerEvaluatingGroup(out, group); getState<ComponentLoweringState>().registerEvaluatingGroup(out, group);
@ -413,16 +413,16 @@ private:
"We expected a 1 dimensional memory of size 1 because there were no " "We expected a 1 dimensional memory of size 1 because there were no "
"address assignment values"); "address assignment values");
// Assign 1'd0 to the address port. // Assign 1'd0 to the address port.
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
loc, addrPorts[0], rewriter, loc, addrPorts[0],
createConstant(loc, rewriter, getComponent(), 1, 0)); createConstant(loc, rewriter, getComponent(), 1, 0));
} else { } else {
assert(addrPorts.size() == addressValues.size() && assert(addrPorts.size() == addressValues.size() &&
"Mismatch between number of address ports of the provided memory " "Mismatch between number of address ports of the provided memory "
"and address assignment values"); "and address assignment values");
for (auto address : enumerate(addressValues)) for (auto address : enumerate(addressValues))
rewriter.create<calyx::AssignOp>(loc, addrPorts[address.index()], calyx::AssignOp::create(rewriter, loc, addrPorts[address.index()],
address.value()); address.value());
} }
} }
}; };
@ -494,18 +494,20 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
assignAddressPorts(rewriter, storeOp.getLoc(), group, memoryInterface, assignAddressPorts(rewriter, storeOp.getLoc(), group, memoryInterface,
storeOp.getIndices()); storeOp.getIndices());
rewriter.setInsertionPointToEnd(group.getBodyBlock()); rewriter.setInsertionPointToEnd(group.getBodyBlock());
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(rewriter, storeOp.getLoc(),
storeOp.getLoc(), memoryInterface.writeData(), storeOp.getValueToStore()); memoryInterface.writeData(),
rewriter.create<calyx::AssignOp>( storeOp.getValueToStore());
storeOp.getLoc(), memoryInterface.writeEn(), calyx::AssignOp::create(
rewriter, storeOp.getLoc(), memoryInterface.writeEn(),
createConstant(storeOp.getLoc(), rewriter, getComponent(), 1, 1)); createConstant(storeOp.getLoc(), rewriter, getComponent(), 1, 1));
if (memoryInterface.contentEnOpt().has_value()) { if (memoryInterface.contentEnOpt().has_value()) {
// If memory has content enable, it must be asserted when writing // If memory has content enable, it must be asserted when writing
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
storeOp.getLoc(), memoryInterface.contentEn(), rewriter, storeOp.getLoc(), memoryInterface.contentEn(),
createConstant(storeOp.getLoc(), rewriter, getComponent(), 1, 1)); createConstant(storeOp.getLoc(), rewriter, getComponent(), 1, 1));
} }
rewriter.create<calyx::GroupDoneOp>(storeOp.getLoc(), memoryInterface.done()); calyx::GroupDoneOp::create(rewriter, storeOp.getLoc(),
memoryInterface.done());
getState<ComponentLoweringState>().registerNonPipelineOperations(storeOp, getState<ComponentLoweringState>().registerNonPipelineOperations(storeOp,
group); group);
@ -570,8 +572,8 @@ static LogicalResult buildAllocOp(ComponentLoweringState &componentState,
sizes.push_back(1); sizes.push_back(1);
addrSizes.push_back(1); addrSizes.push_back(1);
} }
auto memoryOp = rewriter.create<calyx::MemoryOp>( auto memoryOp = calyx::MemoryOp::create(
allocOp.getLoc(), componentState.getUniqueName("mem"), rewriter, allocOp.getLoc(), componentState.getUniqueName("mem"),
memtype.getElementType().getIntOrFloatBitWidth(), sizes, addrSizes); memtype.getElementType().getIntOrFloatBitWidth(), sizes, addrSizes);
// Externalize memories by default. This makes it easier for the native // Externalize memories by default. This makes it easier for the native
// compiler to provide initialized memories. // compiler to provide initialized memories.
@ -832,8 +834,9 @@ struct FuncOpConversion : public calyx::FuncOpPartialLoweringPattern {
calyx::addMandatoryComponentPorts(rewriter, ports); calyx::addMandatoryComponentPorts(rewriter, ports);
/// Create a calyx::ComponentOp corresponding to the to-be-lowered function. /// Create a calyx::ComponentOp corresponding to the to-be-lowered function.
auto compOp = rewriter.create<calyx::ComponentOp>( auto compOp = calyx::ComponentOp::create(
funcOp.getLoc(), rewriter.getStringAttr(funcOp.getSymName()), ports); rewriter, funcOp.getLoc(), rewriter.getStringAttr(funcOp.getSymName()),
ports);
/// Mark this component as the toplevel. /// Mark this component as the toplevel.
compOp->setAttr("toplevel", rewriter.getUnitAttr()); compOp->setAttr("toplevel", rewriter.getUnitAttr());
@ -1139,8 +1142,8 @@ class BuildPipelineGroups : public calyx::FuncOpPartialLoweringPattern {
// Create a sequential group and replace the comb group. // Create a sequential group and replace the comb group.
PatternRewriter::InsertionGuard g(rewriter); PatternRewriter::InsertionGuard g(rewriter);
rewriter.setInsertionPoint(combGroup); rewriter.setInsertionPoint(combGroup);
auto group = rewriter.create<calyx::GroupOp>(combGroup.getLoc(), auto group = calyx::GroupOp::create(rewriter, combGroup.getLoc(),
combGroup.getName()); combGroup.getName());
rewriter.cloneRegionBefore(combGroup.getBodyRegion(), rewriter.cloneRegionBefore(combGroup.getBodyRegion(),
&group.getBody().front()); &group.getBody().front());
group.getBodyRegion().back().erase(); group.getBodyRegion().back().erase();
@ -1202,7 +1205,7 @@ class BuildControl : public calyx::FuncOpPartialLoweringPattern {
auto *entryBlock = &funcOp.getBlocks().front(); auto *entryBlock = &funcOp.getBlocks().front();
rewriter.setInsertionPointToStart( rewriter.setInsertionPointToStart(
getComponent().getControlOp().getBodyBlock()); getComponent().getControlOp().getBodyBlock());
auto topLevelSeqOp = rewriter.create<calyx::SeqOp>(funcOp.getLoc()); auto topLevelSeqOp = calyx::SeqOp::create(rewriter, funcOp.getLoc());
DenseSet<Block *> path; DenseSet<Block *> path;
return buildCFGControl(path, rewriter, topLevelSeqOp.getBodyBlock(), return buildCFGControl(path, rewriter, topLevelSeqOp.getBodyBlock(),
nullptr, entryBlock); nullptr, entryBlock);
@ -1220,15 +1223,15 @@ private:
auto loc = block->front().getLoc(); auto loc = block->front().getLoc();
if (compBlockScheduleables.size() > 1) { if (compBlockScheduleables.size() > 1) {
auto seqOp = rewriter.create<calyx::SeqOp>(loc); auto seqOp = calyx::SeqOp::create(rewriter, loc);
parentCtrlBlock = seqOp.getBodyBlock(); parentCtrlBlock = seqOp.getBodyBlock();
} }
for (auto &group : compBlockScheduleables) { for (auto &group : compBlockScheduleables) {
rewriter.setInsertionPointToEnd(parentCtrlBlock); rewriter.setInsertionPointToEnd(parentCtrlBlock);
if (auto groupPtr = std::get_if<calyx::GroupOp>(&group); groupPtr) { if (auto groupPtr = std::get_if<calyx::GroupOp>(&group); groupPtr) {
rewriter.create<calyx::EnableOp>(groupPtr->getLoc(), calyx::EnableOp::create(rewriter, groupPtr->getLoc(),
groupPtr->getSymName()); groupPtr->getSymName());
} else if (auto *pipeSchedPtr = std::get_if<PipelineScheduleable>(&group); } else if (auto *pipeSchedPtr = std::get_if<PipelineScheduleable>(&group);
pipeSchedPtr) { pipeSchedPtr) {
auto &whileOp = pipeSchedPtr->whileOp; auto &whileOp = pipeSchedPtr->whileOp;
@ -1237,7 +1240,7 @@ private:
buildWhileCtrlOp(whileOp, pipeSchedPtr->initGroups, rewriter); buildWhileCtrlOp(whileOp, pipeSchedPtr->initGroups, rewriter);
rewriter.setInsertionPointToEnd(whileCtrlOp.getBodyBlock()); rewriter.setInsertionPointToEnd(whileCtrlOp.getBodyBlock());
auto whileBodyOp = auto whileBodyOp =
rewriter.create<calyx::ParOp>(whileOp.getOperation()->getLoc()); calyx::ParOp::create(rewriter, whileOp.getOperation()->getLoc());
rewriter.setInsertionPointToEnd(whileBodyOp.getBodyBlock()); rewriter.setInsertionPointToEnd(whileBodyOp.getBodyBlock());
/// Schedule pipeline stages in the parallel group directly. /// Schedule pipeline stages in the parallel group directly.
@ -1246,8 +1249,8 @@ private:
whileOp.getBodyBlock()); whileOp.getBodyBlock());
for (auto &group : bodyBlockScheduleables) for (auto &group : bodyBlockScheduleables)
if (auto *groupPtr = std::get_if<calyx::GroupOp>(&group); groupPtr) if (auto *groupPtr = std::get_if<calyx::GroupOp>(&group); groupPtr)
rewriter.create<calyx::EnableOp>(groupPtr->getLoc(), calyx::EnableOp::create(rewriter, groupPtr->getLoc(),
groupPtr->getSymName()); groupPtr->getSymName());
else else
return whileOp.getOperation()->emitError( return whileOp.getOperation()->emitError(
"Unsupported block schedulable"); "Unsupported block schedulable");
@ -1278,11 +1281,11 @@ private:
/// Schedule any registered block arguments to be executed before the body /// Schedule any registered block arguments to be executed before the body
/// of the branch. /// of the branch.
rewriter.setInsertionPointToEnd(parentCtrlBlock); rewriter.setInsertionPointToEnd(parentCtrlBlock);
auto preSeqOp = rewriter.create<calyx::SeqOp>(loc); auto preSeqOp = calyx::SeqOp::create(rewriter, loc);
rewriter.setInsertionPointToEnd(preSeqOp.getBodyBlock()); rewriter.setInsertionPointToEnd(preSeqOp.getBodyBlock());
for (auto barg : for (auto barg :
getState<ComponentLoweringState>().getBlockArgGroups(from, to)) getState<ComponentLoweringState>().getBlockArgGroups(from, to))
rewriter.create<calyx::EnableOp>(barg.getLoc(), barg.getSymName()); calyx::EnableOp::create(rewriter, barg.getLoc(), barg.getSymName());
return buildCFGControl(path, rewriter, parentCtrlBlock, from, to); return buildCFGControl(path, rewriter, parentCtrlBlock, from, to);
} }
@ -1322,12 +1325,13 @@ private:
auto symbolAttr = FlatSymbolRefAttr::get( auto symbolAttr = FlatSymbolRefAttr::get(
StringAttr::get(getContext(), condGroup.getSymName())); StringAttr::get(getContext(), condGroup.getSymName()));
auto ifOp = rewriter.create<calyx::IfOp>( auto ifOp =
brOp->getLoc(), cond, symbolAttr, /*initializeElseBody=*/true); calyx::IfOp::create(rewriter, brOp->getLoc(), cond, symbolAttr,
/*initializeElseBody=*/true);
rewriter.setInsertionPointToStart(ifOp.getThenBody()); rewriter.setInsertionPointToStart(ifOp.getThenBody());
auto thenSeqOp = rewriter.create<calyx::SeqOp>(brOp.getLoc()); auto thenSeqOp = calyx::SeqOp::create(rewriter, brOp.getLoc());
rewriter.setInsertionPointToStart(ifOp.getElseBody()); rewriter.setInsertionPointToStart(ifOp.getElseBody());
auto elseSeqOp = rewriter.create<calyx::SeqOp>(brOp.getLoc()); auto elseSeqOp = calyx::SeqOp::create(rewriter, brOp.getLoc());
bool trueBrSchedSuccess = bool trueBrSchedSuccess =
schedulePath(rewriter, path, brOp.getLoc(), block, successors[0], schedulePath(rewriter, path, brOp.getLoc(), block, successors[0],
@ -1359,10 +1363,10 @@ private:
/// parallel group to assign one or more registers all at once. /// parallel group to assign one or more registers all at once.
{ {
PatternRewriter::InsertionGuard g(rewriter); PatternRewriter::InsertionGuard g(rewriter);
auto parOp = rewriter.create<calyx::ParOp>(loc); auto parOp = calyx::ParOp::create(rewriter, loc);
rewriter.setInsertionPointToStart(parOp.getBodyBlock()); rewriter.setInsertionPointToStart(parOp.getBodyBlock());
for (calyx::GroupOp group : initGroups) for (calyx::GroupOp group : initGroups)
rewriter.create<calyx::EnableOp>(group.getLoc(), group.getName()); calyx::EnableOp::create(rewriter, group.getLoc(), group.getName());
} }
/// Insert the while op itself. /// Insert the while op itself.
@ -1371,7 +1375,7 @@ private:
.getEvaluatingGroup<calyx::CombGroupOp>(cond); .getEvaluatingGroup<calyx::CombGroupOp>(cond);
auto symbolAttr = FlatSymbolRefAttr::get( auto symbolAttr = FlatSymbolRefAttr::get(
StringAttr::get(getContext(), condGroup.getSymName())); StringAttr::get(getContext(), condGroup.getSymName()));
auto whileCtrlOp = rewriter.create<calyx::WhileOp>(loc, cond, symbolAttr); auto whileCtrlOp = calyx::WhileOp::create(rewriter, loc, cond, symbolAttr);
/// If a bound was specified, add it. /// If a bound was specified, add it.
if (auto bound = whileOp.getBound()) { if (auto bound = whileOp.getBound()) {

View File

@ -58,21 +58,21 @@ static Value adjustIntegerWidth(OpBuilder &builder, Value value,
return value; return value;
if (intWidth < targetWidth) { if (intWidth < targetWidth) {
Value zeroExt = builder.create<hw::ConstantOp>( Value zeroExt = hw::ConstantOp::create(
loc, builder.getIntegerType(targetWidth - intWidth), 0); builder, loc, builder.getIntegerType(targetWidth - intWidth), 0);
return builder.create<comb::ConcatOp>(loc, ValueRange{zeroExt, value}); return comb::ConcatOp::create(builder, loc, ValueRange{zeroExt, value});
} }
Value hi = builder.create<comb::ExtractOp>(loc, value, targetWidth, Value hi = comb::ExtractOp::create(builder, loc, value, targetWidth,
intWidth - targetWidth); intWidth - targetWidth);
Value zero = builder.create<hw::ConstantOp>( Value zero = hw::ConstantOp::create(
loc, builder.getIntegerType(intWidth - targetWidth), 0); builder, loc, builder.getIntegerType(intWidth - targetWidth), 0);
Value isZero = builder.create<comb::ICmpOp>(loc, comb::ICmpPredicate::eq, hi, Value isZero = comb::ICmpOp::create(builder, loc, comb::ICmpPredicate::eq, hi,
zero, false); zero, false);
Value lo = builder.create<comb::ExtractOp>(loc, value, 0, targetWidth); Value lo = comb::ExtractOp::create(builder, loc, value, 0, targetWidth);
Value max = builder.create<hw::ConstantOp>( Value max = hw::ConstantOp::create(builder, loc,
loc, builder.getIntegerType(targetWidth), -1); builder.getIntegerType(targetWidth), -1);
return builder.create<comb::MuxOp>(loc, isZero, lo, max, false); return comb::MuxOp::create(builder, loc, isZero, lo, max, false);
} }
/// Get the ModulePortInfo from a SVModuleOp. /// Get the ModulePortInfo from a SVModuleOp.
@ -125,8 +125,8 @@ struct SVModuleOpConversion : public OpConversionPattern<SVModuleOp> {
// Create the hw.module to replace moore.module // Create the hw.module to replace moore.module
auto hwModuleOp = auto hwModuleOp =
rewriter.create<hw::HWModuleOp>(op.getLoc(), op.getSymNameAttr(), hw::HWModuleOp::create(rewriter, op.getLoc(), op.getSymNameAttr(),
getModulePortInfo(*typeConverter, op)); getModulePortInfo(*typeConverter, op));
// Make hw.module have the same visibility as the moore.module. // Make hw.module have the same visibility as the moore.module.
// The entry/top level module is public, otherwise is private. // The entry/top level module is public, otherwise is private.
SymbolTable::setSymbolVisibility(hwModuleOp, SymbolTable::setSymbolVisibility(hwModuleOp,
@ -166,9 +166,9 @@ struct InstanceOpConversion : public OpConversionPattern<InstanceOp> {
// Create the new hw instanceOp to replace the original one. // Create the new hw instanceOp to replace the original one.
rewriter.setInsertionPoint(op); rewriter.setInsertionPoint(op);
auto instOp = rewriter.create<hw::InstanceOp>( auto instOp = hw::InstanceOp::create(
op.getLoc(), op.getResultTypes(), instName, moduleName, op.getInputs(), rewriter, op.getLoc(), op.getResultTypes(), instName, moduleName,
op.getInputNamesAttr(), op.getOutputNamesAttr(), op.getInputs(), op.getInputNamesAttr(), op.getOutputNamesAttr(),
/*Parameter*/ rewriter.getArrayAttr({}), /*InnerSymbol*/ nullptr, /*Parameter*/ rewriter.getArrayAttr({}), /*InnerSymbol*/ nullptr,
/*doNotPrint*/ nullptr); /*doNotPrint*/ nullptr);
@ -190,7 +190,7 @@ static void getValuesToObserve(Region *region,
auto probeIfSignal = [&](Value value) -> Value { auto probeIfSignal = [&](Value value) -> Value {
if (!isa<hw::InOutType>(value.getType())) if (!isa<hw::InOutType>(value.getType()))
return value; return value;
return rewriter.create<llhd::PrbOp>(loc, value); return llhd::PrbOp::create(rewriter, loc, value);
}; };
region->getParentOp()->walk<WalkOrder::PreOrder, ForwardDominanceIterator<>>( region->getParentOp()->walk<WalkOrder::PreOrder, ForwardDominanceIterator<>>(
@ -249,9 +249,9 @@ struct ProcedureOpConversion : public OpConversionPattern<ProcedureOp> {
op.getKind() == ProcedureKind::Final) { op.getKind() == ProcedureKind::Final) {
Operation *newOp; Operation *newOp;
if (op.getKind() == ProcedureKind::Initial) if (op.getKind() == ProcedureKind::Initial)
newOp = rewriter.create<llhd::ProcessOp>(loc, TypeRange{}); newOp = llhd::ProcessOp::create(rewriter, loc, TypeRange{});
else else
newOp = rewriter.create<llhd::FinalOp>(loc); newOp = llhd::FinalOp::create(rewriter, loc);
auto &body = newOp->getRegion(0); auto &body = newOp->getRegion(0);
rewriter.inlineRegionBefore(op.getBody(), body, body.end()); rewriter.inlineRegionBefore(op.getBody(), body, body.end());
for (auto returnOp : for (auto returnOp :
@ -264,14 +264,14 @@ struct ProcedureOpConversion : public OpConversionPattern<ProcedureOp> {
} }
// All other procedures lower to a an `llhd.process`. // All other procedures lower to a an `llhd.process`.
auto newOp = rewriter.create<llhd::ProcessOp>(loc, TypeRange{}); auto newOp = llhd::ProcessOp::create(rewriter, loc, TypeRange{});
// We need to add an empty entry block because it is not allowed in MLIR to // We need to add an empty entry block because it is not allowed in MLIR to
// branch back to the entry block. Instead we put the logic in the second // branch back to the entry block. Instead we put the logic in the second
// block and branch to that. // block and branch to that.
rewriter.createBlock(&newOp.getBody()); rewriter.createBlock(&newOp.getBody());
auto *block = &op.getBody().front(); auto *block = &op.getBody().front();
rewriter.create<cf::BranchOp>(loc, block); cf::BranchOp::create(rewriter, loc, block);
rewriter.inlineRegionBefore(op.getBody(), newOp.getBody(), rewriter.inlineRegionBefore(op.getBody(), newOp.getBody(),
newOp.getBody().end()); newOp.getBody().end());
@ -284,8 +284,8 @@ struct ProcedureOpConversion : public OpConversionPattern<ProcedureOp> {
if (op.getKind() == ProcedureKind::AlwaysComb || if (op.getKind() == ProcedureKind::AlwaysComb ||
op.getKind() == ProcedureKind::AlwaysLatch) { op.getKind() == ProcedureKind::AlwaysLatch) {
Block *waitBlock = rewriter.createBlock(&newOp.getBody()); Block *waitBlock = rewriter.createBlock(&newOp.getBody());
rewriter.create<llhd::WaitOp>(loc, ValueRange{}, Value(), observedValues, llhd::WaitOp::create(rewriter, loc, ValueRange{}, Value(), observedValues,
ValueRange{}, block); ValueRange{}, block);
block = waitBlock; block = waitBlock;
} }
@ -294,7 +294,7 @@ struct ProcedureOpConversion : public OpConversionPattern<ProcedureOp> {
// `always_latch` procedures. // `always_latch` procedures.
for (auto returnOp : llvm::make_early_inc_range(newOp.getOps<ReturnOp>())) { for (auto returnOp : llvm::make_early_inc_range(newOp.getOps<ReturnOp>())) {
rewriter.setInsertionPoint(returnOp); rewriter.setInsertionPoint(returnOp);
rewriter.create<cf::BranchOp>(loc, block); cf::BranchOp::create(rewriter, loc, block);
rewriter.eraseOp(returnOp); rewriter.eraseOp(returnOp);
} }
@ -360,7 +360,7 @@ struct WaitEventOpConversion : public OpConversionPattern<WaitEventOp> {
auto loc = op.getLoc(); auto loc = op.getLoc();
rewriter.setInsertionPoint(op); rewriter.setInsertionPoint(op);
rewriter.create<cf::BranchOp>(loc, waitBlock); cf::BranchOp::create(rewriter, loc, waitBlock);
// We need to inline two copies of the `wait_event`'s body region: one is // We need to inline two copies of the `wait_event`'s body region: one is
// used to determine the values going into `detect_event` ops before the // used to determine the values going into `detect_event` ops before the
@ -399,8 +399,8 @@ struct WaitEventOpConversion : public OpConversionPattern<WaitEventOp> {
// Create the `llhd.wait` op that suspends the current process and waits for // Create the `llhd.wait` op that suspends the current process and waits for
// a change in the interesting values listed in `observeValues`. When a // a change in the interesting values listed in `observeValues`. When a
// change is detected, execution resumes in the "check" block. // change is detected, execution resumes in the "check" block.
auto waitOp = rewriter.create<llhd::WaitOp>( auto waitOp = llhd::WaitOp::create(rewriter, loc, ValueRange{}, Value(),
loc, ValueRange{}, Value(), observeValues, ValueRange{}, checkBlock); observeValues, ValueRange{}, checkBlock);
rewriter.inlineBlockBefore(&clonedOp.getBody().front(), waitOp); rewriter.inlineBlockBefore(&clonedOp.getBody().front(), waitOp);
rewriter.eraseOp(clonedOp); rewriter.eraseOp(clonedOp);
@ -425,8 +425,8 @@ struct WaitEventOpConversion : public OpConversionPattern<WaitEventOp> {
beforeType = beforeType =
IntType::get(rewriter.getContext(), 1, beforeType.getDomain()); IntType::get(rewriter.getContext(), 1, beforeType.getDomain());
before = before =
rewriter.create<moore::ExtractOp>(loc, beforeType, before, LSB); moore::ExtractOp::create(rewriter, loc, beforeType, before, LSB);
after = rewriter.create<moore::ExtractOp>(loc, beforeType, after, LSB); after = moore::ExtractOp::create(rewriter, loc, beforeType, after, LSB);
} }
auto intType = rewriter.getIntegerType(beforeType.getWidth()); auto intType = rewriter.getIntegerType(beforeType.getWidth());
@ -436,25 +436,25 @@ struct WaitEventOpConversion : public OpConversionPattern<WaitEventOp> {
after); after);
if (edge == Edge::AnyChange) if (edge == Edge::AnyChange)
return rewriter.create<comb::ICmpOp>(loc, ICmpPredicate::ne, before, return comb::ICmpOp::create(rewriter, loc, ICmpPredicate::ne, before,
after, true); after, true);
SmallVector<Value> disjuncts; SmallVector<Value> disjuncts;
Value trueVal = rewriter.create<hw::ConstantOp>(loc, APInt(1, 1)); Value trueVal = hw::ConstantOp::create(rewriter, loc, APInt(1, 1));
if (edge == Edge::PosEdge || edge == Edge::BothEdges) { if (edge == Edge::PosEdge || edge == Edge::BothEdges) {
Value notOldVal = Value notOldVal =
rewriter.create<comb::XorOp>(loc, before, trueVal, true); comb::XorOp::create(rewriter, loc, before, trueVal, true);
Value posedge = Value posedge =
rewriter.create<comb::AndOp>(loc, notOldVal, after, true); comb::AndOp::create(rewriter, loc, notOldVal, after, true);
disjuncts.push_back(posedge); disjuncts.push_back(posedge);
} }
if (edge == Edge::NegEdge || edge == Edge::BothEdges) { if (edge == Edge::NegEdge || edge == Edge::BothEdges) {
Value notCurrVal = Value notCurrVal =
rewriter.create<comb::XorOp>(loc, after, trueVal, true); comb::XorOp::create(rewriter, loc, after, trueVal, true);
Value posedge = Value posedge =
rewriter.create<comb::AndOp>(loc, before, notCurrVal, true); comb::AndOp::create(rewriter, loc, before, notCurrVal, true);
disjuncts.push_back(posedge); disjuncts.push_back(posedge);
} }
@ -477,7 +477,8 @@ struct WaitEventOpConversion : public OpConversionPattern<WaitEventOp> {
if (detectOp.getCondition()) { if (detectOp.getCondition()) {
auto condition = typeConverter->materializeTargetConversion( auto condition = typeConverter->materializeTargetConversion(
rewriter, loc, rewriter.getI1Type(), detectOp.getCondition()); rewriter, loc, rewriter.getI1Type(), detectOp.getCondition());
trigger = rewriter.create<comb::AndOp>(loc, trigger, condition, true); trigger =
comb::AndOp::create(rewriter, loc, trigger, condition, true);
} }
triggers.push_back(trigger); triggers.push_back(trigger);
} }
@ -491,14 +492,15 @@ struct WaitEventOpConversion : public OpConversionPattern<WaitEventOp> {
// block. If there are no detect_event operations in the wait event, the // block. If there are no detect_event operations in the wait event, the
// 'llhd.wait' operation will not have any observed values and thus the // 'llhd.wait' operation will not have any observed values and thus the
// process will hang there forever. // process will hang there forever.
rewriter.create<cf::BranchOp>(loc, resumeBlock); cf::BranchOp::create(rewriter, loc, resumeBlock);
} else { } else {
// If any `detect_event` op detected an event, branch to the "resume" // If any `detect_event` op detected an event, branch to the "resume"
// block which contains any code after the `wait_event` op. If no events // block which contains any code after the `wait_event` op. If no events
// were detected, branch back to the "wait" block to wait for the next // were detected, branch back to the "wait" block to wait for the next
// change on the interesting signals. // change on the interesting signals.
auto triggered = rewriter.createOrFold<comb::OrOp>(loc, triggers, true); auto triggered = rewriter.createOrFold<comb::OrOp>(loc, triggers, true);
rewriter.create<cf::CondBranchOp>(loc, triggered, resumeBlock, waitBlock); cf::CondBranchOp::create(rewriter, loc, triggered, resumeBlock,
waitBlock);
} }
return success(); return success();
@ -531,7 +533,7 @@ struct VariableOpConversion : public OpConversionPattern<VariableOp> {
// TODO: Once the core dialects support four-valued integers, this code // TODO: Once the core dialects support four-valued integers, this code
// will additionally need to generate an all-X value for four-valued // will additionally need to generate an all-X value for four-valued
// variables. // variables.
Value constZero = rewriter.create<hw::ConstantOp>(loc, APInt(width, 0)); Value constZero = hw::ConstantOp::create(rewriter, loc, APInt(width, 0));
init = rewriter.createOrFold<hw::BitcastOp>(loc, elementType, constZero); init = rewriter.createOrFold<hw::BitcastOp>(loc, elementType, constZero);
} }
@ -561,7 +563,7 @@ struct NetOpConversion : public OpConversionPattern<NetOp> {
int64_t width = hw::getBitWidth(elementType); int64_t width = hw::getBitWidth(elementType);
if (width == -1) if (width == -1)
return failure(); return failure();
auto constZero = rewriter.create<hw::ConstantOp>(loc, APInt(width, 0)); auto constZero = hw::ConstantOp::create(rewriter, loc, APInt(width, 0));
auto init = auto init =
rewriter.createOrFold<hw::BitcastOp>(loc, elementType, constZero); rewriter.createOrFold<hw::BitcastOp>(loc, elementType, constZero);
@ -571,8 +573,8 @@ struct NetOpConversion : public OpConversionPattern<NetOp> {
if (auto assignedValue = adaptor.getAssignment()) { if (auto assignedValue = adaptor.getAssignment()) {
auto timeAttr = llhd::TimeAttr::get(resultType.getContext(), 0U, auto timeAttr = llhd::TimeAttr::get(resultType.getContext(), 0U,
llvm::StringRef("ns"), 0, 1); llvm::StringRef("ns"), 0, 1);
auto time = rewriter.create<llhd::ConstantTimeOp>(loc, timeAttr); auto time = llhd::ConstantTimeOp::create(rewriter, loc, timeAttr);
rewriter.create<llhd::DrvOp>(loc, signal, assignedValue, time, Value{}); llhd::DrvOp::create(rewriter, loc, signal, assignedValue, time, Value{});
} }
return success(); return success();
@ -668,8 +670,8 @@ struct ExtractOpConversion : public OpConversionPattern<ExtractOp> {
SmallVector<Value> toConcat; SmallVector<Value> toConcat;
if (low < 0) if (low < 0)
toConcat.push_back(rewriter.create<hw::ConstantOp>( toConcat.push_back(hw::ConstantOp::create(
op.getLoc(), APInt(std::min(-low, resultWidth), 0))); rewriter, op.getLoc(), APInt(std::min(-low, resultWidth), 0)));
if (low < inputWidth && high > 0) { if (low < inputWidth && high > 0) {
int32_t lowIdx = std::max(low, 0); int32_t lowIdx = std::max(low, 0);
@ -684,7 +686,7 @@ struct ExtractOpConversion : public OpConversionPattern<ExtractOp> {
int32_t diff = high - inputWidth; int32_t diff = high - inputWidth;
if (diff > 0) { if (diff > 0) {
Value val = Value val =
rewriter.create<hw::ConstantOp>(op.getLoc(), APInt(diff, 0)); hw::ConstantOp::create(rewriter, op.getLoc(), APInt(diff, 0));
toConcat.push_back(val); toConcat.push_back(val);
} }
@ -708,8 +710,8 @@ struct ExtractOpConversion : public OpConversionPattern<ExtractOp> {
SmallVector<Value> toConcat; SmallVector<Value> toConcat;
if (low < 0) { if (low < 0) {
Value val = rewriter.create<hw::ConstantOp>( Value val = hw::ConstantOp::create(
op.getLoc(), rewriter, op.getLoc(),
APInt(std::min((-low) * elementWidth, resWidth * elementWidth), APInt(std::min((-low) * elementWidth, resWidth * elementWidth),
0)); 0));
Value res = rewriter.createOrFold<hw::BitcastOp>( Value res = rewriter.createOrFold<hw::BitcastOp>(
@ -720,8 +722,8 @@ struct ExtractOpConversion : public OpConversionPattern<ExtractOp> {
if (low < inputWidth && high > 0) { if (low < inputWidth && high > 0) {
int32_t lowIdx = std::max(0, low); int32_t lowIdx = std::max(0, low);
Value lowIdxVal = rewriter.create<hw::ConstantOp>( Value lowIdxVal = hw::ConstantOp::create(
op.getLoc(), rewriter.getIntegerType(width), lowIdx); rewriter, op.getLoc(), rewriter.getIntegerType(width), lowIdx);
Value middle = rewriter.createOrFold<hw::ArraySliceOp>( Value middle = rewriter.createOrFold<hw::ArraySliceOp>(
op.getLoc(), op.getLoc(),
hw::ArrayType::get( hw::ArrayType::get(
@ -733,11 +735,11 @@ struct ExtractOpConversion : public OpConversionPattern<ExtractOp> {
int32_t diff = high - inputWidth; int32_t diff = high - inputWidth;
if (diff > 0) { if (diff > 0) {
Value constZero = rewriter.create<hw::ConstantOp>( Value constZero = hw::ConstantOp::create(
op.getLoc(), APInt(diff * elementWidth, 0)); rewriter, op.getLoc(), APInt(diff * elementWidth, 0));
Value val = rewriter.create<hw::BitcastOp>( Value val = hw::BitcastOp::create(
op.getLoc(), hw::ArrayType::get(arrTy.getElementType(), diff), rewriter, op.getLoc(),
constZero); hw::ArrayType::get(arrTy.getElementType(), diff), constZero);
toConcat.push_back(val); toConcat.push_back(val);
} }
@ -753,15 +755,16 @@ struct ExtractOpConversion : public OpConversionPattern<ExtractOp> {
if (bw < 0) if (bw < 0)
return failure(); return failure();
Value val = rewriter.create<hw::ConstantOp>(op.getLoc(), APInt(bw, 0)); Value val = hw::ConstantOp::create(rewriter, op.getLoc(), APInt(bw, 0));
Value bitcast = Value bitcast =
rewriter.createOrFold<hw::BitcastOp>(op.getLoc(), resultType, val); rewriter.createOrFold<hw::BitcastOp>(op.getLoc(), resultType, val);
rewriter.replaceOp(op, bitcast); rewriter.replaceOp(op, bitcast);
return success(); return success();
} }
Value idx = rewriter.create<hw::ConstantOp>( Value idx = hw::ConstantOp::create(rewriter, op.getLoc(),
op.getLoc(), rewriter.getIntegerType(width), adaptor.getLowBit()); rewriter.getIntegerType(width),
adaptor.getLowBit());
rewriter.replaceOpWithNewOp<hw::ArrayGetOp>(op, adaptor.getInput(), idx); rewriter.replaceOpWithNewOp<hw::ArrayGetOp>(op, adaptor.getInput(), idx);
return success(); return success();
} }
@ -786,8 +789,9 @@ struct ExtractRefOpConversion : public OpConversionPattern<ExtractRefOp> {
if (width == -1) if (width == -1)
return failure(); return failure();
Value lowBit = rewriter.create<hw::ConstantOp>( Value lowBit = hw::ConstantOp::create(
op.getLoc(), rewriter.getIntegerType(llvm::Log2_64_Ceil(width)), rewriter, op.getLoc(),
rewriter.getIntegerType(llvm::Log2_64_Ceil(width)),
adaptor.getLowBit()); adaptor.getLowBit());
rewriter.replaceOpWithNewOp<llhd::SigExtractOp>( rewriter.replaceOpWithNewOp<llhd::SigExtractOp>(
op, resultType, adaptor.getInput(), lowBit); op, resultType, adaptor.getInput(), lowBit);
@ -795,8 +799,8 @@ struct ExtractRefOpConversion : public OpConversionPattern<ExtractRefOp> {
} }
if (auto arrType = dyn_cast<hw::ArrayType>(inputType)) { if (auto arrType = dyn_cast<hw::ArrayType>(inputType)) {
Value lowBit = rewriter.create<hw::ConstantOp>( Value lowBit = hw::ConstantOp::create(
op.getLoc(), rewriter, op.getLoc(),
rewriter.getIntegerType(llvm::Log2_64_Ceil(arrType.getNumElements())), rewriter.getIntegerType(llvm::Log2_64_Ceil(arrType.getNumElements())),
adaptor.getLowBit()); adaptor.getLowBit());
@ -828,8 +832,8 @@ struct DynExtractOpConversion : public OpConversionPattern<DynExtractOp> {
if (auto intType = dyn_cast<IntegerType>(inputType)) { if (auto intType = dyn_cast<IntegerType>(inputType)) {
Value amount = adjustIntegerWidth(rewriter, adaptor.getLowBit(), Value amount = adjustIntegerWidth(rewriter, adaptor.getLowBit(),
intType.getWidth(), op->getLoc()); intType.getWidth(), op->getLoc());
Value value = rewriter.create<comb::ShrUOp>(op->getLoc(), Value value = comb::ShrUOp::create(rewriter, op->getLoc(),
adaptor.getInput(), amount); adaptor.getInput(), amount);
rewriter.replaceOpWithNewOp<comb::ExtractOp>(op, resultType, value, 0); rewriter.replaceOpWithNewOp<comb::ExtractOp>(op, resultType, value, 0);
return success(); return success();
@ -956,7 +960,7 @@ struct ReduceAndOpConversion : public OpConversionPattern<ReduceAndOp> {
matchAndRewrite(ReduceAndOp op, OpAdaptor adaptor, matchAndRewrite(ReduceAndOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
Type resultType = typeConverter->convertType(op.getInput().getType()); Type resultType = typeConverter->convertType(op.getInput().getType());
Value max = rewriter.create<hw::ConstantOp>(op->getLoc(), resultType, -1); Value max = hw::ConstantOp::create(rewriter, op->getLoc(), resultType, -1);
rewriter.replaceOpWithNewOp<comb::ICmpOp>(op, comb::ICmpPredicate::eq, rewriter.replaceOpWithNewOp<comb::ICmpOp>(op, comb::ICmpPredicate::eq,
adaptor.getInput(), max); adaptor.getInput(), max);
@ -970,7 +974,7 @@ struct ReduceOrOpConversion : public OpConversionPattern<ReduceOrOp> {
matchAndRewrite(ReduceOrOp op, OpAdaptor adaptor, matchAndRewrite(ReduceOrOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
Type resultType = typeConverter->convertType(op.getInput().getType()); Type resultType = typeConverter->convertType(op.getInput().getType());
Value zero = rewriter.create<hw::ConstantOp>(op->getLoc(), resultType, 0); Value zero = hw::ConstantOp::create(rewriter, op->getLoc(), resultType, 0);
rewriter.replaceOpWithNewOp<comb::ICmpOp>(op, comb::ICmpPredicate::ne, rewriter.replaceOpWithNewOp<comb::ICmpOp>(op, comb::ICmpPredicate::ne,
adaptor.getInput(), zero); adaptor.getInput(), zero);
@ -996,7 +1000,8 @@ struct BoolCastOpConversion : public OpConversionPattern<BoolCastOp> {
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
Type resultType = typeConverter->convertType(op.getInput().getType()); Type resultType = typeConverter->convertType(op.getInput().getType());
if (isa_and_nonnull<IntegerType>(resultType)) { if (isa_and_nonnull<IntegerType>(resultType)) {
Value zero = rewriter.create<hw::ConstantOp>(op->getLoc(), resultType, 0); Value zero =
hw::ConstantOp::create(rewriter, op->getLoc(), resultType, 0);
rewriter.replaceOpWithNewOp<comb::ICmpOp>(op, comb::ICmpPredicate::ne, rewriter.replaceOpWithNewOp<comb::ICmpOp>(op, comb::ICmpPredicate::ne,
adaptor.getInput(), zero); adaptor.getInput(), zero);
return success(); return success();
@ -1012,7 +1017,7 @@ struct NotOpConversion : public OpConversionPattern<NotOp> {
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
Type resultType = Type resultType =
ConversionPattern::typeConverter->convertType(op.getResult().getType()); ConversionPattern::typeConverter->convertType(op.getResult().getType());
Value max = rewriter.create<hw::ConstantOp>(op.getLoc(), resultType, -1); Value max = hw::ConstantOp::create(rewriter, op.getLoc(), resultType, -1);
rewriter.replaceOpWithNewOp<comb::XorOp>(op, adaptor.getInput(), max); rewriter.replaceOpWithNewOp<comb::XorOp>(op, adaptor.getInput(), max);
return success(); return success();
@ -1026,7 +1031,7 @@ struct NegOpConversion : public OpConversionPattern<NegOp> {
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
Type resultType = Type resultType =
ConversionPattern::typeConverter->convertType(op.getResult().getType()); ConversionPattern::typeConverter->convertType(op.getResult().getType());
Value zero = rewriter.create<hw::ConstantOp>(op.getLoc(), resultType, 0); Value zero = hw::ConstantOp::create(rewriter, op.getLoc(), resultType, 0);
rewriter.replaceOpWithNewOp<comb::SubOp>(op, zero, adaptor.getInput()); rewriter.replaceOpWithNewOp<comb::SubOp>(op, zero, adaptor.getInput());
return success(); return success();
@ -1098,7 +1103,7 @@ struct CaseXZEqOpConversion : public OpConversionPattern<SourceOp> {
Value rhs = adaptor.getRhs(); Value rhs = adaptor.getRhs();
if (!ignoredBits.isZero()) { if (!ignoredBits.isZero()) {
ignoredBits.flipAllBits(); ignoredBits.flipAllBits();
auto maskOp = rewriter.create<hw::ConstantOp>(op.getLoc(), ignoredBits); auto maskOp = hw::ConstantOp::create(rewriter, op.getLoc(), ignoredBits);
lhs = rewriter.createOrFold<comb::AndOp>(op.getLoc(), lhs, maskOp); lhs = rewriter.createOrFold<comb::AndOp>(op.getLoc(), lhs, maskOp);
rhs = rewriter.createOrFold<comb::AndOp>(op.getLoc(), rhs, maskOp); rhs = rewriter.createOrFold<comb::AndOp>(op.getLoc(), rhs, maskOp);
} }
@ -1157,8 +1162,9 @@ struct ZExtOpConversion : public OpConversionPattern<ZExtOp> {
auto targetWidth = op.getType().getWidth(); auto targetWidth = op.getType().getWidth();
auto inputWidth = op.getInput().getType().getWidth(); auto inputWidth = op.getInput().getType().getWidth();
auto zeroExt = rewriter.create<hw::ConstantOp>( auto zeroExt = hw::ConstantOp::create(
op.getLoc(), rewriter.getIntegerType(targetWidth - inputWidth), 0); rewriter, op.getLoc(),
rewriter.getIntegerType(targetWidth - inputWidth), 0);
rewriter.replaceOpWithNewOp<comb::ConcatOp>( rewriter.replaceOpWithNewOp<comb::ConcatOp>(
op, ValueRange{zeroExt, adaptor.getInput()}); op, ValueRange{zeroExt, adaptor.getInput()});
@ -1326,14 +1332,14 @@ struct PowUOpConversion : public OpConversionPattern<PowUOp> {
Location loc = op->getLoc(); Location loc = op->getLoc();
Value zeroVal = rewriter.create<hw::ConstantOp>(loc, APInt(1, 0)); Value zeroVal = hw::ConstantOp::create(rewriter, loc, APInt(1, 0));
// zero extend both LHS & RHS to ensure the unsigned integers are // zero extend both LHS & RHS to ensure the unsigned integers are
// interpreted correctly when calculating power // interpreted correctly when calculating power
auto lhs = rewriter.create<comb::ConcatOp>(loc, zeroVal, adaptor.getLhs()); auto lhs = comb::ConcatOp::create(rewriter, loc, zeroVal, adaptor.getLhs());
auto rhs = rewriter.create<comb::ConcatOp>(loc, zeroVal, adaptor.getRhs()); auto rhs = comb::ConcatOp::create(rewriter, loc, zeroVal, adaptor.getRhs());
// lower the exponentiation via MLIR's math dialect // lower the exponentiation via MLIR's math dialect
auto pow = rewriter.create<mlir::math::IPowIOp>(loc, lhs, rhs); auto pow = mlir::math::IPowIOp::create(rewriter, loc, lhs, rhs);
rewriter.replaceOpWithNewOp<comb::ExtractOp>(op, resultType, pow, 0); rewriter.replaceOpWithNewOp<comb::ExtractOp>(op, resultType, pow, 0);
return success(); return success();
@ -1410,7 +1416,7 @@ struct AssignOpConversion : public OpConversionPattern<OpTy> {
// this conversion. // this conversion.
auto timeAttr = llhd::TimeAttr::get( auto timeAttr = llhd::TimeAttr::get(
op->getContext(), 0U, llvm::StringRef("ns"), DeltaTime, EpsilonTime); op->getContext(), 0U, llvm::StringRef("ns"), DeltaTime, EpsilonTime);
auto time = rewriter.create<llhd::ConstantTimeOp>(op->getLoc(), timeAttr); auto time = llhd::ConstantTimeOp::create(rewriter, op->getLoc(), timeAttr);
rewriter.replaceOpWithNewOp<llhd::DrvOp>(op, adaptor.getDst(), rewriter.replaceOpWithNewOp<llhd::DrvOp>(op, adaptor.getDst(),
adaptor.getSrc(), time, Value{}); adaptor.getSrc(), time, Value{});
return success(); return success();
@ -1466,7 +1472,7 @@ struct ConditionalOpConversion : public OpConversionPattern<ConditionalOp> {
} }
auto ifOp = auto ifOp =
rewriter.create<scf::IfOp>(op.getLoc(), type, adaptor.getCondition()); scf::IfOp::create(rewriter, op.getLoc(), type, adaptor.getCondition());
rewriter.inlineRegionBefore(op.getTrueRegion(), ifOp.getThenRegion(), rewriter.inlineRegionBefore(op.getTrueRegion(), ifOp.getThenRegion(),
ifOp.getThenRegion().end()); ifOp.getThenRegion().end());
rewriter.inlineRegionBefore(op.getFalseRegion(), ifOp.getElseRegion(), rewriter.inlineRegionBefore(op.getFalseRegion(), ifOp.getElseRegion(),
@ -1723,8 +1729,8 @@ static void populateTypeConversion(TypeConverter &typeConverter) {
mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value { mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1 || !inputs[0]) if (inputs.size() != 1 || !inputs[0])
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
.getResult(0); .getResult(0);
}); });
@ -1733,8 +1739,8 @@ static void populateTypeConversion(TypeConverter &typeConverter) {
mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value { mlir::ValueRange inputs, mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
} }

View File

@ -125,14 +125,14 @@ public:
break; break;
case StageKind::Stallable: case StageKind::Stallable:
stageValid = stageValid =
builder.create<comb::AndOp>(loc, args.enable, getOrSetNotStalled()); comb::AndOp::create(builder, loc, args.enable, getOrSetNotStalled());
stageValid.getDefiningOp()->setAttr("sv.namehint", validSignalName); stageValid.getDefiningOp()->setAttr("sv.namehint", validSignalName);
break; break;
case StageKind::Runoff: case StageKind::Runoff:
assert(args.lnsEn && "Expected an LNS signal if this was a runoff stage"); assert(args.lnsEn && "Expected an LNS signal if this was a runoff stage");
stageValid = builder.create<comb::AndOp>( stageValid = comb::AndOp::create(
loc, args.enable, builder, loc, args.enable,
builder.create<comb::OrOp>(loc, args.lnsEn, getOrSetNotStalled())); comb::OrOp::create(builder, loc, args.lnsEn, getOrSetNotStalled()));
stageValid.getDefiningOp()->setAttr("sv.namehint", validSignalName); stageValid.getDefiningOp()->setAttr("sv.namehint", validSignalName);
break; break;
} }
@ -156,8 +156,8 @@ public:
Value notStalledClockGate; Value notStalledClockGate;
if (this->clockGateRegs) { if (this->clockGateRegs) {
// Create the top-level clock gate. // Create the top-level clock gate.
notStalledClockGate = builder.create<seq::ClockGateOp>( notStalledClockGate = seq::ClockGateOp::create(
loc, args.clock, stageValid, /*test_enable=*/Value(), builder, loc, args.clock, stageValid, /*test_enable=*/Value(),
/*inner_sym=*/hw::InnerSymAttr()); /*inner_sym=*/hw::InnerSymAttr());
} }
@ -172,23 +172,24 @@ public:
Value currClockGate = notStalledClockGate; Value currClockGate = notStalledClockGate;
for (auto hierClockGateEnable : stageOp.getClockGatesForReg(regIdx)) { for (auto hierClockGateEnable : stageOp.getClockGatesForReg(regIdx)) {
// Create clock gates for any hierarchically nested clock gates. // Create clock gates for any hierarchically nested clock gates.
currClockGate = builder.create<seq::ClockGateOp>( currClockGate = seq::ClockGateOp::create(
loc, currClockGate, hierClockGateEnable, builder, loc, currClockGate, hierClockGateEnable,
/*test_enable=*/Value(), /*test_enable=*/Value(),
/*inner_sym=*/hw::InnerSymAttr()); /*inner_sym=*/hw::InnerSymAttr());
} }
dataReg = builder.create<seq::CompRegOp>(stageOp->getLoc(), regIn, dataReg = seq::CompRegOp::create(builder, stageOp->getLoc(), regIn,
currClockGate, regName); currClockGate, regName);
} else { } else {
// Only clock-enable the register if the pipeline is stallable. // Only clock-enable the register if the pipeline is stallable.
// For non-stallable (continuous) pipelines, a data register can always // For non-stallable (continuous) pipelines, a data register can always
// be clocked. // be clocked.
if (isStallablePipeline) { if (isStallablePipeline) {
dataReg = builder.create<seq::CompRegClockEnabledOp>( dataReg = seq::CompRegClockEnabledOp::create(
stageOp->getLoc(), regIn, args.clock, stageValid, regName); builder, stageOp->getLoc(), regIn, args.clock, stageValid,
regName);
} else { } else {
dataReg = builder.create<seq::CompRegOp>(stageOp->getLoc(), regIn, dataReg = seq::CompRegOp::create(builder, stageOp->getLoc(), regIn,
args.clock, regName); args.clock, regName);
} }
} }
rets.regs.push_back(dataReg); rets.regs.push_back(dataReg);
@ -381,30 +382,30 @@ public:
Value enableRegResetVal; Value enableRegResetVal;
if (args.reset) if (args.reset)
enableRegResetVal = enableRegResetVal =
builder.create<hw::ConstantOp>(loc, APInt(1, 0, false)).getResult(); hw::ConstantOp::create(builder, loc, APInt(1, 0, false))
.getResult();
switch (stageKind) { switch (stageKind) {
case StageKind::Continuous: case StageKind::Continuous:
LLVM_FALLTHROUGH; LLVM_FALLTHROUGH;
case StageKind::NonStallable: case StageKind::NonStallable:
stageEnabled = builder.create<seq::CompRegOp>( stageEnabled = seq::CompRegOp::create(builder, loc, args.enable,
loc, args.enable, args.clock, args.reset, enableRegResetVal, args.clock, args.reset,
enableRegName); enableRegResetVal, enableRegName);
break; break;
case StageKind::Stallable: case StageKind::Stallable:
stageEnabled = builder.create<seq::CompRegClockEnabledOp>( stageEnabled = seq::CompRegClockEnabledOp::create(
loc, args.enable, args.clock, builder, loc, args.enable, args.clock,
comb::createOrFoldNot(loc, args.stall, builder), args.reset, comb::createOrFoldNot(loc, args.stall, builder), args.reset,
enableRegResetVal, enableRegName); enableRegResetVal, enableRegName);
break; break;
case StageKind::Runoff: case StageKind::Runoff:
assert(args.lnsEn && assert(args.lnsEn &&
"Expected an LNS signal if this was a runoff stage"); "Expected an LNS signal if this was a runoff stage");
stageEnabled = builder.create<seq::CompRegClockEnabledOp>( stageEnabled = seq::CompRegClockEnabledOp::create(
loc, args.enable, args.clock, builder, loc, args.enable, args.clock,
builder.create<comb::OrOp>( comb::OrOp::create(builder, loc, args.lnsEn,
loc, args.lnsEn, comb::createOrFoldNot(loc, args.stall, builder)),
comb::createOrFoldNot(loc, args.stall, builder)),
args.reset, enableRegResetVal, enableRegName); args.reset, enableRegResetVal, enableRegName);
break; break;
} }

View File

@ -495,14 +495,14 @@ private:
calyx::SgeLibOp, calyx::SgtLibOp>(calyxOp.getOperation())) && calyx::SgeLibOp, calyx::SgtLibOp>(calyxOp.getOperation())) &&
"Must be a Calyx comparison library operation."); "Must be a Calyx comparison library operation.");
int64_t outputIndex = 2; int64_t outputIndex = 2;
rewriter.create<calyx::AssignOp>(loc, condReg.getIn(), calyx::AssignOp::create(rewriter, loc, condReg.getIn(),
calyxOp.getResult(outputIndex)); calyxOp.getResult(outputIndex));
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
loc, condReg.getWriteEn(), rewriter, loc, condReg.getWriteEn(),
createConstant(loc, rewriter, createConstant(loc, rewriter,
getState<ComponentLoweringState>().getComponentOp(), 1, getState<ComponentLoweringState>().getComponentOp(), 1,
1)); 1));
rewriter.create<calyx::GroupDoneOp>(loc, condReg.getDone()); calyx::GroupDoneOp::create(rewriter, loc, condReg.getDone());
getState<ComponentLoweringState>().addSeqGuardCmpLibOp(cmpIOp); getState<ComponentLoweringState>().addSeqGuardCmpLibOp(cmpIOp);
} }
@ -565,7 +565,7 @@ private:
auto srcOp = calyx::parentIsSeqCell(dstOp.value()) auto srcOp = calyx::parentIsSeqCell(dstOp.value())
? condReg.getOut() ? condReg.getOut()
: op->getOperand(dstOp.index()); : op->getOperand(dstOp.index());
rewriter.create<calyx::AssignOp>(op.getLoc(), dstOp.value(), srcOp); calyx::AssignOp::create(rewriter, op.getLoc(), dstOp.value(), srcOp);
} }
/// Replace the result values of the source operator with the new operator. /// Replace the result values of the source operator with the new operator.
@ -620,24 +620,24 @@ private:
if constexpr (std::is_same_v<TSrcOp, math::SqrtOp>) if constexpr (std::is_same_v<TSrcOp, math::SqrtOp>)
// According to the Hardfloat library: "If sqrtOp is 1, the operation is // According to the Hardfloat library: "If sqrtOp is 1, the operation is
// the square root of a, and operand b is ignored." // the square root of a, and operand b is ignored."
rewriter.create<calyx::AssignOp>(loc, opPipe.getLeft(), op.getOperand()); calyx::AssignOp::create(rewriter, loc, opPipe.getLeft(), op.getOperand());
else { else {
rewriter.create<calyx::AssignOp>(loc, opPipe.getLeft(), op.getLhs()); calyx::AssignOp::create(rewriter, loc, opPipe.getLeft(), op.getLhs());
rewriter.create<calyx::AssignOp>(loc, opPipe.getRight(), op.getRhs()); calyx::AssignOp::create(rewriter, loc, opPipe.getRight(), op.getRhs());
} }
// Write the output to this register. // Write the output to this register.
rewriter.create<calyx::AssignOp>(loc, reg.getIn(), out); calyx::AssignOp::create(rewriter, loc, reg.getIn(), out);
// The write enable port is high when the pipeline is done. // The write enable port is high when the pipeline is done.
rewriter.create<calyx::AssignOp>(loc, reg.getWriteEn(), opPipe.getDone()); calyx::AssignOp::create(rewriter, loc, reg.getWriteEn(), opPipe.getDone());
// Set pipelineOp to high as long as its done signal is not high. // Set pipelineOp to high as long as its done signal is not high.
// This prevents the pipelineOP from executing for the cycle that we write // This prevents the pipelineOP from executing for the cycle that we write
// to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done // to register. To get !(pipelineOp.done) we do 1 xor pipelineOp.done
hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1); hw::ConstantOp c1 = createConstant(loc, rewriter, getComponent(), 1, 1);
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
loc, opPipe.getGo(), c1, rewriter, loc, opPipe.getGo(), c1,
comb::createOrFoldNot(group.getLoc(), opPipe.getDone(), builder)); comb::createOrFoldNot(group.getLoc(), opPipe.getDone(), builder));
// The group is done when the register write is complete. // The group is done when the register write is complete.
rewriter.create<calyx::GroupDoneOp>(loc, reg.getDone()); calyx::GroupDoneOp::create(rewriter, loc, reg.getDone());
// Pass the result from the source operation to register holding the resullt // Pass the result from the source operation to register holding the resullt
// from the Calyx primitive. // from the Calyx primitive.
@ -653,13 +653,13 @@ private:
subOp = createConstant(loc, rewriter, getComponent(), /*width=*/1, subOp = createConstant(loc, rewriter, getComponent(), /*width=*/1,
/*subtract=*/1); /*subtract=*/1);
} }
rewriter.create<calyx::AssignOp>(loc, opFOp.getSubOp(), subOp); calyx::AssignOp::create(rewriter, loc, opFOp.getSubOp(), subOp);
} else if (auto opFOp = } else if (auto opFOp =
dyn_cast<calyx::DivSqrtOpIEEE754>(opPipe.getOperation())) { dyn_cast<calyx::DivSqrtOpIEEE754>(opPipe.getOperation())) {
bool isSqrt = !isa<arith::DivFOp>(op); bool isSqrt = !isa<arith::DivFOp>(op);
hw::ConstantOp sqrtOp = hw::ConstantOp sqrtOp =
createConstant(loc, rewriter, getComponent(), /*width=*/1, isSqrt); createConstant(loc, rewriter, getComponent(), /*width=*/1, isSqrt);
rewriter.create<calyx::AssignOp>(loc, opFOp.getSqrtOp(), sqrtOp); calyx::AssignOp::create(rewriter, loc, opFOp.getSqrtOp(), sqrtOp);
} }
// Register the values for the pipeline. // Register the values for the pipeline.
@ -698,23 +698,25 @@ private:
group); group);
rewriter.setInsertionPointToEnd(group.getBodyBlock()); rewriter.setInsertionPointToEnd(group.getBodyBlock());
rewriter.create<calyx::AssignOp>(loc, calyxOp.getIn(), op.getIn()); calyx::AssignOp::create(rewriter, loc, calyxOp.getIn(), op.getIn());
if (isa<calyx::FpToIntOpIEEE754>(calyxOp)) { if (isa<calyx::FpToIntOpIEEE754>(calyxOp)) {
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
loc, cast<calyx::FpToIntOpIEEE754>(calyxOp).getSignedOut(), c1); rewriter, loc, cast<calyx::FpToIntOpIEEE754>(calyxOp).getSignedOut(),
c1);
} else if (isa<calyx::IntToFpOpIEEE754>(calyxOp)) { } else if (isa<calyx::IntToFpOpIEEE754>(calyxOp)) {
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
loc, cast<calyx::IntToFpOpIEEE754>(calyxOp).getSignedIn(), c1); rewriter, loc, cast<calyx::IntToFpOpIEEE754>(calyxOp).getSignedIn(),
c1);
} }
op.getResult().replaceAllUsesWith(reg.getOut()); op.getResult().replaceAllUsesWith(reg.getOut());
rewriter.create<calyx::AssignOp>(loc, reg.getIn(), calyxOp.getOut()); calyx::AssignOp::create(rewriter, loc, reg.getIn(), calyxOp.getOut());
rewriter.create<calyx::AssignOp>(loc, reg.getWriteEn(), c1); calyx::AssignOp::create(rewriter, loc, reg.getWriteEn(), c1);
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
loc, calyxOp.getGo(), c1, rewriter, loc, calyxOp.getGo(), c1,
comb::createOrFoldNot(loc, calyxOp.getDone(), builder)); comb::createOrFoldNot(loc, calyxOp.getDone(), builder));
rewriter.create<calyx::GroupDoneOp>(loc, reg.getDone()); calyx::GroupDoneOp::create(rewriter, loc, reg.getDone());
return success(); return success();
} }
@ -734,16 +736,16 @@ private:
"We expected a 1 dimensional memory of size 1 because there were no " "We expected a 1 dimensional memory of size 1 because there were no "
"address assignment values"); "address assignment values");
// Assign to address 1'd0 in memory. // Assign to address 1'd0 in memory.
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
loc, addrPorts[0], rewriter, loc, addrPorts[0],
createConstant(loc, rewriter, getComponent(), 1, 0)); createConstant(loc, rewriter, getComponent(), 1, 0));
} else { } else {
assert(addrPorts.size() == addressValues.size() && assert(addrPorts.size() == addressValues.size() &&
"Mismatch between number of address ports of the provided memory " "Mismatch between number of address ports of the provided memory "
"and address assignment values"); "and address assignment values");
for (auto address : enumerate(addressValues)) for (auto address : enumerate(addressValues))
rewriter.create<calyx::AssignOp>(loc, addrPorts[address.index()], calyx::AssignOp::create(rewriter, loc, addrPorts[address.index()],
address.value()); address.value());
} }
} }
@ -759,18 +761,18 @@ private:
auto reg = createRegister( auto reg = createRegister(
loc, rewriter, component, 1, loc, rewriter, component, 1,
getState<ComponentLoweringState>().getUniqueName(nameSuffix)); getState<ComponentLoweringState>().getUniqueName(nameSuffix));
rewriter.create<calyx::AssignOp>(loc, reg.getWriteEn(), calyx::AssignOp::create(rewriter, loc, reg.getWriteEn(),
calyxCmpFOp.getDone()); calyxCmpFOp.getDone());
if (invert) { if (invert) {
auto notLibOp = getState<ComponentLoweringState>() auto notLibOp = getState<ComponentLoweringState>()
.getNewLibraryOpInstance<calyx::NotLibOp>( .getNewLibraryOpInstance<calyx::NotLibOp>(
rewriter, loc, {one, one}); rewriter, loc, {one, one});
rewriter.create<calyx::AssignOp>(loc, notLibOp.getIn(), signal); calyx::AssignOp::create(rewriter, loc, notLibOp.getIn(), signal);
rewriter.create<calyx::AssignOp>(loc, reg.getIn(), notLibOp.getOut()); calyx::AssignOp::create(rewriter, loc, reg.getIn(), notLibOp.getOut());
getState<ComponentLoweringState>().registerEvaluatingGroup( getState<ComponentLoweringState>().registerEvaluatingGroup(
notLibOp.getOut(), group); notLibOp.getOut(), group);
} else } else
rewriter.create<calyx::AssignOp>(loc, reg.getIn(), signal); calyx::AssignOp::create(rewriter, loc, reg.getIn(), signal);
return reg; return reg;
}; };
}; };
@ -793,8 +795,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
if (memoryInterface.readEnOpt().has_value()) { if (memoryInterface.readEnOpt().has_value()) {
auto oneI1 = auto oneI1 =
calyx::createConstant(loadOp.getLoc(), rewriter, getComponent(), 1, 1); calyx::createConstant(loadOp.getLoc(), rewriter, getComponent(), 1, 1);
rewriter.create<calyx::AssignOp>(loadOp.getLoc(), memoryInterface.readEn(), calyx::AssignOp::create(rewriter, loadOp.getLoc(), memoryInterface.readEn(),
oneI1); oneI1);
regWriteEn = memoryInterface.done(); regWriteEn = memoryInterface.done();
if (calyx::noStoresToMemory(memref) && if (calyx::noStoresToMemory(memref) &&
calyx::singleLoadFromMemory(memref)) { calyx::singleLoadFromMemory(memref)) {
@ -802,8 +804,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
// register. The readData value will be held until readEn is asserted // register. The readData value will be held until readEn is asserted
// again // again
needReg = false; needReg = false;
rewriter.create<calyx::GroupDoneOp>(loadOp.getLoc(), calyx::GroupDoneOp::create(rewriter, loadOp.getLoc(),
memoryInterface.done()); memoryInterface.done());
// We refrain from replacing the loadOp result with // We refrain from replacing the loadOp result with
// memoryInterface.readData, since multiple loadOp's need to be converted // memoryInterface.readData, since multiple loadOp's need to be converted
// to a single memory's ReadData. If this replacement is done now, we lose // to a single memory's ReadData. If this replacement is done now, we lose
@ -820,10 +822,10 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
calyx::createConstant(loadOp.getLoc(), rewriter, getComponent(), 1, 1); calyx::createConstant(loadOp.getLoc(), rewriter, getComponent(), 1, 1);
auto zeroI1 = auto zeroI1 =
calyx::createConstant(loadOp.getLoc(), rewriter, getComponent(), 1, 0); calyx::createConstant(loadOp.getLoc(), rewriter, getComponent(), 1, 0);
rewriter.create<calyx::AssignOp>(loadOp.getLoc(), calyx::AssignOp::create(rewriter, loadOp.getLoc(),
memoryInterface.contentEn(), oneI1); memoryInterface.contentEn(), oneI1);
rewriter.create<calyx::AssignOp>(loadOp.getLoc(), memoryInterface.writeEn(), calyx::AssignOp::create(rewriter, loadOp.getLoc(),
zeroI1); memoryInterface.writeEn(), zeroI1);
regWriteEn = memoryInterface.done(); regWriteEn = memoryInterface.done();
if (calyx::noStoresToMemory(memref) && if (calyx::noStoresToMemory(memref) &&
calyx::singleLoadFromMemory(memref)) { calyx::singleLoadFromMemory(memref)) {
@ -831,8 +833,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
// register. The readData value will be held until contentEn is asserted // register. The readData value will be held until contentEn is asserted
// again // again
needReg = false; needReg = false;
rewriter.create<calyx::GroupDoneOp>(loadOp.getLoc(), calyx::GroupDoneOp::create(rewriter, loadOp.getLoc(),
memoryInterface.done()); memoryInterface.done());
// We refrain from replacing the loadOp result with // We refrain from replacing the loadOp result with
// memoryInterface.readData, since multiple loadOp's need to be converted // memoryInterface.readData, since multiple loadOp's need to be converted
// to a single memory's ReadData. If this replacement is done now, we lose // to a single memory's ReadData. If this replacement is done now, we lose
@ -859,11 +861,11 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
loadOp.getMemRefType().getElementTypeBitWidth(), loadOp.getMemRefType().getElementTypeBitWidth(),
getState<ComponentLoweringState>().getUniqueName("load")); getState<ComponentLoweringState>().getUniqueName("load"));
rewriter.setInsertionPointToEnd(group.getBodyBlock()); rewriter.setInsertionPointToEnd(group.getBodyBlock());
rewriter.create<calyx::AssignOp>(loadOp.getLoc(), reg.getIn(), calyx::AssignOp::create(rewriter, loadOp.getLoc(), reg.getIn(),
memoryInterface.readData()); memoryInterface.readData());
rewriter.create<calyx::AssignOp>(loadOp.getLoc(), reg.getWriteEn(), calyx::AssignOp::create(rewriter, loadOp.getLoc(), reg.getWriteEn(),
regWriteEn); regWriteEn);
rewriter.create<calyx::GroupDoneOp>(loadOp.getLoc(), reg.getDone()); calyx::GroupDoneOp::create(rewriter, loadOp.getLoc(), reg.getDone());
loadOp.getResult().replaceAllUsesWith(reg.getOut()); loadOp.getResult().replaceAllUsesWith(reg.getOut());
res = reg.getOut(); res = reg.getOut();
} }
@ -887,18 +889,20 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
assignAddressPorts(rewriter, storeOp.getLoc(), group, memoryInterface, assignAddressPorts(rewriter, storeOp.getLoc(), group, memoryInterface,
storeOp.getIndices()); storeOp.getIndices());
rewriter.setInsertionPointToEnd(group.getBodyBlock()); rewriter.setInsertionPointToEnd(group.getBodyBlock());
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(rewriter, storeOp.getLoc(),
storeOp.getLoc(), memoryInterface.writeData(), storeOp.getValueToStore()); memoryInterface.writeData(),
rewriter.create<calyx::AssignOp>( storeOp.getValueToStore());
storeOp.getLoc(), memoryInterface.writeEn(), calyx::AssignOp::create(
rewriter, storeOp.getLoc(), memoryInterface.writeEn(),
createConstant(storeOp.getLoc(), rewriter, getComponent(), 1, 1)); createConstant(storeOp.getLoc(), rewriter, getComponent(), 1, 1));
if (memoryInterface.contentEnOpt().has_value()) { if (memoryInterface.contentEnOpt().has_value()) {
// If memory has content enable, it must be asserted when writing // If memory has content enable, it must be asserted when writing
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
storeOp.getLoc(), memoryInterface.contentEn(), rewriter, storeOp.getLoc(), memoryInterface.contentEn(),
createConstant(storeOp.getLoc(), rewriter, getComponent(), 1, 1)); createConstant(storeOp.getLoc(), rewriter, getComponent(), 1, 1));
} }
rewriter.create<calyx::GroupDoneOp>(storeOp.getLoc(), memoryInterface.done()); calyx::GroupDoneOp::create(rewriter, storeOp.getLoc(),
memoryInterface.done());
return success(); return success();
} }
@ -1060,8 +1064,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
group); group);
rewriter.setInsertionPointToEnd(group.getBodyBlock()); rewriter.setInsertionPointToEnd(group.getBodyBlock());
rewriter.create<calyx::AssignOp>(loc, calyxCmpFOp.getLeft(), cmpf.getLhs()); calyx::AssignOp::create(rewriter, loc, calyxCmpFOp.getLeft(), cmpf.getLhs());
rewriter.create<calyx::AssignOp>(loc, calyxCmpFOp.getRight(), cmpf.getRhs()); calyx::AssignOp::create(rewriter, loc, calyxCmpFOp.getRight(), cmpf.getRhs());
bool signalingFlag = false; bool signalingFlag = false;
switch (cmpf.getPredicate()) { switch (cmpf.getPredicate()) {
@ -1089,8 +1093,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
// The IEEE Standard mandates that equality comparisons ordinarily are quiet, // The IEEE Standard mandates that equality comparisons ordinarily are quiet,
// while inequality comparisons ordinarily are signaling. // while inequality comparisons ordinarily are signaling.
rewriter.create<calyx::AssignOp>(loc, calyxCmpFOp.getSignaling(), calyx::AssignOp::create(rewriter, loc, calyxCmpFOp.getSignaling(),
signalingFlag ? c1 : c0); signalingFlag ? c1 : c0);
// Prepare signals and create registers // Prepare signals and create registers
SmallVector<calyx::RegisterOp> inputRegs; SmallVector<calyx::RegisterOp> inputRegs;
@ -1136,10 +1140,10 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
auto outputLibOp = getState<ComponentLoweringState>() auto outputLibOp = getState<ComponentLoweringState>()
.getNewLibraryOpInstance<calyx::AndLibOp>( .getNewLibraryOpInstance<calyx::AndLibOp>(
rewriter, loc, {one, one, one}); rewriter, loc, {one, one, one});
rewriter.create<calyx::AssignOp>(loc, outputLibOp.getLeft(), calyx::AssignOp::create(rewriter, loc, outputLibOp.getLeft(),
inputRegs[0].getOut()); inputRegs[0].getOut());
rewriter.create<calyx::AssignOp>(loc, outputLibOp.getRight(), calyx::AssignOp::create(rewriter, loc, outputLibOp.getRight(),
inputRegs[1].getOut()); inputRegs[1].getOut());
outputValue = outputLibOp.getOut(); outputValue = outputLibOp.getOut();
break; break;
@ -1148,10 +1152,10 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
auto outputLibOp = getState<ComponentLoweringState>() auto outputLibOp = getState<ComponentLoweringState>()
.getNewLibraryOpInstance<calyx::OrLibOp>( .getNewLibraryOpInstance<calyx::OrLibOp>(
rewriter, loc, {one, one, one}); rewriter, loc, {one, one, one});
rewriter.create<calyx::AssignOp>(loc, outputLibOp.getLeft(), calyx::AssignOp::create(rewriter, loc, outputLibOp.getLeft(),
inputRegs[0].getOut()); inputRegs[0].getOut());
rewriter.create<calyx::AssignOp>(loc, outputLibOp.getRight(), calyx::AssignOp::create(rewriter, loc, outputLibOp.getRight(),
inputRegs[1].getOut()); inputRegs[1].getOut());
outputValue = outputLibOp.getOut(); outputValue = outputLibOp.getOut();
break; break;
@ -1162,22 +1166,22 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
auto doneLibOp = getState<ComponentLoweringState>() auto doneLibOp = getState<ComponentLoweringState>()
.getNewLibraryOpInstance<calyx::AndLibOp>( .getNewLibraryOpInstance<calyx::AndLibOp>(
rewriter, loc, {one, one, one}); rewriter, loc, {one, one, one});
rewriter.create<calyx::AssignOp>(loc, doneLibOp.getLeft(), calyx::AssignOp::create(rewriter, loc, doneLibOp.getLeft(),
inputRegs[0].getDone()); inputRegs[0].getDone());
rewriter.create<calyx::AssignOp>(loc, doneLibOp.getRight(), calyx::AssignOp::create(rewriter, loc, doneLibOp.getRight(),
inputRegs[1].getDone()); inputRegs[1].getDone());
doneValue = doneLibOp.getOut(); doneValue = doneLibOp.getOut();
} }
// Write to the output register // Write to the output register
rewriter.create<calyx::AssignOp>(loc, reg.getIn(), outputValue); calyx::AssignOp::create(rewriter, loc, reg.getIn(), outputValue);
rewriter.create<calyx::AssignOp>(loc, reg.getWriteEn(), doneValue); calyx::AssignOp::create(rewriter, loc, reg.getWriteEn(), doneValue);
// Set the go and done signal // Set the go and done signal
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
loc, calyxCmpFOp.getGo(), c1, rewriter, loc, calyxCmpFOp.getGo(), c1,
comb::createOrFoldNot(loc, calyxCmpFOp.getDone(), builder)); comb::createOrFoldNot(loc, calyxCmpFOp.getDone(), builder));
rewriter.create<calyx::GroupDoneOp>(loc, reg.getDone()); calyx::GroupDoneOp::create(rewriter, loc, reg.getDone());
cmpf.getResult().replaceAllUsesWith(reg.getOut()); cmpf.getResult().replaceAllUsesWith(reg.getOut());
@ -1254,7 +1258,7 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
uint64_t signBit = 1ULL << (bitwidth - 1); uint64_t signBit = 1ULL << (bitwidth - 1);
uint64_t absMask = ~signBit & ((1ULL << bitwidth) - 1); // clear sign bit uint64_t absMask = ~signBit & ((1ULL << bitwidth) - 1); // clear sign bit
Value maskOp = rewriter.create<arith::ConstantIntOp>(loc, intTy, absMask); Value maskOp = arith::ConstantIntOp::create(rewriter, loc, intTy, absMask);
auto combGroup = createGroupForOp<calyx::CombGroupOp>(rewriter, absFOp); auto combGroup = createGroupForOp<calyx::CombGroupOp>(rewriter, absFOp);
rewriter.setInsertionPointToStart(combGroup.getBodyBlock()); rewriter.setInsertionPointToStart(combGroup.getBodyBlock());
@ -1262,8 +1266,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
auto andLibOp = getState<ComponentLoweringState>() auto andLibOp = getState<ComponentLoweringState>()
.getNewLibraryOpInstance<calyx::AndLibOp>( .getNewLibraryOpInstance<calyx::AndLibOp>(
rewriter, loc, {intTy, intTy, intTy}); rewriter, loc, {intTy, intTy, intTy});
rewriter.create<calyx::AssignOp>(loc, andLibOp.getLeft(), maskOp); calyx::AssignOp::create(rewriter, loc, andLibOp.getLeft(), maskOp);
rewriter.create<calyx::AssignOp>(loc, andLibOp.getRight(), input); calyx::AssignOp::create(rewriter, loc, andLibOp.getRight(), input);
getState<ComponentLoweringState>().registerEvaluatingGroup(andLibOp.getOut(), getState<ComponentLoweringState>().registerEvaluatingGroup(andLibOp.getOut(),
combGroup); combGroup);
@ -1290,8 +1294,8 @@ static LogicalResult buildAllocOp(ComponentLoweringState &componentState,
sizes.push_back(1); sizes.push_back(1);
addrSizes.push_back(1); addrSizes.push_back(1);
} }
auto memoryOp = rewriter.create<calyx::SeqMemoryOp>( auto memoryOp = calyx::SeqMemoryOp::create(
allocOp.getLoc(), componentState.getUniqueName("mem"), rewriter, allocOp.getLoc(), componentState.getUniqueName("mem"),
memtype.getElementType().getIntOrFloatBitWidth(), sizes, addrSizes); memtype.getElementType().getIntOrFloatBitWidth(), sizes, addrSizes);
// Externalize memories conditionally (only in the top-level component because // Externalize memories conditionally (only in the top-level component because
@ -1443,12 +1447,12 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
// Assign inductionReg.out to the left port of the adder. // Assign inductionReg.out to the left port of the adder.
Value leftOp = opInputPorts.front(); Value leftOp = opInputPorts.front();
rewriter.create<calyx::AssignOp>(forOp.getLoc(), leftOp, calyx::AssignOp::create(rewriter, forOp.getLoc(), leftOp,
inductionReg.getOut()); inductionReg.getOut());
// Assign forOp.getConstantStep to the right port of the adder. // Assign forOp.getConstantStep to the right port of the adder.
Value rightOp = opInputPorts.back(); Value rightOp = opInputPorts.back();
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
forOp.getLoc(), rightOp, rewriter, forOp.getLoc(), rightOp,
createConstant(forOp->getLoc(), rewriter, componentOp, createConstant(forOp->getLoc(), rewriter, componentOp,
regWidth.getIntOrFloatBitWidth(), regWidth.getIntOrFloatBitWidth(),
forOp.getConstantStep().value().getSExtValue())); forOp.getConstantStep().value().getSExtValue()));
@ -1602,8 +1606,8 @@ LogicalResult BuildOpGroups::buildOp(PatternRewriter &rewriter,
auto floatAttr = cast<FloatAttr>(constOp.getValueAttr()); auto floatAttr = cast<FloatAttr>(constOp.getValueAttr());
auto intType = auto intType =
rewriter.getIntegerType(floatAttr.getType().getIntOrFloatBitWidth()); rewriter.getIntegerType(floatAttr.getType().getIntOrFloatBitWidth());
auto calyxConstOp = rewriter.create<calyx::ConstantOp>( auto calyxConstOp = calyx::ConstantOp::create(rewriter, constOp.getLoc(),
constOp.getLoc(), name, floatAttr, intType); name, floatAttr, intType);
calyxConstOp->moveAfter(getComponent().getBodyBlock(), calyxConstOp->moveAfter(getComponent().getBodyBlock(),
getComponent().getBodyBlock()->begin()); getComponent().getBodyBlock()->begin());
rewriter.replaceAllUsesWith(constOp, calyxConstOp.getOut()); rewriter.replaceAllUsesWith(constOp, calyxConstOp.getOut());
@ -1942,8 +1946,9 @@ struct FuncOpConversion : public calyx::FuncOpPartialLoweringPattern {
calyx::addMandatoryComponentPorts(rewriter, ports); calyx::addMandatoryComponentPorts(rewriter, ports);
/// Create a calyx::ComponentOp corresponding to the to-be-lowered function. /// Create a calyx::ComponentOp corresponding to the to-be-lowered function.
auto compOp = rewriter.create<calyx::ComponentOp>( auto compOp = calyx::ComponentOp::create(
funcOp.getLoc(), rewriter.getStringAttr(funcOp.getSymName()), ports); rewriter, funcOp.getLoc(), rewriter.getStringAttr(funcOp.getSymName()),
ports);
std::string funcName = "func_" + funcOp.getSymName().str(); std::string funcName = "func_" + funcOp.getSymName().str();
rewriter.modifyOpInPlace(funcOp, [&]() { funcOp.setSymName(funcName); }); rewriter.modifyOpInPlace(funcOp, [&]() { funcOp.setSymName(funcName); });
@ -1976,8 +1981,8 @@ struct FuncOpConversion : public calyx::FuncOpPartialLoweringPattern {
sizes.push_back(1); sizes.push_back(1);
addrSizes.push_back(1); addrSizes.push_back(1);
} }
auto memOp = rewriter.create<calyx::SeqMemoryOp>( auto memOp = calyx::SeqMemoryOp::create(
funcOp.getLoc(), memName, rewriter, funcOp.getLoc(), memName,
memtype.getElementType().getIntOrFloatBitWidth(), sizes, addrSizes); memtype.getElementType().getIntOrFloatBitWidth(), sizes, addrSizes);
// we don't set the memory to "external", which implies it's a reference // we don't set the memory to "external", which implies it's a reference
@ -2210,7 +2215,7 @@ class BuildControl : public calyx::FuncOpPartialLoweringPattern {
auto *entryBlock = &funcOp.getBlocks().front(); auto *entryBlock = &funcOp.getBlocks().front();
rewriter.setInsertionPointToStart( rewriter.setInsertionPointToStart(
getComponent().getControlOp().getBodyBlock()); getComponent().getControlOp().getBodyBlock());
auto topLevelSeqOp = rewriter.create<calyx::SeqOp>(funcOp.getLoc()); auto topLevelSeqOp = calyx::SeqOp::create(rewriter, funcOp.getLoc());
DenseSet<Block *> path; DenseSet<Block *> path;
return buildCFGControl(path, rewriter, topLevelSeqOp.getBodyBlock(), return buildCFGControl(path, rewriter, topLevelSeqOp.getBodyBlock(),
nullptr, entryBlock); nullptr, entryBlock);
@ -2229,15 +2234,15 @@ private:
if (compBlockScheduleables.size() > 1 && if (compBlockScheduleables.size() > 1 &&
!isa<scf::ParallelOp>(block->getParentOp())) { !isa<scf::ParallelOp>(block->getParentOp())) {
auto seqOp = rewriter.create<calyx::SeqOp>(loc); auto seqOp = calyx::SeqOp::create(rewriter, loc);
parentCtrlBlock = seqOp.getBodyBlock(); parentCtrlBlock = seqOp.getBodyBlock();
} }
for (auto &group : compBlockScheduleables) { for (auto &group : compBlockScheduleables) {
rewriter.setInsertionPointToEnd(parentCtrlBlock); rewriter.setInsertionPointToEnd(parentCtrlBlock);
if (auto groupPtr = std::get_if<calyx::GroupOp>(&group); groupPtr) { if (auto groupPtr = std::get_if<calyx::GroupOp>(&group); groupPtr) {
rewriter.create<calyx::EnableOp>(groupPtr->getLoc(), calyx::EnableOp::create(rewriter, groupPtr->getLoc(),
groupPtr->getSymName()); groupPtr->getSymName());
} else if (auto whileSchedPtr = std::get_if<WhileScheduleable>(&group); } else if (auto whileSchedPtr = std::get_if<WhileScheduleable>(&group);
whileSchedPtr) { whileSchedPtr) {
auto &whileOp = whileSchedPtr->whileOp; auto &whileOp = whileSchedPtr->whileOp;
@ -2248,7 +2253,7 @@ private:
rewriter); rewriter);
rewriter.setInsertionPointToEnd(whileCtrlOp.getBodyBlock()); rewriter.setInsertionPointToEnd(whileCtrlOp.getBodyBlock());
auto whileBodyOp = auto whileBodyOp =
rewriter.create<calyx::SeqOp>(whileOp.getOperation()->getLoc()); calyx::SeqOp::create(rewriter, whileOp.getOperation()->getLoc());
auto *whileBodyOpBlock = whileBodyOp.getBodyBlock(); auto *whileBodyOpBlock = whileBodyOp.getBodyBlock();
/// Only schedule the 'after' block. The 'before' block is /// Only schedule the 'after' block. The 'before' block is
@ -2263,16 +2268,16 @@ private:
rewriter.setInsertionPointToEnd(whileBodyOpBlock); rewriter.setInsertionPointToEnd(whileBodyOpBlock);
calyx::GroupOp whileLatchGroup = calyx::GroupOp whileLatchGroup =
getState<ComponentLoweringState>().getWhileLoopLatchGroup(whileOp); getState<ComponentLoweringState>().getWhileLoopLatchGroup(whileOp);
rewriter.create<calyx::EnableOp>(whileLatchGroup.getLoc(), calyx::EnableOp::create(rewriter, whileLatchGroup.getLoc(),
whileLatchGroup.getName()); whileLatchGroup.getName());
} else if (auto *parSchedPtr = std::get_if<ParScheduleable>(&group)) { } else if (auto *parSchedPtr = std::get_if<ParScheduleable>(&group)) {
auto parOp = parSchedPtr->parOp; auto parOp = parSchedPtr->parOp;
auto calyxParOp = rewriter.create<calyx::ParOp>(parOp.getLoc()); auto calyxParOp = calyx::ParOp::create(rewriter, parOp.getLoc());
WalkResult walkResult = WalkResult walkResult =
parOp.walk([&](scf::ExecuteRegionOp execRegion) { parOp.walk([&](scf::ExecuteRegionOp execRegion) {
rewriter.setInsertionPointToEnd(calyxParOp.getBodyBlock()); rewriter.setInsertionPointToEnd(calyxParOp.getBodyBlock());
auto seqOp = rewriter.create<calyx::SeqOp>(execRegion.getLoc()); auto seqOp = calyx::SeqOp::create(rewriter, execRegion.getLoc());
rewriter.setInsertionPointToEnd(seqOp.getBodyBlock()); rewriter.setInsertionPointToEnd(seqOp.getBodyBlock());
for (auto &execBlock : execRegion.getRegion().getBlocks()) { for (auto &execBlock : execRegion.getRegion().getBlocks()) {
@ -2297,7 +2302,7 @@ private:
forSchedPtr->bound, rewriter); forSchedPtr->bound, rewriter);
rewriter.setInsertionPointToEnd(forCtrlOp.getBodyBlock()); rewriter.setInsertionPointToEnd(forCtrlOp.getBodyBlock());
auto forBodyOp = auto forBodyOp =
rewriter.create<calyx::SeqOp>(forOp.getOperation()->getLoc()); calyx::SeqOp::create(rewriter, forOp.getOperation()->getLoc());
auto *forBodyOpBlock = forBodyOp.getBodyBlock(); auto *forBodyOpBlock = forBodyOp.getBodyBlock();
// Schedule the body of the for loop. // Schedule the body of the for loop.
@ -2310,8 +2315,8 @@ private:
rewriter.setInsertionPointToEnd(forBodyOpBlock); rewriter.setInsertionPointToEnd(forBodyOpBlock);
calyx::GroupOp forLatchGroup = calyx::GroupOp forLatchGroup =
getState<ComponentLoweringState>().getForLoopLatchGroup(forOp); getState<ComponentLoweringState>().getForLoopLatchGroup(forOp);
rewriter.create<calyx::EnableOp>(forLatchGroup.getLoc(), calyx::EnableOp::create(rewriter, forLatchGroup.getLoc(),
forLatchGroup.getName()); forLatchGroup.getName());
} else if (auto *ifSchedPtr = std::get_if<IfScheduleable>(&group); } else if (auto *ifSchedPtr = std::get_if<IfScheduleable>(&group);
ifSchedPtr) { ifSchedPtr) {
auto ifOp = ifSchedPtr->ifOp; auto ifOp = ifSchedPtr->ifOp;
@ -2331,13 +2336,13 @@ private:
} }
bool initElse = !ifOp.getElseRegion().empty(); bool initElse = !ifOp.getElseRegion().empty();
auto ifCtrlOp = rewriter.create<calyx::IfOp>( auto ifCtrlOp = calyx::IfOp::create(rewriter, loc, cond, symbolAttr,
loc, cond, symbolAttr, /*initializeElseBody=*/initElse); /*initializeElseBody=*/initElse);
rewriter.setInsertionPointToEnd(ifCtrlOp.getBodyBlock()); rewriter.setInsertionPointToEnd(ifCtrlOp.getBodyBlock());
auto thenSeqOp = auto thenSeqOp =
rewriter.create<calyx::SeqOp>(ifOp.getThenRegion().getLoc()); calyx::SeqOp::create(rewriter, ifOp.getThenRegion().getLoc());
auto *thenSeqOpBlock = thenSeqOp.getBodyBlock(); auto *thenSeqOpBlock = thenSeqOp.getBodyBlock();
auto *thenBlock = &ifOp.getThenRegion().front(); auto *thenBlock = &ifOp.getThenRegion().front();
@ -2352,15 +2357,15 @@ private:
rewriter.setInsertionPointToEnd(thenSeqOpBlock); rewriter.setInsertionPointToEnd(thenSeqOpBlock);
calyx::GroupOp thenGroup = calyx::GroupOp thenGroup =
getState<ComponentLoweringState>().getThenGroup(ifOp); getState<ComponentLoweringState>().getThenGroup(ifOp);
rewriter.create<calyx::EnableOp>(thenGroup.getLoc(), calyx::EnableOp::create(rewriter, thenGroup.getLoc(),
thenGroup.getName()); thenGroup.getName());
} }
if (!ifOp.getElseRegion().empty()) { if (!ifOp.getElseRegion().empty()) {
rewriter.setInsertionPointToEnd(ifCtrlOp.getElseBody()); rewriter.setInsertionPointToEnd(ifCtrlOp.getElseBody());
auto elseSeqOp = auto elseSeqOp =
rewriter.create<calyx::SeqOp>(ifOp.getElseRegion().getLoc()); calyx::SeqOp::create(rewriter, ifOp.getElseRegion().getLoc());
auto *elseSeqOpBlock = elseSeqOp.getBodyBlock(); auto *elseSeqOpBlock = elseSeqOp.getBodyBlock();
auto *elseBlock = &ifOp.getElseRegion().front(); auto *elseBlock = &ifOp.getElseRegion().front();
@ -2373,14 +2378,14 @@ private:
rewriter.setInsertionPointToEnd(elseSeqOpBlock); rewriter.setInsertionPointToEnd(elseSeqOpBlock);
calyx::GroupOp elseGroup = calyx::GroupOp elseGroup =
getState<ComponentLoweringState>().getElseGroup(ifOp); getState<ComponentLoweringState>().getElseGroup(ifOp);
rewriter.create<calyx::EnableOp>(elseGroup.getLoc(), calyx::EnableOp::create(rewriter, elseGroup.getLoc(),
elseGroup.getName()); elseGroup.getName());
} }
} }
} else if (auto *callSchedPtr = std::get_if<CallScheduleable>(&group)) { } else if (auto *callSchedPtr = std::get_if<CallScheduleable>(&group)) {
auto instanceOp = callSchedPtr->instanceOp; auto instanceOp = callSchedPtr->instanceOp;
OpBuilder::InsertionGuard g(rewriter); OpBuilder::InsertionGuard g(rewriter);
auto callBody = rewriter.create<calyx::SeqOp>(instanceOp.getLoc()); auto callBody = calyx::SeqOp::create(rewriter, instanceOp.getLoc());
rewriter.setInsertionPointToStart(callBody.getBodyBlock()); rewriter.setInsertionPointToStart(callBody.getBodyBlock());
auto callee = callSchedPtr->callOp.getCallee(); auto callee = callSchedPtr->callOp.getCallee();
@ -2428,10 +2433,11 @@ private:
ArrayAttr refCellsAttr = ArrayAttr refCellsAttr =
ArrayAttr::get(rewriter.getContext(), refCells); ArrayAttr::get(rewriter.getContext(), refCells);
rewriter.create<calyx::InvokeOp>( calyx::InvokeOp::create(rewriter, instanceOp.getLoc(),
instanceOp.getLoc(), instanceOp.getSymName(), instancePorts, instanceOp.getSymName(), instancePorts,
inputPorts, refCellsAttr, ArrayAttr::get(rewriter.getContext(), {}), inputPorts, refCellsAttr,
ArrayAttr::get(rewriter.getContext(), {})); ArrayAttr::get(rewriter.getContext(), {}),
ArrayAttr::get(rewriter.getContext(), {}));
} else } else
llvm_unreachable("Unknown scheduleable"); llvm_unreachable("Unknown scheduleable");
} }
@ -2450,11 +2456,11 @@ private:
/// Schedule any registered block arguments to be executed before the body /// Schedule any registered block arguments to be executed before the body
/// of the branch. /// of the branch.
rewriter.setInsertionPointToEnd(parentCtrlBlock); rewriter.setInsertionPointToEnd(parentCtrlBlock);
auto preSeqOp = rewriter.create<calyx::SeqOp>(loc); auto preSeqOp = calyx::SeqOp::create(rewriter, loc);
rewriter.setInsertionPointToEnd(preSeqOp.getBodyBlock()); rewriter.setInsertionPointToEnd(preSeqOp.getBodyBlock());
for (auto barg : for (auto barg :
getState<ComponentLoweringState>().getBlockArgGroups(from, to)) getState<ComponentLoweringState>().getBlockArgGroups(from, to))
rewriter.create<calyx::EnableOp>(barg.getLoc(), barg.getSymName()); calyx::EnableOp::create(rewriter, barg.getLoc(), barg.getSymName());
return buildCFGControl(path, rewriter, parentCtrlBlock, from, to); return buildCFGControl(path, rewriter, parentCtrlBlock, from, to);
} }
@ -2494,12 +2500,13 @@ private:
auto symbolAttr = FlatSymbolRefAttr::get( auto symbolAttr = FlatSymbolRefAttr::get(
StringAttr::get(getContext(), condGroup.getSymName())); StringAttr::get(getContext(), condGroup.getSymName()));
auto ifOp = rewriter.create<calyx::IfOp>( auto ifOp =
brOp->getLoc(), cond, symbolAttr, /*initializeElseBody=*/true); calyx::IfOp::create(rewriter, brOp->getLoc(), cond, symbolAttr,
/*initializeElseBody=*/true);
rewriter.setInsertionPointToStart(ifOp.getThenBody()); rewriter.setInsertionPointToStart(ifOp.getThenBody());
auto thenSeqOp = rewriter.create<calyx::SeqOp>(brOp.getLoc()); auto thenSeqOp = calyx::SeqOp::create(rewriter, brOp.getLoc());
rewriter.setInsertionPointToStart(ifOp.getElseBody()); rewriter.setInsertionPointToStart(ifOp.getElseBody());
auto elseSeqOp = rewriter.create<calyx::SeqOp>(brOp.getLoc()); auto elseSeqOp = calyx::SeqOp::create(rewriter, brOp.getLoc());
bool trueBrSchedSuccess = bool trueBrSchedSuccess =
schedulePath(rewriter, path, brOp.getLoc(), block, successors[0], schedulePath(rewriter, path, brOp.getLoc(), block, successors[0],
@ -2529,10 +2536,10 @@ private:
insertParInitGroups(PatternRewriter &rewriter, Location loc, insertParInitGroups(PatternRewriter &rewriter, Location loc,
const SmallVector<calyx::GroupOp> &initGroups) const { const SmallVector<calyx::GroupOp> &initGroups) const {
PatternRewriter::InsertionGuard g(rewriter); PatternRewriter::InsertionGuard g(rewriter);
auto parOp = rewriter.create<calyx::ParOp>(loc); auto parOp = calyx::ParOp::create(rewriter, loc);
rewriter.setInsertionPointToStart(parOp.getBodyBlock()); rewriter.setInsertionPointToStart(parOp.getBodyBlock());
for (calyx::GroupOp group : initGroups) for (calyx::GroupOp group : initGroups)
rewriter.create<calyx::EnableOp>(group.getLoc(), group.getName()); calyx::EnableOp::create(rewriter, group.getLoc(), group.getName());
} }
calyx::WhileOp buildWhileCtrlOp(ScfWhileOp whileOp, calyx::WhileOp buildWhileCtrlOp(ScfWhileOp whileOp,
@ -2549,7 +2556,7 @@ private:
.getEvaluatingGroup<calyx::CombGroupOp>(cond); .getEvaluatingGroup<calyx::CombGroupOp>(cond);
auto symbolAttr = FlatSymbolRefAttr::get( auto symbolAttr = FlatSymbolRefAttr::get(
StringAttr::get(getContext(), condGroup.getSymName())); StringAttr::get(getContext(), condGroup.getSymName()));
return rewriter.create<calyx::WhileOp>(loc, cond, symbolAttr); return calyx::WhileOp::create(rewriter, loc, cond, symbolAttr);
} }
calyx::RepeatOp buildForCtrlOp(ScfForOp forOp, calyx::RepeatOp buildForCtrlOp(ScfForOp forOp,
@ -2562,7 +2569,7 @@ private:
insertParInitGroups(rewriter, loc, initGroups); insertParInitGroups(rewriter, loc, initGroups);
// Insert the repeatOp that corresponds to the For loop. // Insert the repeatOp that corresponds to the For loop.
return rewriter.create<calyx::RepeatOp>(loc, bound); return calyx::RepeatOp::create(rewriter, loc, bound);
} }
}; };
@ -2792,7 +2799,7 @@ private:
FunctionType funcType = builder.getFunctionType({}, {}); FunctionType funcType = builder.getFunctionType({}, {});
if (auto newFunc = if (auto newFunc =
builder.create<FuncOp>(moduleOp.getLoc(), newName, funcType)) FuncOp::create(builder, moduleOp.getLoc(), newName, funcType))
return newFunc; return newFunc;
return nullptr; return nullptr;
@ -2852,16 +2859,17 @@ private:
Value newOpRes; Value newOpRes;
TypeSwitch<Operation *>(op) TypeSwitch<Operation *>(op)
.Case<memref::AllocaOp>([&](memref::AllocaOp allocaOp) { .Case<memref::AllocaOp>([&](memref::AllocaOp allocaOp) {
newOpRes = builder.create<memref::AllocaOp>(callee.getLoc(), newOpRes = memref::AllocaOp::create(builder, callee.getLoc(),
allocaOp.getType()); allocaOp.getType());
}) })
.Case<memref::AllocOp>([&](memref::AllocOp allocOp) { .Case<memref::AllocOp>([&](memref::AllocOp allocOp) {
newOpRes = builder.create<memref::AllocOp>(callee.getLoc(), newOpRes = memref::AllocOp::create(builder, callee.getLoc(),
allocOp.getType()); allocOp.getType());
}) })
.Case<memref::GetGlobalOp>([&](memref::GetGlobalOp getGlobalOp) { .Case<memref::GetGlobalOp>([&](memref::GetGlobalOp getGlobalOp) {
newOpRes = builder.create<memref::GetGlobalOp>( newOpRes = memref::GetGlobalOp::create(builder, caller.getLoc(),
caller.getLoc(), getGlobalOp.getType(), getGlobalOp.getName()); getGlobalOp.getType(),
getGlobalOp.getName());
}) })
.Default([&](Operation *defaultOp) { .Default([&](Operation *defaultOp) {
llvm::report_fatal_error("Unsupported operation in TypeSwitch"); llvm::report_fatal_error("Unsupported operation in TypeSwitch");
@ -2890,7 +2898,7 @@ private:
if (isa<MemRefType>(arg.getType())) { if (isa<MemRefType>(arg.getType())) {
auto memrefType = cast<MemRefType>(arg.getType()); auto memrefType = cast<MemRefType>(arg.getType());
auto allocOp = auto allocOp =
builder.create<memref::AllocOp>(callee.getLoc(), memrefType); memref::AllocOp::create(builder, callee.getLoc(), memrefType);
calleeArgFnOperands.push_back(allocOp); calleeArgFnOperands.push_back(allocOp);
} else { } else {
auto callerArg = callerEntryBlock->getArgument(otherArgsCount++); auto callerArg = callerEntryBlock->getArgument(otherArgsCount++);
@ -2906,9 +2914,9 @@ private:
auto resultTypes = callee.getResultTypes(); auto resultTypes = callee.getResultTypes();
builder.setInsertionPointToEnd(callerEntryBlock); builder.setInsertionPointToEnd(callerEntryBlock);
builder.create<CallOp>(caller.getLoc(), calleeName, resultTypes, CallOp::create(builder, caller.getLoc(), calleeName, resultTypes,
fnOperands); fnOperands);
builder.create<ReturnOp>(caller.getLoc()); ReturnOp::create(builder, caller.getLoc());
} }
/// Conditionally creates an optional new top-level function; and inserts a /// Conditionally creates an optional new top-level function; and inserts a

View File

@ -56,13 +56,13 @@ SMTGlobalsHandler SMTGlobalsHandler::create(OpBuilder &builder,
auto ptrTy = LLVM::LLVMPointerType::get(builder.getContext()); auto ptrTy = LLVM::LLVMPointerType::get(builder.getContext());
auto createGlobal = [&](StringRef namePrefix) { auto createGlobal = [&](StringRef namePrefix) {
auto global = builder.create<LLVM::GlobalOp>( auto global = LLVM::GlobalOp::create(
loc, ptrTy, false, LLVM::Linkage::Internal, names.newName(namePrefix), builder, loc, ptrTy, false, LLVM::Linkage::Internal,
Attribute{}, /*alignment=*/8); names.newName(namePrefix), Attribute{}, /*alignment=*/8);
OpBuilder::InsertionGuard g(builder); OpBuilder::InsertionGuard g(builder);
builder.createBlock(&global.getInitializer()); builder.createBlock(&global.getInitializer());
Value res = builder.create<LLVM::ZeroOp>(loc, ptrTy); Value res = LLVM::ZeroOp::create(builder, loc, ptrTy);
builder.create<LLVM::ReturnOp>(loc, res); LLVM::ReturnOp::create(builder, loc, res);
return global; return global;
}; };
@ -111,9 +111,9 @@ private:
OpBuilder::InsertionGuard g(builder); OpBuilder::InsertionGuard g(builder);
builder.setInsertionPointToStart(block); builder.setInsertionPointToStart(block);
Value globalAddr = builder.create<LLVM::AddressOfOp>(loc, global); Value globalAddr = LLVM::AddressOfOp::create(builder, loc, global);
return cache[block] = builder.create<LLVM::LoadOp>( return cache[block] = LLVM::LoadOp::create(
loc, LLVM::LLVMPointerType::get(builder.getContext()), builder, loc, LLVM::LLVMPointerType::get(builder.getContext()),
globalAddr); globalAddr);
} }
@ -155,7 +155,7 @@ protected:
assert(succeeded(funcOpResult) && "expected to lookup or create printf"); assert(succeeded(funcOpResult) && "expected to lookup or create printf");
funcOp = funcOpResult.value(); funcOp = funcOpResult.value();
} }
return builder.create<LLVM::CallOp>(loc, funcOp, args); return LLVM::CallOp::create(builder, loc, funcOp, args);
} }
/// Build a global constant for the given string and construct an 'addressof' /// Build a global constant for the given string and construct an 'addressof'
@ -172,11 +172,11 @@ protected:
auto arrayTy = auto arrayTy =
LLVM::LLVMArrayType::get(builder.getI8Type(), str.size() + 1); LLVM::LLVMArrayType::get(builder.getI8Type(), str.size() + 1);
auto strAttr = builder.getStringAttr(str.str() + '\00'); auto strAttr = builder.getStringAttr(str.str() + '\00');
global = builder.create<LLVM::GlobalOp>( global = LLVM::GlobalOp::create(
loc, arrayTy, /*isConstant=*/true, LLVM::Linkage::Internal, builder, loc, arrayTy, /*isConstant=*/true, LLVM::Linkage::Internal,
globals.names.newName("str"), strAttr); globals.names.newName("str"), strAttr);
} }
return builder.create<LLVM::AddressOfOp>(loc, global); return LLVM::AddressOfOp::create(builder, loc, global);
} }
/// Most API functions require a pointer to the the Z3 context object as the /// Most API functions require a pointer to the the Z3 context object as the
/// first argument. This helper function prepends this pointer value to the /// first argument. This helper function prepends this pointer value to the
@ -215,8 +215,8 @@ protected:
return buildPtrAPICall(builder, loc, "Z3_mk_int_sort"); return buildPtrAPICall(builder, loc, "Z3_mk_int_sort");
}) })
.Case([&](smt::BitVectorType ty) { .Case([&](smt::BitVectorType ty) {
Value bitwidth = builder.create<LLVM::ConstantOp>( Value bitwidth = LLVM::ConstantOp::create(
loc, builder.getI32Type(), ty.getWidth()); builder, loc, builder.getI32Type(), ty.getWidth());
return buildPtrAPICall(builder, loc, "Z3_mk_bv_sort", {bitwidth}); return buildPtrAPICall(builder, loc, "Z3_mk_bv_sort", {bitwidth});
}) })
.Case([&](smt::BoolType ty) { .Case([&](smt::BoolType ty) {
@ -267,8 +267,8 @@ struct DeclareFunOpLowering : public SMTLoweringPattern<DeclareFunOp> {
if (adaptor.getNamePrefix()) if (adaptor.getNamePrefix())
prefix = buildString(rewriter, loc, *adaptor.getNamePrefix()); prefix = buildString(rewriter, loc, *adaptor.getNamePrefix());
else else
prefix = rewriter.create<LLVM::ZeroOp>( prefix = LLVM::ZeroOp::create(rewriter, loc,
loc, LLVM::LLVMPointerType::get(getContext())); LLVM::LLVMPointerType::get(getContext()));
// Handle the constant value case. // Handle the constant value case.
if (!isa<SMTFuncType>(op.getType())) { if (!isa<SMTFuncType>(op.getType())) {
@ -287,20 +287,20 @@ struct DeclareFunOpLowering : public SMTLoweringPattern<DeclareFunOp> {
Type arrTy = Type arrTy =
LLVM::LLVMArrayType::get(llvmPtrTy, funcType.getDomainTypes().size()); LLVM::LLVMArrayType::get(llvmPtrTy, funcType.getDomainTypes().size());
Value domain = rewriter.create<LLVM::UndefOp>(loc, arrTy); Value domain = LLVM::UndefOp::create(rewriter, loc, arrTy);
for (auto [i, ty] : llvm::enumerate(funcType.getDomainTypes())) { for (auto [i, ty] : llvm::enumerate(funcType.getDomainTypes())) {
Value sort = buildSort(rewriter, loc, ty); Value sort = buildSort(rewriter, loc, ty);
domain = rewriter.create<LLVM::InsertValueOp>(loc, domain, sort, i); domain = LLVM::InsertValueOp::create(rewriter, loc, domain, sort, i);
} }
Value one = Value one =
rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI32Type(), 1); LLVM::ConstantOp::create(rewriter, loc, rewriter.getI32Type(), 1);
Value domainStorage = Value domainStorage =
rewriter.create<LLVM::AllocaOp>(loc, llvmPtrTy, arrTy, one); LLVM::AllocaOp::create(rewriter, loc, llvmPtrTy, arrTy, one);
rewriter.create<LLVM::StoreOp>(loc, domain, domainStorage); LLVM::StoreOp::create(rewriter, loc, domain, domainStorage);
Value domainSize = rewriter.create<LLVM::ConstantOp>( Value domainSize = LLVM::ConstantOp::create(
loc, rewriter.getI32Type(), funcType.getDomainTypes().size()); rewriter, loc, rewriter.getI32Type(), funcType.getDomainTypes().size());
Value decl = Value decl =
buildPtrAPICall(rewriter, loc, "Z3_mk_fresh_func_decl", buildPtrAPICall(rewriter, loc, "Z3_mk_fresh_func_decl",
{prefix, domainSize, domainStorage, rangeSort}); {prefix, domainSize, domainStorage, rangeSort});
@ -326,21 +326,21 @@ struct ApplyFuncOpLowering : public SMTLoweringPattern<ApplyFuncOp> {
Type arrTy = LLVM::LLVMArrayType::get(llvmPtrTy, adaptor.getArgs().size()); Type arrTy = LLVM::LLVMArrayType::get(llvmPtrTy, adaptor.getArgs().size());
// Create an array of the function arguments. // Create an array of the function arguments.
Value domain = rewriter.create<LLVM::UndefOp>(loc, arrTy); Value domain = LLVM::UndefOp::create(rewriter, loc, arrTy);
for (auto [i, arg] : llvm::enumerate(adaptor.getArgs())) for (auto [i, arg] : llvm::enumerate(adaptor.getArgs()))
domain = rewriter.create<LLVM::InsertValueOp>(loc, domain, arg, i); domain = LLVM::InsertValueOp::create(rewriter, loc, domain, arg, i);
// Store the array on the stack. // Store the array on the stack.
Value one = Value one =
rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI32Type(), 1); LLVM::ConstantOp::create(rewriter, loc, rewriter.getI32Type(), 1);
Value domainStorage = Value domainStorage =
rewriter.create<LLVM::AllocaOp>(loc, llvmPtrTy, arrTy, one); LLVM::AllocaOp::create(rewriter, loc, llvmPtrTy, arrTy, one);
rewriter.create<LLVM::StoreOp>(loc, domain, domainStorage); LLVM::StoreOp::create(rewriter, loc, domain, domainStorage);
// Call the API function with a pointer to the function, the number of // Call the API function with a pointer to the function, the number of
// arguments, and the pointer to the arguments stored on the stack. // arguments, and the pointer to the arguments stored on the stack.
Value domainSize = rewriter.create<LLVM::ConstantOp>( Value domainSize = LLVM::ConstantOp::create(
loc, rewriter.getI32Type(), adaptor.getArgs().size()); rewriter, loc, rewriter.getI32Type(), adaptor.getArgs().size());
Value returnVal = Value returnVal =
buildPtrAPICall(rewriter, loc, "Z3_mk_app", buildPtrAPICall(rewriter, loc, "Z3_mk_app",
{adaptor.getFunc(), domainSize, domainStorage}); {adaptor.getFunc(), domainSize, domainStorage});
@ -374,8 +374,8 @@ struct BVConstantOpLowering : public SMTLoweringPattern<smt::BVConstantOp> {
APInt val = adaptor.getValue().getValue(); APInt val = adaptor.getValue().getValue();
if (width <= 64) { if (width <= 64) {
Value bvConst = rewriter.create<LLVM::ConstantOp>( Value bvConst = LLVM::ConstantOp::create(
loc, rewriter.getI64Type(), val.getZExtValue()); rewriter, loc, rewriter.getI64Type(), val.getZExtValue());
Value res = buildPtrAPICall(rewriter, loc, "Z3_mk_unsigned_int64", Value res = buildPtrAPICall(rewriter, loc, "Z3_mk_unsigned_int64",
{bvConst, bvSort}); {bvConst, bvSort});
rewriter.replaceOp(op, res); rewriter.replaceOp(op, res);
@ -417,21 +417,21 @@ struct VariadicSMTPattern : public SMTLoweringPattern<SourceTy> {
return failure(); return failure();
Location loc = op.getLoc(); Location loc = op.getLoc();
Value numOperands = rewriter.create<LLVM::ConstantOp>( Value numOperands = LLVM::ConstantOp::create(
loc, rewriter.getI32Type(), op->getNumOperands()); rewriter, loc, rewriter.getI32Type(), op->getNumOperands());
Value constOne = Value constOne =
rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI32Type(), 1); LLVM::ConstantOp::create(rewriter, loc, rewriter.getI32Type(), 1);
Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext()); Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext());
Type arrTy = LLVM::LLVMArrayType::get(ptrTy, op->getNumOperands()); Type arrTy = LLVM::LLVMArrayType::get(ptrTy, op->getNumOperands());
Value storage = Value storage =
rewriter.create<LLVM::AllocaOp>(loc, ptrTy, arrTy, constOne); LLVM::AllocaOp::create(rewriter, loc, ptrTy, arrTy, constOne);
Value array = rewriter.create<LLVM::UndefOp>(loc, arrTy); Value array = LLVM::UndefOp::create(rewriter, loc, arrTy);
for (auto [i, operand] : llvm::enumerate(adaptor.getOperands())) for (auto [i, operand] : llvm::enumerate(adaptor.getOperands()))
array = rewriter.create<LLVM::InsertValueOp>( array = LLVM::InsertValueOp::create(rewriter, loc, array, operand,
loc, array, operand, ArrayRef<int64_t>{(int64_t)i}); ArrayRef<int64_t>{(int64_t)i});
rewriter.create<LLVM::StoreOp>(loc, array, storage); LLVM::StoreOp::create(rewriter, loc, array, storage);
rewriter.replaceOp(op, rewriter.replaceOp(op,
SMTLoweringPattern<SourceTy>::buildPtrAPICall( SMTLoweringPattern<SourceTy>::buildPtrAPICall(
@ -490,8 +490,8 @@ class LowerChainableSMTPattern : public SMTLoweringPattern<SourceTy> {
Location loc = op.getLoc(); Location loc = op.getLoc();
SmallVector<Value> elements; SmallVector<Value> elements;
for (int i = 1, e = adaptor.getOperands().size(); i < e; ++i) { for (int i = 1, e = adaptor.getOperands().size(); i < e; ++i) {
Value val = rewriter.create<SourceTy>( Value val = SourceTy::create(
loc, op->getResultTypes(), rewriter, loc, op->getResultTypes(),
ValueRange{adaptor.getOperands()[i - 1], adaptor.getOperands()[i]}); ValueRange{adaptor.getOperands()[i - 1], adaptor.getOperands()[i]});
elements.push_back(val); elements.push_back(val);
} }
@ -515,8 +515,8 @@ class LowerLeftAssocSMTPattern : public SMTLoweringPattern<SourceTy> {
Value runner = adaptor.getOperands()[0]; Value runner = adaptor.getOperands()[0];
for (Value val : adaptor.getOperands().drop_front()) for (Value val : adaptor.getOperands().drop_front())
runner = rewriter.create<SourceTy>(op.getLoc(), op->getResultTypes(), runner = SourceTy::create(rewriter, op.getLoc(), op->getResultTypes(),
ValueRange{runner, val}); ValueRange{runner, val});
rewriter.replaceOp(op, runner); rewriter.replaceOp(op, runner);
return success(); return success();
@ -597,8 +597,8 @@ struct SolverOpLowering : public SMTLoweringPattern<SolverOp> {
Value ctx = buildCall(rewriter, loc, "Z3_mk_context", ptrToPtrFunc, config) Value ctx = buildCall(rewriter, loc, "Z3_mk_context", ptrToPtrFunc, config)
.getResult(); .getResult();
Value ctxAddr = Value ctxAddr =
rewriter.create<LLVM::AddressOfOp>(loc, globals.ctx).getResult(); LLVM::AddressOfOp::create(rewriter, loc, globals.ctx).getResult();
rewriter.create<LLVM::StoreOp>(loc, ctx, ctxAddr); LLVM::StoreOp::create(rewriter, loc, ctx, ctxAddr);
// Delete the configuration again. // Delete the configuration again.
buildCall(rewriter, loc, "Z3_del_config", ptrToVoidFunc, {config}); buildCall(rewriter, loc, "Z3_del_config", ptrToVoidFunc, {config});
@ -618,8 +618,8 @@ struct SolverOpLowering : public SMTLoweringPattern<SolverOp> {
buildCall(rewriter, loc, "Z3_solver_inc_ref", ptrPtrToVoidFunc, buildCall(rewriter, loc, "Z3_solver_inc_ref", ptrPtrToVoidFunc,
{ctx, solver}); {ctx, solver});
Value solverAddr = Value solverAddr =
rewriter.create<LLVM::AddressOfOp>(loc, globals.solver).getResult(); LLVM::AddressOfOp::create(rewriter, loc, globals.solver).getResult();
rewriter.create<LLVM::StoreOp>(loc, solver, solverAddr); LLVM::StoreOp::create(rewriter, loc, solver, solverAddr);
// This assumes that no constant hoisting of the like happens inbetween // This assumes that no constant hoisting of the like happens inbetween
// the patterns defined in this pass because once the solver initialization // the patterns defined in this pass because once the solver initialization
@ -638,8 +638,8 @@ struct SolverOpLowering : public SMTLoweringPattern<SolverOp> {
auto module = op->getParentOfType<ModuleOp>(); auto module = op->getParentOfType<ModuleOp>();
rewriter.setInsertionPointToEnd(module.getBody()); rewriter.setInsertionPointToEnd(module.getBody());
funcOp = rewriter.create<func::FuncOp>( funcOp = func::FuncOp::create(
loc, globals.names.newName("solver"), rewriter, loc, globals.names.newName("solver"),
rewriter.getFunctionType(adaptor.getInputs().getTypes(), rewriter.getFunctionType(adaptor.getInputs().getTypes(),
convertedTypes)); convertedTypes));
rewriter.inlineRegionBefore(op.getBodyRegion(), funcOp.getBody(), rewriter.inlineRegionBefore(op.getBodyRegion(), funcOp.getBody(),
@ -647,7 +647,7 @@ struct SolverOpLowering : public SMTLoweringPattern<SolverOp> {
} }
ValueRange results = ValueRange results =
rewriter.create<func::CallOp>(loc, funcOp, adaptor.getInputs()) func::CallOp::create(rewriter, loc, funcOp, adaptor.getInputs())
->getResults(); ->getResults();
// At the end of the region, decrease the solver's reference counter and // At the end of the region, decrease the solver's reference counter and
@ -740,8 +740,8 @@ struct PopOpLowering : public SMTLoweringPattern<PopOp> {
matchAndRewrite(PopOp op, OpAdaptor adaptor, matchAndRewrite(PopOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
Location loc = op.getLoc(); Location loc = op.getLoc();
Value constVal = rewriter.create<LLVM::ConstantOp>( Value constVal = LLVM::ConstantOp::create(
loc, rewriter.getI32Type(), op.getCount()); rewriter, loc, rewriter.getI32Type(), op.getCount());
buildAPICallWithContext(rewriter, loc, "Z3_solver_pop", buildAPICallWithContext(rewriter, loc, "Z3_solver_pop",
LLVM::LLVMVoidType::get(getContext()), LLVM::LLVMVoidType::get(getContext()),
{buildSolverPtr(rewriter, loc), constVal}); {buildSolverPtr(rewriter, loc), constVal});
@ -831,12 +831,12 @@ struct CheckOpLowering : public SMTLoweringPattern<CheckOp> {
rewriter.getI32Type(), {solver}) rewriter.getI32Type(), {solver})
->getResult(0); ->getResult(0);
Value constOne = Value constOne =
rewriter.create<LLVM::ConstantOp>(loc, checkResult.getType(), 1); LLVM::ConstantOp::create(rewriter, loc, checkResult.getType(), 1);
Value isSat = rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::eq, Value isSat = LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::eq,
checkResult, constOne); checkResult, constOne);
// Simply inline the 'sat' region into the 'then' region of the 'scf.if' // Simply inline the 'sat' region into the 'then' region of the 'scf.if'
auto satIfOp = rewriter.create<scf::IfOp>(loc, resultTypes, isSat); auto satIfOp = scf::IfOp::create(rewriter, loc, resultTypes, isSat);
rewriter.inlineRegionBefore(op.getSatRegion(), satIfOp.getThenRegion(), rewriter.inlineRegionBefore(op.getSatRegion(), satIfOp.getThenRegion(),
satIfOp.getThenRegion().end()); satIfOp.getThenRegion().end());
@ -845,11 +845,11 @@ struct CheckOpLowering : public SMTLoweringPattern<CheckOp> {
// two branches of this nested if-statement as well. // two branches of this nested if-statement as well.
rewriter.createBlock(&satIfOp.getElseRegion()); rewriter.createBlock(&satIfOp.getElseRegion());
Value constNegOne = Value constNegOne =
rewriter.create<LLVM::ConstantOp>(loc, checkResult.getType(), -1); LLVM::ConstantOp::create(rewriter, loc, checkResult.getType(), -1);
Value isUnsat = rewriter.create<LLVM::ICmpOp>(loc, LLVM::ICmpPredicate::eq, Value isUnsat = LLVM::ICmpOp::create(rewriter, loc, LLVM::ICmpPredicate::eq,
checkResult, constNegOne); checkResult, constNegOne);
auto unsatIfOp = rewriter.create<scf::IfOp>(loc, resultTypes, isUnsat); auto unsatIfOp = scf::IfOp::create(rewriter, loc, resultTypes, isUnsat);
rewriter.create<scf::YieldOp>(loc, unsatIfOp->getResults()); scf::YieldOp::create(rewriter, loc, unsatIfOp->getResults());
rewriter.inlineRegionBefore(op.getUnsatRegion(), unsatIfOp.getThenRegion(), rewriter.inlineRegionBefore(op.getUnsatRegion(), unsatIfOp.getThenRegion(),
unsatIfOp.getThenRegion().end()); unsatIfOp.getThenRegion().end());
@ -922,16 +922,16 @@ struct QuantifierLowering : public SMTLoweringPattern<QuantifierOp> {
Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext()); Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext());
Type arrTy = LLVM::LLVMArrayType::get(ptrTy, values.size()); Type arrTy = LLVM::LLVMArrayType::get(ptrTy, values.size());
Value constOne = Value constOne =
rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI32Type(), 1); LLVM::ConstantOp::create(rewriter, loc, rewriter.getI32Type(), 1);
Value storage = Value storage =
rewriter.create<LLVM::AllocaOp>(loc, ptrTy, arrTy, constOne); LLVM::AllocaOp::create(rewriter, loc, ptrTy, arrTy, constOne);
Value array = rewriter.create<LLVM::UndefOp>(loc, arrTy); Value array = LLVM::UndefOp::create(rewriter, loc, arrTy);
for (auto [i, val] : llvm::enumerate(values)) for (auto [i, val] : llvm::enumerate(values))
array = rewriter.create<LLVM::InsertValueOp>(loc, array, val, array = LLVM::InsertValueOp::create(rewriter, loc, array, val,
ArrayRef<int64_t>(i)); ArrayRef<int64_t>(i));
rewriter.create<LLVM::StoreOp>(loc, array, storage); LLVM::StoreOp::create(rewriter, loc, array, storage);
return storage; return storage;
} }
@ -953,13 +953,13 @@ struct QuantifierLowering : public SMTLoweringPattern<QuantifierOp> {
rewriter.setInsertionPoint(op); rewriter.setInsertionPoint(op);
// Weight attribute // Weight attribute
Value weight = rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI32Type(), Value weight = LLVM::ConstantOp::create(
adaptor.getWeight()); rewriter, loc, rewriter.getI32Type(), adaptor.getWeight());
// Bound variables // Bound variables
unsigned numDecls = op.getBody().getNumArguments(); unsigned numDecls = op.getBody().getNumArguments();
Value numDeclsVal = Value numDeclsVal = LLVM::ConstantOp::create(
rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI32Type(), numDecls); rewriter, loc, rewriter.getI32Type(), numDecls);
// We replace the block arguments with constant symbolic values and inform // We replace the block arguments with constant symbolic values and inform
// the quantifier API call which constants it should treat as bound // the quantifier API call which constants it should treat as bound
@ -970,11 +970,11 @@ struct QuantifierLowering : public SMTLoweringPattern<QuantifierOp> {
for (auto [i, arg] : llvm::enumerate(op.getBody().getArguments())) { for (auto [i, arg] : llvm::enumerate(op.getBody().getArguments())) {
Value newArg; Value newArg;
if (adaptor.getBoundVarNames().has_value()) if (adaptor.getBoundVarNames().has_value())
newArg = rewriter.create<smt::DeclareFunOp>( newArg = smt::DeclareFunOp::create(
loc, arg.getType(), rewriter, loc, arg.getType(),
cast<StringAttr>((*adaptor.getBoundVarNames())[i])); cast<StringAttr>((*adaptor.getBoundVarNames())[i]));
else else
newArg = rewriter.create<smt::DeclareFunOp>(loc, arg.getType()); newArg = smt::DeclareFunOp::create(rewriter, loc, arg.getType());
repl.push_back(typeConverter->materializeTargetConversion( repl.push_back(typeConverter->materializeTargetConversion(
rewriter, loc, typeConverter->convertType(arg.getType()), newArg)); rewriter, loc, typeConverter->convertType(arg.getType()), newArg));
} }
@ -994,8 +994,8 @@ struct QuantifierLowering : public SMTLoweringPattern<QuantifierOp> {
// Patterns // Patterns
unsigned numPatterns = adaptor.getPatterns().size(); unsigned numPatterns = adaptor.getPatterns().size();
Value numPatternsVal = rewriter.create<LLVM::ConstantOp>( Value numPatternsVal = LLVM::ConstantOp::create(
loc, rewriter.getI32Type(), numPatterns); rewriter, loc, rewriter.getI32Type(), numPatterns);
Value patternStorage; Value patternStorage;
if (numPatterns > 0) { if (numPatterns > 0) {
@ -1015,8 +1015,8 @@ struct QuantifierLowering : public SMTLoweringPattern<QuantifierOp> {
rewriter.inlineBlockBefore(&patternRegion->front(), op, repl); rewriter.inlineBlockBefore(&patternRegion->front(), op, repl);
rewriter.setInsertionPoint(op); rewriter.setInsertionPoint(op);
Value numTerms = rewriter.create<LLVM::ConstantOp>( Value numTerms = LLVM::ConstantOp::create(
loc, rewriter.getI32Type(), patternTerms.size()); rewriter, loc, rewriter.getI32Type(), patternTerms.size());
Value patternTermStorage = Value patternTermStorage =
createStorageForValueList(patternList, loc, rewriter); createStorageForValueList(patternList, loc, rewriter);
Value pattern = buildPtrAPICall(rewriter, loc, "Z3_mk_pattern", Value pattern = buildPtrAPICall(rewriter, loc, "Z3_mk_pattern",
@ -1028,7 +1028,7 @@ struct QuantifierLowering : public SMTLoweringPattern<QuantifierOp> {
} else { } else {
// If we set the num_patterns parameter to 0, we can just pass a nullptr // If we set the num_patterns parameter to 0, we can just pass a nullptr
// as storage. // as storage.
patternStorage = rewriter.create<LLVM::ZeroOp>(loc, ptrTy); patternStorage = LLVM::ZeroOp::create(rewriter, loc, ptrTy);
} }
StringRef apiCallName = "Z3_mk_forall_const"; StringRef apiCallName = "Z3_mk_forall_const";
@ -1054,8 +1054,8 @@ struct RepeatOpLowering : public SMTLoweringPattern<RepeatOp> {
LogicalResult LogicalResult
matchAndRewrite(RepeatOp op, OpAdaptor adaptor, matchAndRewrite(RepeatOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
Value count = rewriter.create<LLVM::ConstantOp>( Value count = LLVM::ConstantOp::create(
op.getLoc(), rewriter.getI32Type(), op.getCount()); rewriter, op.getLoc(), rewriter.getI32Type(), op.getCount());
rewriter.replaceOp(op, rewriter.replaceOp(op,
buildPtrAPICall(rewriter, op.getLoc(), "Z3_mk_repeat", buildPtrAPICall(rewriter, op.getLoc(), "Z3_mk_repeat",
{count, adaptor.getInput()})); {count, adaptor.getInput()}));
@ -1077,11 +1077,11 @@ struct ExtractOpLowering : public SMTLoweringPattern<ExtractOp> {
matchAndRewrite(ExtractOp op, OpAdaptor adaptor, matchAndRewrite(ExtractOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
Location loc = op.getLoc(); Location loc = op.getLoc();
Value low = rewriter.create<LLVM::ConstantOp>(loc, rewriter.getI32Type(), Value low = LLVM::ConstantOp::create(rewriter, loc, rewriter.getI32Type(),
adaptor.getLowBit()); adaptor.getLowBit());
Value high = rewriter.create<LLVM::ConstantOp>( Value high = LLVM::ConstantOp::create(rewriter, loc, rewriter.getI32Type(),
loc, rewriter.getI32Type(), adaptor.getLowBit() +
adaptor.getLowBit() + op.getType().getWidth() - 1); op.getType().getWidth() - 1);
rewriter.replaceOp(op, buildPtrAPICall(rewriter, loc, "Z3_mk_extract", rewriter.replaceOp(op, buildPtrAPICall(rewriter, loc, "Z3_mk_extract",
{high, low, adaptor.getInput()})); {high, low, adaptor.getInput()}));
return success(); return success();
@ -1149,8 +1149,8 @@ struct IntConstantOpLowering : public SMTLoweringPattern<smt::IntConstantOp> {
Location loc = op.getLoc(); Location loc = op.getLoc();
Value type = buildPtrAPICall(rewriter, loc, "Z3_mk_int_sort"); Value type = buildPtrAPICall(rewriter, loc, "Z3_mk_int_sort");
if (adaptor.getValue().getBitWidth() <= 64) { if (adaptor.getValue().getBitWidth() <= 64) {
Value val = rewriter.create<LLVM::ConstantOp>( Value val = LLVM::ConstantOp::create(rewriter, loc, rewriter.getI64Type(),
loc, rewriter.getI64Type(), adaptor.getValue().getSExtValue()); adaptor.getValue().getSExtValue());
rewriter.replaceOp( rewriter.replaceOp(
op, buildPtrAPICall(rewriter, loc, "Z3_mk_int64", {val, type})); op, buildPtrAPICall(rewriter, loc, "Z3_mk_int64", {val, type}));
return success(); return success();
@ -1204,8 +1204,8 @@ struct Int2BVOpLowering : public SMTLoweringPattern<Int2BVOp> {
matchAndRewrite(Int2BVOp op, OpAdaptor adaptor, matchAndRewrite(Int2BVOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
Value widthConst = Value widthConst =
rewriter.create<LLVM::ConstantOp>(op->getLoc(), rewriter.getI32Type(), LLVM::ConstantOp::create(rewriter, op->getLoc(), rewriter.getI32Type(),
op.getResult().getType().getWidth()); op.getResult().getType().getWidth());
rewriter.replaceOp(op, rewriter.replaceOp(op,
buildPtrAPICall(rewriter, op.getLoc(), "Z3_mk_int2bv", buildPtrAPICall(rewriter, op.getLoc(), "Z3_mk_int2bv",
{widthConst, adaptor.getInput()})); {widthConst, adaptor.getInput()}));
@ -1225,8 +1225,8 @@ struct BV2IntOpLowering : public SMTLoweringPattern<BV2IntOp> {
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
// FIXME: ideally we don't want to use i1 here, since bools can sometimes be // FIXME: ideally we don't want to use i1 here, since bools can sometimes be
// compiled to wider widths in LLVM // compiled to wider widths in LLVM
Value isSignedConst = rewriter.create<LLVM::ConstantOp>( Value isSignedConst = LLVM::ConstantOp::create(
op->getLoc(), rewriter.getI1Type(), op.getIsSigned()); rewriter, op->getLoc(), rewriter.getI1Type(), op.getIsSigned());
rewriter.replaceOp(op, rewriter.replaceOp(op,
buildPtrAPICall(rewriter, op.getLoc(), "Z3_mk_bv2int", buildPtrAPICall(rewriter, op.getLoc(), "Z3_mk_bv2int",
{adaptor.getInput(), isSignedConst})); {adaptor.getInput(), isSignedConst}));
@ -1263,11 +1263,11 @@ struct IntAbsOpLowering : public SMTLoweringPattern<IntAbsOp> {
matchAndRewrite(IntAbsOp op, OpAdaptor adaptor, matchAndRewrite(IntAbsOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
Location loc = op.getLoc(); Location loc = op.getLoc();
Value zero = rewriter.create<IntConstantOp>( Value zero = IntConstantOp::create(
loc, rewriter.getIntegerAttr(rewriter.getI1Type(), 0)); rewriter, loc, rewriter.getIntegerAttr(rewriter.getI1Type(), 0));
Value cmp = rewriter.create<IntCmpOp>(loc, IntPredicate::lt, Value cmp = IntCmpOp::create(rewriter, loc, IntPredicate::lt,
adaptor.getInput(), zero); adaptor.getInput(), zero);
Value neg = rewriter.create<IntSubOp>(loc, zero, adaptor.getInput()); Value neg = IntSubOp::create(rewriter, loc, zero, adaptor.getInput());
rewriter.replaceOpWithNewOp<IteOp>(op, cmp, neg, adaptor.getInput()); rewriter.replaceOpWithNewOp<IteOp>(op, cmp, neg, adaptor.getInput());
return success(); return success();
} }

View File

@ -131,8 +131,8 @@ FlatSymbolRefAttr FirMemLowering::getOrCreateSchema() {
"readUnderWrite", "writeUnderWrite", "readUnderWrite", "writeUnderWrite",
"writeClockIDs", "initFilename", "writeClockIDs", "initFilename",
"initIsBinary", "initIsInline"}; "initIsBinary", "initIsInline"};
schemaOp = builder.create<hw::HWGeneratorSchemaOp>( schemaOp = hw::HWGeneratorSchemaOp::create(
circuit.getLoc(), "FIRRTLMem", "FIRRTL_Memory", builder, circuit.getLoc(), "FIRRTLMem", "FIRRTL_Memory",
builder.getStrArrayAttr(schemaFields)); builder.getStrArrayAttr(schemaFields));
} }
} }
@ -292,8 +292,9 @@ FirMemLowering::createMemoryModule(FirMemConfig &mem,
} }
// Create the module. // Create the module.
auto genOp = builder.create<hw::HWModuleGeneratedOp>( auto genOp =
loc, schemaSymRef, name, ports, StringRef{}, ArrayAttr{}, genAttrs); hw::HWModuleGeneratedOp::create(builder, loc, schemaSymRef, name, ports,
StringRef{}, ArrayAttr{}, genAttrs);
if (mem.outputFile) if (mem.outputFile)
genOp->setAttr("output_file", mem.outputFile); genOp->setAttr("output_file", mem.outputFile);
@ -313,8 +314,8 @@ void FirMemLowering::lowerMemoriesInModule(
auto it = constOneOps.try_emplace(width, Value{}); auto it = constOneOps.try_emplace(width, Value{});
if (it.second) { if (it.second) {
auto builder = OpBuilder::atBlockBegin(module.getBodyBlock()); auto builder = OpBuilder::atBlockBegin(module.getBodyBlock());
it.first->second = builder.create<hw::ConstantOp>( it.first->second = hw::ConstantOp::create(
module.getLoc(), builder.getIntegerType(width), 1); builder, module.getLoc(), builder.getIntegerType(width), 1);
} }
return it.first->second; return it.first->second;
}; };
@ -374,9 +375,9 @@ void FirMemLowering::lowerMemoriesInModule(
if (auto name = memOp.getName(); name && !name->empty()) if (auto name = memOp.getName(); name && !name->empty())
memName = *name; memName = *name;
ImplicitLocOpBuilder builder(memOp.getLoc(), memOp); ImplicitLocOpBuilder builder(memOp.getLoc(), memOp);
auto instOp = builder.create<hw::InstanceOp>( auto instOp = hw::InstanceOp::create(
genOp, builder.getStringAttr(memName + "_ext"), inputs, ArrayAttr{}, builder, genOp, builder.getStringAttr(memName + "_ext"), inputs,
memOp.getInnerSymAttr()); ArrayAttr{}, memOp.getInnerSymAttr());
for (auto [oldOutput, newOutput] : llvm::zip(outputs, instOp.getResults())) for (auto [oldOutput, newOutput] : llvm::zip(outputs, instOp.getResults()))
oldOutput.replaceAllUsesWith(newOutput); oldOutput.replaceAllUsesWith(newOutput);

View File

@ -104,7 +104,7 @@ void FirRegLowering::addToIfBlock(OpBuilder &builder, Value cond,
// later. This way we don't have to build a new if and replace it. // later. This way we don't have to build a new if and replace it.
if (!op) { if (!op) {
auto newIfOp = auto newIfOp =
builder.create<sv::IfOp>(cond.getLoc(), cond, trueSide, falseSide); sv::IfOp::create(builder, cond.getLoc(), cond, trueSide, falseSide);
ifCache.insert({{builder.getBlock(), cond}, newIfOp}); ifCache.insert({{builder.getBlock(), cond}, newIfOp});
} else { } else {
OpBuilder::InsertionGuard guard(builder); OpBuilder::InsertionGuard guard(builder);
@ -213,7 +213,7 @@ static hw::HierPathOp getHierPathTo(OpBuilder &builder, Namespace &ns,
builder.setInsertionPoint(entry.reg->getParentOfType<HWModuleOp>()); builder.setInsertionPoint(entry.reg->getParentOfType<HWModuleOp>());
auto path = builder.getArrayAttr({entry.ref}); auto path = builder.getArrayAttr({entry.ref});
return builder.create<hw::HierPathOp>(entry.reg.getLoc(), name, path); return hw::HierPathOp::create(builder, entry.reg.getLoc(), name, path);
} }
FirRegLowering::PathTable FirRegLowering::createPaths(mlir::ModuleOp top) { FirRegLowering::PathTable FirRegLowering::createPaths(mlir::ModuleOp top) {
@ -296,8 +296,8 @@ SmallVector<Value> FirRegLowering::createRandomizationVector(OpBuilder &builder,
// Create randomization vector // Create randomization vector
SmallVector<Value> randValues; SmallVector<Value> randValues;
auto numRandomCalls = (maxBit + 31) / 32; auto numRandomCalls = (maxBit + 31) / 32;
auto logic = builder.create<sv::LogicOp>( auto logic = sv::LogicOp::create(
loc, builder, loc,
hw::UnpackedArrayType::get(builder.getIntegerType(32), numRandomCalls), hw::UnpackedArrayType::get(builder.getIntegerType(32), numRandomCalls),
"_RANDOM"); "_RANDOM");
// Indvar's width must be equal to `ceil(log2(numRandomCalls + // Indvar's width must be equal to `ceil(log2(numRandomCalls +
@ -308,21 +308,23 @@ SmallVector<Value> FirRegLowering::createRandomizationVector(OpBuilder &builder,
auto ub = auto ub =
getOrCreateConstant(loc, APInt(inducionVariableWidth, numRandomCalls)); getOrCreateConstant(loc, APInt(inducionVariableWidth, numRandomCalls));
auto step = getOrCreateConstant(loc, APInt(inducionVariableWidth, 1)); auto step = getOrCreateConstant(loc, APInt(inducionVariableWidth, 1));
auto forLoop = builder.create<sv::ForOp>( auto forLoop = sv::ForOp::create(
loc, lb, ub, step, "i", [&](BlockArgument iter) { builder, loc, lb, ub, step, "i", [&](BlockArgument iter) {
auto rhs = builder.create<sv::MacroRefExprSEOp>( auto rhs = sv::MacroRefExprSEOp::create(
loc, builder.getIntegerType(32), "RANDOM"); builder, loc, builder.getIntegerType(32), "RANDOM");
Value iterValue = iter; Value iterValue = iter;
if (!iter.getType().isInteger(arrayIndexWith)) if (!iter.getType().isInteger(arrayIndexWith))
iterValue = builder.create<comb::ExtractOp>(loc, iterValue, 0, iterValue = comb::ExtractOp::create(builder, loc, iterValue, 0,
arrayIndexWith); arrayIndexWith);
auto lhs = builder.create<sv::ArrayIndexInOutOp>(loc, logic, iterValue); auto lhs =
builder.create<sv::BPAssignOp>(loc, lhs, rhs); sv::ArrayIndexInOutOp::create(builder, loc, logic, iterValue);
sv::BPAssignOp::create(builder, loc, lhs, rhs);
}); });
builder.setInsertionPointAfter(forLoop); builder.setInsertionPointAfter(forLoop);
for (uint64_t x = 0; x < numRandomCalls; ++x) { for (uint64_t x = 0; x < numRandomCalls; ++x) {
auto lhs = builder.create<sv::ArrayIndexInOutOp>( auto lhs = sv::ArrayIndexInOutOp::create(
loc, logic, getOrCreateConstant(loc, APInt(arrayIndexWith, x))); builder, loc, logic,
getOrCreateConstant(loc, APInt(arrayIndexWith, x)));
randValues.push_back(lhs.getResult()); randValues.push_back(lhs.getResult());
} }
@ -334,11 +336,11 @@ void FirRegLowering::createRandomInitialization(ImplicitLocOpBuilder &builder) {
sv::MacroIdentAttr::get(builder.getContext(), "RANDOMIZE_REG_INIT"); sv::MacroIdentAttr::get(builder.getContext(), "RANDOMIZE_REG_INIT");
if (!randomInitRegs.empty()) { if (!randomInitRegs.empty()) {
builder.create<sv::IfDefProceduralOp>("INIT_RANDOM_PROLOG_", [&] { sv::IfDefProceduralOp::create(builder, "INIT_RANDOM_PROLOG_", [&] {
builder.create<sv::VerbatimOp>("`INIT_RANDOM_PROLOG_"); sv::VerbatimOp::create(builder, "`INIT_RANDOM_PROLOG_");
}); });
builder.create<sv::IfDefProceduralOp>(randInitRef, [&] { sv::IfDefProceduralOp::create(builder, randInitRef, [&] {
auto randValues = createRandomizationVector(builder, builder.getLoc()); auto randValues = createRandomizationVector(builder, builder.getLoc());
for (auto &svReg : randomInitRegs) for (auto &svReg : randomInitRegs)
initialize(builder, svReg, randValues); initialize(builder, svReg, randValues);
@ -356,9 +358,9 @@ void FirRegLowering::createPresetInitialization(ImplicitLocOpBuilder &builder) {
if (cst.getType() == elemTy) if (cst.getType() == elemTy)
rhs = cst; rhs = cst;
else else
rhs = builder.create<hw::BitcastOp>(loc, elemTy, cst); rhs = hw::BitcastOp::create(builder, loc, elemTy, cst);
builder.create<sv::BPAssignOp>(loc, svReg.reg, rhs); sv::BPAssignOp::create(builder, loc, svReg.reg, rhs);
} }
} }
@ -371,10 +373,10 @@ void FirRegLowering::createAsyncResetInitialization(
// if (reset) begin // if (reset) begin
// .. // ..
// end // end
builder.create<sv::IfOp>(reset.first, [&] { sv::IfOp::create(builder, reset.first, [&] {
for (auto &reg : reset.second) for (auto &reg : reset.second)
builder.create<sv::BPAssignOp>(reg.reg.getLoc(), reg.reg, sv::BPAssignOp::create(builder, reg.reg.getLoc(), reg.reg,
reg.asyncResetValue); reg.asyncResetValue);
}); });
} }
} }
@ -401,20 +403,20 @@ void FirRegLowering::createInitialBlock() {
auto builder = auto builder =
ImplicitLocOpBuilder::atBlockTerminator(loc, module.getBodyBlock()); ImplicitLocOpBuilder::atBlockTerminator(loc, module.getBodyBlock());
builder.create<sv::IfDefOp>("ENABLE_INITIAL_REG_", [&] { sv::IfDefOp::create(builder, "ENABLE_INITIAL_REG_", [&] {
builder.create<sv::OrderedOutputOp>([&] { sv::OrderedOutputOp::create(builder, [&] {
builder.create<sv::IfDefOp>("FIRRTL_BEFORE_INITIAL", [&] { sv::IfDefOp::create(builder, "FIRRTL_BEFORE_INITIAL", [&] {
builder.create<sv::VerbatimOp>("`FIRRTL_BEFORE_INITIAL"); sv::VerbatimOp::create(builder, "`FIRRTL_BEFORE_INITIAL");
}); });
builder.create<sv::InitialOp>([&] { sv::InitialOp::create(builder, [&] {
createRandomInitialization(builder); createRandomInitialization(builder);
createPresetInitialization(builder); createPresetInitialization(builder);
createAsyncResetInitialization(builder); createAsyncResetInitialization(builder);
}); });
builder.create<sv::IfDefOp>("FIRRTL_AFTER_INITIAL", [&] { sv::IfDefOp::create(builder, "FIRRTL_AFTER_INITIAL", [&] {
builder.create<sv::VerbatimOp>("`FIRRTL_AFTER_INITIAL"); sv::VerbatimOp::create(builder, "`FIRRTL_AFTER_INITIAL");
}); });
}); });
}); });
@ -566,7 +568,7 @@ void FirRegLowering::createTree(OpBuilder &builder, Value reg, Value term,
// Create an array index op just after `reg`. // Create an array index op just after `reg`.
OpBuilder::InsertionGuard guard(builder); OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPointAfterValue(reg); builder.setInsertionPointAfterValue(reg);
return builder.create<sv::ArrayIndexInOutOp>(reg.getLoc(), reg, idx); return sv::ArrayIndexInOutOp::create(builder, reg.getLoc(), reg, idx);
}; };
SmallVector<Value, 8> opsToDelete; SmallVector<Value, 8> opsToDelete;
@ -588,7 +590,7 @@ void FirRegLowering::createTree(OpBuilder &builder, Value reg, Value term,
if (mux && mux.getTwoState() && if (mux && mux.getTwoState() &&
reachableMuxes->isMuxReachableFrom(firReg, mux)) { reachableMuxes->isMuxReachableFrom(firReg, mux)) {
if (counter >= limit) { if (counter >= limit) {
builder.create<sv::PAssignOp>(term.getLoc(), reg, next); sv::PAssignOp::create(builder, term.getLoc(), reg, next);
continue; continue;
} }
addToIfBlock( addToIfBlock(
@ -614,7 +616,7 @@ void FirRegLowering::createTree(OpBuilder &builder, Value reg, Value term,
// recursive calls. Add the value to `opsToDelete` so that it can // recursive calls. Add the value to `opsToDelete` so that it can
// be deleted afterwards. // be deleted afterwards.
auto termElement = auto termElement =
builder.create<hw::ArrayGetOp>(term.getLoc(), term, index); hw::ArrayGetOp::create(builder, term.getLoc(), term, index);
opsToDelete.push_back(termElement); opsToDelete.push_back(termElement);
addToWorklist(nextReg, termElement, trueValue); addToWorklist(nextReg, termElement, trueValue);
}, },
@ -642,14 +644,14 @@ void FirRegLowering::createTree(OpBuilder &builder, Value reg, Value term,
// recursive calls. Add the value to `opsToDelete` so that it can // recursive calls. Add the value to `opsToDelete` so that it can
// be deleted afterwards. // be deleted afterwards.
auto termElement = auto termElement =
builder.create<hw::ArrayGetOp>(term.getLoc(), term, idxVal); hw::ArrayGetOp::create(builder, term.getLoc(), term, idxVal);
opsToDelete.push_back(termElement); opsToDelete.push_back(termElement);
addToWorklist(index, termElement, value); addToWorklist(index, termElement, value);
} }
continue; continue;
} }
builder.create<sv::PAssignOp>(term.getLoc(), reg, next); sv::PAssignOp::create(builder, term.getLoc(), reg, next);
} }
while (!opsToDelete.empty()) { while (!opsToDelete.empty()) {
@ -671,7 +673,7 @@ void FirRegLowering::lowerReg(FirRegOp reg) {
ImplicitLocOpBuilder builder(reg.getLoc(), reg); ImplicitLocOpBuilder builder(reg.getLoc(), reg);
RegLowerInfo svReg{nullptr, path, reg.getPresetAttr(), nullptr, nullptr, RegLowerInfo svReg{nullptr, path, reg.getPresetAttr(), nullptr, nullptr,
-1, 0}; -1, 0};
svReg.reg = builder.create<sv::RegOp>(loc, regTy, reg.getNameAttr()); svReg.reg = sv::RegOp::create(builder, loc, regTy, reg.getNameAttr());
svReg.width = hw::getBitWidth(regTy); svReg.width = hw::getBitWidth(regTy);
if (auto attr = reg->getAttrOfType<IntegerAttr>("firrtl.random_init_start")) if (auto attr = reg->getAttrOfType<IntegerAttr>("firrtl.random_init_start"))
@ -686,7 +688,7 @@ void FirRegLowering::lowerReg(FirRegOp reg) {
if (auto innerSymAttr = reg.getInnerSymAttr()) if (auto innerSymAttr = reg.getInnerSymAttr())
svReg.reg.setInnerSymAttr(innerSymAttr); svReg.reg.setInnerSymAttr(innerSymAttr);
auto regVal = builder.create<sv::ReadInOutOp>(loc, svReg.reg); auto regVal = sv::ReadInOutOp::create(builder, loc, svReg.reg);
if (reg.hasReset()) { if (reg.hasReset()) {
addToAlwaysBlock( addToAlwaysBlock(
@ -695,14 +697,14 @@ void FirRegLowering::lowerReg(FirRegOp reg) {
// If this is an AsyncReset, ensure that we emit a self connect to // If this is an AsyncReset, ensure that we emit a self connect to
// avoid erroneously creating a latch construct. // avoid erroneously creating a latch construct.
if (reg.getIsAsync() && areEquivalentValues(reg, reg.getNext())) if (reg.getIsAsync() && areEquivalentValues(reg, reg.getNext()))
b.create<sv::PAssignOp>(reg.getLoc(), svReg.reg, reg); sv::PAssignOp::create(b, reg.getLoc(), svReg.reg, reg);
else else
createTree(b, svReg.reg, reg, reg.getNext()); createTree(b, svReg.reg, reg, reg.getNext());
}, },
reg.getIsAsync() ? sv::ResetType::AsyncReset : sv::ResetType::SyncReset, reg.getIsAsync() ? sv::ResetType::AsyncReset : sv::ResetType::SyncReset,
sv::EventControl::AtPosEdge, reg.getReset(), sv::EventControl::AtPosEdge, reg.getReset(),
[&](OpBuilder &builder) { [&](OpBuilder &builder) {
builder.create<sv::PAssignOp>(loc, svReg.reg, reg.getResetValue()); sv::PAssignOp::create(builder, loc, svReg.reg, reg.getResetValue());
}); });
if (reg.getIsAsync()) { if (reg.getIsAsync()) {
svReg.asyncResetSignal = reg.getReset(); svReg.asyncResetSignal = reg.getReset();
@ -749,19 +751,19 @@ void FirRegLowering::initializeRegisterElements(Location loc,
pos -= intTy.getWidth(); pos -= intTy.getWidth();
auto elem = builder.createOrFold<comb::ExtractOp>(loc, randomSource, pos, auto elem = builder.createOrFold<comb::ExtractOp>(loc, randomSource, pos,
intTy.getWidth()); intTy.getWidth());
builder.create<sv::BPAssignOp>(loc, reg, elem); sv::BPAssignOp::create(builder, loc, reg, elem);
} else if (auto array = hw::type_dyn_cast<hw::ArrayType>(type)) { } else if (auto array = hw::type_dyn_cast<hw::ArrayType>(type)) {
for (unsigned i = 0, e = array.getNumElements(); i < e; ++i) { for (unsigned i = 0, e = array.getNumElements(); i < e; ++i) {
auto index = getOrCreateConstant(loc, APInt(llvm::Log2_64_Ceil(e), i)); auto index = getOrCreateConstant(loc, APInt(llvm::Log2_64_Ceil(e), i));
initializeRegisterElements( initializeRegisterElements(
loc, builder, builder.create<sv::ArrayIndexInOutOp>(loc, reg, index), loc, builder, sv::ArrayIndexInOutOp::create(builder, loc, reg, index),
randomSource, pos); randomSource, pos);
} }
} else if (auto structType = hw::type_dyn_cast<hw::StructType>(type)) { } else if (auto structType = hw::type_dyn_cast<hw::StructType>(type)) {
for (auto e : structType.getElements()) for (auto e : structType.getElements())
initializeRegisterElements( initializeRegisterElements(
loc, builder, loc, builder,
builder.create<sv::StructFieldInOutOp>(loc, reg, e.name), sv::StructFieldInOutOp::create(builder, loc, reg, e.name),
randomSource, pos); randomSource, pos);
} else { } else {
assert(false && "unsupported type"); assert(false && "unsupported type");
@ -780,14 +782,14 @@ void FirRegLowering::buildRegConditions(OpBuilder &b, sv::RegOp reg) {
for (auto &condition : conditions) { for (auto &condition : conditions) {
auto kind = condition.getKind(); auto kind = condition.getKind();
if (kind == RegCondition::IfDefThen) { if (kind == RegCondition::IfDefThen) {
auto ifDef = b.create<sv::IfDefProceduralOp>( auto ifDef = sv::IfDefProceduralOp::create(b, reg.getLoc(),
reg.getLoc(), condition.getMacro(), []() {}); condition.getMacro(), []() {});
b.setInsertionPointToEnd(ifDef.getThenBlock()); b.setInsertionPointToEnd(ifDef.getThenBlock());
continue; continue;
} }
if (kind == RegCondition::IfDefElse) { if (kind == RegCondition::IfDefElse) {
auto ifDef = b.create<sv::IfDefProceduralOp>( auto ifDef = sv::IfDefProceduralOp::create(
reg.getLoc(), condition.getMacro(), []() {}, []() {}); b, reg.getLoc(), condition.getMacro(), []() {}, []() {});
b.setInsertionPointToEnd(ifDef.getElseBlock()); b.setInsertionPointToEnd(ifDef.getElseBlock());
continue; continue;
@ -800,7 +802,7 @@ static Value buildXMRTo(OpBuilder &builder, HierPathOp path, Location loc,
Type type) { Type type) {
auto name = path.getSymNameAttr(); auto name = path.getSymNameAttr();
auto ref = mlir::FlatSymbolRefAttr::get(name); auto ref = mlir::FlatSymbolRefAttr::get(name);
return builder.create<sv::XMRRefOp>(loc, type, ref); return sv::XMRRefOp::create(builder, loc, type, ref);
} }
void FirRegLowering::initialize(OpBuilder &builder, RegLowerInfo reg, void FirRegLowering::initialize(OpBuilder &builder, RegLowerInfo reg,
@ -830,7 +832,7 @@ void FirRegLowering::initialize(OpBuilder &builder, RegLowerInfo reg,
auto index = offset / 32; auto index = offset / 32;
auto start = offset % 32; auto start = offset % 32;
auto nwidth = std::min(32 - start, width); auto nwidth = std::min(32 - start, width);
auto elemVal = builder.create<sv::ReadInOutOp>(loc, rands[index]); auto elemVal = sv::ReadInOutOp::create(builder, loc, rands[index]);
auto elem = auto elem =
builder.createOrFold<comb::ExtractOp>(loc, elemVal, start, nwidth); builder.createOrFold<comb::ExtractOp>(loc, elemVal, start, nwidth);
nibbles.push_back(elem); nibbles.push_back(elem);
@ -877,24 +879,24 @@ void FirRegLowering::addToAlwaysBlock(
auto createIfOp = [&]() { auto createIfOp = [&]() {
// It is weird but intended. Here we want to create an empty sv.if // It is weird but intended. Here we want to create an empty sv.if
// with an else block. // with an else block.
insideIfOp = builder.create<sv::IfOp>( insideIfOp = sv::IfOp::create(
reset, []() {}, []() {}); builder, reset, []() {}, []() {});
}; };
if (resetStyle == sv::ResetType::AsyncReset) { if (resetStyle == sv::ResetType::AsyncReset) {
sv::EventControl events[] = {clockEdge, resetEdge}; sv::EventControl events[] = {clockEdge, resetEdge};
Value clocks[] = {clock, reset}; Value clocks[] = {clock, reset};
alwaysOp = builder.create<sv::AlwaysOp>(events, clocks, [&]() { alwaysOp = sv::AlwaysOp::create(builder, events, clocks, [&]() {
if (resetEdge == sv::EventControl::AtNegEdge) if (resetEdge == sv::EventControl::AtNegEdge)
llvm_unreachable("negative edge for reset is not expected"); llvm_unreachable("negative edge for reset is not expected");
createIfOp(); createIfOp();
}); });
} else { } else {
alwaysOp = builder.create<sv::AlwaysOp>(clockEdge, clock, createIfOp); alwaysOp = sv::AlwaysOp::create(builder, clockEdge, clock, createIfOp);
} }
} else { } else {
assert(!resetBody); assert(!resetBody);
alwaysOp = builder.create<sv::AlwaysOp>(clockEdge, clock); alwaysOp = sv::AlwaysOp::create(builder, clockEdge, clock);
insideIfOp = nullptr; insideIfOp = nullptr;
} }
} }

View File

@ -102,7 +102,7 @@ LogicalResult
ModuleLoweringState::ImmutableValueLowering::lower(seq::InitialOp initialOp) { ModuleLoweringState::ImmutableValueLowering::lower(seq::InitialOp initialOp) {
OpBuilder builder = OpBuilder::atBlockBegin(module.getBodyBlock()); OpBuilder builder = OpBuilder::atBlockBegin(module.getBodyBlock());
if (!svInitialOp) if (!svInitialOp)
svInitialOp = builder.create<sv::InitialOp>(initialOp->getLoc()); svInitialOp = sv::InitialOp::create(builder, initialOp->getLoc());
// Initial ops are merged to single one and must not have operands. // Initial ops are merged to single one and must not have operands.
assert(initialOp.getNumOperands() == 0 && assert(initialOp.getNumOperands() == 0 &&
"initial op should have no operands"); "initial op should have no operands");
@ -115,9 +115,8 @@ ModuleLoweringState::ImmutableValueLowering::lower(seq::InitialOp initialOp) {
for (auto [result, operand] : for (auto [result, operand] :
llvm::zip(initialOp.getResults(), yieldOp->getOperands())) { llvm::zip(initialOp.getResults(), yieldOp->getOperands())) {
auto placeholder = auto placeholder =
builder mlir::UnrealizedConversionCastOp::create(
.create<mlir::UnrealizedConversionCastOp>( builder, loc, ArrayRef<Type>{result.getType()}, ArrayRef<Value>{})
loc, ArrayRef<Type>{result.getType()}, ArrayRef<Value>{})
->getResult(0); ->getResult(0);
result.replaceAllUsesWith(placeholder); result.replaceAllUsesWith(placeholder);
mapping.insert( mapping.insert(
@ -154,20 +153,20 @@ public:
auto regTy = auto regTy =
ConversionPattern::getTypeConverter()->convertType(reg.getType()); ConversionPattern::getTypeConverter()->convertType(reg.getType());
auto svReg = rewriter.create<sv::RegOp>(loc, regTy, reg.getNameAttr(), auto svReg = sv::RegOp::create(rewriter, loc, regTy, reg.getNameAttr(),
reg.getInnerSymAttr()); reg.getInnerSymAttr());
svReg->setDialectAttrs(reg->getDialectAttrs()); svReg->setDialectAttrs(reg->getDialectAttrs());
circt::sv::setSVAttributes(svReg, circt::sv::getSVAttributes(reg)); circt::sv::setSVAttributes(svReg, circt::sv::getSVAttributes(reg));
auto regVal = rewriter.create<sv::ReadInOutOp>(loc, svReg); auto regVal = sv::ReadInOutOp::create(rewriter, loc, svReg);
auto assignValue = [&] { auto assignValue = [&] {
createAssign(rewriter, reg.getLoc(), svReg, reg); createAssign(rewriter, reg.getLoc(), svReg, reg);
}; };
auto assignReset = [&] { auto assignReset = [&] {
rewriter.create<sv::PAssignOp>(loc, svReg, adaptor.getResetValue()); sv::PAssignOp::create(rewriter, loc, svReg, adaptor.getResetValue());
}; };
// Registers written in an `always_ff` process may not have any assignments // Registers written in an `always_ff` process may not have any assignments
@ -177,24 +176,24 @@ public:
if (adaptor.getReset() && adaptor.getResetValue()) { if (adaptor.getReset() && adaptor.getResetValue()) {
if (mayLowerToAlwaysFF) { if (mayLowerToAlwaysFF) {
rewriter.create<sv::AlwaysFFOp>( sv::AlwaysFFOp::create(rewriter, loc, sv::EventControl::AtPosEdge,
loc, sv::EventControl::AtPosEdge, adaptor.getClk(), adaptor.getClk(), sv::ResetType::SyncReset,
sv::ResetType::SyncReset, sv::EventControl::AtPosEdge, sv::EventControl::AtPosEdge, adaptor.getReset(),
adaptor.getReset(), assignValue, assignReset); assignValue, assignReset);
} else { } else {
rewriter.create<sv::AlwaysOp>( sv::AlwaysOp::create(
loc, sv::EventControl::AtPosEdge, adaptor.getClk(), [&] { rewriter, loc, sv::EventControl::AtPosEdge, adaptor.getClk(), [&] {
rewriter.create<sv::IfOp>(loc, adaptor.getReset(), assignReset, sv::IfOp::create(rewriter, loc, adaptor.getReset(), assignReset,
assignValue); assignValue);
}); });
} }
} else { } else {
if (mayLowerToAlwaysFF) { if (mayLowerToAlwaysFF) {
rewriter.create<sv::AlwaysFFOp>(loc, sv::EventControl::AtPosEdge, sv::AlwaysFFOp::create(rewriter, loc, sv::EventControl::AtPosEdge,
adaptor.getClk(), assignValue); adaptor.getClk(), assignValue);
} else { } else {
rewriter.create<sv::AlwaysOp>(loc, sv::EventControl::AtPosEdge, sv::AlwaysOp::create(rewriter, loc, sv::EventControl::AtPosEdge,
adaptor.getClk(), assignValue); adaptor.getClk(), assignValue);
} }
} }
@ -216,7 +215,7 @@ public:
OpBuilder::InsertionGuard guard(rewriter); OpBuilder::InsertionGuard guard(rewriter);
auto in = initial.getSVInitial(); auto in = initial.getSVInitial();
rewriter.setInsertionPointToEnd(in.getBodyBlock()); rewriter.setInsertionPointToEnd(in.getBodyBlock());
rewriter.create<sv::BPAssignOp>(reg->getLoc(), svReg, initialValue); sv::BPAssignOp::create(rewriter, reg->getLoc(), svReg, initialValue);
} }
} }
@ -238,15 +237,15 @@ template <>
void CompRegLower<CompRegOp>::createAssign(ConversionPatternRewriter &rewriter, void CompRegLower<CompRegOp>::createAssign(ConversionPatternRewriter &rewriter,
Location loc, sv::RegOp svReg, Location loc, sv::RegOp svReg,
OpAdaptor reg) const { OpAdaptor reg) const {
rewriter.create<sv::PAssignOp>(loc, svReg, reg.getInput()); sv::PAssignOp::create(rewriter, loc, svReg, reg.getInput());
} }
/// Create the assign inside of an if block. /// Create the assign inside of an if block.
template <> template <>
void CompRegLower<CompRegClockEnabledOp>::createAssign( void CompRegLower<CompRegClockEnabledOp>::createAssign(
ConversionPatternRewriter &rewriter, Location loc, sv::RegOp svReg, ConversionPatternRewriter &rewriter, Location loc, sv::RegOp svReg,
OpAdaptor reg) const { OpAdaptor reg) const {
rewriter.create<sv::IfOp>(loc, reg.getClockEnable(), [&]() { sv::IfOp::create(rewriter, loc, reg.getClockEnable(), [&]() {
rewriter.create<sv::PAssignOp>(loc, svReg, reg.getInput()); sv::PAssignOp::create(rewriter, loc, svReg, reg.getInput());
}); });
} }
@ -268,9 +267,9 @@ public:
auto regTy = ConversionPattern::getTypeConverter()->convertType( auto regTy = ConversionPattern::getTypeConverter()->convertType(
fromImmutableOp.getType()); fromImmutableOp.getType());
auto svReg = rewriter.create<sv::RegOp>(loc, regTy); auto svReg = sv::RegOp::create(rewriter, loc, regTy);
auto regVal = rewriter.create<sv::ReadInOutOp>(loc, svReg); auto regVal = sv::ReadInOutOp::create(rewriter, loc, svReg);
// Lower initial values. // Lower initial values.
auto module = fromImmutableOp->template getParentOfType<hw::HWModuleOp>(); auto module = fromImmutableOp->template getParentOfType<hw::HWModuleOp>();
@ -283,8 +282,8 @@ public:
OpBuilder::InsertionGuard guard(rewriter); OpBuilder::InsertionGuard guard(rewriter);
auto in = initial.getSVInitial(); auto in = initial.getSVInitial();
rewriter.setInsertionPointToEnd(in.getBodyBlock()); rewriter.setInsertionPointToEnd(in.getBodyBlock());
rewriter.create<sv::BPAssignOp>(fromImmutableOp->getLoc(), svReg, sv::BPAssignOp::create(rewriter, fromImmutableOp->getLoc(), svReg,
initialValue); initialValue);
rewriter.replaceOp(fromImmutableOp, regVal); rewriter.replaceOp(fromImmutableOp, regVal);
return success(); return success();
@ -308,25 +307,26 @@ public:
// enable in // enable in
Value enable = adaptor.getEnable(); Value enable = adaptor.getEnable();
if (auto te = adaptor.getTestEnable()) if (auto te = adaptor.getTestEnable())
enable = rewriter.create<comb::OrOp>(loc, enable, te); enable = comb::OrOp::create(rewriter, loc, enable, te);
// Enable latch. // Enable latch.
Value enableLatch = rewriter.create<sv::RegOp>( Value enableLatch =
loc, rewriter.getI1Type(), rewriter.getStringAttr("cg_en_latch")); sv::RegOp::create(rewriter, loc, rewriter.getI1Type(),
rewriter.getStringAttr("cg_en_latch"));
// Latch the enable signal using an always @* block. // Latch the enable signal using an always @* block.
rewriter.create<sv::AlwaysOp>( sv::AlwaysOp::create(
loc, llvm::SmallVector<sv::EventControl>{}, llvm::SmallVector<Value>{}, rewriter, loc, llvm::SmallVector<sv::EventControl>{},
[&]() { llvm::SmallVector<Value>{}, [&]() {
rewriter.create<sv::IfOp>( sv::IfOp::create(
loc, comb::createOrFoldNot(loc, clk, rewriter), [&]() { rewriter, loc, comb::createOrFoldNot(loc, clk, rewriter), [&]() {
rewriter.create<sv::PAssignOp>(loc, enableLatch, enable); sv::PAssignOp::create(rewriter, loc, enableLatch, enable);
}); });
}); });
// Create the gated clock signal. // Create the gated clock signal.
rewriter.replaceOpWithNewOp<comb::AndOp>( rewriter.replaceOpWithNewOp<comb::AndOp>(
clockGate, clk, rewriter.create<sv::ReadInOutOp>(loc, enableLatch)); clockGate, clk, sv::ReadInOutOp::create(rewriter, loc, enableLatch));
return success(); return success();
} }
}; };
@ -344,7 +344,7 @@ public:
Value clk = adaptor.getInput(); Value clk = adaptor.getInput();
StringAttr name = op->getAttrOfType<StringAttr>("sv.namehint"); StringAttr name = op->getAttrOfType<StringAttr>("sv.namehint");
Value one = rewriter.create<hw::ConstantOp>(loc, APInt(1, 1)); Value one = hw::ConstantOp::create(rewriter, loc, APInt(1, 1));
auto newOp = rewriter.replaceOpWithNewOp<comb::XorOp>(op, clk, one); auto newOp = rewriter.replaceOpWithNewOp<comb::XorOp>(op, clk, one);
if (name) if (name)
rewriter.modifyOpInPlace(newOp, rewriter.modifyOpInPlace(newOp,
@ -408,8 +408,8 @@ struct SeqToSVTypeConverter : public TypeConverter {
mlir::Location loc) -> mlir::Value { mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return mlir::UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<mlir::UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
@ -418,8 +418,8 @@ struct SeqToSVTypeConverter : public TypeConverter {
mlir::Location loc) -> mlir::Value { mlir::Location loc) -> mlir::Value {
if (inputs.size() != 1) if (inputs.size() != 1)
return Value(); return Value();
return builder return mlir::UnrealizedConversionCastOp::create(builder, loc, resultType,
.create<mlir::UnrealizedConversionCastOp>(loc, resultType, inputs[0]) inputs[0])
->getResult(0); ->getResult(0);
}); });
} }
@ -498,33 +498,33 @@ public:
Value one; Value one;
if (clockDiv.getPow2()) { if (clockDiv.getPow2()) {
one = rewriter.create<hw::ConstantOp>(loc, APInt(1, 1)); one = hw::ConstantOp::create(rewriter, loc, APInt(1, 1));
} }
Value output = clockDiv.getInput(); Value output = clockDiv.getInput();
SmallVector<Value> regs; SmallVector<Value> regs;
for (unsigned i = 0; i < clockDiv.getPow2(); ++i) { for (unsigned i = 0; i < clockDiv.getPow2(); ++i) {
Value reg = rewriter.create<sv::RegOp>( Value reg = sv::RegOp::create(
loc, rewriter.getI1Type(), rewriter, loc, rewriter.getI1Type(),
rewriter.getStringAttr("clock_out_" + std::to_string(i))); rewriter.getStringAttr("clock_out_" + std::to_string(i)));
regs.push_back(reg); regs.push_back(reg);
rewriter.create<sv::AlwaysOp>( sv::AlwaysOp::create(
loc, sv::EventControl::AtPosEdge, output, [&] { rewriter, loc, sv::EventControl::AtPosEdge, output, [&] {
Value outputVal = rewriter.create<sv::ReadInOutOp>(loc, reg); Value outputVal = sv::ReadInOutOp::create(rewriter, loc, reg);
Value inverted = rewriter.create<comb::XorOp>(loc, outputVal, one); Value inverted = comb::XorOp::create(rewriter, loc, outputVal, one);
rewriter.create<sv::BPAssignOp>(loc, reg, inverted); sv::BPAssignOp::create(rewriter, loc, reg, inverted);
}); });
output = rewriter.create<sv::ReadInOutOp>(loc, reg); output = sv::ReadInOutOp::create(rewriter, loc, reg);
} }
if (!regs.empty()) { if (!regs.empty()) {
Value zero = rewriter.create<hw::ConstantOp>(loc, APInt(1, 0)); Value zero = hw::ConstantOp::create(rewriter, loc, APInt(1, 0));
rewriter.create<sv::InitialOp>(loc, [&] { sv::InitialOp::create(rewriter, loc, [&] {
for (Value reg : regs) { for (Value reg : regs) {
rewriter.create<sv::BPAssignOp>(loc, reg, zero); sv::BPAssignOp::create(rewriter, loc, reg, zero);
} }
}); });
} }
@ -719,20 +719,20 @@ void SeqToSVPass::runOnOperation() {
auto loc = UnknownLoc::get(context); auto loc = UnknownLoc::get(context);
auto b = ImplicitLocOpBuilder::atBlockBegin(loc, circuit.getBody()); auto b = ImplicitLocOpBuilder::atBlockBegin(loc, circuit.getBody());
if (needsRegRandomization || needsMemRandomization) { if (needsRegRandomization || needsMemRandomization) {
b.create<sv::MacroDeclOp>("ENABLE_INITIAL_REG_"); sv::MacroDeclOp::create(b, "ENABLE_INITIAL_REG_");
b.create<sv::MacroDeclOp>("ENABLE_INITIAL_MEM_"); sv::MacroDeclOp::create(b, "ENABLE_INITIAL_MEM_");
if (needsRegRandomization) { if (needsRegRandomization) {
b.create<sv::MacroDeclOp>("FIRRTL_BEFORE_INITIAL"); sv::MacroDeclOp::create(b, "FIRRTL_BEFORE_INITIAL");
b.create<sv::MacroDeclOp>("FIRRTL_AFTER_INITIAL"); sv::MacroDeclOp::create(b, "FIRRTL_AFTER_INITIAL");
} }
if (needsMemRandomization) if (needsMemRandomization)
b.create<sv::MacroDeclOp>("RANDOMIZE_MEM_INIT"); sv::MacroDeclOp::create(b, "RANDOMIZE_MEM_INIT");
b.create<sv::MacroDeclOp>("RANDOMIZE_REG_INIT"); sv::MacroDeclOp::create(b, "RANDOMIZE_REG_INIT");
b.create<sv::MacroDeclOp>("RANDOMIZE"); sv::MacroDeclOp::create(b, "RANDOMIZE");
b.create<sv::MacroDeclOp>("RANDOMIZE_DELAY"); sv::MacroDeclOp::create(b, "RANDOMIZE_DELAY");
b.create<sv::MacroDeclOp>("RANDOM"); sv::MacroDeclOp::create(b, "RANDOM");
b.create<sv::MacroDeclOp>("INIT_RANDOM"); sv::MacroDeclOp::create(b, "INIT_RANDOM");
b.create<sv::MacroDeclOp>("INIT_RANDOM_PROLOG_"); sv::MacroDeclOp::create(b, "INIT_RANDOM_PROLOG_");
} }
bool hasRegRandomization = needsRegRandomization && !disableRegRandomization; bool hasRegRandomization = needsRegRandomization && !disableRegRandomization;
@ -755,9 +755,9 @@ void SeqToSVPass::runOnOperation() {
for (auto sym : circuit.getOps<sv::MacroDeclOp>()) for (auto sym : circuit.getOps<sv::MacroDeclOp>())
symbols.insert(sym.getName()); symbols.insert(sym.getName());
if (!symbols.count("SYNTHESIS")) if (!symbols.count("SYNTHESIS"))
b.create<sv::MacroDeclOp>("SYNTHESIS"); sv::MacroDeclOp::create(b, "SYNTHESIS");
if (!symbols.count("VERILATOR")) if (!symbols.count("VERILATOR"))
b.create<sv::MacroDeclOp>("VERILATOR"); sv::MacroDeclOp::create(b, "VERILATOR");
} }
// TODO: We could have an operation for macros and uses of them, and // TODO: We could have an operation for macros and uses of them, and
@ -767,66 +767,66 @@ void SeqToSVPass::runOnOperation() {
StringRef defineFalse = StringRef()) { StringRef defineFalse = StringRef()) {
if (!defineFalse.data()) { if (!defineFalse.data()) {
assert(defineTrue.data() && "didn't define anything"); assert(defineTrue.data() && "didn't define anything");
b.create<sv::IfDefOp>( sv::IfDefOp::create(
guard, [&]() { b.create<sv::MacroDefOp>(defName, defineTrue); }); b, guard, [&]() { sv::MacroDefOp::create(b, defName, defineTrue); });
} else { } else {
b.create<sv::IfDefOp>( sv::IfDefOp::create(
guard, b, guard,
[&]() { [&]() {
if (defineTrue.data()) if (defineTrue.data())
b.create<sv::MacroDefOp>(defName, defineTrue); sv::MacroDefOp::create(b, defName, defineTrue);
}, },
[&]() { b.create<sv::MacroDefOp>(defName, defineFalse); }); [&]() { sv::MacroDefOp::create(b, defName, defineFalse); });
} }
}; };
// Helper function to emit #ifndef guard. // Helper function to emit #ifndef guard.
auto emitGuard = [&](const char *guard, llvm::function_ref<void(void)> body) { auto emitGuard = [&](const char *guard, llvm::function_ref<void(void)> body) {
b.create<sv::IfDefOp>( sv::IfDefOp::create(
guard, []() {}, body); b, guard, []() {}, body);
}; };
b.create<emit::FragmentOp>(randomInitFragmentName.getAttr(), [&] { emit::FragmentOp::create(b, randomInitFragmentName.getAttr(), [&] {
b.create<sv::VerbatimOp>( sv::VerbatimOp::create(b,
"// Standard header to adapt well known macros for " "// Standard header to adapt well known macros for "
"register randomization."); "register randomization.");
b.create<sv::VerbatimOp>( sv::VerbatimOp::create(
"\n// RANDOM may be set to an expression that produces a 32-bit " b, "\n// RANDOM may be set to an expression that produces a 32-bit "
"random unsigned value."); "random unsigned value.");
emitGuardedDefine("RANDOM", "RANDOM", StringRef(), "$random"); emitGuardedDefine("RANDOM", "RANDOM", StringRef(), "$random");
b.create<sv::VerbatimOp>( sv::VerbatimOp::create(
"\n// Users can define INIT_RANDOM as general code that gets " b, "\n// Users can define INIT_RANDOM as general code that gets "
"injected " "injected "
"into the\n// initializer block for modules with registers."); "into the\n// initializer block for modules with registers.");
emitGuardedDefine("INIT_RANDOM", "INIT_RANDOM", StringRef(), ""); emitGuardedDefine("INIT_RANDOM", "INIT_RANDOM", StringRef(), "");
b.create<sv::VerbatimOp>( sv::VerbatimOp::create(
"\n// If using random initialization, you can also define " b, "\n// If using random initialization, you can also define "
"RANDOMIZE_DELAY to\n// customize the delay used, otherwise 0.002 " "RANDOMIZE_DELAY to\n// customize the delay used, otherwise 0.002 "
"is used."); "is used.");
emitGuardedDefine("RANDOMIZE_DELAY", "RANDOMIZE_DELAY", StringRef(), emitGuardedDefine("RANDOMIZE_DELAY", "RANDOMIZE_DELAY", StringRef(),
"0.002"); "0.002");
b.create<sv::VerbatimOp>( sv::VerbatimOp::create(
"\n// Define INIT_RANDOM_PROLOG_ for use in our modules below."); b, "\n// Define INIT_RANDOM_PROLOG_ for use in our modules below.");
emitGuard("INIT_RANDOM_PROLOG_", [&]() { emitGuard("INIT_RANDOM_PROLOG_", [&]() {
b.create<sv::IfDefOp>( sv::IfDefOp::create(
"RANDOMIZE", b, "RANDOMIZE",
[&]() { [&]() {
emitGuardedDefine("VERILATOR", "INIT_RANDOM_PROLOG_", emitGuardedDefine("VERILATOR", "INIT_RANDOM_PROLOG_",
"`INIT_RANDOM", "`INIT_RANDOM",
"`INIT_RANDOM #`RANDOMIZE_DELAY begin end"); "`INIT_RANDOM #`RANDOMIZE_DELAY begin end");
}, },
[&]() { b.create<sv::MacroDefOp>("INIT_RANDOM_PROLOG_", ""); }); [&]() { sv::MacroDefOp::create(b, "INIT_RANDOM_PROLOG_", ""); });
}); });
}); });
if (hasMemRandomization) { if (hasMemRandomization) {
b.create<emit::FragmentOp>(randomInitMemFragmentName.getAttr(), [&] { emit::FragmentOp::create(b, randomInitMemFragmentName.getAttr(), [&] {
b.create<sv::VerbatimOp>("\n// Include rmemory initializers in init " sv::VerbatimOp::create(b, "\n// Include rmemory initializers in init "
"blocks unless synthesis is set"); "blocks unless synthesis is set");
emitGuard("RANDOMIZE", [&]() { emitGuard("RANDOMIZE", [&]() {
emitGuardedDefine("RANDOMIZE_MEM_INIT", "RANDOMIZE"); emitGuardedDefine("RANDOMIZE_MEM_INIT", "RANDOMIZE");
}); });
@ -834,14 +834,14 @@ void SeqToSVPass::runOnOperation() {
emitGuardedDefine("ENABLE_INITIAL_MEM_", "ENABLE_INITIAL_MEM_", emitGuardedDefine("ENABLE_INITIAL_MEM_", "ENABLE_INITIAL_MEM_",
StringRef(), ""); StringRef(), "");
}); });
b.create<sv::VerbatimOp>(""); sv::VerbatimOp::create(b, "");
}); });
} }
if (hasRegRandomization) { if (hasRegRandomization) {
b.create<emit::FragmentOp>(randomInitRegFragmentName.getAttr(), [&] { emit::FragmentOp::create(b, randomInitRegFragmentName.getAttr(), [&] {
b.create<sv::VerbatimOp>("\n// Include register initializers in init " sv::VerbatimOp::create(b, "\n// Include register initializers in init "
"blocks unless synthesis is set"); "blocks unless synthesis is set");
emitGuard("RANDOMIZE", [&]() { emitGuard("RANDOMIZE", [&]() {
emitGuardedDefine("RANDOMIZE_REG_INIT", "RANDOMIZE"); emitGuardedDefine("RANDOMIZE_REG_INIT", "RANDOMIZE");
}); });
@ -849,7 +849,7 @@ void SeqToSVPass::runOnOperation() {
emitGuardedDefine("ENABLE_INITIAL_REG_", "ENABLE_INITIAL_REG_", emitGuardedDefine("ENABLE_INITIAL_REG_", "ENABLE_INITIAL_REG_",
StringRef(), ""); StringRef(), "");
}); });
b.create<sv::VerbatimOp>(""); sv::VerbatimOp::create(b, "");
}); });
} }
} }

View File

@ -65,13 +65,13 @@ public:
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
auto loc = op.getLoc(); auto loc = op.getLoc();
auto resultType = rewriter.getIntegerType(1); auto resultType = rewriter.getIntegerType(1);
auto str = rewriter.create<sv::ConstantStrOp>(loc, op.getFormatString()); auto str = sv::ConstantStrOp::create(rewriter, loc, op.getFormatString());
auto reg = rewriter.create<sv::RegOp>(loc, resultType, auto reg = sv::RegOp::create(rewriter, loc, resultType,
rewriter.getStringAttr("_pargs")); rewriter.getStringAttr("_pargs"));
rewriter.create<sv::InitialOp>(loc, [&] { sv::InitialOp::create(rewriter, loc, [&] {
auto call = rewriter.create<sv::SystemFunctionOp>( auto call = sv::SystemFunctionOp::create(
loc, resultType, "test$plusargs", ArrayRef<Value>{str}); rewriter, loc, resultType, "test$plusargs", ArrayRef<Value>{str});
rewriter.create<sv::BPAssignOp>(loc, reg, call); sv::BPAssignOp::create(rewriter, loc, reg, call);
}); });
rewriter.replaceOpWithNewOp<sv::ReadInOutOp>(op, reg); rewriter.replaceOpWithNewOp<sv::ReadInOutOp>(op, reg);
@ -93,18 +93,18 @@ public:
auto i1ty = rewriter.getIntegerType(1); auto i1ty = rewriter.getIntegerType(1);
auto type = op.getResult().getType(); auto type = op.getResult().getType();
auto wirev = rewriter.create<sv::WireOp>( auto wirev = sv::WireOp::create(rewriter, loc, type,
loc, type, rewriter.getStringAttr("_pargs_v")); rewriter.getStringAttr("_pargs_v"));
auto wiref = rewriter.create<sv::WireOp>( auto wiref = sv::WireOp::create(rewriter, loc, i1ty,
loc, i1ty, rewriter.getStringAttr("_pargs_f")); rewriter.getStringAttr("_pargs_f"));
state.usedSynthesisMacro = true; state.usedSynthesisMacro = true;
rewriter.create<sv::IfDefOp>( sv::IfDefOp::create(
loc, "SYNTHESIS", rewriter, loc, "SYNTHESIS",
[&]() { [&]() {
auto cstFalse = rewriter.create<hw::ConstantOp>(loc, APInt(1, 0)); auto cstFalse = hw::ConstantOp::create(rewriter, loc, APInt(1, 0));
auto cstZ = rewriter.create<sv::ConstantZOp>(loc, type); auto cstZ = sv::ConstantZOp::create(rewriter, loc, type);
auto assignZ = rewriter.create<sv::AssignOp>(loc, wirev, cstZ); auto assignZ = sv::AssignOp::create(rewriter, loc, wirev, cstZ);
circt::sv::setSVAttributes( circt::sv::setSVAttributes(
assignZ, assignZ,
sv::SVAttributeAttr::get( sv::SVAttributeAttr::get(
@ -112,33 +112,34 @@ public:
"This dummy assignment exists to avoid undriven lint " "This dummy assignment exists to avoid undriven lint "
"warnings (e.g., Verilator UNDRIVEN).", "warnings (e.g., Verilator UNDRIVEN).",
/*emitAsComment=*/true)); /*emitAsComment=*/true));
rewriter.create<sv::AssignOp>(loc, wiref, cstFalse); sv::AssignOp::create(rewriter, loc, wiref, cstFalse);
}, },
[&]() { [&]() {
auto i32ty = rewriter.getIntegerType(32); auto i32ty = rewriter.getIntegerType(32);
auto regf = rewriter.create<sv::RegOp>( auto regf = sv::RegOp::create(rewriter, loc, i32ty,
loc, i32ty, rewriter.getStringAttr("_found")); rewriter.getStringAttr("_found"));
auto regv = rewriter.create<sv::RegOp>( auto regv = sv::RegOp::create(rewriter, loc, type,
loc, type, rewriter.getStringAttr("_value")); rewriter.getStringAttr("_value"));
rewriter.create<sv::InitialOp>(loc, [&] { sv::InitialOp::create(rewriter, loc, [&] {
auto str = auto str =
rewriter.create<sv::ConstantStrOp>(loc, op.getFormatString()); sv::ConstantStrOp::create(rewriter, loc, op.getFormatString());
auto call = rewriter.create<sv::SystemFunctionOp>( auto call = sv::SystemFunctionOp::create(
loc, i32ty, "value$plusargs", ArrayRef<Value>{str, regv}); rewriter, loc, i32ty, "value$plusargs",
rewriter.create<sv::BPAssignOp>(loc, regf, call); ArrayRef<Value>{str, regv});
sv::BPAssignOp::create(rewriter, loc, regf, call);
}); });
Value readRegF = rewriter.create<sv::ReadInOutOp>(loc, regf); Value readRegF = sv::ReadInOutOp::create(rewriter, loc, regf);
Value readRegV = rewriter.create<sv::ReadInOutOp>(loc, regv); Value readRegV = sv::ReadInOutOp::create(rewriter, loc, regv);
auto cstTrue = rewriter.create<hw::ConstantOp>(loc, i32ty, 1); auto cstTrue = hw::ConstantOp::create(rewriter, loc, i32ty, 1);
// Squash any X coming from the regf to 0. // Squash any X coming from the regf to 0.
auto cmp = rewriter.create<comb::ICmpOp>( auto cmp = comb::ICmpOp::create(
loc, comb::ICmpPredicate::ceq, readRegF, cstTrue); rewriter, loc, comb::ICmpPredicate::ceq, readRegF, cstTrue);
rewriter.create<sv::AssignOp>(loc, wiref, cmp); sv::AssignOp::create(rewriter, loc, wiref, cmp);
rewriter.create<sv::AssignOp>(loc, wirev, readRegV); sv::AssignOp::create(rewriter, loc, wirev, readRegV);
}); });
Value readf = rewriter.create<sv::ReadInOutOp>(loc, wiref); Value readf = sv::ReadInOutOp::create(rewriter, loc, wiref);
Value readv = rewriter.create<sv::ReadInOutOp>(loc, wirev); Value readv = sv::ReadInOutOp::create(rewriter, loc, wirev);
rewriter.replaceOp(op, {readf, readv}); rewriter.replaceOp(op, {readf, readv});
return success(); return success();
@ -155,16 +156,16 @@ public:
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
auto loc = op.getLoc(); auto loc = op.getLoc();
Value clockCast = rewriter.create<seq::FromClockOp>(loc, adaptor.getClk()); Value clockCast = seq::FromClockOp::create(rewriter, loc, adaptor.getClk());
this->state.usedSynthesisMacro = true; this->state.usedSynthesisMacro = true;
rewriter.create<sv::IfDefOp>( sv::IfDefOp::create(
loc, "SYNTHESIS", [&] {}, rewriter, loc, "SYNTHESIS", [&] {},
[&] { [&] {
rewriter.create<sv::AlwaysOp>( sv::AlwaysOp::create(
loc, sv::EventControl::AtPosEdge, clockCast, [&] { rewriter, loc, sv::EventControl::AtPosEdge, clockCast, [&] {
rewriter.create<sv::IfOp>(loc, adaptor.getCond(), sv::IfOp::create(rewriter, loc, adaptor.getCond(),
[&] { rewriter.create<ToOp>(loc); }); [&] { ToOp::create(rewriter, loc); });
}); });
}); });
@ -192,49 +193,50 @@ public:
SmallVector<Value> reads; SmallVector<Value> reads;
for (auto [type, result] : for (auto [type, result] :
llvm::zip(op.getResultTypes(), op.getResults())) { llvm::zip(op.getResultTypes(), op.getResults())) {
temporaries.push_back(rewriter.create<sv::RegOp>(op.getLoc(), type)); temporaries.push_back(sv::RegOp::create(rewriter, op.getLoc(), type));
reads.push_back( reads.push_back(
rewriter.create<sv::ReadInOutOp>(op.getLoc(), temporaries.back())); sv::ReadInOutOp::create(rewriter, op.getLoc(), temporaries.back()));
} }
auto emitCall = [&]() { auto emitCall = [&]() {
auto call = rewriter.create<sv::FuncCallProceduralOp>( auto call = sv::FuncCallProceduralOp::create(
op.getLoc(), op.getResultTypes(), op.getCalleeAttr(), rewriter, op.getLoc(), op.getResultTypes(), op.getCalleeAttr(),
adaptor.getInputs()); adaptor.getInputs());
for (auto [lhs, rhs] : llvm::zip(temporaries, call.getResults())) { for (auto [lhs, rhs] : llvm::zip(temporaries, call.getResults())) {
if (isClockedCall) if (isClockedCall)
rewriter.create<sv::PAssignOp>(op.getLoc(), lhs, rhs); sv::PAssignOp::create(rewriter, op.getLoc(), lhs, rhs);
else else
rewriter.create<sv::BPAssignOp>(op.getLoc(), lhs, rhs); sv::BPAssignOp::create(rewriter, op.getLoc(), lhs, rhs);
} }
}; };
if (isClockedCall) { if (isClockedCall) {
Value clockCast = Value clockCast =
rewriter.create<seq::FromClockOp>(loc, adaptor.getClock()); seq::FromClockOp::create(rewriter, loc, adaptor.getClock());
rewriter.create<sv::AlwaysOp>( sv::AlwaysOp::create(
loc, ArrayRef<sv::EventControl>{sv::EventControl::AtPosEdge}, rewriter, loc,
ArrayRef<sv::EventControl>{sv::EventControl::AtPosEdge},
ArrayRef<Value>{clockCast}, [&]() { ArrayRef<Value>{clockCast}, [&]() {
if (!hasEnable) if (!hasEnable)
return emitCall(); return emitCall();
rewriter.create<sv::IfOp>(op.getLoc(), adaptor.getEnable(), sv::IfOp::create(rewriter, op.getLoc(), adaptor.getEnable(),
emitCall); emitCall);
}); });
} else { } else {
// Unclocked call is lowered into always_comb. // Unclocked call is lowered into always_comb.
// TODO: If there is a return value and no output argument, use an // TODO: If there is a return value and no output argument, use an
// unclocked call op. // unclocked call op.
rewriter.create<sv::AlwaysCombOp>(loc, [&]() { sv::AlwaysCombOp::create(rewriter, loc, [&]() {
if (!hasEnable) if (!hasEnable)
return emitCall(); return emitCall();
auto assignXToResults = [&] { auto assignXToResults = [&] {
for (auto lhs : temporaries) { for (auto lhs : temporaries) {
auto xValue = rewriter.create<sv::ConstantXOp>( auto xValue = sv::ConstantXOp::create(
op.getLoc(), lhs.getType().getElementType()); rewriter, op.getLoc(), lhs.getType().getElementType());
rewriter.create<sv::BPAssignOp>(op.getLoc(), lhs, xValue); sv::BPAssignOp::create(rewriter, op.getLoc(), lhs, xValue);
} }
}; };
rewriter.create<sv::IfOp>(op.getLoc(), adaptor.getEnable(), emitCall, sv::IfOp::create(rewriter, op.getLoc(), adaptor.getEnable(), emitCall,
assignXToResults); assignXToResults);
}); });
} }
@ -269,24 +271,25 @@ void LowerDPIFunc::lower(sim::DPIFuncOp func) {
} }
auto svFuncDecl = auto svFuncDecl =
builder.create<sv::FuncOp>(func.getSymNameAttr(), func.getModuleType(), sv::FuncOp::create(builder, func.getSymNameAttr(), func.getModuleType(),
func.getPerArgumentAttrsAttr(), inputLocsAttr, func.getPerArgumentAttrsAttr(), inputLocsAttr,
outputLocsAttr, func.getVerilogNameAttr()); outputLocsAttr, func.getVerilogNameAttr());
// DPI function is a declaration so it must be a private function. // DPI function is a declaration so it must be a private function.
svFuncDecl.setPrivate(); svFuncDecl.setPrivate();
auto name = builder.getStringAttr(nameSpace.newName( auto name = builder.getStringAttr(nameSpace.newName(
func.getSymNameAttr().getValue(), "dpi_import_fragument")); func.getSymNameAttr().getValue(), "dpi_import_fragument"));
// Add include guards to avoid duplicate declarations. See Issue 7458. // Add include guards to avoid duplicate declarations. See Issue 7458.
auto macroDecl = builder.create<sv::MacroDeclOp>(nameSpace.newName( auto macroDecl = sv::MacroDeclOp::create(
"__CIRCT_DPI_IMPORT", func.getSymNameAttr().getValue().upper())); builder, nameSpace.newName("__CIRCT_DPI_IMPORT",
builder.create<emit::FragmentOp>(name, [&]() { func.getSymNameAttr().getValue().upper()));
builder.create<sv::IfDefOp>( emit::FragmentOp::create(builder, name, [&]() {
macroDecl.getSymNameAttr(), []() {}, sv::IfDefOp::create(
builder, macroDecl.getSymNameAttr(), []() {},
[&]() { [&]() {
builder.create<sv::FuncDPIImportOp>(func.getSymNameAttr(), sv::FuncDPIImportOp::create(builder, func.getSymNameAttr(),
StringAttr()); StringAttr());
builder.create<sv::MacroDefOp>(macroDecl.getSymNameAttr(), ""); sv::MacroDefOp::create(builder, macroDecl.getSymNameAttr(), "");
}); });
}); });
@ -369,7 +372,7 @@ struct SimToSVPass : public circt::impl::LowerSimToSVBase<SimToSVPass> {
} else { } else {
auto builder = ImplicitLocOpBuilder::atBlockBegin( auto builder = ImplicitLocOpBuilder::atBlockBegin(
UnknownLoc::get(context), circuit.getBody()); UnknownLoc::get(context), circuit.getBody());
builder.create<sv::MacroDeclOp>("SYNTHESIS"); sv::MacroDeclOp::create(builder, "SYNTHESIS");
} }
} }
} }

View File

@ -47,7 +47,7 @@ struct VerifAssertOpConversion : OpConversionPattern<verif::AssertOp> {
Value cond = typeConverter->materializeTargetConversion( Value cond = typeConverter->materializeTargetConversion(
rewriter, op.getLoc(), smt::BoolType::get(getContext()), rewriter, op.getLoc(), smt::BoolType::get(getContext()),
adaptor.getProperty()); adaptor.getProperty());
Value notCond = rewriter.create<smt::NotOp>(op.getLoc(), cond); Value notCond = smt::NotOp::create(rewriter, op.getLoc(), cond);
rewriter.replaceOpWithNewOp<smt::AssertOp>(op, notCond); rewriter.replaceOpWithNewOp<smt::AssertOp>(op, notCond);
return success(); return success();
} }
@ -89,7 +89,7 @@ protected:
Value o2 = typeConverter->materializeTargetConversion( Value o2 = typeConverter->materializeTargetConversion(
rewriter, loc, typeConverter->convertType(out1.getType()), out2); rewriter, loc, typeConverter->convertType(out1.getType()), out2);
outputsDifferent.emplace_back( outputsDifferent.emplace_back(
rewriter.create<smt::DistinctOp>(loc, o1, o2)); smt::DistinctOp::create(rewriter, loc, o1, o2));
} }
} }
@ -101,32 +101,32 @@ protected:
// the result type of the operation and yield the result of the check // the result type of the operation and yield the result of the check
// operation. // operation.
if (op.getNumResults() == 0) { if (op.getNumResults() == 0) {
auto checkOp = rewriter.create<smt::CheckOp>(loc, TypeRange{}); auto checkOp = smt::CheckOp::create(rewriter, loc, TypeRange{});
rewriter.createBlock(&checkOp.getSatRegion()); rewriter.createBlock(&checkOp.getSatRegion());
rewriter.create<smt::YieldOp>(loc); smt::YieldOp::create(rewriter, loc);
rewriter.createBlock(&checkOp.getUnknownRegion()); rewriter.createBlock(&checkOp.getUnknownRegion());
rewriter.create<smt::YieldOp>(loc); smt::YieldOp::create(rewriter, loc);
rewriter.createBlock(&checkOp.getUnsatRegion()); rewriter.createBlock(&checkOp.getUnsatRegion());
rewriter.create<smt::YieldOp>(loc); smt::YieldOp::create(rewriter, loc);
rewriter.setInsertionPointAfter(checkOp); rewriter.setInsertionPointAfter(checkOp);
rewriter.create<smt::YieldOp>(loc); smt::YieldOp::create(rewriter, loc);
// Erase as operation is replaced by an operator without a return value. // Erase as operation is replaced by an operator without a return value.
rewriter.eraseOp(op); rewriter.eraseOp(op);
} else { } else {
Value falseVal = Value falseVal =
rewriter.create<arith::ConstantOp>(loc, rewriter.getBoolAttr(false)); arith::ConstantOp::create(rewriter, loc, rewriter.getBoolAttr(false));
Value trueVal = Value trueVal =
rewriter.create<arith::ConstantOp>(loc, rewriter.getBoolAttr(true)); arith::ConstantOp::create(rewriter, loc, rewriter.getBoolAttr(true));
auto checkOp = rewriter.create<smt::CheckOp>(loc, rewriter.getI1Type()); auto checkOp = smt::CheckOp::create(rewriter, loc, rewriter.getI1Type());
rewriter.createBlock(&checkOp.getSatRegion()); rewriter.createBlock(&checkOp.getSatRegion());
rewriter.create<smt::YieldOp>(loc, falseVal); smt::YieldOp::create(rewriter, loc, falseVal);
rewriter.createBlock(&checkOp.getUnknownRegion()); rewriter.createBlock(&checkOp.getUnknownRegion());
rewriter.create<smt::YieldOp>(loc, falseVal); smt::YieldOp::create(rewriter, loc, falseVal);
rewriter.createBlock(&checkOp.getUnsatRegion()); rewriter.createBlock(&checkOp.getUnsatRegion());
rewriter.create<smt::YieldOp>(loc, trueVal); smt::YieldOp::create(rewriter, loc, trueVal);
rewriter.setInsertionPointAfter(checkOp); rewriter.setInsertionPointAfter(checkOp);
rewriter.create<smt::YieldOp>(loc, checkOp->getResults()); smt::YieldOp::create(rewriter, loc, checkOp->getResults());
rewriter.replaceOp(op, solver->getResults()); rewriter.replaceOp(op, solver->getResults());
} }
@ -157,8 +157,8 @@ struct LogicEquivalenceCheckingOpConversion
if (hasNoResult) { if (hasNoResult) {
rewriter.eraseOp(op); rewriter.eraseOp(op);
} else { } else {
Value trueVal = Value trueVal = arith::ConstantOp::create(rewriter, loc,
rewriter.create<arith::ConstantOp>(loc, rewriter.getBoolAttr(true)); rewriter.getBoolAttr(true));
rewriter.replaceOp(op, trueVal); rewriter.replaceOp(op, trueVal);
} }
return success(); return success();
@ -168,10 +168,10 @@ struct LogicEquivalenceCheckingOpConversion
// value. // value.
smt::SolverOp solver; smt::SolverOp solver;
if (hasNoResult) if (hasNoResult)
solver = rewriter.create<smt::SolverOp>(loc, TypeRange{}, ValueRange{}); solver = smt::SolverOp::create(rewriter, loc, TypeRange{}, ValueRange{});
else else
solver = rewriter.create<smt::SolverOp>(loc, rewriter.getI1Type(), solver = smt::SolverOp::create(rewriter, loc, rewriter.getI1Type(),
ValueRange{}); ValueRange{});
rewriter.createBlock(&solver.getBodyRegion()); rewriter.createBlock(&solver.getBodyRegion());
// First, convert the block arguments of the miter bodies. // First, convert the block arguments of the miter bodies.
@ -185,7 +185,7 @@ struct LogicEquivalenceCheckingOpConversion
// Second, create the symbolic values we replace the block arguments with // Second, create the symbolic values we replace the block arguments with
SmallVector<Value> inputs; SmallVector<Value> inputs;
for (auto arg : adaptor.getFirstCircuit().getArguments()) for (auto arg : adaptor.getFirstCircuit().getArguments())
inputs.push_back(rewriter.create<smt::DeclareFunOp>(loc, arg.getType())); inputs.push_back(smt::DeclareFunOp::create(rewriter, loc, arg.getType()));
// Third, inline the blocks // Third, inline the blocks
// Note: the argument value replacement does not happen immediately, but // Note: the argument value replacement does not happen immediately, but
@ -212,9 +212,9 @@ struct LogicEquivalenceCheckingOpConversion
if (outputsDifferent.size() == 1) if (outputsDifferent.size() == 1)
toAssert = outputsDifferent[0]; toAssert = outputsDifferent[0];
else else
toAssert = rewriter.create<smt::OrOp>(loc, outputsDifferent); toAssert = smt::OrOp::create(rewriter, loc, outputsDifferent);
rewriter.create<smt::AssertOp>(loc, toAssert); smt::AssertOp::create(rewriter, loc, toAssert);
// Fifth, check for satisfiablility and report the result back. // Fifth, check for satisfiablility and report the result back.
replaceOpWithSatCheck(op, loc, rewriter, solver); replaceOpWithSatCheck(op, loc, rewriter, solver);
@ -251,8 +251,8 @@ struct RefinementCheckingOpConversion
// If there is no non-determinism in the source circuit, the // If there is no non-determinism in the source circuit, the
// refinement check becomes an equivalence check, which does not // refinement check becomes an equivalence check, which does not
// need quantified expressions. // need quantified expressions.
auto eqOp = rewriter.create<verif::LogicEquivalenceCheckingOp>( auto eqOp = verif::LogicEquivalenceCheckingOp::create(
op.getLoc(), op.getNumResults() != 0); rewriter, op.getLoc(), op.getNumResults() != 0);
rewriter.moveBlockBefore(&op.getFirstCircuit().front(), rewriter.moveBlockBefore(&op.getFirstCircuit().front(),
&eqOp.getFirstCircuit(), &eqOp.getFirstCircuit(),
eqOp.getFirstCircuit().end()); eqOp.getFirstCircuit().end());
@ -274,8 +274,8 @@ struct RefinementCheckingOpConversion
if (hasNoResult) { if (hasNoResult) {
rewriter.eraseOp(op); rewriter.eraseOp(op);
} else { } else {
Value trueVal = Value trueVal = arith::ConstantOp::create(rewriter, loc,
rewriter.create<arith::ConstantOp>(loc, rewriter.getBoolAttr(true)); rewriter.getBoolAttr(true));
rewriter.replaceOp(op, trueVal); rewriter.replaceOp(op, trueVal);
} }
return success(); return success();
@ -285,10 +285,10 @@ struct RefinementCheckingOpConversion
// value. // value.
smt::SolverOp solver; smt::SolverOp solver;
if (hasNoResult) if (hasNoResult)
solver = rewriter.create<smt::SolverOp>(loc, TypeRange{}, ValueRange{}); solver = smt::SolverOp::create(rewriter, loc, TypeRange{}, ValueRange{});
else else
solver = rewriter.create<smt::SolverOp>(loc, rewriter.getI1Type(), solver = smt::SolverOp::create(rewriter, loc, rewriter.getI1Type(),
ValueRange{}); ValueRange{});
rewriter.createBlock(&solver.getBodyRegion()); rewriter.createBlock(&solver.getBodyRegion());
// Convert the block arguments of the miter bodies. // Convert the block arguments of the miter bodies.
@ -302,7 +302,7 @@ struct RefinementCheckingOpConversion
// Create the symbolic values we replace the block arguments with // Create the symbolic values we replace the block arguments with
SmallVector<Value> inputs; SmallVector<Value> inputs;
for (auto arg : adaptor.getFirstCircuit().getArguments()) for (auto arg : adaptor.getFirstCircuit().getArguments())
inputs.push_back(rewriter.create<smt::DeclareFunOp>(loc, arg.getType())); inputs.push_back(smt::DeclareFunOp::create(rewriter, loc, arg.getType()));
// Inline the target circuit. Free variables remain free variables. // Inline the target circuit. Free variables remain free variables.
rewriter.mergeBlocks(&adaptor.getSecondCircuit().front(), solver.getBody(), rewriter.mergeBlocks(&adaptor.getSecondCircuit().front(), solver.getBody(),
@ -311,8 +311,8 @@ struct RefinementCheckingOpConversion
// Create the universally quantified expression containing the source // Create the universally quantified expression containing the source
// circuit. Free variables in the circuit's body become bound variables. // circuit. Free variables in the circuit's body become bound variables.
auto forallOp = rewriter.create<smt::ForallOp>( auto forallOp = smt::ForallOp::create(
op.getLoc(), TypeRange(srcNonDetValues), rewriter, op.getLoc(), TypeRange(srcNonDetValues),
[&](OpBuilder &builder, auto, ValueRange args) -> Value { [&](OpBuilder &builder, auto, ValueRange args) -> Value {
// Inline the source circuit // Inline the source circuit
Block *body = builder.getBlock(); Block *body = builder.getBlock();
@ -340,7 +340,7 @@ struct RefinementCheckingOpConversion
// Assert the quantified expression // Assert the quantified expression
rewriter.setInsertionPointAfter(forallOp); rewriter.setInsertionPointAfter(forallOp);
rewriter.create<smt::AssertOp>(op.getLoc(), forallOp.getResult()); smt::AssertOp::create(rewriter, op.getLoc(), forallOp.getResult());
// Check for satisfiability and report the result back. // Check for satisfiability and report the result back.
replaceOpWithSatCheck(op, loc, rewriter, solver); replaceOpWithSatCheck(op, loc, rewriter, solver);
@ -403,16 +403,16 @@ struct VerifBoundedModelCheckingOpConversion
OpBuilder::InsertionGuard guard(rewriter); OpBuilder::InsertionGuard guard(rewriter);
rewriter.setInsertionPointToEnd( rewriter.setInsertionPointToEnd(
op->getParentOfType<ModuleOp>().getBody()); op->getParentOfType<ModuleOp>().getBody());
initFuncOp = rewriter.create<func::FuncOp>(loc, names.newName("bmc_init"), initFuncOp = func::FuncOp::create(rewriter, loc,
initFuncTy); names.newName("bmc_init"), initFuncTy);
rewriter.inlineRegionBefore(op.getInit(), initFuncOp.getFunctionBody(), rewriter.inlineRegionBefore(op.getInit(), initFuncOp.getFunctionBody(),
initFuncOp.end()); initFuncOp.end());
loopFuncOp = rewriter.create<func::FuncOp>(loc, names.newName("bmc_loop"), loopFuncOp = func::FuncOp::create(rewriter, loc,
loopFuncTy); names.newName("bmc_loop"), loopFuncTy);
rewriter.inlineRegionBefore(op.getLoop(), loopFuncOp.getFunctionBody(), rewriter.inlineRegionBefore(op.getLoop(), loopFuncOp.getFunctionBody(),
loopFuncOp.end()); loopFuncOp.end());
circuitFuncOp = rewriter.create<func::FuncOp>( circuitFuncOp = func::FuncOp::create(
loc, names.newName("bmc_circuit"), circuitFuncTy); rewriter, loc, names.newName("bmc_circuit"), circuitFuncTy);
rewriter.inlineRegionBefore(op.getCircuit(), rewriter.inlineRegionBefore(op.getCircuit(),
circuitFuncOp.getFunctionBody(), circuitFuncOp.getFunctionBody(),
circuitFuncOp.end()); circuitFuncOp.end());
@ -427,20 +427,20 @@ struct VerifBoundedModelCheckingOpConversion
for (unsigned i = 0; i < outputTy.size(); ++i) for (unsigned i = 0; i < outputTy.size(); ++i)
toReturn.push_back(typeConverter->materializeTargetConversion( toReturn.push_back(typeConverter->materializeTargetConversion(
rewriter, loc, outputTy[i], operands[i])); rewriter, loc, outputTy[i], operands[i]));
rewriter.create<func::ReturnOp>(loc, toReturn); func::ReturnOp::create(rewriter, loc, toReturn);
} }
} }
auto solver = auto solver = smt::SolverOp::create(rewriter, loc, rewriter.getI1Type(),
rewriter.create<smt::SolverOp>(loc, rewriter.getI1Type(), ValueRange{}); ValueRange{});
rewriter.createBlock(&solver.getBodyRegion()); rewriter.createBlock(&solver.getBodyRegion());
// Call init func to get initial clock values // Call init func to get initial clock values
ValueRange initVals = ValueRange initVals =
rewriter.create<func::CallOp>(loc, initFuncOp)->getResults(); func::CallOp::create(rewriter, loc, initFuncOp)->getResults();
// Initial push // Initial push
rewriter.create<smt::PushOp>(loc, 1); smt::PushOp::create(rewriter, loc, 1);
// InputDecls order should be <circuit arguments> <state arguments> // InputDecls order should be <circuit arguments> <state arguments>
// <wasViolated> // <wasViolated>
@ -463,11 +463,12 @@ struct VerifBoundedModelCheckingOpConversion
assert(cstInt.getBitWidth() == assert(cstInt.getBitWidth() ==
cast<smt::BitVectorType>(newTy).getWidth() && cast<smt::BitVectorType>(newTy).getWidth() &&
"Width mismatch between initial value and target type"); "Width mismatch between initial value and target type");
inputDecls.push_back(rewriter.create<smt::BVConstantOp>(loc, cstInt)); inputDecls.push_back(
smt::BVConstantOp::create(rewriter, loc, cstInt));
continue; continue;
} }
} }
inputDecls.push_back(rewriter.create<smt::DeclareFunOp>(loc, newTy)); inputDecls.push_back(smt::DeclareFunOp::create(rewriter, loc, newTy));
} }
auto numStateArgs = initVals.size() - initIndex; auto numStateArgs = initVals.size() - initIndex;
@ -476,33 +477,32 @@ struct VerifBoundedModelCheckingOpConversion
inputDecls.push_back(initVals[initIndex]); inputDecls.push_back(initVals[initIndex]);
Value lowerBound = Value lowerBound =
rewriter.create<arith::ConstantOp>(loc, rewriter.getI32IntegerAttr(0)); arith::ConstantOp::create(rewriter, loc, rewriter.getI32IntegerAttr(0));
Value step = Value step =
rewriter.create<arith::ConstantOp>(loc, rewriter.getI32IntegerAttr(1)); arith::ConstantOp::create(rewriter, loc, rewriter.getI32IntegerAttr(1));
Value upperBound = Value upperBound =
rewriter.create<arith::ConstantOp>(loc, adaptor.getBoundAttr()); arith::ConstantOp::create(rewriter, loc, adaptor.getBoundAttr());
Value constFalse = Value constFalse =
rewriter.create<arith::ConstantOp>(loc, rewriter.getBoolAttr(false)); arith::ConstantOp::create(rewriter, loc, rewriter.getBoolAttr(false));
Value constTrue = Value constTrue =
rewriter.create<arith::ConstantOp>(loc, rewriter.getBoolAttr(true)); arith::ConstantOp::create(rewriter, loc, rewriter.getBoolAttr(true));
inputDecls.push_back(constFalse); // wasViolated? inputDecls.push_back(constFalse); // wasViolated?
// TODO: swapping to a whileOp here would allow early exit once the property // TODO: swapping to a whileOp here would allow early exit once the property
// is violated // is violated
// Perform model check up to the provided bound // Perform model check up to the provided bound
auto forOp = rewriter.create<scf::ForOp>( auto forOp = scf::ForOp::create(
loc, lowerBound, upperBound, step, inputDecls, rewriter, loc, lowerBound, upperBound, step, inputDecls,
[&](OpBuilder &builder, Location loc, Value i, ValueRange iterArgs) { [&](OpBuilder &builder, Location loc, Value i, ValueRange iterArgs) {
// Drop existing assertions // Drop existing assertions
builder.create<smt::PopOp>(loc, 1); smt::PopOp::create(builder, loc, 1);
builder.create<smt::PushOp>(loc, 1); smt::PushOp::create(builder, loc, 1);
// Execute the circuit // Execute the circuit
ValueRange circuitCallOuts = ValueRange circuitCallOuts =
builder func::CallOp::create(
.create<func::CallOp>( builder, loc, circuitFuncOp,
loc, circuitFuncOp, iterArgs.take_front(circuitFuncOp.getNumArguments()))
iterArgs.take_front(circuitFuncOp.getNumArguments()))
->getResults(); ->getResults();
// If we have a cycle up to which we ignore assertions, we need an // If we have a cycle up to which we ignore assertions, we need an
@ -516,41 +516,43 @@ struct VerifBoundedModelCheckingOpConversion
auto ignoreAssertionsUntil = auto ignoreAssertionsUntil =
op->getAttrOfType<IntegerAttr>("ignore_asserts_until"); op->getAttrOfType<IntegerAttr>("ignore_asserts_until");
if (ignoreAssertionsUntil) { if (ignoreAssertionsUntil) {
auto ignoreUntilConstant = builder.create<arith::ConstantOp>( auto ignoreUntilConstant = arith::ConstantOp::create(
loc, rewriter.getI32IntegerAttr( builder, loc,
ignoreAssertionsUntil.getValue().getZExtValue())); rewriter.getI32IntegerAttr(
auto shouldIgnore = builder.create<arith::CmpIOp>( ignoreAssertionsUntil.getValue().getZExtValue()));
loc, arith::CmpIPredicate::ult, i, ignoreUntilConstant); auto shouldIgnore =
auto ifShouldIgnore = builder.create<scf::IfOp>( arith::CmpIOp::create(builder, loc, arith::CmpIPredicate::ult,
loc, builder.getI1Type(), shouldIgnore, true); i, ignoreUntilConstant);
auto ifShouldIgnore = scf::IfOp::create(
builder, loc, builder.getI1Type(), shouldIgnore, true);
// If we should ignore, yield the existing value // If we should ignore, yield the existing value
builder.setInsertionPointToEnd( builder.setInsertionPointToEnd(
&ifShouldIgnore.getThenRegion().front()); &ifShouldIgnore.getThenRegion().front());
builder.create<scf::YieldOp>(loc, ValueRange(iterArgs.back())); scf::YieldOp::create(builder, loc, ValueRange(iterArgs.back()));
builder.setInsertionPointToEnd( builder.setInsertionPointToEnd(
&ifShouldIgnore.getElseRegion().front()); &ifShouldIgnore.getElseRegion().front());
yieldedValue = ifShouldIgnore.getResult(0); yieldedValue = ifShouldIgnore.getResult(0);
} }
auto checkOp = auto checkOp =
rewriter.create<smt::CheckOp>(loc, builder.getI1Type()); smt::CheckOp::create(rewriter, loc, builder.getI1Type());
{ {
OpBuilder::InsertionGuard guard(builder); OpBuilder::InsertionGuard guard(builder);
builder.createBlock(&checkOp.getSatRegion()); builder.createBlock(&checkOp.getSatRegion());
builder.create<smt::YieldOp>(loc, constTrue); smt::YieldOp::create(builder, loc, constTrue);
builder.createBlock(&checkOp.getUnknownRegion()); builder.createBlock(&checkOp.getUnknownRegion());
builder.create<smt::YieldOp>(loc, constTrue); smt::YieldOp::create(builder, loc, constTrue);
builder.createBlock(&checkOp.getUnsatRegion()); builder.createBlock(&checkOp.getUnsatRegion());
builder.create<smt::YieldOp>(loc, constFalse); smt::YieldOp::create(builder, loc, constFalse);
} }
Value violated = builder.create<arith::OrIOp>( Value violated = arith::OrIOp::create(
loc, checkOp.getResult(0), iterArgs.back()); builder, loc, checkOp.getResult(0), iterArgs.back());
// If we've packaged everything in an IfOp, we need to yield the // If we've packaged everything in an IfOp, we need to yield the
// new violated value // new violated value
if (ignoreAssertionsUntil) { if (ignoreAssertionsUntil) {
builder.create<scf::YieldOp>(loc, violated); scf::YieldOp::create(builder, loc, violated);
// Replace the variable with the yielded value // Replace the variable with the yielded value
violated = yieldedValue; violated = yieldedValue;
} }
@ -567,7 +569,7 @@ struct VerifBoundedModelCheckingOpConversion
for (auto stateArg : iterArgs.drop_back().take_back(numStateArgs)) for (auto stateArg : iterArgs.drop_back().take_back(numStateArgs))
loopCallInputs.push_back(stateArg); loopCallInputs.push_back(stateArg);
ValueRange loopVals = ValueRange loopVals =
builder.create<func::CallOp>(loc, loopFuncOp, loopCallInputs) func::CallOp::create(builder, loc, loopFuncOp, loopCallInputs)
->getResults(); ->getResults();
size_t loopIndex = 0; size_t loopIndex = 0;
@ -579,7 +581,8 @@ struct VerifBoundedModelCheckingOpConversion
if (isa<seq::ClockType>(oldTy)) if (isa<seq::ClockType>(oldTy))
newDecls.push_back(loopVals[loopIndex++]); newDecls.push_back(loopVals[loopIndex++]);
else else
newDecls.push_back(builder.create<smt::DeclareFunOp>(loc, newTy)); newDecls.push_back(
smt::DeclareFunOp::create(builder, loc, newTy));
} }
// Only update the registers on a clock posedge unless in rising // Only update the registers on a clock posedge unless in rising
@ -598,13 +601,13 @@ struct VerifBoundedModelCheckingOpConversion
// The clock is necessarily the first value returned by the loop // The clock is necessarily the first value returned by the loop
// region // region
auto newClock = loopVals[0]; auto newClock = loopVals[0];
auto oldClockLow = builder.create<smt::BVNotOp>(loc, oldClock); auto oldClockLow = smt::BVNotOp::create(builder, loc, oldClock);
auto isPosedgeBV = auto isPosedgeBV =
builder.create<smt::BVAndOp>(loc, oldClockLow, newClock); smt::BVAndOp::create(builder, loc, oldClockLow, newClock);
// Convert posedge bv<1> to bool // Convert posedge bv<1> to bool
auto trueBV = builder.create<smt::BVConstantOp>(loc, 1, 1); auto trueBV = smt::BVConstantOp::create(builder, loc, 1, 1);
auto isPosedge = auto isPosedge =
builder.create<smt::EqOp>(loc, isPosedgeBV, trueBV); smt::EqOp::create(builder, loc, isPosedgeBV, trueBV);
auto regStates = auto regStates =
iterArgs.take_front(circuitFuncOp.getNumArguments()) iterArgs.take_front(circuitFuncOp.getNumArguments())
.take_back(numRegs); .take_back(numRegs);
@ -614,8 +617,8 @@ struct VerifBoundedModelCheckingOpConversion
// Create an ITE to calculate the next reg state // Create an ITE to calculate the next reg state
// TODO: we create a lot of ITEs here that will slow things down // TODO: we create a lot of ITEs here that will slow things down
// - these could be avoided by making init/loop regions concrete // - these could be avoided by making init/loop regions concrete
nextRegStates.push_back(builder.create<smt::IteOp>( nextRegStates.push_back(smt::IteOp::create(
loc, isPosedge, regInput, regState)); builder, loc, isPosedge, regInput, regState));
} }
newDecls.append(nextRegStates); newDecls.append(nextRegStates);
} }
@ -627,12 +630,12 @@ struct VerifBoundedModelCheckingOpConversion
newDecls.push_back(violated); newDecls.push_back(violated);
builder.create<scf::YieldOp>(loc, newDecls); scf::YieldOp::create(builder, loc, newDecls);
}); });
Value res = rewriter.create<arith::XOrIOp>(loc, forOp->getResults().back(), Value res = arith::XOrIOp::create(rewriter, loc, forOp->getResults().back(),
constTrue); constTrue);
rewriter.create<smt::YieldOp>(loc, res); smt::YieldOp::create(rewriter, loc, res);
rewriter.replaceOp(op, solver.getResults()); rewriter.replaceOp(op, solver.getResults());
return success(); return success();
} }

View File

@ -45,7 +45,7 @@ struct PrintOpConversionPattern : public OpConversionPattern<PrintOp> {
// Printf's will be emitted to stdout (32'h8000_0001 in IEEE Std 1800-2012). // Printf's will be emitted to stdout (32'h8000_0001 in IEEE Std 1800-2012).
Value fdStdout = Value fdStdout =
rewriter.create<hw::ConstantOp>(op.getLoc(), APInt(32, 0x80000001)); hw::ConstantOp::create(rewriter, op.getLoc(), APInt(32, 0x80000001));
auto fstrOp = auto fstrOp =
dyn_cast_or_null<FormatVerilogStringOp>(op.getString().getDefiningOp()); dyn_cast_or_null<FormatVerilogStringOp>(op.getString().getDefiningOp());
@ -66,13 +66,13 @@ struct HasBeenResetConversion : public OpConversionPattern<HasBeenResetOp> {
matchAndRewrite(HasBeenResetOp op, OpAdaptor operands, matchAndRewrite(HasBeenResetOp op, OpAdaptor operands,
ConversionPatternRewriter &rewriter) const override { ConversionPatternRewriter &rewriter) const override {
auto i1 = rewriter.getI1Type(); auto i1 = rewriter.getI1Type();
auto constOne = rewriter.create<hw::ConstantOp>(op.getLoc(), i1, 1); auto constOne = hw::ConstantOp::create(rewriter, op.getLoc(), i1, 1);
auto constZero = rewriter.create<hw::ConstantOp>(op.getLoc(), i1, 0); auto constZero = hw::ConstantOp::create(rewriter, op.getLoc(), i1, 0);
auto constX = rewriter.create<sv::ConstantXOp>(op.getLoc(), i1); auto constX = sv::ConstantXOp::create(rewriter, op.getLoc(), i1);
// Declare the register that will track the reset state. // Declare the register that will track the reset state.
auto reg = rewriter.create<sv::RegOp>( auto reg = sv::RegOp::create(rewriter, op.getLoc(), i1,
op.getLoc(), i1, rewriter.getStringAttr("hasBeenResetReg")); rewriter.getStringAttr("hasBeenResetReg"));
auto clock = operands.getClock(); auto clock = operands.getClock();
auto reset = operands.getReset(); auto reset = operands.getReset();
@ -84,15 +84,15 @@ struct HasBeenResetConversion : public OpConversionPattern<HasBeenResetOp> {
// In case the reset is async, check if the reset is already active during // In case the reset is async, check if the reset is already active during
// the `initial` block and immediately set the register to 1. Otherwise // the `initial` block and immediately set the register to 1. Otherwise
// initialize to X. // initialize to X.
rewriter.create<sv::InitialOp>(op.getLoc(), [&] { sv::InitialOp::create(rewriter, op.getLoc(), [&] {
auto assignOne = [&] { auto assignOne = [&] {
rewriter.create<sv::BPAssignOp>(op.getLoc(), reg, constOne); sv::BPAssignOp::create(rewriter, op.getLoc(), reg, constOne);
}; };
auto assignX = [&] { auto assignX = [&] {
rewriter.create<sv::BPAssignOp>(op.getLoc(), reg, constX); sv::BPAssignOp::create(rewriter, op.getLoc(), reg, constX);
}; };
if (op.getAsync()) if (op.getAsync())
rewriter.create<sv::IfOp>(op.getLoc(), reset, assignOne, assignX); sv::IfOp::create(rewriter, op.getLoc(), reset, assignOne, assignX);
else else
assignX(); assignX();
}); });
@ -101,20 +101,20 @@ struct HasBeenResetConversion : public OpConversionPattern<HasBeenResetOp> {
// reset is initiated. For async resets this happens at the reset's posedge; // reset is initiated. For async resets this happens at the reset's posedge;
// for sync resets this happens on the clock's posedge if the reset is set. // for sync resets this happens on the clock's posedge if the reset is set.
Value triggerOn = op.getAsync() ? reset : clock; Value triggerOn = op.getAsync() ? reset : clock;
rewriter.create<sv::AlwaysOp>( sv::AlwaysOp::create(
op.getLoc(), sv::EventControl::AtPosEdge, triggerOn, [&] { rewriter, op.getLoc(), sv::EventControl::AtPosEdge, triggerOn, [&] {
auto assignOne = [&] { auto assignOne = [&] {
rewriter.create<sv::PAssignOp>(op.getLoc(), reg, constOne); sv::PAssignOp::create(rewriter, op.getLoc(), reg, constOne);
}; };
if (op.getAsync()) if (op.getAsync())
assignOne(); assignOne();
else else
rewriter.create<sv::IfOp>(op.getLoc(), reset, assignOne); sv::IfOp::create(rewriter, op.getLoc(), reset, assignOne);
}); });
// Derive the actual result value: // Derive the actual result value:
// hasBeenReset = (hasBeenResetReg === 1) && (reset === 0); // hasBeenReset = (hasBeenResetReg === 1) && (reset === 0);
auto regRead = rewriter.create<sv::ReadInOutOp>(op.getLoc(), reg); auto regRead = sv::ReadInOutOp::create(rewriter, op.getLoc(), reg);
auto regIsOne = rewriter.createOrFold<comb::ICmpOp>( auto regIsOne = rewriter.createOrFold<comb::ICmpOp>(
op.getLoc(), comb::ICmpPredicate::ceq, regRead, constOne); op.getLoc(), comb::ICmpPredicate::ceq, regRead, constOne);
auto resetIsZero = rewriter.createOrFold<comb::ICmpOp>( auto resetIsZero = rewriter.createOrFold<comb::ICmpOp>(

View File

@ -87,7 +87,7 @@ LogicalResult AndInverterOp::canonicalize(AndInverterOp op,
return failure(); return failure();
if (!constValue.isAllOnes()) { if (!constValue.isAllOnes()) {
auto constOp = rewriter.create<hw::ConstantOp>(op.getLoc(), constValue); auto constOp = hw::ConstantOp::create(rewriter, op.getLoc(), constValue);
uniqueInverts.push_back(false); uniqueInverts.push_back(false);
uniqueValues.push_back(constOp); uniqueValues.push_back(constOp);
} }

View File

@ -417,7 +417,7 @@ LogicalResult AIGERRunner::importFromAIGER(Converter &converter,
mlir::OpBuilder builder(originalModule->getContext()); mlir::OpBuilder builder(originalModule->getContext());
builder.setInsertionPointToStart(&temporaryBlock); builder.setInsertionPointToStart(&temporaryBlock);
auto temporaryModule = auto temporaryModule =
builder.create<mlir::ModuleOp>(builder.getUnknownLoc()); mlir::ModuleOp::create(builder, builder.getUnknownLoc());
// Import the AIGER file into the temporary module // Import the AIGER file into the temporary module
if (failed(circt::aiger::importAIGER(sourceMgr, originalModule->getContext(), if (failed(circt::aiger::importAIGER(sourceMgr, originalModule->getContext(),

View File

@ -42,12 +42,12 @@ static Value lowerVariadicAndInverterOp(AndInverterOp op, OperandRange operands,
break; break;
case 1: case 1:
if (inverts[0]) if (inverts[0])
return rewriter.create<AndInverterOp>(op.getLoc(), operands[0], true); return AndInverterOp::create(rewriter, op.getLoc(), operands[0], true);
else else
return operands[0]; return operands[0];
case 2: case 2:
return rewriter.create<AndInverterOp>(op.getLoc(), operands[0], operands[1], return AndInverterOp::create(rewriter, op.getLoc(), operands[0],
inverts[0], inverts[1]); operands[1], inverts[0], inverts[1]);
default: default:
auto firstHalf = operands.size() / 2; auto firstHalf = operands.size() / 2;
auto lhs = auto lhs =
@ -56,7 +56,7 @@ static Value lowerVariadicAndInverterOp(AndInverterOp op, OperandRange operands,
auto rhs = auto rhs =
lowerVariadicAndInverterOp(op, operands.drop_front(firstHalf), lowerVariadicAndInverterOp(op, operands.drop_front(firstHalf),
inverts.drop_front(firstHalf), rewriter); inverts.drop_front(firstHalf), rewriter);
return rewriter.create<AndInverterOp>(op.getLoc(), lhs, rhs); return AndInverterOp::create(rewriter, op.getLoc(), lhs, rhs);
} }
return Value(); return Value();

View File

@ -64,10 +64,10 @@ struct WordRewritePattern : public OpRewritePattern<AndInverterOp> {
} }
// Otherwise, we need to extract the bit. // Otherwise, we need to extract the bit.
operands.push_back( operands.push_back(
rewriter.create<comb::ExtractOp>(op.getLoc(), operand, i, 1)); comb::ExtractOp::create(rewriter, op.getLoc(), operand, i, 1));
} }
results.push_back(rewriter.create<AndInverterOp>(op.getLoc(), operands, results.push_back(AndInverterOp::create(rewriter, op.getLoc(), operands,
op.getInvertedAttr())); op.getInvertedAttr()));
} }
rewriter.replaceOpWithNewOp<comb::ConcatOp>(op, results); rewriter.replaceOpWithNewOp<comb::ConcatOp>(op, results);

View File

@ -66,7 +66,7 @@ Operation *ArcDialect::materializeConstant(OpBuilder &builder, Attribute value,
// Integer constants. // Integer constants.
if (auto intType = dyn_cast<IntegerType>(type)) if (auto intType = dyn_cast<IntegerType>(type))
if (auto attrValue = dyn_cast<IntegerAttr>(value)) if (auto attrValue = dyn_cast<IntegerAttr>(value))
return builder.create<hw::ConstantOp>(loc, type, attrValue); return hw::ConstantOp::create(builder, loc, type, attrValue);
// Parameter expressions materialize into hw.param.value. // Parameter expressions materialize into hw.param.value.
auto *parentOp = builder.getBlock()->getParentOp(); auto *parentOp = builder.getBlock()->getParentOp();
@ -74,7 +74,7 @@ Operation *ArcDialect::materializeConstant(OpBuilder &builder, Attribute value,
if (!curModule) if (!curModule)
curModule = parentOp->getParentOfType<hw::HWModuleOp>(); curModule = parentOp->getParentOfType<hw::HWModuleOp>();
if (curModule && isValidParameterExpression(value, curModule)) if (curModule && isValidParameterExpression(value, curModule))
return builder.create<hw::ParamValueOp>(loc, type, value); return hw::ParamValueOp::create(builder, loc, type, value);
return nullptr; return nullptr;
} }

View File

@ -158,8 +158,8 @@ static bool removeUnusedClockDomainOutputs(ClockDomainOp op,
rewriter.setInsertionPoint(op); rewriter.setInsertionPoint(op);
auto newDomain = rewriter.create<ClockDomainOp>( auto newDomain = ClockDomainOp::create(rewriter, op.getLoc(), resultTypes,
op.getLoc(), resultTypes, op.getInputs(), op.getClock()); op.getInputs(), op.getClock());
rewriter.inlineRegionBefore(op.getBody(), newDomain.getBody(), rewriter.inlineRegionBefore(op.getBody(), newDomain.getBody(),
newDomain->getRegion(0).begin()); newDomain->getRegion(0).begin());

View File

@ -29,9 +29,9 @@ struct StateElimination : public OpReduction<StateOp> {
LogicalResult rewrite(StateOp stateOp) override { LogicalResult rewrite(StateOp stateOp) override {
OpBuilder builder(stateOp); OpBuilder builder(stateOp);
ValueRange results = ValueRange results =
builder arc::CallOp::create(builder, stateOp.getLoc(),
.create<arc::CallOp>(stateOp.getLoc(), stateOp->getResultTypes(), stateOp->getResultTypes(), stateOp.getArcAttr(),
stateOp.getArcAttr(), stateOp.getInputs()) stateOp.getInputs())
->getResults(); ->getResults();
stateOp.replaceAllUsesWith(results); stateOp.replaceAllUsesWith(results);
stateOp.erase(); stateOp.erase();

View File

@ -66,7 +66,7 @@ struct AddTapsPass : public arc::impl::AddTapsBase<AddTapsPass> {
OpBuilder builder(wireOp); OpBuilder builder(wireOp);
if (!readOp) if (!readOp)
readOp = builder.create<sv::ReadInOutOp>(wireOp.getLoc(), wireOp); readOp = sv::ReadInOutOp::create(builder, wireOp.getLoc(), wireOp);
buildTap(builder, readOp.getLoc(), readOp, wireOp.getName()); buildTap(builder, readOp.getLoc(), readOp, wireOp.getName());
} }
@ -95,7 +95,7 @@ struct AddTapsPass : public arc::impl::AddTapsBase<AddTapsPass> {
return; return;
if (isa<seq::ClockType>(value.getType())) if (isa<seq::ClockType>(value.getType()))
value = builder.createOrFold<seq::FromClockOp>(loc, value); value = builder.createOrFold<seq::FromClockOp>(loc, value);
builder.create<arc::TapOp>(loc, value, name); arc::TapOp::create(builder, loc, value, name);
} }
}; };
} // namespace } // namespace

View File

@ -135,7 +135,7 @@ void AllocateStatePass::allocateOps(Value storage, Block *block,
if (!getter || !result.getDefiningOp<AllocStorageOp>()) { if (!getter || !result.getDefiningOp<AllocStorageOp>()) {
ImplicitLocOpBuilder builder(result.getLoc(), user); ImplicitLocOpBuilder builder(result.getLoc(), user);
getter = getter =
builder.create<StorageGetOp>(result.getType(), storage, offset); StorageGetOp::create(builder, result.getType(), storage, offset);
getters.push_back(getter); getters.push_back(getter);
opOrder[getter] = userOrder; opOrder[getter] = userOrder;
} else if (userOrder < opOrder.lookup(getter)) { } else if (userOrder < opOrder.lookup(getter)) {
@ -152,8 +152,8 @@ void AllocateStatePass::allocateOps(Value storage, Block *block,
storageOwner = cast<BlockArgument>(storage).getOwner()->getParentOp(); storageOwner = cast<BlockArgument>(storage).getOwner()->getParentOp();
if (storageOwner->isProperAncestor(block->getParentOp())) { if (storageOwner->isProperAncestor(block->getParentOp())) {
auto substorage = builder.create<AllocStorageOp>( auto substorage = AllocStorageOp::create(
block->getParentOp()->getLoc(), builder, block->getParentOp()->getLoc(),
StorageType::get(&getContext(), currentByte), storage); StorageType::get(&getContext(), currentByte), storage);
for (auto *op : ops) for (auto *op : ops)
op->replaceUsesOfWith(storage, substorage); op->replaceUsesOfWith(storage, substorage);

View File

@ -358,13 +358,13 @@ LogicalResult MemWritePortEnableAndMaskCanonicalizer::matchAndRewrite(
&newDefOp.getBody(), newDefOp.getBody().end(), &newDefOp.getBody(), newDefOp.getBody().end(),
newDefOp.getArgumentTypes(), newDefOp.getArgumentTypes(),
SmallVector<Location>(newDefOp.getNumArguments(), defOp.getLoc())); SmallVector<Location>(newDefOp.getNumArguments(), defOp.getLoc()));
auto callOp = rewriter.create<CallOp>(newDefOp.getLoc(), newResultTypes, auto callOp = CallOp::create(rewriter, newDefOp.getLoc(), newResultTypes,
newName, block->getArguments()); newName, block->getArguments());
SmallVector<Value> results(callOp->getResults()); SmallVector<Value> results(callOp->getResults());
Value constTrue = rewriter.create<hw::ConstantOp>( Value constTrue = hw::ConstantOp::create(rewriter, newDefOp.getLoc(),
newDefOp.getLoc(), rewriter.getI1Type(), 1); rewriter.getI1Type(), 1);
results.insert(results.begin() + op.getEnableIdx(), constTrue); results.insert(results.begin() + op.getEnableIdx(), constTrue);
rewriter.create<OutputOp>(newDefOp.getLoc(), results); OutputOp::create(rewriter, newDefOp.getLoc(), results);
// Remove the enable output from the current arc // Remove the enable output from the current arc
auto *terminator = defOp.getBodyBlock().getTerminator(); auto *terminator = defOp.getBodyBlock().getTerminator();
@ -416,7 +416,7 @@ LogicalResult
ICMPCanonicalizer::matchAndRewrite(comb::ICmpOp op, ICMPCanonicalizer::matchAndRewrite(comb::ICmpOp op,
PatternRewriter &rewriter) const { PatternRewriter &rewriter) const {
auto getConstant = [&](const APInt &constant) -> Value { auto getConstant = [&](const APInt &constant) -> Value {
return rewriter.create<hw::ConstantOp>(op.getLoc(), constant); return hw::ConstantOp::create(rewriter, op.getLoc(), constant);
}; };
auto sameWidthIntegers = [](TypeRange types) -> std::optional<unsigned> { auto sameWidthIntegers = [](TypeRange types) -> std::optional<unsigned> {
if (llvm::all_equal(types) && !types.empty()) if (llvm::all_equal(types) && !types.empty())
@ -425,9 +425,9 @@ ICMPCanonicalizer::matchAndRewrite(comb::ICmpOp op,
return std::nullopt; return std::nullopt;
}; };
auto negate = [&](Value input) -> Value { auto negate = [&](Value input) -> Value {
auto constTrue = rewriter.create<hw::ConstantOp>(op.getLoc(), APInt(1, 1)); auto constTrue = hw::ConstantOp::create(rewriter, op.getLoc(), APInt(1, 1));
return rewriter.create<comb::XorOp>(op.getLoc(), input, constTrue, return comb::XorOp::create(rewriter, op.getLoc(), input, constTrue,
op.getTwoState()); op.getTwoState());
}; };
APInt rhs; APInt rhs;
@ -438,8 +438,8 @@ ICMPCanonicalizer::matchAndRewrite(comb::ICmpOp op,
if ((op.getPredicate() == comb::ICmpPredicate::eq || if ((op.getPredicate() == comb::ICmpPredicate::eq ||
op.getPredicate() == comb::ICmpPredicate::ne) && op.getPredicate() == comb::ICmpPredicate::ne) &&
rhs.isAllOnes()) { rhs.isAllOnes()) {
Value andOp = rewriter.create<comb::AndOp>( Value andOp = comb::AndOp::create(
op.getLoc(), concatOp.getInputs(), op.getTwoState()); rewriter, op.getLoc(), concatOp.getInputs(), op.getTwoState());
if (*optionalWidth == 1) { if (*optionalWidth == 1) {
if (op.getPredicate() == comb::ICmpPredicate::ne) if (op.getPredicate() == comb::ICmpPredicate::ne)
andOp = negate(andOp); andOp = negate(andOp);
@ -457,8 +457,8 @@ ICMPCanonicalizer::matchAndRewrite(comb::ICmpOp op,
if ((op.getPredicate() == comb::ICmpPredicate::ne || if ((op.getPredicate() == comb::ICmpPredicate::ne ||
op.getPredicate() == comb::ICmpPredicate::eq) && op.getPredicate() == comb::ICmpPredicate::eq) &&
rhs.isZero()) { rhs.isZero()) {
Value orOp = rewriter.create<comb::OrOp>( Value orOp = comb::OrOp::create(
op.getLoc(), concatOp.getInputs(), op.getTwoState()); rewriter, op.getLoc(), concatOp.getInputs(), op.getTwoState());
if (*optionalWidth == 1) { if (*optionalWidth == 1) {
if (op.getPredicate() == comb::ICmpPredicate::eq) if (op.getPredicate() == comb::ICmpPredicate::eq)
orOp = negate(orOp); orOp = negate(orOp);
@ -595,8 +595,8 @@ CompRegCanonicalizer::matchAndRewrite(seq::CompRegOp op,
if (constant.isZero()) if (constant.isZero())
return failure(); return failure();
Value newInput = rewriter.create<comb::MuxOp>( Value newInput = comb::MuxOp::create(rewriter, op->getLoc(), op.getReset(),
op->getLoc(), op.getReset(), op.getResetValue(), op.getInput()); op.getResetValue(), op.getInput());
rewriter.modifyOpInPlace(op, [&]() { rewriter.modifyOpInPlace(op, [&]() {
op.getInputMutable().set(newInput); op.getInputMutable().set(newInput);
op.getResetMutable().clear(); op.getResetMutable().clear();

View File

@ -219,7 +219,7 @@ Vectorizer::vectorize(FindInitialVectorsPass::StatisticVars &stat) {
// Now construct the `VectorizeOp` // Now construct the `VectorizeOp`
ImplicitLocOpBuilder builder(ops[0]->getLoc(), ops[0]); ImplicitLocOpBuilder builder(ops[0]->getLoc(), ops[0]);
auto vectorizeOp = auto vectorizeOp =
builder.create<VectorizeOp>(resultTypes, operandValueRanges); VectorizeOp::create(builder, resultTypes, operandValueRanges);
// Now we have the operands, results and attributes, now we need to get // Now we have the operands, results and attributes, now we need to get
// the blocks. // the blocks.
@ -245,7 +245,7 @@ Vectorizer::vectorize(FindInitialVectorsPass::StatisticVars &stat) {
auto *clonedOp = builder.clone(*ops[0], argMapping); auto *clonedOp = builder.clone(*ops[0], argMapping);
// `VectorizeReturnOp` // `VectorizeReturnOp`
builder.create<VectorizeReturnOp>(clonedOp->getResult(0)); VectorizeReturnOp::create(builder, clonedOp->getResult(0));
// Now replace the original ops with the vectorized ops // Now replace the original ops with the vectorized ops
for (auto [op, result] : llvm::zip(ops, vectorizeOp->getResults())) { for (auto [op, result] : llvm::zip(ops, vectorizeOp->getResults())) {

View File

@ -115,7 +115,7 @@ void InferMemoriesPass::runOnOperation() {
return signalPassFailure(); return signalPassFailure();
} }
auto memType = MemoryType::get(&getContext(), depth, wordType, addressTy); auto memType = MemoryType::get(&getContext(), depth, wordType, addressTy);
auto memOp = builder.create<MemoryOp>(memType); auto memOp = MemoryOp::create(builder, memType);
if (tapMemories && !instOp.getInstanceName().empty()) if (tapMemories && !instOp.getInstanceName().empty())
memOp->setAttr("name", instOp.getInstanceNameAttr()); memOp->setAttr("name", instOp.getInstanceNameAttr());
@ -124,9 +124,9 @@ void InferMemoriesPass::runOnOperation() {
auto applyLatency = [&](Value clock, Value data, unsigned latency) { auto applyLatency = [&](Value clock, Value data, unsigned latency) {
for (unsigned i = 0; i < latency; ++i) for (unsigned i = 0; i < latency; ++i)
data = builder.create<seq::CompRegOp>( data = seq::CompRegOp::create(builder, data, clock,
data, clock, builder.getStringAttr(""), Value{}, Value{}, Value{}, builder.getStringAttr(""), Value{},
hw::InnerSymAttr{}); Value{}, Value{}, hw::InnerSymAttr{});
return data; return data;
}; };
@ -141,7 +141,7 @@ void InferMemoriesPass::runOnOperation() {
auto tap = [&](Value value, const Twine &name) { auto tap = [&](Value value, const Twine &name) {
auto prefixedName = builder.getStringAttr(tapPrefix + "_" + name); auto prefixedName = builder.getStringAttr(tapPrefix + "_" + name);
builder.create<arc::TapOp>(value, prefixedName); arc::TapOp::create(builder, value, prefixedName);
}; };
// Handle read ports. // Handle read ports.
@ -174,9 +174,10 @@ void InferMemoriesPass::runOnOperation() {
// Read the underlying storage. (The result of a disabled read port is // Read the underlying storage. (The result of a disabled read port is
// undefined, currently we define it to be zero.) // undefined, currently we define it to be zero.)
Value readOp = builder.create<MemoryReadPortOp>(wordType, memOp, address); Value readOp =
Value zero = builder.create<hw::ConstantOp>(wordType, 0); MemoryReadPortOp::create(builder, wordType, memOp, address);
readOp = builder.create<comb::MuxOp>(enable, readOp, zero); Value zero = hw::ConstantOp::create(builder, wordType, 0);
readOp = comb::MuxOp::create(builder, enable, readOp, zero);
// Apply the latency after the underlying storage was accessed. (If the // Apply the latency after the underlying storage was accessed. (If the
// latency is 0, the memory read is combinatorial without any buffer.) // latency is 0, the memory read is combinatorial without any buffer.)
@ -216,9 +217,9 @@ void InferMemoriesPass::runOnOperation() {
tap(readData, "rdata"); tap(readData, "rdata");
} }
auto c1_i1 = builder.create<hw::ConstantOp>(builder.getI1Type(), 1); auto c1_i1 = hw::ConstantOp::create(builder, builder.getI1Type(), 1);
auto notWriteMode = builder.create<comb::XorOp>(writeMode, c1_i1); auto notWriteMode = comb::XorOp::create(builder, writeMode, c1_i1);
Value readEnable = builder.create<comb::AndOp>(enable, notWriteMode); Value readEnable = comb::AndOp::create(builder, enable, notWriteMode);
// Apply the latency before the underlying storage is accessed. // Apply the latency before the underlying storage is accessed.
Value readAddress = applyLatency(clock, address, readPreLatency); Value readAddress = applyLatency(clock, address, readPreLatency);
@ -227,21 +228,21 @@ void InferMemoriesPass::runOnOperation() {
// Read the underlying storage. (The result of a disabled read port is // Read the underlying storage. (The result of a disabled read port is
// undefined, currently we define it to be zero.) // undefined, currently we define it to be zero.)
Value readOp = Value readOp =
builder.create<MemoryReadPortOp>(wordType, memOp, readAddress); MemoryReadPortOp::create(builder, wordType, memOp, readAddress);
Value zero = builder.create<hw::ConstantOp>(wordType, 0); Value zero = hw::ConstantOp::create(builder, wordType, 0);
readOp = builder.create<comb::MuxOp>(readEnable, readOp, zero); readOp = comb::MuxOp::create(builder, readEnable, readOp, zero);
if (writeMask) { if (writeMask) {
unsigned maskWidth = cast<IntegerType>(writeMask.getType()).getWidth(); unsigned maskWidth = cast<IntegerType>(writeMask.getType()).getWidth();
SmallVector<Value> toConcat; SmallVector<Value> toConcat;
for (unsigned i = 0; i < maskWidth; ++i) { for (unsigned i = 0; i < maskWidth; ++i) {
Value bit = builder.create<comb::ExtractOp>(writeMask, i, 1); Value bit = comb::ExtractOp::create(builder, writeMask, i, 1);
Value replicated = builder.create<comb::ReplicateOp>(bit, maskGran); Value replicated = comb::ReplicateOp::create(builder, bit, maskGran);
toConcat.push_back(replicated); toConcat.push_back(replicated);
} }
std::reverse(toConcat.begin(), toConcat.end()); // I hate concat std::reverse(toConcat.begin(), toConcat.end()); // I hate concat
writeMask = writeMask =
builder.create<comb::ConcatOp>(writeData.getType(), toConcat); comb::ConcatOp::create(builder, writeData.getType(), toConcat);
} }
// Apply the latency after the underlying storage was accessed. (If the // Apply the latency after the underlying storage was accessed. (If the
@ -249,7 +250,7 @@ void InferMemoriesPass::runOnOperation() {
readOp = applyLatency(clock, readOp, readPostLatency); readOp = applyLatency(clock, readOp, readPostLatency);
readData.replaceAllUsesWith(readOp); readData.replaceAllUsesWith(readOp);
auto writeEnable = builder.create<comb::AndOp>(enable, writeMode); auto writeEnable = comb::AndOp::create(builder, enable, writeMode);
SmallVector<Value> inputs({address, writeData, writeEnable}); SmallVector<Value> inputs({address, writeData, writeEnable});
if (writeMask) if (writeMask)
inputs.push_back(writeMask); inputs.push_back(writeMask);
@ -287,12 +288,12 @@ void InferMemoriesPass::runOnOperation() {
unsigned maskWidth = cast<IntegerType>(mask.getType()).getWidth(); unsigned maskWidth = cast<IntegerType>(mask.getType()).getWidth();
SmallVector<Value> toConcat; SmallVector<Value> toConcat;
for (unsigned i = 0; i < maskWidth; ++i) { for (unsigned i = 0; i < maskWidth; ++i) {
Value bit = builder.create<comb::ExtractOp>(mask, i, 1); Value bit = comb::ExtractOp::create(builder, mask, i, 1);
Value replicated = builder.create<comb::ReplicateOp>(bit, maskGran); Value replicated = comb::ReplicateOp::create(builder, bit, maskGran);
toConcat.push_back(replicated); toConcat.push_back(replicated);
} }
std::reverse(toConcat.begin(), toConcat.end()); // I hate concat std::reverse(toConcat.begin(), toConcat.end()); // I hate concat
mask = builder.create<comb::ConcatOp>(data.getType(), toConcat); mask = comb::ConcatOp::create(builder, data.getType(), toConcat);
} }
SmallVector<Value> inputs({address, data}); SmallVector<Value> inputs({address, data});
if (enable) if (enable)
@ -308,16 +309,16 @@ void InferMemoriesPass::runOnOperation() {
auto ipSave = builder.saveInsertionPoint(); auto ipSave = builder.saveInsertionPoint();
TypeRange types = ValueRange(inputs).getTypes(); TypeRange types = ValueRange(inputs).getTypes();
builder.setInsertionPointToStart(module.getBody()); builder.setInsertionPointToStart(module.getBody());
auto defOp = builder.create<DefineOp>( auto defOp = DefineOp::create(builder, names.newName("mem_write"),
names.newName("mem_write"), builder.getFunctionType(types, types)); builder.getFunctionType(types, types));
auto &block = defOp.getBody().emplaceBlock(); auto &block = defOp.getBody().emplaceBlock();
auto args = block.addArguments( auto args = block.addArguments(
types, SmallVector<Location>(types.size(), builder.getLoc())); types, SmallVector<Location>(types.size(), builder.getLoc()));
builder.setInsertionPointToEnd(&block); builder.setInsertionPointToEnd(&block);
builder.create<arc::OutputOp>(SmallVector<Value>(args)); arc::OutputOp::create(builder, SmallVector<Value>(args));
builder.restoreInsertionPoint(ipSave); builder.restoreInsertionPoint(ipSave);
builder.create<MemoryWritePortOp>(memOp, defOp.getName(), inputs, clock, MemoryWritePortOp::create(builder, memOp, defOp.getName(), inputs, clock,
hasEnable, hasMask); hasEnable, hasMask);
} }
opsToDelete.push_back(instOp); opsToDelete.push_back(instOp);

View File

@ -148,10 +148,10 @@ static void setResetOperandOfStateOp(arc::StateOp stateOp,
ImplicitLocOpBuilder builder(stateOp.getLoc(), stateOp); ImplicitLocOpBuilder builder(stateOp.getLoc(), stateOp);
if (stateOp.getEnable()) if (stateOp.getEnable())
resetCond = builder.create<comb::AndOp>(stateOp.getEnable(), resetCond); resetCond = comb::AndOp::create(builder, stateOp.getEnable(), resetCond);
if (stateOp.getReset()) if (stateOp.getReset())
resetCond = builder.create<comb::OrOp>(stateOp.getReset(), resetCond); resetCond = comb::OrOp::create(builder, stateOp.getReset(), resetCond);
stateOp.getResetMutable().assign(resetCond); stateOp.getResetMutable().assign(resetCond);
} }
@ -192,25 +192,24 @@ applyEnableTransformation(arc::DefineOp arcOp, arc::StateOp stateOp,
Value enableCond = Value enableCond =
stateOp.getInputs()[enableInfos[0].condition.getArgNumber()]; stateOp.getInputs()[enableInfos[0].condition.getArgNumber()];
Value one = builder.create<hw::ConstantOp>(builder.getI1Type(), -1); Value one = hw::ConstantOp::create(builder, builder.getI1Type(), -1);
if (enableInfos[0].isDisable) { if (enableInfos[0].isDisable) {
inputs[enableInfos[0].condition.getArgNumber()] = inputs[enableInfos[0].condition.getArgNumber()] =
builder.create<hw::ConstantOp>(builder.getI1Type(), 0); hw::ConstantOp::create(builder, builder.getI1Type(), 0);
enableCond = builder.create<comb::XorOp>(enableCond, one); enableCond = comb::XorOp::create(builder, enableCond, one);
} else { } else {
inputs[enableInfos[0].condition.getArgNumber()] = one; inputs[enableInfos[0].condition.getArgNumber()] = one;
} }
if (stateOp.getEnable()) if (stateOp.getEnable())
enableCond = builder.create<comb::AndOp>(stateOp.getEnable(), enableCond); enableCond = comb::AndOp::create(builder, stateOp.getEnable(), enableCond);
stateOp.getEnableMutable().assign(enableCond); stateOp.getEnableMutable().assign(enableCond);
for (size_t i = 0, e = outputOp.getOutputs().size(); i < e; ++i) { for (size_t i = 0, e = outputOp.getOutputs().size(); i < e; ++i) {
if (enableInfos[i].selfArg.hasOneUse()) if (enableInfos[i].selfArg.hasOneUse())
inputs[enableInfos[i].selfArg.getArgNumber()] = inputs[enableInfos[i].selfArg.getArgNumber()] = hw::ConstantOp::create(
builder.create<hw::ConstantOp>(stateOp.getLoc(), builder, stateOp.getLoc(), enableInfos[i].selfArg.getType(), 0);
enableInfos[i].selfArg.getType(), 0);
} }
stateOp.getInputsMutable().assign(inputs); stateOp.getInputsMutable().assign(inputs);

View File

@ -113,9 +113,9 @@ ClockDomainOp ClockDomain::materialize(OpBuilder &materializeBuilder,
computeCrossingValues(inputs, outputs); computeCrossingValues(inputs, outputs);
// Add the terminator and clock domain outputs and rewire the SSA value uses // Add the terminator and clock domain outputs and rewire the SSA value uses
auto outputOp = builder.create<arc::OutputOp>(loc, outputs); auto outputOp = arc::OutputOp::create(builder, loc, outputs);
auto clockDomainOp = materializeBuilder.create<ClockDomainOp>( auto clockDomainOp = ClockDomainOp::create(
loc, ValueRange(outputs).getTypes(), inputs, clock); materializeBuilder, loc, ValueRange(outputs).getTypes(), inputs, clock);
for (auto [domainOutput, val] : for (auto [domainOutput, val] :
llvm::zip(clockDomainOp.getOutputs(), outputOp->getOperands())) { llvm::zip(clockDomainOp.getOutputs(), outputOp->getOperands())) {
val.replaceUsesWithIf(domainOutput, [&](OpOperand &operand) { val.replaceUsesWithIf(domainOutput, [&](OpOperand &operand) {

View File

@ -42,8 +42,8 @@ struct DefineOpLowering : public OpConversionPattern<arc::DefineOp> {
LogicalResult LogicalResult
matchAndRewrite(arc::DefineOp op, OpAdaptor adaptor, matchAndRewrite(arc::DefineOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const final { ConversionPatternRewriter &rewriter) const final {
auto func = rewriter.create<mlir::func::FuncOp>(op.getLoc(), op.getName(), auto func = mlir::func::FuncOp::create(rewriter, op.getLoc(), op.getName(),
op.getFunctionType()); op.getFunctionType());
func->setAttr( func->setAttr(
"llvm.linkage", "llvm.linkage",
LLVM::LinkageAttr::get(getContext(), LLVM::linkage::Linkage::Internal)); LLVM::LinkageAttr::get(getContext(), LLVM::linkage::Linkage::Internal));

View File

@ -125,7 +125,7 @@ LogicalResult LowerClocksToFuncsPass::lowerClock(Operation *clockOp,
// Add a return op to the end of the body. // Add a return op to the end of the body.
auto builder = OpBuilder::atBlockEnd(&clockRegion.front()); auto builder = OpBuilder::atBlockEnd(&clockRegion.front());
builder.create<func::ReturnOp>(clockOp->getLoc()); func::ReturnOp::create(builder, clockOp->getLoc());
// Pick a name for the clock function. // Pick a name for the clock function.
SmallString<32> funcName; SmallString<32> funcName;
@ -137,8 +137,8 @@ LogicalResult LowerClocksToFuncsPass::lowerClock(Operation *clockOp,
else if (isa<FinalOp>(clockOp)) else if (isa<FinalOp>(clockOp))
funcName.append("_final"); funcName.append("_final");
auto funcOp = funcBuilder.create<func::FuncOp>( auto funcOp = func::FuncOp::create(
clockOp->getLoc(), funcName, funcBuilder, clockOp->getLoc(), funcName,
builder.getFunctionType({modelStorageArg.getType()}, {})); builder.getFunctionType({modelStorageArg.getType()}, {}));
symbolTable->insert(funcOp); // uniquifies the name symbolTable->insert(funcOp); // uniquifies the name
LLVM_DEBUG(llvm::dbgs() << " - Created function `" << funcOp.getSymName() LLVM_DEBUG(llvm::dbgs() << " - Created function `" << funcOp.getSymName()

View File

@ -170,7 +170,7 @@ void LutCalculator::getTableEntriesAsConstValues(
DenseMap<IntegerAttr, Value> map; DenseMap<IntegerAttr, Value> map;
for (auto entry : table) { for (auto entry : table) {
if (!map.count(entry)) if (!map.count(entry))
map[entry] = builder.create<hw::ConstantOp>(lut.getLoc(), entry); map[entry] = hw::ConstantOp::create(builder, lut.getLoc(), entry);
tableEntries.push_back(map[entry]); tableEntries.push_back(map[entry]);
} }
@ -225,26 +225,27 @@ struct LutToInteger : OpConversionPattern<LutOp> {
result.insertBits(chunk, nextInsertion); result.insertBits(chunk, nextInsertion);
} }
Value table = rewriter.create<hw::ConstantOp>(lut.getLoc(), result); Value table = hw::ConstantOp::create(rewriter, lut.getLoc(), result);
// Zero-extend the lookup/index value to the same bit-width as the table, // Zero-extend the lookup/index value to the same bit-width as the table,
// because the shift operation requires both operands to have the same // because the shift operation requires both operands to have the same
// bit-width. // bit-width.
Value zextValue = rewriter.create<hw::ConstantOp>( Value zextValue =
lut->getLoc(), rewriter.getIntegerType(tableSize - inputBw), 0); hw::ConstantOp::create(rewriter, lut->getLoc(),
Value entryOffset = rewriter.create<comb::ConcatOp>(lut.getLoc(), zextValue, rewriter.getIntegerType(tableSize - inputBw), 0);
lut.getInputs()); Value entryOffset = comb::ConcatOp::create(rewriter, lut.getLoc(),
Value resultBitWidth = rewriter.create<hw::ConstantOp>( zextValue, lut.getInputs());
lut.getLoc(), entryOffset.getType(), Value resultBitWidth = hw::ConstantOp::create(
rewriter, lut.getLoc(), entryOffset.getType(),
lut.getResult().getType().getIntOrFloatBitWidth()); lut.getResult().getType().getIntOrFloatBitWidth());
Value lookupValue = Value lookupValue = comb::MulOp::create(rewriter, lut.getLoc(), entryOffset,
rewriter.create<comb::MulOp>(lut.getLoc(), entryOffset, resultBitWidth); resultBitWidth);
// Shift the table and truncate to the bitwidth of the output value. // Shift the table and truncate to the bitwidth of the output value.
Value shiftedTable = Value shiftedTable =
rewriter.create<comb::ShrUOp>(lut->getLoc(), table, lookupValue); comb::ShrUOp::create(rewriter, lut->getLoc(), table, lookupValue);
const Value extracted = rewriter.create<comb::ExtractOp>( const Value extracted = comb::ExtractOp::create(
lut.getLoc(), shiftedTable, 0, rewriter, lut.getLoc(), shiftedTable, 0,
lut.getOutput().getType().getIntOrFloatBitWidth()); lut.getOutput().getType().getIntOrFloatBitWidth());
rewriter.replaceOp(lut, extracted); rewriter.replaceOp(lut, extracted);
@ -275,13 +276,15 @@ struct LutToArray : OpConversionPattern<LutOp> {
if (tableSize <= 256) if (tableSize <= 256)
return failure(); return failure();
Value table = rewriter.create<hw::AggregateConstantOp>( Value table = hw::AggregateConstantOp::create(
lut.getLoc(), hw::ArrayType::get(lut.getType(), constantAttrs.size()), rewriter, lut.getLoc(),
hw::ArrayType::get(lut.getType(), constantAttrs.size()),
rewriter.getArrayAttr(constantAttrs)); rewriter.getArrayAttr(constantAttrs));
Value lookupValue = rewriter.create<comb::ConcatOp>( Value lookupValue = comb::ConcatOp::create(rewriter, lut.getLoc(),
lut.getLoc(), rewriter.getIntegerType(inputBw), lut.getInputs()); rewriter.getIntegerType(inputBw),
lut.getInputs());
const Value extracted = const Value extracted =
rewriter.create<hw::ArrayGetOp>(lut.getLoc(), table, lookupValue); hw::ArrayGetOp::create(rewriter, lut.getLoc(), table, lookupValue);
rewriter.replaceOp(lut, extracted); rewriter.replaceOp(lut, extracted);
return success(); return success();

View File

@ -190,9 +190,9 @@ LogicalResult ModuleLowering::run() {
// Create the replacement `ModelOp`. // Create the replacement `ModelOp`.
auto modelOp = auto modelOp =
builder.create<ModelOp>(moduleOp.getLoc(), moduleOp.getModuleNameAttr(), ModelOp::create(builder, moduleOp.getLoc(), moduleOp.getModuleNameAttr(),
TypeAttr::get(moduleOp.getModuleType()), TypeAttr::get(moduleOp.getModuleType()),
FlatSymbolRefAttr{}, FlatSymbolRefAttr{}); FlatSymbolRefAttr{}, FlatSymbolRefAttr{});
auto &modelBlock = modelOp.getBody().emplaceBlock(); auto &modelBlock = modelOp.getBody().emplaceBlock();
storageArg = modelBlock.addArgument( storageArg = modelBlock.addArgument(
StorageType::get(builder.getContext(), {}), modelOp.getLoc()); StorageType::get(builder.getContext(), {}), modelOp.getLoc());
@ -200,11 +200,11 @@ LogicalResult ModuleLowering::run() {
// Create the `arc.initial` op to contain the ops for the initialization // Create the `arc.initial` op to contain the ops for the initialization
// phase. // phase.
auto initialOp = builder.create<InitialOp>(moduleOp.getLoc()); auto initialOp = InitialOp::create(builder, moduleOp.getLoc());
initialBuilder.setInsertionPointToStart(&initialOp.getBody().emplaceBlock()); initialBuilder.setInsertionPointToStart(&initialOp.getBody().emplaceBlock());
// Create the `arc.final` op to contain the ops for the finalization phase. // Create the `arc.final` op to contain the ops for the finalization phase.
auto finalOp = builder.create<FinalOp>(moduleOp.getLoc()); auto finalOp = FinalOp::create(builder, moduleOp.getLoc());
finalBuilder.setInsertionPointToStart(&finalOp.getBody().emplaceBlock()); finalBuilder.setInsertionPointToStart(&finalOp.getBody().emplaceBlock());
// Position the alloc builder such that allocation ops get inserted above the // Position the alloc builder such that allocation ops get inserted above the
@ -214,8 +214,9 @@ LogicalResult ModuleLowering::run() {
// Allocate storage for the inputs. // Allocate storage for the inputs.
for (auto arg : moduleOp.getBodyBlock()->getArguments()) { for (auto arg : moduleOp.getBodyBlock()->getArguments()) {
auto name = moduleOp.getArgName(arg.getArgNumber()); auto name = moduleOp.getArgName(arg.getArgNumber());
auto state = allocBuilder.create<RootInputOp>( auto state =
arg.getLoc(), StateType::get(arg.getType()), name, storageArg); RootInputOp::create(allocBuilder, arg.getLoc(),
StateType::get(arg.getType()), name, storageArg);
allocatedInputs.push_back(state); allocatedInputs.push_back(state);
} }
@ -315,15 +316,17 @@ Value ModuleLowering::getAllocatedState(OpResult result) {
// Handle memories. // Handle memories.
if (auto memOp = dyn_cast<MemoryOp>(result.getOwner())) { if (auto memOp = dyn_cast<MemoryOp>(result.getOwner())) {
auto alloc = allocBuilder.create<AllocMemoryOp>( auto alloc =
memOp.getLoc(), memOp.getType(), storageArg, memOp->getAttrs()); AllocMemoryOp::create(allocBuilder, memOp.getLoc(), memOp.getType(),
storageArg, memOp->getAttrs());
allocatedStates.insert({result, alloc}); allocatedStates.insert({result, alloc});
return alloc; return alloc;
} }
// Create the allocation op. // Create the allocation op.
auto alloc = allocBuilder.create<AllocStateOp>( auto alloc =
result.getLoc(), StateType::get(result.getType()), storageArg); AllocStateOp::create(allocBuilder, result.getLoc(),
StateType::get(result.getType()), storageArg);
allocatedStates.insert({result, alloc}); allocatedStates.insert({result, alloc});
// HACK: If the result comes from an instance op, add the instance and port // HACK: If the result comes from an instance op, add the instance and port
@ -351,20 +354,20 @@ Value ModuleLowering::getAllocatedState(OpResult result) {
Value ModuleLowering::detectPosedge(Value clock) { Value ModuleLowering::detectPosedge(Value clock) {
auto loc = clock.getLoc(); auto loc = clock.getLoc();
if (isa<seq::ClockType>(clock.getType())) if (isa<seq::ClockType>(clock.getType()))
clock = builder.create<seq::FromClockOp>(loc, clock); clock = seq::FromClockOp::create(builder, loc, clock);
// Allocate storage to store the previous clock value. // Allocate storage to store the previous clock value.
auto oldStorage = allocBuilder.create<AllocStateOp>( auto oldStorage = AllocStateOp::create(
loc, StateType::get(builder.getI1Type()), storageArg); allocBuilder, loc, StateType::get(builder.getI1Type()), storageArg);
// Read the old clock value from storage and write the new clock value to // Read the old clock value from storage and write the new clock value to
// storage. // storage.
auto oldClock = builder.create<StateReadOp>(loc, oldStorage); auto oldClock = StateReadOp::create(builder, loc, oldStorage);
builder.create<StateWriteOp>(loc, oldStorage, clock, Value{}); StateWriteOp::create(builder, loc, oldStorage, clock, Value{});
// Detect a rising edge. // Detect a rising edge.
auto edge = builder.create<comb::XorOp>(loc, oldClock, clock); auto edge = comb::XorOp::create(builder, loc, oldClock, clock);
return builder.create<comb::AndOp>(loc, edge, clock); return comb::AndOp::create(builder, loc, edge, clock);
} }
/// Get the builder appropriate for the given phase. /// Get the builder appropriate for the given phase.
@ -402,7 +405,7 @@ static scf::IfOp createOrReuseIf(OpBuilder &builder, Value condition,
if (auto ifOp = dyn_cast<scf::IfOp>(*std::prev(ip))) if (auto ifOp = dyn_cast<scf::IfOp>(*std::prev(ip)))
if (ifOp.getCondition() == condition) if (ifOp.getCondition() == condition)
return ifOp; return ifOp;
return builder.create<scf::IfOp>(condition.getLoc(), condition, withElse); return scf::IfOp::create(builder, condition.getLoc(), condition, withElse);
} }
/// This function is called from the lowering worklist in order to perform a /// This function is called from the lowering worklist in order to perform a
@ -483,8 +486,8 @@ LogicalResult OpLowering::lower(StateOp op) {
auto state = module.getAllocatedState(result); auto state = module.getAllocatedState(result);
if (!state) if (!state)
return failure(); return failure();
module.initialBuilder.create<StateWriteOp>(value.getLoc(), state, value, StateWriteOp::create(module.initialBuilder, value.getLoc(), state, value,
Value{}); Value{});
} }
return success(); return success();
} }
@ -500,9 +503,9 @@ LogicalResult OpLowering::lower(StateOp op) {
return lowerStateful(op.getClock(), op.getEnable(), op.getReset(), return lowerStateful(op.getClock(), op.getEnable(), op.getReset(),
op.getInputs(), op.getResults(), [&](ValueRange inputs) { op.getInputs(), op.getResults(), [&](ValueRange inputs) {
return module.builder return CallOp::create(module.builder, op.getLoc(),
.create<CallOp>(op.getLoc(), op.getResultTypes(), op.getResultTypes(), op.getArc(),
op.getArc(), inputs) inputs)
.getResults(); .getResults();
}); });
} }
@ -526,8 +529,9 @@ LogicalResult OpLowering::lower(sim::DPICallOp op) {
return op.emitOpError() << "without clock cannot have an enable"; return op.emitOpError() << "without clock cannot have an enable";
// Lower the op to a regular function call. // Lower the op to a regular function call.
auto callOp = module.getBuilder(phase).create<func::CallOp>( auto callOp =
op.getLoc(), op.getCalleeAttr(), op.getResultTypes(), inputs); func::CallOp::create(module.getBuilder(phase), op.getLoc(),
op.getCalleeAttr(), op.getResultTypes(), inputs);
for (auto [oldResult, newResult] : for (auto [oldResult, newResult] :
llvm::zip(op.getResults(), callOp.getResults())) llvm::zip(op.getResults(), callOp.getResults()))
module.loweredValues[{oldResult, phase}] = newResult; module.loweredValues[{oldResult, phase}] = newResult;
@ -538,10 +542,10 @@ LogicalResult OpLowering::lower(sim::DPICallOp op) {
return lowerStateful(op.getClock(), op.getEnable(), /*reset=*/{}, return lowerStateful(op.getClock(), op.getEnable(), /*reset=*/{},
op.getInputs(), op.getResults(), [&](ValueRange inputs) { op.getInputs(), op.getResults(), [&](ValueRange inputs) {
return module.builder return func::CallOp::create(
.create<func::CallOp>(op.getLoc(), module.builder, op.getLoc(),
op.getCalleeAttr(), op.getCalleeAttr(), op.getResultTypes(),
op.getResultTypes(), inputs) inputs)
.getResults(); .getResults();
}); });
} }
@ -607,14 +611,14 @@ LogicalResult OpLowering::lowerStateful(
// Generate the zero value writes. // Generate the zero value writes.
for (auto state : states) { for (auto state : states) {
auto type = cast<StateType>(state.getType()).getType(); auto type = cast<StateType>(state.getType()).getType();
Value value = module.builder.create<ConstantOp>( Value value = ConstantOp::create(
loweredReset.getLoc(), module.builder, loweredReset.getLoc(),
module.builder.getIntegerType(hw::getBitWidth(type)), 0); module.builder.getIntegerType(hw::getBitWidth(type)), 0);
if (value.getType() != type) if (value.getType() != type)
value = module.builder.create<BitcastOp>(loweredReset.getLoc(), type, value = BitcastOp::create(module.builder, loweredReset.getLoc(), type,
value); value);
module.builder.create<StateWriteOp>(loweredReset.getLoc(), state, value, StateWriteOp::create(module.builder, loweredReset.getLoc(), state, value,
Value{}); Value{});
} }
module.builder.setInsertionPoint(ifResetOp.elseYield()); module.builder.setInsertionPoint(ifResetOp.elseYield());
} }
@ -649,14 +653,14 @@ LogicalResult OpLowering::lowerStateful(
// Compute the transfer function and write its results to the state's storage. // Compute the transfer function and write its results to the state's storage.
auto loweredResults = createMapping(loweredInputs); auto loweredResults = createMapping(loweredInputs);
for (auto [state, value] : llvm::zip(states, loweredResults)) for (auto [state, value] : llvm::zip(states, loweredResults))
module.builder.create<StateWriteOp>(value.getLoc(), state, value, Value{}); StateWriteOp::create(module.builder, value.getLoc(), state, value, Value{});
// Since we just wrote the new state value to storage, insert read ops just // Since we just wrote the new state value to storage, insert read ops just
// before the if op that keep the old value around for any later ops that // before the if op that keep the old value around for any later ops that
// still need it. // still need it.
module.builder.setInsertionPoint(ifClockOp); module.builder.setInsertionPoint(ifClockOp);
for (auto [state, result] : llvm::zip(states, results)) { for (auto [state, result] : llvm::zip(states, results)) {
auto oldValue = module.builder.create<StateReadOp>(result.getLoc(), state); auto oldValue = StateReadOp::create(module.builder, result.getLoc(), state);
module.loweredValues[{result, Phase::Old}] = oldValue; module.loweredValues[{result, Phase::Old}] = oldValue;
} }
@ -734,8 +738,9 @@ LogicalResult OpLowering::lower(MemoryOp op) {
return failure(); return failure();
inputs.push_back(lowered); inputs.push_back(lowered);
} }
auto callOp = module.builder.create<CallOp>( auto callOp =
write.getLoc(), write.getArcResultTypes(), write.getArc(), inputs); CallOp::create(module.builder, write.getLoc(),
write.getArcResultTypes(), write.getArc(), inputs);
// If the write has an enable, wrap the remaining logic in an if op. // If the write has an enable, wrap the remaining logic in an if op.
if (write.getEnable()) { if (write.getEnable()) {
@ -752,21 +757,22 @@ LogicalResult OpLowering::lower(MemoryOp op) {
auto mask = callOp.getResult(write.getMaskIdx(write.getEnable())); auto mask = callOp.getResult(write.getMaskIdx(write.getEnable()));
auto maskInv = module.builder.createOrFold<comb::XorOp>( auto maskInv = module.builder.createOrFold<comb::XorOp>(
write.getLoc(), mask, write.getLoc(), mask,
module.builder.create<ConstantOp>(write.getLoc(), mask.getType(), -1), ConstantOp::create(module.builder, write.getLoc(), mask.getType(),
-1),
true); true);
auto oldData = auto oldData =
module.builder.create<MemoryReadOp>(write.getLoc(), state, address); MemoryReadOp::create(module.builder, write.getLoc(), state, address);
auto oldMasked = module.builder.create<comb::AndOp>( auto oldMasked = comb::AndOp::create(module.builder, write.getLoc(),
write.getLoc(), maskInv, oldData, true); maskInv, oldData, true);
auto newMasked = auto newMasked =
module.builder.create<comb::AndOp>(write.getLoc(), mask, data, true); comb::AndOp::create(module.builder, write.getLoc(), mask, data, true);
data = module.builder.create<comb::OrOp>(write.getLoc(), oldMasked, data = comb::OrOp::create(module.builder, write.getLoc(), oldMasked,
newMasked, true); newMasked, true);
} }
// Actually write to the memory. // Actually write to the memory.
module.builder.create<MemoryWriteOp>(write.getLoc(), state, address, MemoryWriteOp::create(module.builder, write.getLoc(), state, address,
Value{}, data); Value{}, data);
} }
return success(); return success();
@ -785,12 +791,13 @@ LogicalResult OpLowering::lower(TapOp op) {
auto &state = module.allocatedTaps[op]; auto &state = module.allocatedTaps[op];
if (!state) { if (!state) {
auto alloc = module.allocBuilder.create<AllocStateOp>( auto alloc = AllocStateOp::create(module.allocBuilder, op.getLoc(),
op.getLoc(), StateType::get(value.getType()), module.storageArg, true); StateType::get(value.getType()),
module.storageArg, true);
alloc->setAttr("name", op.getNameAttr()); alloc->setAttr("name", op.getNameAttr());
state = alloc; state = alloc;
} }
module.builder.create<StateWriteOp>(op.getLoc(), state, value, Value{}); StateWriteOp::create(module.builder, op.getLoc(), state, value, Value{});
return success(); return success();
} }
@ -812,12 +819,13 @@ LogicalResult OpLowering::lower(InstanceOp op) {
// Then allocate storage for each instance input and assign the corresponding // Then allocate storage for each instance input and assign the corresponding
// value. // value.
for (auto [value, name] : llvm::zip(values, op.getArgNames())) { for (auto [value, name] : llvm::zip(values, op.getArgNames())) {
auto state = module.allocBuilder.create<AllocStateOp>( auto state = AllocStateOp::create(module.allocBuilder, value.getLoc(),
value.getLoc(), StateType::get(value.getType()), module.storageArg); StateType::get(value.getType()),
module.storageArg);
state->setAttr("name", module.builder.getStringAttr( state->setAttr("name", module.builder.getStringAttr(
op.getInstanceName() + "/" + op.getInstanceName() + "/" +
cast<StringAttr>(name).getValue())); cast<StringAttr>(name).getValue()));
module.builder.create<StateWriteOp>(value.getLoc(), state, value, Value{}); StateWriteOp::create(module.builder, value.getLoc(), state, value, Value{});
} }
// HACK: Also ensure that storage has been allocated for all outputs. // HACK: Also ensure that storage has been allocated for all outputs.
@ -847,10 +855,10 @@ LogicalResult OpLowering::lower(hw::OutputOp op) {
// Then allocate storage for each output and assign the corresponding value. // Then allocate storage for each output and assign the corresponding value.
for (auto [value, name] : for (auto [value, name] :
llvm::zip(values, module.moduleOp.getOutputNames())) { llvm::zip(values, module.moduleOp.getOutputNames())) {
auto state = module.allocBuilder.create<RootOutputOp>( auto state = RootOutputOp::create(
value.getLoc(), StateType::get(value.getType()), cast<StringAttr>(name), module.allocBuilder, value.getLoc(), StateType::get(value.getType()),
module.storageArg); cast<StringAttr>(name), module.storageArg);
module.builder.create<StateWriteOp>(value.getLoc(), state, value, Value{}); StateWriteOp::create(module.builder, value.getLoc(), state, value, Value{});
} }
return success(); return success();
} }
@ -947,12 +955,13 @@ LogicalResult OpLowering::lower(llhd::FinalOp op) {
// Create a new `scf.execute_region` op and clone the entire `llhd.final` body // Create a new `scf.execute_region` op and clone the entire `llhd.final` body
// region into it. Replace `llhd.halt` ops with `scf.yield`. // region into it. Replace `llhd.halt` ops with `scf.yield`.
auto executeOp = module.finalBuilder.create<scf::ExecuteRegionOp>( auto executeOp = scf::ExecuteRegionOp::create(module.finalBuilder,
op.getLoc(), TypeRange{}); op.getLoc(), TypeRange{});
module.finalBuilder.cloneRegionBefore(op.getBody(), executeOp.getRegion(), module.finalBuilder.cloneRegionBefore(op.getBody(), executeOp.getRegion(),
executeOp.getRegion().begin(), mapping); executeOp.getRegion().begin(), mapping);
executeOp.walk([&](llhd::HaltOp op) { executeOp.walk([&](llhd::HaltOp op) {
OpBuilder(op).create<scf::YieldOp>(op.getLoc()); auto builder = OpBuilder(op);
scf::YieldOp::create(builder, op.getLoc());
op.erase(); op.erase();
}); });
@ -988,7 +997,7 @@ Value OpLowering::lowerValue(Value value, Phase phase) {
if (initial) if (initial)
return {}; return {};
auto state = module.allocatedInputs[arg.getArgNumber()]; auto state = module.allocatedInputs[arg.getArgNumber()];
return module.getBuilder(phase).create<StateReadOp>(arg.getLoc(), state); return StateReadOp::create(module.getBuilder(phase), arg.getLoc(), state);
} }
// Check if the value has already been lowered. // Check if the value has already been lowered.
@ -1031,7 +1040,7 @@ Value OpLowering::lowerValue(InstanceOp op, OpResult result, Phase phase) {
if (initial) if (initial)
return {}; return {};
auto state = module.getAllocatedState(result); auto state = module.getAllocatedState(result);
return module.getBuilder(phase).create<StateReadOp>(result.getLoc(), state); return StateReadOp::create(module.getBuilder(phase), result.getLoc(), state);
} }
/// Handle uses of a state. This creates an `arc.state_read` op to read from the /// Handle uses of a state. This creates an `arc.state_read` op to read from the
@ -1053,7 +1062,7 @@ Value OpLowering::lowerValue(StateOp op, OpResult result, Phase phase) {
"need old value but new value already written"); "need old value but new value already written");
auto state = module.getAllocatedState(result); auto state = module.getAllocatedState(result);
return module.getBuilder(phase).create<StateReadOp>(result.getLoc(), state); return StateReadOp::create(module.getBuilder(phase), result.getLoc(), state);
} }
/// Handle uses of a DPI call. This creates an `arc.state_read` op to read from /// Handle uses of a DPI call. This creates an `arc.state_read` op to read from
@ -1075,7 +1084,7 @@ Value OpLowering::lowerValue(sim::DPICallOp op, OpResult result, Phase phase) {
"need old value but new value already written"); "need old value but new value already written");
auto state = module.getAllocatedState(result); auto state = module.getAllocatedState(result);
return module.getBuilder(phase).create<StateReadOp>(result.getLoc(), state); return StateReadOp::create(module.getBuilder(phase), result.getLoc(), state);
} }
/// Handle uses of a memory read operation. This creates an `arc.memory_read` op /// Handle uses of a memory read operation. This creates an `arc.memory_read` op
@ -1109,8 +1118,8 @@ Value OpLowering::lowerValue(MemoryReadPortOp op, OpResult result,
} }
auto state = module.getAllocatedState(memOp->getResult(0)); auto state = module.getAllocatedState(memOp->getResult(0));
return module.getBuilder(phase).create<MemoryReadOp>(result.getLoc(), state, return MemoryReadOp::create(module.getBuilder(phase), result.getLoc(), state,
address); address);
} }
/// Handle uses of `seq.initial` values computed during the initial phase. This /// Handle uses of `seq.initial` values computed during the initial phase. This
@ -1137,16 +1146,17 @@ Value OpLowering::lowerValue(seq::InitialOp op, OpResult result, Phase phase) {
// initial phase. // initial phase.
auto &state = module.allocatedInitials[result]; auto &state = module.allocatedInitials[result];
if (!state) { if (!state) {
state = module.allocBuilder.create<AllocStateOp>( state = AllocStateOp::create(module.allocBuilder, value.getLoc(),
value.getLoc(), StateType::get(value.getType()), module.storageArg); StateType::get(value.getType()),
module.storageArg);
OpBuilder::InsertionGuard guard(module.initialBuilder); OpBuilder::InsertionGuard guard(module.initialBuilder);
module.initialBuilder.setInsertionPointAfterValue(value); module.initialBuilder.setInsertionPointAfterValue(value);
module.initialBuilder.create<StateWriteOp>(value.getLoc(), state, value, StateWriteOp::create(module.initialBuilder, value.getLoc(), state, value,
Value{}); Value{});
} }
// Read back the value computed during the initial phase. // Read back the value computed during the initial phase.
return module.getBuilder(phase).create<StateReadOp>(state.getLoc(), state); return StateReadOp::create(module.getBuilder(phase), state.getLoc(), state);
} }
/// The `seq.from_immutable` cast is just a passthrough. /// The `seq.from_immutable` cast is just a passthrough.

View File

@ -57,20 +57,20 @@ static VectorizeOp lowerBoundaryScalar(VectorizeOp op) {
for (ValueRange range : op.getInputs()) { for (ValueRange range : op.getInputs()) {
unsigned bw = range.front().getType().getIntOrFloatBitWidth(); unsigned bw = range.front().getType().getIntOrFloatBitWidth();
vectors.push_back(builder vectors.push_back(
.create<comb::ConcatOp>( comb::ConcatOp::create(builder,
builder.getIntegerType(bw * range.size()), range) builder.getIntegerType(bw * range.size()), range)
->getResults()); ->getResults());
} }
unsigned width = op->getResult(0).getType().getIntOrFloatBitWidth(); unsigned width = op->getResult(0).getType().getIntOrFloatBitWidth();
VectorizeOp newOp = builder.create<VectorizeOp>( VectorizeOp newOp = VectorizeOp::create(
builder.getIntegerType(width * op->getNumResults()), vectors); builder, builder.getIntegerType(width * op->getNumResults()), vectors);
newOp.getBody().takeBody(op.getBody()); newOp.getBody().takeBody(op.getBody());
for (OpResult res : op.getResults()) { for (OpResult res : op.getResults()) {
Value newRes = builder.create<comb::ExtractOp>( Value newRes = comb::ExtractOp::create(
newOp.getResult(0), width * res.getResultNumber(), width); builder, newOp.getResult(0), width * res.getResultNumber(), width);
res.replaceAllUsesWith(newRes); res.replaceAllUsesWith(newRes);
} }
@ -119,21 +119,22 @@ static VectorizeOp lowerBoundaryVector(VectorizeOp op) {
range.front().getType()); range.front().getType());
if (llvm::all_equal(range)) { if (llvm::all_equal(range)) {
vectors.push_back( vectors.push_back(
builder.create<vector::BroadcastOp>(type, range.front()) vector::BroadcastOp::create(builder, type, range.front())
->getResults()); ->getResults());
continue; continue;
} }
// Otherwise do a gather. // Otherwise do a gather.
ValueRange vector = ValueRange vector =
builder arith::ConstantOp::create(
.create<arith::ConstantOp>(DenseElementsAttr::get( builder,
DenseElementsAttr::get(
type, SmallVector<Attribute>( type, SmallVector<Attribute>(
range.size(), range.size(),
builder.getIntegerAttr(type.getElementType(), 0)))) builder.getIntegerAttr(type.getElementType(), 0))))
->getResults(); ->getResults();
for (auto [i, element] : llvm::enumerate(range)) for (auto [i, element] : llvm::enumerate(range))
vector = builder.create<vector::InsertOp>(element, vector.front(), i) vector = vector::InsertOp::create(builder, element, vector.front(), i)
->getResults(); ->getResults();
vectors.push_back(vector); vectors.push_back(vector);
@ -141,12 +142,12 @@ static VectorizeOp lowerBoundaryVector(VectorizeOp op) {
VectorType resType = VectorType::get( VectorType resType = VectorType::get(
SmallVector<int64_t>(1, op->getNumResults()), op.getResult(0).getType()); SmallVector<int64_t>(1, op->getNumResults()), op.getResult(0).getType());
VectorizeOp newOp = builder.create<VectorizeOp>(resType, vectors); VectorizeOp newOp = VectorizeOp::create(builder, resType, vectors);
newOp.getBody().takeBody(op.getBody()); newOp.getBody().takeBody(op.getBody());
for (OpResult res : op.getResults()) for (OpResult res : op.getResults())
res.replaceAllUsesWith(builder.create<vector::ExtractOp>( res.replaceAllUsesWith(vector::ExtractOp::create(
newOp.getResult(0), res.getResultNumber())); builder, newOp.getResult(0), res.getResultNumber()));
op->erase(); op->erase();
return newOp; return newOp;

View File

@ -59,8 +59,9 @@ void LowerVerifSimulationsPass::runOnOperation() {
return signalPassFailure(); return signalPassFailure();
} }
} else { } else {
auto func = builder.create<func::FuncOp>( auto func =
getOperation().getLoc(), builder.getStringAttr("exit"), exitFuncType); func::FuncOp::create(builder, getOperation().getLoc(),
builder.getStringAttr("exit"), exitFuncType);
SymbolTable::setSymbolVisibility(func, SymbolTable::Visibility::Private); SymbolTable::setSymbolVisibility(func, SymbolTable::Visibility::Private);
} }
@ -108,7 +109,7 @@ void LowerVerifSimulationsPass::lowerSimulation(verif::SimulationOp op,
// Replace the `verif.yield` operation with an `hw.output`. // Replace the `verif.yield` operation with an `hw.output`.
OpBuilder builder(yieldOp); OpBuilder builder(yieldOp);
builder.create<hw::OutputOp>(yieldOp->getLoc(), yieldOp->getOperands()); hw::OutputOp::create(builder, yieldOp->getLoc(), yieldOp->getOperands());
yieldOp->erase(); yieldOp->erase();
// Move the body of the simulation into a separate HW module. // Move the body of the simulation into a separate HW module.
@ -116,25 +117,25 @@ void LowerVerifSimulationsPass::lowerSimulation(verif::SimulationOp op,
auto implName = StringAttr::get(context, Twine("verif.simulation.impl.") + auto implName = StringAttr::get(context, Twine("verif.simulation.impl.") +
op.getSymName()); op.getSymName());
auto loc = op.getLoc(); auto loc = op.getLoc();
auto implOp = builder.create<hw::HWModuleOp>(loc, implName, implPorts); auto implOp = hw::HWModuleOp::create(builder, loc, implName, implPorts);
symbolTable.insert(implOp); symbolTable.insert(implOp);
implOp.getBody().takeBody(op.getBodyRegion()); implOp.getBody().takeBody(op.getBodyRegion());
// Create a new function for the verification op. // Create a new function for the verification op.
auto funcType = builder.getFunctionType({}, {}); auto funcType = builder.getFunctionType({}, {});
auto funcOp = auto funcOp =
builder.create<func::FuncOp>(loc, op.getSymNameAttr(), funcType); func::FuncOp::create(builder, loc, op.getSymNameAttr(), funcType);
auto *funcBody = builder.createBlock(&funcOp.getBody()); auto *funcBody = builder.createBlock(&funcOp.getBody());
auto falseOp = builder.create<hw::ConstantOp>(loc, i1Type, 0); auto falseOp = hw::ConstantOp::create(builder, loc, i1Type, 0);
auto trueOp = builder.create<hw::ConstantOp>(loc, i1Type, 1); auto trueOp = hw::ConstantOp::create(builder, loc, i1Type, 1);
auto lowOp = builder.create<seq::ToClockOp>(loc, falseOp); auto lowOp = seq::ToClockOp::create(builder, loc, falseOp);
auto highOp = builder.create<seq::ToClockOp>(loc, trueOp); auto highOp = seq::ToClockOp::create(builder, loc, trueOp);
// Instantiate the implementation module. // Instantiate the implementation module.
auto instType = SimModelInstanceType::get( auto instType = SimModelInstanceType::get(
context, FlatSymbolRefAttr::get(implOp.getSymNameAttr())); context, FlatSymbolRefAttr::get(implOp.getSymNameAttr()));
auto instOp = builder.create<SimInstantiateOp>(loc); auto instOp = SimInstantiateOp::create(builder, loc);
auto *instBody = auto *instBody =
builder.createBlock(&instOp.getBody(), {}, {instType}, {loc}); builder.createBlock(&instOp.getBody(), {}, {instType}, {loc});
auto instArg = instBody->getArgument(0); auto instArg = instBody->getArgument(0);
@ -142,57 +143,57 @@ void LowerVerifSimulationsPass::lowerSimulation(verif::SimulationOp op,
// Create an `scf.execute_region` op inside such that we can use simple // Create an `scf.execute_region` op inside such that we can use simple
// control flow in the `arc.sim.instantiate` op body. This is simpler than // control flow in the `arc.sim.instantiate` op body. This is simpler than
// setting up an `scf.while` op. // setting up an `scf.while` op.
auto execOp = builder.create<scf::ExecuteRegionOp>(loc, TypeRange{}); auto execOp = scf::ExecuteRegionOp::create(builder, loc, TypeRange{});
builder.setInsertionPointToEnd(&execOp.getRegion().emplaceBlock()); builder.setInsertionPointToEnd(&execOp.getRegion().emplaceBlock());
// Apply the initial clock tick to the design. // Apply the initial clock tick to the design.
builder.create<SimSetInputOp>(loc, instArg, clockName, lowOp); SimSetInputOp::create(builder, loc, instArg, clockName, lowOp);
builder.create<SimSetInputOp>(loc, instArg, initName, trueOp); SimSetInputOp::create(builder, loc, instArg, initName, trueOp);
builder.create<SimStepOp>(loc, instArg); SimStepOp::create(builder, loc, instArg);
builder.create<SimSetInputOp>(loc, instArg, clockName, highOp); SimSetInputOp::create(builder, loc, instArg, clockName, highOp);
builder.create<SimStepOp>(loc, instArg); SimStepOp::create(builder, loc, instArg);
builder.create<SimSetInputOp>(loc, instArg, clockName, lowOp); SimSetInputOp::create(builder, loc, instArg, clockName, lowOp);
builder.create<SimSetInputOp>(loc, instArg, initName, falseOp); SimSetInputOp::create(builder, loc, instArg, initName, falseOp);
builder.create<SimStepOp>(loc, instArg); SimStepOp::create(builder, loc, instArg);
// Create the block that will perform a single clock tick. // Create the block that will perform a single clock tick.
auto &loopBlock = execOp.getRegion().emplaceBlock(); auto &loopBlock = execOp.getRegion().emplaceBlock();
builder.create<cf::BranchOp>(loc, &loopBlock); cf::BranchOp::create(builder, loc, &loopBlock);
builder.setInsertionPointToEnd(&loopBlock); builder.setInsertionPointToEnd(&loopBlock);
// Sample the done and success signals. // Sample the done and success signals.
auto doneSample = auto doneSample =
builder.create<SimGetPortOp>(loc, i1Type, instArg, doneName); SimGetPortOp::create(builder, loc, i1Type, instArg, doneName);
auto successSample = auto successSample =
builder.create<SimGetPortOp>(loc, i1Type, instArg, successName); SimGetPortOp::create(builder, loc, i1Type, instArg, successName);
// Apply a full clock cycle to the design. // Apply a full clock cycle to the design.
builder.create<SimSetInputOp>(loc, instArg, clockName, highOp); SimSetInputOp::create(builder, loc, instArg, clockName, highOp);
builder.create<SimStepOp>(loc, instArg); SimStepOp::create(builder, loc, instArg);
builder.create<SimSetInputOp>(loc, instArg, clockName, lowOp); SimSetInputOp::create(builder, loc, instArg, clockName, lowOp);
builder.create<SimStepOp>(loc, instArg); SimStepOp::create(builder, loc, instArg);
// If done, exit the loop. // If done, exit the loop.
auto &exitBlock = execOp.getRegion().emplaceBlock(); auto &exitBlock = execOp.getRegion().emplaceBlock();
builder.create<cf::CondBranchOp>(loc, doneSample, &exitBlock, &loopBlock); cf::CondBranchOp::create(builder, loc, doneSample, &exitBlock, &loopBlock);
builder.setInsertionPointToEnd(&exitBlock); builder.setInsertionPointToEnd(&exitBlock);
// Convert the i1 success signal into an i32 failure signal that can be used // Convert the i1 success signal into an i32 failure signal that can be used
// as an exit code. // as an exit code.
auto i32Type = builder.getI32Type(); auto i32Type = builder.getI32Type();
auto failureI32 = builder.create<arith::ExtUIOp>( auto failureI32 = arith::ExtUIOp::create(
loc, i32Type, builder, loc, i32Type,
builder.create<arith::XOrIOp>( arith::XOrIOp::create(builder, loc, successSample,
loc, successSample, builder.create<hw::ConstantOp>(loc, i1Type, 1))); hw::ConstantOp::create(builder, loc, i1Type, 1)));
// Call exit with the computed exit code. // Call exit with the computed exit code.
builder.create<func::CallOp>(loc, TypeRange{}, builder.getStringAttr("exit"), func::CallOp::create(builder, loc, TypeRange{}, builder.getStringAttr("exit"),
ValueRange{failureI32}); ValueRange{failureI32});
builder.create<scf::YieldOp>(loc); scf::YieldOp::create(builder, loc);
// Create the final function return. // Create the final function return.
builder.setInsertionPointToEnd(funcBody); builder.setInsertionPointToEnd(funcBody);
builder.create<func::ReturnOp>(loc); func::ReturnOp::create(builder, loc);
// Get rid of the original simulation op. // Get rid of the original simulation op.
op.erase(); op.erase();

View File

@ -119,7 +119,7 @@ void MakeTablesPass::runOnArc(DefineOp defineOp) {
SmallVector<Value> inputsToConcat(defineOp.getArguments()); SmallVector<Value> inputsToConcat(defineOp.getArguments());
std::reverse(inputsToConcat.begin(), inputsToConcat.end()); std::reverse(inputsToConcat.begin(), inputsToConcat.end());
auto concatInputs = inputsToConcat.size() > 1 auto concatInputs = inputsToConcat.size() > 1
? builder.create<comb::ConcatOp>(inputsToConcat) ? comb::ConcatOp::create(builder, inputsToConcat)
: inputsToConcat[0]; : inputsToConcat[0];
// Compute a lookup table for every output. // Compute a lookup table for every output.
@ -170,10 +170,10 @@ void MakeTablesPass::runOnArc(DefineOp defineOp) {
// Create the table lookup ops. // Create the table lookup ops.
for (auto [table, outputOperand] : for (auto [table, outputOperand] :
llvm::zip(tables, outputOp->getOpOperands())) { llvm::zip(tables, outputOp->getOpOperands())) {
auto array = builder.create<hw::AggregateConstantOp>( auto array = hw::AggregateConstantOp::create(
ArrayType::get(outputOperand.get().getType(), numTableEntries), builder, ArrayType::get(outputOperand.get().getType(), numTableEntries),
builder.getArrayAttr(table)); builder.getArrayAttr(table));
outputOperand.set(builder.create<hw::ArrayGetOp>(array, concatInputs)); outputOperand.set(hw::ArrayGetOp::create(builder, array, concatInputs));
} }
for (auto *op : tabularizedOps) { for (auto *op : tabularizedOps) {

View File

@ -185,13 +185,13 @@ static void doConversion(Operation *op, BranchInfo info,
// Build the scf.if operation with the scf.yields inside. // Build the scf.if operation with the scf.yields inside.
ImplicitLocOpBuilder builder(op->getLoc(), op); ImplicitLocOpBuilder builder(op->getLoc(), op);
mlir::scf::IfOp ifOp = builder.create<mlir::scf::IfOp>( mlir::scf::IfOp ifOp = mlir::scf::IfOp::create(
info.condition, builder, info.condition,
[&](OpBuilder &builder, Location loc) { [&](OpBuilder &builder, Location loc) {
builder.create<mlir::scf::YieldOp>(loc, info.trueValue); mlir::scf::YieldOp::create(builder, loc, info.trueValue);
}, },
[&](OpBuilder &builder, Location loc) { [&](OpBuilder &builder, Location loc) {
builder.create<mlir::scf::YieldOp>(loc, info.falseValue); mlir::scf::YieldOp::create(builder, loc, info.falseValue);
}); });
op->getResult(0).replaceAllUsesWith(ifOp.getResult(0)); op->getResult(0).replaceAllUsesWith(ifOp.getResult(0));

View File

@ -112,7 +112,7 @@ LogicalResult SplitFuncsPass::lowerFunc(FuncOp funcOp) {
outValues.push_back(el); outValues.push_back(el);
}); });
opBuilder.setInsertionPointToEnd(currentBlock); opBuilder.setInsertionPointToEnd(currentBlock);
opBuilder.create<ReturnOp>(funcOp->getLoc(), outValues); ReturnOp::create(opBuilder, funcOp->getLoc(), outValues);
} }
// Create and populate new FuncOps // Create and populate new FuncOps
for (long unsigned i = 0; i < blocks.size() - 1; ++i) { for (long unsigned i = 0; i < blocks.size() - 1; ++i) {
@ -132,8 +132,8 @@ LogicalResult SplitFuncsPass::lowerFunc(FuncOp funcOp) {
funcName.append("_split_func"); funcName.append("_split_func");
funcName.append(std::to_string(i)); funcName.append(std::to_string(i));
auto newFunc = auto newFunc =
opBuilder.create<FuncOp>(funcOp->getLoc(), funcName, FuncOp::create(opBuilder, funcOp->getLoc(), funcName,
opBuilder.getFunctionType(argTypes, outTypes)); opBuilder.getFunctionType(argTypes, outTypes));
++numFuncsCreated; ++numFuncsCreated;
symbolTable->insert(newFunc); symbolTable->insert(newFunc);
auto *funcBlock = newFunc.addEntryBlock(); auto *funcBlock = newFunc.addEntryBlock();
@ -150,8 +150,8 @@ LogicalResult SplitFuncsPass::lowerFunc(FuncOp funcOp) {
for (auto pair : argMap) for (auto pair : argMap)
replaceAllUsesInRegionWith(pair.first, pair.second, newFunc.getRegion()); replaceAllUsesInRegionWith(pair.first, pair.second, newFunc.getRegion());
opBuilder.setInsertionPointToStart(blocks[i + 1]); opBuilder.setInsertionPointToStart(blocks[i + 1]);
Operation *callOp = opBuilder.create<func::CallOp>( Operation *callOp = func::CallOp::create(opBuilder, funcOp->getLoc(),
funcOp->getLoc(), outTypes, funcName, args); outTypes, funcName, args);
auto callResults = callOp->getResults(); auto callResults = callOp->getResults();
argMap.clear(); argMap.clear();
for (unsigned long k = 0; k < outValues.size(); ++k) for (unsigned long k = 0; k < outValues.size(); ++k)

View File

@ -161,7 +161,7 @@ void Splitter::run(Block &block, DenseMap<Operation *, APInt> &coloring) {
// Create the final `arc.output` op for each of the splits. // Create the final `arc.output` op for each of the splits.
for (auto &split : splits) for (auto &split : splits)
split->builder.create<arc::OutputOp>(loc, split->exportedValues); arc::OutputOp::create(split->builder, loc, split->exportedValues);
} }
/// Get or create the split for a given operation color. /// Get or create the split for a given operation color.
@ -291,10 +291,11 @@ void SplitLoopsPass::splitArc(Namespace &arcNamespace, DefineOp defOp,
if (splitter.splits.size() > 1) if (splitter.splits.size() > 1)
splitName = arcNamespace.newName(defOp.getSymName() + "_split_" + splitName = arcNamespace.newName(defOp.getSymName() + "_split_" +
Twine(split->index)); Twine(split->index));
auto splitArc = builder.create<DefineOp>( auto splitArc =
splitName, builder.getFunctionType( DefineOp::create(builder, splitName,
split->block->getArgumentTypes(), builder.getFunctionType(
split->block->getTerminator()->getOperandTypes())); split->block->getArgumentTypes(),
split->block->getTerminator()->getOperandTypes()));
splitArc.getBody().push_back(split->block.release()); splitArc.getBody().push_back(split->block.release());
splitArcs.push_back(splitArc); splitArcs.push_back(splitArc);
++numArcsCreated; ++numArcsCreated;
@ -365,7 +366,7 @@ void SplitLoopsPass::replaceArcUse(CallOpInterface arcUse,
if (!getMappedValuesOrSchedule(split->importedValues, operands)) if (!getMappedValuesOrSchedule(split->importedValues, operands))
continue; continue;
auto newUse = builder.create<CallOp>(splitDef, operands); auto newUse = CallOp::create(builder, splitDef, operands);
allArcUses.insert(newUse); allArcUses.insert(newUse);
newUses[split->index] = newUse; newUses[split->index] = newUse;

View File

@ -138,9 +138,8 @@ void StripSVPass::runOnOperation() {
Value next; Value next;
// Note: this register will have an sync reset regardless. // Note: this register will have an sync reset regardless.
if (reg.hasReset()) if (reg.hasReset())
next = builder.create<comb::MuxOp>(reg.getLoc(), reg.getReset(), next = comb::MuxOp::create(builder, reg.getLoc(), reg.getReset(),
reg.getResetValue(), reg.getNext(), reg.getResetValue(), reg.getNext(), false);
false);
else else
next = reg.getNext(); next = reg.getNext();
@ -154,9 +153,9 @@ void StripSVPass::runOnOperation() {
IntegerAttr::get(reg.getType(), *reg.getPreset())); IntegerAttr::get(reg.getType(), *reg.getPreset()));
} }
Value compReg = builder.create<seq::CompRegOp>( Value compReg = seq::CompRegOp::create(
reg.getLoc(), next.getType(), next, reg.getClk(), reg.getNameAttr(), builder, reg.getLoc(), next.getType(), next, reg.getClk(),
Value{}, Value{}, /*initialValue*/ presetValue, reg.getNameAttr(), Value{}, Value{}, /*initialValue*/ presetValue,
reg.getInnerSymAttr()); reg.getInnerSymAttr());
reg.replaceAllUsesWith(compReg); reg.replaceAllUsesWith(compReg);
opsToDelete.push_back(reg); opsToDelete.push_back(reg);
@ -169,9 +168,9 @@ void StripSVPass::runOnOperation() {
auto modName = instOp.getModuleNameAttr().getAttr(); auto modName = instOp.getModuleNameAttr().getAttr();
ImplicitLocOpBuilder builder(instOp.getLoc(), instOp); ImplicitLocOpBuilder builder(instOp.getLoc(), instOp);
if (clockGateModuleNames.contains(modName)) { if (clockGateModuleNames.contains(modName)) {
auto gated = builder.create<seq::ClockGateOp>( auto gated = seq::ClockGateOp::create(
instOp.getOperand(0), instOp.getOperand(1), instOp.getOperand(2), builder, instOp.getOperand(0), instOp.getOperand(1),
hw::InnerSymAttr{}); instOp.getOperand(2), hw::InnerSymAttr{});
instOp.replaceAllUsesWith(gated); instOp.replaceAllUsesWith(gated);
opsToDelete.push_back(instOp); opsToDelete.push_back(instOp);
} }

View File

@ -601,9 +601,9 @@ static void buildComponentLike(OpBuilder &builder, OperationState &result,
// Insert the WiresOp and ControlOp. // Insert the WiresOp and ControlOp.
IRRewriter::InsertionGuard guard(builder); IRRewriter::InsertionGuard guard(builder);
builder.setInsertionPointToStart(body); builder.setInsertionPointToStart(body);
builder.create<WiresOp>(result.location); WiresOp::create(builder, result.location);
if (!combinational) if (!combinational)
builder.create<ControlOp>(result.location); ControlOp::create(builder, result.location);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -2437,12 +2437,12 @@ static LogicalResult commonTailPatternWithSeq(IfOpTy ifOp,
// this IfOp is nested in a ParOp. This avoids unintentionally // this IfOp is nested in a ParOp. This avoids unintentionally
// parallelizing the pulled out EnableOps. // parallelizing the pulled out EnableOps.
rewriter.setInsertionPointAfter(ifOp); rewriter.setInsertionPointAfter(ifOp);
SeqOpTy seqOp = rewriter.create<SeqOpTy>(ifOp.getLoc()); SeqOpTy seqOp = SeqOpTy::create(rewriter, ifOp.getLoc());
Block *body = seqOp.getBodyBlock(); Block *body = seqOp.getBodyBlock();
ifOp->remove(); ifOp->remove();
body->push_back(ifOp); body->push_back(ifOp);
rewriter.setInsertionPointToEnd(body); rewriter.setInsertionPointToEnd(body);
rewriter.create<EnableOp>(seqOp.getLoc(), lastThenEnableOp->getGroupName()); EnableOp::create(rewriter, seqOp.getLoc(), lastThenEnableOp->getGroupName());
// Erase the common EnableOp from the Then and Else regions. // Erase the common EnableOp from the Then and Else regions.
rewriter.eraseOp(*lastThenEnableOp); rewriter.eraseOp(*lastThenEnableOp);
@ -2496,7 +2496,7 @@ static LogicalResult commonTailPatternWithPar(OpTy controlOp,
// the pulled out EnableOps. // the pulled out EnableOps.
rewriter.setInsertionPointAfter(controlOp); rewriter.setInsertionPointAfter(controlOp);
ParOpTy parOp = rewriter.create<ParOpTy>(controlOp.getLoc()); ParOpTy parOp = ParOpTy::create(rewriter, controlOp.getLoc());
Block *body = parOp.getBodyBlock(); Block *body = parOp.getBodyBlock();
controlOp->remove(); controlOp->remove();
body->push_back(controlOp); body->push_back(controlOp);
@ -2504,7 +2504,7 @@ static LogicalResult commonTailPatternWithPar(OpTy controlOp,
// counterparts in the Then and Else regions. // counterparts in the Then and Else regions.
rewriter.setInsertionPointToEnd(body); rewriter.setInsertionPointToEnd(body);
for (StringRef groupName : groupNames) for (StringRef groupName : groupNames)
rewriter.create<EnableOp>(parOp.getLoc(), groupName); EnableOp::create(rewriter, parOp.getLoc(), groupName);
return success(); return success();
} }

View File

@ -260,8 +260,8 @@ struct AffineParallelUnroll : public OpRewritePattern<AffineParallelOp> {
rewriter.getContext()); rewriter.getContext());
AffineMap ubMap = AffineMap::get(0, 0, rewriter.getAffineConstantExpr(1), AffineMap ubMap = AffineMap::get(0, 0, rewriter.getAffineConstantExpr(1),
rewriter.getContext()); rewriter.getContext());
auto newParallelOp = rewriter.create<AffineParallelOp>( auto newParallelOp = AffineParallelOp::create(
loc, /*resultTypes=*/TypeRange(), rewriter, loc, /*resultTypes=*/TypeRange(),
/*reductions=*/SmallVector<arith::AtomicRMWKind>(), /*reductions=*/SmallVector<arith::AtomicRMWKind>(),
/*lowerBoundsMap=*/lbMap, /*lowerBoundsOperands=*/SmallVector<Value>(), /*lowerBoundsMap=*/lbMap, /*lowerBoundsOperands=*/SmallVector<Value>(),
/*upperBoundsMap=*/ubMap, /*upperBoundsOperands=*/SmallVector<Value>(), /*upperBoundsMap=*/ubMap, /*upperBoundsOperands=*/SmallVector<Value>(),
@ -294,7 +294,7 @@ struct AffineParallelUnroll : public OpRewritePattern<AffineParallelOp> {
// Create an `scf.execute_region` to wrap each unrolled block since // Create an `scf.execute_region` to wrap each unrolled block since
// `affine.parallel` requires only one block in the body region. // `affine.parallel` requires only one block in the body region.
auto executeRegionOp = auto executeRegionOp =
insideBuilder.create<scf::ExecuteRegionOp>(loc, TypeRange{}); scf::ExecuteRegionOp::create(insideBuilder, loc, TypeRange{});
Region &executeRegionRegion = executeRegionOp.getRegion(); Region &executeRegionRegion = executeRegionOp.getRegion();
Block *executeRegionBlock = &executeRegionRegion.emplaceBlock(); Block *executeRegionBlock = &executeRegionRegion.emplaceBlock();
@ -307,7 +307,7 @@ struct AffineParallelUnroll : public OpRewritePattern<AffineParallelOp> {
// Map induction variables to constant indices // Map induction variables to constant indices
for (unsigned i = 0; i < indices.size(); ++i) { for (unsigned i = 0; i < indices.size(); ++i) {
Value ivConstant = Value ivConstant =
regionBuilder.create<arith::ConstantIndexOp>(loc, indices[i]); arith::ConstantIndexOp::create(regionBuilder, loc, indices[i]);
operandMap.map(pLoopIVs[i], ivConstant); operandMap.map(pLoopIVs[i], ivConstant);
} }
@ -316,7 +316,7 @@ struct AffineParallelUnroll : public OpRewritePattern<AffineParallelOp> {
regionBuilder.clone(*it, operandMap); regionBuilder.clone(*it, operandMap);
// A terminator should always be inserted in `scf.execute_region`'s block. // A terminator should always be inserted in `scf.execute_region`'s block.
regionBuilder.create<scf::YieldOp>(loc); scf::YieldOp::create(regionBuilder, loc);
// Increment indices using `step`. // Increment indices using `step`.
bool done = false; bool done = false;

View File

@ -79,8 +79,8 @@ public:
SmallVector<scf::IndexSwitchOp> simplifiableIndexSwitchOps = SmallVector<scf::IndexSwitchOp> simplifiableIndexSwitchOps =
collectSimplifiableIndexSwitchOps(affineParallelOp, factor); collectSimplifiableIndexSwitchOps(affineParallelOp, factor);
auto outerLoop = rewriter.create<affine::AffineForOp>( auto outerLoop = affine::AffineForOp::create(
loc, lowerBound, rewriter.getDimIdentityMap(), upperBound, rewriter, loc, lowerBound, rewriter.getDimIdentityMap(), upperBound,
rewriter.getDimIdentityMap(), step * factor); rewriter.getDimIdentityMap(), step * factor);
rewriter.setInsertionPointToStart(outerLoop.getBody()); rewriter.setInsertionPointToStart(outerLoop.getBody());
@ -89,8 +89,8 @@ public:
/*results=*/rewriter.getAffineConstantExpr(0), rewriter.getContext()); /*results=*/rewriter.getAffineConstantExpr(0), rewriter.getContext());
AffineMap ubMap = AffineMap::get( AffineMap ubMap = AffineMap::get(
0, 0, rewriter.getAffineConstantExpr(factor), rewriter.getContext()); 0, 0, rewriter.getAffineConstantExpr(factor), rewriter.getContext());
auto innerParallel = rewriter.create<affine::AffineParallelOp>( auto innerParallel = affine::AffineParallelOp::create(
loc, /*resultTypes=*/TypeRange(), rewriter, loc, /*resultTypes=*/TypeRange(),
/*reductions=*/SmallVector<arith::AtomicRMWKind>(), /*reductions=*/SmallVector<arith::AtomicRMWKind>(),
/*lowerBoundsMap=*/lbMap, /*lowerBoundsOperands=*/SmallVector<Value>(), /*lowerBoundsMap=*/lbMap, /*lowerBoundsOperands=*/SmallVector<Value>(),
/*upperBoundsMap=*/ubMap, /*upperBoundsOperands=*/SmallVector<Value>(), /*upperBoundsMap=*/ubMap, /*upperBoundsOperands=*/SmallVector<Value>(),
@ -109,8 +109,8 @@ public:
2, 0, rewriter.getAffineDimExpr(0) + rewriter.getAffineDimExpr(1), 2, 0, rewriter.getAffineDimExpr(0) + rewriter.getAffineDimExpr(1),
rewriter.getContext()); rewriter.getContext());
auto newIndex = rewriter.create<affine::AffineApplyOp>( auto newIndex = affine::AffineApplyOp::create(
loc, addMap, rewriter, loc, addMap,
ValueRange{outerLoop.getInductionVar(), innerParallel.getIVs()[0]}); ValueRange{outerLoop.getInductionVar(), innerParallel.getIVs()[0]});
Block *srcBlock = affineParallelOp.getBody(); Block *srcBlock = affineParallelOp.getBody();
@ -133,7 +133,7 @@ public:
}); });
rewriter.setInsertionPointToEnd(destBlock); rewriter.setInsertionPointToEnd(destBlock);
rewriter.create<affine::AffineYieldOp>(loc); affine::AffineYieldOp::create(rewriter, loc);
for (auto indexSwitchOp : simplifiableIndexSwitchOps) { for (auto indexSwitchOp : simplifiableIndexSwitchOps) {
indexSwitchOp.setOperand(innerParallel.getIVs().front()); indexSwitchOp.setOperand(innerParallel.getIVs().front());

View File

@ -56,7 +56,7 @@ public:
Location loc = affineParallelOp.getLoc(); Location loc = affineParallelOp.getLoc();
SmallVector<Value, 8> steps; SmallVector<Value, 8> steps;
for (int64_t step : affineParallelSteps) for (int64_t step : affineParallelSteps)
steps.push_back(rewriter.create<arith::ConstantIndexOp>(loc, step)); steps.push_back(arith::ConstantIndexOp::create(rewriter, loc, step));
auto upperBoundTuple = mlir::affine::expandAffineMap( auto upperBoundTuple = mlir::affine::expandAffineMap(
rewriter, loc, affineParallelOp.getUpperBoundsMap(), rewriter, loc, affineParallelOp.getUpperBoundsMap(),
@ -69,8 +69,8 @@ public:
auto affineParallelTerminator = cast<affine::AffineYieldOp>( auto affineParallelTerminator = cast<affine::AffineYieldOp>(
affineParallelOp.getBody()->getTerminator()); affineParallelOp.getBody()->getTerminator());
scf::ParallelOp scfParallelOp = rewriter.create<scf::ParallelOp>( scf::ParallelOp scfParallelOp = scf::ParallelOp::create(
loc, *lowerBoundTuple, *upperBoundTuple, steps, rewriter, loc, *lowerBoundTuple, *upperBoundTuple, steps,
/*bodyBuilderFn=*/nullptr); /*bodyBuilderFn=*/nullptr);
scfParallelOp->setAttr("calyx.unroll", scfParallelOp->setAttr("calyx.unroll",
affineParallelOp->getAttr("calyx.unroll")); affineParallelOp->getAttr("calyx.unroll"));

View File

@ -24,7 +24,7 @@ calyx::RegisterOp createRegister(Location loc, OpBuilder &builder,
Twine prefix) { Twine prefix) {
OpBuilder::InsertionGuard guard(builder); OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPointToStart(component.getBodyBlock()); builder.setInsertionPointToStart(component.getBodyBlock());
return builder.create<RegisterOp>(loc, (prefix + "_reg").str(), width); return RegisterOp::create(builder, loc, (prefix + "_reg").str(), width);
} }
hw::ConstantOp createConstant(Location loc, OpBuilder &builder, hw::ConstantOp createConstant(Location loc, OpBuilder &builder,
@ -32,8 +32,8 @@ hw::ConstantOp createConstant(Location loc, OpBuilder &builder,
size_t value) { size_t value) {
OpBuilder::InsertionGuard g(builder); OpBuilder::InsertionGuard g(builder);
builder.setInsertionPointToStart(component.getBodyBlock()); builder.setInsertionPointToStart(component.getBodyBlock());
return builder.create<hw::ConstantOp>( return hw::ConstantOp::create(builder, loc,
loc, APInt(width, value, /*isSigned=*/false)); APInt(width, value, /*isSigned=*/false));
} }
calyx::InstanceOp createInstance(Location loc, OpBuilder &builder, calyx::InstanceOp createInstance(Location loc, OpBuilder &builder,
@ -43,8 +43,8 @@ calyx::InstanceOp createInstance(Location loc, OpBuilder &builder,
StringRef componentName) { StringRef componentName) {
OpBuilder::InsertionGuard g(builder); OpBuilder::InsertionGuard g(builder);
builder.setInsertionPointToStart(component.getBodyBlock()); builder.setInsertionPointToStart(component.getBodyBlock());
return builder.create<InstanceOp>(loc, resultTypes, instanceName, return InstanceOp::create(builder, loc, resultTypes, instanceName,
componentName); componentName);
} }
std::string getInstanceName(mlir::func::CallOp callOp) { std::string getInstanceName(mlir::func::CallOp callOp) {

View File

@ -174,10 +174,10 @@ void buildAssignmentsForRegisterWrite(OpBuilder &builder,
mlir::IRRewriter::InsertionGuard guard(builder); mlir::IRRewriter::InsertionGuard guard(builder);
auto loc = inputValue.getLoc(); auto loc = inputValue.getLoc();
builder.setInsertionPointToEnd(groupOp.getBodyBlock()); builder.setInsertionPointToEnd(groupOp.getBodyBlock());
builder.create<calyx::AssignOp>(loc, reg.getIn(), inputValue); calyx::AssignOp::create(builder, loc, reg.getIn(), inputValue);
builder.create<calyx::AssignOp>( calyx::AssignOp::create(builder, loc, reg.getWriteEn(),
loc, reg.getWriteEn(), createConstant(loc, builder, componentOp, 1, 1)); createConstant(loc, builder, componentOp, 1, 1));
builder.create<calyx::GroupDoneOp>(loc, reg.getDone()); calyx::GroupDoneOp::create(builder, loc, reg.getDone());
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -610,13 +610,13 @@ MultipleGroupDonePattern::matchAndRewrite(calyx::GroupOp groupOp,
SmallVector<Value> doneOpSrcs; SmallVector<Value> doneOpSrcs;
llvm::transform(groupDoneOps, std::back_inserter(doneOpSrcs), llvm::transform(groupDoneOps, std::back_inserter(doneOpSrcs),
[](calyx::GroupDoneOp op) { return op.getSrc(); }); [](calyx::GroupDoneOp op) { return op.getSrc(); });
Value allDone = rewriter.create<comb::AndOp>(groupDoneOps.front().getLoc(), Value allDone = comb::AndOp::create(rewriter, groupDoneOps.front().getLoc(),
doneOpSrcs, false); doneOpSrcs, false);
/// Create a group done op with the complex expression as a guard. /// Create a group done op with the complex expression as a guard.
rewriter.create<calyx::GroupDoneOp>( calyx::GroupDoneOp::create(
groupOp.getLoc(), rewriter, groupOp.getLoc(),
rewriter.create<hw::ConstantOp>(groupOp.getLoc(), APInt(1, 1)), allDone); hw::ConstantOp::create(rewriter, groupOp.getLoc(), APInt(1, 1)), allDone);
for (auto groupDoneOp : groupDoneOps) for (auto groupDoneOp : groupDoneOps)
rewriter.eraseOp(groupDoneOp); rewriter.eraseOp(groupDoneOp);
@ -775,8 +775,8 @@ RewriteMemoryAccesses::partiallyLower(calyx::AssignOp assignOp,
rewriter.setInsertionPoint(assignOp->getBlock(), rewriter.setInsertionPoint(assignOp->getBlock(),
assignOp->getBlock()->begin()); assignOp->getBlock()->begin());
rewriter.create<calyx::AssignOp>(assignOp->getLoc(), newOp->getResult(0), calyx::AssignOp::create(rewriter, assignOp->getLoc(), newOp->getResult(0),
src); src);
assignOp.setOperand(1, newOp->getResult(1)); assignOp.setOperand(1, newOp->getResult(1));
return success(); return success();
@ -828,8 +828,8 @@ BuildReturnRegs::partiallyLowerFuncToComp(mlir::func::FuncOp funcOp,
rewriter.setInsertionPointToStart( rewriter.setInsertionPointToStart(
getComponent().getWiresOp().getBodyBlock()); getComponent().getWiresOp().getBodyBlock());
rewriter.create<calyx::AssignOp>( calyx::AssignOp::create(
funcOp->getLoc(), rewriter, funcOp->getLoc(),
calyx::getComponentOutput( calyx::getComponentOutput(
getComponent(), getState().getFuncOpResultMapping(argType.index())), getComponent(), getState().getFuncOpResultMapping(argType.index())),
reg.getOut()); reg.getOut());

View File

@ -45,7 +45,7 @@ static void doPortPassthrough(ComponentOp comp, Value fromPort,
for (auto port : cell.getInputPorts()) { for (auto port : cell.getInputPorts()) {
if (!cell.portInfo(port).hasAttribute(portID)) if (!cell.portInfo(port).hasAttribute(portID))
continue; continue;
builder.create<AssignOp>(cell.getLoc(), port, fromPort); AssignOp::create(builder, cell.getLoc(), port, fromPort);
} }
} }
} }

View File

@ -94,7 +94,7 @@ void CompileControlVisitor::visit(SeqOp seq, ComponentOp &component) {
// Create the new compilation group to replace this SeqOp. // Create the new compilation group to replace this SeqOp.
builder.setInsertionPointToEnd(wiresBody); builder.setInsertionPointToEnd(wiresBody);
auto seqGroup = auto seqGroup =
builder.create<GroupOp>(wires->getLoc(), builder.getStringAttr("seq")); GroupOp::create(builder, wires->getLoc(), builder.getStringAttr("seq"));
// Guarantees a unique SymbolName for the group. // Guarantees a unique SymbolName for the group.
auto &symTable = am.getChildAnalysis<SymbolTable>(wires); auto &symTable = am.getChildAnalysis<SymbolTable>(wires);
@ -118,25 +118,25 @@ void CompileControlVisitor::visit(SeqOp seq, ComponentOp &component) {
auto guard = groupOp.getDoneOp().getGuard(); auto guard = groupOp.getDoneOp().getGuard();
Value source = groupOp.getDoneOp().getSrc(); Value source = groupOp.getDoneOp().getSrc();
auto doneOpValue = !guard ? source auto doneOpValue = !guard ? source
: builder.create<comb::AndOp>( : comb::AndOp::create(builder, wires->getLoc(),
wires->getLoc(), guard, source, false); guard, source, false);
// Build the Guard for the `go` signal of the current group being walked. // Build the Guard for the `go` signal of the current group being walked.
// The group should begin when: // The group should begin when:
// (1) the current step in the fsm is reached, and // (1) the current step in the fsm is reached, and
// (2) the done signal of this group is not high. // (2) the done signal of this group is not high.
auto eqCmp = auto eqCmp =
builder.create<comb::ICmpOp>(wires->getLoc(), comb::ICmpPredicate::eq, comb::ICmpOp::create(builder, wires->getLoc(), comb::ICmpPredicate::eq,
fsmOut, fsmCurrentState, false); fsmOut, fsmCurrentState, false);
auto notDone = comb::createOrFoldNot(wires->getLoc(), doneOpValue, builder); auto notDone = comb::createOrFoldNot(wires->getLoc(), doneOpValue, builder);
auto groupGoGuard = auto groupGoGuard =
builder.create<comb::AndOp>(wires->getLoc(), eqCmp, notDone, false); comb::AndOp::create(builder, wires->getLoc(), eqCmp, notDone, false);
// Guard for the `in` and `write_en` signal of the fsm register. These are // Guard for the `in` and `write_en` signal of the fsm register. These are
// driven when the group has completed. // driven when the group has completed.
builder.setInsertionPoint(seqGroup); builder.setInsertionPoint(seqGroup);
auto groupDoneGuard = auto groupDoneGuard = comb::AndOp::create(builder, wires->getLoc(), eqCmp,
builder.create<comb::AndOp>(wires->getLoc(), eqCmp, doneOpValue, false); doneOpValue, false);
// Directly update the GroupGoOp of the current group being walked. // Directly update the GroupGoOp of the current group being walked.
auto goOp = groupOp.getGoOp(); auto goOp = groupOp.getGoOp();
@ -147,10 +147,10 @@ void CompileControlVisitor::visit(SeqOp seq, ComponentOp &component) {
fsmNextState = createConstant(wires->getLoc(), builder, component, fsmNextState = createConstant(wires->getLoc(), builder, component,
fsmBitWidth, fsmIndex + 1); fsmBitWidth, fsmIndex + 1);
builder.setInsertionPointToEnd(seqGroup.getBodyBlock()); builder.setInsertionPointToEnd(seqGroup.getBodyBlock());
builder.create<AssignOp>(wires->getLoc(), fsmIn, fsmNextState, AssignOp::create(builder, wires->getLoc(), fsmIn, fsmNextState,
groupDoneGuard); groupDoneGuard);
builder.create<AssignOp>(wires->getLoc(), fsmWriteEn, oneConstant, AssignOp::create(builder, wires->getLoc(), fsmWriteEn, oneConstant,
groupDoneGuard); groupDoneGuard);
// Increment the fsm index for the next group. // Increment the fsm index for the next group.
++fsmIndex; ++fsmIndex;
}); });
@ -158,27 +158,27 @@ void CompileControlVisitor::visit(SeqOp seq, ComponentOp &component) {
// Build the final guard for the new Seq group's GroupDoneOp. This is // Build the final guard for the new Seq group's GroupDoneOp. This is
// defined by the fsm's final state. // defined by the fsm's final state.
builder.setInsertionPoint(seqGroup); builder.setInsertionPoint(seqGroup);
auto isFinalState = builder.create<comb::ICmpOp>( auto isFinalState =
wires->getLoc(), comb::ICmpPredicate::eq, fsmOut, fsmNextState, false); comb::ICmpOp::create(builder, wires->getLoc(), comb::ICmpPredicate::eq,
fsmOut, fsmNextState, false);
// Insert the respective GroupDoneOp. // Insert the respective GroupDoneOp.
builder.setInsertionPointToEnd(seqGroup.getBodyBlock()); builder.setInsertionPointToEnd(seqGroup.getBodyBlock());
builder.create<GroupDoneOp>(seqGroup->getLoc(), oneConstant, isFinalState); GroupDoneOp::create(builder, seqGroup->getLoc(), oneConstant, isFinalState);
// Add continuous wires to reset the `in` and `write_en` ports of the fsm // Add continuous wires to reset the `in` and `write_en` ports of the fsm
// when the SeqGroup is finished executing. // when the SeqGroup is finished executing.
builder.setInsertionPointToEnd(wiresBody); builder.setInsertionPointToEnd(wiresBody);
auto zeroConstant = auto zeroConstant =
createConstant(wires->getLoc(), builder, component, fsmBitWidth, 0); createConstant(wires->getLoc(), builder, component, fsmBitWidth, 0);
builder.create<AssignOp>(wires->getLoc(), fsmIn, zeroConstant, isFinalState); AssignOp::create(builder, wires->getLoc(), fsmIn, zeroConstant, isFinalState);
builder.create<AssignOp>(wires->getLoc(), fsmWriteEn, oneConstant, AssignOp::create(builder, wires->getLoc(), fsmWriteEn, oneConstant,
isFinalState); isFinalState);
// Replace the SeqOp with an EnableOp. // Replace the SeqOp with an EnableOp.
builder.setInsertionPoint(seq); builder.setInsertionPoint(seq);
builder.create<EnableOp>( EnableOp::create(builder, seq->getLoc(), seqGroup.getSymName(),
seq->getLoc(), seqGroup.getSymName(), ArrayAttr::get(builder.getContext(), compiledGroups));
ArrayAttr::get(builder.getContext(), compiledGroups));
seq->erase(); seq->erase();
} }

View File

@ -43,13 +43,13 @@ void GoInsertionPass::runOnOperation() {
OpBuilder builder(wiresOp->getRegion(0)); OpBuilder builder(wiresOp->getRegion(0));
auto undefinedOp = auto undefinedOp =
builder.create<UndefinedOp>(wiresOp->getLoc(), builder.getI1Type()); UndefinedOp::create(builder, wiresOp->getLoc(), builder.getI1Type());
wiresOp.walk([&](GroupOp group) { wiresOp.walk([&](GroupOp group) {
OpBuilder builder(group->getRegion(0)); OpBuilder builder(group->getRegion(0));
// Since the source of a GroupOp's go signal isn't set until the // Since the source of a GroupOp's go signal isn't set until the
// the Compile Control pass, use an undefined value. // the Compile Control pass, use an undefined value.
auto goOp = builder.create<GroupGoOp>(group->getLoc(), undefinedOp); auto goOp = GroupGoOp::create(builder, group->getLoc(), undefinedOp);
updateGroupAssignmentGuards(builder, group, goOp); updateGroupAssignmentGuards(builder, group, goOp);
}); });

View File

@ -98,8 +98,8 @@ static calyx::RegisterOp createReg(ComponentOp component,
Twine prefix, size_t width) { Twine prefix, size_t width) {
IRRewriter::InsertionGuard guard(rewriter); IRRewriter::InsertionGuard guard(rewriter);
rewriter.setInsertionPointToStart(component.getBodyBlock()); rewriter.setInsertionPointToStart(component.getBodyBlock());
return rewriter.create<calyx::RegisterOp>(loc, (prefix + "_reg").str(), return calyx::RegisterOp::create(rewriter, loc, (prefix + "_reg").str(),
width); width);
} }
// Wraps the provided 'op' inside a newly created TOp operation, and // Wraps the provided 'op' inside a newly created TOp operation, and
@ -108,7 +108,7 @@ template <typename TOp>
static TOp wrapInsideOp(OpBuilder &builder, Operation *op) { static TOp wrapInsideOp(OpBuilder &builder, Operation *op) {
OpBuilder::InsertionGuard g(builder); OpBuilder::InsertionGuard g(builder);
builder.setInsertionPoint(op); builder.setInsertionPoint(op);
auto newOp = builder.create<TOp>(op->getLoc()); auto newOp = TOp::create(builder, op->getLoc());
op->moveBefore(newOp.getBodyBlock(), newOp.getBodyBlock()->begin()); op->moveBefore(newOp.getBodyBlock(), newOp.getBodyBlock()->begin());
return newOp; return newOp;
} }
@ -125,8 +125,8 @@ struct RemoveCombGroupsPattern : public OpRewritePattern<calyx::CombGroupOp> {
PatternRewriter &rewriter) const override { PatternRewriter &rewriter) const override {
auto component = combGroup->getParentOfType<ComponentOp>(); auto component = combGroup->getParentOfType<ComponentOp>();
auto group = rewriter.create<calyx::GroupOp>(combGroup.getLoc(), auto group = calyx::GroupOp::create(rewriter, combGroup.getLoc(),
combGroup.getName()); combGroup.getName());
rewriter.mergeBlocks(combGroup.getBodyBlock(), group.getBodyBlock()); rewriter.mergeBlocks(combGroup.getBodyBlock(), group.getBodyBlock());
rewriter.replaceOp(combGroup, group); rewriter.replaceOp(combGroup, group);
@ -139,8 +139,9 @@ struct RemoveCombGroupsPattern : public OpRewritePattern<calyx::CombGroupOp> {
} }
rewriter.setInsertionPointToStart(group.getBodyBlock()); rewriter.setInsertionPointToStart(group.getBodyBlock());
auto oneConstant = rewriter.create<hw::ConstantOp>( auto oneConstant = hw::ConstantOp::create(
group.getLoc(), APInt(1, 1, /*isSigned=*/true, /*implicitTrunc=*/true)); rewriter, group.getLoc(),
APInt(1, 1, /*isSigned=*/true, /*implicitTrunc=*/true));
// Maintain the set of cell results which have already been assigned to // Maintain the set of cell results which have already been assigned to
// its register within this group. // its register within this group.
@ -177,11 +178,10 @@ struct RemoveCombGroupsPattern : public OpRewritePattern<calyx::CombGroupOp> {
// Assign the cell result register - a register should only be // Assign the cell result register - a register should only be
// assigned once within a group. // assigned once within a group.
if (!alreadyAssignedResults.contains(combRes)) { if (!alreadyAssignedResults.contains(combRes)) {
rewriter.create<AssignOp>(combRes.getLoc(), AssignOp::create(rewriter, combRes.getLoc(),
combResReg->second.getIn(), combRes); combResReg->second.getIn(), combRes);
rewriter.create<AssignOp>(combRes.getLoc(), AssignOp::create(rewriter, combRes.getLoc(),
combResReg->second.getWriteEn(), combResReg->second.getWriteEn(), oneConstant);
oneConstant);
alreadyAssignedResults.insert(combRes); alreadyAssignedResults.insert(combRes);
} }
@ -196,11 +196,11 @@ struct RemoveCombGroupsPattern : public OpRewritePattern<calyx::CombGroupOp> {
assert(!registerDoneSigs.empty() && assert(!registerDoneSigs.empty() &&
"No registers assigned in the combinational group?"); "No registers assigned in the combinational group?");
rewriter.setInsertionPointToEnd(group.getBodyBlock()); rewriter.setInsertionPointToEnd(group.getBodyBlock());
rewriter.create<calyx::GroupDoneOp>( calyx::GroupDoneOp::create(
group.getLoc(), rewriter, group.getLoc(),
rewriter.create<hw::ConstantOp>(group.getLoc(), APInt(1, 1)), hw::ConstantOp::create(rewriter, group.getLoc(), APInt(1, 1)),
rewriter.create<comb::AndOp>(combGroup.getLoc(), rewriter.getI1Type(), comb::AndOp::create(rewriter, combGroup.getLoc(), rewriter.getI1Type(),
registerDoneSigs.takeVector())); registerDoneSigs.takeVector()));
return success(); return success();
} }
@ -223,7 +223,7 @@ struct RemoveCombGroupsPass
// Ensure that we're inside a sequential control composition. // Ensure that we're inside a sequential control composition.
wrapInsideOp<SeqOp>(builder, ifOp); wrapInsideOp<SeqOp>(builder, ifOp);
builder.setInsertionPoint(ifOp); builder.setInsertionPoint(ifOp);
builder.create<EnableOp>(ifOp.getLoc(), groupName.value()); EnableOp::create(builder, ifOp.getLoc(), groupName.value());
ifOp.removeGroupNameAttr(); ifOp.removeGroupNameAttr();
}); });
} }
@ -237,16 +237,16 @@ struct RemoveCombGroupsPass
// Ensure that we're inside a sequential control composition. // Ensure that we're inside a sequential control composition.
wrapInsideOp<SeqOp>(builder, whileOp); wrapInsideOp<SeqOp>(builder, whileOp);
builder.setInsertionPoint(whileOp); builder.setInsertionPoint(whileOp);
builder.create<EnableOp>(whileOp.getLoc(), groupName); EnableOp::create(builder, whileOp.getLoc(), groupName);
whileOp.removeGroupNameAttr(); whileOp.removeGroupNameAttr();
// Also schedule the group at the end of the while body. // Also schedule the group at the end of the while body.
auto &curWhileBodyOp = whileOp.getBodyBlock()->front(); auto &curWhileBodyOp = whileOp.getBodyBlock()->front();
builder.setInsertionPointToStart(whileOp.getBodyBlock()); builder.setInsertionPointToStart(whileOp.getBodyBlock());
auto newSeqBody = builder.create<SeqOp>(curWhileBodyOp.getLoc()); auto newSeqBody = SeqOp::create(builder, curWhileBodyOp.getLoc());
builder.setInsertionPointToStart(newSeqBody.getBodyBlock()); builder.setInsertionPointToStart(newSeqBody.getBodyBlock());
auto condEnable = auto condEnable =
builder.create<EnableOp>(curWhileBodyOp.getLoc(), groupName); EnableOp::create(builder, curWhileBodyOp.getLoc(), groupName);
curWhileBodyOp.moveBefore(condEnable); curWhileBodyOp.moveBefore(condEnable);
}); });
} }

View File

@ -54,8 +54,8 @@ static void modifyGroupOperations(ComponentOp component) {
// Replace `calyx.group_done %0, %1 ? : i1` // Replace `calyx.group_done %0, %1 ? : i1`
// with `calyx.assign %done, %0, %1 ? : i1` // with `calyx.assign %done, %0, %1 ? : i1`
auto assignOp = auto assignOp =
builder.create<AssignOp>(group->getLoc(), component.getDonePort(), AssignOp::create(builder, group->getLoc(), component.getDonePort(),
groupDone.getSrc(), groupDone.getGuard()); groupDone.getSrc(), groupDone.getGuard());
groupDone->replaceAllUsesWith(assignOp); groupDone->replaceAllUsesWith(assignOp);
} else { } else {
// Replace calyx.group_go's uses with its guard, e.g. // Replace calyx.group_go's uses with its guard, e.g.

View File

@ -44,15 +44,15 @@ Operation *CombDialect::materializeConstant(OpBuilder &builder, Attribute value,
// Integer constants. // Integer constants.
if (auto intType = dyn_cast<IntegerType>(type)) if (auto intType = dyn_cast<IntegerType>(type))
if (auto attrValue = dyn_cast<IntegerAttr>(value)) if (auto attrValue = dyn_cast<IntegerAttr>(value))
return builder.create<hw::ConstantOp>(loc, type, attrValue); return hw::ConstantOp::create(builder, loc, type, attrValue);
// Parameter expressions materialize into hw.param.value. // Parameter expressions materialize into hw.param.value.
auto parentOp = builder.getBlock()->getParentOp(); auto *parentOp = builder.getBlock()->getParentOp();
auto curModule = dyn_cast<hw::HWModuleOp>(parentOp); auto curModule = dyn_cast<hw::HWModuleOp>(parentOp);
if (!curModule) if (!curModule)
curModule = parentOp->getParentOfType<hw::HWModuleOp>(); curModule = parentOp->getParentOfType<hw::HWModuleOp>();
if (curModule && isValidParameterExpression(value, curModule)) if (curModule && isValidParameterExpression(value, curModule))
return builder.create<hw::ParamValueOp>(loc, type, value); return hw::ParamValueOp::create(builder, loc, type, value);
return nullptr; return nullptr;
} }

View File

@ -227,7 +227,7 @@ static bool narrowOperationWidth(OpTy op, bool narrowTrailingBits,
args.push_back(rewriter.createOrFold<ExtractOp>(inop.getLoc(), newType, args.push_back(rewriter.createOrFold<ExtractOp>(inop.getLoc(), newType,
inop, range.first)); inop, range.first));
} }
auto newop = rewriter.create<OpTy>(op.getLoc(), newType, args); auto newop = OpTy::create(rewriter, op.getLoc(), newType, args);
newop->setDialectAttrs(op->getDialectAttrs()); newop->setDialectAttrs(op->getDialectAttrs());
if (op.getTwoState()) if (op.getTwoState())
newop.setTwoState(true); newop.setTwoState(true);
@ -236,13 +236,14 @@ static bool narrowOperationWidth(OpTy op, bool narrowTrailingBits,
if (range.first) if (range.first)
newResult = rewriter.createOrFold<ConcatOp>( newResult = rewriter.createOrFold<ConcatOp>(
op.getLoc(), newResult, op.getLoc(), newResult,
rewriter.create<hw::ConstantOp>(op.getLoc(), hw::ConstantOp::create(rewriter, op.getLoc(),
APInt::getZero(range.first))); APInt::getZero(range.first)));
if (range.second + 1 < opType.getWidth()) if (range.second + 1 < opType.getWidth())
newResult = rewriter.createOrFold<ConcatOp>( newResult = rewriter.createOrFold<ConcatOp>(
op.getLoc(), op.getLoc(),
rewriter.create<hw::ConstantOp>( hw::ConstantOp::create(
op.getLoc(), APInt::getZero(opType.getWidth() - range.second - 1)), rewriter, op.getLoc(),
APInt::getZero(opType.getWidth() - range.second - 1)),
newResult); newResult);
rewriter.replaceOp(op, newResult); rewriter.replaceOp(op, newResult);
return true; return true;
@ -333,11 +334,11 @@ LogicalResult ShlOp::canonicalize(ShlOp op, PatternRewriter &rewriter) {
return failure(); return failure();
auto zeros = auto zeros =
rewriter.create<hw::ConstantOp>(op.getLoc(), APInt::getZero(shift)); hw::ConstantOp::create(rewriter, op.getLoc(), APInt::getZero(shift));
// Remove the high bits which would be removed by the Shl. // Remove the high bits which would be removed by the Shl.
auto extract = auto extract =
rewriter.create<ExtractOp>(op.getLoc(), op.getLhs(), 0, width - shift); ExtractOp::create(rewriter, op.getLoc(), op.getLhs(), 0, width - shift);
replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, extract, zeros); replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, extract, zeros);
return success(); return success();
@ -371,11 +372,11 @@ LogicalResult ShrUOp::canonicalize(ShrUOp op, PatternRewriter &rewriter) {
return failure(); return failure();
auto zeros = auto zeros =
rewriter.create<hw::ConstantOp>(op.getLoc(), APInt::getZero(shift)); hw::ConstantOp::create(rewriter, op.getLoc(), APInt::getZero(shift));
// Remove the low bits which would be removed by the Shr. // Remove the low bits which would be removed by the Shr.
auto extract = rewriter.create<ExtractOp>(op.getLoc(), op.getLhs(), shift, auto extract = ExtractOp::create(rewriter, op.getLoc(), op.getLhs(), shift,
width - shift); width - shift);
replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, zeros, extract); replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, zeros, extract);
return success(); return success();
@ -408,8 +409,8 @@ LogicalResult ShrSOp::canonicalize(ShrSOp op, PatternRewriter &rewriter) {
return success(); return success();
} }
auto extract = rewriter.create<ExtractOp>(op.getLoc(), op.getLhs(), shift, auto extract = ExtractOp::create(rewriter, op.getLoc(), op.getLhs(), shift,
width - shift); width - shift);
replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, sext, extract); replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, sext, extract);
return success(); return success();
@ -498,7 +499,7 @@ static LogicalResult extractConcatToConcatExtract(ExtractOp op,
} else { } else {
auto resultType = IntegerType::get(rewriter.getContext(), widthToConsume); auto resultType = IntegerType::get(rewriter.getContext(), widthToConsume);
reverseConcatArgs.push_back( reverseConcatArgs.push_back(
rewriter.create<ExtractOp>(op.getLoc(), resultType, *it, extractLo)); ExtractOp::create(rewriter, op.getLoc(), resultType, *it, extractLo));
} }
widthRemaining -= widthToConsume; widthRemaining -= widthToConsume;
@ -608,14 +609,14 @@ LogicalResult ExtractOp::canonicalize(ExtractOp op, PatternRewriter &rewriter) {
auto resultTy = rewriter.getIntegerType(pop); auto resultTy = rewriter.getIntegerType(pop);
SmallVector<Value> resultElts; SmallVector<Value> resultElts;
if (lz) if (lz)
resultElts.push_back(rewriter.create<hw::ConstantOp>( resultElts.push_back(hw::ConstantOp::create(rewriter, op.getLoc(),
op.getLoc(), APInt::getZero(lz))); APInt::getZero(lz)));
resultElts.push_back(rewriter.createOrFold<ExtractOp>( resultElts.push_back(rewriter.createOrFold<ExtractOp>(
op.getLoc(), resultTy, inputOp->getOperand(0), op.getLoc(), resultTy, inputOp->getOperand(0),
op.getLowBit() + tz)); op.getLowBit() + tz));
if (tz) if (tz)
resultElts.push_back(rewriter.create<hw::ConstantOp>( resultElts.push_back(hw::ConstantOp::create(rewriter, op.getLoc(),
op.getLoc(), APInt::getZero(tz))); APInt::getZero(tz)));
replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, resultElts); replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, resultElts);
return success(); return success();
} }
@ -631,8 +632,8 @@ LogicalResult ExtractOp::canonicalize(ExtractOp op, PatternRewriter &rewriter) {
if (shlOp->hasOneUse()) if (shlOp->hasOneUse())
if (auto lhsCst = shlOp.getLhs().getDefiningOp<hw::ConstantOp>()) if (auto lhsCst = shlOp.getLhs().getDefiningOp<hw::ConstantOp>())
if (lhsCst.getValue().isOne()) { if (lhsCst.getValue().isOne()) {
auto newCst = rewriter.create<hw::ConstantOp>( auto newCst = hw::ConstantOp::create(
shlOp.getLoc(), rewriter, shlOp.getLoc(),
APInt(lhsCst.getValue().getBitWidth(), op.getLowBit())); APInt(lhsCst.getValue().getBitWidth(), op.getLowBit()));
replaceOpWithNewOpAndCopyNamehint<ICmpOp>( replaceOpWithNewOpAndCopyNamehint<ICmpOp>(
rewriter, op, ICmpPredicate::eq, shlOp->getOperand(1), newCst, rewriter, op, ICmpPredicate::eq, shlOp->getOperand(1), newCst,
@ -731,15 +732,16 @@ static bool canonicalizeLogicalCstWithConcat(Operation *logicalOp,
size_t operandWidth = operand.getType().getIntOrFloatBitWidth(); size_t operandWidth = operand.getType().getIntOrFloatBitWidth();
nextOperandBit -= operandWidth; nextOperandBit -= operandWidth;
// Take a slice of the constant. // Take a slice of the constant.
auto eltCst = rewriter.create<hw::ConstantOp>( auto eltCst =
logicalOp->getLoc(), cst.lshr(nextOperandBit).trunc(operandWidth)); hw::ConstantOp::create(rewriter, logicalOp->getLoc(),
cst.lshr(nextOperandBit).trunc(operandWidth));
newConcatOperands.push_back(createLogicalOp({operand, eltCst})); newConcatOperands.push_back(createLogicalOp({operand, eltCst}));
} }
// Create the concat, and the rest of the logical op if we need it. // Create the concat, and the rest of the logical op if we need it.
Value newResult = Value newResult =
rewriter.create<ConcatOp>(concatOp.getLoc(), newConcatOperands); ConcatOp::create(rewriter, concatOp.getLoc(), newConcatOperands);
// If we had a variadic logical op on the top level, then recreate it with the // If we had a variadic logical op on the top level, then recreate it with the
// new concat and without the constant operand. // new concat and without the constant operand.
@ -949,7 +951,7 @@ LogicalResult AndOp::canonicalize(AndOp op, PatternRewriter &rewriter) {
// folding // folding
APInt value2; APInt value2;
if (matchPattern(inputs[size - 2], m_ConstantInt(&value2))) { if (matchPattern(inputs[size - 2], m_ConstantInt(&value2))) {
auto cst = rewriter.create<hw::ConstantOp>(op.getLoc(), value & value2); auto cst = hw::ConstantOp::create(rewriter, op.getLoc(), value & value2);
SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2)); SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2));
newOperands.push_back(cst); newOperands.push_back(cst);
replaceOpWithNewOpAndCopyNamehint<AndOp>(rewriter, op, op.getType(), replaceOpWithNewOpAndCopyNamehint<AndOp>(rewriter, op, op.getType(),
@ -972,14 +974,15 @@ LogicalResult AndOp::canonicalize(AndOp op, PatternRewriter &rewriter) {
// Don't add zero bit constants unnecessarily. // Don't add zero bit constants unnecessarily.
SmallVector<Value, 3> concatOperands; SmallVector<Value, 3> concatOperands;
if (trailingZeros != resultWidth - 1) { if (trailingZeros != resultWidth - 1) {
auto highZeros = rewriter.create<hw::ConstantOp>( auto highZeros = hw::ConstantOp::create(
op.getLoc(), APInt::getZero(resultWidth - trailingZeros - 1)); rewriter, op.getLoc(),
APInt::getZero(resultWidth - trailingZeros - 1));
concatOperands.push_back(highZeros); concatOperands.push_back(highZeros);
} }
concatOperands.push_back(replicateOperand); concatOperands.push_back(replicateOperand);
if (trailingZeros != 0) { if (trailingZeros != 0) {
auto lowZeros = rewriter.create<hw::ConstantOp>( auto lowZeros = hw::ConstantOp::create(
op.getLoc(), APInt::getZero(trailingZeros)); rewriter, op.getLoc(), APInt::getZero(trailingZeros));
concatOperands.push_back(lowZeros); concatOperands.push_back(lowZeros);
} }
replaceOpWithNewOpAndCopyNamehint<ConcatOp>( replaceOpWithNewOpAndCopyNamehint<ConcatOp>(
@ -1007,7 +1010,7 @@ LogicalResult AndOp::canonicalize(AndOp op, PatternRewriter &rewriter) {
if (!smallMask.isAllOnes()) { if (!smallMask.isAllOnes()) {
auto loc = inputs.back().getLoc(); auto loc = inputs.back().getLoc();
smallElt = rewriter.createOrFold<AndOp>( smallElt = rewriter.createOrFold<AndOp>(
loc, smallElt, rewriter.create<hw::ConstantOp>(loc, smallMask), loc, smallElt, hw::ConstantOp::create(rewriter, loc, smallMask),
false); false);
} }
@ -1015,12 +1018,12 @@ LogicalResult AndOp::canonicalize(AndOp op, PatternRewriter &rewriter) {
// along with the smaller extracted value. // along with the smaller extracted value.
SmallVector<Value> resultElts; SmallVector<Value> resultElts;
if (lz) if (lz)
resultElts.push_back( resultElts.push_back(hw::ConstantOp::create(rewriter, op.getLoc(),
rewriter.create<hw::ConstantOp>(op.getLoc(), APInt::getZero(lz))); APInt::getZero(lz)));
resultElts.push_back(smallElt); resultElts.push_back(smallElt);
if (tz) if (tz)
resultElts.push_back( resultElts.push_back(hw::ConstantOp::create(rewriter, op.getLoc(),
rewriter.create<hw::ConstantOp>(op.getLoc(), APInt::getZero(tz))); APInt::getZero(tz)));
replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, resultElts); replaceOpWithNewOpAndCopyNamehint<ConcatOp>(rewriter, op, resultElts);
return success(); return success();
} }
@ -1043,7 +1046,7 @@ LogicalResult AndOp::canonicalize(AndOp op, PatternRewriter &rewriter) {
// and(a[0], a[1], ..., a[n]) -> icmp eq(a, -1) // and(a[0], a[1], ..., a[n]) -> icmp eq(a, -1)
if (auto source = getCommonOperand(op)) { if (auto source = getCommonOperand(op)) {
auto cmpAgainst = auto cmpAgainst =
rewriter.create<hw::ConstantOp>(op.getLoc(), APInt::getAllOnes(size)); hw::ConstantOp::create(rewriter, op.getLoc(), APInt::getAllOnes(size));
replaceOpWithNewOpAndCopyNamehint<ICmpOp>(rewriter, op, ICmpPredicate::eq, replaceOpWithNewOpAndCopyNamehint<ICmpOp>(rewriter, op, ICmpPredicate::eq,
source, cmpAgainst); source, cmpAgainst);
return success(); return success();
@ -1128,7 +1131,7 @@ LogicalResult OrOp::canonicalize(OrOp op, PatternRewriter &rewriter) {
// or(..., c1, c2) -> or(..., c3) where c3 = c1 | c2 -- constant folding // or(..., c1, c2) -> or(..., c3) where c3 = c1 | c2 -- constant folding
APInt value2; APInt value2;
if (matchPattern(inputs[size - 2], m_ConstantInt(&value2))) { if (matchPattern(inputs[size - 2], m_ConstantInt(&value2))) {
auto cst = rewriter.create<hw::ConstantOp>(op.getLoc(), value | value2); auto cst = hw::ConstantOp::create(rewriter, op.getLoc(), value | value2);
SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2)); SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2));
newOperands.push_back(cst); newOperands.push_back(cst);
replaceOpWithNewOpAndCopyNamehint<OrOp>(rewriter, op, op.getType(), replaceOpWithNewOpAndCopyNamehint<OrOp>(rewriter, op, op.getType(),
@ -1153,7 +1156,7 @@ LogicalResult OrOp::canonicalize(OrOp op, PatternRewriter &rewriter) {
// or(a[0], a[1], ..., a[n]) -> icmp ne(a, 0) // or(a[0], a[1], ..., a[n]) -> icmp ne(a, 0)
if (auto source = getCommonOperand(op)) { if (auto source = getCommonOperand(op)) {
auto cmpAgainst = auto cmpAgainst =
rewriter.create<hw::ConstantOp>(op.getLoc(), APInt::getZero(size)); hw::ConstantOp::create(rewriter, op.getLoc(), APInt::getZero(size));
replaceOpWithNewOpAndCopyNamehint<ICmpOp>(rewriter, op, ICmpPredicate::ne, replaceOpWithNewOpAndCopyNamehint<ICmpOp>(rewriter, op, ICmpPredicate::ne,
source, cmpAgainst); source, cmpAgainst);
return success(); return success();
@ -1177,7 +1180,7 @@ LogicalResult OrOp::canonicalize(OrOp op, PatternRewriter &rewriter) {
firstMux.getFalseValue() == mux.getFalseValue(); firstMux.getFalseValue() == mux.getFalseValue();
}; };
if (llvm::all_of(op.getOperands().drop_front(), check)) { if (llvm::all_of(op.getOperands().drop_front(), check)) {
auto cond = rewriter.create<comb::OrOp>(op.getLoc(), conditions, true); auto cond = comb::OrOp::create(rewriter, op.getLoc(), conditions, true);
replaceOpWithNewOpAndCopyNamehint<comb::MuxOp>( replaceOpWithNewOpAndCopyNamehint<comb::MuxOp>(
rewriter, op, cond, firstMux.getTrueValue(), rewriter, op, cond, firstMux.getTrueValue(),
firstMux.getFalseValue(), true); firstMux.getFalseValue(), true);
@ -1227,8 +1230,8 @@ static void canonicalizeXorIcmpTrue(XorOp op, unsigned icmpOperand,
auto negatedPred = ICmpOp::getNegatedPredicate(icmp.getPredicate()); auto negatedPred = ICmpOp::getNegatedPredicate(icmp.getPredicate());
Value result = Value result =
rewriter.create<ICmpOp>(icmp.getLoc(), negatedPred, icmp.getOperand(0), ICmpOp::create(rewriter, icmp.getLoc(), negatedPred, icmp.getOperand(0),
icmp.getOperand(1), icmp.getTwoState()); icmp.getOperand(1), icmp.getTwoState());
// If the xor had other operands, rebuild it. // If the xor had other operands, rebuild it.
if (op.getNumOperands() > 2) { if (op.getNumOperands() > 2) {
@ -1236,7 +1239,8 @@ static void canonicalizeXorIcmpTrue(XorOp op, unsigned icmpOperand,
newOperands.pop_back(); newOperands.pop_back();
newOperands.erase(newOperands.begin() + icmpOperand); newOperands.erase(newOperands.begin() + icmpOperand);
newOperands.push_back(result); newOperands.push_back(result);
result = rewriter.create<XorOp>(op.getLoc(), newOperands, op.getTwoState()); result =
XorOp::create(rewriter, op.getLoc(), newOperands, op.getTwoState());
} }
replaceOpAndCopyNamehint(rewriter, op, result); replaceOpAndCopyNamehint(rewriter, op, result);
@ -1269,7 +1273,7 @@ LogicalResult XorOp::canonicalize(XorOp op, PatternRewriter &rewriter) {
// xor(..., c1, c2) -> xor(..., c3) where c3 = c1 ^ c2. // xor(..., c1, c2) -> xor(..., c3) where c3 = c1 ^ c2.
APInt value2; APInt value2;
if (matchPattern(inputs[size - 2], m_ConstantInt(&value2))) { if (matchPattern(inputs[size - 2], m_ConstantInt(&value2))) {
auto cst = rewriter.create<hw::ConstantOp>(op.getLoc(), value ^ value2); auto cst = hw::ConstantOp::create(rewriter, op.getLoc(), value ^ value2);
SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2)); SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2));
newOperands.push_back(cst); newOperands.push_back(cst);
replaceOpWithNewOpAndCopyNamehint<XorOp>(rewriter, op, op.getType(), replaceOpWithNewOpAndCopyNamehint<XorOp>(rewriter, op, op.getType(),
@ -1351,7 +1355,7 @@ LogicalResult SubOp::canonicalize(SubOp op, PatternRewriter &rewriter) {
// sub(x, cst) -> add(x, -cst) // sub(x, cst) -> add(x, -cst)
APInt value; APInt value;
if (matchPattern(op.getRhs(), m_ConstantInt(&value))) { if (matchPattern(op.getRhs(), m_ConstantInt(&value))) {
auto negCst = rewriter.create<hw::ConstantOp>(op.getLoc(), -value); auto negCst = hw::ConstantOp::create(rewriter, op.getLoc(), -value);
replaceOpWithNewOpAndCopyNamehint<AddOp>(rewriter, op, op.getLhs(), negCst, replaceOpWithNewOpAndCopyNamehint<AddOp>(rewriter, op, op.getLhs(), negCst,
false); false);
return success(); return success();
@ -1392,7 +1396,7 @@ LogicalResult AddOp::canonicalize(AddOp op, PatternRewriter &rewriter) {
// add(..., c1, c2) -> add(..., c3) where c3 = c1 + c2 -- constant folding // add(..., c1, c2) -> add(..., c3) where c3 = c1 + c2 -- constant folding
if (matchPattern(inputs[size - 1], m_ConstantInt(&value)) && if (matchPattern(inputs[size - 1], m_ConstantInt(&value)) &&
matchPattern(inputs[size - 2], m_ConstantInt(&value2))) { matchPattern(inputs[size - 2], m_ConstantInt(&value2))) {
auto cst = rewriter.create<hw::ConstantOp>(op.getLoc(), value + value2); auto cst = hw::ConstantOp::create(rewriter, op.getLoc(), value + value2);
SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2)); SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2));
newOperands.push_back(cst); newOperands.push_back(cst);
replaceOpWithNewOpAndCopyNamehint<AddOp>(rewriter, op, op.getType(), replaceOpWithNewOpAndCopyNamehint<AddOp>(rewriter, op, op.getType(),
@ -1404,9 +1408,9 @@ LogicalResult AddOp::canonicalize(AddOp op, PatternRewriter &rewriter) {
if (inputs[size - 1] == inputs[size - 2]) { if (inputs[size - 1] == inputs[size - 2]) {
SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2)); SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2));
auto one = rewriter.create<hw::ConstantOp>(op.getLoc(), op.getType(), 1); auto one = hw::ConstantOp::create(rewriter, op.getLoc(), op.getType(), 1);
auto shiftLeftOp = auto shiftLeftOp =
rewriter.create<comb::ShlOp>(op.getLoc(), inputs.back(), one, false); comb::ShlOp::create(rewriter, op.getLoc(), inputs.back(), one, false);
newOperands.push_back(shiftLeftOp); newOperands.push_back(shiftLeftOp);
replaceOpWithNewOpAndCopyNamehint<AddOp>(rewriter, op, op.getType(), replaceOpWithNewOpAndCopyNamehint<AddOp>(rewriter, op, op.getType(),
@ -1421,10 +1425,10 @@ LogicalResult AddOp::canonicalize(AddOp op, PatternRewriter &rewriter) {
APInt one(/*numBits=*/value.getBitWidth(), 1, /*isSigned=*/false); APInt one(/*numBits=*/value.getBitWidth(), 1, /*isSigned=*/false);
auto rhs = auto rhs =
rewriter.create<hw::ConstantOp>(op.getLoc(), (one << value) + one); hw::ConstantOp::create(rewriter, op.getLoc(), (one << value) + one);
std::array<Value, 2> factors = {shlOp.getLhs(), rhs}; std::array<Value, 2> factors = {shlOp.getLhs(), rhs};
auto mulOp = rewriter.create<comb::MulOp>(op.getLoc(), factors, false); auto mulOp = comb::MulOp::create(rewriter, op.getLoc(), factors, false);
SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2)); SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2));
newOperands.push_back(mulOp); newOperands.push_back(mulOp);
@ -1440,9 +1444,9 @@ LogicalResult AddOp::canonicalize(AddOp op, PatternRewriter &rewriter) {
matchPattern(mulOp.getInputs()[1], m_ConstantInt(&value))) { matchPattern(mulOp.getInputs()[1], m_ConstantInt(&value))) {
APInt one(/*numBits=*/value.getBitWidth(), 1, /*isSigned=*/false); APInt one(/*numBits=*/value.getBitWidth(), 1, /*isSigned=*/false);
auto rhs = rewriter.create<hw::ConstantOp>(op.getLoc(), value + one); auto rhs = hw::ConstantOp::create(rewriter, op.getLoc(), value + one);
std::array<Value, 2> factors = {mulOp.getInputs()[0], rhs}; std::array<Value, 2> factors = {mulOp.getInputs()[0], rhs};
auto newMulOp = rewriter.create<comb::MulOp>(op.getLoc(), factors, false); auto newMulOp = comb::MulOp::create(rewriter, op.getLoc(), factors, false);
SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2)); SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2));
newOperands.push_back(newMulOp); newOperands.push_back(newMulOp);
@ -1465,7 +1469,7 @@ LogicalResult AddOp::canonicalize(AddOp op, PatternRewriter &rewriter) {
matchPattern(addOp.getInputs()[1], m_ConstantInt(&value2)) && matchPattern(addOp.getInputs()[1], m_ConstantInt(&value2)) &&
inputs.size() == 2 && matchPattern(inputs[1], m_ConstantInt(&value))) { inputs.size() == 2 && matchPattern(inputs[1], m_ConstantInt(&value))) {
auto rhs = rewriter.create<hw::ConstantOp>(op.getLoc(), value + value2); auto rhs = hw::ConstantOp::create(rewriter, op.getLoc(), value + value2);
replaceOpWithNewOpAndCopyNamehint<AddOp>( replaceOpWithNewOpAndCopyNamehint<AddOp>(
rewriter, op, op.getType(), ArrayRef<Value>{addOp.getInputs()[0], rhs}, rewriter, op, op.getType(), ArrayRef<Value>{addOp.getInputs()[0], rhs},
/*twoState=*/op.getTwoState() && addOp.getTwoState()); /*twoState=*/op.getTwoState() && addOp.getTwoState());
@ -1512,10 +1516,10 @@ LogicalResult MulOp::canonicalize(MulOp op, PatternRewriter &rewriter) {
// mul(x, c) -> shl(x, log2(c)), where c is a power of two. // mul(x, c) -> shl(x, log2(c)), where c is a power of two.
if (size == 2 && matchPattern(inputs.back(), m_ConstantInt(&value)) && if (size == 2 && matchPattern(inputs.back(), m_ConstantInt(&value)) &&
value.isPowerOf2()) { value.isPowerOf2()) {
auto shift = rewriter.create<hw::ConstantOp>(op.getLoc(), op.getType(), auto shift = hw::ConstantOp::create(rewriter, op.getLoc(), op.getType(),
value.exactLogBase2()); value.exactLogBase2());
auto shlOp = auto shlOp =
rewriter.create<comb::ShlOp>(op.getLoc(), inputs[0], shift, false); comb::ShlOp::create(rewriter, op.getLoc(), inputs[0], shift, false);
replaceOpWithNewOpAndCopyNamehint<MulOp>(rewriter, op, op.getType(), replaceOpWithNewOpAndCopyNamehint<MulOp>(rewriter, op, op.getType(),
ArrayRef<Value>(shlOp), false); ArrayRef<Value>(shlOp), false);
@ -1532,7 +1536,7 @@ LogicalResult MulOp::canonicalize(MulOp op, PatternRewriter &rewriter) {
// mul(..., c1, c2) -> mul(..., c3) where c3 = c1 * c2 -- constant folding // mul(..., c1, c2) -> mul(..., c3) where c3 = c1 * c2 -- constant folding
if (matchPattern(inputs[size - 1], m_ConstantInt(&value)) && if (matchPattern(inputs[size - 1], m_ConstantInt(&value)) &&
matchPattern(inputs[size - 2], m_ConstantInt(&value2))) { matchPattern(inputs[size - 2], m_ConstantInt(&value2))) {
auto cst = rewriter.create<hw::ConstantOp>(op.getLoc(), value * value2); auto cst = hw::ConstantOp::create(rewriter, op.getLoc(), value * value2);
SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2)); SmallVector<Value, 4> newOperands(inputs.drop_back(/*n=*/2));
newOperands.push_back(cst); newOperands.push_back(cst);
replaceOpWithNewOpAndCopyNamehint<MulOp>(rewriter, op, op.getType(), replaceOpWithNewOpAndCopyNamehint<MulOp>(rewriter, op, op.getType(),
@ -1677,7 +1681,7 @@ LogicalResult ConcatOp::canonicalize(ConcatOp op, PatternRewriter &rewriter) {
resultCst |= prevCst.getValue().zext(prevWidth + thisWidth) resultCst |= prevCst.getValue().zext(prevWidth + thisWidth)
<< thisWidth; << thisWidth;
Value replacement = Value replacement =
rewriter.create<hw::ConstantOp>(op.getLoc(), resultCst); hw::ConstantOp::create(rewriter, op.getLoc(), resultCst);
return flattenConcat(i - 1, i, replacement); return flattenConcat(i - 1, i, replacement);
} }
} }
@ -1727,9 +1731,9 @@ LogicalResult ConcatOp::canonicalize(ConcatOp op, PatternRewriter &rewriter) {
if (prevExtract.getLowBit() == extract.getLowBit() + thisWidth) { if (prevExtract.getLowBit() == extract.getLowBit() + thisWidth) {
auto prevWidth = prevExtract.getType().getIntOrFloatBitWidth(); auto prevWidth = prevExtract.getType().getIntOrFloatBitWidth();
auto resType = rewriter.getIntegerType(thisWidth + prevWidth); auto resType = rewriter.getIntegerType(thisWidth + prevWidth);
Value replacement = rewriter.create<ExtractOp>( Value replacement =
op.getLoc(), resType, extract.getInput(), ExtractOp::create(rewriter, op.getLoc(), resType,
extract.getLowBit()); extract.getInput(), extract.getLowBit());
return flattenConcat(i - 1, i, replacement); return flattenConcat(i - 1, i, replacement);
} }
} }
@ -1770,11 +1774,11 @@ LogicalResult ConcatOp::canonicalize(ConcatOp op, PatternRewriter &rewriter) {
.getElementType(), .getElementType(),
extractOpt->width + prevExtractOpt->width); extractOpt->width + prevExtractOpt->width);
auto resIntType = rewriter.getIntegerType(hw::getBitWidth(resType)); auto resIntType = rewriter.getIntegerType(hw::getBitWidth(resType));
Value replacement = rewriter.create<hw::BitcastOp>( Value replacement = hw::BitcastOp::create(
op.getLoc(), resIntType, rewriter, op.getLoc(), resIntType,
rewriter.create<hw::ArraySliceOp>(op.getLoc(), resType, hw::ArraySliceOp::create(rewriter, op.getLoc(), resType,
prevExtractOpt->input, prevExtractOpt->input,
extractOpt->index)); extractOpt->index));
return flattenConcat(i - 1, i, replacement); return flattenConcat(i - 1, i, replacement);
} }
} }
@ -1976,7 +1980,7 @@ static bool foldMuxChain(MuxOp rootMux, bool isFalseSide,
// Build the array_create and the array_get. // Build the array_create and the array_get.
auto fusedLoc = rewriter.getFusedLoc(locationsFound); auto fusedLoc = rewriter.getFusedLoc(locationsFound);
auto array = rewriter.create<hw::ArrayCreateOp>(fusedLoc, table); auto array = hw::ArrayCreateOp::create(rewriter, fusedLoc, table);
replaceOpWithNewOpAndCopyNamehint<hw::ArrayGetOp>(rewriter, rootMux, array, replaceOpWithNewOpAndCopyNamehint<hw::ArrayGetOp>(rewriter, rootMux, array,
indexValue); indexValue);
return true; return true;
@ -2245,9 +2249,9 @@ static bool foldMuxOfUniformArrays(MuxOp op, PatternRewriter &rewriter) {
if (!trueVec.isUniform() || !falseVec.isUniform()) if (!trueVec.isUniform() || !falseVec.isUniform())
return false; return false;
auto mux = rewriter.create<MuxOp>( auto mux = MuxOp::create(rewriter, op.getLoc(), op.getCond(),
op.getLoc(), op.getCond(), trueVec.getUniformElement(), trueVec.getUniformElement(),
falseVec.getUniformElement(), op.getTwoState()); falseVec.getUniformElement(), op.getTwoState());
SmallVector<Value> values(trueVec.getInputs().size(), mux); SmallVector<Value> values(trueVec.getInputs().size(), mux);
rewriter.replaceOpWithNewOp<hw::ArrayCreateOp>(op, values); rewriter.replaceOpWithNewOp<hw::ArrayCreateOp>(op, values);
@ -2268,7 +2272,7 @@ static bool assumeMuxCondInOperand(Value muxCond, Value muxValue,
OpBuilder::InsertionGuard guard(rewriter); OpBuilder::InsertionGuard guard(rewriter);
rewriter.setInsertionPoint(op); rewriter.setInsertionPoint(op);
auto condValue = auto condValue =
rewriter.create<hw::ConstantOp>(muxCond.getLoc(), APInt(1, constCond)); hw::ConstantOp::create(rewriter, muxCond.getLoc(), APInt(1, constCond));
rewriter.modifyOpInPlace(op, [&] { rewriter.modifyOpInPlace(op, [&] {
for (auto &use : op->getOpOperands()) for (auto &use : op->getOpOperands())
if (use.get() == muxCond) if (use.get() == muxCond)
@ -2461,8 +2465,8 @@ LogicalResult MuxRewriter::matchAndRewrite(MuxOp op,
trueMux && falseMux && trueMux.getCond() == falseMux.getCond() && trueMux && falseMux && trueMux.getCond() == falseMux.getCond() &&
trueMux.getTrueValue() == falseMux.getTrueValue() && trueMux != op && trueMux.getTrueValue() == falseMux.getTrueValue() && trueMux != op &&
falseMux != op) { falseMux != op) {
auto subMux = rewriter.create<MuxOp>( auto subMux = MuxOp::create(
rewriter.getFusedLoc({trueMux.getLoc(), falseMux.getLoc()}), rewriter, rewriter.getFusedLoc({trueMux.getLoc(), falseMux.getLoc()}),
op.getCond(), trueMux.getFalseValue(), falseMux.getFalseValue()); op.getCond(), trueMux.getFalseValue(), falseMux.getFalseValue());
replaceOpWithNewOpAndCopyNamehint<MuxOp>(rewriter, op, trueMux.getCond(), replaceOpWithNewOpAndCopyNamehint<MuxOp>(rewriter, op, trueMux.getCond(),
trueMux.getTrueValue(), subMux, trueMux.getTrueValue(), subMux,
@ -2476,8 +2480,8 @@ LogicalResult MuxRewriter::matchAndRewrite(MuxOp op,
trueMux && falseMux && trueMux.getCond() == falseMux.getCond() && trueMux && falseMux && trueMux.getCond() == falseMux.getCond() &&
trueMux.getFalseValue() == falseMux.getFalseValue() && trueMux != op && trueMux.getFalseValue() == falseMux.getFalseValue() && trueMux != op &&
falseMux != op) { falseMux != op) {
auto subMux = rewriter.create<MuxOp>( auto subMux = MuxOp::create(
rewriter.getFusedLoc({trueMux.getLoc(), falseMux.getLoc()}), rewriter, rewriter.getFusedLoc({trueMux.getLoc(), falseMux.getLoc()}),
op.getCond(), trueMux.getTrueValue(), falseMux.getTrueValue()); op.getCond(), trueMux.getTrueValue(), falseMux.getTrueValue());
replaceOpWithNewOpAndCopyNamehint<MuxOp>(rewriter, op, trueMux.getCond(), replaceOpWithNewOpAndCopyNamehint<MuxOp>(rewriter, op, trueMux.getCond(),
subMux, trueMux.getFalseValue(), subMux, trueMux.getFalseValue(),
@ -2492,10 +2496,11 @@ LogicalResult MuxRewriter::matchAndRewrite(MuxOp op,
trueMux.getTrueValue() == falseMux.getTrueValue() && trueMux.getTrueValue() == falseMux.getTrueValue() &&
trueMux.getFalseValue() == falseMux.getFalseValue() && trueMux != op && trueMux.getFalseValue() == falseMux.getFalseValue() && trueMux != op &&
falseMux != op) { falseMux != op) {
auto subMux = rewriter.create<MuxOp>( auto subMux =
rewriter.getFusedLoc( MuxOp::create(rewriter,
{op.getLoc(), trueMux.getLoc(), falseMux.getLoc()}), rewriter.getFusedLoc(
op.getCond(), trueMux.getCond(), falseMux.getCond()); {op.getLoc(), trueMux.getLoc(), falseMux.getLoc()}),
op.getCond(), trueMux.getCond(), falseMux.getCond());
replaceOpWithNewOpAndCopyNamehint<MuxOp>( replaceOpWithNewOpAndCopyNamehint<MuxOp>(
rewriter, op, subMux, trueMux.getTrueValue(), trueMux.getFalseValue(), rewriter, op, subMux, trueMux.getTrueValue(), trueMux.getFalseValue(),
op.getTwoStateAttr()); op.getTwoStateAttr());
@ -2580,8 +2585,8 @@ static bool foldArrayOfMuxes(hw::ArrayCreateOp op, PatternRewriter &rewriter) {
// Replace the create with an aggregate operation. Push the create op // Replace the create with an aggregate operation. Push the create op
// into the operands of the aggregate operation. // into the operands of the aggregate operation.
auto arrayTy = op.getType(); auto arrayTy = op.getType();
auto trueValues = rewriter.create<hw::ArrayCreateOp>(loc, arrayTy, trues); auto trueValues = hw::ArrayCreateOp::create(rewriter, loc, arrayTy, trues);
auto falseValues = rewriter.create<hw::ArrayCreateOp>(loc, arrayTy, falses); auto falseValues = hw::ArrayCreateOp::create(rewriter, loc, arrayTy, falses);
rewriter.replaceOpWithNewOp<comb::MuxOp>(op, arrayTy, first.getCond(), rewriter.replaceOpWithNewOp<comb::MuxOp>(op, arrayTy, first.getCond(),
trueValues, falseValues, isTwoState); trueValues, falseValues, isTwoState);
return true; return true;
@ -2787,8 +2792,8 @@ static LogicalResult matchAndRewriteCompareConcat(ICmpOp op, Operation *lhs,
Value signBit = rewriter.createOrFold<ExtractOp>( Value signBit = rewriter.createOrFold<ExtractOp>(
op.getLoc(), firstNonEmptyValue, firstNonEmptyElemWidth - 1, 1); op.getLoc(), firstNonEmptyValue, firstNonEmptyElemWidth - 1, 1);
auto newLhs = rewriter.create<ConcatOp>(lhs->getLoc(), signBit, lhsOnly); auto newLhs = ConcatOp::create(rewriter, lhs->getLoc(), signBit, lhsOnly);
auto newRhs = rewriter.create<ConcatOp>(rhs->getLoc(), signBit, rhsOnly); auto newRhs = ConcatOp::create(rewriter, rhs->getLoc(), signBit, rhsOnly);
return replaceWith(op.getPredicate(), newLhs, newRhs); return replaceWith(op.getPredicate(), newLhs, newRhs);
}; };
@ -2894,8 +2899,8 @@ static void combineEqualityICmpWithKnownBitsAndConstant(
rewriter.createOrFold<ConcatOp>(operand.getLoc(), newConcatOperands); rewriter.createOrFold<ConcatOp>(operand.getLoc(), newConcatOperands);
// Form the comparison against the smaller constant. // Form the comparison against the smaller constant.
auto newConstantOp = rewriter.create<hw::ConstantOp>( auto newConstantOp = hw::ConstantOp::create(
cmpOp.getOperand(1).getLoc(), newConstant); rewriter, cmpOp.getOperand(1).getLoc(), newConstant);
replaceOpWithNewOpAndCopyNamehint<ICmpOp>(rewriter, cmpOp, replaceOpWithNewOpAndCopyNamehint<ICmpOp>(rewriter, cmpOp,
cmpOp.getPredicate(), concatResult, cmpOp.getPredicate(), concatResult,
@ -2910,14 +2915,14 @@ static void combineEqualityICmpWithXorOfConstant(ICmpOp cmpOp, XorOp xorOp,
rewriter.setInsertionPoint(xorOp); rewriter.setInsertionPoint(xorOp);
auto xorRHS = xorOp.getOperands().back().getDefiningOp<hw::ConstantOp>(); auto xorRHS = xorOp.getOperands().back().getDefiningOp<hw::ConstantOp>();
auto newRHS = rewriter.create<hw::ConstantOp>(xorRHS->getLoc(), auto newRHS = hw::ConstantOp::create(rewriter, xorRHS->getLoc(),
xorRHS.getValue() ^ rhs); xorRHS.getValue() ^ rhs);
Value newLHS; Value newLHS;
switch (xorOp.getNumOperands()) { switch (xorOp.getNumOperands()) {
case 1: case 1:
// This isn't common but is defined so we need to handle it. // This isn't common but is defined so we need to handle it.
newLHS = rewriter.create<hw::ConstantOp>(xorOp.getLoc(), newLHS = hw::ConstantOp::create(rewriter, xorOp.getLoc(),
APInt::getZero(rhs.getBitWidth())); APInt::getZero(rhs.getBitWidth()));
break; break;
case 2: case 2:
// The binary case is the most common. // The binary case is the most common.
@ -2927,7 +2932,7 @@ static void combineEqualityICmpWithXorOfConstant(ICmpOp cmpOp, XorOp xorOp,
// The general case forces us to form a new xor with the remaining operands. // The general case forces us to form a new xor with the remaining operands.
SmallVector<Value> newOperands(xorOp.getOperands()); SmallVector<Value> newOperands(xorOp.getOperands());
newOperands.pop_back(); newOperands.pop_back();
newLHS = rewriter.create<XorOp>(xorOp.getLoc(), newOperands, false); newLHS = XorOp::create(rewriter, xorOp.getLoc(), newOperands, false);
break; break;
} }
@ -2961,7 +2966,7 @@ LogicalResult ICmpOp::canonicalize(ICmpOp op, PatternRewriter &rewriter) {
// Canonicalize with RHS constant // Canonicalize with RHS constant
if (matchPattern(op.getRhs(), m_ConstantInt(&rhs))) { if (matchPattern(op.getRhs(), m_ConstantInt(&rhs))) {
auto getConstant = [&](APInt constant) -> Value { auto getConstant = [&](APInt constant) -> Value {
return rewriter.create<hw::ConstantOp>(op.getLoc(), std::move(constant)); return hw::ConstantOp::create(rewriter, op.getLoc(), std::move(constant));
}; };
auto replaceWith = [&](ICmpPredicate predicate, Value lhs, auto replaceWith = [&](ICmpPredicate predicate, Value lhs,
@ -3018,8 +3023,8 @@ LogicalResult ICmpOp::canonicalize(ICmpOp op, PatternRewriter &rewriter) {
if (rhs.countLeadingOnes() + rhs.countTrailingZeros() == if (rhs.countLeadingOnes() + rhs.countTrailingZeros() ==
rhs.getBitWidth()) { rhs.getBitWidth()) {
auto numOnes = rhs.countLeadingOnes(); auto numOnes = rhs.countLeadingOnes();
auto smaller = rewriter.create<ExtractOp>( auto smaller = ExtractOp::create(rewriter, op.getLoc(), op.getLhs(),
op.getLoc(), op.getLhs(), rhs.getBitWidth() - numOnes, numOnes); rhs.getBitWidth() - numOnes, numOnes);
return replaceWith(ICmpPredicate::ne, smaller, return replaceWith(ICmpPredicate::ne, smaller,
getConstant(APInt::getAllOnes(numOnes))); getConstant(APInt::getAllOnes(numOnes)));
} }
@ -3041,8 +3046,8 @@ LogicalResult ICmpOp::canonicalize(ICmpOp op, PatternRewriter &rewriter) {
if ((rhs + 1).isPowerOf2()) { if ((rhs + 1).isPowerOf2()) {
auto numOnes = rhs.countTrailingOnes(); auto numOnes = rhs.countTrailingOnes();
auto newWidth = rhs.getBitWidth() - numOnes; auto newWidth = rhs.getBitWidth() - numOnes;
auto smaller = rewriter.create<ExtractOp>(op.getLoc(), op.getLhs(), auto smaller = ExtractOp::create(rewriter, op.getLoc(), op.getLhs(),
numOnes, newWidth); numOnes, newWidth);
return replaceWith(ICmpPredicate::ne, smaller, return replaceWith(ICmpPredicate::ne, smaller,
getConstant(APInt::getZero(newWidth))); getConstant(APInt::getZero(newWidth)));
} }
@ -3136,9 +3141,10 @@ LogicalResult ICmpOp::canonicalize(ICmpOp op, PatternRewriter &rewriter) {
if (auto replicateOp = op.getLhs().getDefiningOp<ReplicateOp>()) if (auto replicateOp = op.getLhs().getDefiningOp<ReplicateOp>())
if (rhs.isAllOnes() || rhs.isZero()) { if (rhs.isAllOnes() || rhs.isZero()) {
auto width = replicateOp.getInput().getType().getIntOrFloatBitWidth(); auto width = replicateOp.getInput().getType().getIntOrFloatBitWidth();
auto cst = rewriter.create<hw::ConstantOp>( auto cst =
op.getLoc(), rhs.isAllOnes() ? APInt::getAllOnes(width) hw::ConstantOp::create(rewriter, op.getLoc(),
: APInt::getZero(width)); rhs.isAllOnes() ? APInt::getAllOnes(width)
: APInt::getZero(width));
replaceOpWithNewOpAndCopyNamehint<ICmpOp>( replaceOpWithNewOpAndCopyNamehint<ICmpOp>(
rewriter, op, op.getPredicate(), replicateOp.getInput(), cst, rewriter, op, op.getPredicate(), replicateOp.getInput(), cst,
op.getTwoState()); op.getTwoState());

View File

@ -32,8 +32,8 @@ Value comb::createZExt(OpBuilder &builder, Location loc, Value value,
return value; return value;
// Create a zero constant for the upper bits. // Create a zero constant for the upper bits.
auto zeros = builder.create<hw::ConstantOp>( auto zeros = hw::ConstantOp::create(
loc, builder.getIntegerType(targetWidth - inputWidth), 0); builder, loc, builder.getIntegerType(targetWidth - inputWidth), 0);
return builder.createOrFold<ConcatOp>(loc, zeros, value); return builder.createOrFold<ConcatOp>(loc, zeros, value);
} }
@ -64,7 +64,7 @@ Value comb::createOrFoldSExt(Value value, Type destTy,
Value comb::createOrFoldNot(Location loc, Value value, OpBuilder &builder, Value comb::createOrFoldNot(Location loc, Value value, OpBuilder &builder,
bool twoState) { bool twoState) {
auto allOnes = builder.create<hw::ConstantOp>(loc, value.getType(), -1); auto allOnes = hw::ConstantOp::create(builder, loc, value.getType(), -1);
return builder.createOrFold<XorOp>(loc, value, allOnes, twoState); return builder.createOrFold<XorOp>(loc, value, allOnes, twoState);
} }
@ -170,8 +170,8 @@ Value comb::createDynamicInject(OpBuilder &builder, Location loc, Value value,
// Zero-extend the offset and clear the value bits we are replacing. // Zero-extend the offset and clear the value bits we are replacing.
offset = createZExt(builder, loc, offset, largeWidth); offset = createZExt(builder, loc, offset, largeWidth);
Value mask = builder.create<hw::ConstantOp>( Value mask = hw::ConstantOp::create(
loc, APInt::getLowBitsSet(largeWidth, smallWidth)); builder, loc, APInt::getLowBitsSet(largeWidth, smallWidth));
mask = builder.createOrFold<comb::ShlOp>(loc, mask, offset); mask = builder.createOrFold<comb::ShlOp>(loc, mask, offset);
mask = createOrFoldNot(loc, mask, builder, true); mask = createOrFoldNot(loc, mask, builder, true);
value = builder.createOrFold<comb::AndOp>(loc, value, mask, twoState); value = builder.createOrFold<comb::AndOp>(loc, value, mask, twoState);
@ -205,14 +205,15 @@ Value comb::createInject(OpBuilder &builder, Location loc, Value value,
auto end = offset + smallWidth; auto end = offset + smallWidth;
if (end < largeWidth) if (end < largeWidth)
fragments.push_back( fragments.push_back(
builder.create<comb::ExtractOp>(loc, value, end, largeWidth - end)); comb::ExtractOp::create(builder, loc, value, end, largeWidth - end));
if (end <= largeWidth) if (end <= largeWidth)
fragments.push_back(replacement); fragments.push_back(replacement);
else else
fragments.push_back(builder.create<comb::ExtractOp>(loc, replacement, 0, fragments.push_back(comb::ExtractOp::create(builder, loc, replacement, 0,
largeWidth - offset)); largeWidth - offset));
if (offset > 0) if (offset > 0)
fragments.push_back(builder.create<comb::ExtractOp>(loc, value, 0, offset)); fragments.push_back(
comb::ExtractOp::create(builder, loc, value, 0, offset));
return builder.createOrFold<comb::ConcatOp>(loc, fragments); return builder.createOrFold<comb::ConcatOp>(loc, fragments);
} }
@ -237,7 +238,7 @@ SmallVector<Value>
comb::wallaceReduction(OpBuilder &builder, Location loc, size_t width, comb::wallaceReduction(OpBuilder &builder, Location loc, size_t width,
size_t targetAddends, size_t targetAddends,
SmallVector<SmallVector<Value>> &addends) { SmallVector<SmallVector<Value>> &addends) {
auto falseValue = builder.create<hw::ConstantOp>(loc, APInt(1, 0)); auto falseValue = hw::ConstantOp::create(builder, loc, APInt(1, 0));
SmallVector<SmallVector<Value>> newAddends; SmallVector<SmallVector<Value>> newAddends;
newAddends.reserve(addends.size()); newAddends.reserve(addends.size());
// Continue reduction until we have only two rows. The length of // Continue reduction until we have only two rows. The length of
@ -285,11 +286,11 @@ comb::wallaceReduction(OpBuilder &builder, Location loc, size_t width,
for (auto &addend : addends) { for (auto &addend : addends) {
// Reverse the order of the bits // Reverse the order of the bits
std::reverse(addend.begin(), addend.end()); std::reverse(addend.begin(), addend.end());
carrySave.push_back(builder.create<comb::ConcatOp>(loc, addend)); carrySave.push_back(comb::ConcatOp::create(builder, loc, addend));
} }
// Pad with zeros // Pad with zeros
auto zero = builder.create<hw::ConstantOp>(loc, APInt(width, 0)); auto zero = hw::ConstantOp::create(builder, loc, APInt(width, 0));
while (carrySave.size() < targetAddends) while (carrySave.size() < targetAddends)
carrySave.push_back(zero); carrySave.push_back(zero);

View File

@ -89,16 +89,16 @@ struct CombOpNarrow : public OpRewritePattern<CombOpTy> {
// Extract the lsbs from each operand // Extract the lsbs from each operand
auto extractLhsOp = auto extractLhsOp =
rewriter.create<comb::ExtractOp>(loc, replaceType, lhs, 0); comb::ExtractOp::create(rewriter, loc, replaceType, lhs, 0);
auto extractRhsOp = auto extractRhsOp =
rewriter.create<comb::ExtractOp>(loc, replaceType, rhs, 0); comb::ExtractOp::create(rewriter, loc, replaceType, rhs, 0);
auto narrowOp = rewriter.create<CombOpTy>(loc, extractLhsOp, extractRhsOp); auto narrowOp = CombOpTy::create(rewriter, loc, extractLhsOp, extractRhsOp);
// Concatenate zeros to match the original operator width // Concatenate zeros to match the original operator width
auto zero = auto zero =
rewriter.create<hw::ConstantOp>(loc, APInt::getZero(removeWidth)); hw::ConstantOp::create(rewriter, loc, APInt::getZero(removeWidth));
auto replaceOp = rewriter.create<comb::ConcatOp>( auto replaceOp = comb::ConcatOp::create(rewriter, loc, op.getType(),
loc, op.getType(), ValueRange{zero, narrowOp}); ValueRange{zero, narrowOp});
rewriter.replaceOp(op, replaceOp); rewriter.replaceOp(op, replaceOp);
return success(); return success();

View File

@ -42,7 +42,7 @@ private:
getMux(loc, b, t, f, table.drop_front(half), inputs.drop_front()); getMux(loc, b, t, f, table.drop_front(half), inputs.drop_front());
Value if0 = Value if0 =
getMux(loc, b, t, f, table.drop_back(half), inputs.drop_front()); getMux(loc, b, t, f, table.drop_back(half), inputs.drop_front());
return b.create<MuxOp>(loc, inputs.front(), if1, if0, false); return MuxOp::create(b, loc, inputs.front(), if1, if0, false);
} }
public: public:
@ -52,8 +52,10 @@ public:
SmallVector<bool> table( SmallVector<bool> table(
llvm::map_range(op.getLookupTableAttr().getAsValueRange<IntegerAttr>(), llvm::map_range(op.getLookupTableAttr().getAsValueRange<IntegerAttr>(),
[](const APInt &a) { return !a.isZero(); })); [](const APInt &a) { return !a.isZero(); }));
Value t = b.create<hw::ConstantOp>(loc, b.getIntegerAttr(b.getI1Type(), 1)); Value t =
Value f = b.create<hw::ConstantOp>(loc, b.getIntegerAttr(b.getI1Type(), 0)); hw::ConstantOp::create(b, loc, b.getIntegerAttr(b.getI1Type(), 1));
Value f =
hw::ConstantOp::create(b, loc, b.getIntegerAttr(b.getI1Type(), 0));
Value tree = getMux(loc, b, t, f, table, op.getInputs()); Value tree = getMux(loc, b, t, f, table, op.getInputs());
b.modifyOpInPlace(tree.getDefiningOp(), [&]() { b.modifyOpInPlace(tree.getDefiningOp(), [&]() {

View File

@ -83,7 +83,7 @@ struct JoinOnBranchPattern : public OpRewritePattern<JoinOp> {
// Unpack the !dc.value<i1> input to the branch op // Unpack the !dc.value<i1> input to the branch op
auto unpacked = auto unpacked =
rewriter.create<UnpackOp>(op.getLoc(), branch.getCondition()); UnpackOp::create(rewriter, op.getLoc(), branch.getCondition());
rewriter.modifyOpInPlace(op, [&]() { rewriter.modifyOpInPlace(op, [&]() {
op->eraseOperands(operandInfo.indices); op->eraseOperands(operandInfo.indices);
op.getTokensMutable().append({unpacked.getToken()}); op.getTokensMutable().append({unpacked.getToken()});
@ -219,8 +219,8 @@ public:
// adding more outputs to the current fork. // adding more outputs to the current fork.
size_t totalForks = fork.getNumResults() + userFork.getNumResults(); size_t totalForks = fork.getNumResults() + userFork.getNumResults();
auto newFork = rewriter.create<dc::ForkOp>(fork.getLoc(), auto newFork = dc::ForkOp::create(rewriter, fork.getLoc(),
fork.getToken(), totalForks); fork.getToken(), totalForks);
rewriter.replaceOp( rewriter.replaceOp(
fork, newFork.getResults().take_front(fork.getNumResults())); fork, newFork.getResults().take_front(fork.getNumResults()));
rewriter.replaceOp( rewriter.replaceOp(
@ -252,7 +252,7 @@ public:
// each output. // each output.
llvm::SmallVector<Value> sources; llvm::SmallVector<Value> sources;
for (size_t i = 0; i < fork.getNumResults(); ++i) for (size_t i = 0; i < fork.getNumResults(); ++i)
sources.push_back(rewriter.create<dc::SourceOp>(fork.getLoc())); sources.push_back(dc::SourceOp::create(rewriter, fork.getLoc()));
rewriter.replaceOp(fork, sources); rewriter.replaceOp(fork, sources);
return success(); return success();
@ -276,8 +276,8 @@ struct EliminateUnusedForkResultsPattern : mlir::OpRewritePattern<ForkOp> {
// Create a new fork op, dropping the unused results. // Create a new fork op, dropping the unused results.
rewriter.setInsertionPoint(op); rewriter.setInsertionPoint(op);
auto operand = op.getOperand(); auto operand = op.getOperand();
auto newFork = rewriter.create<ForkOp>( auto newFork = ForkOp::create(rewriter, op.getLoc(), operand,
op.getLoc(), operand, op.getNumResults() - unusedIndexes.size()); op.getNumResults() - unusedIndexes.size());
unsigned i = 0; unsigned i = 0;
for (auto oldRes : llvm::enumerate(op.getResults())) for (auto oldRes : llvm::enumerate(op.getResults()))
if (unusedIndexes.count(oldRes.index()) == 0) if (unusedIndexes.count(oldRes.index()) == 0)
@ -414,11 +414,10 @@ public:
rewriter.replaceOpWithNewOp<JoinOp>( rewriter.replaceOpWithNewOp<JoinOp>(
select, select,
llvm::SmallVector<Value>{ llvm::SmallVector<Value>{
rewriter.create<UnpackOp>(select.getLoc(), select.getCondition()) UnpackOp::create(rewriter, select.getLoc(), select.getCondition())
.getToken(), .getToken(),
rewriter UnpackOp::create(rewriter, branchInput.getLoc(),
.create<UnpackOp>(branchInput.getLoc(), branchInput.getCondition())
branchInput.getCondition())
.getToken()}); .getToken()});
return success(); return success();

View File

@ -43,10 +43,10 @@ static void insertSink(Value v, OpBuilder &rewriter) {
rewriter.setInsertionPointAfterValue(v); rewriter.setInsertionPointAfterValue(v);
if (isa<ValueType>(v.getType())) { if (isa<ValueType>(v.getType())) {
// Unpack before sinking // Unpack before sinking
v = rewriter.create<UnpackOp>(v.getLoc(), v).getToken(); v = UnpackOp::create(rewriter, v.getLoc(), v).getToken();
} }
rewriter.create<SinkOp>(v.getLoc(), v); SinkOp::create(rewriter, v.getLoc(), v);
} }
// Adds a fork of the provided token or value-typed Value `result`. // Adds a fork of the provided token or value-typed Value `result`.
@ -61,14 +61,14 @@ static void insertFork(Value result, OpBuilder &rewriter) {
Value token = result; Value token = result;
Value value; Value value;
if (isValue) { if (isValue) {
auto unpack = rewriter.create<UnpackOp>(result.getLoc(), result); auto unpack = UnpackOp::create(rewriter, result.getLoc(), result);
token = unpack.getToken(); token = unpack.getToken();
value = unpack.getOutput(); value = unpack.getOutput();
} }
// Insert fork after op // Insert fork after op
auto forkSize = opsToProcess.size(); auto forkSize = opsToProcess.size();
auto newFork = rewriter.create<ForkOp>(token.getLoc(), token, forkSize); auto newFork = ForkOp::create(rewriter, token.getLoc(), token, forkSize);
// Modify operands of successor // Modify operands of successor
// opsToProcess may have multiple instances of same operand // opsToProcess may have multiple instances of same operand
@ -76,8 +76,8 @@ static void insertFork(Value result, OpBuilder &rewriter) {
for (auto [op, forkOutput] : llvm::zip(opsToProcess, newFork->getResults())) { for (auto [op, forkOutput] : llvm::zip(opsToProcess, newFork->getResults())) {
Value forkRes = forkOutput; Value forkRes = forkOutput;
if (isValue) if (isValue)
forkRes = forkRes = PackOp::create(rewriter, forkRes.getLoc(), forkRes, value)
rewriter.create<PackOp>(forkRes.getLoc(), forkRes, value).getOutput(); .getOutput();
replaceFirstUse(op, result, forkRes); replaceFirstUse(op, result, forkRes);
} }
} }

View File

@ -158,8 +158,8 @@ struct FoldAddIntoCompress : public OpRewritePattern<comb::AddOp> {
return failure(); return failure();
// Create a new CompressOp with all collected operands // Create a new CompressOp with all collected operands
auto newCompressOp = rewriter.create<datapath::CompressOp>( auto newCompressOp = datapath::CompressOp::create(rewriter, addOp.getLoc(),
addOp.getLoc(), newCompressOperands, 2); newCompressOperands, 2);
// Replace the original AddOp with a new add(compress(inputs)) // Replace the original AddOp with a new add(compress(inputs))
rewriter.replaceOpWithNewOp<comb::AddOp>(addOp, newCompressOp.getResults(), rewriter.replaceOpWithNewOp<comb::AddOp>(addOp, newCompressOp.getResults(),
@ -235,11 +235,11 @@ struct ReduceNumPartialProducts : public OpRewritePattern<PartialProductOp> {
maxNonZeroBits = std::max(maxNonZeroBits, nonZeroBits); maxNonZeroBits = std::max(maxNonZeroBits, nonZeroBits);
} }
auto newPP = rewriter.create<datapath::PartialProductOp>( auto newPP = datapath::PartialProductOp::create(
op.getLoc(), op.getOperands(), maxNonZeroBits); rewriter, op.getLoc(), op.getOperands(), maxNonZeroBits);
auto zero = rewriter.create<hw::ConstantOp>(op.getLoc(), auto zero = hw::ConstantOp::create(rewriter, op.getLoc(),
APInt::getZero(inputWidth)); APInt::getZero(inputWidth));
// Collect newPP results and pad with zeros if needed // Collect newPP results and pad with zeros if needed
SmallVector<Value> newResults(newPP.getResults().begin(), SmallVector<Value> newResults(newPP.getResults().begin(),

View File

@ -42,7 +42,7 @@ void ESIDialect::initialize() {
Operation *ESIDialect::materializeConstant(OpBuilder &builder, Attribute value, Operation *ESIDialect::materializeConstant(OpBuilder &builder, Attribute value,
Type type, Location loc) { Type type, Location loc) {
if (isa<mlir::UnitAttr>(value)) if (isa<mlir::UnitAttr>(value))
return builder.create<hw::ConstantOp>(loc, builder.getI1Type(), 1); return hw::ConstantOp::create(builder, loc, builder.getI1Type(), 1);
return builder.getContext() return builder.getContext()
->getOrLoadDialect<hw::HWDialect>() ->getOrLoadDialect<hw::HWDialect>()
->materializeConstant(builder, value, type, loc); ->materializeConstant(builder, value, type, loc);

View File

@ -21,7 +21,7 @@ LogicalResult WrapValidReadyOp::fold(FoldAdaptor,
return failure(); return failure();
OpBuilder builder(getContext()); OpBuilder builder(getContext());
results.push_back( results.push_back(
builder.create<NullSourceOp>(getLoc(), getChanOutput().getType()) NullSourceOp::create(builder, getLoc(), getChanOutput().getType())
.getOut()); .getOut());
results.push_back(IntegerAttr::get(IntegerType::get(getContext(), 1), 1)); results.push_back(IntegerAttr::get(IntegerType::get(getContext(), 1), 1));
return success(); return success();
@ -51,7 +51,7 @@ LogicalResult WrapFIFOOp::fold(FoldAdaptor,
OpBuilder builder(getContext()); OpBuilder builder(getContext());
results.push_back( results.push_back(
builder.create<NullSourceOp>(getLoc(), getChanOutput().getType()) NullSourceOp::create(builder, getLoc(), getChanOutput().getType())
.getOut()); .getOut());
results.push_back(IntegerAttr::get( results.push_back(IntegerAttr::get(
IntegerType::get(getContext(), 1, IntegerType::Signless), 0)); IntegerType::get(getContext(), 1, IntegerType::Signless), 0));

View File

@ -107,15 +107,15 @@ instantiateCosimEndpointOps(ServiceImplementReqOp implReq,
fromHostType = b.getType<ChannelType>(fromHostType.getInner(), fromHostType = b.getType<ChannelType>(fromHostType.getInner(),
ChannelSignaling::ValidReady, ChannelSignaling::ValidReady,
fromHostType.getDataDelay()); fromHostType.getDataDelay());
auto cosim = b.create<CosimFromHostEndpointOp>( auto cosim = CosimFromHostEndpointOp::create(
loc, fromHostType, clk, rst, b, loc, fromHostType, clk, rst,
toStringAttr(req.getRelativeAppIDPathAttr(), ch.name)); toStringAttr(req.getRelativeAppIDPathAttr(), ch.name));
mlir::TypedValue<ChannelType> fromHost = cosim.getFromHost(); mlir::TypedValue<ChannelType> fromHost = cosim.getFromHost();
if (fromHostType.getSignaling() == ChannelSignaling::FIFO) if (fromHostType.getSignaling() == ChannelSignaling::FIFO)
fromHost = b.create<ChannelBufferOp>( fromHost = ChannelBufferOp::create(
loc, ch.type, clk, rst, fromHost, b, loc, ch.type, clk, rst, fromHost,
/*stages=*/b.getIntegerAttr(b.getI64Type(), 1), /*stages=*/b.getIntegerAttr(b.getI64Type(), 1),
/*name=*/StringAttr()) /*name=*/StringAttr())
.getOutput(); .getOutput();
toServerValues.push_back(fromHost); toServerValues.push_back(fromHost);
channelAssignments.push_back(getAssignment(ch.name, cosim.getIdAttr())); channelAssignments.push_back(getAssignment(ch.name, cosim.getIdAttr()));
@ -123,7 +123,7 @@ instantiateCosimEndpointOps(ServiceImplementReqOp implReq,
} }
auto pack = auto pack =
b.create<PackBundleOp>(implReq.getLoc(), bundleType, toServerValues); PackBundleOp::create(b, implReq.getLoc(), bundleType, toServerValues);
implReq.getResult(toClientResultNum[req]) implReq.getResult(toClientResultNum[req])
.replaceAllUsesWith(pack.getBundle()); .replaceAllUsesWith(pack.getBundle());
@ -136,23 +136,23 @@ instantiateCosimEndpointOps(ServiceImplementReqOp implReq,
auto cosimType = b.getType<ChannelType>(chType.getInner(), auto cosimType = b.getType<ChannelType>(chType.getInner(),
ChannelSignaling::ValidReady, ChannelSignaling::ValidReady,
chType.getDataDelay()); chType.getDataDelay());
fromChannel = b.create<ChannelBufferOp>( fromChannel = ChannelBufferOp::create(
loc, cosimType, clk, rst, fromChannel, b, loc, cosimType, clk, rst, fromChannel,
/*stages=*/b.getIntegerAttr(b.getI64Type(), 1), /*stages=*/b.getIntegerAttr(b.getI64Type(), 1),
/*name=*/StringAttr()) /*name=*/StringAttr())
.getOutput(); .getOutput();
} }
auto cosim = b.create<CosimToHostEndpointOp>( auto cosim = CosimToHostEndpointOp::create(
loc, clk, rst, fromChannel, b, loc, clk, rst, fromChannel,
toStringAttr(req.getRelativeAppIDPathAttr(), ch.name)); toStringAttr(req.getRelativeAppIDPathAttr(), ch.name));
channelAssignments.push_back(getAssignment(ch.name, cosim.getIdAttr())); channelAssignments.push_back(getAssignment(ch.name, cosim.getIdAttr()));
} }
} }
implRecords.create<ServiceImplClientRecordOp>( ServiceImplClientRecordOp::create(
req.getLoc(), req.getRelativeAppIDPathAttr(), req.getServicePortAttr(), implRecords, req.getLoc(), req.getRelativeAppIDPathAttr(),
TypeAttr::get(bundleType), b.getDictionaryAttr(channelAssignments), req.getServicePortAttr(), TypeAttr::get(bundleType),
DictionaryAttr()); b.getDictionaryAttr(channelAssignments), DictionaryAttr());
} }
// Erase the generation request. // Erase the generation request.
@ -186,10 +186,10 @@ instantiateSystemVerilogMemory(ServiceImplementReqOp implReq,
auto rst = implReq.getOperand(1); auto rst = implReq.getOperand(1);
auto write = b.getStringAttr("write"); auto write = b.getStringAttr("write");
auto read = b.getStringAttr("read"); auto read = b.getStringAttr("read");
auto none = b.create<hw::ConstantOp>( auto none = hw::ConstantOp::create(
APInt(/*numBits*/ 0, /*val*/ 0, /*isSigned*/ false)); b, APInt(/*numBits*/ 0, /*val*/ 0, /*isSigned*/ false));
auto i1 = b.getI1Type(); auto i1 = b.getI1Type();
auto c0 = b.create<hw::ConstantOp>(i1, 0); auto c0 = hw::ConstantOp::create(b, i1, 0);
// List of reqs which have a result. // List of reqs which have a result.
SmallVector<ServiceImplementConnReqOp, 8> toClientReqs( SmallVector<ServiceImplementConnReqOp, 8> toClientReqs(
@ -211,7 +211,7 @@ instantiateSystemVerilogMemory(ServiceImplementReqOp implReq,
hw::UnpackedArrayType memType = hw::UnpackedArrayType memType =
hw::UnpackedArrayType::get(ramDecl.getInnerType(), ramDecl.getDepth()); hw::UnpackedArrayType::get(ramDecl.getInnerType(), ramDecl.getDepth());
auto mem = auto mem =
b.create<sv::RegOp>(memType, implReq.getServiceSymbolAttr().getAttr()) sv::RegOp::create(b, memType, implReq.getServiceSymbolAttr().getAttr())
.getResult(); .getResult();
// Do everything which doesn't actually write to the memory, store the signals // Do everything which doesn't actually write to the memory, store the signals
@ -226,30 +226,30 @@ instantiateSystemVerilogMemory(ServiceImplementReqOp implReq,
// Construct the response channel. // Construct the response channel.
auto doneValid = bb.get(i1); auto doneValid = bb.get(i1);
auto ackChannel = b.create<WrapValidReadyOp>(none, doneValid); auto ackChannel = WrapValidReadyOp::create(b, none, doneValid);
auto pack = auto pack =
b.create<PackBundleOp>(implReq.getLoc(), req.getToClient().getType(), PackBundleOp::create(b, implReq.getLoc(), req.getToClient().getType(),
ackChannel.getChanOutput()); ackChannel.getChanOutput());
Value toServer = Value toServer =
pack.getFromChannels()[RandomAccessMemoryDeclOp::ReqDirChannelIdx]; pack.getFromChannels()[RandomAccessMemoryDeclOp::ReqDirChannelIdx];
toClientResp = pack.getBundle(); toClientResp = pack.getBundle();
// Unwrap the write request and 'explode' the struct. // Unwrap the write request and 'explode' the struct.
auto unwrap = auto unwrap =
b.create<UnwrapValidReadyOp>(toServer, ackChannel.getReady()); UnwrapValidReadyOp::create(b, toServer, ackChannel.getReady());
Value address = b.create<hw::StructExtractOp>(unwrap.getRawOutput(), Value address = hw::StructExtractOp::create(b, unwrap.getRawOutput(),
b.getStringAttr("address")); b.getStringAttr("address"));
Value data = b.create<hw::StructExtractOp>(unwrap.getRawOutput(), Value data = hw::StructExtractOp::create(b, unwrap.getRawOutput(),
b.getStringAttr("data")); b.getStringAttr("data"));
// Determine if the write should occur this cycle. // Determine if the write should occur this cycle.
auto go = b.create<comb::AndOp>(unwrap.getValid(), unwrap.getReady()); auto go = comb::AndOp::create(b, unwrap.getValid(), unwrap.getReady());
go->setAttr("sv.namehint", b.getStringAttr("write_go")); go->setAttr("sv.namehint", b.getStringAttr("write_go"));
// Register the 'go' signal and use it as the done message. // Register the 'go' signal and use it as the done message.
doneValid.setValue( doneValid.setValue(
b.create<seq::CompRegOp>(go, clk, rst, c0, "write_done")); seq::CompRegOp::create(b, go, clk, rst, c0, "write_done"));
// Store the necessary data for the 'always' memory writing block. // Store the necessary data for the 'always' memory writing block.
writeGoAddressData.push_back(std::make_tuple(go, address, data)); writeGoAddressData.push_back(std::make_tuple(go, address, data));
@ -259,24 +259,24 @@ instantiateSystemVerilogMemory(ServiceImplementReqOp implReq,
// Construct the response channel. // Construct the response channel.
auto dataValid = bb.get(i1); auto dataValid = bb.get(i1);
auto data = bb.get(ramDecl.getInnerType()); auto data = bb.get(ramDecl.getInnerType());
auto dataChannel = b.create<WrapValidReadyOp>(data, dataValid); auto dataChannel = WrapValidReadyOp::create(b, data, dataValid);
auto pack = auto pack =
b.create<PackBundleOp>(implReq.getLoc(), req.getToClient().getType(), PackBundleOp::create(b, implReq.getLoc(), req.getToClient().getType(),
dataChannel.getChanOutput()); dataChannel.getChanOutput());
Value toServer = Value toServer =
pack.getFromChannels()[RandomAccessMemoryDeclOp::RespDirChannelIdx]; pack.getFromChannels()[RandomAccessMemoryDeclOp::RespDirChannelIdx];
toClientResp = pack.getBundle(); toClientResp = pack.getBundle();
// Unwrap the requested address and read from that memory location. // Unwrap the requested address and read from that memory location.
auto addressUnwrap = auto addressUnwrap =
b.create<UnwrapValidReadyOp>(toServer, dataChannel.getReady()); UnwrapValidReadyOp::create(b, toServer, dataChannel.getReady());
Value unsignedAddress = addressUnwrap.getRawOutput(); Value unsignedAddress = addressUnwrap.getRawOutput();
Value signlessAddress = b.create<hw::BitcastOp>( Value signlessAddress = hw::BitcastOp::create(
b.getIntegerType(llvm::Log2_64_Ceil(ramDecl.getDepth())), b, b.getIntegerType(llvm::Log2_64_Ceil(ramDecl.getDepth())),
unsignedAddress); unsignedAddress);
Value memLoc = b.create<sv::ArrayIndexInOutOp>(mem, signlessAddress); Value memLoc = sv::ArrayIndexInOutOp::create(b, mem, signlessAddress);
auto readData = b.create<sv::ReadInOutOp>(memLoc); auto readData = sv::ReadInOutOp::create(b, memLoc);
// Set the data on the response. // Set the data on the response.
data.setValue(readData); data.setValue(readData);
@ -289,19 +289,19 @@ instantiateSystemVerilogMemory(ServiceImplementReqOp implReq,
} }
// Now construct the memory writes. // Now construct the memory writes.
auto hwClk = b.create<seq::FromClockOp>(clk); auto hwClk = seq::FromClockOp::create(b, clk);
b.create<sv::AlwaysFFOp>( sv::AlwaysFFOp::create(
sv::EventControl::AtPosEdge, hwClk, sv::ResetType::SyncReset, b, sv::EventControl::AtPosEdge, hwClk, sv::ResetType::SyncReset,
sv::EventControl::AtPosEdge, rst, [&] { sv::EventControl::AtPosEdge, rst, [&] {
for (auto [go, address, data] : writeGoAddressData) { for (auto [go, address, data] : writeGoAddressData) {
Value a = address, d = data; // So the lambda can capture. Value a = address, d = data; // So the lambda can capture.
// If we're told to go, do the write. // If we're told to go, do the write.
b.create<sv::IfOp>(go, [&] { sv::IfOp::create(b, go, [&] {
Value signlessAddress = b.create<hw::BitcastOp>( Value signlessAddress = hw::BitcastOp::create(
b.getIntegerType(llvm::Log2_64_Ceil(ramDecl.getDepth())), a); b, b.getIntegerType(llvm::Log2_64_Ceil(ramDecl.getDepth())), a);
Value memLoc = Value memLoc =
b.create<sv::ArrayIndexInOutOp>(mem, signlessAddress); sv::ArrayIndexInOutOp::create(b, mem, signlessAddress);
b.create<sv::PAssignOp>(memLoc, d); sv::PAssignOp::create(b, memLoc, d);
}); });
} }
}); });
@ -330,8 +330,8 @@ ServiceGeneratorDispatcher::generate(ServiceImplementReqOp req,
// Since we always need a record of generation, create it here then pass it to // Since we always need a record of generation, create it here then pass it to
// the generator for possible modification. // the generator for possible modification.
OpBuilder b(req); OpBuilder b(req);
auto implRecord = b.create<ServiceImplRecordOp>( auto implRecord = ServiceImplRecordOp::create(
req.getLoc(), req.getAppID(), /*isEngine=*/false, b, req.getLoc(), req.getAppID(), /*isEngine=*/false,
req.getServiceSymbolAttr(), req.getStdServiceAttr(), req.getServiceSymbolAttr(), req.getStdServiceAttr(),
req.getImplTypeAttr(), b.getDictionaryAttr({})); req.getImplTypeAttr(), b.getDictionaryAttr({}));
implRecord.getReqDetails().emplaceBlock(); implRecord.getReqDetails().emplaceBlock();
@ -491,15 +491,15 @@ StringAttr ESIConnectServicesPass::getStdService(FlatSymbolRefAttr svcSym) {
void ESIConnectServicesPass::convertReq(RequestConnectionOp req) { void ESIConnectServicesPass::convertReq(RequestConnectionOp req) {
OpBuilder b(req); OpBuilder b(req);
auto newReq = b.create<ServiceImplementConnReqOp>( auto newReq = ServiceImplementConnReqOp::create(
req.getLoc(), req.getToClient().getType(), req.getServicePortAttr(), b, req.getLoc(), req.getToClient().getType(), req.getServicePortAttr(),
ArrayAttr::get(&getContext(), {req.getAppIDAttr()})); ArrayAttr::get(&getContext(), {req.getAppIDAttr()}));
newReq->setDialectAttrs(req->getDialectAttrs()); newReq->setDialectAttrs(req->getDialectAttrs());
req.getToClient().replaceAllUsesWith(newReq.getToClient()); req.getToClient().replaceAllUsesWith(newReq.getToClient());
// Emit a record of the original request. // Emit a record of the original request.
b.create<ServiceRequestRecordOp>( ServiceRequestRecordOp::create(
req.getLoc(), req.getAppID(), req.getServicePortAttr(), b, req.getLoc(), req.getAppID(), req.getServicePortAttr(),
getStdService(req.getServicePortAttr().getModuleRef()), getStdService(req.getServicePortAttr().getModuleRef()),
req.getToClient().getType()); req.getToClient().getType());
req.erase(); req.erase();
@ -523,7 +523,7 @@ LogicalResult ESIConnectServicesPass::process(hw::HWModuleLike mod) {
// location of the values), get the pointer to the default service instance, // location of the values), get the pointer to the default service instance,
// if any. // if any.
llvm::SetVector<ServiceImplementConnReqOp> *anyServiceInst = nullptr; llvm::SetVector<ServiceImplementConnReqOp> *anyServiceInst = nullptr;
if (auto defaultService = localImplReqs.find(SymbolRefAttr()); if (auto *defaultService = localImplReqs.find(SymbolRefAttr());
defaultService != localImplReqs.end()) defaultService != localImplReqs.end())
anyServiceInst = &defaultService->second; anyServiceInst = &defaultService->second;
@ -532,7 +532,7 @@ LogicalResult ESIConnectServicesPass::process(hw::HWModuleLike mod) {
for (auto req : llvm::make_early_inc_range( for (auto req : llvm::make_early_inc_range(
mod.getBodyBlock()->getOps<ServiceImplementConnReqOp>())) { mod.getBodyBlock()->getOps<ServiceImplementConnReqOp>())) {
auto service = req.getServicePort().getModuleRef(); auto service = req.getServicePort().getModuleRef();
auto reqListIter = localImplReqs.find(service); auto *reqListIter = localImplReqs.find(service);
if (reqListIter != localImplReqs.end()) if (reqListIter != localImplReqs.end())
reqListIter->second.insert(req); reqListIter->second.insert(req);
else if (anyServiceInst) else if (anyServiceInst)
@ -590,8 +590,8 @@ LogicalResult ESIConnectServicesPass::replaceInst(
// Create the generation request op. // Create the generation request op.
OpBuilder b(instOp); OpBuilder b(instOp);
auto implOp = b.create<ServiceImplementReqOp>( auto implOp = ServiceImplementReqOp::create(
instOp.getLoc(), resultTypes, instOp.getAppIDAttr(), b, instOp.getLoc(), resultTypes, instOp.getAppIDAttr(),
instOp.getServiceSymbolAttr(), instOp.getImplTypeAttr(), instOp.getServiceSymbolAttr(), instOp.getImplTypeAttr(),
getStdService(declSym), instOp.getImplOptsAttr(), instOp.getOperands()); getStdService(declSym), instOp.getImplOptsAttr(), instOp.getOperands());
implOp->setDialectAttrs(instOp->getDialectAttrs()); implOp->setDialectAttrs(instOp->getDialectAttrs());
@ -691,9 +691,9 @@ ESIConnectServicesPass::surfaceReqs(hw::HWMutableModuleLike mod,
appIDPath = prependNamePart(appIDPath, instAppID); appIDPath = prependNamePart(appIDPath, instAppID);
// Clone the request. // Clone the request.
auto clone = b.create<ServiceImplementConnReqOp>( auto clone = ServiceImplementConnReqOp::create(
req.getLoc(), req.getToClient().getType(), req.getServicePortAttr(), b, req.getLoc(), req.getToClient().getType(),
appIDPath); req.getServicePortAttr(), appIDPath);
clone->setDialectAttrs(req->getDialectAttrs()); clone->setDialectAttrs(req->getDialectAttrs());
newOperands.push_back(clone.getToClient()); newOperands.push_back(clone.getToClient());
} }

View File

@ -41,19 +41,19 @@ private:
// Check if we need to create a root node. // Check if we need to create a root node.
if (path.getPath().empty()) { if (path.getPath().empty()) {
auto rootOp = OpBuilder::atBlockEnd(getOperation().getBody()) auto builder = OpBuilder::atBlockEnd(getOperation().getBody());
.create<AppIDHierRootOp>(UnknownLoc::get(&getContext()), auto rootOp = AppIDHierRootOp::create(
path.getRoot()); builder, UnknownLoc::get(&getContext()), path.getRoot());
block = &rootOp.getChildren().emplaceBlock(); block = &rootOp.getChildren().emplaceBlock();
} else { } else {
Block *parentBlock = getBlock(path.getParent(), opStack.drop_back()); Block *parentBlock = getBlock(path.getParent(), opStack.drop_back());
Operation *op = opStack.back(); Operation *op = opStack.back();
if (auto inst = dyn_cast<hw::InstanceOp>(op)) { if (auto inst = dyn_cast<hw::InstanceOp>(op)) {
// Create a normal node underneath the parent AppID. // Create a normal node underneath the parent AppID.
auto node = OpBuilder::atBlockEnd(parentBlock) auto builder = OpBuilder::atBlockEnd(parentBlock);
.create<AppIDHierNodeOp>(UnknownLoc::get(&getContext()), auto node = AppIDHierNodeOp::create(
path.getPath().back(), builder, UnknownLoc::get(&getContext()), path.getPath().back(),
inst.getModuleNameAttr()); inst.getModuleNameAttr());
block = &node.getChildren().emplaceBlock(); block = &node.getChildren().emplaceBlock();
} else { } else {
block = parentBlock; block = parentBlock;

View File

@ -123,8 +123,8 @@ void ESIBuildManifestPass::runOnOperation() {
->getRegion(0) ->getRegion(0)
.front() .front()
.getTerminator()); .getTerminator());
b.create<CompressedManifestOp>(b.getUnknownLoc(), CompressedManifestOp::create(b, b.getUnknownLoc(),
BlobAttr::get(ctxt, compressedManifest)); BlobAttr::get(ctxt, compressedManifest));
} else { } else {
mod->emitWarning() mod->emitWarning()
<< "zlib not available but required for manifest support"; << "zlib not available but required for manifest support";

View File

@ -85,8 +85,8 @@ void BundlePort::mapInputSignals(OpBuilder &b, Operation *inst, Value,
})); }));
SmallVector<Type, 5> toChannelTypes(llvm::map_range( SmallVector<Type, 5> toChannelTypes(llvm::map_range(
newInputChannels, [](hw::PortInfo port) { return port.type; })); newInputChannels, [](hw::PortInfo port) { return port.type; }));
auto unpack = b.create<UnpackBundleOp>( auto unpack = UnpackBundleOp::create(
origPort.loc, b, origPort.loc,
/*bundle=*/inst->getOperand(origPort.argNum), fromChannels); /*bundle=*/inst->getOperand(origPort.argNum), fromChannels);
// Connect the new instance inputs to the results of the unpack. // Connect the new instance inputs to the results of the unpack.
@ -106,8 +106,8 @@ void BundlePort::mapOutputSignals(OpBuilder &b, Operation *inst, Value,
})); }));
SmallVector<Type, 5> fromChannelTypes(llvm::map_range( SmallVector<Type, 5> fromChannelTypes(llvm::map_range(
newInputChannels, [](hw::PortInfo port) { return port.type; })); newInputChannels, [](hw::PortInfo port) { return port.type; }));
auto pack = b.create<PackBundleOp>( auto pack = PackBundleOp::create(
origPort.loc, cast<ChannelBundleType>(origPort.type), toChannels); b, origPort.loc, cast<ChannelBundleType>(origPort.type), toChannels);
// Feed the fromChannels into the new instance. // Feed the fromChannels into the new instance.
for (auto [idx, inPort] : llvm::enumerate(newInputChannels)) for (auto [idx, inPort] : llvm::enumerate(newInputChannels))
@ -141,7 +141,7 @@ void BundlePort::buildInputSignals() {
PackBundleOp pack; PackBundleOp pack;
if (body) { if (body) {
ImplicitLocOpBuilder b(origPort.loc, body, body->begin()); ImplicitLocOpBuilder b(origPort.loc, body, body->begin());
pack = b.create<PackBundleOp>(bundleType, newInputValues); pack = PackBundleOp::create(b, bundleType, newInputValues);
body->getArgument(origPort.argNum).replaceAllUsesWith(pack.getBundle()); body->getArgument(origPort.argNum).replaceAllUsesWith(pack.getBundle());
} }
@ -179,10 +179,12 @@ void BundlePort::buildOutputSignals() {
// For an output port, the original bundle must be unpacked into the // For an output port, the original bundle must be unpacked into the
// individual channel ports. // individual channel ports.
UnpackBundleOp unpack; UnpackBundleOp unpack;
if (body) if (body) {
unpack = OpBuilder::atBlockTerminator(body).create<UnpackBundleOp>( auto builder = OpBuilder::atBlockTerminator(body);
origPort.loc, body->getTerminator()->getOperand(origPort.argNum), unpack = UnpackBundleOp::create(
unpackChannels); builder, origPort.loc,
body->getTerminator()->getOperand(origPort.argNum), unpackChannels);
}
// Build new ports and put the new port info directly into the member // Build new ports and put the new port info directly into the member
// variable. // variable.

View File

@ -64,16 +64,17 @@ LogicalResult ChannelBufferLowering::matchAndRewrite(
Backedge rdEn = bb.get(rewriter.getI1Type()); Backedge rdEn = bb.get(rewriter.getI1Type());
Backedge valid = bb.get(rewriter.getI1Type()); Backedge valid = bb.get(rewriter.getI1Type());
auto unwrap = rewriter.create<UnwrapFIFOOp>(loc, stageInput, rdEn); auto unwrap = UnwrapFIFOOp::create(rewriter, loc, stageInput, rdEn);
auto wrap = rewriter.create<WrapValidReadyOp>(loc, unwrap.getData(), valid); auto wrap =
WrapValidReadyOp::create(rewriter, loc, unwrap.getData(), valid);
stageInput = wrap.getChanOutput(); stageInput = wrap.getChanOutput();
// rdEn = valid && ready // rdEn = valid && ready
rdEn.setValue(rewriter.create<comb::AndOp>(loc, wrap.getReady(), valid)); rdEn.setValue(comb::AndOp::create(rewriter, loc, wrap.getReady(), valid));
// valid = !empty // valid = !empty
valid.setValue(rewriter.create<comb::XorOp>( valid.setValue(comb::XorOp::create(
loc, unwrap.getEmpty(), rewriter, loc, unwrap.getEmpty(),
rewriter.create<hw::ConstantOp>(loc, rewriter.getBoolAttr(true)))); hw::ConstantOp::create(rewriter, loc, rewriter.getBoolAttr(true))));
} }
// Expand 'abstract' buffer into 'physical' stages. // Expand 'abstract' buffer into 'physical' stages.
@ -86,8 +87,8 @@ LogicalResult ChannelBufferLowering::matchAndRewrite(
for (uint64_t i = 0; i < numStages; ++i) { for (uint64_t i = 0; i < numStages; ++i) {
// Create the stages, connecting them up as we build. // Create the stages, connecting them up as we build.
auto stage = rewriter.create<PipelineStageOp>(loc, buffer.getClk(), auto stage = PipelineStageOp::create(rewriter, loc, buffer.getClk(),
buffer.getRst(), stageInput); buffer.getRst(), stageInput);
if (bufferName) { if (bufferName) {
SmallString<64> stageName( SmallString<64> stageName(
{bufferName.getValue(), "_stage", std::to_string(i)}); {bufferName.getValue(), "_stage", std::to_string(i)});
@ -104,15 +105,15 @@ LogicalResult ChannelBufferLowering::matchAndRewrite(
Backedge ready = bb.get(rewriter.getI1Type()); Backedge ready = bb.get(rewriter.getI1Type());
Backedge empty = bb.get(rewriter.getI1Type()); Backedge empty = bb.get(rewriter.getI1Type());
auto unwrap = rewriter.create<UnwrapValidReadyOp>(loc, stageInput, ready); auto unwrap = UnwrapValidReadyOp::create(rewriter, loc, stageInput, ready);
auto wrap = rewriter.create<WrapFIFOOp>( auto wrap = WrapFIFOOp::create(rewriter, loc,
loc, TypeRange{outputType, rewriter.getI1Type()}, unwrap.getRawOutput(), TypeRange{outputType, rewriter.getI1Type()},
empty); unwrap.getRawOutput(), empty);
ready.setValue(wrap.getRden()); ready.setValue(wrap.getRden());
empty.setValue(rewriter.create<comb::XorOp>( empty.setValue(comb::XorOp::create(
loc, unwrap.getValid(), rewriter, loc, unwrap.getValid(),
rewriter.create<hw::ConstantOp>(loc, rewriter.getBoolAttr(true)))); hw::ConstantOp::create(rewriter, loc, rewriter.getBoolAttr(true))));
output = wrap.getChanOutput(); output = wrap.getChanOutput();
} }
@ -142,8 +143,8 @@ FIFOLowering::matchAndRewrite(FIFOOp op, OpAdaptor adaptor,
auto outputType = op.getType(); auto outputType = op.getType();
BackedgeBuilder bb(rewriter, loc); BackedgeBuilder bb(rewriter, loc);
auto i1 = rewriter.getI1Type(); auto i1 = rewriter.getI1Type();
auto c1 = rewriter.create<hw::ConstantOp>(loc, rewriter.getI1Type(), auto c1 = hw::ConstantOp::create(rewriter, loc, rewriter.getI1Type(),
rewriter.getBoolAttr(true)); rewriter.getBoolAttr(true));
mlir::TypedValue<ChannelType> chanInput = op.getInput(); mlir::TypedValue<ChannelType> chanInput = op.getInput();
if (chanInput.getType().getDataDelay() != 0) if (chanInput.getType().getDataDelay() != 0)
return op.emitOpError( return op.emitOpError(
@ -154,14 +155,14 @@ FIFOLowering::matchAndRewrite(FIFOOp op, OpAdaptor adaptor,
Value dataNotAvailable; Value dataNotAvailable;
if (chanInput.getType().getSignaling() == ChannelSignaling::ValidReady) { if (chanInput.getType().getSignaling() == ChannelSignaling::ValidReady) {
auto unwrapValidReady = auto unwrapValidReady =
rewriter.create<UnwrapValidReadyOp>(loc, chanInput, inputEn); UnwrapValidReadyOp::create(rewriter, loc, chanInput, inputEn);
rawData = unwrapValidReady.getRawOutput(); rawData = unwrapValidReady.getRawOutput();
dataNotAvailable = comb::createOrFoldNot(loc, unwrapValidReady.getValid(), dataNotAvailable = comb::createOrFoldNot(loc, unwrapValidReady.getValid(),
rewriter, /*twoState=*/true); rewriter, /*twoState=*/true);
dataNotAvailable.getDefiningOp()->setAttr( dataNotAvailable.getDefiningOp()->setAttr(
"sv.namehint", rewriter.getStringAttr("dataNotAvailable")); "sv.namehint", rewriter.getStringAttr("dataNotAvailable"));
} else if (chanInput.getType().getSignaling() == ChannelSignaling::FIFO) { } else if (chanInput.getType().getSignaling() == ChannelSignaling::FIFO) {
auto unwrapPull = rewriter.create<UnwrapFIFOOp>(loc, chanInput, inputEn); auto unwrapPull = UnwrapFIFOOp::create(rewriter, loc, chanInput, inputEn);
rawData = unwrapPull.getData(); rawData = unwrapPull.getData();
dataNotAvailable = unwrapPull.getEmpty(); dataNotAvailable = unwrapPull.getEmpty();
} else { } else {
@ -170,39 +171,39 @@ FIFOLowering::matchAndRewrite(FIFOOp op, OpAdaptor adaptor,
} }
Backedge outputRdEn = bb.get(i1); Backedge outputRdEn = bb.get(i1);
auto seqFifo = rewriter.create<seq::FIFOOp>( auto seqFifo = seq::FIFOOp::create(
loc, outputType.getInner(), i1, i1, Type(), Type(), rawData, outputRdEn, rewriter, loc, outputType.getInner(), i1, i1, Type(), Type(), rawData,
inputEn, op.getClk(), op.getRst(), op.getDepthAttr(), outputRdEn, inputEn, op.getClk(), op.getRst(), op.getDepthAttr(),
rewriter.getI64IntegerAttr(outputType.getDataDelay()), IntegerAttr(), rewriter.getI64IntegerAttr(outputType.getDataDelay()), IntegerAttr(),
IntegerAttr()); IntegerAttr());
auto inputNotEmpty = rewriter.create<comb::XorOp>(loc, dataNotAvailable, c1); auto inputNotEmpty = comb::XorOp::create(rewriter, loc, dataNotAvailable, c1);
inputNotEmpty->setAttr("sv.namehint", inputNotEmpty->setAttr("sv.namehint",
rewriter.getStringAttr("inputNotEmpty")); rewriter.getStringAttr("inputNotEmpty"));
auto seqFifoNotFull = auto seqFifoNotFull =
rewriter.create<comb::XorOp>(loc, seqFifo.getFull(), c1); comb::XorOp::create(rewriter, loc, seqFifo.getFull(), c1);
seqFifoNotFull->setAttr("sv.namehint", seqFifoNotFull->setAttr("sv.namehint",
rewriter.getStringAttr("seqFifoNotFull")); rewriter.getStringAttr("seqFifoNotFull"));
inputEn.setValue( inputEn.setValue(
rewriter.create<comb::AndOp>(loc, inputNotEmpty, seqFifoNotFull)); comb::AndOp::create(rewriter, loc, inputNotEmpty, seqFifoNotFull));
static_cast<Value>(inputEn).getDefiningOp()->setAttr( static_cast<Value>(inputEn).getDefiningOp()->setAttr(
"sv.namehint", rewriter.getStringAttr("inputEn")); "sv.namehint", rewriter.getStringAttr("inputEn"));
Value output; Value output;
if (outputType.getSignaling() == ChannelSignaling::ValidReady) { if (outputType.getSignaling() == ChannelSignaling::ValidReady) {
auto wrap = rewriter.create<WrapValidReadyOp>( auto wrap = WrapValidReadyOp::create(
loc, mlir::TypeRange{outputType, i1}, seqFifo.getOutput(), rewriter, loc, mlir::TypeRange{outputType, i1}, seqFifo.getOutput(),
comb::createOrFoldNot(loc, seqFifo.getEmpty(), rewriter, comb::createOrFoldNot(loc, seqFifo.getEmpty(), rewriter,
/*twoState=*/true)); /*twoState=*/true));
output = wrap.getChanOutput(); output = wrap.getChanOutput();
outputRdEn.setValue( outputRdEn.setValue(
rewriter.create<comb::AndOp>(loc, wrap.getValid(), wrap.getReady())); comb::AndOp::create(rewriter, loc, wrap.getValid(), wrap.getReady()));
static_cast<Value>(outputRdEn) static_cast<Value>(outputRdEn)
.getDefiningOp() .getDefiningOp()
->setAttr("sv.namehint", rewriter.getStringAttr("outputRdEn")); ->setAttr("sv.namehint", rewriter.getStringAttr("outputRdEn"));
} else if (outputType.getSignaling() == ChannelSignaling::FIFO) { } else if (outputType.getSignaling() == ChannelSignaling::FIFO) {
auto wrap = auto wrap =
rewriter.create<WrapFIFOOp>(loc, mlir::TypeRange{outputType, i1}, WrapFIFOOp::create(rewriter, loc, mlir::TypeRange{outputType, i1},
seqFifo.getOutput(), seqFifo.getEmpty()); seqFifo.getOutput(), seqFifo.getEmpty());
output = wrap.getChanOutput(); output = wrap.getChanOutput();
outputRdEn.setValue(wrap.getRden()); outputRdEn.setValue(wrap.getRden());
} else { } else {
@ -277,8 +278,9 @@ PureModuleLowering::matchAndRewrite(ESIPureModuleOp pureMod, OpAdaptor adaptor,
} }
// Create the replacement `hw.module`. // Create the replacement `hw.module`.
auto hwMod = rewriter.create<hw::HWModuleOp>( auto hwMod =
loc, pureMod.getNameAttr(), ports, ArrayAttr::get(getContext(), params)); hw::HWModuleOp::create(rewriter, loc, pureMod.getNameAttr(), ports,
ArrayAttr::get(getContext(), params));
hwMod->setDialectAttrs(pureMod->getDialectAttrs()); hwMod->setDialectAttrs(pureMod->getDialectAttrs());
rewriter.eraseBlock(hwMod.getBodyBlock()); rewriter.eraseBlock(hwMod.getBodyBlock());
rewriter.inlineRegionBefore(*body->getParent(), hwMod.getBodyRegion(), rewriter.inlineRegionBefore(*body->getParent(), hwMod.getBodyRegion(),
@ -302,7 +304,7 @@ PureModuleLowering::matchAndRewrite(ESIPureModuleOp pureMod, OpAdaptor adaptor,
rewriter.eraseOp(output); rewriter.eraseOp(output);
} }
rewriter.setInsertionPointToEnd(body); rewriter.setInsertionPointToEnd(body);
rewriter.create<hw::OutputOp>(pureMod.getLoc(), hwOutputOperands); hw::OutputOp::create(rewriter, pureMod.getLoc(), hwOutputOperands);
// Erase the original op. // Erase the original op.
rewriter.eraseOp(pureMod); rewriter.eraseOp(pureMod);

View File

@ -141,7 +141,7 @@ void ValidReady::buildInputSignals() {
ImplicitLocOpBuilder b(origPort.loc, body, body->begin()); ImplicitLocOpBuilder b(origPort.loc, body, body->begin());
// Build the ESI wrap operation to translate the lowered signals to what // Build the ESI wrap operation to translate the lowered signals to what
// they were. (A later pass takes care of eliminating the ESI ops.) // they were. (A later pass takes care of eliminating the ESI ops.)
auto wrap = b.create<WrapValidReadyOp>(data, valid); auto wrap = WrapValidReadyOp::create(b, data, valid);
ready = wrap.getReady(); ready = wrap.getReady();
// Replace uses of the old ESI port argument with the new one from the // Replace uses of the old ESI port argument with the new one from the
// wrap. // wrap.
@ -159,9 +159,9 @@ void ValidReady::buildInputSignals() {
void ValidReady::mapInputSignals(OpBuilder &b, Operation *inst, Value instValue, void ValidReady::mapInputSignals(OpBuilder &b, Operation *inst, Value instValue,
SmallVectorImpl<Value> &newOperands, SmallVectorImpl<Value> &newOperands,
ArrayRef<Backedge> newResults) { ArrayRef<Backedge> newResults) {
auto unwrap = b.create<UnwrapValidReadyOp>(inst->getLoc(), auto unwrap = UnwrapValidReadyOp::create(b, inst->getLoc(),
inst->getOperand(origPort.argNum), inst->getOperand(origPort.argNum),
newResults[readyPort.argNum]); newResults[readyPort.argNum]);
newOperands[dataPort.argNum] = unwrap.getRawOutput(); newOperands[dataPort.argNum] = unwrap.getRawOutput();
newOperands[validPort.argNum] = unwrap.getValid(); newOperands[validPort.argNum] = unwrap.getValid();
} }
@ -181,8 +181,8 @@ void ValidReady::buildOutputSignals() {
auto *terminator = body->getTerminator(); auto *terminator = body->getTerminator();
ImplicitLocOpBuilder b(origPort.loc, terminator); ImplicitLocOpBuilder b(origPort.loc, terminator);
auto unwrap = b.create<UnwrapValidReadyOp>( auto unwrap = UnwrapValidReadyOp::create(
terminator->getOperand(origPort.argNum), ready); b, terminator->getOperand(origPort.argNum), ready);
data = unwrap.getRawOutput(); data = unwrap.getRawOutput();
valid = unwrap.getValid(); valid = unwrap.getValid();
} }
@ -204,8 +204,8 @@ void ValidReady::mapOutputSignals(OpBuilder &b, Operation *inst,
SmallVectorImpl<Value> &newOperands, SmallVectorImpl<Value> &newOperands,
ArrayRef<Backedge> newResults) { ArrayRef<Backedge> newResults) {
auto wrap = auto wrap =
b.create<WrapValidReadyOp>(inst->getLoc(), newResults[dataPort.argNum], WrapValidReadyOp::create(b, inst->getLoc(), newResults[dataPort.argNum],
newResults[validPort.argNum]); newResults[validPort.argNum]);
inst->getResult(origPort.argNum).replaceAllUsesWith(wrap.getChanOutput()); inst->getResult(origPort.argNum).replaceAllUsesWith(wrap.getChanOutput());
newOperands[readyPort.argNum] = wrap.getReady(); newOperands[readyPort.argNum] = wrap.getReady();
} }
@ -235,8 +235,8 @@ void FIFO::buildInputSignals() {
ImplicitLocOpBuilder b(origPort.loc, body, body->begin()); ImplicitLocOpBuilder b(origPort.loc, body, body->begin());
// Build the ESI wrap operation to translate the lowered signals to what // Build the ESI wrap operation to translate the lowered signals to what
// they were. (A later pass takes care of eliminating the ESI ops.) // they were. (A later pass takes care of eliminating the ESI ops.)
auto wrap = b.create<WrapFIFOOp>(ArrayRef<Type>({chanTy, b.getI1Type()}), auto wrap = WrapFIFOOp::create(b, ArrayRef<Type>({chanTy, b.getI1Type()}),
data, empty); data, empty);
rden = wrap.getRden(); rden = wrap.getRden();
// Replace uses of the old ESI port argument with the new one from the // Replace uses of the old ESI port argument with the new one from the
// wrap. // wrap.
@ -251,8 +251,8 @@ void FIFO::mapInputSignals(OpBuilder &b, Operation *inst, Value instValue,
SmallVectorImpl<Value> &newOperands, SmallVectorImpl<Value> &newOperands,
ArrayRef<Backedge> newResults) { ArrayRef<Backedge> newResults) {
auto unwrap = auto unwrap =
b.create<UnwrapFIFOOp>(inst->getLoc(), inst->getOperand(origPort.argNum), UnwrapFIFOOp::create(b, inst->getLoc(), inst->getOperand(origPort.argNum),
newResults[rdenPort.argNum]); newResults[rdenPort.argNum]);
newOperands[dataPort.argNum] = unwrap.getData(); newOperands[dataPort.argNum] = unwrap.getData();
newOperands[emptyPort.argNum] = unwrap.getEmpty(); newOperands[emptyPort.argNum] = unwrap.getEmpty();
} }
@ -276,7 +276,7 @@ void FIFO::buildOutputSignals() {
ImplicitLocOpBuilder b(origPort.loc, terminator); ImplicitLocOpBuilder b(origPort.loc, terminator);
auto unwrap = auto unwrap =
b.create<UnwrapFIFOOp>(terminator->getOperand(origPort.argNum), rden); UnwrapFIFOOp::create(b, terminator->getOperand(origPort.argNum), rden);
data = unwrap.getData(); data = unwrap.getData();
empty = unwrap.getEmpty(); empty = unwrap.getEmpty();
} }
@ -292,8 +292,8 @@ void FIFO::buildOutputSignals() {
void FIFO::mapOutputSignals(OpBuilder &b, Operation *inst, Value instValue, void FIFO::mapOutputSignals(OpBuilder &b, Operation *inst, Value instValue,
SmallVectorImpl<Value> &newOperands, SmallVectorImpl<Value> &newOperands,
ArrayRef<Backedge> newResults) { ArrayRef<Backedge> newResults) {
auto wrap = b.create<WrapFIFOOp>( auto wrap = WrapFIFOOp::create(
inst->getLoc(), ArrayRef<Type>({origPort.type, b.getI1Type()}), b, inst->getLoc(), ArrayRef<Type>({origPort.type, b.getI1Type()}),
newResults[dataPort.argNum], newResults[emptyPort.argNum]); newResults[dataPort.argNum], newResults[emptyPort.argNum]);
inst->getResult(origPort.argNum).replaceAllUsesWith(wrap.getChanOutput()); inst->getResult(origPort.argNum).replaceAllUsesWith(wrap.getChanOutput());
newOperands[rdenPort.argNum] = wrap.getRden(); newOperands[rdenPort.argNum] = wrap.getRden();
@ -503,17 +503,17 @@ void ESIPortsPass::updateInstance(HWModuleExternOp mod, InstanceOp inst) {
// Build a gasket by instantiating an interface, connecting one end to an // Build a gasket by instantiating an interface, connecting one end to an
// `esi.unwrap.iface` and the other end to the instance. // `esi.unwrap.iface` and the other end to the instance.
auto ifaceInst = auto ifaceInst =
instBuilder.create<InterfaceInstanceOp>(iface.getInterfaceType()); InterfaceInstanceOp::create(instBuilder, iface.getInterfaceType());
nameStringBuffer.clear(); nameStringBuffer.clear();
ifaceInst->setAttr( ifaceInst->setAttr(
"name", "name",
StringAttr::get(mod.getContext(), StringAttr::get(mod.getContext(),
constructInstanceName(op, iface, nameStringBuffer))); constructInstanceName(op, iface, nameStringBuffer)));
GetModportOp sinkModport = GetModportOp sinkModport =
instBuilder.create<GetModportOp>(ifaceInst, ESIHWBuilder::sinkStr); GetModportOp::create(instBuilder, ifaceInst, ESIHWBuilder::sinkStr);
instBuilder.create<UnwrapSVInterfaceOp>(op, sinkModport); UnwrapSVInterfaceOp::create(instBuilder, op, sinkModport);
GetModportOp sourceModport = GetModportOp sourceModport =
instBuilder.create<GetModportOp>(ifaceInst, ESIHWBuilder::sourceStr); GetModportOp::create(instBuilder, ifaceInst, ESIHWBuilder::sourceStr);
// Finally, add the correct modport to the list of operands. // Finally, add the correct modport to the list of operands.
newOperands.push_back(sourceModport); newOperands.push_back(sourceModport);
} }
@ -550,29 +550,29 @@ void ESIPortsPass::updateInstance(HWModuleExternOp mod, InstanceOp inst) {
// `esi.wrap.iface` and the other end to the instance. Append it to the // `esi.wrap.iface` and the other end to the instance. Append it to the
// operand list. // operand list.
auto ifaceInst = auto ifaceInst =
instBuilder.create<InterfaceInstanceOp>(iface.getInterfaceType()); InterfaceInstanceOp::create(instBuilder, iface.getInterfaceType());
nameStringBuffer.clear(); nameStringBuffer.clear();
ifaceInst->setAttr( ifaceInst->setAttr(
"name", "name",
StringAttr::get(mod.getContext(), StringAttr::get(mod.getContext(),
constructInstanceName(res, iface, nameStringBuffer))); constructInstanceName(res, iface, nameStringBuffer)));
GetModportOp sourceModport = GetModportOp sourceModport =
instBuilder.create<GetModportOp>(ifaceInst, ESIHWBuilder::sourceStr); GetModportOp::create(instBuilder, ifaceInst, ESIHWBuilder::sourceStr);
auto newChannel = auto newChannel =
instBuilder.create<WrapSVInterfaceOp>(res.getType(), sourceModport); WrapSVInterfaceOp::create(instBuilder, res.getType(), sourceModport);
// Connect all the old users of the output channel with the newly // Connect all the old users of the output channel with the newly
// wrapped replacement channel. // wrapped replacement channel.
res.replaceAllUsesWith(newChannel); res.replaceAllUsesWith(newChannel);
GetModportOp sinkModport = GetModportOp sinkModport =
instBuilder.create<GetModportOp>(ifaceInst, ESIHWBuilder::sinkStr); GetModportOp::create(instBuilder, ifaceInst, ESIHWBuilder::sinkStr);
// And add the modport on the other side to the new operand list. // And add the modport on the other side to the new operand list.
newOperands.push_back(sinkModport); newOperands.push_back(sinkModport);
} }
// Create the new instance! // Create the new instance!
auto newInst = instBuilder.create<hw::InstanceOp>( auto newInst = hw::InstanceOp::create(
mod, inst.getInstanceNameAttr(), newOperands, inst.getParameters(), instBuilder, mod, inst.getInstanceNameAttr(), newOperands,
inst.getInnerSymAttr()); inst.getParameters(), inst.getInnerSymAttr());
// Go through the old list of non-ESI result values, and replace them with // Go through the old list of non-ESI result values, and replace them with
// the new non-ESI results. // the new non-ESI results.

Some files were not shown because too many files have changed in this diff Show More