23#define GEN_PASS_DEF_CONVERTOPENMPTOLLVMPASS
24#include "mlir/Conversion/Passes.h.inc"
42 using ConvertOpToLLVMPattern<T>::ConvertOpToLLVMPattern;
44 OpenMPOpConversion(LLVMTypeConverter &typeConverter,
45 PatternBenefit benefit = 1)
46 : ConvertOpToLLVMPattern<T>(typeConverter, benefit) {
50 typeConverter.addConversion(
51 [&](::mlir::omp::CanonicalLoopInfoType type) {
return type; });
55 matchAndRewrite(T op,
typename T::Adaptor adaptor,
56 ConversionPatternRewriter &rewriter)
const override {
59 SmallVector<Type> resTypes;
60 if (
failed(converter->convertTypes(op->getResultTypes(), resTypes)))
65 SmallVector<NamedAttribute> convertedAttrs;
66 for (NamedAttribute attr : op->getAttrs()) {
67 if (
auto typeAttr = dyn_cast<TypeAttr>(attr.getValue())) {
68 Type convertedType = converter->convertType(typeAttr.getValue());
70 return rewriter.notifyMatchFailure(
71 op,
"failed to convert type in attribute");
72 convertedAttrs.emplace_back(attr.getName(),
73 TypeAttr::get(convertedType));
75 convertedAttrs.push_back(attr);
80 SmallVector<Value> convertedOperands;
81 convertedOperands.reserve(op->getNumOperands());
82 for (
auto [originalOperand, convertedOperand] :
83 llvm::zip_equal(op->getOperands(), adaptor.getOperands())) {
89 if constexpr (llvm::is_one_of<T, omp::AtomicUpdateOp, omp::AtomicWriteOp,
90 omp::FlushOp, omp::MapBoundsOp,
91 omp::ThreadprivateOp>::value) {
92 if (isa<MemRefType>(originalOperand.getType())) {
94 return rewriter.notifyMatchFailure(op,
"memref is not supported yet");
97 convertedOperands.push_back(convertedOperand);
101 auto newOp = T::create(rewriter, op.getLoc(), resTypes, convertedOperands,
105 for (
auto [originalRegion, convertedRegion] :
106 llvm::zip_equal(op->getRegions(), newOp->getRegions())) {
107 rewriter.inlineRegionBefore(originalRegion, convertedRegion,
108 convertedRegion.end());
109 if (
failed(rewriter.convertRegionTypes(&convertedRegion,
110 *this->getTypeConverter())))
115 rewriter.replaceOp(op, newOp->getResults());
124 target.addDynamicallyLegalOp<
126#include "mlir/Dialect/OpenMP/OpenMPOps.cpp.inc"
128 return typeConverter.isLegal(op->getOperandTypes()) &&
129 typeConverter.isLegal(op->getResultTypes()) &&
130 llvm::all_of(op->getRegions(),
132 return typeConverter.isLegal(®ion);
135 auto typeAttr = dyn_cast<TypeAttr>(attr.getValue());
136 return !typeAttr || typeConverter.isLegal(typeAttr.getValue());
143template <
typename... Ts>
147 return patterns.
add<OpenMPOpConversion<Ts>...>(converter);
155 converter.addConversion(
156 [&](omp::MapBoundsType type) ->
Type {
return type; });
161#include "mlir/Dialect/OpenMP/OpenMPOps.cpp.inc"
162 >(converter, patterns);
166struct ConvertOpenMPToLLVMPass
170 void runOnOperation()
override;
174void ConvertOpenMPToLLVMPass::runOnOperation() {
175 auto module = getOperation();
180 arith::populateArithToLLVMConversionPatterns(converter, patterns);
188 target.addLegalOp<omp::BarrierOp, omp::FlushOp, omp::TaskwaitOp,
189 omp::TaskyieldOp, omp::TerminatorOp>();
191 if (
failed(applyPartialConversion(module,
target, std::move(patterns))))
200struct OpenMPToLLVMDialectInterface :
public ConvertToLLVMPatternInterface {
202 void loadDependentDialects(MLIRContext *context)
const final {
203 context->loadDialect<LLVM::LLVMDialect>();
208 void populateConvertToLLVMConversionPatterns(
209 ConversionTarget &
target, LLVMTypeConverter &typeConverter,
210 RewritePatternSet &patterns)
const final {
219 dialect->addInterfaces<OpenMPToLLVMDialectInterface>();
static RewritePatternSet & addOpenMPOpConversions(LLVMTypeConverter &converter, RewritePatternSet &patterns)
Add an OpenMPOpConversion<T> conversion pattern for each operation type passed as template argument.
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
ConvertToLLVMPatternInterface(Dialect *dialect)
const LLVMTypeConverter * getTypeConverter() const
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
Conversion from types to the LLVM IR dialect.
MLIRContext is the top-level object for a collection of MLIR operations.
NamedAttribute represents a combination of a name and an Attribute value.
Operation is the basic unit of execution within MLIR.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
void populateControlFlowToLLVMConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns)
Collect the patterns to convert from the ControlFlow dialect to LLVM.
void populateAssertToLLVMConversionPattern(const LLVMTypeConverter &converter, RewritePatternSet &patterns, bool abortOnFailure=true, SymbolTableCollection *symbolTables=nullptr)
Populate the cf.assert to LLVM conversion pattern.
Include the generated interface declarations.
void populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter, RewritePatternSet &patterns)
Populate the given list with patterns that convert from OpenMP to LLVM.
void populateFuncToLLVMConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns, SymbolTableCollection *symbolTables=nullptr)
Collect the patterns to convert from the Func dialect to LLVM.
void populateFinalizeMemRefToLLVMConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns, SymbolTableCollection *symbolTables=nullptr)
Collect a set of patterns to convert memory-related operations from the MemRef dialect to the LLVM di...
void registerConvertOpenMPToLLVMInterface(DialectRegistry ®istry)
Registers the ConvertToLLVMPatternInterface interface in the OpenMP dialect.
void configureOpenMPToLLVMConversionLegality(ConversionTarget &target, const LLVMTypeConverter &typeConverter)
Configure dynamic conversion legality of regionless operations from OpenMP to LLVM.