Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:12

0001 //=- FunctionPropertiesAnalysis.h - Function Properties Analysis --*- C++ -*-=//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the FunctionPropertiesInfo and FunctionPropertiesAnalysis
0010 // classes used to extract function properties.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_ANALYSIS_FUNCTIONPROPERTIESANALYSIS_H
0015 #define LLVM_ANALYSIS_FUNCTIONPROPERTIESANALYSIS_H
0016 
0017 #include "llvm/ADT/DenseSet.h"
0018 #include "llvm/IR/Dominators.h"
0019 #include "llvm/IR/PassManager.h"
0020 
0021 namespace llvm {
0022 class BasicBlock;
0023 class CallBase;
0024 class DominatorTree;
0025 class Function;
0026 class LoopInfo;
0027 
0028 class FunctionPropertiesInfo {
0029   friend class FunctionPropertiesUpdater;
0030   void updateForBB(const BasicBlock &BB, int64_t Direction);
0031   void updateAggregateStats(const Function &F, const LoopInfo &LI);
0032   void reIncludeBB(const BasicBlock &BB);
0033 
0034 public:
0035   static FunctionPropertiesInfo
0036   getFunctionPropertiesInfo(const Function &F, const DominatorTree &DT,
0037                             const LoopInfo &LI);
0038 
0039   static FunctionPropertiesInfo
0040   getFunctionPropertiesInfo(Function &F, FunctionAnalysisManager &FAM);
0041 
0042   bool operator==(const FunctionPropertiesInfo &FPI) const {
0043     return std::memcmp(this, &FPI, sizeof(FunctionPropertiesInfo)) == 0;
0044   }
0045 
0046   bool operator!=(const FunctionPropertiesInfo &FPI) const {
0047     return !(*this == FPI);
0048   }
0049 
0050   void print(raw_ostream &OS) const;
0051 
0052   /// Number of basic blocks
0053   int64_t BasicBlockCount = 0;
0054 
0055   /// Number of blocks reached from a conditional instruction, or that are
0056   /// 'cases' of a SwitchInstr.
0057   // FIXME: We may want to replace this with a more meaningful metric, like
0058   // number of conditionally executed blocks:
0059   // 'if (a) s();' would be counted here as 2 blocks, just like
0060   // 'if (a) s(); else s2(); s3();' would.
0061   int64_t BlocksReachedFromConditionalInstruction = 0;
0062 
0063   /// Number of uses of this function, plus 1 if the function is callable
0064   /// outside the module.
0065   int64_t Uses = 0;
0066 
0067   /// Number of direct calls made from this function to other functions
0068   /// defined in this module.
0069   int64_t DirectCallsToDefinedFunctions = 0;
0070 
0071   // Load Instruction Count
0072   int64_t LoadInstCount = 0;
0073 
0074   // Store Instruction Count
0075   int64_t StoreInstCount = 0;
0076 
0077   // Maximum Loop Depth in the Function
0078   int64_t MaxLoopDepth = 0;
0079 
0080   // Number of Top Level Loops in the Function
0081   int64_t TopLevelLoopCount = 0;
0082 
0083   // All non-debug instructions
0084   int64_t TotalInstructionCount = 0;
0085 
0086   // Basic blocks grouped by number of successors.
0087   int64_t BasicBlocksWithSingleSuccessor = 0;
0088   int64_t BasicBlocksWithTwoSuccessors = 0;
0089   int64_t BasicBlocksWithMoreThanTwoSuccessors = 0;
0090 
0091   // Basic blocks grouped by number of predecessors.
0092   int64_t BasicBlocksWithSinglePredecessor = 0;
0093   int64_t BasicBlocksWithTwoPredecessors = 0;
0094   int64_t BasicBlocksWithMoreThanTwoPredecessors = 0;
0095 
0096   // Basic blocks grouped by size as determined by the number of non-debug
0097   // instructions that they contain.
0098   int64_t BigBasicBlocks = 0;
0099   int64_t MediumBasicBlocks = 0;
0100   int64_t SmallBasicBlocks = 0;
0101 
0102   // The number of cast instructions inside the function.
0103   int64_t CastInstructionCount = 0;
0104 
0105   // The number of floating point instructions inside the function.
0106   int64_t FloatingPointInstructionCount = 0;
0107 
0108   // The number of integer instructions inside the function.
0109   int64_t IntegerInstructionCount = 0;
0110 
0111   // Operand type couns
0112   int64_t ConstantIntOperandCount = 0;
0113   int64_t ConstantFPOperandCount = 0;
0114   int64_t ConstantOperandCount = 0;
0115   int64_t InstructionOperandCount = 0;
0116   int64_t BasicBlockOperandCount = 0;
0117   int64_t GlobalValueOperandCount = 0;
0118   int64_t InlineAsmOperandCount = 0;
0119   int64_t ArgumentOperandCount = 0;
0120   int64_t UnknownOperandCount = 0;
0121 
0122   // Additional CFG Properties
0123   int64_t CriticalEdgeCount = 0;
0124   int64_t ControlFlowEdgeCount = 0;
0125   int64_t UnconditionalBranchCount = 0;
0126 
0127   // Call related instructions
0128   int64_t IntrinsicCount = 0;
0129   int64_t DirectCallCount = 0;
0130   int64_t IndirectCallCount = 0;
0131   int64_t CallReturnsIntegerCount = 0;
0132   int64_t CallReturnsFloatCount = 0;
0133   int64_t CallReturnsPointerCount = 0;
0134   int64_t CallReturnsVectorIntCount = 0;
0135   int64_t CallReturnsVectorFloatCount = 0;
0136   int64_t CallReturnsVectorPointerCount = 0;
0137   int64_t CallWithManyArgumentsCount = 0;
0138   int64_t CallWithPointerArgumentCount = 0;
0139 };
0140 
0141 // Analysis pass
0142 class FunctionPropertiesAnalysis
0143     : public AnalysisInfoMixin<FunctionPropertiesAnalysis> {
0144 
0145 public:
0146   static AnalysisKey Key;
0147 
0148   using Result = const FunctionPropertiesInfo;
0149 
0150   FunctionPropertiesInfo run(Function &F, FunctionAnalysisManager &FAM);
0151 };
0152 
0153 /// Printer pass for the FunctionPropertiesAnalysis results.
0154 class FunctionPropertiesPrinterPass
0155     : public PassInfoMixin<FunctionPropertiesPrinterPass> {
0156   raw_ostream &OS;
0157 
0158 public:
0159   explicit FunctionPropertiesPrinterPass(raw_ostream &OS) : OS(OS) {}
0160 
0161   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0162 
0163   static bool isRequired() { return true; }
0164 };
0165 
0166 /// Correctly update FunctionPropertiesInfo post-inlining. A
0167 /// FunctionPropertiesUpdater keeps the state necessary for tracking the changes
0168 /// llvm::InlineFunction makes. The idea is that inlining will at most modify
0169 /// a few BBs of the Caller (maybe the entry BB and definitely the callsite BB)
0170 /// and potentially affect exception handling BBs in the case of invoke
0171 /// inlining.
0172 class FunctionPropertiesUpdater {
0173 public:
0174   FunctionPropertiesUpdater(FunctionPropertiesInfo &FPI, CallBase &CB);
0175 
0176   void finish(FunctionAnalysisManager &FAM) const;
0177   bool finishAndTest(FunctionAnalysisManager &FAM) const {
0178     finish(FAM);
0179     return isUpdateValid(Caller, FPI, FAM);
0180   }
0181 
0182 private:
0183   FunctionPropertiesInfo &FPI;
0184   BasicBlock &CallSiteBB;
0185   Function &Caller;
0186 
0187   static bool isUpdateValid(Function &F, const FunctionPropertiesInfo &FPI,
0188                             FunctionAnalysisManager &FAM);
0189 
0190   DominatorTree &getUpdatedDominatorTree(FunctionAnalysisManager &FAM) const;
0191 
0192   DenseSet<const BasicBlock *> Successors;
0193 
0194   // Edges we might potentially need to remove from the dominator tree.
0195   SmallVector<DominatorTree::UpdateType, 2> DomTreeUpdates;
0196 };
0197 } // namespace llvm
0198 #endif // LLVM_ANALYSIS_FUNCTIONPROPERTIESANALYSIS_H