42 #include "llvm/ADT/SmallVector.h"
43 #include "llvm/ADT/TypeSwitch.h"
44 #include "llvm/IR/DerivedTypes.h"
45 #include "llvm/IR/IRBuilder.h"
46 #include "llvm/IR/Type.h"
47 #include "llvm/Support/Casting.h"
48 #include "llvm/Support/CommandLine.h"
49 #include "llvm/Support/FormatVariadic.h"
55 #define GEN_PASS_DEF_CONVERTFUNCTOLLVMPASS
56 #define GEN_PASS_DEF_SETLLVMMODULEDATALAYOUTPASS
57 #include "mlir/Conversion/Passes.h.inc"
62 #define PASS_NAME "convert-func-to-llvm"
82 attr.getName() == LLVM::LLVMDialect::getReadnoneAttrName())
84 result.push_back(attr);
90 FunctionOpInterface funcOp,
91 LLVM::LLVMFuncOp wrapperFuncOp) {
92 auto argAttrs = funcOp.getAllArgAttrs();
93 if (!resultStructType) {
94 if (
auto resAttrs = funcOp.getAllResultAttrs())
95 wrapperFuncOp.setAllResultAttrs(resAttrs);
97 wrapperFuncOp.setAllArgAttrs(argAttrs);
104 argAttributes.append(argAttrs.begin(), argAttrs.end());
105 wrapperFuncOp.setAllArgAttrs(argAttributes);
108 cast<FunctionOpInterface>(wrapperFuncOp.getOperation())
109 .setVisibility(funcOp.getVisibility());
122 FunctionOpInterface funcOp,
123 LLVM::LLVMFuncOp newFuncOp) {
124 auto type = cast<FunctionType>(funcOp.getFunctionType());
125 auto [wrapperFuncType, resultStructType] =
131 auto wrapperFuncOp = rewriter.
create<LLVM::LLVMFuncOp>(
132 loc, llvm::formatv(
"_mlir_ciface_{0}", funcOp.getName()).str(),
133 wrapperFuncType, LLVM::Linkage::External,
false,
134 LLVM::CConv::C,
nullptr, attributes);
141 size_t argOffset = resultStructType ? 1 : 0;
143 Value arg = wrapperFuncOp.getArgument(index + argOffset);
144 if (
auto memrefType = dyn_cast<MemRefType>(argType)) {
150 if (isa<UnrankedMemRefType>(argType)) {
160 auto call = rewriter.
create<LLVM::CallOp>(loc, newFuncOp, args);
162 if (resultStructType) {
163 rewriter.
create<LLVM::StoreOp>(loc, call.getResult(),
164 wrapperFuncOp.getArgument(0));
167 rewriter.
create<LLVM::ReturnOp>(loc, call.getResults());
182 FunctionOpInterface funcOp,
183 LLVM::LLVMFuncOp newFuncOp) {
186 auto [wrapperType, resultStructType] =
188 cast<FunctionType>(funcOp.getFunctionType()));
192 assert(wrapperType &&
"unexpected type conversion failure");
198 auto wrapperFunc = builder.
create<LLVM::LLVMFuncOp>(
199 loc, llvm::formatv(
"_mlir_ciface_{0}", funcOp.getName()).str(),
200 wrapperType, LLVM::Linkage::External,
false,
201 LLVM::CConv::C,
nullptr, attributes);
205 newFuncOp.setLinkage(LLVM::Linkage::Private);
209 FunctionType type = cast<FunctionType>(funcOp.getFunctionType());
211 args.reserve(type.getNumInputs());
212 ValueRange wrapperArgsRange(newFuncOp.getArguments());
214 if (resultStructType) {
216 Type resultType = cast<LLVM::LLVMFunctionType>(wrapperType).getParamType(0);
221 builder.
create<LLVM::AllocaOp>(loc, resultType, resultStructType, one);
222 args.push_back(result);
227 for (
Type input : type.getInputs()) {
230 auto memRefType = dyn_cast<MemRefType>(input);
231 auto unrankedMemRefType = dyn_cast<UnrankedMemRefType>(input);
232 if (memRefType || unrankedMemRefType) {
233 numToDrop = memRefType
239 wrapperArgsRange.take_front(numToDrop))
241 builder, loc, typeConverter, unrankedMemRefType,
242 wrapperArgsRange.take_front(numToDrop));
249 loc, ptrTy, packed.
getType(), one, 0);
250 builder.
create<LLVM::StoreOp>(loc, packed, allocated);
253 arg = wrapperArgsRange[0];
257 wrapperArgsRange = wrapperArgsRange.drop_front(numToDrop);
259 assert(wrapperArgsRange.empty() &&
"did not map some of the arguments");
261 auto call = builder.
create<LLVM::CallOp>(loc, wrapperFunc, args);
263 if (resultStructType) {
265 builder.
create<LLVM::LoadOp>(loc, resultStructType, args.front());
266 builder.
create<LLVM::ReturnOp>(loc, result);
268 builder.
create<LLVM::ReturnOp>(loc, call.getResults());
278 if (funcOp.getBody().empty())
284 Block *entryBlock = &funcOp.getBody().
front();
286 assert(blockArgs.size() == oldArgTypes.size() &&
287 "The number of arguments and types doesn't match");
291 for (
auto it : llvm::zip(blockArgs, oldArgTypes)) {
293 Type argTy = std::get<1>(it);
298 assert(!isa<UnrankedMemRefType>(argTy) &&
299 "Unranked memref is not supported");
300 auto memrefTy = dyn_cast<MemRefType>(argTy);
311 auto placeholder = rewriter.
create<LLVM::UndefOp>(
326 auto funcTy = dyn_cast<FunctionType>(funcOp.getFunctionType());
329 funcOp,
"Only support FunctionOpInterface with FunctionType");
336 funcTy, varargsAttr && varargsAttr.getValue(),
343 LLVM::Linkage linkage = LLVM::Linkage::External;
349 <<
" attribute not of type LLVM::LinkageAttr";
351 funcOp,
"Contains linkage attribute not of type LLVM::LinkageAttr");
353 linkage = attr.getLinkage();
358 auto newFuncOp = rewriter.
create<LLVM::LLVMFuncOp>(
359 funcOp.getLoc(), funcOp.getName(), llvmType, linkage,
360 false, LLVM::CConv::C,
nullptr,
362 cast<FunctionOpInterface>(newFuncOp.getOperation())
363 .setVisibility(funcOp.getVisibility());
366 StringRef readnoneAttrName = LLVM::LLVMDialect::getReadnoneAttrName();
367 if (funcOp->hasAttr(readnoneAttrName)) {
368 auto attr = funcOp->getAttrOfType<UnitAttr>(readnoneAttrName);
370 funcOp->emitError() <<
"Contains " << readnoneAttrName
371 <<
" attribute not of type UnitAttr";
373 funcOp,
"Contains readnone attribute not of type UnitAttr");
377 {LLVM::ModRefInfo::NoModRef, LLVM::ModRefInfo::NoModRef,
378 LLVM::ModRefInfo::NoModRef});
379 newFuncOp.setMemoryAttr(memoryAttr);
384 if (ArrayAttr resAttrDicts = funcOp.getAllResultAttrs()) {
385 assert(!resAttrDicts.empty() &&
"expected array to be non-empty");
386 if (funcOp.getNumResults() == 1)
387 newFuncOp.setAllResultAttrs(resAttrDicts);
389 if (ArrayAttr argAttrDicts = funcOp.getAllArgAttrs()) {
391 cast<LLVM::LLVMFunctionType>(llvmType).getNumParams());
392 for (
unsigned i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
397 auto attrsDict = cast<DictionaryAttr>(argAttrDicts[i]);
398 convertedAttrs.reserve(attrsDict.size());
402 cast<TypeAttr>(attr.getValue()).getValue()));
404 if (attr.getName().getValue() ==
405 LLVM::LLVMDialect::getByValAttrName()) {
407 LLVM::LLVMDialect::getByValAttrName(), convert(attr)));
408 }
else if (attr.getName().getValue() ==
409 LLVM::LLVMDialect::getByRefAttrName()) {
411 LLVM::LLVMDialect::getByRefAttrName(), convert(attr)));
412 }
else if (attr.getName().getValue() ==
413 LLVM::LLVMDialect::getStructRetAttrName()) {
415 LLVM::LLVMDialect::getStructRetAttrName(), convert(attr)));
416 }
else if (attr.getName().getValue() ==
417 LLVM::LLVMDialect::getInAllocaAttrName()) {
419 LLVM::LLVMDialect::getInAllocaAttrName(), convert(attr)));
421 convertedAttrs.push_back(attr);
424 auto mapping = result.getInputMapping(i);
425 assert(mapping &&
"unexpected deletion of function argument");
429 if (mapping->size == 1) {
430 newArgAttrs[mapping->inputNo] =
436 for (
size_t j = 0;
j < mapping->size; ++
j)
437 newArgAttrs[mapping->inputNo +
j] =
440 if (!newArgAttrs.empty())
441 newFuncOp.setAllArgAttrs(rewriter.
getArrayAttr(newArgAttrs));
449 "region types conversion failed");
467 cast<FunctionOpInterface>(funcOp.getOperation()), rewriter,
468 *getTypeConverter());
475 struct FuncOpConversion :
public FuncOpConversionBase {
477 : FuncOpConversionBase(converter) {}
480 matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,
488 if (funcOp->getAttrOfType<UnitAttr>(
489 LLVM::LLVMDialect::getEmitCWrapperAttrName())) {
490 if (newFuncOp->isVarArg())
491 return funcOp->emitError(
"C interface for variadic functions is not "
494 if (newFuncOp->isExternal())
499 *getTypeConverter(), funcOp, *newFuncOp);
503 *getTypeConverter(), *newFuncOp,
504 funcOp.getFunctionType().getInputs());
516 matchAndRewrite(func::ConstantOp op, OpAdaptor adaptor,
523 rewriter.
create<LLVM::AddressOfOp>(op.
getLoc(), type, op.getValue());
525 if (attr.getName().strref() ==
"value")
527 newOp->
setAttr(attr.getName(), attr.getValue());
529 rewriter.
replaceOp(op, newOp->getResults());
536 template <
typename CallOpType>
539 using Super = CallOpInterfaceLowering<CallOpType>;
543 typename CallOpType::Adaptor adaptor,
545 bool useBarePtrCallConv =
false)
const {
547 Type packedResult =
nullptr;
548 unsigned numResults = callOp.getNumResults();
549 auto resultTypes = llvm::to_vector<4>(callOp.getResultTypes());
551 if (numResults != 0) {
552 if (!(packedResult = this->getTypeConverter()->packFunctionResults(
553 resultTypes, useBarePtrCallConv)))
557 if (useBarePtrCallConv) {
558 for (
auto it : callOp->getOperands()) {
559 Type operandType = it.getType();
560 if (isa<UnrankedMemRefType>(operandType)) {
567 auto promoted = this->getTypeConverter()->promoteOperands(
568 callOp.getLoc(), callOp->getOperands(),
569 adaptor.getOperands(), rewriter, useBarePtrCallConv);
570 auto newOp = rewriter.
create<LLVM::CallOp>(
572 promoted, callOp->getAttrs());
575 if (numResults < 2) {
577 results.append(newOp.result_begin(), newOp.result_end());
581 results.reserve(numResults);
582 for (
unsigned i = 0; i < numResults; ++i) {
583 results.push_back(rewriter.
create<LLVM::ExtractValueOp>(
584 callOp.getLoc(), newOp->getResult(0), i));
588 if (useBarePtrCallConv) {
591 assert(results.size() == resultTypes.size() &&
592 "The number of arguments and types doesn't match");
593 this->getTypeConverter()->promoteBarePtrsToDescriptors(
594 rewriter, callOp.getLoc(), resultTypes, results);
595 }
else if (
failed(this->copyUnrankedDescriptors(rewriter, callOp.getLoc(),
596 resultTypes, results,
606 class CallOpLowering :
public CallOpInterfaceLowering<func::CallOp> {
611 : CallOpInterfaceLowering<func::CallOp>(typeConverter, benefit),
612 symbolTable(symbolTable) {}
615 matchAndRewrite(func::CallOp callOp, OpAdaptor adaptor,
617 bool useBarePtrCallConv =
false;
618 if (getTypeConverter()->getOptions().useBarePtrCallConv) {
619 useBarePtrCallConv =
true;
620 }
else if (symbolTable !=
nullptr) {
623 symbolTable->lookup(callOp.getCalleeAttr().getValue());
633 return matchAndRewriteImpl(callOp, adaptor, rewriter, useBarePtrCallConv);
640 struct CallIndirectOpLowering
641 :
public CallOpInterfaceLowering<func::CallIndirectOp> {
645 matchAndRewrite(func::CallIndirectOp callIndirectOp, OpAdaptor adaptor,
647 return matchAndRewriteImpl(callIndirectOp, adaptor, rewriter);
651 struct UnrealizedConversionCastOpLowering
657 matchAndRewrite(UnrealizedConversionCastOp op, OpAdaptor adaptor,
660 if (
succeeded(typeConverter->convertTypes(op.getOutputs().getTypes(),
662 convertedTypes == adaptor.getInputs().getTypes()) {
663 rewriter.
replaceOp(op, adaptor.getInputs());
667 convertedTypes.clear();
668 if (
succeeded(typeConverter->convertTypes(adaptor.getInputs().getTypes(),
670 convertedTypes == op.getOutputs().getType()) {
671 rewriter.
replaceOp(op, adaptor.getInputs());
688 matchAndRewrite(func::ReturnOp op, OpAdaptor adaptor,
695 bool useBarePtrCallConv =
697 if (useBarePtrCallConv) {
700 for (
auto it : llvm::zip(op->
getOperands(), adaptor.getOperands())) {
701 Type oldTy = std::get<0>(it).getType();
702 Value newOperand = std::get<1>(it);
703 if (isa<MemRefType>(oldTy) && getTypeConverter()->canConvertToBarePtr(
704 cast<BaseMemRefType>(oldTy))) {
706 newOperand = memrefDesc.allocatedPtr(rewriter, loc);
707 }
else if (isa<UnrankedMemRefType>(oldTy)) {
712 updatedOperands.push_back(newOperand);
715 updatedOperands = llvm::to_vector<4>(adaptor.getOperands());
722 if (numArguments <= 1) {
730 auto packedType = getTypeConverter()->packFunctionResults(
736 Value packed = rewriter.
create<LLVM::UndefOp>(loc, packedType);
738 packed = rewriter.
create<LLVM::InsertValueOp>(loc, packed, operand, idx);
749 patterns.
add<FuncOpConversion>(converter);
756 patterns.
add<CallIndirectOpLowering>(converter);
757 patterns.
add<CallOpLowering>(converter, symbolTable);
758 patterns.
add<ConstantOpLowering>(converter);
759 patterns.
add<ReturnOpLowering>(converter);
764 struct ConvertFuncToLLVMPass
765 :
public impl::ConvertFuncToLLVMPassBase<ConvertFuncToLLVMPass> {
769 void runOnOperation()
override {
770 ModuleOp m = getOperation();
771 StringRef dataLayout;
772 auto dataLayoutAttr = dyn_cast_or_null<StringAttr>(
773 m->getAttr(LLVM::LLVMDialect::getDataLayoutAttrName()));
775 dataLayout = dataLayoutAttr.getValue();
777 if (
failed(LLVM::LLVMDialect::verifyDataLayoutString(
778 dataLayout, [
this](
const Twine &message) {
779 getOperation().emitError() << message.str();
785 const auto &dataLayoutAnalysis = getAnalysis<DataLayoutAnalysis>();
788 dataLayoutAnalysis.getAtOrAbove(m));
789 options.useBarePtrCallConv = useBarePtrCallConv;
791 options.overrideIndexBitwidth(indexBitwidth);
792 options.dataLayout = llvm::DataLayout(dataLayout);
795 &dataLayoutAnalysis);
797 std::optional<SymbolTable> optSymbolTable = std::nullopt;
799 if (!
options.useBarePtrCallConv) {
800 optSymbolTable.emplace(m);
801 symbolTable = &optSymbolTable.value();
818 struct SetLLVMModuleDataLayoutPass
819 :
public impl::SetLLVMModuleDataLayoutPassBase<
820 SetLLVMModuleDataLayoutPass> {
824 void runOnOperation()
override {
825 if (
failed(LLVM::LLVMDialect::verifyDataLayoutString(
826 this->dataLayout, [
this](
const Twine &message) {
827 getOperation().emitError() << message.str();
832 ModuleOp m = getOperation();
833 m->setAttr(LLVM::LLVMDialect::getDataLayoutAttrName(),
849 void populateConvertToLLVMConversionPatterns(
859 dialect->addInterfaces<FuncToLLVMDialectInterface>();
static void modifyFuncOpToUseBarePtrCallingConv(ConversionPatternRewriter &rewriter, Location loc, const LLVMTypeConverter &typeConverter, LLVM::LLVMFuncOp funcOp, TypeRange oldArgTypes)
Modifies the body of the function to construct the MemRefDescriptor from the bare pointer calling con...
static void propagateArgResAttrs(OpBuilder &builder, bool resultStructType, FunctionOpInterface funcOp, LLVM::LLVMFuncOp wrapperFuncOp)
Propagate argument/results attributes.
static constexpr StringRef barePtrAttrName
static constexpr StringRef varargsAttrName
static constexpr StringRef linkageAttrName
static void filterFuncAttributes(FunctionOpInterface func, SmallVectorImpl< NamedAttribute > &result)
Only retain those attributes that are not constructed by LLVMFuncOp::build.
static bool shouldUseBarePtrCallConv(Operation *op, const LLVMTypeConverter *typeConverter)
Return true if the op should use bare pointer calling convention.
static void wrapExternalFunction(OpBuilder &builder, Location loc, const LLVMTypeConverter &typeConverter, FunctionOpInterface funcOp, LLVM::LLVMFuncOp newFuncOp)
Creates an auxiliary function with pointer-to-memref-descriptor-struct arguments instead of unpacked ...
static void wrapForExternalCallers(OpBuilder &rewriter, Location loc, const LLVMTypeConverter &typeConverter, FunctionOpInterface funcOp, LLVM::LLVMFuncOp newFuncOp)
Creates an auxiliary function with pointer-to-memref-descriptor-struct arguments instead of unpacked ...
static MLIRContext * getContext(OpFoldResult val)
static llvm::ManagedStatic< PassManagerOptions > options
This class represents an argument of a Block.
Block represents an ordered list of Operations.
BlockArgListType getArguments()
Special case of IntegerAttr to represent boolean integers, i.e., signless i1 integers.
IntegerAttr getIntegerAttr(Type type, int64_t value)
MLIRContext * getContext() const
ArrayAttr getArrayAttr(ArrayRef< Attribute > value)
DictionaryAttr getDictionaryAttr(ArrayRef< NamedAttribute > value)
NamedAttribute getNamedAttr(StringRef name, Attribute val)
This class implements a pattern rewriter for use with ConversionPatterns.
void replaceOp(Operation *op, ValueRange newValues) override
PatternRewriter hook for replacing an operation.
FailureOr< Block * > convertRegionTypes(Region *region, const TypeConverter &converter, TypeConverter::SignatureConversion *entryConversion=nullptr)
Convert the types of block arguments within the given region.
void eraseOp(Operation *op) override
PatternRewriter hook for erasing a dead operation.
void replaceUsesOfBlockArgument(BlockArgument from, Value to)
Replace all the uses of the block argument from with value to.
This class describes a specific conversion target.
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
Base class for dialect interfaces providing translation to LLVM IR.
ConvertToLLVMPatternInterface(Dialect *dialect)
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
void addExtension(std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
This class provides support for representing a failure result, or a valid value of type T.
Derived class that automatically populates legalization information for different LLVM ops.
Conversion from types to the LLVM IR dialect.
const LowerToLLVMOptions & getOptions() const
Type convertFunctionSignature(FunctionType funcTy, bool isVariadic, bool useBarePtrCallConv, SignatureConversion &result) const
Convert a function type.
LogicalResult convertType(Type t, SmallVectorImpl< Type > &results) const
Convert the given type.
std::pair< LLVM::LLVMFunctionType, LLVM::LLVMStructType > convertFunctionTypeCWrapper(FunctionType type) const
Converts the function type to a C-compatible format, in particular using pointers to memref descripto...
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.
Helper class to produce LLVM dialect operations extracting or inserting elements of a MemRef descript...
static Value pack(OpBuilder &builder, Location loc, const LLVMTypeConverter &converter, MemRefType type, ValueRange values)
Builds IR populating a MemRef descriptor structure from a list of individual values composing that de...
static unsigned getNumUnpackedValues(MemRefType type)
Returns the number of non-aggregate values that would be produced by unpack.
static void unpack(OpBuilder &builder, Location loc, Value packed, MemRefType type, SmallVectorImpl< Value > &results)
Builds IR extracting individual elements of a MemRef descriptor structure and returning them as resul...
static MemRefDescriptor fromStaticShape(OpBuilder &builder, Location loc, const LLVMTypeConverter &typeConverter, MemRefType type, Value memory)
Builds IR creating a MemRef descriptor that represents type and populates it with static shape and st...
NamedAttribute represents a combination of a name and an Attribute value.
RAII guard to reset the insertion point of the builder when destroyed.
This class helps build Operations.
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
type_range getTypes() const
Operation is the basic unit of execution within MLIR.
bool hasAttr(StringAttr name)
Return true if the operation has an attribute with the provided name, false otherwise.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Location getLoc()
The source location the operation was defined or derived from.
unsigned getNumOperands()
ArrayRef< NamedAttribute > getAttrs()
Return all of the attributes on this operation.
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
operand_type_range getOperandTypes()
operand_range getOperands()
Returns an iterator on the underlying Value's.
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
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...
This class allows for representing and managing the symbol table used by operations with the 'SymbolT...
static Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
This class provides all of the information necessary to convert a type signature.
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...
static Value pack(OpBuilder &builder, Location loc, const LLVMTypeConverter &converter, UnrankedMemRefType type, ValueRange values)
Builds IR populating an unranked MemRef descriptor structure from a list of individual constituent va...
static void unpack(OpBuilder &builder, Location loc, Value packed, SmallVectorImpl< Value > &results)
Builds IR extracting individual elements that compose an unranked memref descriptor and returns them ...
static unsigned getNumUnpackedValues()
Returns the number of non-aggregate values that would be produced by unpack.
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.
bool isCompatibleType(Type type)
Returns true if the given type is compatible with the LLVM dialect.
void populateArithToLLVMConversionPatterns(LLVMTypeConverter &converter, RewritePatternSet &patterns)
void populateControlFlowToLLVMConversionPatterns(LLVMTypeConverter &converter, RewritePatternSet &patterns)
Collect the patterns to convert from the ControlFlow dialect to LLVM.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
void populateFuncToLLVMConversionPatterns(LLVMTypeConverter &converter, RewritePatternSet &patterns, const SymbolTable *symbolTable=nullptr)
Collect the patterns to convert from the Func dialect to LLVM.
static constexpr unsigned kDeriveIndexBitwidthFromDataLayout
Value to pass as bitwidth for the index type when the converter is expected to derive the bitwidth fr...
void registerConvertFuncToLLVMInterface(DialectRegistry ®istry)
bool succeeded(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a success value.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
FailureOr< LLVM::LLVMFuncOp > convertFuncOpToLLVMFuncOp(FunctionOpInterface funcOp, ConversionPatternRewriter &rewriter, const LLVMTypeConverter &converter)
Convert input FunctionOpInterface operation to LLVMFuncOp by using the provided LLVMTypeConverter.
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.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
void populateFuncToLLVMFuncOpConversionPattern(LLVMTypeConverter &converter, RewritePatternSet &patterns)
Collect the default pattern to convert a FuncOp to the LLVM dialect.
This class represents an efficient way to signal success or failure.
Eliminates variable at the specified position using Fourier-Motzkin variable elimination.