[llvm] [bolt] add support for bisecting bolt opt passes (PR #88758)

via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 15 09:57:45 PDT 2024


https://github.com/yubingex007-a11y created https://github.com/llvm/llvm-project/pull/88758

None

>From 52ebaf4b313039fbb11a614cff3cf0cc99296264 Mon Sep 17 00:00:00 2001
From: "Wang, Qing1" <qing1.wang at intel.com>
Date: Tue, 16 Apr 2024 00:51:04 +0800
Subject: [PATCH] [bolt] add support for bisecting bolt opt passes

---
 bolt/include/bolt/Core/BinaryContext.h  |  7 +++
 bolt/include/bolt/Core/BoltBisect.h     | 60 +++++++++++++++++++++++++
 bolt/include/bolt/Passes/BinaryPasses.h |  2 +
 bolt/lib/Core/BoltBisect.cpp            | 53 ++++++++++++++++++++++
 bolt/lib/Core/CMakeLists.txt            |  1 +
 bolt/lib/Passes/BinaryPasses.cpp        |  8 ++++
 6 files changed, 131 insertions(+)
 create mode 100644 bolt/include/bolt/Core/BoltBisect.h
 create mode 100644 bolt/lib/Core/BoltBisect.cpp

diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h
index 8b1af9e8153925..3b745ab24fdf90 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -16,6 +16,7 @@
 #include "bolt/Core/AddressMap.h"
 #include "bolt/Core/BinaryData.h"
 #include "bolt/Core/BinarySection.h"
+#include "bolt/Core/BoltBisect.h"
 #include "bolt/Core/DebugData.h"
 #include "bolt/Core/JumpTable.h"
 #include "bolt/Core/MCPlusBuilder.h"
@@ -35,6 +36,7 @@
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCSymbol.h"
 #include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/RWMutex.h"
 #include "llvm/Support/raw_ostream.h"
@@ -59,6 +61,7 @@ using namespace object;
 namespace bolt {
 
 class BinaryFunction;
+class BoltBisect;
 
 /// Information on loadable part of the file.
 struct SegmentInfo {
@@ -264,6 +267,10 @@ class BinaryContext {
   void deregisterSectionName(const BinarySection &Section);
 
 public:
+
+  BoltBisect &getBoltBisect() const {
+    return *BoltBisector;
+  }
   static Expected<std::unique_ptr<BinaryContext>>
   createBinaryContext(Triple TheTriple, StringRef InputFileName,
                       SubtargetFeatures *Features, bool IsPIC,
diff --git a/bolt/include/bolt/Core/BoltBisect.h b/bolt/include/bolt/Core/BoltBisect.h
new file mode 100644
index 00000000000000..f989e65ddc00d1
--- /dev/null
+++ b/bolt/include/bolt/Core/BoltBisect.h
@@ -0,0 +1,60 @@
+//===- llvm/IR/BoltBisect.h - LLVM Bisect support ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file declares the interface for bisecting optimizations.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_OPTBISECT_H
+#define LLVM_IR_OPTBISECT_H
+
+#include "llvm/ADT/StringRef.h"
+#include <limits>
+
+namespace llvm {
+
+class BoltPassGate {
+public:
+  virtual ~BoltPassGate() = default;
+
+  virtual bool shouldRunPass(const StringRef PassName) {
+    return true;
+  }
+
+  virtual bool isEnabled() const { return false; }
+};
+
+class BoltBisect : public BoltPassGate {
+public:
+
+  BoltBisect() = default;
+
+  virtual ~BoltBisect() = default;
+
+  bool shouldRunPass(const StringRef PassName) override;
+
+  bool isEnabled() const override { return BisectLimit != Disabled; }
+
+  void setLimit(int Limit) {
+    BisectLimit = Limit;
+    LastBisectNum = 0;
+  }
+
+  static const int Disabled = std::numeric_limits<int>::max();
+
+private:
+  int BisectLimit = Disabled;
+  int LastBisectNum = 0;
+};
+
+BoltPassGate &getGlobalPassGate();
+
+} // end namespace llvm
+
+#endif // LLVM_IR_OPTBISECT_H
diff --git a/bolt/include/bolt/Passes/BinaryPasses.h b/bolt/include/bolt/Passes/BinaryPasses.h
index 8d89ef8b5484f8..d4c85d91b905a3 100644
--- a/bolt/include/bolt/Passes/BinaryPasses.h
+++ b/bolt/include/bolt/Passes/BinaryPasses.h
@@ -34,6 +34,8 @@ class BinaryFunctionPass {
 
   /// Control whether a specific function should be skipped during
   /// optimization.
+  virtual bool skipFunction(const BinaryFunction &BF) const;
+
   virtual bool shouldOptimize(const BinaryFunction &BF) const;
 
 public:
diff --git a/bolt/lib/Core/BoltBisect.cpp b/bolt/lib/Core/BoltBisect.cpp
new file mode 100644
index 00000000000000..11d5556acd1c5c
--- /dev/null
+++ b/bolt/lib/Core/BoltBisect.cpp
@@ -0,0 +1,53 @@
+//===- bolt/Bisect.cpp - LLVM Bisect support -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// This file implements support for a bisecting optimizations based on a
+/// command line option.
+//
+//===----------------------------------------------------------------------===//
+
+#include "bolt/Core/BoltBisect.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
+using namespace llvm;
+
+static BoltBisect &getBoltBisector() {
+  static BoltBisect BoltBisector;
+  return BoltBisector;
+}
+
+static cl::opt<int> BoltBisectLimit("opt-bisect-limit", cl::Hidden,
+                                   cl::init(BoltBisect::Disabled), cl::Optional,
+                                   cl::cb<void, int>([](int Limit) {
+                                     getBoltBisector().setLimit(Limit);
+                                   }),
+                                   cl::desc("Maximum optimization to perform"));
+
+static void printPassMessage(const StringRef &Name, int PassNum,
+                             bool Running) {
+  StringRef Status = Running ? "" : "NOT ";
+  errs() << "BISECT: " << Status << "running pass "
+         << "(" << PassNum << ") " << Name << " on " << "\n";
+}
+
+bool BoltBisect::shouldRunPass(const StringRef PassName) {
+  assert(isEnabled());
+
+  int CurBisectNum = ++LastBisectNum;
+  bool ShouldRun = (BisectLimit == -1 || CurBisectNum <= BisectLimit);
+  printPassMessage(PassName, CurBisectNum, ShouldRun);
+  return ShouldRun;
+}
+
+const int BoltBisect::Disabled;
+
+BoltPassGate &llvm::getGlobalPassGate() { return getBoltBisector(); }
diff --git a/bolt/lib/Core/CMakeLists.txt b/bolt/lib/Core/CMakeLists.txt
index 441df9fe084648..c79a3eec604b9e 100644
--- a/bolt/lib/Core/CMakeLists.txt
+++ b/bolt/lib/Core/CMakeLists.txt
@@ -19,6 +19,7 @@ add_llvm_library(LLVMBOLTCore
   BinaryFunction.cpp
   BinaryFunctionProfile.cpp
   BinarySection.cpp
+  BoltBisect.cpp
   DebugData.cpp
   DebugNames.cpp
   DIEBuilder.cpp
diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp
index c0ba73108f5778..00a15702c39373 100644
--- a/bolt/lib/Passes/BinaryPasses.cpp
+++ b/bolt/lib/Passes/BinaryPasses.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "bolt/Passes/BinaryPasses.h"
+#include "bolt/Core/BoltBisect.h"
 #include "bolt/Core/FunctionLayout.h"
 #include "bolt/Core/ParallelUtilities.h"
 #include "bolt/Passes/ReorderAlgorithm.h"
@@ -229,6 +230,13 @@ static cl::opt<unsigned> TopCalledLimit(
 namespace llvm {
 namespace bolt {
 
+bool BinaryFunctionPass::skipFunction(const BinaryFunction &BF) const {
+  BoltPassGate &Gate = BF.getBinaryContext().getBoltBisect();
+  if (Gate.isEnabled() && !Gate.shouldRunPass(this->getName()))
+    return true;
+  return false;
+}
+
 bool BinaryFunctionPass::shouldOptimize(const BinaryFunction &BF) const {
   return BF.isSimple() && BF.getState() == BinaryFunction::State::CFG &&
          !BF.isIgnored();



More information about the llvm-commits mailing list