1 //===- StaticValueUtils.cpp - Utilities for dealing with static values ----===// 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 #include "mlir/Dialect/Utils/StaticValueUtils.h" 10 #include "mlir/IR/Matchers.h" 11 #include "mlir/Support/LLVM.h" 12 #include "llvm/ADT/APSInt.h" 13 14 namespace mlir { 15 16 /// Helper function to dispatch an OpFoldResult into `staticVec` if: 17 /// a) it is an IntegerAttr 18 /// In other cases, the OpFoldResult is dispached to the `dynamicVec`. 19 /// In such dynamic cases, a copy of the `sentinel` value is also pushed to 20 /// `staticVec`. This is useful to extract mixed static and dynamic entries that 21 /// come from an AttrSizedOperandSegments trait. 22 void dispatchIndexOpFoldResult(OpFoldResult ofr, 23 SmallVectorImpl<Value> &dynamicVec, 24 SmallVectorImpl<int64_t> &staticVec, 25 int64_t sentinel) { 26 auto v = ofr.dyn_cast<Value>(); 27 if (!v) { 28 APInt apInt = ofr.get<Attribute>().cast<IntegerAttr>().getValue(); 29 staticVec.push_back(apInt.getSExtValue()); 30 return; 31 } 32 dynamicVec.push_back(v); 33 staticVec.push_back(sentinel); 34 } 35 36 void dispatchIndexOpFoldResults(ArrayRef<OpFoldResult> ofrs, 37 SmallVectorImpl<Value> &dynamicVec, 38 SmallVectorImpl<int64_t> &staticVec, 39 int64_t sentinel) { 40 for (OpFoldResult ofr : ofrs) 41 dispatchIndexOpFoldResult(ofr, dynamicVec, staticVec, sentinel); 42 } 43 44 /// Extract int64_t values from the assumed ArrayAttr of IntegerAttr. 45 SmallVector<int64_t, 4> extractFromI64ArrayAttr(Attribute attr) { 46 return llvm::to_vector<4>( 47 llvm::map_range(attr.cast<ArrayAttr>(), [](Attribute a) -> int64_t { 48 return a.cast<IntegerAttr>().getInt(); 49 })); 50 } 51 52 /// Given a value, try to extract a constant Attribute. If this fails, return 53 /// the original value. 54 OpFoldResult getAsOpFoldResult(Value val) { 55 Attribute attr; 56 if (matchPattern(val, m_Constant(&attr))) 57 return attr; 58 return val; 59 } 60 61 /// Given an array of values, try to extract a constant Attribute from each 62 /// value. If this fails, return the original value. 63 SmallVector<OpFoldResult> getAsOpFoldResult(ArrayRef<Value> values) { 64 return llvm::to_vector<4>( 65 llvm::map_range(values, [](Value v) { return getAsOpFoldResult(v); })); 66 } 67 68 /// If ofr is a constant integer or an IntegerAttr, return the integer. 69 Optional<int64_t> getConstantIntValue(OpFoldResult ofr) { 70 // Case 1: Check for Constant integer. 71 if (auto val = ofr.dyn_cast<Value>()) { 72 APSInt intVal; 73 if (matchPattern(val, m_ConstantInt(&intVal))) 74 return intVal.getSExtValue(); 75 return llvm::None; 76 } 77 // Case 2: Check for IntegerAttr. 78 Attribute attr = ofr.dyn_cast<Attribute>(); 79 if (auto intAttr = attr.dyn_cast_or_null<IntegerAttr>()) 80 return intAttr.getValue().getSExtValue(); 81 return llvm::None; 82 } 83 84 /// Return true if ofr1 and ofr2 are the same integer constant attribute values 85 /// or the same SSA value. 86 /// Ignore integer bitwidth and type mismatch that come from the fact there is 87 /// no IndexAttr and that IndexType has no bitwidth. 88 bool isEqualConstantIntOrValue(OpFoldResult ofr1, OpFoldResult ofr2) { 89 auto cst1 = getConstantIntValue(ofr1), cst2 = getConstantIntValue(ofr2); 90 if (cst1 && cst2 && *cst1 == *cst2) 91 return true; 92 auto v1 = ofr1.dyn_cast<Value>(), v2 = ofr2.dyn_cast<Value>(); 93 return v1 && v1 == v2; 94 } 95 } // namespace mlir 96