1 //===- FunctionPropertiesAnalysis.cpp - Function Properties Analysis ------===// 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 #include "llvm/Analysis/FunctionPropertiesAnalysis.h" 15 #include "llvm/Analysis/LoopInfo.h" 16 #include "llvm/IR/Instructions.h" 17 18 using namespace llvm; 19 20 FunctionPropertiesInfo 21 FunctionPropertiesInfo::getFunctionPropertiesInfo(const Function &F, 22 const LoopInfo &LI) { 23 24 FunctionPropertiesInfo FPI; 25 26 FPI.Uses = ((!F.hasLocalLinkage()) ? 1 : 0) + F.getNumUses(); 27 28 for (const auto &BB : F) { 29 ++FPI.BasicBlockCount; 30 31 if (const auto *BI = dyn_cast<BranchInst>(BB.getTerminator())) { 32 if (BI->isConditional()) 33 FPI.BlocksReachedFromConditionalInstruction += BI->getNumSuccessors(); 34 } else if (const auto *SI = dyn_cast<SwitchInst>(BB.getTerminator())) { 35 FPI.BlocksReachedFromConditionalInstruction += 36 (SI->getNumCases() + (nullptr != SI->getDefaultDest())); 37 } 38 39 for (const auto &I : BB) { 40 if (auto *CS = dyn_cast<CallBase>(&I)) { 41 const auto *Callee = CS->getCalledFunction(); 42 if (Callee && !Callee->isIntrinsic() && !Callee->isDeclaration()) 43 ++FPI.DirectCallsToDefinedFunctions; 44 } 45 if (I.getOpcode() == Instruction::Load) { 46 ++FPI.LoadInstCount; 47 } else if (I.getOpcode() == Instruction::Store) { 48 ++FPI.StoreInstCount; 49 } 50 } 51 // Loop Depth of the Basic Block 52 int64_t LoopDepth; 53 LoopDepth = LI.getLoopDepth(&BB); 54 if (FPI.MaxLoopDepth < LoopDepth) 55 FPI.MaxLoopDepth = LoopDepth; 56 } 57 FPI.TopLevelLoopCount += llvm::size(LI); 58 return FPI; 59 } 60 61 void FunctionPropertiesInfo::print(raw_ostream &OS) const { 62 OS << "BasicBlockCount: " << BasicBlockCount << "\n" 63 << "BlocksReachedFromConditionalInstruction: " 64 << BlocksReachedFromConditionalInstruction << "\n" 65 << "Uses: " << Uses << "\n" 66 << "DirectCallsToDefinedFunctions: " << DirectCallsToDefinedFunctions 67 << "\n" 68 << "LoadInstCount: " << LoadInstCount << "\n" 69 << "StoreInstCount: " << StoreInstCount << "\n" 70 << "MaxLoopDepth: " << MaxLoopDepth << "\n" 71 << "TopLevelLoopCount: " << TopLevelLoopCount << "\n\n"; 72 } 73 74 AnalysisKey FunctionPropertiesAnalysis::Key; 75 76 const FunctionPropertiesInfo 77 FunctionPropertiesAnalysis::run(Function &F, FunctionAnalysisManager &FAM) { 78 return FunctionPropertiesInfo::getFunctionPropertiesInfo( 79 F, FAM.getResult<LoopAnalysis>(F)); 80 } 81 82 PreservedAnalyses 83 FunctionPropertiesPrinterPass::run(Function &F, FunctionAnalysisManager &AM) { 84 OS << "Printing analysis results of CFA for function " 85 << "'" << F.getName() << "':" 86 << "\n"; 87 AM.getResult<FunctionPropertiesAnalysis>(F).print(OS); 88 return PreservedAnalyses::all(); 89 } 90