24 #include "llvm/ADT/TypeSwitch.h"
27 #define GEN_PASS_DEF_CONVERTASYNCTOLLVMPASS
28 #include "mlir/Conversion/Passes.h.inc"
31 #define DEBUG_TYPE "convert-async-to-llvm"
40 static constexpr
const char *
kAddRef =
"mlirAsyncRuntimeAddRef";
41 static constexpr
const char *
kDropRef =
"mlirAsyncRuntimeDropRef";
42 static constexpr
const char *
kCreateToken =
"mlirAsyncRuntimeCreateToken";
43 static constexpr
const char *
kCreateValue =
"mlirAsyncRuntimeCreateValue";
44 static constexpr
const char *
kCreateGroup =
"mlirAsyncRuntimeCreateGroup";
45 static constexpr
const char *
kEmplaceToken =
"mlirAsyncRuntimeEmplaceToken";
46 static constexpr
const char *
kEmplaceValue =
"mlirAsyncRuntimeEmplaceValue";
47 static constexpr
const char *
kSetTokenError =
"mlirAsyncRuntimeSetTokenError";
48 static constexpr
const char *
kSetValueError =
"mlirAsyncRuntimeSetValueError";
49 static constexpr
const char *
kIsTokenError =
"mlirAsyncRuntimeIsTokenError";
50 static constexpr
const char *
kIsValueError =
"mlirAsyncRuntimeIsValueError";
51 static constexpr
const char *
kIsGroupError =
"mlirAsyncRuntimeIsGroupError";
52 static constexpr
const char *
kAwaitToken =
"mlirAsyncRuntimeAwaitToken";
53 static constexpr
const char *
kAwaitValue =
"mlirAsyncRuntimeAwaitValue";
54 static constexpr
const char *
kAwaitGroup =
"mlirAsyncRuntimeAwaitAllInGroup";
55 static constexpr
const char *
kExecute =
"mlirAsyncRuntimeExecute";
57 "mlirAsyncRuntimeGetValueStorage";
59 "mlirAsyncRuntimeAddTokenToGroup";
61 "mlirAsyncRuntimeAwaitTokenAndExecute";
63 "mlirAsyncRuntimeAwaitValueAndExecute";
65 "mlirAsyncRuntimeAwaitAllInGroupAndExecute";
67 "mlirAsyncRuntimGetNumWorkerThreads";
77 static LLVM::LLVMPointerType opaquePointerType(
MLIRContext *ctx) {
81 static LLVM::LLVMTokenType tokenType(
MLIRContext *ctx) {
85 static FunctionType addOrDropRefFunctionType(
MLIRContext *ctx) {
86 auto ref = opaquePointerType(ctx);
91 static FunctionType createTokenFunctionType(
MLIRContext *ctx) {
95 static FunctionType createValueFunctionType(
MLIRContext *ctx) {
97 auto value = opaquePointerType(ctx);
101 static FunctionType createGroupFunctionType(
MLIRContext *ctx) {
106 static FunctionType getValueStorageFunctionType(
MLIRContext *ctx) {
107 auto ptrType = opaquePointerType(ctx);
111 static FunctionType emplaceTokenFunctionType(
MLIRContext *ctx) {
115 static FunctionType emplaceValueFunctionType(
MLIRContext *ctx) {
116 auto value = opaquePointerType(ctx);
120 static FunctionType setTokenErrorFunctionType(
MLIRContext *ctx) {
124 static FunctionType setValueErrorFunctionType(
MLIRContext *ctx) {
125 auto value = opaquePointerType(ctx);
129 static FunctionType isTokenErrorFunctionType(
MLIRContext *ctx) {
134 static FunctionType isValueErrorFunctionType(
MLIRContext *ctx) {
135 auto value = opaquePointerType(ctx);
140 static FunctionType isGroupErrorFunctionType(
MLIRContext *ctx) {
145 static FunctionType awaitTokenFunctionType(
MLIRContext *ctx) {
149 static FunctionType awaitValueFunctionType(
MLIRContext *ctx) {
150 auto value = opaquePointerType(ctx);
154 static FunctionType awaitGroupFunctionType(
MLIRContext *ctx) {
158 static FunctionType executeFunctionType(
MLIRContext *ctx) {
159 auto ptrType = opaquePointerType(ctx);
163 static FunctionType addTokenToGroupFunctionType(
MLIRContext *ctx) {
169 static FunctionType awaitTokenAndExecuteFunctionType(
MLIRContext *ctx) {
170 auto ptrType = opaquePointerType(ctx);
174 static FunctionType awaitValueAndExecuteFunctionType(
MLIRContext *ctx) {
175 auto ptrType = opaquePointerType(ctx);
179 static FunctionType awaitAllAndExecuteFunctionType(
MLIRContext *ctx) {
180 auto ptrType = opaquePointerType(ctx);
184 static FunctionType getNumWorkerThreads(
MLIRContext *ctx) {
191 auto ptrType = opaquePointerType(ctx);
202 auto addFuncDecl = [&](StringRef name, FunctionType type) {
203 if (module.lookupSymbol(name))
205 func::FuncOp::create(builder, name, type).setPrivate();
209 addFuncDecl(
kAddRef, AsyncAPI::addOrDropRefFunctionType(ctx));
210 addFuncDecl(
kDropRef, AsyncAPI::addOrDropRefFunctionType(ctx));
211 addFuncDecl(
kCreateToken, AsyncAPI::createTokenFunctionType(ctx));
212 addFuncDecl(
kCreateValue, AsyncAPI::createValueFunctionType(ctx));
213 addFuncDecl(
kCreateGroup, AsyncAPI::createGroupFunctionType(ctx));
214 addFuncDecl(
kEmplaceToken, AsyncAPI::emplaceTokenFunctionType(ctx));
215 addFuncDecl(
kEmplaceValue, AsyncAPI::emplaceValueFunctionType(ctx));
216 addFuncDecl(
kSetTokenError, AsyncAPI::setTokenErrorFunctionType(ctx));
217 addFuncDecl(
kSetValueError, AsyncAPI::setValueErrorFunctionType(ctx));
218 addFuncDecl(
kIsTokenError, AsyncAPI::isTokenErrorFunctionType(ctx));
219 addFuncDecl(
kIsValueError, AsyncAPI::isValueErrorFunctionType(ctx));
220 addFuncDecl(
kIsGroupError, AsyncAPI::isGroupErrorFunctionType(ctx));
221 addFuncDecl(
kAwaitToken, AsyncAPI::awaitTokenFunctionType(ctx));
222 addFuncDecl(
kAwaitValue, AsyncAPI::awaitValueFunctionType(ctx));
223 addFuncDecl(
kAwaitGroup, AsyncAPI::awaitGroupFunctionType(ctx));
224 addFuncDecl(
kExecute, AsyncAPI::executeFunctionType(ctx));
228 AsyncAPI::awaitTokenAndExecuteFunctionType(ctx));
230 AsyncAPI::awaitValueAndExecuteFunctionType(ctx));
232 AsyncAPI::awaitAllAndExecuteFunctionType(ctx));
240 static constexpr
const char *
kResume =
"__resume";
246 if (module.lookupSymbol(
kResume))
250 auto loc = module.getLoc();
254 Type ptrType = AsyncAPI::opaquePointerType(ctx);
256 auto resumeOp = LLVM::LLVMFuncOp::create(
258 resumeOp.setPrivate();
260 auto *block = resumeOp.addEntryBlock(moduleBuilder);
263 LLVM::CoroResumeOp::create(blockBuilder, resumeOp.getArgument(0));
264 LLVM::ReturnOp::create(blockBuilder,
ValueRange());
277 addConversion([](
Type type) {
return type; });
278 addConversion([](
Type type) {
return convertAsyncTypes(type); });
285 UnrealizedConversionCastOp::create(builder, loc, type, inputs);
286 return cast.getResult(0);
289 addSourceMaterialization(addUnrealizedCast);
290 addTargetMaterialization(addUnrealizedCast);
293 static std::optional<Type> convertAsyncTypes(
Type type) {
294 if (isa<TokenType, GroupType, ValueType>(type))
295 return AsyncAPI::opaquePointerType(type.
getContext());
297 if (isa<CoroIdType, CoroStateType>(type))
298 return AsyncAPI::tokenType(type.
getContext());
299 if (isa<CoroHandleType>(type))
300 return AsyncAPI::opaquePointerType(type.
getContext());
309 template <
typename SourceOp>
315 AsyncOpConversionPattern(
const AsyncRuntimeTypeConverter &typeConverter,
317 : Base(typeConverter, context) {}
320 const AsyncRuntimeTypeConverter *getTypeConverter()
const {
321 return static_cast<const AsyncRuntimeTypeConverter *
>(
322 Base::getTypeConverter());
333 class CoroIdOpConversion :
public AsyncOpConversionPattern<CoroIdOp> {
335 using AsyncOpConversionPattern::AsyncOpConversionPattern;
338 matchAndRewrite(CoroIdOp op, OpAdaptor adaptor,
340 auto token = AsyncAPI::tokenType(op->getContext());
341 auto ptrType = AsyncAPI::opaquePointerType(op->getContext());
342 auto loc = op->getLoc();
346 LLVM::ConstantOp::create(rewriter, loc, rewriter.
getI32Type(), 0);
347 auto nullPtr = LLVM::ZeroOp::create(rewriter, loc, ptrType);
351 op, token,
ValueRange({constZero, nullPtr, nullPtr, nullPtr}));
363 class CoroBeginOpConversion :
public AsyncOpConversionPattern<CoroBeginOp> {
365 using AsyncOpConversionPattern::AsyncOpConversionPattern;
368 matchAndRewrite(CoroBeginOp op, OpAdaptor adaptor,
370 auto ptrType = AsyncAPI::opaquePointerType(op->getContext());
371 auto loc = op->getLoc();
375 LLVM::CoroSizeOp::create(rewriter, loc, rewriter.
getI64Type());
378 LLVM::CoroAlignOp::create(rewriter, loc, rewriter.
getI64Type());
383 auto makeConstant = [&](uint64_t c) {
384 return LLVM::ConstantOp::create(rewriter, op->getLoc(),
387 coroSize = LLVM::AddOp::create(rewriter, op->getLoc(), coroSize, coroAlign);
389 LLVM::SubOp::create(rewriter, op->getLoc(), coroSize, makeConstant(1));
391 LLVM::SubOp::create(rewriter, op->getLoc(), makeConstant(0), coroAlign);
393 LLVM::AndOp::create(rewriter, op->getLoc(), coroSize, negCoroAlign);
397 rewriter, op->getParentOfType<ModuleOp>(), rewriter.
getI64Type());
398 if (failed(allocFuncOp))
400 auto coroAlloc = LLVM::CallOp::create(rewriter, loc, allocFuncOp.value(),
404 auto coroId = CoroBeginOpAdaptor(adaptor.getOperands()).getId();
406 op, ptrType,
ValueRange({coroId, coroAlloc.getResult()}));
418 class CoroFreeOpConversion :
public AsyncOpConversionPattern<CoroFreeOp> {
420 using AsyncOpConversionPattern::AsyncOpConversionPattern;
423 matchAndRewrite(CoroFreeOp op, OpAdaptor adaptor,
425 auto ptrType = AsyncAPI::opaquePointerType(op->getContext());
426 auto loc = op->getLoc();
430 LLVM::CoroFreeOp::create(rewriter, loc, ptrType, adaptor.getOperands());
435 if (failed(freeFuncOp))
455 matchAndRewrite(CoroEndOp op, OpAdaptor adaptor,
459 LLVM::ConstantOp::create(rewriter, op->getLoc(), rewriter.
getI1Type(),
461 auto noneToken = LLVM::NoneTokenOp::create(rewriter, op->getLoc());
464 auto coroHdl = adaptor.getHandle();
465 LLVM::CoroEndOp::create(rewriter, op->getLoc(), rewriter.
getI1Type(),
466 ValueRange({coroHdl, constFalse, noneToken}));
484 matchAndRewrite(CoroSaveOp op, OpAdaptor adaptor,
488 op, AsyncAPI::tokenType(op->getContext()), adaptor.getOperands());
530 matchAndRewrite(CoroSuspendOp op, OpAdaptor adaptor,
534 auto loc = op->getLoc();
537 auto constFalse = LLVM::ConstantOp::create(
541 auto coroState = adaptor.getState();
542 auto coroSuspend = LLVM::CoroSuspendOp::create(
543 rewriter, loc, i8,
ValueRange({coroState, constFalse}));
552 op.getCleanupDest()};
554 op, LLVM::SExtOp::create(rewriter, loc, i32, coroSuspend.getResult()),
580 matchAndRewrite(RuntimeCreateOp op, OpAdaptor adaptor,
583 Type resultType = op->getResultTypes()[0];
586 if (isa<TokenType>(resultType)) {
593 if (
auto value = dyn_cast<ValueType>(resultType)) {
595 auto sizeOf = [&](ValueType valueType) ->
Value {
599 auto storedType = converter->
convertType(valueType.getValueType());
600 auto storagePtrType =
601 AsyncAPI::opaquePointerType(rewriter.
getContext());
605 auto nullPtr = LLVM::ZeroOp::create(rewriter, loc, storagePtrType);
607 LLVM::GEPOp::create(rewriter, loc, storagePtrType, storedType,
609 return LLVM::PtrToIntOp::create(rewriter, loc, i64, gep);
628 class RuntimeCreateGroupOpLowering
634 matchAndRewrite(RuntimeCreateGroupOp op, OpAdaptor adaptor,
637 Type resultType = op.getResult().getType();
641 adaptor.getOperands());
652 class RuntimeSetAvailableOpLowering
658 matchAndRewrite(RuntimeSetAvailableOp op, OpAdaptor adaptor,
660 StringRef apiFuncName =
666 adaptor.getOperands());
678 class RuntimeSetErrorOpLowering
684 matchAndRewrite(RuntimeSetErrorOp op, OpAdaptor adaptor,
686 StringRef apiFuncName =
692 adaptor.getOperands());
709 matchAndRewrite(RuntimeIsErrorOp op, OpAdaptor adaptor,
711 StringRef apiFuncName =
718 op, apiFuncName, rewriter.
getI1Type(), adaptor.getOperands());
734 matchAndRewrite(RuntimeAwaitOp op, OpAdaptor adaptor,
736 StringRef apiFuncName =
742 func::CallOp::create(rewriter, op->getLoc(), apiFuncName,
TypeRange(),
743 adaptor.getOperands());
756 class RuntimeAwaitAndResumeOpLowering
757 :
public AsyncOpConversionPattern<RuntimeAwaitAndResumeOp> {
759 using AsyncOpConversionPattern::AsyncOpConversionPattern;
762 matchAndRewrite(RuntimeAwaitAndResumeOp op, OpAdaptor adaptor,
764 StringRef apiFuncName =
770 Value operand = adaptor.getOperand();
771 Value handle = adaptor.getHandle();
775 auto resumePtr = LLVM::AddressOfOp::create(
776 rewriter, op->getLoc(),
779 func::CallOp::create(rewriter, op->getLoc(), apiFuncName,
TypeRange(),
780 ValueRange({operand, handle, resumePtr.getRes()}));
793 class RuntimeResumeOpLowering
794 :
public AsyncOpConversionPattern<RuntimeResumeOp> {
796 using AsyncOpConversionPattern::AsyncOpConversionPattern;
799 matchAndRewrite(RuntimeResumeOp op, OpAdaptor adaptor,
803 auto resumePtr = LLVM::AddressOfOp::create(
804 rewriter, op->getLoc(),
808 auto coroHdl = adaptor.getHandle();
827 matchAndRewrite(RuntimeStoreOp op, OpAdaptor adaptor,
832 auto ptrType = AsyncAPI::opaquePointerType(rewriter.
getContext());
833 auto storage = adaptor.getStorage();
838 auto valueType = op.getValue().getType();
839 auto llvmValueType = getTypeConverter()->convertType(valueType);
842 op,
"failed to convert stored value type to LLVM type");
844 Value castedStoragePtr = storagePtr.getResult(0);
846 auto value = adaptor.getValue();
847 LLVM::StoreOp::create(rewriter, loc, value, castedStoragePtr);
867 matchAndRewrite(RuntimeLoadOp op, OpAdaptor adaptor,
872 auto ptrType = AsyncAPI::opaquePointerType(rewriter.
getContext());
873 auto storage = adaptor.getStorage();
878 auto valueType = op.getResult().getType();
879 auto llvmValueType = getTypeConverter()->convertType(valueType);
882 op,
"failed to convert loaded value type to LLVM type");
884 Value castedStoragePtr = storagePtr.getResult(0);
900 class RuntimeAddToGroupOpLowering
906 matchAndRewrite(RuntimeAddToGroupOp op, OpAdaptor adaptor,
909 if (!isa<TokenType>(op.getOperand().getType()))
927 class RuntimeNumWorkerThreadsOpLowering
933 matchAndRewrite(RuntimeNumWorkerThreadsOp op, OpAdaptor adaptor,
951 template <
typename RefCountingOp>
954 explicit RefCountingOpLowering(
const TypeConverter &converter,
957 apiFunctionName(apiFunctionName) {}
960 matchAndRewrite(RefCountingOp op,
typename RefCountingOp::Adaptor adaptor,
963 arith::ConstantOp::create(rewriter, op->getLoc(), rewriter.
getI64Type(),
966 auto operand = adaptor.getOperand();
974 StringRef apiFunctionName;
977 class RuntimeAddRefOpLowering :
public RefCountingOpLowering<RuntimeAddRefOp> {
979 explicit RuntimeAddRefOpLowering(
const TypeConverter &converter,
981 : RefCountingOpLowering(converter, ctx,
kAddRef) {}
984 class RuntimeDropRefOpLowering
985 :
public RefCountingOpLowering<RuntimeDropRefOp> {
987 explicit RuntimeDropRefOpLowering(
const TypeConverter &converter,
989 : RefCountingOpLowering(converter, ctx,
kDropRef) {}
1003 matchAndRewrite(func::ReturnOp op, OpAdaptor adaptor,
1014 struct ConvertAsyncToLLVMPass
1015 :
public impl::ConvertAsyncToLLVMPassBase<ConvertAsyncToLLVMPass> {
1018 void runOnOperation()
override;
1022 void ConvertAsyncToLLVMPass::runOnOperation() {
1023 ModuleOp module = getOperation();
1037 AsyncRuntimeTypeConverter converter(
options);
1043 llvmConverter.addConversion([&](
Type type) {
1044 return AsyncRuntimeTypeConverter::convertAsyncTypes(type);
1048 populateFunctionOpInterfaceTypeConversionPattern<func::FuncOp>(
patterns,
1053 patterns.add<ReturnOpOpConversion>(converter, ctx);
1056 patterns.add<RuntimeSetAvailableOpLowering, RuntimeSetErrorOpLowering,
1057 RuntimeIsErrorOpLowering, RuntimeAwaitOpLowering,
1058 RuntimeAwaitAndResumeOpLowering, RuntimeResumeOpLowering,
1059 RuntimeAddToGroupOpLowering, RuntimeNumWorkerThreadsOpLowering,
1060 RuntimeAddRefOpLowering, RuntimeDropRefOpLowering>(converter,
1065 patterns.add<RuntimeCreateOpLowering, RuntimeCreateGroupOpLowering,
1066 RuntimeStoreOpLowering, RuntimeLoadOpLowering>(llvmConverter);
1070 .add<CoroIdOpConversion, CoroBeginOpConversion, CoroFreeOpConversion,
1071 CoroEndOpConversion, CoroSaveOpConversion, CoroSuspendOpConversion>(
1075 target.addLegalOp<arith::ConstantOp, func::ConstantOp,
1076 UnrealizedConversionCastOp>();
1077 target.addLegalDialect<LLVM::LLVMDialect>();
1081 target.addIllegalDialect<AsyncDialect>();
1084 target.addDynamicallyLegalOp<func::FuncOp>([&](func::FuncOp op) {
1085 return converter.isSignatureLegal(op.getFunctionType());
1087 target.addDynamicallyLegalOp<func::ReturnOp>([&](func::ReturnOp op) {
1088 return converter.isLegal(op.getOperandTypes());
1090 target.addDynamicallyLegalOp<func::CallOp>([&](func::CallOp op) {
1091 return converter.isSignatureLegal(op.getCalleeType());
1095 signalPassFailure();
1107 matchAndRewrite(ExecuteOp op, OpAdaptor adaptor,
1112 newOp.getRegion().end());
1115 newOp->setOperands(adaptor.getOperands());
1118 for (
auto result : newOp.getResults())
1119 result.setType(typeConverter->convertType(result.getType()));
1121 rewriter.
replaceOp(op, newOp.getResults());
1131 matchAndRewrite(AwaitOp op, OpAdaptor adaptor,
1143 matchAndRewrite(async::YieldOp op, OpAdaptor adaptor,
1154 typeConverter.
addConversion([&](TokenType type) {
return type; });
1160 patterns.add<ConvertExecuteOpTypes, ConvertAwaitOpTypes, ConvertYieldOpTypes>(
1161 typeConverter,
patterns.getContext());
static constexpr const char * kAwaitValueAndExecute
static constexpr const char * kCreateValue
static constexpr const char * kCreateGroup
static constexpr const char * kCreateToken
static constexpr const char * kEmplaceValue
static void addResumeFunction(ModuleOp module)
A function that takes a coroutine handle and calls a llvm.coro.resume intrinsics.
static constexpr const char * kEmplaceToken
static void addAsyncRuntimeApiDeclarations(ModuleOp module)
Adds Async Runtime C API declarations to the module.
static constexpr const char * kResume
static constexpr const char * kAddRef
static constexpr const char * kAwaitTokenAndExecute
static constexpr const char * kAwaitValue
static constexpr const char * kSetTokenError
static constexpr const char * kExecute
static constexpr const char * kAddTokenToGroup
static constexpr const char * kIsGroupError
static constexpr const char * kSetValueError
static constexpr const char * kIsTokenError
static constexpr const char * kAwaitGroup
static constexpr const char * kAwaitAllAndExecute
static constexpr const char * kGetNumWorkerThreads
static constexpr const char * kDropRef
static constexpr const char * kIsValueError
static constexpr const char * kAwaitToken
static constexpr const char * kGetValueStorage
static llvm::ManagedStatic< PassManagerOptions > options
IntegerAttr getI64IntegerAttr(int64_t value)
IntegerType getIntegerType(unsigned width)
BoolAttr getBoolAttr(bool value)
MLIRContext * getContext() const
This class implements a pattern rewriter for use with ConversionPatterns.
void replaceOp(Operation *op, ValueRange newValues) override
Replace the given operation with the new values.
FailureOr< Block * > convertRegionTypes(Region *region, const TypeConverter &converter, TypeConverter::SignatureConversion *entryConversion=nullptr)
Apply a signature conversion to each block in the given region.
void eraseOp(Operation *op) override
PatternRewriter hook for erasing a dead operation.
This class describes a specific conversion target.
void addDynamicallyLegalOp(OperationName op, const DynamicLegalityCallbackFn &callback)
Register the given operation as dynamically legal and set the dynamic legalization callback to the on...
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
ConvertOpToLLVMPattern(const LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
static ImplicitLocOpBuilder atBlockEnd(Location loc, Block *block, Listener *listener=nullptr)
Create a builder and set the insertion point to after the last operation in the block but still insid...
Conversion from types to the LLVM IR dialect.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Options to control the LLVM lowering.
MLIRContext is the top-level object for a collection of MLIR operations.
This class helps build Operations.
Operation * cloneWithoutRegions(Operation &op, IRMapping &mapper)
Creates a deep copy of this operation but keep the operation regions empty.
OpConversionPattern is a wrapper around ConversionPattern that allows for matching and rewriting agai...
OpConversionPattern(MLIRContext *context, PatternBenefit benefit=1)
Operation is the basic unit of execution within MLIR.
std::enable_if_t<!std::is_convertible< CallbackT, Twine >::value, LogicalResult > notifyMatchFailure(Location loc, CallbackT &&reasonCallback)
Used to notify the listener that the IR failed to be rewritten because of a match failure,...
void inlineRegionBefore(Region ®ion, Region &parent, Region::iterator before)
Move the blocks that belong to "region" before the given position in another region "parent".
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
void addConversion(FnT &&callback)
Register a conversion function.
bool isLegal(Type type) const
Return true if the given type is legal for this type converter, i.e.
LogicalResult convertType(Type t, SmallVectorImpl< Type > &results) const
Convert the given type.
This class provides an abstraction over the various different ranges of value types.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
MLIRContext * getContext() const
Return the MLIRContext in which this type was uniqued.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Location getLoc() const
Return the location of this value.
FailureOr< LLVM::LLVMFuncOp > lookupOrCreateFreeFn(OpBuilder &b, Operation *moduleOp, SymbolTableCollection *symbolTables=nullptr)
FailureOr< LLVM::LLVMFuncOp > lookupOrCreateAlignedAllocFn(OpBuilder &b, Operation *moduleOp, Type indexType, SymbolTableCollection *symbolTables=nullptr)
Include the generated interface declarations.
const FrozenRewritePatternSet & patterns
void populateAsyncStructuralTypeConversionsAndLegality(TypeConverter &typeConverter, RewritePatternSet &patterns, ConversionTarget &target)
Populates patterns for async structural type conversions.
void populateCallOpTypeConversionPattern(RewritePatternSet &patterns, const TypeConverter &converter)
Add a pattern to the given pattern list to convert the operand and result types of a CallOp with the ...
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
LogicalResult applyPartialConversion(ArrayRef< Operation * > ops, const ConversionTarget &target, const FrozenRewritePatternSet &patterns, ConversionConfig config=ConversionConfig())
Below we define several entry points for operation conversion.