15#include "mlir/Dialect/Func/IR/FuncOps.h"
16#include "mlir/IR/Block.h"
17#include "mlir/IR/Operation.h"
18#include "mlir/IR/PatternMatch.h"
19#include "mlir/IR/Region.h"
20#include "mlir/Support/LogicalResult.h"
21#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
30#define GEN_PASS_DEF_CIRCANONICALIZE
31#include "clang/CIR/Dialect/Passes.h.inc"
47struct RemoveRedundantBranches :
public OpRewritePattern<BrOp> {
48 using OpRewritePattern<BrOp>::OpRewritePattern;
50 LogicalResult matchAndRewrite(BrOp op,
51 PatternRewriter &rewriter)
const final {
52 Block *block = op.getOperation()->getBlock();
53 Block *dest = op.getDest();
55 if (isa<cir::LabelOp>(dest->front()))
58 if (block->getNumSuccessors() == 1 &&
59 dest->getSinglePredecessor() == block) {
61 rewriter.mergeBlocks(dest, block);
69struct RemoveEmptyScope :
public OpRewritePattern<ScopeOp> {
70 using OpRewritePattern<ScopeOp>::OpRewritePattern;
72 LogicalResult matchAndRewrite(ScopeOp op,
73 PatternRewriter &rewriter)
const final {
81 Region ®ion = op.getScopeRegion();
82 if (region.getBlocks().front().getOperations().size() == 1 &&
83 isa<YieldOp>(region.getBlocks().front().front())) {
92struct RemoveEmptySwitch :
public OpRewritePattern<SwitchOp> {
93 using OpRewritePattern<SwitchOp>::OpRewritePattern;
95 LogicalResult matchAndRewrite(SwitchOp op,
96 PatternRewriter &rewriter)
const final {
97 if (!(op.getBody().empty() || isa<YieldOp>(op.getBody().front().front())))
100 rewriter.eraseOp(op);
109struct CIRCanonicalizePass
110 :
public impl::CIRCanonicalizeBase<CIRCanonicalizePass> {
111 using CIRCanonicalizeBase::CIRCanonicalizeBase;
121 void runOnOperation()
override;
124void populateCIRCanonicalizePatterns(RewritePatternSet &patterns) {
127 RemoveRedundantBranches,
129 >(patterns.getContext());
133void CIRCanonicalizePass::runOnOperation() {
135 RewritePatternSet patterns(&getContext());
136 populateCIRCanonicalizePatterns(patterns);
139 llvm::SmallVector<Operation *, 16> ops;
140 getOperation()->walk([&](Operation *op) {
147 if (isa<BrOp, BrCondOp, CastOp, ScopeOp, SwitchOp, SelectOp, UnaryOp,
148 ComplexCreateOp, ComplexImagOp, ComplexRealOp, VecCmpOp,
149 VecCreateOp, VecExtractOp, VecShuffleOp, VecShuffleDynamicOp,
150 VecTernaryOp, BitClrsbOp, BitClzOp, BitCtzOp, BitFfsOp, BitParityOp,
151 BitPopcountOp, BitReverseOp, ByteSwapOp, RotateOp>(op))
156 if (applyOpPatternsGreedily(ops, std::move(patterns)).failed())
163 return std::make_unique<CIRCanonicalizePass>();
std::unique_ptr< Pass > createCIRCanonicalizePass()