[llvm] 67a58fa - [FuncSpec] Don't run the solver if there's nothing to do

Sjoerd Meijer via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 13 11:07:23 PDT 2021


Author: Sjoerd Meijer
Date: 2021-10-13T19:05:19+01:00
New Revision: 67a58fa3a687ec7463511f8e447e9ae8a26037fc

URL: https://github.com/llvm/llvm-project/commit/67a58fa3a687ec7463511f8e447e9ae8a26037fc
DIFF: https://github.com/llvm/llvm-project/commit/67a58fa3a687ec7463511f8e447e9ae8a26037fc.diff

LOG: [FuncSpec] Don't run the solver if there's nothing to do

Even if there are no interesting functions, the SCCP solver would still run
before bailing. Now bail earlier, avoid running the solver for nothing.

Differential Revision: https://reviews.llvm.org/D111645

Added: 
    llvm/test/Transforms/FunctionSpecialization/function-specialization-nothing-todo.ll

Modified: 
    llvm/lib/Transforms/IPO/FunctionSpecialization.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
index 8ab5311fd4359..fdb240d581252 100644
--- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
@@ -789,12 +789,27 @@ bool llvm::runFunctionSpecialization(
       Solver.trackValueOfGlobalVariable(&G);
   }
 
+  auto &TrackedFuncs = Solver.getArgumentTrackedFunctions();
+  SmallVector<Function *, 16> FuncDecls(TrackedFuncs.begin(),
+                                        TrackedFuncs.end());
+
+  // No tracked functions, so nothing to do: don't run the solver and remove
+  // the ssa_copy intrinsics that may have been introduced.
+  if (TrackedFuncs.empty()) {
+    removeSSACopy(M);
+    return false;
+  }
+
   // Solve for constants.
   auto RunSCCPSolver = [&](auto &WorkList) {
     bool ResolvedUndefs = true;
 
     while (ResolvedUndefs) {
+      // Not running the solver unnecessary is checked in regression test
+      // nothing-to-do.ll, so if this debug message is changed, this regression
+      // test needs updating too.
       LLVM_DEBUG(dbgs() << "FnSpecialization: Running solver\n");
+
       Solver.solve();
       LLVM_DEBUG(dbgs() << "FnSpecialization: Resolving undefs\n");
       ResolvedUndefs = false;
@@ -815,9 +830,6 @@ bool llvm::runFunctionSpecialization(
     }
   };
 
-  auto &TrackedFuncs = Solver.getArgumentTrackedFunctions();
-  SmallVector<Function *, 16> FuncDecls(TrackedFuncs.begin(),
-                                        TrackedFuncs.end());
 #ifndef NDEBUG
   LLVM_DEBUG(dbgs() << "FnSpecialization: Worklist fn decls:\n");
   for (auto *F : FuncDecls)

diff  --git a/llvm/test/Transforms/FunctionSpecialization/function-specialization-nothing-todo.ll b/llvm/test/Transforms/FunctionSpecialization/function-specialization-nothing-todo.ll
new file mode 100644
index 0000000000000..b707eca22360d
--- /dev/null
+++ b/llvm/test/Transforms/FunctionSpecialization/function-specialization-nothing-todo.ll
@@ -0,0 +1,51 @@
+; REQUIRES: asserts
+; RUN: opt -function-specialization -debug -S < %s 2>&1 | FileCheck %s
+
+; The purpose of this test is to check that we don't run the solver as there's
+; nothing to do here. For a test that doesn't trigger function specialisation,
+; it is intentionally 'big' because we also want to check that the ssa.copy
+; intrinsics that are introduced by the solver are cleaned up if we bail
+; early. Thus, first check the debug messages for the introduction of these
+; intrinsics:
+
+; CHECK: FnSpecialization: Analysing decl: foo
+; CHECK: Found replacement{{.*}} call i32 @llvm.ssa.copy.i32
+; CHECK: Found replacement{{.*}} call i32 @llvm.ssa.copy.i32
+
+; Then, make sure the solver didn't run:
+
+; CHECK-NOT: Running solver
+
+; Finally, check the absence and thus removal of these intrinsics:
+
+; CHECK-LABEL: @foo
+; CHECK-NOT:   call i32 @llvm.ssa.copy.i32
+
+ at N = external dso_local global i32, align 4
+ at B = external dso_local global i32*, align 8
+ at A = external dso_local global i32*, align 8
+
+define dso_local i32 @foo() {
+entry:
+  br label %for.cond
+
+for.cond:
+  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
+  %0 = load i32, i32* @N, align 4
+  %cmp = icmp slt i32 %i.0, %0
+  br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup:
+  ret i32 undef
+
+for.body:
+  %1 = load i32*, i32** @B, align 8
+  %idxprom = sext i32 %i.0 to i64
+  %arrayidx = getelementptr inbounds i32, i32* %1, i64 %idxprom
+  %2 = load i32, i32* %arrayidx, align 4
+  %3 = load i32*, i32** @A, align 8
+  %arrayidx2 = getelementptr inbounds i32, i32* %3, i64 %idxprom
+  store i32 %2, i32* %arrayidx2, align 4
+  %inc = add nsw i32 %i.0, 1
+  br label %for.cond
+}


        


More information about the llvm-commits mailing list