23#define GEN_PASS_DEF_CONVERTOPENMPTOLLVMPASS
24#include "mlir/Conversion/Passes.h.inc"
31static LogicalResult convertTypeAttr(
Attribute &attr,
33 auto typeAttr = dyn_cast<TypeAttr>(attr);
36 Type convertedType = typeConverter.convertType(typeAttr.getValue());
39 attr = TypeAttr::get(convertedType);
43static bool areTypeAttrsLegal(
Operation *op,
45 bool inherentAttrsLegal =
true;
47 if (
auto typeAttr = dyn_cast<TypeAttr>(attr))
48 inherentAttrsLegal &= typeConverter.isLegal(typeAttr.getValue());
50 return inherentAttrsLegal &&
52 auto typeAttr = dyn_cast<TypeAttr>(attr.getValue());
53 return !typeAttr || typeConverter.isLegal(typeAttr.getValue());
68 using ConvertOpToLLVMPattern<T>::ConvertOpToLLVMPattern;
70 OpenMPOpConversion(LLVMTypeConverter &typeConverter,
71 PatternBenefit benefit = 1)
72 : ConvertOpToLLVMPattern<T>(typeConverter, benefit) {
76 typeConverter.addConversion(
77 [&](::mlir::omp::CanonicalLoopInfoType type) {
return type; });
81 matchAndRewrite(T op,
typename T::Adaptor adaptor,
82 ConversionPatternRewriter &rewriter)
const override {
85 SmallVector<Type> resTypes;
86 if (
failed(converter->convertTypes(op->getResultTypes(), resTypes)))
91 typename T::Properties convertedProperties = op.getProperties();
92 LogicalResult attrConversionResult =
success();
94 op.getContext(), convertedProperties, [&](StringRef, Attribute &attr) {
95 if (succeeded(attrConversionResult))
96 attrConversionResult = convertTypeAttr(attr, *converter);
98 if (
failed(attrConversionResult))
99 return rewriter.notifyMatchFailure(op,
100 "failed to convert type in attribute");
102 SmallVector<NamedAttribute> convertedDiscardableAttrs;
103 for (NamedAttribute attr : op->getDiscardableAttrs()) {
104 Attribute convertedAttr = attr.getValue();
105 if (
failed(convertTypeAttr(convertedAttr, *converter)))
106 return rewriter.notifyMatchFailure(
107 op,
"failed to convert type in attribute");
108 convertedDiscardableAttrs.emplace_back(attr.getName(), convertedAttr);
112 SmallVector<Value> convertedOperands;
113 convertedOperands.reserve(op->getNumOperands());
114 for (
auto [originalOperand, convertedOperand] :
115 llvm::zip_equal(op->getOperands(), adaptor.getOperands())) {
116 if (!originalOperand)
121 if constexpr (llvm::is_one_of<T, omp::AtomicUpdateOp, omp::AtomicWriteOp,
122 omp::FlushOp, omp::MapBoundsOp,
123 omp::ThreadprivateOp>::value) {
124 if (isa<MemRefType>(originalOperand.getType())) {
126 return rewriter.notifyMatchFailure(op,
"memref is not supported yet");
129 convertedOperands.push_back(convertedOperand);
133 auto newOp = T::create(rewriter, op.getLoc(), resTypes, convertedOperands,
134 convertedProperties, convertedDiscardableAttrs);
137 for (
auto [originalRegion, convertedRegion] :
138 llvm::zip_equal(op->getRegions(), newOp->getRegions())) {
139 rewriter.inlineRegionBefore(originalRegion, convertedRegion,
140 convertedRegion.end());
141 if (
failed(rewriter.convertRegionTypes(&convertedRegion,
142 *this->getTypeConverter())))
147 rewriter.replaceOp(op, newOp->getResults());
156 target.addDynamicallyLegalOp<
158#include "mlir/Dialect/OpenMP/OpenMPOps.cpp.inc"
160 return typeConverter.isLegal(op->getOperandTypes()) &&
161 typeConverter.isLegal(op->getResultTypes()) &&
162 llvm::all_of(op->getRegions(),
164 return typeConverter.isLegal(®ion);
166 areTypeAttrsLegal(op, typeConverter);
172template <
typename... Ts>
176 return patterns.
add<OpenMPOpConversion<Ts>...>(converter);
184 converter.addConversion(
185 [&](omp::MapBoundsType type) ->
Type {
return type; });
186 converter.addConversion(
187 [&](omp::AffinityEntryType type) ->
Type {
return type; });
188 converter.addConversion([&](omp::IteratedType type) ->
Type {
return type; });
193#include "mlir/Dialect/OpenMP/OpenMPOps.cpp.inc"
194 >(converter, patterns);
198struct ConvertOpenMPToLLVMPass
199 :
public impl::ConvertOpenMPToLLVMPassBase<ConvertOpenMPToLLVMPass> {
202 void runOnOperation()
override;
206void ConvertOpenMPToLLVMPass::runOnOperation() {
207 auto module = getOperation();
212 arith::populateArithToLLVMConversionPatterns(converter, patterns);
220 target.addLegalOp<omp::BarrierOp, omp::FlushOp, omp::TaskwaitOp,
221 omp::TaskyieldOp, omp::TerminatorOp>();
223 if (
failed(applyPartialConversion(module,
target, std::move(patterns))))
232struct OpenMPToLLVMDialectInterface :
public ConvertToLLVMPatternInterface {
233 OpenMPToLLVMDialectInterface(Dialect *dialect)
234 : ConvertToLLVMPatternInterface(dialect) {}
236 void loadDependentDialects(MLIRContext *context)
const final {
237 context->loadDialect<LLVM::LLVMDialect>();
242 void populateConvertToLLVMConversionPatterns(
243 ConversionTarget &
target, LLVMTypeConverter &typeConverter,
244 RewritePatternSet &patterns)
const final {
253 dialect->addInterfaces<OpenMPToLLVMDialectInterface>();
static RewritePatternSet & addOpenMPOpConversions(LLVMTypeConverter &converter, RewritePatternSet &patterns)
Add an OpenMPOpConversion<T> conversion pattern for each operation type passed as template argument.
Attributes are known-constant values of operations.
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
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.
void walkInherentAttrs(Operation *op, InherentAttrVisitor visitor) const
Visit the inherent attributes stored in the properties of op.
Operation is the basic unit of execution within MLIR.
auto getDiscardableAttrs()
Return a range of all of discardable attributes on this operation.
OperationName getName()
The name of an operation is the key identifier for it.
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.