//===- UnsignedWhenEquivalent.cpp - Pass to replace signed operations with // unsigned // ones when all their arguments and results are statically non-negative --===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "mlir/Dialect/Arith/Transforms/Passes.h" #include "mlir/Analysis/DataFlow/DeadCodeAnalysis.h" #include "mlir/Analysis/DataFlow/IntegerRangeAnalysis.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Transforms/DialectConversion.h" namespace mlir { namespace arith { #define GEN_PASS_DEF_ARITHUNSIGNEDWHENEQUIVALENT #include "mlir/Dialect/Arith/Transforms/Passes.h.inc" } // namespace arith } // namespace mlir usingnamespacemlir; usingnamespacemlir::arith; usingnamespacemlir::dataflow; /// Succeeds when a value is statically non-negative in that it has a lower /// bound on its value (if it is treated as signed) and that bound is /// non-negative. static LogicalResult staticallyNonNegative(DataFlowSolver &solver, Value v) { … } /// Succeeds if an op can be converted to its unsigned equivalent without /// changing its semantics. This is the case when none of its openands or /// results can be below 0 when analyzed from a signed perspective. static LogicalResult staticallyNonNegative(DataFlowSolver &solver, Operation *op) { … } /// Succeeds when the comparison predicate is a signed operation and all the /// operands are non-negative, indicating that the cmpi operation `op` can have /// its predicate changed to an unsigned equivalent. static LogicalResult isCmpIConvertable(DataFlowSolver &solver, CmpIOp op) { … } /// Return the unsigned equivalent of a signed comparison predicate, /// or the predicate itself if there is none. static CmpIPredicate toUnsignedPred(CmpIPredicate pred) { … } namespace { template <typename Signed, typename Unsigned> struct ConvertOpToUnsigned : OpConversionPattern<Signed> { … }; struct ConvertCmpIToUnsigned : OpConversionPattern<CmpIOp> { … }; struct ArithUnsignedWhenEquivalentPass : public arith::impl::ArithUnsignedWhenEquivalentBase< ArithUnsignedWhenEquivalentPass> { … }; } // end anonymous namespace std::unique_ptr<Pass> mlir::arith::createArithUnsignedWhenEquivalentPass() { … }