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"
166struct ConvertOpenMPToLLVMPass
167 :
public impl::ConvertOpenMPToLLVMPassBase<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>();
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.
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...
const FrozenRewritePatternSet & patterns
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.