[Mlir-commits] [mlir] 0c41758 - [MLIR][Python] Remove partial LLVM APIs in python bindings (#178290)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Jan 28 10:27:30 PST 2026
Author: RattataKing
Date: 2026-01-28T13:27:25-05:00
New Revision: 0c41758502e6952f0501acf4d8c2c13bf5b2b4b5
URL: https://github.com/llvm/llvm-project/commit/0c41758502e6952f0501acf4d8c2c13bf5b2b4b5
DIFF: https://github.com/llvm/llvm-project/commit/0c41758502e6952f0501acf4d8c2c13bf5b2b4b5.diff
LOG: [MLIR][Python] Remove partial LLVM APIs in python bindings (#178290)
mlir-py bindings should only rely on C mlir APIs.
This PR replaced partial LLVM utilities (`Twine`, `ArrayRef`,
`SmallVector`, `StringRef`) with equivalent STL, and added a `join()`
helper function in `IRCore.cpp` to concat strings.
---------
Co-authored-by: Jakub Kuderski <kubakuderski at gmail.com>
Added:
Modified:
mlir/include/mlir/Bindings/Python/IRCore.h
mlir/lib/Bindings/Python/IRCore.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/Bindings/Python/IRCore.h b/mlir/include/mlir/Bindings/Python/IRCore.h
index f9fc34e82c972..a9861c3c72555 100644
--- a/mlir/include/mlir/Bindings/Python/IRCore.h
+++ b/mlir/include/mlir/Bindings/Python/IRCore.h
@@ -10,6 +10,7 @@
#ifndef MLIR_BINDINGS_PYTHON_IRCORE_H
#define MLIR_BINDINGS_PYTHON_IRCORE_H
+#include <cstddef>
#include <optional>
#include <sstream>
#include <utility>
@@ -29,8 +30,6 @@
#include "mlir/Bindings/Python/Nanobind.h"
#include "mlir/Bindings/Python/NanobindAdaptors.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ThreadPool.h"
namespace mlir {
@@ -255,7 +254,7 @@ class MLIR_PYTHON_API_EXPORTED PyMlirContext {
// extension mechanism on the MlirContext for stashing user pointers.
// Note that this holds a handle, which does not imply ownership.
// Mappings will be removed when the context is destructed.
- using LiveContextMap = llvm::DenseMap<void *, PyMlirContext *>;
+ using LiveContextMap = std::unordered_map<void *, PyMlirContext *>;
static nanobind::ft_mutex live_contexts_mutex;
static LiveContextMap &getLiveContexts();
@@ -264,7 +263,7 @@ class MLIR_PYTHON_API_EXPORTED PyMlirContext {
// from this map, and while it still exists as an instance, any
// attempt to access it will raise an error.
using LiveModuleMap =
- llvm::DenseMap<const void *, std::pair<nanobind::handle, PyModule *>>;
+ std::unordered_map<const void *, std::pair<nanobind::handle, PyModule *>>;
LiveModuleMap liveModules;
bool emitErrorDiagnostics = false;
@@ -687,7 +686,7 @@ class MLIR_PYTHON_API_EXPORTED PyOperation : public PyOperationBase,
/// Creates an operation. See corresponding python docstring.
static nanobind::object
create(std::string_view name, std::optional<std::vector<PyType *>> results,
- llvm::ArrayRef<MlirValue> operands,
+ const MlirValue *operands, size_t numOperands,
std::optional<nanobind::dict> attributes,
std::optional<std::vector<PyBlock *>> successors, int regions,
PyLocation &location, const nanobind::object &ip, bool inferType);
@@ -947,10 +946,9 @@ class MLIR_PYTHON_API_EXPORTED PyConcreteType : public BaseTy {
if (!DerivedTy::isaFunction(orig)) {
auto origRepr =
nanobind::cast<std::string>(nanobind::repr(nanobind::cast(orig)));
- throw nanobind::value_error((::llvm::Twine("Cannot cast type to ") +
+ throw nanobind::value_error((std::string("Cannot cast type to ") +
DerivedTy::pyClassName + " (from " +
origRepr + ")")
- .str()
.c_str());
}
return orig;
@@ -966,8 +964,7 @@ class MLIR_PYTHON_API_EXPORTED PyConcreteType : public BaseTy {
if (DerivedTy::getTypeIdFunction)
return PyTypeID(DerivedTy::getTypeIdFunction());
throw nanobind::attribute_error(
- (DerivedTy::pyClassName + ::llvm::Twine(" has no typeid."))
- .str()
+ (DerivedTy::pyClassName + std::string(" has no typeid."))
.c_str());
},
nanobind::sig("def static_typeid(/) -> TypeID"));
@@ -1080,10 +1077,9 @@ class MLIR_PYTHON_API_EXPORTED PyConcreteAttribute : public BaseTy {
if (!DerivedTy::isaFunction(orig)) {
auto origRepr =
nanobind::cast<std::string>(nanobind::repr(nanobind::cast(orig)));
- throw nanobind::value_error((::llvm::Twine("Cannot cast attribute to ") +
+ throw nanobind::value_error((std::string("Cannot cast attribute to ") +
DerivedTy::pyClassName + " (from " +
origRepr + ")")
- .str()
.c_str());
}
return orig;
@@ -1111,8 +1107,7 @@ class MLIR_PYTHON_API_EXPORTED PyConcreteAttribute : public BaseTy {
if (DerivedTy::getTypeIdFunction)
return PyTypeID(DerivedTy::getTypeIdFunction());
throw nanobind::attribute_error(
- (DerivedTy::pyClassName + ::llvm::Twine(" has no typeid."))
- .str()
+ (DerivedTy::pyClassName + std::string(" has no typeid."))
.c_str());
},
nanobind::sig("def static_typeid(/) -> TypeID"));
@@ -1329,9 +1324,10 @@ class MLIR_PYTHON_API_EXPORTED PySymbolTable {
/// Custom exception that allows access to error diagnostic information. This is
/// converted to the `ir.MLIRError` python exception when thrown.
struct MLIR_PYTHON_API_EXPORTED MLIRError {
- MLIRError(::llvm::Twine message,
+ MLIRError(std::string message,
std::vector<PyDiagnostic::DiagnosticInfo> &&errorDiagnostics = {})
- : message(message.str()), errorDiagnostics(std::move(errorDiagnostics)) {}
+ : message(std::move(message)),
+ errorDiagnostics(std::move(errorDiagnostics)) {}
std::string message;
std::vector<PyDiagnostic::DiagnosticInfo> errorDiagnostics;
};
@@ -1549,10 +1545,9 @@ class MLIR_PYTHON_API_EXPORTED PyConcreteValue : public PyValue {
if (!DerivedTy::isaFunction(orig.get())) {
auto origRepr =
nanobind::cast<std::string>(nanobind::repr(nanobind::cast(orig)));
- throw nanobind::value_error((::llvm::Twine("Cannot cast value to ") +
+ throw nanobind::value_error((std::string("Cannot cast value to ") +
DerivedTy::pyClassName + " (from " +
origRepr + ")")
- .str()
.c_str());
}
return orig.get();
@@ -1561,9 +1556,8 @@ class MLIR_PYTHON_API_EXPORTED PyConcreteValue : public PyValue {
/// Binds the Python module objects to functions of this class.
static void bind(nanobind::module_ &m) {
auto cls = ClassTy(m, DerivedTy::pyClassName, nanobind::is_generic(),
- nanobind::sig((::llvm::Twine("class ") +
+ nanobind::sig((std::string("class ") +
DerivedTy::pyClassName + "(Value[_T])")
- .str()
.c_str()));
cls.def(nanobind::init<PyValue &>(), nanobind::keep_alive<0, 1>(),
nanobind::arg("value"));
@@ -1825,9 +1819,8 @@ class MLIR_PYTHON_API_EXPORTED PyOpAttributeMap {
bool dunderContains(const std::string &name);
- static void
- forEachAttr(MlirOperation op,
- llvm::function_ref<void(MlirStringRef, MlirAttribute)> fn);
+ static void forEachAttr(MlirOperation op,
+ std::function<void(MlirStringRef, MlirAttribute)> fn);
static void bind(nanobind::module_ &m);
diff --git a/mlir/lib/Bindings/Python/IRCore.cpp b/mlir/lib/Bindings/Python/IRCore.cpp
index 54d5a15b92bf0..7a344c1214c1c 100644
--- a/mlir/lib/Bindings/Python/IRCore.cpp
+++ b/mlir/lib/Bindings/Python/IRCore.cpp
@@ -18,19 +18,15 @@
#include "mlir-c/Diagnostics.h"
#include "mlir-c/IR.h"
#include "mlir-c/Support.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
#include <optional>
+#include <sstream>
+#include <string>
namespace nb = nanobind;
using namespace nb::literals;
using namespace mlir;
-using llvm::SmallVector;
-using llvm::StringRef;
-using llvm::Twine;
-
static const char kModuleParseDocstring[] =
R"(Parses a module's assembly format from a string.
@@ -52,6 +48,14 @@ operations.
// Utilities.
//------------------------------------------------------------------------------
+/// Local helper to concatenate arguments into a `std::string`.
+template <typename... Ts>
+static std::string join(const Ts &...args) {
+ std::ostringstream oss;
+ (oss << ... << args);
+ return oss.str();
+}
+
/// Helper for creating an @classmethod.
template <class Func, typename... Args>
static nb::object classmethod(Func f, Args... args) {
@@ -81,13 +85,13 @@ namespace MLIR_BINDINGS_PYTHON_DOMAIN {
MlirBlock createBlock(const nb::sequence &pyArgTypes,
const std::optional<nb::sequence> &pyArgLocs) {
- SmallVector<MlirType> argTypes;
+ std::vector<MlirType> argTypes;
argTypes.reserve(nb::len(pyArgTypes));
for (const auto &pyType : pyArgTypes)
argTypes.push_back(
nb::cast<python::MLIR_BINDINGS_PYTHON_DOMAIN::PyType &>(pyType));
- SmallVector<MlirLocation> argLocs;
+ std::vector<MlirLocation> argLocs;
if (pyArgLocs) {
argLocs.reserve(nb::len(*pyArgLocs));
for (const auto &pyLoc : *pyArgLocs)
@@ -100,10 +104,9 @@ MlirBlock createBlock(const nb::sequence &pyArgTypes,
}
if (argTypes.size() != argLocs.size())
- throw nb::value_error(("Expected " + Twine(argTypes.size()) +
- " locations, got: " + Twine(argLocs.size()))
- .str()
- .c_str());
+ throw nb::value_error(
+ join("Expected ", argTypes.size(), " locations, got: ", argLocs.size())
+ .c_str());
return mlirBlockCreate(argTypes.size(), argTypes.data(), argLocs.data());
}
@@ -824,7 +827,7 @@ MlirDialect PyDialects::getDialectForKey(const std::string &key,
MlirDialect dialect = mlirContextGetOrLoadDialect(getContext()->get(),
{key.data(), key.size()});
if (mlirDialectIsNull(dialect)) {
- std::string msg = (Twine("Dialect '") + key + "' not found").str();
+ std::string msg = join("Dialect '", key, "' not found");
if (attrError)
throw nb::attribute_error(msg.c_str());
throw nb::index_error(msg.c_str());
@@ -1105,10 +1108,9 @@ void PyOperationBase::writeBytecode(const nb::object &fileOrStringObject,
operation, config, accum.getCallback(), accum.getUserData());
mlirBytecodeWriterConfigDestroy(config);
if (mlirLogicalResultIsFailure(res))
- throw nb::value_error((Twine("Unable to honor desired bytecode version ") +
- Twine(*bytecodeVersion))
- .str()
- .c_str());
+ throw nb::value_error(
+ join("Unable to honor desired bytecode version ", *bytecodeVersion)
+ .c_str());
}
void PyOperationBase::walk(std::function<PyWalkResult(MlirOperation)> callback,
@@ -1255,14 +1257,14 @@ static void maybeInsertOperation(PyOperationRef &op,
nb::object PyOperation::create(std::string_view name,
std::optional<std::vector<PyType *>> results,
- llvm::ArrayRef<MlirValue> operands,
+ const MlirValue *operands, size_t numOperands,
std::optional<nb::dict> attributes,
std::optional<std::vector<PyBlock *>> successors,
int regions, PyLocation &location,
const nb::object &maybeIp, bool inferType) {
- llvm::SmallVector<MlirType, 4> mlirResults;
- llvm::SmallVector<MlirBlock, 4> mlirSuccessors;
- llvm::SmallVector<std::pair<std::string, MlirAttribute>, 4> mlirAttributes;
+ std::vector<MlirType> mlirResults;
+ std::vector<MlirBlock> mlirSuccessors;
+ std::vector<std::pair<std::string, MlirAttribute>> mlirAttributes;
// General parameter validation.
if (regions < 0)
@@ -1286,9 +1288,9 @@ nb::object PyOperation::create(std::string_view name,
try {
key = nb::cast<std::string>(it.first);
} catch (nb::cast_error &err) {
- std::string msg = "Invalid attribute key (not a string) when "
- "attempting to create the operation \"" +
- std::string(name) + "\" (" + err.what() + ")";
+ std::string msg = join("Invalid attribute key (not a string) when "
+ "attempting to create the operation \"",
+ name, "\" (", err.what(), ")");
throw nb::type_error(msg.c_str());
}
try {
@@ -1296,16 +1298,15 @@ nb::object PyOperation::create(std::string_view name,
// TODO: Verify attribute originates from the same context.
mlirAttributes.emplace_back(std::move(key), attribute);
} catch (nb::cast_error &err) {
- std::string msg = "Invalid attribute value for the key \"" + key +
- "\" when attempting to create the operation \"" +
- std::string(name) + "\" (" + err.what() + ")";
+ std::string msg = join("Invalid attribute value for the key \"", key,
+ "\" when attempting to create the operation \"",
+ name, "\" (", err.what(), ")");
throw nb::type_error(msg.c_str());
} catch (std::runtime_error &) {
// This exception seems thrown when the value is "None".
- std::string msg =
- "Found an invalid (`None`?) attribute value for the key \"" + key +
- "\" when attempting to create the operation \"" +
- std::string(name) + "\"";
+ std::string msg = join(
+ "Found an invalid (`None`?) attribute value for the key \"", key,
+ "\" when attempting to create the operation \"", name, "\"");
throw std::runtime_error(msg);
}
}
@@ -1325,8 +1326,8 @@ nb::object PyOperation::create(std::string_view name,
// point, exceptions cannot be thrown or else the state will leak.
MlirOperationState state =
mlirOperationStateGet(toMlirStringRef(name), location);
- if (!operands.empty())
- mlirOperationStateAddOperands(&state, operands.size(), operands.data());
+ if (numOperands > 0)
+ mlirOperationStateAddOperands(&state, numOperands, operands);
state.enableResultTypeInference = inferType;
if (!mlirResults.empty())
mlirOperationStateAddResults(&state, mlirResults.size(),
@@ -1335,7 +1336,7 @@ nb::object PyOperation::create(std::string_view name,
// Note that the attribute names directly reference bytes in
// mlirAttributes, so that vector must not be changed from here
// on.
- llvm::SmallVector<MlirNamedAttribute, 4> mlirNamedAttributes;
+ std::vector<MlirNamedAttribute> mlirNamedAttributes;
mlirNamedAttributes.reserve(mlirAttributes.size());
for (auto &it : mlirAttributes)
mlirNamedAttributes.push_back(mlirNamedAttributeGet(
@@ -1349,7 +1350,7 @@ nb::object PyOperation::create(std::string_view name,
mlirOperationStateAddSuccessors(&state, mlirSuccessors.size(),
mlirSuccessors.data());
if (regions) {
- llvm::SmallVector<MlirRegion, 4> mlirRegions;
+ std::vector<MlirRegion> mlirRegions;
mlirRegions.resize(regions);
for (int i = 0; i < regions; ++i)
mlirRegions[i] = mlirRegionCreate();
@@ -1383,7 +1384,7 @@ nb::object PyOperation::createOpView() {
MlirIdentifier ident = mlirOperationGetName(get());
MlirStringRef identStr = mlirIdentifierStr(ident);
auto operationCls = PyGlobals::get().lookupOperationClass(
- StringRef(identStr.data, identStr.length));
+ std::string_view(identStr.data, identStr.length));
if (operationCls)
return PyOpView::constructDerived(*operationCls, getRef().getObject());
return nb::cast(PyOpView(getRef().getObject()));
@@ -1468,7 +1469,7 @@ PyOpResultList PyOpResultList::slice(intptr_t startIndex, intptr_t length,
// PyOpView
//------------------------------------------------------------------------------
-static void populateResultTypes(StringRef name, nb::list resultTypeList,
+static void populateResultTypes(std::string_view name, nb::list resultTypeList,
const nb::object &resultSegmentSpecObj,
std::vector<int32_t> &resultSegmentLengths,
std::vector<PyType *> &resultTypes) {
@@ -1481,10 +1482,8 @@ static void populateResultTypes(StringRef name, nb::list resultTypeList,
if (!resultTypes.back())
throw nb::cast_error();
} catch (nb::cast_error &err) {
- throw nb::value_error((llvm::Twine("Result ") +
- llvm::Twine(it.index()) + " of operation \"" +
- name + "\" must be a Type (" + err.what() + ")")
- .str()
+ throw nb::value_error(join("Result ", it.index(), " of operation \"",
+ name, "\" must be a Type (", err.what(), ")")
.c_str());
}
}
@@ -1492,13 +1491,10 @@ static void populateResultTypes(StringRef name, nb::list resultTypeList,
// Sized result unpacking.
auto resultSegmentSpec = nb::cast<std::vector<int>>(resultSegmentSpecObj);
if (resultSegmentSpec.size() != resultTypeList.size()) {
- throw nb::value_error((llvm::Twine("Operation \"") + name +
- "\" requires " +
- llvm::Twine(resultSegmentSpec.size()) +
- " result segments but was provided " +
- llvm::Twine(resultTypeList.size()))
- .str()
- .c_str());
+ throw nb::value_error(
+ join("Operation \"", name, "\" requires ", resultSegmentSpec.size(),
+ " result segments but was provided ", resultTypeList.size())
+ .c_str());
}
resultSegmentLengths.reserve(resultTypeList.size());
for (const auto &it :
@@ -1516,18 +1512,14 @@ static void populateResultTypes(StringRef name, nb::list resultTypeList,
resultSegmentLengths.push_back(0);
} else {
throw nb::value_error(
- (llvm::Twine("Result ") + llvm::Twine(it.index()) +
- " of operation \"" + name +
- "\" must be a Type (was None and result is not optional)")
- .str()
+ join("Result ", it.index(), " of operation \"", name,
+ "\" must be a Type (was None and result is not optional)")
.c_str());
}
} catch (nb::cast_error &err) {
- throw nb::value_error((llvm::Twine("Result ") +
- llvm::Twine(it.index()) + " of operation \"" +
- name + "\" must be a Type (" + err.what() +
- ")")
- .str()
+ throw nb::value_error(join("Result ", it.index(), " of operation \"",
+ name, "\" must be a Type (", err.what(),
+ ")")
.c_str());
}
} else if (segmentSpec == -1) {
@@ -1551,11 +1543,9 @@ static void populateResultTypes(StringRef name, nb::list resultTypeList,
// NOTE: Sloppy to be using a catch-all here, but there are at least
// three
diff erent unrelated exceptions that can be thrown in the
// above "casts". Just keep the scope above small and catch them all.
- throw nb::value_error((llvm::Twine("Result ") +
- llvm::Twine(it.index()) + " of operation \"" +
- name + "\" must be a Sequence of Types (" +
- err.what() + ")")
- .str()
+ throw nb::value_error(join("Result ", it.index(), " of operation \"",
+ name, "\" must be a Sequence of Types (",
+ err.what(), ")")
.c_str());
}
} else {
@@ -1569,13 +1559,13 @@ MlirValue getUniqueResult(MlirOperation operation) {
auto numResults = mlirOperationGetNumResults(operation);
if (numResults != 1) {
auto name = mlirIdentifierStr(mlirOperationGetName(operation));
- throw nb::value_error((Twine("Cannot call .result on operation ") +
- StringRef(name.data, name.length) + " which has " +
- Twine(numResults) +
- " results (it is only valid for operations with a "
- "single result)")
- .str()
- .c_str());
+ throw nb::value_error(
+ join("Cannot call .result on operation ",
+ std::string_view(name.data, name.length), " which has ",
+ numResults,
+ " results (it is only valid for operations with a "
+ "single result)")
+ .c_str());
}
return mlirOperationGetResult(operation, 0);
}
@@ -1625,20 +1615,16 @@ nb::object PyOpView::buildGeneric(
regions = opMinRegionCount;
}
if (*regions < opMinRegionCount) {
- throw nb::value_error(
- (llvm::Twine("Operation \"") + name + "\" requires a minimum of " +
- llvm::Twine(opMinRegionCount) +
- " regions but was built with regions=" + llvm::Twine(*regions))
- .str()
- .c_str());
+ throw nb::value_error(join("Operation \"", name,
+ "\" requires a minimum of ", opMinRegionCount,
+ " regions but was built with regions=", *regions)
+ .c_str());
}
if (opHasNoVariadicRegions && *regions > opMinRegionCount) {
- throw nb::value_error(
- (llvm::Twine("Operation \"") + name + "\" requires a maximum of " +
- llvm::Twine(opMinRegionCount) +
- " regions but was built with regions=" + llvm::Twine(*regions))
- .str()
- .c_str());
+ throw nb::value_error(join("Operation \"", name,
+ "\" requires a maximum of ", opMinRegionCount,
+ " regions but was built with regions=", *regions)
+ .c_str());
}
// Unpack results.
@@ -1649,7 +1635,7 @@ nb::object PyOpView::buildGeneric(
}
// Unpack operands.
- llvm::SmallVector<MlirValue, 4> operands;
+ std::vector<MlirValue> operands;
operands.reserve(operands.size());
if (operandSegmentSpecObj.is_none()) {
// Non-sized operand unpacking.
@@ -1657,10 +1643,9 @@ nb::object PyOpView::buildGeneric(
try {
operands.push_back(getOpResultOrValue(it.value()));
} catch (nb::builtin_exception &err) {
- throw nb::value_error((llvm::Twine("Operand ") +
- llvm::Twine(it.index()) + " of operation \"" +
- name + "\" must be a Value (" + err.what() + ")")
- .str()
+ throw nb::value_error(join("Operand ", it.index(), " of operation \"",
+ name, "\" must be a Value (", err.what(),
+ ")")
.c_str());
}
}
@@ -1668,13 +1653,10 @@ nb::object PyOpView::buildGeneric(
// Sized operand unpacking.
auto operandSegmentSpec = nb::cast<std::vector<int>>(operandSegmentSpecObj);
if (operandSegmentSpec.size() != operandList.size()) {
- throw nb::value_error((llvm::Twine("Operation \"") + name +
- "\" requires " +
- llvm::Twine(operandSegmentSpec.size()) +
- "operand segments but was provided " +
- llvm::Twine(operandList.size()))
- .str()
- .c_str());
+ throw nb::value_error(
+ join("Operation \"", name, "\" requires ", operandSegmentSpec.size(),
+ "operand segments but was provided ", operandList.size())
+ .c_str());
}
operandSegmentLengths.reserve(operandList.size());
for (const auto &it :
@@ -1688,11 +1670,9 @@ nb::object PyOpView::buildGeneric(
operands.push_back(getOpResultOrValue(operand));
} catch (nb::builtin_exception &err) {
- throw nb::value_error((llvm::Twine("Operand ") +
- llvm::Twine(it.index()) +
- " of operation \"" + name +
- "\" must be a Value (" + err.what() + ")")
- .str()
+ throw nb::value_error(join("Operand ", it.index(),
+ " of operation \"", name,
+ "\" must be a Value (", err.what(), ")")
.c_str());
}
@@ -1702,10 +1682,8 @@ nb::object PyOpView::buildGeneric(
operandSegmentLengths.push_back(0);
} else {
throw nb::value_error(
- (llvm::Twine("Operand ") + llvm::Twine(it.index()) +
- " of operation \"" + name +
- "\" must be a Value (was None and operand is not optional)")
- .str()
+ join("Operand ", it.index(), " of operation \"", name,
+ "\" must be a Value (was None and operand is not optional)")
.c_str());
}
} else if (segmentSpec == -1) {
@@ -1726,11 +1704,9 @@ nb::object PyOpView::buildGeneric(
// NOTE: Sloppy to be using a catch-all here, but there are at least
// three
diff erent unrelated exceptions that can be thrown in the
// above "casts". Just keep the scope above small and catch them all.
- throw nb::value_error((llvm::Twine("Operand ") +
- llvm::Twine(it.index()) + " of operation \"" +
- name + "\" must be a Sequence of Values (" +
- err.what() + ")")
- .str()
+ throw nb::value_error(join("Operand ", it.index(), " of operation \"",
+ name, "\" must be a Sequence of Values (",
+ err.what(), ")")
.c_str());
}
} else {
@@ -1776,7 +1752,8 @@ nb::object PyOpView::buildGeneric(
// Delegate to create.
return PyOperation::create(name,
/*results=*/std::move(resultTypes),
- /*operands=*/operands,
+ /*operands=*/operands.data(),
+ /*numOperands=*/operands.size(),
/*attributes=*/std::move(attributes),
/*successors=*/std::move(successors),
/*regions=*/*regions, location, maybeIp,
@@ -2071,7 +2048,7 @@ nb::object PySymbolTable::dunderGetItem(const std::string &name) {
symbolTable, mlirStringRefCreate(name.data(), name.length()));
if (mlirOperationIsNull(symbol))
throw nb::key_error(
- ("Symbol '" + name + "' not in the symbol table.").c_str());
+ join("Symbol '", name, "' not in the symbol table.").c_str());
return PyOperation::forOperation(operation->getContext(), symbol,
operation.getObject())
@@ -2445,8 +2422,7 @@ bool PyOpAttributeMap::dunderContains(const std::string &name) {
}
void PyOpAttributeMap::forEachAttr(
- MlirOperation op,
- llvm::function_ref<void(MlirStringRef, MlirAttribute)> fn) {
+ MlirOperation op, std::function<void(MlirStringRef, MlirAttribute)> fn) {
intptr_t n = mlirOperationGetNumAttributes(op);
for (intptr_t i = 0; i < n; ++i) {
MlirNamedAttribute na = mlirOperationGetAttribute(op, i);
@@ -2619,7 +2595,7 @@ MlirLocation tracebackToLocation(MlirContext ctx) {
PyCodeObject *code = PyFrame_GetCode(pyFrame);
auto fileNameStr =
nb::cast<std::string>(nb::borrow<nb::str>(code->co_filename));
- llvm::StringRef fileName(fileNameStr);
+ std::string_view fileName(fileNameStr);
if (!PyGlobals::get().getTracebackLoc().isUserTracebackFilename(fileName))
continue;
@@ -2627,14 +2603,14 @@ MlirLocation tracebackToLocation(MlirContext ctx) {
#if PY_VERSION_HEX < 0x030B00F0
std::string name =
nb::cast<std::string>(nb::borrow<nb::str>(code->co_name));
- llvm::StringRef funcName(name);
+ std::string_view funcName(name);
int startLine = PyFrame_GetLineNumber(pyFrame);
MlirLocation loc =
mlirLocationFileLineColGet(ctx, wrap(fileName), startLine, 0);
#else
std::string name =
nb::cast<std::string>(nb::borrow<nb::str>(code->co_qualname));
- llvm::StringRef funcName(name);
+ std::string_view funcName(name);
int startLine, startCol, endLine, endCol;
int lasti = PyFrame_GetLasti(pyFrame);
if (!PyCode_Addr2Location(code, lasti, &startLine, &startCol, &endLine,
@@ -2954,7 +2930,7 @@ void populateIRCore(nb::module_ &m) {
self.get(), {name.data(), name.size()});
if (mlirDialectIsNull(dialect)) {
throw nb::value_error(
- (Twine("Dialect '") + name + "' not found").str().c_str());
+ join("Dialect '", name, "' not found").c_str());
}
return PyDialectDescriptor(self.getRef(), dialect);
},
@@ -3259,7 +3235,7 @@ void populateIRCore(nb::module_ &m) {
[](const std::vector<PyLocation> &pyLocations,
std::optional<PyAttribute> metadata,
DefaultingPyMlirContext context) {
- llvm::SmallVector<MlirLocation, 4> locations;
+ std::vector<MlirLocation> locations;
locations.reserve(pyLocations.size());
for (auto &pyLocation : pyLocations)
locations.push_back(pyLocation.get());
@@ -3763,7 +3739,7 @@ void populateIRCore(nb::module_ &m) {
const nb::object &maybeIp,
bool inferType) -> nb::typed<nb::object, PyOperation> {
// Unpack/validate operands.
- llvm::SmallVector<MlirValue, 4> mlirOperands;
+ std::vector<MlirValue> mlirOperands;
if (operands) {
mlirOperands.reserve(operands->size());
for (PyValue *operand : *operands) {
@@ -3774,9 +3750,9 @@ void populateIRCore(nb::module_ &m) {
}
PyLocation pyLoc = maybeGetTracebackLocation(location);
- return PyOperation::create(name, results, mlirOperands, attributes,
- successors, regions, pyLoc, maybeIp,
- inferType);
+ return PyOperation::create(
+ name, results, mlirOperands.data(), mlirOperands.size(),
+ attributes, successors, regions, pyLoc, maybeIp, inferType);
},
"name"_a, "results"_a = nb::none(), "operands"_a = nb::none(),
"attributes"_a = nb::none(), "successors"_a = nb::none(),
@@ -3944,8 +3920,8 @@ void populateIRCore(nb::module_ &m) {
mlirIdentifierStr(mlirOperationGetName(*parsed.get()));
std::string_view parsedOpName(identifier.data, identifier.length);
if (clsOpName != parsedOpName)
- throw MLIRError(Twine("Expected a '") + clsOpName + "' op, got: '" +
- parsedOpName + "'");
+ throw MLIRError(join("Expected a '", clsOpName, "' op, got: '",
+ parsedOpName, "'"));
return PyOpView::constructDerived(cls, parsed.getObject());
},
"cls"_a, "source"_a, nb::kw_only(), "source_name"_a = "",
@@ -4477,8 +4453,7 @@ void populateIRCore(nb::module_ &m) {
if (!mlirTypeIDIsNull(mlirTypeID))
return PyTypeID(mlirTypeID);
auto origRepr = nb::cast<std::string>(nb::repr(nb::cast(self)));
- throw nb::value_error(
- (origRepr + llvm::Twine(" has no typeid.")).str().c_str());
+ throw nb::value_error(join(origRepr, " has no typeid.").c_str());
},
"Returns the `TypeID` of the `Type`, or raises `ValueError` if "
"`Type` has no "
@@ -4670,8 +4645,8 @@ void populateIRCore(nb::module_ &m) {
.def(
"replace_all_uses_except",
[](PyValue &self, PyValue &with, const nb::list &exceptions) {
- // Convert Python list to a SmallVector of MlirOperations
- llvm::SmallVector<MlirOperation> exceptionOps;
+ // Convert Python list to a std::vector of MlirOperations
+ std::vector<MlirOperation> exceptionOps;
for (nb::handle exception : exceptions) {
exceptionOps.push_back(nb::cast<PyOperation &>(exception).get());
}
@@ -4692,8 +4667,8 @@ void populateIRCore(nb::module_ &m) {
"replace_all_uses_except",
[](PyValue &self, PyValue &with,
std::vector<PyOperation> &exceptions) {
- // Convert Python list to a SmallVector of MlirOperations
- llvm::SmallVector<MlirOperation> exceptionOps;
+ // Convert Python list to a std::vector of MlirOperations
+ std::vector<MlirOperation> exceptionOps;
for (PyOperation &exception : exceptions)
exceptionOps.push_back(exception);
mlirValueReplaceAllUsesExcept(
More information about the Mlir-commits
mailing list