xref: /llvm-project/bolt/include/bolt/Passes/RegAnalysis.h (revision 4c106cfdf7cf7eec861ad3983a3dd9a9e8f3a8ae)
1 //===- bolt/Passes/RegAnalysis.h --------------------------------*- 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 #ifndef BOLT_PASSES_REGANALYSIS_H
10 #define BOLT_PASSES_REGANALYSIS_H
11 
12 #include "llvm/ADT/BitVector.h"
13 #include <cstdint>
14 #include <map>
15 
16 namespace llvm {
17 class MCInst;
18 
19 namespace bolt {
20 class BinaryContext;
21 class BinaryFunction;
22 class BinaryFunctionCallGraph;
23 
24 /// Determine the set of registers read or clobbered for each instruction
25 /// in a BinaryFunction. If the instruction is a call, this analysis rely on
26 /// a call graph traversal to accurately extract the set of registers touched
27 /// after the call returns.
28 class RegAnalysis {
29 public:
30   /// Compute the set of registers \p Func may read from during its execution.
31   BitVector getFunctionUsedRegsList(const BinaryFunction *Func);
32 
33   /// Compute the set of registers \p Func may write to during its execution,
34   /// starting at the point when it is called up until when it returns. Returns
35   /// a BitVector the size of the target number of registers, representing the
36   /// set of clobbered registers.
37   BitVector getFunctionClobberList(const BinaryFunction *Func);
38 
39   RegAnalysis(BinaryContext &BC, std::map<uint64_t, BinaryFunction> *BFs,
40               BinaryFunctionCallGraph *CG);
41 
42   /// Compute the set of registers \p Inst may read from, marking them in
43   /// \p RegSet. If GetClobbers is true, the set set the instr may write to.
44   /// Use the callgraph to fill out this info for calls.
45   void getInstUsedRegsList(const MCInst &Inst, BitVector &RegSet,
46                            bool GetClobbers) const;
47 
48   /// Compute the set of registers \p Inst may write to, marking them in
49   /// \p KillSet. If this is a call, try to get the set of registers the call
50   /// target will write to.
51   void getInstClobberList(const MCInst &Inst, BitVector &KillSet) const;
52 
53   /// Return true iff Vec has a conservative estimation of used/clobbered regs,
54   /// expressing no specific knowledge of reg usage.
55   bool isConservative(BitVector &Vec) const;
56 
57   /// Set what to do when lacking information about a call
58   enum class ConservativeStrategy { CLOBBERS_ALL, CLOBBERS_ABI, CLOBBERS_NONE };
setConservativeStrategy(ConservativeStrategy S)59   void setConservativeStrategy(ConservativeStrategy S) { CS = S; }
60 
61   /// Print stats about the quality of our analysis
62   void printStats();
63 
64 private:
65   BinaryContext &BC;
66 
67   /// Map functions to the set of registers they may overwrite starting at when
68   /// it is called until it returns to the caller.
69   std::map<const BinaryFunction *, BitVector> RegsKilledMap;
70 
71   /// Similar concept above but for registers that are read in that function.
72   std::map<const BinaryFunction *, BitVector> RegsGenMap;
73 
74   /// Analysis stats counters
75   uint64_t NumFunctionsAllClobber{0};
76   uint64_t CountFunctionsAllClobber{0};
77   uint64_t CountDenominator{0};
78 
79   ConservativeStrategy CS;
80 
81   /// Helper function used to get the set of clobbered/used regs whenever
82   /// we know nothing about the function.
83   void beConservative(BitVector &Result) const;
84 };
85 
86 } // namespace bolt
87 } // namespace llvm
88 
89 #endif
90