[llvm] [BOLT][NFC] Run ADRRelaxationPass in parallel (PR #67831)

Vladislav Khmelevsky via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 29 10:50:56 PDT 2023


https://github.com/yota9 updated https://github.com/llvm/llvm-project/pull/67831

>From 7edc308c519d234f0f90f0c633f28fb9af1aed65 Mon Sep 17 00:00:00 2001
From: Vladislav Khmelevsky <och95 at yandex.ru>
Date: Fri, 29 Sep 2023 20:22:09 +0400
Subject: [PATCH] [BOLT][NFC] Run ADRRelaxationPass in parallel

To do this:
1. Protect BC.Ctx with mutex
2. Don't call exit from thread, please check the reason comment near
PassFailed variable definition. The other option would be call _Exit
instead of exit, but I think we shall call destructors properly.
---
 bolt/lib/Passes/ADRRelaxationPass.cpp | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/bolt/lib/Passes/ADRRelaxationPass.cpp b/bolt/lib/Passes/ADRRelaxationPass.cpp
index 76924d96fcf9bc5..7b612cbf6572bd3 100644
--- a/bolt/lib/Passes/ADRRelaxationPass.cpp
+++ b/bolt/lib/Passes/ADRRelaxationPass.cpp
@@ -29,7 +29,16 @@ static cl::opt<bool>
 namespace llvm {
 namespace bolt {
 
+// We don't exit directly from runOnFunction since it would call ThreadPool
+// destructor which might result in internal assert if we're not finished
+// creating async jobs on the moment of exit. So we're finishing all parallel
+// jobs and checking the exit flag after it.
+static bool PassFailed = false;
+
 void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
+  if (PassFailed)
+    return;
+
   BinaryContext &BC = BF.getBinaryContext();
   for (BinaryBasicBlock &BB : BF) {
     for (auto It = BB.begin(); It != BB.end(); ++It) {
@@ -54,8 +63,12 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
       MCPhysReg Reg;
       BC.MIB->getADRReg(Inst, Reg);
       int64_t Addend = BC.MIB->getTargetAddend(Inst);
-      InstructionListType Addr =
-          BC.MIB->materializeAddress(Symbol, BC.Ctx.get(), Reg, Addend);
+      InstructionListType Addr;
+
+      {
+        auto L = BC.scopeLock();
+        Addr = BC.MIB->materializeAddress(Symbol, BC.Ctx.get(), Reg, Addend);
+      }
 
       if (It != BB.begin() && BC.MIB->isNoop(*std::prev(It))) {
         It = BB.eraseInstruction(std::prev(It));
@@ -68,7 +81,8 @@ void ADRRelaxationPass::runOnFunction(BinaryFunction &BF) {
         errs() << formatv("BOLT-ERROR: Cannot relax adr in non-simple function "
                           "{0}. Can't proceed in current mode.\n",
                           BF.getOneName());
-        exit(1);
+        PassFailed = true;
+        return;
       }
       It = BB.replaceInstruction(It, Addr);
     }
@@ -85,7 +99,10 @@ void ADRRelaxationPass::runOnFunctions(BinaryContext &BC) {
 
   ParallelUtilities::runOnEachFunction(
       BC, ParallelUtilities::SchedulingPolicy::SP_TRIVIAL, WorkFun, nullptr,
-      "ADRRelaxationPass", /* ForceSequential */ true);
+      "ADRRelaxationPass");
+
+  if (PassFailed)
+    exit(1);
 }
 
 } // end namespace bolt



More information about the llvm-commits mailing list