clang 23.0.0git
CIRCanonicalize.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements pass that canonicalizes CIR operations, eliminating
10// redundant branches, empty scopes, and other unnecessary operations.
11//
12//===----------------------------------------------------------------------===//
13
14#include "PassDetail.h"
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"
25
26using namespace mlir;
27using namespace cir;
28
29namespace mlir {
30#define GEN_PASS_DEF_CIRCANONICALIZE
31#include "clang/CIR/Dialect/Passes.h.inc"
32} // namespace mlir
33
34namespace {
35
36//===----------------------------------------------------------------------===//
37// CIRCanonicalizePass
38//===----------------------------------------------------------------------===//
39
40struct CIRCanonicalizePass
41 : public impl::CIRCanonicalizeBase<CIRCanonicalizePass> {
42 using CIRCanonicalizeBase::CIRCanonicalizeBase;
43
44 // The same operation rewriting done here could have been performed
45 // by CanonicalizerPass (adding hasCanonicalizer for target Ops and
46 // implementing the same from above in CIRDialects.cpp). However, it's
47 // currently too aggressive for static analysis purposes, since it might
48 // remove things where a diagnostic can be generated.
49 //
50 // FIXME: perhaps we can add one more mode to GreedyRewriteConfig to
51 // disable this behavior.
52 void runOnOperation() override;
53};
54
55void CIRCanonicalizePass::runOnOperation() {
56 RewritePatternSet patterns(&getContext());
57
58 // Collect canonicalization patterns from CIR ops.
59 mlir::Dialect *cir = getContext().getLoadedDialect<cir::CIRDialect>();
60 for (mlir::RegisteredOperationName op :
61 getContext().getRegisteredOperations())
62 if (&op.getDialect() == cir)
63 op.getCanonicalizationPatterns(patterns, &getContext());
64
65 // Collect operations to apply patterns.
66 llvm::SmallVector<Operation *, 16> ops;
67 getOperation()->walk([&](Operation *op) {
70
71 // Many operations are here to perform a manual `fold` in
72 // applyOpPatternsGreedily.
73 if (isa<BrOp, BrCondOp, CastOp, ScopeOp, SwitchOp, SelectOp, UnaryOp,
74 ComplexCreateOp, ComplexImagOp, ComplexRealOp, VecCmpOp,
75 VecCreateOp, VecExtractOp, VecShuffleOp, VecShuffleDynamicOp,
76 VecTernaryOp, BitClrsbOp, BitClzOp, BitCtzOp, BitFfsOp, BitParityOp,
77 BitPopcountOp, BitReverseOp, ByteSwapOp, RotateOp, ConstantOp>(op))
78 ops.push_back(op);
79 });
80
81 // Apply patterns.
82 if (applyOpPatternsGreedily(ops, std::move(patterns)).failed())
83 signalPassFailure();
84}
85
86} // namespace
87
88std::unique_ptr<Pass> mlir::createCIRCanonicalizePass() {
89 return std::make_unique<CIRCanonicalizePass>();
90}
std::unique_ptr< Pass > createCIRCanonicalizePass()