26 #include "llvm/ADT/TypeSwitch.h"
29 #define GEN_PASS_DEF_CONVERTASYNCTOLLVMPASS
30 #include "mlir/Conversion/Passes.h.inc"
33 #define DEBUG_TYPE "convert-async-to-llvm"
42 static constexpr
const char *
kAddRef =
"mlirAsyncRuntimeAddRef";
43 static constexpr
const char *
kDropRef =
"mlirAsyncRuntimeDropRef";
44 static constexpr
const char *
kCreateToken =
"mlirAsyncRuntimeCreateToken";
45 static constexpr
const char *
kCreateValue =
"mlirAsyncRuntimeCreateValue";
46 static constexpr
const char *
kCreateGroup =
"mlirAsyncRuntimeCreateGroup";
47 static constexpr
const char *
kEmplaceToken =
"mlirAsyncRuntimeEmplaceToken";
48 static constexpr
const char *
kEmplaceValue =
"mlirAsyncRuntimeEmplaceValue";
49 static constexpr
const char *
kSetTokenError =
"mlirAsyncRuntimeSetTokenError";
50 static constexpr
const char *
kSetValueError =
"mlirAsyncRuntimeSetValueError";
51 static constexpr
const char *
kIsTokenError =
"mlirAsyncRuntimeIsTokenError";
52 static constexpr
const char *
kIsValueError =
"mlirAsyncRuntimeIsValueError";
53 static constexpr
const char *
kIsGroupError =
"mlirAsyncRuntimeIsGroupError";
54 static constexpr
const char *
kAwaitToken =
"mlirAsyncRuntimeAwaitToken";
55 static constexpr
const char *
kAwaitValue =
"mlirAsyncRuntimeAwaitValue";
56 static constexpr
const char *
kAwaitGroup =
"mlirAsyncRuntimeAwaitAllInGroup";
57 static constexpr
const char *
kExecute =
"mlirAsyncRuntimeExecute";
59 "mlirAsyncRuntimeGetValueStorage";
61 "mlirAsyncRuntimeAddTokenToGroup";
63 "mlirAsyncRuntimeAwaitTokenAndExecute";
65 "mlirAsyncRuntimeAwaitValueAndExecute";
67 "mlirAsyncRuntimeAwaitAllInGroupAndExecute";
69 "mlirAsyncRuntimGetNumWorkerThreads";
79 static LLVM::LLVMPointerType opaquePointerType(
MLIRContext *ctx) {
83 static LLVM::LLVMTokenType tokenType(
MLIRContext *ctx) {
87 static FunctionType addOrDropRefFunctionType(
MLIRContext *ctx) {
88 auto ref = opaquePointerType(ctx);
93 static FunctionType createTokenFunctionType(
MLIRContext *ctx) {
97 static FunctionType createValueFunctionType(
MLIRContext *ctx) {
99 auto value = opaquePointerType(ctx);
103 static FunctionType createGroupFunctionType(
MLIRContext *ctx) {
108 static FunctionType getValueStorageFunctionType(
MLIRContext *ctx) {
109 auto ptrType = opaquePointerType(ctx);
113 static FunctionType emplaceTokenFunctionType(
MLIRContext *ctx) {
117 static FunctionType emplaceValueFunctionType(
MLIRContext *ctx) {
118 auto value = opaquePointerType(ctx);
122 static FunctionType setTokenErrorFunctionType(
MLIRContext *ctx) {
126 static FunctionType setValueErrorFunctionType(
MLIRContext *ctx) {
127 auto value = opaquePointerType(ctx);
131 static FunctionType isTokenErrorFunctionType(
MLIRContext *ctx) {
136 static FunctionType isValueErrorFunctionType(
MLIRContext *ctx) {
137 auto value = opaquePointerType(ctx);
142 static FunctionType isGroupErrorFunctionType(
MLIRContext *ctx) {
147 static FunctionType awaitTokenFunctionType(
MLIRContext *ctx) {
151 static FunctionType awaitValueFunctionType(
MLIRContext *ctx) {
152 auto value = opaquePointerType(ctx);
156 static FunctionType awaitGroupFunctionType(
MLIRContext *ctx) {
160 static FunctionType executeFunctionType(
MLIRContext *ctx) {
161 auto ptrType = opaquePointerType(ctx);
165 static FunctionType addTokenToGroupFunctionType(
MLIRContext *ctx) {
171 static FunctionType awaitTokenAndExecuteFunctionType(
MLIRContext *ctx) {
172 auto ptrType = opaquePointerType(ctx);
176 static FunctionType awaitValueAndExecuteFunctionType(
MLIRContext *ctx) {
177 auto ptrType = opaquePointerType(ctx);
181 static FunctionType awaitAllAndExecuteFunctionType(
MLIRContext *ctx) {
182 auto ptrType = opaquePointerType(ctx);
186 static FunctionType getNumWorkerThreads(
MLIRContext *ctx) {
193 auto ptrType = opaquePointerType(ctx);
204 auto addFuncDecl = [&](StringRef name, FunctionType type) {
205 if (module.lookupSymbol(name))
207 builder.create<func::FuncOp>(name, type).setPrivate();
211 addFuncDecl(
kAddRef, AsyncAPI::addOrDropRefFunctionType(ctx));
212 addFuncDecl(
kDropRef, AsyncAPI::addOrDropRefFunctionType(ctx));
213 addFuncDecl(
kCreateToken, AsyncAPI::createTokenFunctionType(ctx));
214 addFuncDecl(
kCreateValue, AsyncAPI::createValueFunctionType(ctx));
215 addFuncDecl(
kCreateGroup, AsyncAPI::createGroupFunctionType(ctx));
216 addFuncDecl(
kEmplaceToken, AsyncAPI::emplaceTokenFunctionType(ctx));
217 addFuncDecl(
kEmplaceValue, AsyncAPI::emplaceValueFunctionType(ctx));
218 addFuncDecl(
kSetTokenError, AsyncAPI::setTokenErrorFunctionType(ctx));
219 addFuncDecl(
kSetValueError, AsyncAPI::setValueErrorFunctionType(ctx));
220 addFuncDecl(
kIsTokenError, AsyncAPI::isTokenErrorFunctionType(ctx));
221 addFuncDecl(
kIsValueError, AsyncAPI::isValueErrorFunctionType(ctx));
222 addFuncDecl(
kIsGroupError, AsyncAPI::isGroupErrorFunctionType(ctx));
223 addFuncDecl(
kAwaitToken, AsyncAPI::awaitTokenFunctionType(ctx));
224 addFuncDecl(
kAwaitValue, AsyncAPI::awaitValueFunctionType(ctx));
225 addFuncDecl(
kAwaitGroup, AsyncAPI::awaitGroupFunctionType(ctx));
226 addFuncDecl(
kExecute, AsyncAPI::executeFunctionType(ctx));
230 AsyncAPI::awaitTokenAndExecuteFunctionType(ctx));
232 AsyncAPI::awaitValueAndExecuteFunctionType(ctx));
234 AsyncAPI::awaitAllAndExecuteFunctionType(ctx));
242 static constexpr
const char *
kResume =
"__resume";
248 if (module.lookupSymbol(
kResume))
252 auto loc = module.getLoc();
256 Type ptrType = AsyncAPI::opaquePointerType(ctx);
258 auto resumeOp = moduleBuilder.create<LLVM::LLVMFuncOp>(
260 resumeOp.setPrivate();
262 auto *block = resumeOp.addEntryBlock(moduleBuilder);
265 blockBuilder.create<LLVM::CoroResumeOp>(resumeOp.getArgument(0));
266 blockBuilder.create<LLVM::ReturnOp>(
ValueRange());
279 addConversion([](
Type type) {
return type; });
280 addConversion([](
Type type) {
return convertAsyncTypes(type); });
286 auto cast = builder.
create<UnrealizedConversionCastOp>(loc, type, inputs);
290 addSourceMaterialization(addUnrealizedCast);
291 addTargetMaterialization(addUnrealizedCast);
294 static std::optional<Type> convertAsyncTypes(
Type type) {
295 if (isa<TokenType, GroupType, ValueType>(type))
296 return AsyncAPI::opaquePointerType(type.
getContext());
298 if (isa<CoroIdType, CoroStateType>(type))
299 return AsyncAPI::tokenType(type.
getContext());
300 if (isa<CoroHandleType>(type))
301 return AsyncAPI::opaquePointerType(type.
getContext());
310 template <
typename SourceOp>
316 AsyncOpConversionPattern(
const AsyncRuntimeTypeConverter &typeConverter,
318 : Base(typeConverter, context) {}
321 const AsyncRuntimeTypeConverter *getTypeConverter()
const {
322 return static_cast<const AsyncRuntimeTypeConverter *
>(
323 Base::getTypeConverter());
334 class CoroIdOpConversion :
public AsyncOpConversionPattern<CoroIdOp> {
336 using AsyncOpConversionPattern::AsyncOpConversionPattern;
339 matchAndRewrite(CoroIdOp op, OpAdaptor adaptor,
341 auto token = AsyncAPI::tokenType(op->getContext());
342 auto ptrType = AsyncAPI::opaquePointerType(op->getContext());
343 auto loc = op->getLoc();
348 auto nullPtr = rewriter.
create<LLVM::ZeroOp>(loc, ptrType);
352 op, token,
ValueRange({constZero, nullPtr, nullPtr, nullPtr}));
364 class CoroBeginOpConversion :
public AsyncOpConversionPattern<CoroBeginOp> {
366 using AsyncOpConversionPattern::AsyncOpConversionPattern;
369 matchAndRewrite(CoroBeginOp op, OpAdaptor adaptor,
371 auto ptrType = AsyncAPI::opaquePointerType(op->getContext());
372 auto loc = op->getLoc();
384 auto makeConstant = [&](uint64_t c) {
385 return rewriter.
create<LLVM::ConstantOp>(op->getLoc(),
388 coroSize = rewriter.
create<LLVM::AddOp>(op->getLoc(), coroSize, coroAlign);
390 rewriter.
create<LLVM::SubOp>(op->getLoc(), coroSize, makeConstant(1));
392 rewriter.
create<LLVM::SubOp>(op->getLoc(), makeConstant(0), coroAlign);
394 rewriter.
create<LLVM::AndOp>(op->getLoc(), coroSize, negCoroAlign);
398 op->getParentOfType<ModuleOp>(), rewriter.
getI64Type());
399 auto coroAlloc = rewriter.
create<LLVM::CallOp>(
400 loc, allocFuncOp,
ValueRange{coroAlign, coroSize});
403 auto coroId = CoroBeginOpAdaptor(adaptor.getOperands()).getId();
405 op, ptrType,
ValueRange({coroId, coroAlloc.getResult()}));
417 class CoroFreeOpConversion :
public AsyncOpConversionPattern<CoroFreeOp> {
419 using AsyncOpConversionPattern::AsyncOpConversionPattern;
422 matchAndRewrite(CoroFreeOp op, OpAdaptor adaptor,
424 auto ptrType = AsyncAPI::opaquePointerType(op->getContext());
425 auto loc = op->getLoc();
429 rewriter.
create<LLVM::CoroFreeOp>(loc, ptrType, adaptor.getOperands());
452 matchAndRewrite(CoroEndOp op, OpAdaptor adaptor,
455 auto constFalse = rewriter.
create<LLVM::ConstantOp>(
457 auto noneToken = rewriter.
create<LLVM::NoneTokenOp>(op->getLoc());
460 auto coroHdl = adaptor.getHandle();
461 rewriter.
create<LLVM::CoroEndOp>(
463 ValueRange({coroHdl, constFalse, noneToken}));
481 matchAndRewrite(CoroSaveOp op, OpAdaptor adaptor,
485 op, AsyncAPI::tokenType(op->getContext()), adaptor.getOperands());
527 matchAndRewrite(CoroSuspendOp op, OpAdaptor adaptor,
531 auto loc = op->getLoc();
534 auto constFalse = rewriter.
create<LLVM::ConstantOp>(
538 auto coroState = adaptor.getState();
539 auto coroSuspend = rewriter.
create<LLVM::CoroSuspendOp>(
540 loc, i8,
ValueRange({coroState, constFalse}));
549 op.getCleanupDest()};
551 op, rewriter.
create<LLVM::SExtOp>(loc, i32, coroSuspend.getResult()),
577 matchAndRewrite(RuntimeCreateOp op, OpAdaptor adaptor,
580 Type resultType = op->getResultTypes()[0];
583 if (isa<TokenType>(resultType)) {
590 if (
auto value = dyn_cast<ValueType>(resultType)) {
592 auto sizeOf = [&](ValueType valueType) ->
Value {
596 auto storedType = converter->
convertType(valueType.getValueType());
597 auto storagePtrType =
598 AsyncAPI::opaquePointerType(rewriter.
getContext());
602 auto nullPtr = rewriter.
create<LLVM::ZeroOp>(loc, storagePtrType);
604 rewriter.
create<LLVM::GEPOp>(loc, storagePtrType, storedType,
606 return rewriter.
create<LLVM::PtrToIntOp>(loc, i64, gep);
625 class RuntimeCreateGroupOpLowering
631 matchAndRewrite(RuntimeCreateGroupOp op, OpAdaptor adaptor,
634 Type resultType = op.getResult().getType();
638 adaptor.getOperands());
649 class RuntimeSetAvailableOpLowering
655 matchAndRewrite(RuntimeSetAvailableOp op, OpAdaptor adaptor,
657 StringRef apiFuncName =
663 adaptor.getOperands());
675 class RuntimeSetErrorOpLowering
681 matchAndRewrite(RuntimeSetErrorOp op, OpAdaptor adaptor,
683 StringRef apiFuncName =
689 adaptor.getOperands());
706 matchAndRewrite(RuntimeIsErrorOp op, OpAdaptor adaptor,
708 StringRef apiFuncName =
715 op, apiFuncName, rewriter.
getI1Type(), adaptor.getOperands());
731 matchAndRewrite(RuntimeAwaitOp op, OpAdaptor adaptor,
733 StringRef apiFuncName =
740 adaptor.getOperands());
753 class RuntimeAwaitAndResumeOpLowering
754 :
public AsyncOpConversionPattern<RuntimeAwaitAndResumeOp> {
756 using AsyncOpConversionPattern::AsyncOpConversionPattern;
759 matchAndRewrite(RuntimeAwaitAndResumeOp op, OpAdaptor adaptor,
761 StringRef apiFuncName =
767 Value operand = adaptor.getOperand();
768 Value handle = adaptor.getHandle();
772 auto resumePtr = rewriter.
create<LLVM::AddressOfOp>(
773 op->getLoc(), AsyncAPI::opaquePointerType(rewriter.
getContext()),
776 rewriter.
create<func::CallOp>(
778 ValueRange({operand, handle, resumePtr.getRes()}));
791 class RuntimeResumeOpLowering
792 :
public AsyncOpConversionPattern<RuntimeResumeOp> {
794 using AsyncOpConversionPattern::AsyncOpConversionPattern;
797 matchAndRewrite(RuntimeResumeOp op, OpAdaptor adaptor,
801 auto resumePtr = rewriter.
create<LLVM::AddressOfOp>(
802 op->getLoc(), AsyncAPI::opaquePointerType(rewriter.
getContext()),
806 auto coroHdl = adaptor.getHandle();
825 matchAndRewrite(RuntimeStoreOp op, OpAdaptor adaptor,
830 auto ptrType = AsyncAPI::opaquePointerType(rewriter.
getContext());
831 auto storage = adaptor.getStorage();
832 auto storagePtr = rewriter.
create<func::CallOp>(
836 auto valueType = op.getValue().getType();
837 auto llvmValueType = getTypeConverter()->convertType(valueType);
840 op,
"failed to convert stored value type to LLVM type");
842 Value castedStoragePtr = storagePtr.getResult(0);
844 auto value = adaptor.getValue();
845 rewriter.
create<LLVM::StoreOp>(loc, value, castedStoragePtr);
865 matchAndRewrite(RuntimeLoadOp op, OpAdaptor adaptor,
870 auto ptrType = AsyncAPI::opaquePointerType(rewriter.
getContext());
871 auto storage = adaptor.getStorage();
872 auto storagePtr = rewriter.
create<func::CallOp>(
877 auto llvmValueType = getTypeConverter()->convertType(valueType);
880 op,
"failed to convert loaded value type to LLVM type");
882 Value castedStoragePtr = storagePtr.getResult(0);
898 class RuntimeAddToGroupOpLowering
904 matchAndRewrite(RuntimeAddToGroupOp op, OpAdaptor adaptor,
907 if (!isa<TokenType>(op.getOperand().getType()))
925 class RuntimeNumWorkerThreadsOpLowering
931 matchAndRewrite(RuntimeNumWorkerThreadsOp op, OpAdaptor adaptor,
949 template <
typename RefCountingOp>
952 explicit RefCountingOpLowering(
const TypeConverter &converter,
955 apiFunctionName(apiFunctionName) {}
958 matchAndRewrite(RefCountingOp op,
typename RefCountingOp::Adaptor adaptor,
960 auto count = rewriter.
create<arith::ConstantOp>(
972 StringRef apiFunctionName;
975 class RuntimeAddRefOpLowering :
public RefCountingOpLowering<RuntimeAddRefOp> {
977 explicit RuntimeAddRefOpLowering(
const TypeConverter &converter,
979 : RefCountingOpLowering(converter, ctx,
kAddRef) {}
982 class RuntimeDropRefOpLowering
983 :
public RefCountingOpLowering<RuntimeDropRefOp> {
985 explicit RuntimeDropRefOpLowering(
const TypeConverter &converter,
987 : RefCountingOpLowering(converter, ctx,
kDropRef) {}
1001 matchAndRewrite(func::ReturnOp op, OpAdaptor adaptor,
1012 struct ConvertAsyncToLLVMPass
1013 :
public impl::ConvertAsyncToLLVMPassBase<ConvertAsyncToLLVMPass> {
1016 void runOnOperation()
override;
1020 void ConvertAsyncToLLVMPass::runOnOperation() {
1021 ModuleOp module = getOperation();
1035 AsyncRuntimeTypeConverter converter(
options);
1041 llvmConverter.addConversion([&](
Type type) {
1042 return AsyncRuntimeTypeConverter::convertAsyncTypes(type);
1046 populateFunctionOpInterfaceTypeConversionPattern<func::FuncOp>(
patterns,
1051 patterns.add<ReturnOpOpConversion>(converter, ctx);
1054 patterns.add<RuntimeSetAvailableOpLowering, RuntimeSetErrorOpLowering,
1055 RuntimeIsErrorOpLowering, RuntimeAwaitOpLowering,
1056 RuntimeAwaitAndResumeOpLowering, RuntimeResumeOpLowering,
1057 RuntimeAddToGroupOpLowering, RuntimeNumWorkerThreadsOpLowering,
1058 RuntimeAddRefOpLowering, RuntimeDropRefOpLowering>(converter,
1063 patterns.add<RuntimeCreateOpLowering, RuntimeCreateGroupOpLowering,
1064 RuntimeStoreOpLowering, RuntimeLoadOpLowering>(llvmConverter);
1068 .add<CoroIdOpConversion, CoroBeginOpConversion, CoroFreeOpConversion,
1069 CoroEndOpConversion, CoroSaveOpConversion, CoroSuspendOpConversion>(
1073 target.addLegalOp<arith::ConstantOp, func::ConstantOp,
1074 UnrealizedConversionCastOp>();
1075 target.addLegalDialect<LLVM::LLVMDialect>();
1079 target.addIllegalDialect<AsyncDialect>();
1082 target.addDynamicallyLegalOp<func::FuncOp>([&](func::FuncOp op) {
1083 return converter.isSignatureLegal(op.getFunctionType());
1085 target.addDynamicallyLegalOp<func::ReturnOp>([&](func::ReturnOp op) {
1086 return converter.isLegal(op.getOperandTypes());
1088 target.addDynamicallyLegalOp<func::CallOp>([&](func::CallOp op) {
1089 return converter.isSignatureLegal(op.getCalleeType());
1093 signalPassFailure();
1105 matchAndRewrite(ExecuteOp op, OpAdaptor adaptor,
1110 newOp.getRegion().end());
1113 newOp->setOperands(adaptor.getOperands());
1116 for (
auto result : newOp.getResults())
1117 result.setType(typeConverter->convertType(result.getType()));
1119 rewriter.
replaceOp(op, newOp.getResults());
1129 matchAndRewrite(AwaitOp op, OpAdaptor adaptor,
1141 matchAndRewrite(async::YieldOp op, OpAdaptor adaptor,
1152 typeConverter.
addConversion([&](TokenType type) {
return type; });
1158 patterns.add<ConvertExecuteOpTypes, ConvertAwaitOpTypes, ConvertYieldOpTypes>(
1159 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 * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
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.
Value getOperand(unsigned idx)
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
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...
Type getType() const
Return the type of this value.
Location getLoc() const
Return the location of this value.
LLVM::LLVMFuncOp lookupOrCreateFreeFn(Operation *moduleOp)
LLVM::LLVMFuncOp lookupOrCreateAlignedAllocFn(Operation *moduleOp, Type indexType)
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.