[Mlir-commits] [mlir] [mlir] Make remove-dead-values can delate useless function (PR #161471)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Tue Sep 30 18:56:18 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-core
Author: lonely eagle (linuxlonelyeagle)
<details>
<summary>Changes</summary>
Fix https://github.com/llvm/llvm-project/issues/158760. If a private functionOpInterface has no users and there is no callOpInterface in its region, it is a useless function, and the remove-dead-values pass will delete this function.
---
Full diff: https://github.com/llvm/llvm-project/pull/161471.diff
2 Files Affected:
- (modified) mlir/lib/Transforms/RemoveDeadValues.cpp (+15-2)
- (modified) mlir/test/Transforms/remove-dead-values.mlir (+15)
``````````diff
diff --git a/mlir/lib/Transforms/RemoveDeadValues.cpp b/mlir/lib/Transforms/RemoveDeadValues.cpp
index e0c65b0e09774..18c6006f04788 100644
--- a/mlir/lib/Transforms/RemoveDeadValues.cpp
+++ b/mlir/lib/Transforms/RemoveDeadValues.cpp
@@ -297,6 +297,17 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module,
return;
}
+ // If a private function has neither users and function calls, it is a useless
+ // function.
+ SymbolTable::UseRange uses = *funcOp.getSymbolUses(module);
+ auto callSites = funcOp.getFunctionBody().getOps<CallOpInterface>();
+ if (uses.empty() && callSites.empty()) {
+ LDBG() << "Delete function op: "
+ << OpWithFlags(funcOp, OpPrintingFlags().skipRegions());
+ funcOp.erase();
+ return;
+ }
+
// Get the list of unnecessary (non-live) arguments in `nonLiveArgs`.
SmallVector<Value> arguments(funcOp.getArguments());
BitVector nonLiveArgs = markLives(arguments, nonLiveSet, la);
@@ -312,7 +323,6 @@ static void processFuncOp(FunctionOpInterface funcOp, Operation *module,
// Do (2). (Skip creating generic operand cleanup entries for call ops.
// Call arguments will be removed in the call-site specific segment-aware
// cleanup, avoiding generic eraseOperands bitvector mechanics.)
- SymbolTable::UseRange uses = *funcOp.getSymbolUses(module);
for (SymbolTable::SymbolUse use : uses) {
Operation *callOp = use.getUser();
assert(isa<CallOpInterface>(callOp) && "expected a call-like user");
@@ -881,9 +891,12 @@ void RemoveDeadValues::runOnOperation() {
// end of this pass.
RDVFinalCleanupList finalCleanupList;
+ module->walk([&](FunctionOpInterface op) {
+ processFuncOp(op, module, la, deadVals, finalCleanupList);
+ });
module->walk([&](Operation *op) {
if (auto funcOp = dyn_cast<FunctionOpInterface>(op)) {
- processFuncOp(funcOp, module, la, deadVals, finalCleanupList);
+ // The FunctionOpInterface has been processed in advance.
} else if (auto regionBranchOp = dyn_cast<RegionBranchOpInterface>(op)) {
processRegionBranchOp(regionBranchOp, la, deadVals, finalCleanupList);
} else if (auto branchOp = dyn_cast<BranchOpInterface>(op)) {
diff --git a/mlir/test/Transforms/remove-dead-values.mlir b/mlir/test/Transforms/remove-dead-values.mlir
index 56449469dc29f..b8ad762c52ddf 100644
--- a/mlir/test/Transforms/remove-dead-values.mlir
+++ b/mlir/test/Transforms/remove-dead-values.mlir
@@ -649,3 +649,18 @@ func.func @callee(%arg0: index, %arg1: index, %arg2: index) -> index {
%res = call @mutl_parameter(%arg0, %arg1, %arg2) : (index, index, index) -> (index)
return %res : index
}
+
+// -----
+
+// CHECK-NOT: func private @single_private_func
+func.func private @single_private_func(%arg0: i64) -> (i64) {
+ %c0_i64 = arith.constant 0 : i64
+ %2 = arith.cmpi eq, %arg0, %c0_i64 : i64
+ cf.cond_br %2, ^bb1, ^bb2
+ ^bb1: // pred: ^bb0
+ %c1_i64 = arith.constant 1 : i64
+ return %c1_i64 : i64
+ ^bb2: // pred: ^bb0
+ %c3_i64 = arith.constant 3 : i64
+ return %c3_i64 : i64
+}
\ No newline at end of file
``````````
</details>
https://github.com/llvm/llvm-project/pull/161471
More information about the Mlir-commits
mailing list