Consistently query `ExecutableTargetAttr` (#11291)
#11057 added a `IREE::HAL::ExecutableTargetAttr::lookup` function which
should be the preferred way to get a `ExecutableTargetAttr`, since it
honors the overrides made possible by that PR.
It's also neatly shrinking code at call sites, and better conveys
intent: before, we were querying a `ExecutableVariantOp` only to get at
the `ExecutableTargetAttr`, now we query directly the latter.
The Utils are updated to all take a `ExecutableTargetAttr`, and since
they were already implementing logic to handle optionally present
fields, this further simplifies logic at call sites.
Some Utils implementation functions, which were internal, are now
exposed in `Utils.h`. Particularly `getConfigStringAttr`. There seemed
to be no point having various place in the code reimplement that
boilerplate themselves (with opportunities to mishandle optionals). A
new `getConfigIntegerAttr` is added.
This is preparation for determining tile sizes based on target info in
`MaterializeEncoding`, which following #11290 we will be able to do
based on the `ExecutableTargetAttr` which we query there. It would be
inconvenient, at least for testing purposes, to have to deal only with
`ExecutableVariantOp` there, so the new `MaterializeEncoding` code in
#11290 is using `IREE::HAL::ExecutableTargetAttr::lookup` and needs to
access helpers taking a `ExecutableTargetAttr`, which was the original
motivation for the `Utils.*` changes here.
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/ConvertToLLVM.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/ConvertToLLVM.cpp
index 0f2feb6..35a975f 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/ConvertToLLVM.cpp
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/ConvertToLLVM.cpp
@@ -1122,16 +1122,9 @@
static std::string getStringAttrFromTargetAttr(ModuleOp module,
StringRef attrName) {
- if (auto variantOp =
- module->getParentOfType<IREE::HAL::ExecutableVariantOp>()) {
- IREE::HAL::ExecutableTargetAttr targetAttr = variantOp.getTarget();
- if (auto config = targetAttr.getConfiguration()) {
- if (auto attr = config.getAs<StringAttr>(attrName)) {
- return attr.getValue().str();
- }
- }
- }
- return "";
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(module);
+ auto stringAttr = getConfigStringAttr(targetAttr, attrName);
+ return stringAttr ? stringAttr.value().str() : std::string("");
}
void ConvertToLLVMPass::runOnOperation() {
@@ -1194,13 +1187,13 @@
//
// TODO(bjacob): Use a lowering that uses specific ARM/X86 intrinsics.
bool use32BitImpl = false;
- auto variantOp = getExecutableVariantOp(module);
- if (succeeded(variantOp) && isRISCV(*variantOp)) {
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(module);
+ if (isRISCV(targetAttr)) {
// Use the 32-bit lowering for RISC-V if 'zve32x' is specified and there is
// no 64-bit integer vector support.
// TODO(#9440) Simplify logic when 'cpu_features' is simplified.
- use32BitImpl = hasZve32xFeature(*variantOp) && !hasVFeature(*variantOp) &&
- !hasZve64xFeature(*variantOp);
+ use32BitImpl = hasZve32xFeature(targetAttr) && !hasVFeature(targetAttr) &&
+ !hasZve64xFeature(targetAttr);
}
tosa::populateTosaRescaleToArithConversionPatterns(&patterns, use32BitImpl);
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/KernelDispatch.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/KernelDispatch.cpp
index 7a529b2..d5d3522 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/KernelDispatch.cpp
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/KernelDispatch.cpp
@@ -15,6 +15,7 @@
#include "iree/compiler/Codegen/Transforms/Transforms.h"
#include "iree/compiler/Codegen/Utils/Utils.h"
#include "iree/compiler/Dialect/Flow/IR/FlowOps.h"
+#include "iree/compiler/Dialect/HAL/IR/HALTypes.h"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetSelect.h"
@@ -177,38 +178,31 @@
return VectorPreProcStrategy::Peeling;
}
- auto maybeVariantOp = getExecutableVariantOp(linalgOp);
- assert(succeeded(maybeVariantOp) && "ExecutableVariantOp not found");
- auto variantOp = *maybeVariantOp;
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(linalgOp);
// Default X86 specific strategy.
- if (isX86(variantOp) && enableVectorPadding) {
+ if (isX86(targetAttr) && enableVectorPadding) {
// Padding is only enabled on x86. It leads to too much overhead on RISC-V
// and ARM.
return VectorPreProcStrategy::Padding;
}
// Default RISC-V specific strategies.
- if (isRISCV(variantOp) && enableVectorPeeling) {
+ if (isRISCV(targetAttr) && enableVectorPeeling) {
return VectorPreProcStrategy::Peeling;
}
return VectorPreProcStrategy::None;
}
-/// Looks for the `native_vector_size` attribute in the hal.executable.variant
-/// op.
+/// Looks for the `native_vector_size` attribute in the hal.executable.target
+/// looked up from this op.
static Optional<int64_t> getNativeVectorSizeInBytes(func::FuncOp entryPointFn) {
- auto variantOp =
- entryPointFn->getParentOfType<IREE::HAL::ExecutableVariantOp>();
- if (!variantOp) return llvm::None;
- IREE::HAL::ExecutableTargetAttr targetAttr = variantOp.getTarget();
- if (!targetAttr) return llvm::None;
- auto config = targetAttr.getConfiguration();
- if (!config) return llvm::None;
- auto nativeVectorSizeAttr = config.getAs<IntegerAttr>("native_vector_size");
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
+ auto nativeVectorSizeAttr =
+ getConfigIntegerAttr(targetAttr, "native_vector_size");
if (!nativeVectorSizeAttr) return llvm::None;
- int64_t nativeVectorSizeVal = nativeVectorSizeAttr.getInt();
+ int64_t nativeVectorSizeVal = nativeVectorSizeAttr->getInt();
if (!nativeVectorSizeVal) return llvm::None;
return nativeVectorSizeVal;
}
@@ -819,13 +813,13 @@
static void getDefaultMatmulWorkgroupSizes(linalg::LinalgOp op,
SmallVectorImpl<int64_t> &sizes,
int64_t vectorSize) {
- auto variantOp = getExecutableVariantOp(op);
- if (isX86(*variantOp)) {
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(op);
+ if (isX86(targetAttr)) {
sizes.append({8, 32, 16});
return;
}
- if (isRISCV(*variantOp)) {
+ if (isRISCV(targetAttr)) {
// RISC-V natively supports scalar x vector operations so we don't have to
// vectorize dimension k. Vectorizing dimension k results in a vector load
// and a sequence of vrgather ops to implemement the broadcast explicitly.
@@ -846,13 +840,12 @@
int64_t vectorSize,
bool isQuantized) {
SmallVector<int64_t> matmulTileSizes;
- auto variantOp = getExecutableVariantOp(entryPointFn);
- assert(succeeded(variantOp) && "ExecutableVariantOp not found");
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
// Compute workgroup tile sizes using heuristics.
- // TODO: if (isX86(*variantOp) || isRISCV(*variantOp)) {
+ // TODO: if (isX86(targetAttr) || isRISCV(targetAttr)) {
- if (isAArch64(*variantOp)) {
+ if (isAArch64(targetAttr)) {
if (isQuantized) {
matmulTileSizes = {vectorSize, vectorSize * 4, vectorSize};
} else {
@@ -910,12 +903,11 @@
SmallVector<int64_t> workgroupTileSizes =
getMatmulWorkgroupSizes(entryPointFn, linalgOp, vectorSize, isQuantized);
- auto variantOp = getExecutableVariantOp(entryPointFn);
- assert(succeeded(variantOp) && "ExecutableVariantOp not found");
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
// Use the default distribution for the matmul loops.
int64_t defaultMaxSize = defaultWorkgroupTileSize;
- if (isX86(*variantOp) || isRISCV(*variantOp)) {
+ if (isX86(targetAttr) || isRISCV(targetAttr)) {
defaultMaxSize = 128;
}
@@ -959,7 +951,7 @@
// ARM codgen does not switch to use codegen driver based approach, so we have
// special logic for it. All the new pipeline is expected to use codegen
// driver based approach.
- if (isAArch64(*variantOp) && !isQuantized) {
+ if (isAArch64(targetAttr) && !isQuantized) {
return setAArch64RootConfig(entryPointFn, contractionOp, flowTileSizes,
workgroupTileSizes, vectorSize);
}
@@ -1269,9 +1261,8 @@
return success();
}
- auto variantOp = getExecutableVariantOp(genericOp);
- assert(succeeded(variantOp) && "ExecutableVariantOp not found");
- if (!hasAVX2Feature(*variantOp) || !isSupportedTransposeOp(genericOp)) {
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
+ if (!hasAVX2Feature(targetAttr) || !isSupportedTransposeOp(genericOp)) {
return success();
}
@@ -1492,24 +1483,23 @@
assert(isSupported && "conv op is not supported");
SmallVector<int64_t> tileSizes;
- auto variantOp = getExecutableVariantOp(entryPointFn);
- assert(succeeded(variantOp) && "ExecutableVariantOp not found");
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
- if (isX86(*variantOp)) {
+ if (isX86(targetAttr)) {
TypeSwitch<Operation *>(op.getOperation())
.Case<linalg::Conv2DNhwcHwcfOp>(
[&](auto op) { tileSizes = {1, 1, 8, vectorSize * 2, 1, 1, 8}; })
.Case<linalg::DepthwiseConv2DNhwcHwcOp>(
[&](auto op) { tileSizes = {1, 1, 8, vectorSize * 2, 1, 3}; })
.Default([&](Operation *op) { llvm_unreachable("unsupported conv"); });
- } else if (isRISCV(*variantOp)) {
+ } else if (isRISCV(targetAttr)) {
TypeSwitch<Operation *>(op.getOperation())
.Case<linalg::Conv2DNhwcHwcfOp>(
[&](auto op) { tileSizes = {1, 1, 8, vectorSize * 2, 1, 1, 8}; })
.Case<linalg::DepthwiseConv2DNhwcHwcOp>(
[&](auto op) { tileSizes = {1, 1, 8, vectorSize, 1, 3}; })
.Default([&](Operation *op) { llvm_unreachable("unsupported conv"); });
- } else if (isAArch64(*variantOp)) {
+ } else if (isAArch64(targetAttr)) {
TypeSwitch<Operation *>(op.getOperation())
.Case<linalg::Conv2DNhwcHwcfOp>(
[&](auto op) { tileSizes = {1, 1, 32, 64, 1, 1, 16}; })
@@ -1709,15 +1699,14 @@
Operation *rootOperation = rootOp.value();
if (rootOperation) {
- auto variantOp = getExecutableVariantOp(entryPointFn);
- assert(succeeded(variantOp) && "ExecutableVariantOp not found");
- if (isVMVXBackend(*variantOp)) {
+ auto targetAttr = IREE::HAL::ExecutableTargetAttr::lookup(entryPointFn);
+ if (isVMVXBackend(targetAttr)) {
if (failed(setVMVXRootConfigImpl(entryPointFn, rootOperation))) {
return failure();
}
} else {
auto targetMLTransInfo =
- TargetMLTransformInfo::getTargetMLTransformInfo(*variantOp);
+ TargetMLTransformInfo::getTargetMLTransformInfo(targetAttr);
if (failed(setRootConfigImpl(entryPointFn, rootOperation,
targetMLTransInfo))) {
return failure();
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPULowerExecutableTarget.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPULowerExecutableTarget.cpp
index a06562f..30eff7d 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPULowerExecutableTarget.cpp
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPULowerExecutableTarget.cpp
@@ -184,7 +184,7 @@
return signalPassFailure();
}
- bool lowerToAVX2 = hasAVX2Feature(variantOp);
+ bool lowerToAVX2 = hasAVX2Feature(variantOp.getTarget());
if (!testLoweringConfiguration) {
switch (translationInfo.value().getDispatchLoweringPassPipeline()) {
case IREE::Codegen::DispatchLoweringPassPipeline::CPUDefault:
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.cpp
index bf26b16..959318f 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.cpp
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.cpp
@@ -26,8 +26,8 @@
namespace iree_compiler {
const TargetMLTransformInfo TargetMLTransformInfo::getTargetMLTransformInfo(
- IREE::HAL::ExecutableVariantOp variantOp) {
- if (isRISCV(variantOp)) {
+ IREE::HAL::ExecutableTargetAttr targetAttr) {
+ if (isRISCV(targetAttr)) {
return RISCVTargetMLTransformInfo();
}
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.h b/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.h
index bbdf4d3..06ffd6f 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.h
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/TargetMLTransformInfo.h
@@ -9,7 +9,7 @@
#include <limits>
-#include "iree/compiler/Dialect/HAL/IR/HALOps.h"
+#include "iree/compiler/Dialect/HAL/IR/HALTypes.h"
namespace mlir {
namespace iree_compiler {
@@ -22,7 +22,7 @@
std::numeric_limits<unsigned>::max();
static const TargetMLTransformInfo getTargetMLTransformInfo(
- IREE::HAL::ExecutableVariantOp variantOp);
+ IREE::HAL::ExecutableTargetAttr targetAttr);
};
} // namespace iree_compiler
diff --git a/compiler/src/iree/compiler/Codegen/Utils/Utils.cpp b/compiler/src/iree/compiler/Codegen/Utils/Utils.cpp
index 03ae9f6..a53f5f2 100644
--- a/compiler/src/iree/compiler/Codegen/Utils/Utils.cpp
+++ b/compiler/src/iree/compiler/Codegen/Utils/Utils.cpp
@@ -71,11 +71,8 @@
return exportOps;
}
-/// Returns the StringAttr with the name `stringAttr` in the configuration of
-/// `variantOp`, in found.
-static Optional<StringAttr> getConfigStringAttr(
- IREE::HAL::ExecutableVariantOp variantOp, StringRef stringAttr) {
- IREE::HAL::ExecutableTargetAttr targetAttr = variantOp.getTarget();
+Optional<StringAttr> getConfigStringAttr(
+ IREE::HAL::ExecutableTargetAttr targetAttr, StringRef stringAttr) {
if (!targetAttr) return llvm::None;
auto config = targetAttr.getConfiguration();
if (!config) return llvm::None;
@@ -84,41 +81,57 @@
return attr;
}
-/// Returns the LLVM Target triple associated with the `hal.executable.variant`
-/// operation if set.
-static Optional<llvm::Triple> getTargetTriple(
- IREE::HAL::ExecutableVariantOp variantOp) {
- auto triple = getConfigStringAttr(variantOp, "target_triple");
+Optional<IntegerAttr> getConfigIntegerAttr(
+ IREE::HAL::ExecutableTargetAttr targetAttr, StringRef integerAttr) {
+ if (!targetAttr) return llvm::None;
+ auto config = targetAttr.getConfiguration();
+ if (!config) return llvm::None;
+ auto attr = config.getAs<IntegerAttr>(integerAttr);
+ if (!attr) return llvm::None;
+ return attr;
+}
+
+Optional<llvm::Triple> getTargetTriple(
+ IREE::HAL::ExecutableTargetAttr targetAttr) {
+ auto triple = getConfigStringAttr(targetAttr, "target_triple");
if (!triple) return llvm::None;
return llvm::Triple(triple.value().str());
}
/// Returns the CPU target features associated with the `hal.executable.variant`
/// operation, if set.
-static Optional<StringRef> getCpuFeatures(
- IREE::HAL::ExecutableVariantOp variantOp) {
- auto cpuFeatures = getConfigStringAttr(variantOp, "cpu_features");
+Optional<StringRef> getCpuFeatures(IREE::HAL::ExecutableTargetAttr targetAttr) {
+ auto cpuFeatures = getConfigStringAttr(targetAttr, "cpu_features");
if (!cpuFeatures) return llvm::None;
return cpuFeatures->getValue();
}
-bool isX86(IREE::HAL::ExecutableVariantOp variantOp) {
- Optional<llvm::Triple> triple = getTargetTriple(variantOp);
+bool isX86(IREE::HAL::ExecutableTargetAttr targetAttr) {
+ Optional<llvm::Triple> triple = getTargetTriple(targetAttr);
return triple && triple.value().isX86();
}
-bool isAArch64(IREE::HAL::ExecutableVariantOp variantOp) {
- Optional<llvm::Triple> triple = getTargetTriple(variantOp);
+bool isAArch64(IREE::HAL::ExecutableTargetAttr targetAttr) {
+ Optional<llvm::Triple> triple = getTargetTriple(targetAttr);
return triple && triple.value().isAArch64();
}
+bool isRISCV(IREE::HAL::ExecutableTargetAttr targetAttr) {
+ Optional<llvm::Triple> triple = getTargetTriple(targetAttr);
+ return triple && triple.value().isRISCV();
+}
+
+bool isVMVXBackend(IREE::HAL::ExecutableTargetAttr targetAttr) {
+ return targetAttr.getBackend().getValue().startswith("vmvx");
+}
+
// TODO(dcaballe): If we have to check for a significantly large number of
// features in the future, we may want to consider a persistent state to carry
// over processed HAL information or keeping the TTI instance alive and query
// subtarget features data structure.
-static bool hasFeature(IREE::HAL::ExecutableVariantOp variantOp,
+static bool hasFeature(IREE::HAL::ExecutableTargetAttr targetAttr,
StringRef feature) {
- Optional<StringRef> features = getCpuFeatures(variantOp);
+ Optional<StringRef> features = getCpuFeatures(targetAttr);
if (!features) {
return false;
}
@@ -136,29 +149,20 @@
return false;
}
-/// Returns true if the 'variantOp' contains '+avx2' in its cpu features.
-bool hasAVX2Feature(IREE::HAL::ExecutableVariantOp variantOp) {
- return hasFeature(variantOp, "+avx2");
+bool hasAVX2Feature(IREE::HAL::ExecutableTargetAttr targetAttr) {
+ return hasFeature(targetAttr, "+avx2");
}
-/// Returns true if the 'variantOp' contains '+v' in its cpu features.
-bool hasVFeature(IREE::HAL::ExecutableVariantOp variantOp) {
- return hasFeature(variantOp, "+v");
+bool hasVFeature(IREE::HAL::ExecutableTargetAttr targetAttr) {
+ return hasFeature(targetAttr, "+v");
}
-/// Returns true if the 'variantOp' contains '+zve32x' in its cpu features.
-bool hasZve32xFeature(IREE::HAL::ExecutableVariantOp variantOp) {
- return hasFeature(variantOp, "+zve32x");
+bool hasZve32xFeature(IREE::HAL::ExecutableTargetAttr targetAttr) {
+ return hasFeature(targetAttr, "+zve32x");
}
-/// Returns true if the 'variantOp' contains '+zve64x' in its cpu features.
-bool hasZve64xFeature(IREE::HAL::ExecutableVariantOp variantOp) {
- return hasFeature(variantOp, "+zve64x");
-}
-
-bool isRISCV(IREE::HAL::ExecutableVariantOp variantOp) {
- Optional<llvm::Triple> triple = getTargetTriple(variantOp);
- return triple && triple.value().isRISCV();
+bool hasZve64xFeature(IREE::HAL::ExecutableTargetAttr targetAttr) {
+ return hasFeature(targetAttr, "+zve64x");
}
bool isReadOnly(Value v) {
diff --git a/compiler/src/iree/compiler/Codegen/Utils/Utils.h b/compiler/src/iree/compiler/Codegen/Utils/Utils.h
index 506f707..47778b8 100644
--- a/compiler/src/iree/compiler/Codegen/Utils/Utils.h
+++ b/compiler/src/iree/compiler/Codegen/Utils/Utils.h
@@ -43,28 +43,40 @@
/// failure.
FailureOr<IREE::HAL::ExecutableVariantOp> getExecutableVariantOp(Operation *op);
+/// Returns the StringAttr with the name `stringAttr` in the `targetAttr`, if
+/// found.
+Optional<StringAttr> getConfigStringAttr(
+ IREE::HAL::ExecutableTargetAttr targetAttr, StringRef stringAttr);
+
+/// Returns the IntegerAttr with the name `integerAttr` in the `targetAttr`, if
+/// found.
+Optional<IntegerAttr> getConfigIntegerAttr(
+ IREE::HAL::ExecutableTargetAttr targetAttr, StringRef integerAttr);
+
+/// Returns the LLVM Target triple associated with the `targetAttr`, if set.
+Optional<llvm::Triple> getTargetTriple(
+ IREE::HAL::ExecutableTargetAttr targetAttr);
+
+/// Returns the CPU target features associated with the `targetAttr`, if set.
+Optional<StringRef> getCpuFeatures(IREE::HAL::ExecutableTargetAttr targetAttr);
+
/// Methods to get target information.
-bool isX86(IREE::HAL::ExecutableVariantOp variantOp);
-
-bool isAArch64(IREE::HAL::ExecutableVariantOp variantOp);
-
-bool isRISCV(IREE::HAL::ExecutableVariantOp variantOp);
-
-inline bool isVMVXBackend(IREE::HAL::ExecutableVariantOp variantOp) {
- return variantOp.getTarget().getBackend().getValue().startswith("vmvx");
-}
+bool isX86(IREE::HAL::ExecutableTargetAttr targetAttr);
+bool isAArch64(IREE::HAL::ExecutableTargetAttr targetAttr);
+bool isRISCV(IREE::HAL::ExecutableTargetAttr targetAttr);
+bool isVMVXBackend(IREE::HAL::ExecutableTargetAttr targetAttr);
/// Returns true if the 'variantOp' contains '+avx2' in its cpu features.
-bool hasAVX2Feature(IREE::HAL::ExecutableVariantOp variantOp);
+bool hasAVX2Feature(IREE::HAL::ExecutableTargetAttr targetAttr);
/// Returns true if the 'variantOp' contains '+v' in its cpu features.
-bool hasVFeature(IREE::HAL::ExecutableVariantOp variantOp);
+bool hasVFeature(IREE::HAL::ExecutableTargetAttr targetAttr);
/// Returns true if the 'variantOp' contains '+zve32x' in its cpu features.
-bool hasZve32xFeature(IREE::HAL::ExecutableVariantOp variantOp);
+bool hasZve32xFeature(IREE::HAL::ExecutableTargetAttr targetAttr);
/// Returns true if the 'variantOp' contains '+zve64x' in its cpu features.
-bool hasZve64xFeature(IREE::HAL::ExecutableVariantOp variantOp);
+bool hasZve64xFeature(IREE::HAL::ExecutableTargetAttr targetAttr);
/// Checks if a tensor value is generated from a read-only object, like
/// and interface binding with read-only attribute or from an `arith.constant`