xref: /llvm-project/mlir/lib/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.cpp (revision a9f62244f28a64e7b7338c2299ba169df70fbb03)
161bc6aa5SAlex Zinenko //===- ReconcileUnrealizedCasts.cpp - Eliminate noop unrealized casts -----===//
28b58ab8cSAlex Zinenko //
38b58ab8cSAlex Zinenko // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48b58ab8cSAlex Zinenko // See https://llvm.org/LICENSE.txt for license information.
58b58ab8cSAlex Zinenko // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68b58ab8cSAlex Zinenko //
78b58ab8cSAlex Zinenko //===----------------------------------------------------------------------===//
88b58ab8cSAlex Zinenko 
98b58ab8cSAlex Zinenko #include "mlir/Conversion/ReconcileUnrealizedCasts/ReconcileUnrealizedCasts.h"
1067d0d7acSMichele Scuttari 
118b58ab8cSAlex Zinenko #include "mlir/IR/BuiltinOps.h"
128b58ab8cSAlex Zinenko #include "mlir/Pass/Pass.h"
13*a9f62244SMatthias Springer #include "mlir/Transforms/DialectConversion.h"
148b58ab8cSAlex Zinenko 
1567d0d7acSMichele Scuttari namespace mlir {
1667d0d7acSMichele Scuttari #define GEN_PASS_DEF_RECONCILEUNREALIZEDCASTS
1767d0d7acSMichele Scuttari #include "mlir/Conversion/Passes.h.inc"
1867d0d7acSMichele Scuttari } // namespace mlir
1967d0d7acSMichele Scuttari 
208b58ab8cSAlex Zinenko using namespace mlir;
218b58ab8cSAlex Zinenko 
228b58ab8cSAlex Zinenko namespace {
238b58ab8cSAlex Zinenko 
248b58ab8cSAlex Zinenko /// Pass to simplify and eliminate unrealized conversion casts.
255b007582SMatthias Springer ///
265b007582SMatthias Springer /// This pass processes unrealized_conversion_cast ops in a worklist-driven
275b007582SMatthias Springer /// fashion. For each matched cast op, if the chain of input casts eventually
285b007582SMatthias Springer /// reaches a cast op where the input types match the output types of the
295b007582SMatthias Springer /// matched op, replace the matched op with the inputs.
305b007582SMatthias Springer ///
315b007582SMatthias Springer /// Example:
325b007582SMatthias Springer /// %1 = unrealized_conversion_cast %0 : !A to !B
335b007582SMatthias Springer /// %2 = unrealized_conversion_cast %1 : !B to !C
345b007582SMatthias Springer /// %3 = unrealized_conversion_cast %2 : !C to !A
355b007582SMatthias Springer ///
365b007582SMatthias Springer /// In the above example, %0 can be used instead of %3 and all cast ops are
375b007582SMatthias Springer /// folded away.
38039b969bSMichele Scuttari struct ReconcileUnrealizedCasts
3967d0d7acSMichele Scuttari     : public impl::ReconcileUnrealizedCastsBase<ReconcileUnrealizedCasts> {
40039b969bSMichele Scuttari   ReconcileUnrealizedCasts() = default;
418b58ab8cSAlex Zinenko 
428b58ab8cSAlex Zinenko   void runOnOperation() override {
43*a9f62244SMatthias Springer     SmallVector<UnrealizedConversionCastOp> ops;
445b007582SMatthias Springer     getOperation()->walk(
45*a9f62244SMatthias Springer         [&](UnrealizedConversionCastOp castOp) { ops.push_back(castOp); });
46*a9f62244SMatthias Springer     reconcileUnrealizedCasts(ops);
478b58ab8cSAlex Zinenko   }
488b58ab8cSAlex Zinenko };
498b58ab8cSAlex Zinenko 
508b58ab8cSAlex Zinenko } // namespace
518b58ab8cSAlex Zinenko 
52039b969bSMichele Scuttari std::unique_ptr<Pass> mlir::createReconcileUnrealizedCastsPass() {
53039b969bSMichele Scuttari   return std::make_unique<ReconcileUnrealizedCasts>();
54039b969bSMichele Scuttari }
55