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/iterator_range.h"
18#include "llvm/IR/InstrTypes.h"
19#include "llvm/IR/PassManager.h"
20
21namespace llvm {
22class DominatorTree;
23class Function;
24class LoopInfo;
25
26class 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
32public:
33 static FunctionPropertiesInfo
34 getFunctionPropertiesInfo(const Function &F, const DominatorTree &DT,
35 const LoopInfo &LI);
36
37 static FunctionPropertiesInfo
38 getFunctionPropertiesInfo(Function &F, FunctionAnalysisManager &FAM);
39
40 bool operator==(const FunctionPropertiesInfo &FPI) const {
41 return std::memcmp(s1: this, s2: &FPI, n: sizeof(FunctionPropertiesInfo)) == 0;
42 }
43
44 bool operator!=(const FunctionPropertiesInfo &FPI) const {
45 return !(*this == FPI);
46 }
47
48 void print(raw_ostream &OS) const;
49
50 /// Number of basic blocks
51 int64_t BasicBlockCount = 0;
52
53 /// Number of blocks reached from a conditional instruction, or that are
54 /// 'cases' of a SwitchInstr.
55 // FIXME: We may want to replace this with a more meaningful metric, like
56 // number of conditionally executed blocks:
57 // 'if (a) s();' would be counted here as 2 blocks, just like
58 // 'if (a) s(); else s2(); s3();' would.
59 int64_t BlocksReachedFromConditionalInstruction = 0;
60
61 /// Number of uses of this function, plus 1 if the function is callable
62 /// outside the module.
63 int64_t Uses = 0;
64
65 /// Number of direct calls made from this function to other functions
66 /// defined in this module.
67 int64_t DirectCallsToDefinedFunctions = 0;
68
69 // Load Instruction Count
70 int64_t LoadInstCount = 0;
71
72 // Store Instruction Count
73 int64_t StoreInstCount = 0;
74
75 // Maximum Loop Depth in the Function
76 int64_t MaxLoopDepth = 0;
77
78 // Number of Top Level Loops in the Function
79 int64_t TopLevelLoopCount = 0;
80
81 // All non-debug instructions
82 int64_t TotalInstructionCount = 0;
83
84 // Basic blocks grouped by number of successors.
85 int64_t BasicBlocksWithSingleSuccessor = 0;
86 int64_t BasicBlocksWithTwoSuccessors = 0;
87 int64_t BasicBlocksWithMoreThanTwoSuccessors = 0;
88
89 // Basic blocks grouped by number of predecessors.
90 int64_t BasicBlocksWithSinglePredecessor = 0;
91 int64_t BasicBlocksWithTwoPredecessors = 0;
92 int64_t BasicBlocksWithMoreThanTwoPredecessors = 0;
93
94 // Basic blocks grouped by size as determined by the number of non-debug
95 // instructions that they contain.
96 int64_t BigBasicBlocks = 0;
97 int64_t MediumBasicBlocks = 0;
98 int64_t SmallBasicBlocks = 0;
99
100 // The number of cast instructions inside the function.
101 int64_t CastInstructionCount = 0;
102
103 // The number of floating point instructions inside the function.
104 int64_t FloatingPointInstructionCount = 0;
105
106 // The number of integer instructions inside the function.
107 int64_t IntegerInstructionCount = 0;
108
109 // Operand type couns
110 int64_t ConstantIntOperandCount = 0;
111 int64_t ConstantFPOperandCount = 0;
112 int64_t ConstantOperandCount = 0;
113 int64_t InstructionOperandCount = 0;
114 int64_t BasicBlockOperandCount = 0;
115 int64_t GlobalValueOperandCount = 0;
116 int64_t InlineAsmOperandCount = 0;
117 int64_t ArgumentOperandCount = 0;
118 int64_t UnknownOperandCount = 0;
119
120 // Additional CFG Properties
121 int64_t CriticalEdgeCount = 0;
122 int64_t ControlFlowEdgeCount = 0;
123 int64_t UnconditionalBranchCount = 0;
124
125 // Call related instructions
126 int64_t IntrinsicCount = 0;
127 int64_t DirectCallCount = 0;
128 int64_t IndirectCallCount = 0;
129 int64_t CallReturnsIntegerCount = 0;
130 int64_t CallReturnsFloatCount = 0;
131 int64_t CallReturnsPointerCount = 0;
132 int64_t CallReturnsVectorIntCount = 0;
133 int64_t CallReturnsVectorFloatCount = 0;
134 int64_t CallReturnsVectorPointerCount = 0;
135 int64_t CallWithManyArgumentsCount = 0;
136 int64_t CallWithPointerArgumentCount = 0;
137};
138
139// Analysis pass
140class FunctionPropertiesAnalysis
141 : public AnalysisInfoMixin<FunctionPropertiesAnalysis> {
142
143public:
144 static AnalysisKey Key;
145
146 using Result = const FunctionPropertiesInfo;
147
148 FunctionPropertiesInfo run(Function &F, FunctionAnalysisManager &FAM);
149};
150
151/// Printer pass for the FunctionPropertiesAnalysis results.
152class FunctionPropertiesPrinterPass
153 : public PassInfoMixin<FunctionPropertiesPrinterPass> {
154 raw_ostream &OS;
155
156public:
157 explicit FunctionPropertiesPrinterPass(raw_ostream &OS) : OS(OS) {}
158
159 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
160
161 static bool isRequired() { return true; }
162};
163
164/// Correctly update FunctionPropertiesInfo post-inlining. A
165/// FunctionPropertiesUpdater keeps the state necessary for tracking the changes
166/// llvm::InlineFunction makes. The idea is that inlining will at most modify
167/// a few BBs of the Caller (maybe the entry BB and definitely the callsite BB)
168/// and potentially affect exception handling BBs in the case of invoke
169/// inlining.
170class FunctionPropertiesUpdater {
171public:
172 FunctionPropertiesUpdater(FunctionPropertiesInfo &FPI, CallBase &CB);
173
174 void finish(FunctionAnalysisManager &FAM) const;
175 bool finishAndTest(FunctionAnalysisManager &FAM) const {
176 finish(FAM);
177 return isUpdateValid(F&: Caller, FPI, FAM);
178 }
179
180private:
181 FunctionPropertiesInfo &FPI;
182 BasicBlock &CallSiteBB;
183 Function &Caller;
184
185 static bool isUpdateValid(Function &F, const FunctionPropertiesInfo &FPI,
186 FunctionAnalysisManager &FAM);
187
188 DenseSet<const BasicBlock *> Successors;
189};
190} // namespace llvm
191#endif // LLVM_ANALYSIS_FUNCTIONPROPERTIESANALYSIS_H
192

source code of llvm/include/llvm/Analysis/FunctionPropertiesAnalysis.h