29 #define GEN_PASS_DEF_CONVERTCONTROLFLOWTOLLVMPASS
30 #include "mlir/Conversion/Passes.h.inc"
35 #define PASS_NAME "convert-cf-to-llvm"
44 bool abortOnFailedAssert =
true,
47 abortOnFailedAssert(abortOnFailedAssert), symbolTables(symbolTables) {}
50 matchAndRewrite(cf::AssertOp op, OpAdaptor adaptor,
52 auto loc = op.getLoc();
53 auto module = op->getParentOfType<ModuleOp>();
63 rewriter, loc, module,
"assert_msg", op.getMsg(), *getTypeConverter(),
65 "puts", symbolTables);
66 if (createResult.failed())
69 if (abortOnFailedAssert) {
71 auto abortFunc = module.lookupSymbol<LLVM::LLVMFuncOp>(
"abort");
76 abortFunc = LLVM::LLVMFuncOp::create(rewriter, rewriter.
getUnknownLoc(),
77 "abort", abortFuncTy);
79 LLVM::CallOp::create(rewriter, loc, abortFunc,
ValueRange());
80 LLVM::UnreachableOp::create(rewriter, loc);
82 LLVM::BrOp::create(rewriter, loc,
ValueRange(), continuationBlock);
88 op, adaptor.getArg(), continuationBlock, failureBlock);
96 bool abortOnFailedAssert =
true;
108 assert(converter &&
"expected non-null type converter");
109 assert(!block->
isEntryBlock() &&
"entry blocks have no predecessors");
116 std::optional<TypeConverter::SignatureConversion> conversion =
120 "could not compute block signature");
121 if (expectedTypes != conversion->getConvertedTypes())
124 "mismatch between adaptor operand types and computed block signature");
132 llvm::append_range(result, vals);
144 matchAndRewrite(cf::BranchOp op, Adaptor adaptor,
147 FailureOr<Block *> convertedBlock =
148 getConvertedBlock(rewriter, getTypeConverter(), op, op.getSuccessor(),
150 if (
failed(convertedBlock))
152 DictionaryAttr attrs = op->getAttrDictionary();
154 op, flattenedAdaptor, *convertedBlock);
170 matchAndRewrite(cf::CondBranchOp op, Adaptor adaptor,
176 if (!llvm::hasSingleElement(adaptor.getCondition()))
178 "expected single element condition");
179 FailureOr<Block *> convertedTrueBlock =
180 getConvertedBlock(rewriter, getTypeConverter(), op, op.getTrueDest(),
182 if (
failed(convertedTrueBlock))
184 FailureOr<Block *> convertedFalseBlock =
185 getConvertedBlock(rewriter, getTypeConverter(), op, op.getFalseDest(),
187 if (
failed(convertedFalseBlock))
189 DictionaryAttr attrs = op->getDiscardableAttrDictionary();
191 op, llvm::getSingleElement(adaptor.getCondition()),
192 flattenedAdaptorTrue, flattenedAdaptorFalse, op.getBranchWeightsAttr(),
193 *convertedTrueBlock, *convertedFalseBlock);
196 newOp->setDiscardableAttrs(attrs);
207 matchAndRewrite(cf::SwitchOp op,
typename cf::SwitchOp::Adaptor adaptor,
210 FailureOr<Block *> convertedDefaultBlock = getConvertedBlock(
211 rewriter, getTypeConverter(), op, op.getDefaultDestination(),
212 TypeRange(adaptor.getDefaultOperands()));
213 if (
failed(convertedDefaultBlock))
220 Block *b = it.value();
221 FailureOr<Block *> convertedBlock =
222 getConvertedBlock(rewriter, getTypeConverter(), op, b,
224 if (
failed(convertedBlock))
226 caseDestinations.push_back(*convertedBlock);
230 op, adaptor.getFlag(), *convertedDefaultBlock,
231 adaptor.getDefaultOperands(), adaptor.getCaseValuesAttr(),
232 caseDestinations, caseOperands);
244 CondBranchOpLowering,
245 SwitchOpLowering>(converter);
261 struct ConvertControlFlowToLLVM
262 :
public impl::ConvertControlFlowToLLVMPassBase<ConvertControlFlowToLLVM> {
267 void runOnOperation()
override {
273 target.markUnknownOpDynamicallyLegal([&](
Operation *op) {
280 options.overrideIndexBitwidth(indexBitwidth);
300 struct ControlFlowToLLVMDialectInterface
303 void loadDependentDialects(
MLIRContext *context)
const final {
304 context->loadDialect<LLVM::LLVMDialect>();
309 void populateConvertToLLVMConversionPatterns(
322 dialect->addInterfaces<ControlFlowToLLVMDialectInterface>();
static MLIRContext * getContext(OpFoldResult val)
static llvm::ManagedStatic< PassManagerOptions > options
Block represents an ordered list of Operations.
ValueTypeRange< BlockArgListType > getArgumentTypes()
Return a range containing the types of the arguments for this block.
bool isEntryBlock()
Return if this block is the entry block in the parent region.
This class implements a pattern rewriter for use with ConversionPatterns.
Block * applySignatureConversion(Block *block, TypeConverter::SignatureConversion &conversion, const TypeConverter *converter=nullptr)
Apply a signature conversion to given block.
This class describes a specific conversion target.
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
typename SourceOp::template GenericAdaptor< ArrayRef< ValueRange > > OneToNOpAdaptor
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.
Options to control the LLVM lowering.
MLIRContext is the top-level object for a collection of MLIR operations.
Dialect * getLoadedDialect(StringRef name)
Get a registered IR dialect with the given namespace.
RAII guard to reset the insertion point of the builder when destroyed.
Block::iterator getInsertionPoint() const
Returns the current insertion point of the builder.
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes={}, ArrayRef< Location > locs={})
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
Block * getInsertionBlock() const
Return the block the current insertion point belongs to.
Operation is the basic unit of execution within MLIR.
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
void setAttrs(DictionaryAttr newAttrs)
Set the attributes from a dictionary on this operation.
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,...
Block * splitBlock(Block *block, Block::iterator before)
Split the operations starting at "before" (inclusive) out of the given block into a new block,...
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 represents a collection of SymbolTables.
std::optional< SignatureConversion > convertBlockSignature(Block *block) const
This function converts the type signature of the given block, by invoking 'convertSignatureArg' for e...
This class provides an abstraction over the various different ranges of value types.
This class provides an abstraction over the different types of ranges over Values.
LogicalResult createPrintStrCall(OpBuilder &builder, Location loc, ModuleOp moduleOp, StringRef symbolName, StringRef string, const LLVMTypeConverter &typeConverter, bool addNewline=true, std::optional< StringRef > runtimeFunctionName={}, SymbolTableCollection *symbolTables=nullptr)
Generate IR that prints the given string to stdout.
void registerConvertControlFlowToLLVMInterface(DialectRegistry ®istry)
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.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
SmallVector< Value > flattenValues(ArrayRef< ValueRange > values)
Flatten a set of ValueRange into a single SmallVector<Value>
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...
const FrozenRewritePatternSet & patterns
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.