1 //===- llvm/IR/OptBisect.h - LLVM Bisect support ----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// This file declares the interface for bisecting optimizations.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_IR_OPTBISECT_H
15 #define LLVM_IR_OPTBISECT_H
16 
17 #include "llvm/ADT/StringRef.h"
18 #include <limits>
19 
20 namespace llvm {
21 
22 /// Extensions to this class implement mechanisms to disable passes and
23 /// individual optimizations at compile time.
24 class OptPassGate {
25 public:
26   virtual ~OptPassGate() = default;
27 
28   /// IRDescription is a textual description of the IR unit the pass is running
29   /// over.
30   virtual bool shouldRunPass(const StringRef PassName,
31                              StringRef IRDescription) {
32     return true;
33   }
34 
35   /// isEnabled() should return true before calling shouldRunPass().
36   virtual bool isEnabled() const { return false; }
37 };
38 
39 /// This class implements a mechanism to disable passes and individual
40 /// optimizations at compile time based on a command line option
41 /// (-opt-bisect-limit) in order to perform a bisecting search for
42 /// optimization-related problems.
43 class OptBisect : public OptPassGate {
44 public:
45   /// Default constructor. Initializes the state to "disabled". The bisection
46   /// will be enabled by the cl::opt call-back when the command line option
47   /// is processed.
48   /// Clients should not instantiate this class directly.  All access should go
49   /// through LLVMContext.
50   OptBisect() = default;
51 
52   virtual ~OptBisect() = default;
53 
54   /// Checks the bisect limit to determine if the specified pass should run.
55   ///
56   /// This forwards to checkPass().
57   bool shouldRunPass(const StringRef PassName,
58                      StringRef IRDescription) override;
59 
60   /// isEnabled() should return true before calling shouldRunPass().
61   bool isEnabled() const override { return BisectLimit != Disabled; }
62 
63   /// Set the new optimization limit and reset the counter. Passing
64   /// OptBisect::Disabled disables the limiting.
65   void setLimit(int Limit) {
66     BisectLimit = Limit;
67     LastBisectNum = 0;
68   }
69 
70   /// Checks the bisect limit to determine if the specified pass should run.
71   ///
72   /// If the bisect limit is set to -1, the function prints a message describing
73   /// the pass and the bisect number assigned to it and return true.  Otherwise,
74   /// the function prints a message with the bisect number assigned to the
75   /// pass and indicating whether or not the pass will be run and return true if
76   /// the bisect limit has not yet been exceeded or false if it has.
77   ///
78   /// Most passes should not call this routine directly. Instead, they are
79   /// called through helper routines provided by the pass base classes.  For
80   /// instance, function passes should call FunctionPass::skipFunction().
81   bool checkPass(const StringRef PassName, const StringRef TargetDesc);
82 
83   static const int Disabled = std::numeric_limits<int>::max();
84 
85 private:
86   int BisectLimit = Disabled;
87   int LastBisectNum = 0;
88 };
89 
90 /// Singleton instance of the OptBisect class, so multiple pass managers don't
91 /// need to coordinate their uses of OptBisect.
92 OptPassGate &getGlobalPassGate();
93 
94 } // end namespace llvm
95 
96 #endif // LLVM_IR_OPTBISECT_H
97