40 #include "llvm/ADT/SmallVector.h"
41 #include "llvm/ADT/TypeSwitch.h"
42 #include "llvm/IR/DerivedTypes.h"
43 #include "llvm/IR/IRBuilder.h"
44 #include "llvm/IR/Type.h"
45 #include "llvm/Support/Casting.h"
46 #include "llvm/Support/CommandLine.h"
47 #include "llvm/Support/FormatVariadic.h"
53 #define GEN_PASS_DEF_CONVERTFUNCTOLLVMPASS
54 #define GEN_PASS_DEF_SETLLVMMODULEDATALAYOUTPASS
55 #include "mlir/Conversion/Passes.h.inc"
60 #define PASS_NAME "convert-func-to-llvm"
80 attr.getName() == LLVM::LLVMDialect::getReadnoneAttrName())
82 result.push_back(attr);
88 FunctionOpInterface funcOp,
89 LLVM::LLVMFuncOp wrapperFuncOp) {
90 auto argAttrs = funcOp.getAllArgAttrs();
91 if (!resultStructType) {
92 if (
auto resAttrs = funcOp.getAllResultAttrs())
93 wrapperFuncOp.setAllResultAttrs(resAttrs);
95 wrapperFuncOp.setAllArgAttrs(argAttrs);
102 argAttributes.append(argAttrs.begin(), argAttrs.end());
103 wrapperFuncOp.setAllArgAttrs(argAttributes);
106 cast<FunctionOpInterface>(wrapperFuncOp.getOperation())
107 .setVisibility(funcOp.getVisibility());
120 FunctionOpInterface funcOp,
121 LLVM::LLVMFuncOp newFuncOp) {
122 auto type = cast<FunctionType>(funcOp.getFunctionType());
123 auto [wrapperFuncType, resultStructType] =
129 auto wrapperFuncOp = rewriter.
create<LLVM::LLVMFuncOp>(
130 loc, llvm::formatv(
"_mlir_ciface_{0}", funcOp.getName()).str(),
131 wrapperFuncType, LLVM::Linkage::External,
false,
132 LLVM::CConv::C,
nullptr, attributes);
139 size_t argOffset = resultStructType ? 1 : 0;
141 Value arg = wrapperFuncOp.getArgument(index + argOffset);
142 if (
auto memrefType = dyn_cast<MemRefType>(argType)) {
148 if (isa<UnrankedMemRefType>(argType)) {
158 auto call = rewriter.
create<LLVM::CallOp>(loc, newFuncOp, args);
160 if (resultStructType) {
161 rewriter.
create<LLVM::StoreOp>(loc, call.getResult(),
162 wrapperFuncOp.getArgument(0));
165 rewriter.
create<LLVM::ReturnOp>(loc, call.getResults());
180 FunctionOpInterface funcOp,
181 LLVM::LLVMFuncOp newFuncOp) {
184 auto [wrapperType, resultStructType] =
186 cast<FunctionType>(funcOp.getFunctionType()));
190 assert(wrapperType &&
"unexpected type conversion failure");
196 auto wrapperFunc = builder.
create<LLVM::LLVMFuncOp>(
197 loc, llvm::formatv(
"_mlir_ciface_{0}", funcOp.getName()).str(),
198 wrapperType, LLVM::Linkage::External,
false,
199 LLVM::CConv::C,
nullptr, attributes);
203 newFuncOp.setLinkage(LLVM::Linkage::Private);
207 FunctionType type = cast<FunctionType>(funcOp.getFunctionType());
209 args.reserve(type.getNumInputs());
210 ValueRange wrapperArgsRange(newFuncOp.getArguments());
212 if (resultStructType) {
214 Type resultType = cast<LLVM::LLVMFunctionType>(wrapperType).getParamType(0);
219 builder.
create<LLVM::AllocaOp>(loc, resultType, resultStructType, one);
220 args.push_back(result);
225 for (
Type input : type.getInputs()) {
228 auto memRefType = dyn_cast<MemRefType>(input);
229 auto unrankedMemRefType = dyn_cast<UnrankedMemRefType>(input);
230 if (memRefType || unrankedMemRefType) {
231 numToDrop = memRefType
237 wrapperArgsRange.take_front(numToDrop))
239 builder, loc, typeConverter, unrankedMemRefType,
240 wrapperArgsRange.take_front(numToDrop));
247 loc, ptrTy, packed.
getType(), one, 0);
248 builder.
create<LLVM::StoreOp>(loc, packed, allocated);
251 arg = wrapperArgsRange[0];
255 wrapperArgsRange = wrapperArgsRange.drop_front(numToDrop);
257 assert(wrapperArgsRange.empty() &&
"did not map some of the arguments");
259 auto call = builder.
create<LLVM::CallOp>(loc, wrapperFunc, args);
261 if (resultStructType) {
263 builder.
create<LLVM::LoadOp>(loc, resultStructType, args.front());
264 builder.
create<LLVM::ReturnOp>(loc, result);
266 builder.
create<LLVM::ReturnOp>(loc, call.getResults());
275 ArrayRef<std::optional<NamedAttribute>> byValRefNonPtrAttrs,
278 if (funcOp.isExternal())
281 ConversionPatternRewriter::InsertionGuard guard(rewriter);
284 for (
const auto &[arg, oldArg, byValRefAttr] :
285 llvm::zip(funcOp.getArguments(), oldBlockArgs, byValRefNonPtrAttrs)) {
291 assert(isa<LLVM::LLVMPointerType>(arg.getType()) &&
292 "Expected LLVM pointer type for argument with "
293 "`llvm.byval`/`llvm.byref` attribute");
295 cast<TypeAttr>(byValRefAttr->getValue()).getValue());
297 auto valueArg = rewriter.
create<LLVM::LoadOp>(arg.getLoc(), resTy, arg);
302 FailureOr<LLVM::LLVMFuncOp>
307 auto funcTy = dyn_cast<FunctionType>(funcOp.getFunctionType());
310 funcOp,
"Only support FunctionOpInterface with FunctionType");
314 llvm::to_vector(funcOp.getArguments());
323 auto llvmType = dyn_cast_or_null<LLVM::LLVMFunctionType>(
325 funcOp, varargsAttr && varargsAttr.getValue(),
327 byValRefNonPtrAttrs));
333 if (funcOp->getAttrOfType<UnitAttr>(
334 LLVM::LLVMDialect::getEmitCWrapperAttrName()))
335 if (llvmType.isVarArg())
336 return funcOp.emitError(
"C interface for variadic functions is not "
341 LLVM::Linkage linkage = LLVM::Linkage::External;
347 <<
" attribute not of type LLVM::LinkageAttr";
349 funcOp,
"Contains linkage attribute not of type LLVM::LinkageAttr");
351 linkage = attr.getLinkage();
355 StringRef readnoneAttrName = LLVM::LLVMDialect::getReadnoneAttrName();
356 if (funcOp->hasAttr(readnoneAttrName)) {
357 auto attr = funcOp->getAttrOfType<UnitAttr>(readnoneAttrName);
359 funcOp->emitError() <<
"Contains " << readnoneAttrName
360 <<
" attribute not of type UnitAttr";
362 funcOp,
"Contains readnone attribute not of type UnitAttr");
368 auto newFuncOp = rewriter.
create<LLVM::LLVMFuncOp>(
369 funcOp.getLoc(), funcOp.getName(), llvmType, linkage,
370 false, LLVM::CConv::C,
nullptr,
372 cast<FunctionOpInterface>(newFuncOp.getOperation())
373 .setVisibility(funcOp.getVisibility());
376 if (funcOp->hasAttr(readnoneAttrName)) {
379 {LLVM::ModRefInfo::NoModRef, LLVM::ModRefInfo::NoModRef,
380 LLVM::ModRefInfo::NoModRef});
381 newFuncOp.setMemoryEffectsAttr(memoryAttr);
386 if (ArrayAttr resAttrDicts = funcOp.getAllResultAttrs()) {
387 assert(!resAttrDicts.empty() &&
"expected array to be non-empty");
388 if (funcOp.getNumResults() == 1)
389 newFuncOp.setAllResultAttrs(resAttrDicts);
391 if (ArrayAttr argAttrDicts = funcOp.getAllArgAttrs()) {
393 cast<LLVM::LLVMFunctionType>(llvmType).getNumParams());
394 for (
unsigned i = 0, e = funcOp.getNumArguments(); i < e; ++i) {
399 auto attrsDict = cast<DictionaryAttr>(argAttrDicts[i]);
400 convertedAttrs.reserve(attrsDict.size());
404 cast<TypeAttr>(attr.getValue()).getValue()));
406 if (attr.getName().getValue() ==
407 LLVM::LLVMDialect::getByValAttrName()) {
409 LLVM::LLVMDialect::getByValAttrName(), convert(attr)));
410 }
else if (attr.getName().getValue() ==
411 LLVM::LLVMDialect::getByRefAttrName()) {
413 LLVM::LLVMDialect::getByRefAttrName(), convert(attr)));
414 }
else if (attr.getName().getValue() ==
415 LLVM::LLVMDialect::getStructRetAttrName()) {
417 LLVM::LLVMDialect::getStructRetAttrName(), convert(attr)));
418 }
else if (attr.getName().getValue() ==
419 LLVM::LLVMDialect::getInAllocaAttrName()) {
421 LLVM::LLVMDialect::getInAllocaAttrName(), convert(attr)));
423 convertedAttrs.push_back(attr);
427 assert(mapping &&
"unexpected deletion of function argument");
431 if (mapping->size == 1) {
432 newArgAttrs[mapping->inputNo] =
438 for (
size_t j = 0;
j < mapping->size; ++
j)
439 newArgAttrs[mapping->inputNo +
j] =
442 if (!newArgAttrs.empty())
443 newFuncOp.setAllArgAttrs(rewriter.
getArrayAttr(newArgAttrs));
450 if (!newFuncOp.getBody().empty())
458 oldBlockArgs, newFuncOp);
461 if (funcOp->getAttrOfType<UnitAttr>(
462 LLVM::LLVMDialect::getEmitCWrapperAttrName())) {
463 if (newFuncOp.isExternal())
485 matchAndRewrite(func::FuncOp funcOp, OpAdaptor adaptor,
488 cast<FunctionOpInterface>(funcOp.getOperation()), rewriter,
489 *getTypeConverter());
490 if (failed(newFuncOp))
502 matchAndRewrite(func::ConstantOp op, OpAdaptor adaptor,
504 auto type = typeConverter->convertType(op.getResult().getType());
509 rewriter.
create<LLVM::AddressOfOp>(op.getLoc(), type, op.getValue());
511 if (attr.getName().strref() ==
"value")
513 newOp->
setAttr(attr.getName(), attr.getValue());
515 rewriter.
replaceOp(op, newOp->getResults());
522 template <
typename CallOpType>
525 using Super = CallOpInterfaceLowering<CallOpType>;
528 LogicalResult matchAndRewriteImpl(CallOpType callOp,
529 typename CallOpType::Adaptor adaptor,
531 bool useBarePtrCallConv =
false)
const {
533 Type packedResult =
nullptr;
534 unsigned numResults = callOp.getNumResults();
535 auto resultTypes = llvm::to_vector<4>(callOp.getResultTypes());
537 if (numResults != 0) {
538 if (!(packedResult = this->getTypeConverter()->packFunctionResults(
539 resultTypes, useBarePtrCallConv)))
543 if (useBarePtrCallConv) {
544 for (
auto it : callOp->getOperands()) {
545 Type operandType = it.getType();
546 if (isa<UnrankedMemRefType>(operandType)) {
553 auto promoted = this->getTypeConverter()->promoteOperands(
554 callOp.getLoc(), callOp->getOperands(),
555 adaptor.getOperands(), rewriter, useBarePtrCallConv);
556 auto newOp = rewriter.
create<LLVM::CallOp>(
558 promoted, callOp->getAttrs());
560 newOp.getProperties().operandSegmentSizes = {
561 static_cast<int32_t
>(promoted.size()), 0};
565 if (numResults < 2) {
567 results.append(newOp.result_begin(), newOp.result_end());
571 results.reserve(numResults);
572 for (
unsigned i = 0; i < numResults; ++i) {
573 results.push_back(rewriter.
create<LLVM::ExtractValueOp>(
574 callOp.getLoc(), newOp->getResult(0), i));
578 if (useBarePtrCallConv) {
581 assert(results.size() == resultTypes.size() &&
582 "The number of arguments and types doesn't match");
583 this->getTypeConverter()->promoteBarePtrsToDescriptors(
584 rewriter, callOp.getLoc(), resultTypes, results);
585 }
else if (failed(this->copyUnrankedDescriptors(rewriter, callOp.getLoc(),
586 resultTypes, results,
596 class CallOpLowering :
public CallOpInterfaceLowering<func::CallOp> {
601 : CallOpInterfaceLowering<func::CallOp>(typeConverter, benefit),
602 symbolTable(symbolTable) {}
605 matchAndRewrite(func::CallOp callOp, OpAdaptor adaptor,
607 bool useBarePtrCallConv =
false;
608 if (getTypeConverter()->getOptions().useBarePtrCallConv) {
609 useBarePtrCallConv =
true;
610 }
else if (symbolTable !=
nullptr) {
613 symbolTable->lookup(callOp.getCalleeAttr().getValue());
623 return matchAndRewriteImpl(callOp, adaptor, rewriter, useBarePtrCallConv);
630 struct CallIndirectOpLowering
631 :
public CallOpInterfaceLowering<func::CallIndirectOp> {
635 matchAndRewrite(func::CallIndirectOp callIndirectOp, OpAdaptor adaptor,
637 return matchAndRewriteImpl(callIndirectOp, adaptor, rewriter);
641 struct UnrealizedConversionCastOpLowering
647 matchAndRewrite(UnrealizedConversionCastOp op, OpAdaptor adaptor,
650 if (succeeded(typeConverter->convertTypes(op.getOutputs().getTypes(),
652 convertedTypes == adaptor.getInputs().getTypes()) {
653 rewriter.
replaceOp(op, adaptor.getInputs());
657 convertedTypes.clear();
658 if (succeeded(typeConverter->convertTypes(adaptor.getInputs().getTypes(),
660 convertedTypes == op.getOutputs().getType()) {
661 rewriter.
replaceOp(op, adaptor.getInputs());
678 matchAndRewrite(func::ReturnOp op, OpAdaptor adaptor,
681 unsigned numArguments = op.getNumOperands();
684 auto funcOp = op->getParentOfType<LLVM::LLVMFuncOp>();
685 bool useBarePtrCallConv =
687 if (useBarePtrCallConv) {
690 for (
auto it : llvm::zip(op->getOperands(), adaptor.getOperands())) {
691 Type oldTy = std::get<0>(it).getType();
692 Value newOperand = std::get<1>(it);
693 if (isa<MemRefType>(oldTy) && getTypeConverter()->canConvertToBarePtr(
694 cast<BaseMemRefType>(oldTy))) {
696 newOperand = memrefDesc.allocatedPtr(rewriter, loc);
697 }
else if (isa<UnrankedMemRefType>(oldTy)) {
702 updatedOperands.push_back(newOperand);
705 updatedOperands = llvm::to_vector<4>(adaptor.getOperands());
706 (void)copyUnrankedDescriptors(rewriter, loc, op.getOperands().getTypes(),
712 if (numArguments <= 1) {
714 op,
TypeRange(), updatedOperands, op->getAttrs());
720 auto packedType = getTypeConverter()->packFunctionResults(
721 op.getOperandTypes(), useBarePtrCallConv);
726 Value packed = rewriter.
create<LLVM::PoisonOp>(loc, packedType);
728 packed = rewriter.
create<LLVM::InsertValueOp>(loc, packed, operand, idx);
739 patterns.add<FuncOpConversion>(converter);
746 patterns.add<CallIndirectOpLowering>(converter);
747 patterns.add<CallOpLowering>(converter, symbolTable);
748 patterns.add<ConstantOpLowering>(converter);
749 patterns.add<ReturnOpLowering>(converter);
754 struct ConvertFuncToLLVMPass
755 :
public impl::ConvertFuncToLLVMPassBase<ConvertFuncToLLVMPass> {
759 void runOnOperation()
override {
760 ModuleOp m = getOperation();
761 StringRef dataLayout;
762 auto dataLayoutAttr = dyn_cast_or_null<StringAttr>(
763 m->getAttr(LLVM::LLVMDialect::getDataLayoutAttrName()));
765 dataLayout = dataLayoutAttr.getValue();
767 if (failed(LLVM::LLVMDialect::verifyDataLayoutString(
768 dataLayout, [
this](
const Twine &message) {
769 getOperation().emitError() << message.str();
775 const auto &dataLayoutAnalysis = getAnalysis<DataLayoutAnalysis>();
778 dataLayoutAnalysis.getAtOrAbove(m));
779 options.useBarePtrCallConv = useBarePtrCallConv;
781 options.overrideIndexBitwidth(indexBitwidth);
782 options.dataLayout = llvm::DataLayout(dataLayout);
785 &dataLayoutAnalysis);
787 std::optional<SymbolTable> optSymbolTable = std::nullopt;
789 if (!
options.useBarePtrCallConv) {
790 optSymbolTable.emplace(m);
791 symbolTable = &optSymbolTable.value();
803 struct SetLLVMModuleDataLayoutPass
804 :
public impl::SetLLVMModuleDataLayoutPassBase<
805 SetLLVMModuleDataLayoutPass> {
809 void runOnOperation()
override {
810 if (failed(LLVM::LLVMDialect::verifyDataLayoutString(
811 this->dataLayout, [
this](
const Twine &message) {
812 getOperation().emitError() << message.str();
817 ModuleOp m = getOperation();
818 m->setAttr(LLVM::LLVMDialect::getDataLayoutAttrName(),
834 void populateConvertToLLVMConversionPatterns(
844 dialect->addInterfaces<FuncToLLVMDialectInterface>();
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 restoreByValRefArgumentType(ConversionPatternRewriter &rewriter, const LLVMTypeConverter &typeConverter, ArrayRef< std::optional< NamedAttribute >> byValRefNonPtrAttrs, ArrayRef< BlockArgument > oldBlockArgs, LLVM::LLVMFuncOp funcOp)
Inserts llvm.load ops in the function body to restore the expected pointee value from llvm....
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
Special case of IntegerAttr to represent boolean integers, i.e., signless i1 integers.
DenseI32ArrayAttr getDenseI32ArrayAttr(ArrayRef< int32_t > values)
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
Replace the given operation with the new values.
Block * applySignatureConversion(Block *block, TypeConverter::SignatureConversion &conversion, const TypeConverter *converter=nullptr)
Apply a signature conversion to given block.
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.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
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 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 unsigned getNumUnpackedValues(MemRefType type)
Returns the number of non-aggregate values that would be produced by unpack.
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...
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.
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.
void setAttr(StringAttr name, Attribute value)
If the an attribute exists with the specified name, change it to the new value.
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
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.
std::optional< InputMapping > getInputMapping(unsigned input) const
Get the input mapping for the given argument.
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.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
static constexpr unsigned kDeriveIndexBitwidthFromDataLayout
Value to pass as bitwidth for the index type when the converter is expected to derive the bitwidth fr...
void populateFuncToLLVMFuncOpConversionPattern(const LLVMTypeConverter &converter, RewritePatternSet &patterns)
Collect the default pattern to convert a FuncOp to the LLVM dialect.
void registerConvertFuncToLLVMInterface(DialectRegistry ®istry)
const FrozenRewritePatternSet & patterns
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...
void populateFuncToLLVMConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns, const SymbolTable *symbolTable=nullptr)
Collect the patterns to convert from the Func dialect to LLVM.
LogicalResult applyPartialConversion(ArrayRef< Operation * > ops, const ConversionTarget &target, const FrozenRewritePatternSet &patterns, ConversionConfig config=ConversionConfig())
Below we define several entry points for operation conversion.
Eliminates variable at the specified position using Fourier-Motzkin variable elimination.