Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MLIR][LLVM] Fix memory explosion when converting global variable bod…
…ies in ModuleTranslation (llvm#82708) There is memory explosion when converting the body or initializer region of a large global variable, e.g. a constant array. For example, when translating a constant array of 100000 strings: llvm.mlir.global internal constant @cats_strings() {addr_space = 0 : i32, alignment = 16 : i64} : !llvm.array<100000 x ptr<i8>> { %0 = llvm.mlir.undef : !llvm.array<100000 x ptr<i8>> %1 = llvm.mlir.addressof @om_1 : !llvm.ptr<array<1 x i8>> %2 = llvm.getelementptr %1[0, 0] : (!llvm.ptr<array<1 x i8>>) -> !llvm.ptr<i8> %3 = llvm.insertvalue %2, %0[0] : !llvm.array<100000 x ptr<i8>> %4 = llvm.mlir.addressof @om_2 : !llvm.ptr<array<1 x i8>> %5 = llvm.getelementptr %4[0, 0] : (!llvm.ptr<array<1 x i8>>) -> !llvm.ptr<i8> %6 = llvm.insertvalue %5, %3[1] : !llvm.array<100000 x ptr<i8>> %7 = llvm.mlir.addressof @om_3 : !llvm.ptr<array<1 x i8>> %8 = llvm.getelementptr %7[0, 0] : (!llvm.ptr<array<1 x i8>>) -> !llvm.ptr<i8> %9 = llvm.insertvalue %8, %6[2] : !llvm.array<100000 x ptr<i8>> %10 = llvm.mlir.addressof @om_4 : !llvm.ptr<array<1 x i8>> %11 = llvm.getelementptr %10[0, 0] : (!llvm.ptr<array<1 x i8>>) -> !llvm.ptr<i8> %12 = llvm.insertvalue %11, %9[3] : !llvm.array<100000 x ptr<i8>> ... (ignore the remaining part) } where @om_1, @om_2, ... are string global constants. Each time an operation is converted to LLVM, a new constant is created. When it comes to llvm.insertvalue, a new constant array of 100000 elements is created and the old constant array (input) is not destroyed. This causes memory explosion. We observed that, on a system with 128 GB memory, the translation of 100000 elements got killed due to using up all the memory. On a system with 64 GB, 65536 elements was enough to cause the translation killed. There is a previous patch (https://reviews.llvm.org/D148487) which fix this issue but was reverted for llvm#62802 The old patch checks generated constants and destroyed them if there is no use. But the check of use for the constant is too early, which cause the constant be removed before use. This new patch added a map was added a map to save expected use count for a constant. Then decrease when reach each use. And only erase the constant when the use count reach to zero With new patch, the repro in llvm#62802 finished correctly. commit-id:3cd23a98
- Loading branch information