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