1 //===- ConversionUtils.h - Helper functions for tosa conversion -*- C++ -*-===//
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 // Utility functions for TOSA lowering
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef DIALECT_TOSA_UTILS_COVERSION_UTILS_H_
14 #define DIALECT_TOSA_UTILS_COVERSION_UTILS_H_
15 
16 #include "mlir/Dialect/Arithmetic/IR/Arithmetic.h"
17 #include "mlir/Dialect/Tensor/IR/Tensor.h"
18 #include "mlir/Dialect/Utils/StructuredOpsUtils.h"
19 #include "mlir/IR/PatternMatch.h"
20 
21 namespace mlir {
22 namespace tosa {
23 
24 // Creates a SmallVector of Stringrefs for N parallel loops
25 SmallVector<StringRef> getNParallelLoopsAttrs(unsigned nParallelLoops);
26 
27 // Takes a vector of values and condenses them to a vector with no gaps.
28 SmallVector<Value> condenseValues(const SmallVector<Value> &values);
29 
30 // Takes the parameters for a clamp and turns it into a series of ops.
31 template <typename T, typename P>
clampHelper(Location loc,Value arg,arith::ConstantOp min,arith::ConstantOp max,P pred,OpBuilder & rewriter)32 arith::SelectOp clampHelper(Location loc, Value arg, arith::ConstantOp min,
33                             arith::ConstantOp max, P pred,
34                             OpBuilder &rewriter) {
35   auto smallerThanMin = rewriter.create<T>(loc, pred, arg, min);
36   auto minOrArg =
37       rewriter.create<arith::SelectOp>(loc, smallerThanMin, min, arg);
38   auto largerThanMax = rewriter.create<T>(loc, pred, max, arg);
39   return rewriter.create<arith::SelectOp>(loc, largerThanMax, max, minOrArg);
40 }
41 
42 // Returns the values in an attribute as an array of values.
43 template <typename T>
getValuesFromIntArrayAttribute(ArrayAttr attr,SmallVector<T> & arrayValues)44 void getValuesFromIntArrayAttribute(ArrayAttr attr,
45                                     SmallVector<T> &arrayValues) {
46   for (Attribute val : attr.getValue()) {
47     arrayValues.push_back(val.cast<IntegerAttr>().getValue().getSExtValue());
48   }
49 }
50 
51 // Checks for a dynamic batch dim in any of the passed parameters of an op.
52 // The batch dimention must be #0 and the rest of the dimensions must be static.
53 template <typename Op>
checkHasDynamicBatchDims(PatternRewriter & rewriter,Op op,ArrayRef<Value> params)54 Optional<SmallVector<Value>> checkHasDynamicBatchDims(PatternRewriter &rewriter,
55                                                       Op op,
56                                                       ArrayRef<Value> params) {
57   SmallVector<ShapedType> dynTypes;
58   SmallVector<Value> dynamicDims;
59   for (const Value &param : params) {
60     auto paramTy = param.getType().cast<ShapedType>();
61     if (!paramTy.hasStaticShape())
62       dynTypes.push_back(paramTy);
63   }
64 
65   if (dynTypes.empty())
66     return dynamicDims;
67 
68   for (const ShapedType &dynTy : dynTypes) {
69     if (llvm::any_of(dynTy.getShape().drop_front(), ShapedType::isDynamic)) {
70       (void)rewriter.notifyMatchFailure(
71           op, "input can only be dynamic for batch size");
72       return llvm::None;
73     }
74   }
75 
76   dynamicDims.push_back(
77       rewriter.create<tensor::DimOp>(op->getLoc(), params[0], 0));
78   return dynamicDims;
79 }
80 
81 } // namespace tosa
82 } // namespace mlir
83 
84 #endif // DIALECT_TOSA_UTILS_COVERSION_UTILS_H_
85