Skip to content

Commit

Permalink
[mlir] StandardToLLVM: make one-to-one convresion pattern publicly av…
Browse files Browse the repository at this point in the history
…ailable

Summary:
The Standard-to-LLVM dialect convresion has a set of utility classes that
simplify conversions, including patterns that provide one-to-one conversion
operation conversion with optional result packing. Expose these classes in a
public header so that conversions other than Standard-to-LLVM (e.g. vectors, or
LLVM-based intrinsics) could also use them. Since the patterns are implemented
as class templates and in order to keep the code size limited, keep the
implementation private by resorting to op identifiers instead of template-based
builders.

Differential Revision: https://reviews.llvm.org/D76864
  • Loading branch information
ftynse committed Mar 26, 2020
1 parent abcb9bb commit 987fbae
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 157 deletions.
Expand Up @@ -90,6 +90,9 @@ class LLVMTypeConverter : public TypeConverter {
/// to each of the MLIR types converted with `convertType`.
Type packFunctionResults(ArrayRef<Type> types);

/// Returns the MLIR context.
MLIRContext &getContext();

/// Returns the LLVM context.
llvm::LLVMContext &getLLVMContext();

Expand Down Expand Up @@ -356,6 +359,7 @@ class UnrankedMemRefDescriptor : public StructBuilder {
/// `unpack`.
static unsigned getNumUnpackedValues() { return 2; }
};

/// Base class for operation conversions targeting the LLVM IR dialect. Provides
/// conversion patterns with access to an LLVMTypeConverter.
class ConvertToLLVMPattern : public ConversionPattern {
Expand All @@ -364,11 +368,79 @@ class ConvertToLLVMPattern : public ConversionPattern {
LLVMTypeConverter &typeConverter,
PatternBenefit benefit = 1);

/// Returns the LLVM dialect.
LLVM::LLVMDialect &getDialect() const;

/// Returns the LLVM IR context.
llvm::LLVMContext &getContext() const;

/// Returns the LLVM IR module associated with the LLVM dialect.
llvm::Module &getModule() const;

/// Gets the MLIR type wrapping the LLVM integer type whose bit width is
/// defined by the pointer size used in the LLVM module.
LLVM::LLVMType getIndexType() const;

/// Gets the MLIR type wrapping the LLVM void type.
LLVM::LLVMType getVoidType() const;

/// Get the MLIR type wrapping the LLVM i8* type.
LLVM::LLVMType getVoidPtrType() const;

/// Create an LLVM dialect operation defining the given index constant.
Value createIndexConstant(ConversionPatternRewriter &builder, Location loc,
uint64_t value) const;

protected:
/// Reference to the type converter, with potential extensions.
LLVMTypeConverter &typeConverter;
};

/// Utility class for operation conversions targeting the LLVM dialect that
/// match exactly one source operation.
template <typename OpTy>
class ConvertOpToLLVMPattern : public ConvertToLLVMPattern {
public:
ConvertOpToLLVMPattern(LLVMTypeConverter &typeConverter,
PatternBenefit benefit = 1)
: ConvertToLLVMPattern(OpTy::getOperationName(),
&typeConverter.getContext(), typeConverter,
benefit) {}
};

namespace LLVM {
namespace detail {
/// Replaces the given operaiton "op" with a new operation of type "targetOp"
/// and given operands.
LogicalResult oneToOneRewrite(Operation *op, StringRef targetOp,
ValueRange operands,
LLVMTypeConverter &typeConverter,
ConversionPatternRewriter &rewriter);
} // namespace detail
} // namespace LLVM

/// Generic implementation of one-to-one conversion from "SourceOp" to
/// "TargetOp" where the latter belongs to the LLVM dialect or an equivalent.
/// Upholds a convention that multi-result operations get converted into an
/// operation returning the LLVM IR structure type, in which case individual
/// values must be extacted from using LLVM::ExtractValueOp before being used.
template <typename SourceOp, typename TargetOp>
class OneToOneConvertToLLVMPattern : public ConvertOpToLLVMPattern<SourceOp> {
public:
using ConvertOpToLLVMPattern<SourceOp>::ConvertOpToLLVMPattern;
using Super = OneToOneConvertToLLVMPattern<SourceOp, TargetOp>;

/// Converts the type of the result to an LLVM type, pass operands as is,
/// preserve attributes.
LogicalResult
matchAndRewrite(Operation *op, ArrayRef<Value> operands,
ConversionPatternRewriter &rewriter) const override {
return LLVM::detail::oneToOneRewrite(op, TargetOp::getOperationName(),
operands, this->typeConverter,
rewriter);
}
};

/// Derived class that automatically populates legalization information for
/// different LLVM ops.
class LLVMConversionTarget : public ConversionTarget {
Expand Down

0 comments on commit 987fbae

Please sign in to comment.