27 #define GEN_PASS_DEF_SCFTOEMITC
28 #include "mlir/Conversion/Passes.h.inc"
36 struct SCFToEmitCPass :
public impl::SCFToEmitCBase<SCFToEmitCPass> {
37 void runOnOperation()
override;
45 LogicalResult matchAndRewrite(ForOp forOp,
55 if (!op.getNumResults())
56 return resultVariables;
64 for (
OpResult result : op.getResults()) {
65 Type resultType = result.getType();
68 emitc::VariableOp var =
69 rewriter.
create<emitc::VariableOp>(loc, varType, noInit);
70 resultVariables.push_back(var);
73 return resultVariables;
80 for (
auto [value, var] : llvm::zip(values, variables))
81 rewriter.
create<emitc::AssignOp>(loc, var, value);
86 return llvm::map_to_vector<>(variables, [&](
Value var) {
87 Type type = cast<emitc::LValueType>(var.
getType()).getValueType();
88 return rewriter.
create<emitc::LoadOp>(loc, type, var).getResult();
100 assignValues(operands, resultVariables, rewriter, loc);
102 rewriter.
create<emitc::YieldOp>(loc);
116 lowerYield(resultVariables, rewriter, cast<scf::YieldOp>(terminator));
119 LogicalResult ForLowering::matchAndRewrite(ForOp forOp,
126 createVariablesForResults(forOp, rewriter);
128 assignValues(forOp.getInits(), resultVariables, rewriter, loc);
130 emitc::ForOp loweredFor = rewriter.
create<emitc::ForOp>(
131 loc, forOp.getLowerBound(), forOp.getUpperBound(), forOp.getStep());
133 Block *loweredBody = loweredFor.getBody();
136 rewriter.
eraseOp(loweredBody->getTerminator());
142 loadValues(resultVariables, rewriter, loc);
147 replacingValues.push_back(loweredFor.getInductionVar());
148 replacingValues.append(iterArgsValues.begin(), iterArgsValues.end());
150 rewriter.
mergeBlocks(forOp.getBody(), loweredBody, replacingValues);
151 lowerYield(resultVariables, rewriter,
152 cast<scf::YieldOp>(loweredBody->getTerminator()));
166 LogicalResult matchAndRewrite(IfOp ifOp,
172 LogicalResult IfLowering::matchAndRewrite(IfOp ifOp,
179 createVariablesForResults(ifOp, rewriter);
181 Region &thenRegion = ifOp.getThenRegion();
182 Region &elseRegion = ifOp.getElseRegion();
184 bool hasElseBlock = !elseRegion.
empty();
187 rewriter.
create<emitc::IfOp>(loc, ifOp.getCondition(),
false,
false);
189 Region &loweredThenRegion = loweredIf.getThenRegion();
190 lowerRegion(resultVariables, rewriter, thenRegion, loweredThenRegion);
193 Region &loweredElseRegion = loweredIf.getElseRegion();
194 lowerRegion(resultVariables, rewriter, elseRegion, loweredElseRegion);
209 LogicalResult matchAndRewrite(IndexSwitchOp indexSwitchOp,
216 Location loc = indexSwitchOp.getLoc();
221 createVariablesForResults(indexSwitchOp, rewriter);
223 auto loweredSwitch = rewriter.
create<emitc::SwitchOp>(
224 loc, indexSwitchOp.getArg(), indexSwitchOp.getCases(),
225 indexSwitchOp.getNumCases());
228 for (
auto pair : llvm::zip(indexSwitchOp.getCaseRegions(),
229 loweredSwitch.getCaseRegions())) {
230 lowerRegion(resultVariables, rewriter, std::get<0>(pair),
235 lowerRegion(resultVariables, rewriter, indexSwitchOp.getDefaultRegion(),
236 loweredSwitch.getDefaultRegion());
241 rewriter.
replaceOp(indexSwitchOp, results);
251 void SCFToEmitCPass::runOnOperation() {
257 target.addIllegalOp<scf::ForOp, scf::IfOp, scf::IndexSwitchOp>();
258 target.markUnknownOpDynamicallyLegal([](
Operation *) {
return true; });
static MLIRContext * getContext(OpFoldResult val)
Block represents an ordered list of Operations.
Operation * getTerminator()
Get the terminator operation of this block.
This class describes a specific conversion target.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
RAII guard to reset the insertion point of the builder when destroyed.
InsertPoint saveInsertionPoint() const
Return a saved insertion point.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
void restoreInsertionPoint(InsertPoint ip)
Restore the insert point to a previously saved point.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
void setInsertionPointAfter(Operation *op)
Sets the insertion point to the node after the specified operation, which will cause subsequent inser...
This is a value defined by a result of an operation.
Operation is the basic unit of execution within MLIR.
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
This class contains a list of basic blocks and a link to the parent operation it is attached to.
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
void mergeBlocks(Block *source, Block *dest, ValueRange argValues=std::nullopt)
Inline the operations of block 'source' into the end of block 'dest'.
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
void inlineRegionBefore(Region ®ion, Region &parent, Region::iterator before)
Move the blocks that belong to "region" before the given position in another region "parent".
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
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.
Include the generated interface declarations.
void populateSCFToEmitCConversionPatterns(RewritePatternSet &patterns)
Collect a set of patterns to convert SCF operations to the EmitC dialect.
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.
LogicalResult matchAndRewrite(IndexSwitchOp indexSwitchOp, PatternRewriter &rewriter) const override
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...