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