[Mlir-commits] [mlir] [MLIR][LLVM] Fix memory explosion when converting global variable bodies in ModuleTranslation (PR #82708)
Xiang Li
llvmlistbot at llvm.org
Sat Feb 24 09:38:03 PST 2024
================
@@ -1042,17 +1046,77 @@ LogicalResult ModuleTranslation::convertGlobals() {
for (auto op : getModuleBody(mlirModule).getOps<LLVM::GlobalOp>()) {
if (Block *initializer = op.getInitializerBlock()) {
llvm::IRBuilder<> builder(llvmModule->getContext());
+
+ int numConstantsHit = 0;
+ int numConstantsErased = 0;
+ DenseMap<llvm::ConstantAggregate *, int> constantAggregateUseMap;
+
for (auto &op : initializer->without_terminator()) {
if (failed(convertOperation(op, builder)) ||
!isa<llvm::Constant>(lookupValue(op.getResult(0))))
return emitError(op.getLoc(), "unemittable constant value");
+
+ // When emitting an LLVM constant, a new constant is created and the old
+ // constant may become dangling and take space. We should remove the
+ // dangling constants to avoid memory explosion especially for constant
+ // arrays whose number of elements is large.
+ // Because multiple operations may refer to the same constant, we need
+ // to count the number of uses of each constant array and remove it only
+ // when the count becomes zero.
+ if (op.getNumResults() == 1) {
+ Value result = op.getResult(0);
+ auto cst = dyn_cast<llvm::ConstantAggregate>(lookupValue(result));
+ if (!cst)
+ continue;
+ numConstantsHit++;
+ auto iter = constantAggregateUseMap.find(cst);
+ int numUsers = std::distance(result.use_begin(), result.use_end());
+ if (iter == constantAggregateUseMap.end())
+ constantAggregateUseMap.try_emplace(cst, numUsers);
+ else
+ iter->second += numUsers;
+ }
+ for (Value v : op.getOperands()) {
+ auto cst = dyn_cast<llvm::ConstantAggregate>(lookupValue(v));
+ if (!cst)
+ continue;
+ auto iter = constantAggregateUseMap.find(cst);
+ assert(iter != constantAggregateUseMap.end() && "constant not found");
+ iter->second--;
+ if (iter->second == 0) {
+ cst->removeDeadConstantUsers();
+ if (cst->user_empty()) {
+ cst->destroyConstant();
+ numConstantsErased++;
+ }
+ constantAggregateUseMap.erase(iter);
+ }
+ }
}
----------------
python3kgae wrote:
> Wouldn't it be just a concat of all the strings into a single dense attribute of the right type?
Thanks for this suggestion. It saves a lot of time for create globalOp for each string!
But to create the array of string, I still have to create a lot of insertvalue.
Is it possible to express the following llvm ir with LLVM dialect?
```
@c = dso_local global [7 x i8] c"abcxby\00", align 1
@a = dso_local global [3 x ptr] [ptr @c, ptr getelementptr (i8, ptr @c, i64 2), ptr getelementptr (i8, ptr @c, i64 5)]
```
Then there will be no insertvalue needed.
https://github.com/llvm/llvm-project/pull/82708
More information about the Mlir-commits
mailing list