How to construct a ValueRange from another ValueRange

Hi

I have an mlir::ValueRange and I want to apply a function process to each mlir::Value and generate another mlir::ValueRange. It seems that mlir::ValueRange is a weak reference and does not hold its values. I use std::vector and implement as follows:

mlir::Value process(mlir::Value x);

mlir::ValueRange inputs;
std::vector<mlir::Value> vec;
for (size_t i = 0; i < inputs.size(); i++) {
    vec.push_back(process(inputs[i]));
}
llvm::ArrayRef<mlir::Value> ref(vec.data(), vec.size());
mlir::ValueRange outputs(ref);

This implementation seems kind of stupid. How should I do this correctly?

Thanks in advance

Yes, ValueRange and similar such classes just create a view of the underlying data and do not copy/hold ownership. The user is responsible to make sure that the underlying data stays valid while the ValueRange is used.

Depending upon what you want to do with the processed values, you may need to create a new vector to provide the backing storage like you suggested. If “on-the-fly” processing is ok, you can also see if llvm::map_range works, which can take a ValueRange and the process function and apply it on the fly as the mapped range is iterated.

See also llvm::to_vector, here is a usual pattern: https://github.com/llvm/llvm-project/blob/master/mlir/lib/Dialect/StandardOps/IR/Ops.cpp#L374-L379