19#include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
20#include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h"
21#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
22#include "mlir/Conversion/IndexToLLVM/IndexToLLVM.h"
23#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
24#include "mlir/Conversion/LLVMCommon/TypeConverter.h"
25#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
26#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
27#include "mlir/Dialect/Func/IR/FuncOps.h"
28#include "mlir/Dialect/Index/IR/IndexOps.h"
29#include "mlir/Dialect/LLVMIR/FunctionCallUtils.h"
30#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
31#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
32#include "mlir/Dialect/SCF/IR/SCF.h"
33#include "mlir/IR/BuiltinDialect.h"
34#include "mlir/Pass/Pass.h"
35#include "mlir/Transforms/DialectConversion.h"
36#include "llvm/Support/Debug.h"
38#define DEBUG_TYPE "lower-arc-to-llvm"
41#define GEN_PASS_DEF_LOWERARCTOLLVM
42#include "circt/Conversion/Passes.h.inc"
55 return modelName +
"_eval";
61 using OpConversionPattern::OpConversionPattern;
63 matchAndRewrite(arc::ModelOp op, OpAdaptor adaptor,
64 ConversionPatternRewriter &rewriter)
const final {
66 IRRewriter::InsertionGuard guard(rewriter);
67 rewriter.setInsertionPointToEnd(&op.getBodyBlock());
68 func::ReturnOp::create(rewriter, op.getLoc());
73 rewriter.getFunctionType(op.getBody().getArgumentTypes(), {});
75 mlir::func::FuncOp::create(rewriter, op.getLoc(), funcName, funcType);
76 rewriter.inlineRegionBefore(op.getRegion(), func.getBody(), func.end());
82struct AllocStorageOpLowering
84 using OpConversionPattern::OpConversionPattern;
86 matchAndRewrite(arc::AllocStorageOp op, OpAdaptor adaptor,
87 ConversionPatternRewriter &rewriter)
const final {
88 auto type = typeConverter->convertType(op.getType());
89 if (!op.getOffset().has_value())
91 rewriter.replaceOpWithNewOp<LLVM::GEPOp>(op, type, rewriter.getI8Type(),
93 LLVM::GEPArg(*op.getOffset()));
98template <
class ConcreteOp>
102 using OpAdaptor =
typename ConcreteOp::Adaptor;
105 matchAndRewrite(ConcreteOp op, OpAdaptor adaptor,
106 ConversionPatternRewriter &rewriter)
const final {
108 auto offsetAttr = op->template getAttrOfType<IntegerAttr>(
"offset");
111 Value ptr = LLVM::GEPOp::create(
112 rewriter, op->getLoc(), adaptor.getStorage().getType(),
113 rewriter.getI8Type(), adaptor.getStorage(),
114 LLVM::GEPArg(offsetAttr.getValue().getZExtValue()));
115 rewriter.replaceOp(op, ptr);
121 using OpConversionPattern::OpConversionPattern;
123 matchAndRewrite(arc::StateReadOp op, OpAdaptor adaptor,
124 ConversionPatternRewriter &rewriter)
const final {
125 auto type = typeConverter->convertType(op.getType());
126 rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, type, adaptor.getState());
132 using OpConversionPattern::OpConversionPattern;
134 matchAndRewrite(arc::StateWriteOp op, OpAdaptor adaptor,
135 ConversionPatternRewriter &rewriter)
const final {
136 if (adaptor.getCondition()) {
137 rewriter.replaceOpWithNewOp<scf::IfOp>(
138 op, adaptor.getCondition(), [&](
auto &builder,
auto loc) {
139 LLVM::StoreOp::create(builder, loc, adaptor.getValue(),
141 scf::YieldOp::create(builder, loc);
144 rewriter.replaceOpWithNewOp<LLVM::StoreOp>(op, adaptor.getValue(),
152 using OpConversionPattern::OpConversionPattern;
154 matchAndRewrite(arc::AllocMemoryOp op, OpAdaptor adaptor,
155 ConversionPatternRewriter &rewriter)
const final {
156 auto offsetAttr = op->getAttrOfType<IntegerAttr>(
"offset");
159 Value ptr = LLVM::GEPOp::create(
160 rewriter, op.getLoc(), adaptor.getStorage().getType(),
161 rewriter.getI8Type(), adaptor.getStorage(),
162 LLVM::GEPArg(offsetAttr.getValue().getZExtValue()));
164 rewriter.replaceOp(op, ptr);
170 using OpConversionPattern::OpConversionPattern;
172 matchAndRewrite(arc::StorageGetOp op, OpAdaptor adaptor,
173 ConversionPatternRewriter &rewriter)
const final {
174 Value offset = LLVM::ConstantOp::create(
175 rewriter, op.getLoc(), rewriter.getI32Type(), op.getOffsetAttr());
176 Value ptr = LLVM::GEPOp::create(
177 rewriter, op.getLoc(), adaptor.getStorage().getType(),
178 rewriter.getI8Type(), adaptor.getStorage(), offset);
179 rewriter.replaceOp(op, ptr);
189static MemoryAccess prepareMemoryAccess(Location loc, Value memory,
190 Value address, MemoryType type,
191 ConversionPatternRewriter &rewriter) {
192 auto zextAddrType = rewriter.getIntegerType(
193 cast<IntegerType>(address.getType()).getWidth() + 1);
194 Value
addr = LLVM::ZExtOp::create(rewriter, loc, zextAddrType, address);
196 LLVM::ConstantOp::create(rewriter, loc, zextAddrType,
197 rewriter.getI32IntegerAttr(type.getNumWords()));
198 Value withinBounds = LLVM::ICmpOp::create(
199 rewriter, loc, LLVM::ICmpPredicate::ult, addr, addrLimit);
200 Value ptr = LLVM::GEPOp::create(
201 rewriter, loc, LLVM::LLVMPointerType::get(memory.getContext()),
202 rewriter.getIntegerType(type.getStride() * 8), memory, ValueRange{addr});
203 return {ptr, withinBounds};
207 using OpConversionPattern::OpConversionPattern;
209 matchAndRewrite(arc::MemoryReadOp op, OpAdaptor adaptor,
210 ConversionPatternRewriter &rewriter)
const final {
211 auto type = typeConverter->convertType(op.getType());
212 auto memoryType = cast<MemoryType>(op.getMemory().getType());
214 prepareMemoryAccess(op.getLoc(), adaptor.getMemory(),
215 adaptor.getAddress(), memoryType, rewriter);
219 rewriter.replaceOpWithNewOp<scf::IfOp>(
220 op, access.withinBounds,
221 [&](
auto &builder,
auto loc) {
222 Value loadOp = LLVM::LoadOp::create(
223 builder, loc, memoryType.getWordType(), access.ptr);
224 scf::YieldOp::create(builder, loc, loadOp);
226 [&](
auto &builder,
auto loc) {
227 Value zeroValue = LLVM::ConstantOp::create(
228 builder, loc, type, builder.getI64IntegerAttr(0));
229 scf::YieldOp::create(builder, loc, zeroValue);
236 using OpConversionPattern::OpConversionPattern;
238 matchAndRewrite(arc::MemoryWriteOp op, OpAdaptor adaptor,
239 ConversionPatternRewriter &rewriter)
const final {
240 auto access = prepareMemoryAccess(
241 op.getLoc(), adaptor.getMemory(), adaptor.getAddress(),
242 cast<MemoryType>(op.getMemory().getType()), rewriter);
243 auto enable = access.withinBounds;
244 if (adaptor.getEnable())
245 enable = LLVM::AndOp::create(rewriter, op.getLoc(), adaptor.getEnable(),
249 rewriter.replaceOpWithNewOp<scf::IfOp>(
250 op, enable, [&](
auto &builder,
auto loc) {
251 LLVM::StoreOp::create(builder, loc, adaptor.getData(), access.ptr);
252 scf::YieldOp::create(builder, loc);
260 using OpConversionPattern::OpConversionPattern;
262 matchAndRewrite(seq::ClockGateOp op, OpAdaptor adaptor,
263 ConversionPatternRewriter &rewriter)
const final {
264 rewriter.replaceOpWithNewOp<LLVM::AndOp>(op, adaptor.getInput(),
265 adaptor.getEnable());
272 using OpConversionPattern::OpConversionPattern;
274 matchAndRewrite(seq::ClockInverterOp op, OpAdaptor adaptor,
275 ConversionPatternRewriter &rewriter)
const final {
276 auto constTrue = LLVM::ConstantOp::create(rewriter, op->getLoc(),
277 rewriter.getI1Type(), 1);
278 rewriter.replaceOpWithNewOp<LLVM::XOrOp>(op, adaptor.getInput(), constTrue);
284 using OpConversionPattern::OpConversionPattern;
286 matchAndRewrite(arc::ZeroCountOp op, OpAdaptor adaptor,
287 ConversionPatternRewriter &rewriter)
const override {
289 IntegerAttr isZeroPoison = rewriter.getBoolAttr(
true);
291 if (op.getPredicate() == arc::ZeroCountPredicate::leading) {
292 rewriter.replaceOpWithNewOp<LLVM::CountLeadingZerosOp>(
293 op, adaptor.getInput().getType(), adaptor.getInput(), isZeroPoison);
297 rewriter.replaceOpWithNewOp<LLVM::CountTrailingZerosOp>(
298 op, adaptor.getInput().getType(), adaptor.getInput(), isZeroPoison);
304 using OpConversionPattern::OpConversionPattern;
306 matchAndRewrite(seq::ConstClockOp op, OpAdaptor adaptor,
307 ConversionPatternRewriter &rewriter)
const override {
308 rewriter.replaceOpWithNewOp<LLVM::ConstantOp>(
309 op, rewriter.getI1Type(),
static_cast<int64_t
>(op.getValue()));
314template <
typename OpTy>
317 using OpAdaptor =
typename OpTy::Adaptor;
319 matchAndRewrite(OpTy op, OpAdaptor adaptor,
320 ConversionPatternRewriter &rewriter)
const override {
321 rewriter.replaceOp(op, adaptor.getInput());
335 size_t numStateBytes;
336 llvm::DenseMap<StringRef, StateInfo> states;
337 mlir::FlatSymbolRefAttr initialFnSymbol;
338 mlir::FlatSymbolRefAttr finalFnSymbol;
341template <
typename OpTy>
343 ModelAwarePattern(
const TypeConverter &typeConverter, MLIRContext *context,
344 llvm::DenseMap<StringRef, ModelInfoMap> &modelInfo)
346 modelInfo(modelInfo) {}
349 Value createPtrToPortState(ConversionPatternRewriter &rewriter, Location loc,
350 Value state,
const StateInfo &port)
const {
351 MLIRContext *ctx = rewriter.getContext();
352 return LLVM::GEPOp::create(rewriter, loc, LLVM::LLVMPointerType::get(ctx),
353 IntegerType::get(ctx, 8), state,
354 LLVM::GEPArg(port.
offset));
357 llvm::DenseMap<StringRef, ModelInfoMap> &modelInfo;
362struct SimInstantiateOpLowering
363 :
public ModelAwarePattern<arc::SimInstantiateOp> {
364 using ModelAwarePattern::ModelAwarePattern;
367 matchAndRewrite(arc::SimInstantiateOp op, OpAdaptor adaptor,
368 ConversionPatternRewriter &rewriter)
const final {
369 auto modelIt = modelInfo.find(
370 cast<SimModelInstanceType>(op.getBody().getArgument(0).getType())
373 ModelInfoMap &model = modelIt->second;
375 ModuleOp moduleOp = op->getParentOfType<ModuleOp>();
379 ConversionPatternRewriter::InsertionGuard guard(rewriter);
383 Type convertedIndex = typeConverter->convertType(rewriter.getIndexType());
385 FailureOr<LLVM::LLVMFuncOp> mallocFunc =
386 LLVM::lookupOrCreateMallocFn(rewriter, moduleOp, convertedIndex);
387 if (failed(mallocFunc))
390 FailureOr<LLVM::LLVMFuncOp> freeFunc =
391 LLVM::lookupOrCreateFreeFn(rewriter, moduleOp);
392 if (failed(freeFunc))
395 Location loc = op.getLoc();
396 Value numStateBytes = LLVM::ConstantOp::create(
397 rewriter, loc, convertedIndex, model.numStateBytes);
398 Value allocated = LLVM::CallOp::create(rewriter, loc, mallocFunc.value(),
399 ValueRange{numStateBytes})
402 LLVM::ConstantOp::create(rewriter, loc, rewriter.getI8Type(), 0);
403 LLVM::MemsetOp::create(rewriter, loc, allocated, zero, numStateBytes,
407 if (model.initialFnSymbol) {
408 auto initialFnType = LLVM::LLVMFunctionType::get(
409 LLVM::LLVMVoidType::get(op.getContext()),
410 {LLVM::LLVMPointerType::get(op.getContext())});
411 LLVM::CallOp::create(rewriter, loc, initialFnType, model.initialFnSymbol,
412 ValueRange{allocated});
416 rewriter.inlineBlockBefore(&adaptor.getBody().getBlocks().front(), op,
420 if (model.finalFnSymbol) {
421 auto finalFnType = LLVM::LLVMFunctionType::get(
422 LLVM::LLVMVoidType::get(op.getContext()),
423 {LLVM::LLVMPointerType::get(op.getContext())});
424 LLVM::CallOp::create(rewriter, loc, finalFnType, model.finalFnSymbol,
425 ValueRange{allocated});
428 LLVM::CallOp::create(rewriter, loc, freeFunc.value(),
429 ValueRange{allocated});
430 rewriter.eraseOp(op);
436struct SimSetInputOpLowering :
public ModelAwarePattern<arc::SimSetInputOp> {
437 using ModelAwarePattern::ModelAwarePattern;
440 matchAndRewrite(arc::SimSetInputOp op, OpAdaptor adaptor,
441 ConversionPatternRewriter &rewriter)
const final {
443 modelInfo.find(cast<SimModelInstanceType>(op.getInstance().getType())
446 ModelInfoMap &model = modelIt->second;
448 auto portIt = model.states.find(op.getInput());
449 if (portIt == model.states.end()) {
452 rewriter.eraseOp(op);
457 Value statePtr = createPtrToPortState(rewriter, op.getLoc(),
458 adaptor.getInstance(), port);
459 rewriter.replaceOpWithNewOp<LLVM::StoreOp>(op, adaptor.getValue(),
466struct SimGetPortOpLowering :
public ModelAwarePattern<arc::SimGetPortOp> {
467 using ModelAwarePattern::ModelAwarePattern;
470 matchAndRewrite(arc::SimGetPortOp op, OpAdaptor adaptor,
471 ConversionPatternRewriter &rewriter)
const final {
473 modelInfo.find(cast<SimModelInstanceType>(op.getInstance().getType())
476 ModelInfoMap &model = modelIt->second;
478 auto type = typeConverter->convertType(op.getValue().getType());
481 auto portIt = model.states.find(op.getPort());
482 if (portIt == model.states.end()) {
485 rewriter.replaceOpWithNewOp<LLVM::ConstantOp>(op, type, 0);
490 Value statePtr = createPtrToPortState(rewriter, op.getLoc(),
491 adaptor.getInstance(), port);
492 rewriter.replaceOpWithNewOp<LLVM::LoadOp>(op, type, statePtr);
498struct SimStepOpLowering :
public ModelAwarePattern<arc::SimStepOp> {
499 using ModelAwarePattern::ModelAwarePattern;
502 matchAndRewrite(arc::SimStepOp op, OpAdaptor adaptor,
503 ConversionPatternRewriter &rewriter)
const final {
504 StringRef modelName = cast<SimModelInstanceType>(op.getInstance().getType())
508 StringAttr evalFunc =
510 rewriter.replaceOpWithNewOp<LLVM::CallOp>(op, mlir::TypeRange(), evalFunc,
511 adaptor.getInstance());
520struct SimEmitValueOpLowering
522 using OpConversionPattern::OpConversionPattern;
525 matchAndRewrite(arc::SimEmitValueOp op, OpAdaptor adaptor,
526 ConversionPatternRewriter &rewriter)
const final {
527 auto valueType = dyn_cast<IntegerType>(adaptor.getValue().getType());
531 Location loc = op.getLoc();
533 ModuleOp moduleOp = op->getParentOfType<ModuleOp>();
540 Value toPrint = adaptor.getValue();
541 DataLayout layout = DataLayout::closest(op);
542 llvm::TypeSize sizeOfSizeT =
543 layout.getTypeSizeInBits(rewriter.getIndexType());
544 assert(!sizeOfSizeT.isScalable() &&
545 sizeOfSizeT.getFixedValue() <= std::numeric_limits<unsigned>::max());
546 bool truncated =
false;
547 if (valueType.getWidth() > sizeOfSizeT) {
548 toPrint = LLVM::TruncOp::create(
550 IntegerType::get(getContext(), sizeOfSizeT.getFixedValue()), toPrint);
552 }
else if (valueType.getWidth() < sizeOfSizeT)
553 toPrint = LLVM::ZExtOp::create(
555 IntegerType::get(getContext(), sizeOfSizeT.getFixedValue()), toPrint);
558 auto printfFunc = LLVM::lookupOrCreateFn(
559 rewriter, moduleOp,
"printf", LLVM::LLVMPointerType::get(getContext()),
560 LLVM::LLVMVoidType::get(getContext()),
true);
561 if (failed(printfFunc))
565 SmallString<16> formatStrName{
"_arc_sim_emit_"};
566 formatStrName.append(truncated ?
"trunc_" :
"full_");
567 formatStrName.append(adaptor.getValueName());
568 LLVM::GlobalOp formatStrGlobal;
569 if (!(formatStrGlobal =
570 moduleOp.lookupSymbol<LLVM::GlobalOp>(formatStrName))) {
571 ConversionPatternRewriter::InsertionGuard insertGuard(rewriter);
573 SmallString<16> formatStr = adaptor.getValueName();
574 formatStr.append(
" = ");
576 formatStr.append(
"(truncated) ");
577 formatStr.append(
"%zx\n");
578 SmallVector<char> formatStrVec{formatStr.begin(), formatStr.end()};
579 formatStrVec.push_back(0);
581 rewriter.setInsertionPointToStart(moduleOp.getBody());
583 LLVM::LLVMArrayType::get(rewriter.getI8Type(), formatStrVec.size());
584 formatStrGlobal = LLVM::GlobalOp::create(
585 rewriter, loc, globalType,
true,
586 LLVM::Linkage::Internal,
587 formatStrName, rewriter.getStringAttr(formatStrVec),
591 Value formatStrGlobalPtr =
592 LLVM::AddressOfOp::create(rewriter, loc, formatStrGlobal);
593 rewriter.replaceOpWithNewOp<LLVM::CallOp>(
594 op, printfFunc.value(), ValueRange{formatStrGlobalPtr, toPrint});
602static LogicalResult
convert(arc::ExecuteOp op, arc::ExecuteOp::Adaptor adaptor,
603 ConversionPatternRewriter &rewriter,
604 const TypeConverter &converter) {
606 if (failed(rewriter.convertRegionTypes(&op.getBody(), converter)))
612 auto *blockBefore = rewriter.getInsertionBlock();
614 rewriter.splitBlock(blockBefore, rewriter.getInsertionPoint());
617 rewriter.setInsertionPointToEnd(blockBefore);
618 mlir::cf::BranchOp::create(rewriter, op.getLoc(), &op.getBody().front(),
619 adaptor.getInputs());
623 for (
auto &block : op.getBody()) {
624 auto outputOp = dyn_cast<arc::OutputOp>(block.getTerminator());
627 rewriter.setInsertionPointToEnd(&block);
628 rewriter.replaceOpWithNewOp<mlir::cf::BranchOp>(outputOp, blockAfter,
629 outputOp.getOperands());
633 rewriter.inlineRegionBefore(op.getBody(), blockAfter);
637 SmallVector<Value> args;
638 args.reserve(op.getNumResults());
639 for (
auto result : op.getResults())
640 args.push_back(blockAfter->addArgument(result.getType(), result.getLoc()));
641 rewriter.replaceOp(op, args);
642 auto conversion = converter.convertBlockSignature(blockAfter);
645 rewriter.applySignatureConversion(blockAfter, *conversion, &converter);
654struct LowerArcToLLVMPass
655 :
public circt::impl::LowerArcToLLVMBase<LowerArcToLLVMPass> {
656 void runOnOperation()
override;
660void LowerArcToLLVMPass::runOnOperation() {
664 DenseMap<Region *, hw::ConstantOp> zeros;
665 getOperation().walk([&](Operation *op) {
666 if (op->hasTrait<OpTrait::ConstantLike>())
668 for (
auto result : op->getResults()) {
669 auto type = dyn_cast<IntegerType>(result.getType());
670 if (!type || type.getWidth() != 0)
672 auto *region = op->getParentRegion();
673 auto &zero = zeros[region];
675 auto builder = OpBuilder::atBlockBegin(®ion->front());
679 result.replaceAllUsesWith(zero);
695 LLVMConversionTarget target(getContext());
696 target.addLegalOp<mlir::ModuleOp>();
697 target.addLegalOp<scf::YieldOp>();
700 LLVMTypeConverter converter(&getContext());
701 converter.addConversion([&](seq::ClockType type) {
702 return IntegerType::get(type.getContext(), 1);
704 converter.addConversion([&](StorageType type) {
705 return LLVM::LLVMPointerType::get(type.getContext());
707 converter.addConversion([&](MemoryType type) {
708 return LLVM::LLVMPointerType::get(type.getContext());
710 converter.addConversion([&](StateType type) {
711 return LLVM::LLVMPointerType::get(type.getContext());
713 converter.addConversion([&](SimModelInstanceType type) {
714 return LLVM::LLVMPointerType::get(type.getContext());
721 populateSCFToControlFlowConversionPatterns(
patterns);
722 populateFuncToLLVMConversionPatterns(converter,
patterns);
723 cf::populateControlFlowToLLVMConversionPatterns(converter,
patterns);
724 arith::populateArithToLLVMConversionPatterns(converter,
patterns);
725 index::populateIndexToLLVMConversionPatterns(converter,
patterns);
726 populateAnyFunctionOpInterfaceTypeConversionPattern(
patterns, converter);
729 DenseMap<std::pair<Type, ArrayAttr>, LLVM::GlobalOp> constAggregateGlobalsMap;
731 constAggregateGlobalsMap);
739 AllocMemoryOpLowering,
740 AllocStateLikeOpLowering<arc::AllocStateOp>,
741 AllocStateLikeOpLowering<arc::RootInputOp>,
742 AllocStateLikeOpLowering<arc::RootOutputOp>,
743 AllocStorageOpLowering,
746 MemoryReadOpLowering,
747 MemoryWriteOpLowering,
749 ReplaceOpWithInputPattern<seq::ToClockOp>,
750 ReplaceOpWithInputPattern<seq::FromClockOp>,
751 SeqConstClockLowering,
752 SimEmitValueOpLowering,
754 StateWriteOpLowering,
755 StorageGetOpLowering,
757 >(converter, &getContext());
761 SmallVector<ModelInfo> models;
767 llvm::DenseMap<StringRef, ModelInfoMap> modelMap(models.size());
769 llvm::DenseMap<StringRef, StateInfo> states(modelInfo.states.size());
770 for (
StateInfo &stateInfo : modelInfo.states)
771 states.insert({stateInfo.name, stateInfo});
774 ModelInfoMap{modelInfo.numStateBytes, std::move(states),
775 modelInfo.initialFnSym, modelInfo.finalFnSym}});
778 patterns.add<SimInstantiateOpLowering, SimSetInputOpLowering,
779 SimGetPortOpLowering, SimStepOpLowering>(
780 converter, &getContext(), modelMap);
783 ConversionConfig config;
784 config.allowPatternRollback =
false;
785 if (failed(applyFullConversion(getOperation(), target, std::move(
patterns),
791 return std::make_unique<LowerArcToLLVMPass>();
assert(baseType &&"element must be base type")
static llvm::Twine evalSymbolFromModelName(StringRef modelName)
static LogicalResult convert(arc::ExecuteOp op, arc::ExecuteOp::Adaptor adaptor, ConversionPatternRewriter &rewriter, const TypeConverter &converter)
Extension of RewritePatternSet that allows adding matchAndRewrite functions with op adaptors and Conv...
A namespace that is used to store existing names and generate new names in some scope within the IR.
void add(mlir::ModuleOp module)
void addDefinitions(mlir::Operation *top)
Populate the symbol cache with all symbol-defining operations within the 'top' operation.
Default symbol cache implementation; stores associations between names (StringAttr's) to mlir::Operat...
mlir::LogicalResult collectModels(mlir::ModuleOp module, llvm::SmallVector< ModelInfo > &models)
Collects information about all Arc models in the provided module, and adds it to models.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
void populateHWToLLVMConversionPatterns(mlir::LLVMTypeConverter &converter, RewritePatternSet &patterns, Namespace &globals, DenseMap< std::pair< Type, ArrayAttr >, mlir::LLVM::GlobalOp > &constAggregateGlobalsMap)
Get the HW to LLVM conversion patterns.
void populateCombToArithConversionPatterns(TypeConverter &converter, RewritePatternSet &patterns)
void populateCombToLLVMConversionPatterns(mlir::LLVMTypeConverter &converter, RewritePatternSet &patterns)
Get the Comb to LLVM conversion patterns.
void populateHWToLLVMTypeConversions(mlir::LLVMTypeConverter &converter)
Get the HW to LLVM type conversions.
std::unique_ptr< OperationPass< ModuleOp > > createLowerArcToLLVMPass()
Gathers information about a given Arc model.
Gathers information about a given Arc state.