[llvm] Run delta-pass with child process (PR #87647)

Rushi Bhamani via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 5 04:01:27 PDT 2024


https://github.com/rushiraj7677 updated https://github.com/llvm/llvm-project/pull/87647

>From b0235c6d55ccff89044381080d7e20a836c4277f Mon Sep 17 00:00:00 2001
From: rushi <bhamanirushi2121 at gmail.com>
Date: Thu, 4 Apr 2024 20:53:04 +0530
Subject: [PATCH 1/3] adding fork in Deltapass

---
 llvm/test/tools/llvm-reduce/remove-alias.ll |   2 +
 llvm/test/tools/llvm-reduce/remove-bbs.ll   |   2 +
 llvm/tools/llvm-reduce/DeltaManager.cpp     | 102 +++++++++++++++++++-
 3 files changed, 102 insertions(+), 4 deletions(-)

diff --git a/llvm/test/tools/llvm-reduce/remove-alias.ll b/llvm/test/tools/llvm-reduce/remove-alias.ll
index d9ec4f768678ba..1999fb2426e7fe 100644
--- a/llvm/test/tools/llvm-reduce/remove-alias.ll
+++ b/llvm/test/tools/llvm-reduce/remove-alias.ll
@@ -1,6 +1,8 @@
 ; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
 ; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s
 
+; RUN: llvm-reduce --run-delta-in-child --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s
 ; Test handling of 'alias'.
 
 ; CHECK-INTERESTINGNESS: define void @fn3
diff --git a/llvm/test/tools/llvm-reduce/remove-bbs.ll b/llvm/test/tools/llvm-reduce/remove-bbs.ll
index a1fe9a3468d126..cc1c89377d0392 100644
--- a/llvm/test/tools/llvm-reduce/remove-bbs.ll
+++ b/llvm/test/tools/llvm-reduce/remove-bbs.ll
@@ -3,6 +3,8 @@
 ;
 ; RUN: llvm-reduce -abort-on-invalid-reduction --delta-passes=basic-blocks --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
 ; RUN: FileCheck -implicit-check-not=uninteresting %s < %t
+; RUN: llvm-reduce -abort-on-invalid-reduction --run-delta-in-child --delta-passes=basic-blocks --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: FileCheck -implicit-check-not=uninteresting %s < %t
 
 ; CHECK-INTERESTINGNESS: store i32 0
 ; CHECK-INTERESTINGNESS: store i32 1
diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp
index 56e39b8f9316fa..a2099cee4803d3 100644
--- a/llvm/tools/llvm-reduce/DeltaManager.cpp
+++ b/llvm/tools/llvm-reduce/DeltaManager.cpp
@@ -52,6 +52,10 @@
 #include "deltas/StripDebugInfo.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/Support/CommandLine.h"
+#ifndef _WIN32
+#include <sys/wait.h>
+#include <unistd.h>
+#endif
 
 using namespace llvm;
 
@@ -69,6 +73,9 @@ static cl::list<std::string>
                     cl::desc("Delta passes to not run, separated by commas. By "
                              "default, run all delta passes."),
                     cl::cat(LLVMReduceOptions), cl::CommaSeparated);
+static cl::opt<bool> RunEachDeltaPassInChildProcess(
+    "run-delta-in-child", cl::desc("Run each delta pass in new child process."),
+    cl::init(false), cl::cat(LLVMReduceOptions));
 
 #define DELTA_PASSES                                                           \
   do {                                                                         \
@@ -112,7 +119,7 @@ static cl::list<std::string>
     DELTA_PASS("atomic-ordering", reduceAtomicOrderingDeltaPass)               \
     DELTA_PASS("syncscopes", reduceAtomicSyncScopesDeltaPass)                  \
     DELTA_PASS("instruction-flags", reduceInstructionFlagsDeltaPass)           \
-} while (false)
+  } while (false)
 
 #define DELTA_PASSES_MIR                                                       \
   do {                                                                         \
@@ -160,6 +167,86 @@ static void runDeltaPassName(TestRunner &Tester, StringRef PassName) {
   llvm_unreachable("unknown delta pass");
 }
 
+static void runAllDeltaPassesInChild(TestRunner &Tester,
+                                     const SmallStringSet &SkipPass) {
+#ifdef _WIN32
+  errs() << "runAllDeltaPassesInChild() is only available on POSIX systems. \n";
+  return;
+#endif
+
+#define DELTA_PASS(NAME, FUNC)                                                 \
+  if (!SkipPass.count(NAME)) {                                                 \
+    pid_t CPid = fork();                                                       \
+    if (CPid == -1) {                                                          \
+      errs() << "Could not create child process. \n";                          \
+      return;                                                                  \
+    }                                                                          \
+    if (CPid == 0) {                                                           \
+      FUNC(Tester);                                                            \
+    } else {                                                                   \
+      /*parent waits for child to finish.*/                                    \
+      int ReturnStatus;                                                        \
+      waitpid(CPid, &ReturnStatus, 0);                                         \
+      if (ReturnStatus != 0) {                                                 \
+        errs() << "Reduction " << NAME << " failed. \n";                       \
+        exit(ReturnStatus);                                                    \
+      }                                                                        \
+      /* if child finishes fine we kill parent otherwise it will overwrite*/   \
+      /* results to output files.*/                                            \
+      exit(0);                                                                 \
+    }                                                                          \
+  }
+
+  if (Tester.getProgram().isMIR()) {
+    DELTA_PASSES_MIR;
+  } else {
+    DELTA_PASSES;
+  }
+#undef DELTA_PASS
+}
+
+static void runDeltaPassNameInChild(TestRunner &Tester, StringRef PassName) {
+#ifdef _WIN32
+  errs() << "runDeltaPassNameInChild() is only available on POSIX systems. \n";
+  return;
+#endif
+
+#define DELTA_PASS(NAME, FUNC)                                                 \
+  if (PassName == NAME) {                                                      \
+    pid_t CPid = fork();                                                       \
+    if (CPid == -1) {                                                          \
+      errs() << "Could not create child process.\n";                           \
+      return;                                                                  \
+    }                                                                          \
+    if (CPid == 0) {                                                           \
+      FUNC(Tester);                                                            \
+      return;                                                                  \
+    } else {                                                                   \
+      /*parent waits for child to finish.*/                                    \
+      int ReturnStatus;                                                        \
+      waitpid(CPid, &ReturnStatus, 0);                                         \
+      if (ReturnStatus != 0) {                                                 \
+        errs() << "Reduction " << NAME << " failed. \n";                       \
+        exit(ReturnStatus);                                                    \
+      }                                                                        \
+      /* if child finishes fine we kill parent otherwise it will overwrite*/   \
+      /* results to output files.*/                                            \
+      exit(0);                                                                 \
+    }                                                                          \
+  }
+
+  if (Tester.getProgram().isMIR()) {
+    DELTA_PASSES_MIR;
+  } else {
+    DELTA_PASSES;
+  }
+#undef DELTA_PASS
+
+  // We should have errored on unrecognized passes before trying to run
+  // anything.
+  llvm_unreachable("unknown delta pass");
+}
+
 void llvm::printDeltaPasses(raw_ostream &OS) {
   OS << "Delta passes (pass to `--delta-passes=` as a comma separated list):\n";
 #define DELTA_PASS(NAME, FUNC) OS << "  " << NAME << "\n";
@@ -215,11 +302,18 @@ void llvm::runDeltaPasses(TestRunner &Tester, int MaxPassIterations) {
 
   for (int Iter = 0; Iter < MaxPassIterations; ++Iter) {
     if (DeltaPasses.empty()) {
-      runAllDeltaPasses(Tester, SkipPassSet);
+      if (!RunEachDeltaPassInChildProcess)
+        runAllDeltaPasses(Tester, SkipPassSet);
+      else
+        runAllDeltaPassesInChild(Tester, SkipPassSet);
     } else {
       for (StringRef PassName : DeltaPasses) {
-        if (!SkipPassSet.count(PassName))
-          runDeltaPassName(Tester, PassName);
+        if (!SkipPassSet.count(PassName)) {
+          if (!RunEachDeltaPassInChildProcess)
+            runDeltaPassName(Tester, PassName);
+          else
+            runDeltaPassNameInChild(Tester, PassName);
+        }
       }
     }
 

>From 18b180f52c00fb3063e7b3bb7f3e6eb438bd3244 Mon Sep 17 00:00:00 2001
From: Vivek Pandya <vivekvpandya at gmail.com>
Date: Fri, 5 Apr 2024 16:16:23 +0530
Subject: [PATCH 2/3] Add missing ifndef guard for windows.

---
 llvm/tools/llvm-reduce/DeltaManager.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp
index a2099cee4803d3..ee9d275f7c2f49 100644
--- a/llvm/tools/llvm-reduce/DeltaManager.cpp
+++ b/llvm/tools/llvm-reduce/DeltaManager.cpp
@@ -174,6 +174,7 @@ static void runAllDeltaPassesInChild(TestRunner &Tester,
   return;
 #endif
 
+#ifndef _WIN32
 #define DELTA_PASS(NAME, FUNC)                                                 \
   if (!SkipPass.count(NAME)) {                                                 \
     pid_t CPid = fork();                                                       \
@@ -203,6 +204,7 @@ static void runAllDeltaPassesInChild(TestRunner &Tester,
     DELTA_PASSES;
   }
 #undef DELTA_PASS
+#endif
 }
 
 static void runDeltaPassNameInChild(TestRunner &Tester, StringRef PassName) {
@@ -211,6 +213,7 @@ static void runDeltaPassNameInChild(TestRunner &Tester, StringRef PassName) {
   return;
 #endif
 
+#ifndef _WIN32
 #define DELTA_PASS(NAME, FUNC)                                                 \
   if (PassName == NAME) {                                                      \
     pid_t CPid = fork();                                                       \
@@ -241,6 +244,7 @@ static void runDeltaPassNameInChild(TestRunner &Tester, StringRef PassName) {
     DELTA_PASSES;
   }
 #undef DELTA_PASS
+#endif
 
   // We should have errored on unrecognized passes before trying to run
   // anything.

>From 9cb5ad31b1613f5b7525f57a5c97977f47fbb6f8 Mon Sep 17 00:00:00 2001
From: Vivek Pandya <vivekvpandya at gmail.com>
Date: Fri, 5 Apr 2024 16:27:26 +0530
Subject: [PATCH 3/3] Add separate tests and disable them on windows

---
 llvm/test/tools/llvm-reduce/remove-alias.ll   |  2 -
 llvm/test/tools/llvm-reduce/remove-bbs.ll     |  2 -
 .../llvm-reduce/run-all-delta-in-child.ll     | 53 +++++++++++++++++++
 .../llvm-reduce/run-single-delta-in-child.ll  | 37 +++++++++++++
 4 files changed, 90 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/tools/llvm-reduce/run-all-delta-in-child.ll
 create mode 100644 llvm/test/tools/llvm-reduce/run-single-delta-in-child.ll

diff --git a/llvm/test/tools/llvm-reduce/remove-alias.ll b/llvm/test/tools/llvm-reduce/remove-alias.ll
index 1999fb2426e7fe..d9ec4f768678ba 100644
--- a/llvm/test/tools/llvm-reduce/remove-alias.ll
+++ b/llvm/test/tools/llvm-reduce/remove-alias.ll
@@ -1,8 +1,6 @@
 ; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
 ; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s
 
-; RUN: llvm-reduce --run-delta-in-child --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
-; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s
 ; Test handling of 'alias'.
 
 ; CHECK-INTERESTINGNESS: define void @fn3
diff --git a/llvm/test/tools/llvm-reduce/remove-bbs.ll b/llvm/test/tools/llvm-reduce/remove-bbs.ll
index cc1c89377d0392..a1fe9a3468d126 100644
--- a/llvm/test/tools/llvm-reduce/remove-bbs.ll
+++ b/llvm/test/tools/llvm-reduce/remove-bbs.ll
@@ -3,8 +3,6 @@
 ;
 ; RUN: llvm-reduce -abort-on-invalid-reduction --delta-passes=basic-blocks --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
 ; RUN: FileCheck -implicit-check-not=uninteresting %s < %t
-; RUN: llvm-reduce -abort-on-invalid-reduction --run-delta-in-child --delta-passes=basic-blocks --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
-; RUN: FileCheck -implicit-check-not=uninteresting %s < %t
 
 ; CHECK-INTERESTINGNESS: store i32 0
 ; CHECK-INTERESTINGNESS: store i32 1
diff --git a/llvm/test/tools/llvm-reduce/run-all-delta-in-child.ll b/llvm/test/tools/llvm-reduce/run-all-delta-in-child.ll
new file mode 100644
index 00000000000000..05b3020279e5a3
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/run-all-delta-in-child.ll
@@ -0,0 +1,53 @@
+; UNSUPPORTED: target={{.-windows.}}
+; RUN: llvm-reduce --run-delta-in-child --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s
+
+; Test handling of 'alias'.
+
+; CHECK-INTERESTINGNESS: define void @fn3
+
+; CHECK-FINAL-NOT: = {{.*}} global
+; CHECK-FINAL-NOT: = alias
+
+; CHECK-FINAL-NOT: @llvm.used
+; CHECK-FINAL-NOT: @llvm.compiler.used
+
+; CHECK-FINAL-NOT: define void @fn1
+; CHECK-FINAL-NOT: define void @fn2
+; CHECK-FINAL: define void @fn3
+; CHECK-FINAL-NOT: define void @fn4
+
+ at g1 = global [ 4 x i32 ] zeroinitializer
+ at g2 = global [ 4 x i32 ] zeroinitializer
+
+@"$a1" = alias void (), ptr @fn1
+@"$a2" = alias void (), ptr @fn2
+@"$a3" = alias void (), ptr @fn3
+@"$a4" = alias void (), ptr @fn4
+
+@"$a5" = alias i64, getelementptr ([ 4 x i32 ], ptr @g1, i32 0, i32 1)
+@"$a6" = alias i64, getelementptr ([ 4 x i32 ], ptr @g2, i32 0, i32 1)
+
+ at llvm.used = appending global [1 x ptr] [
+   ptr @"$a5"
+], section "llvm.metadata"
+
+ at llvm.compiler.used = appending global [1 x ptr] [
+   ptr @"$a6"
+], section "llvm.metadata"
+
+define void @fn1() {
+  ret void
+}
+
+define void @fn2() {
+  ret void
+}
+
+define void @fn3() {
+  ret void
+}
+
+define void @fn4() {
+  ret void
+}
diff --git a/llvm/test/tools/llvm-reduce/run-single-delta-in-child.ll b/llvm/test/tools/llvm-reduce/run-single-delta-in-child.ll
new file mode 100644
index 00000000000000..9f929edc111b0f
--- /dev/null
+++ b/llvm/test/tools/llvm-reduce/run-single-delta-in-child.ll
@@ -0,0 +1,37 @@
+; UNSUPPORTED: target={{.-windows.}}
+; Test that llvm-reduce can remove uninteresting Basic Blocks, and remove them from instructions (i.e. SwitchInst, BranchInst and IndirectBrInst)
+; Note: if an uninteresting BB is the default case for a switch, the instruction is removed altogether (since the default case cannot be replaced)
+;
+; RUN: llvm-reduce -abort-on-invalid-reduction --run-delta-in-child --delta-passes=basic-blocks --test FileCheck --test-arg --check-prefix=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: FileCheck -implicit-check-not=uninteresting %s < %t
+
+; CHECK-INTERESTINGNESS: store i32 0
+; CHECK-INTERESTINGNESS: store i32 1
+; CHECK-INTERESTINGNESS: store i32 2
+
+define void @main() {
+interesting:
+  store i32 0, ptr null
+  ; CHECK-NOT: switch i32 0, label %uninteresting
+  switch i32 0, label %uninteresting [
+    i32 1, label %interesting2
+  ]
+
+uninteresting:
+  ret void
+
+interesting2:
+  store i32 1, ptr null
+  ; CHECK: switch i32 1, label %interesting3
+  switch i32 1, label %interesting3 [
+    ; CHECK-NOT: i32 0, label %uninteresting
+    i32 0, label %uninteresting
+    ; CHECK: i32 1, label %interesting3
+    i32 1, label %interesting3
+  ]
+
+interesting3:
+  store i32 2, ptr null
+  ; CHECK: br label %interesting2
+  br i1 true, label %interesting2, label %uninteresting
+}



More information about the llvm-commits mailing list