1 //=- FunctionPropertiesAnalysis.h - Function Properties Analysis --*- 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 // This file defines the FunctionPropertiesInfo and FunctionPropertiesAnalysis
10 // classes used to extract function properties.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_ANALYSIS_FUNCTIONPROPERTIESANALYSIS_H
15 #define LLVM_ANALYSIS_FUNCTIONPROPERTIESANALYSIS_H
16 
17 #include "llvm/ADT/SmallPtrSet.h"
18 #include "llvm/ADT/iterator_range.h"
19 #include "llvm/IR/InstrTypes.h"
20 #include "llvm/IR/PassManager.h"
21 
22 namespace llvm {
23 class Function;
24 class LoopInfo;
25 
26 class FunctionPropertiesInfo {
27   friend class FunctionPropertiesUpdater;
28   void updateForBB(const BasicBlock &BB, int64_t Direction);
29   void updateAggregateStats(const Function &F, const LoopInfo &LI);
30   void reIncludeBB(const BasicBlock &BB);
31 
32 public:
33   static FunctionPropertiesInfo
34   getFunctionPropertiesInfo(const Function &F, FunctionAnalysisManager &FAM);
35 
36   bool operator==(const FunctionPropertiesInfo &FPI) const {
37     return std::memcmp(this, &FPI, sizeof(FunctionPropertiesInfo)) == 0;
38   }
39 
40   bool operator!=(const FunctionPropertiesInfo &FPI) const {
41     return !(*this == FPI);
42   }
43 
44   void print(raw_ostream &OS) const;
45 
46   /// Number of basic blocks
47   int64_t BasicBlockCount = 0;
48 
49   /// Number of blocks reached from a conditional instruction, or that are
50   /// 'cases' of a SwitchInstr.
51   // FIXME: We may want to replace this with a more meaningful metric, like
52   // number of conditionally executed blocks:
53   // 'if (a) s();' would be counted here as 2 blocks, just like
54   // 'if (a) s(); else s2(); s3();' would.
55   int64_t BlocksReachedFromConditionalInstruction = 0;
56 
57   /// Number of uses of this function, plus 1 if the function is callable
58   /// outside the module.
59   int64_t Uses = 0;
60 
61   /// Number of direct calls made from this function to other functions
62   /// defined in this module.
63   int64_t DirectCallsToDefinedFunctions = 0;
64 
65   // Load Instruction Count
66   int64_t LoadInstCount = 0;
67 
68   // Store Instruction Count
69   int64_t StoreInstCount = 0;
70 
71   // Maximum Loop Depth in the Function
72   int64_t MaxLoopDepth = 0;
73 
74   // Number of Top Level Loops in the Function
75   int64_t TopLevelLoopCount = 0;
76 
77   // All non-debug instructions
78   int64_t TotalInstructionCount = 0;
79 };
80 
81 // Analysis pass
82 class FunctionPropertiesAnalysis
83     : public AnalysisInfoMixin<FunctionPropertiesAnalysis> {
84 
85 public:
86   static AnalysisKey Key;
87 
88   using Result = const FunctionPropertiesInfo;
89 
90   FunctionPropertiesInfo run(Function &F, FunctionAnalysisManager &FAM);
91 };
92 
93 /// Printer pass for the FunctionPropertiesAnalysis results.
94 class FunctionPropertiesPrinterPass
95     : public PassInfoMixin<FunctionPropertiesPrinterPass> {
96   raw_ostream &OS;
97 
98 public:
99   explicit FunctionPropertiesPrinterPass(raw_ostream &OS) : OS(OS) {}
100 
101   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
102 };
103 
104 /// Correctly update FunctionPropertiesInfo post-inlining. A
105 /// FunctionPropertiesUpdater keeps the state necessary for tracking the changes
106 /// llvm::InlineFunction makes. The idea is that inlining will at most modify
107 /// a few BBs of the Caller (maybe the entry BB and definitely the callsite BB)
108 /// and potentially affect exception handling BBs in the case of invoke
109 /// inlining.
110 class FunctionPropertiesUpdater {
111 public:
112   FunctionPropertiesUpdater(FunctionPropertiesInfo &FPI, const CallBase &CB);
113 
114   void finish(FunctionAnalysisManager &FAM) const;
115 
116 private:
117   FunctionPropertiesInfo &FPI;
118   const BasicBlock &CallSiteBB;
119   const Function &Caller;
120 
121   DenseSet<const BasicBlock *> Successors;
122 };
123 } // namespace llvm
124 #endif // LLVM_ANALYSIS_FUNCTIONPROPERTIESANALYSIS_H
125