[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