clang API Documentation

FunctionSummary.h
Go to the documentation of this file.
00001 //== FunctionSummary.h - Stores summaries of functions. ------------*- C++ -*-//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines a summary of a function gathered/used by static analysis.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
00015 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H
00016 
00017 #include "clang/Basic/LLVM.h"
00018 #include "llvm/ADT/DenseMap.h"
00019 #include "llvm/ADT/DenseSet.h"
00020 #include "llvm/ADT/Optional.h"
00021 #include "llvm/ADT/SmallBitVector.h"
00022 #include <deque>
00023 
00024 namespace clang {
00025 class Decl;
00026 
00027 namespace ento {
00028 typedef std::deque<Decl*> SetOfDecls;
00029 typedef llvm::DenseSet<const Decl*> SetOfConstDecls;
00030 
00031 class FunctionSummariesTy {
00032   class FunctionSummary {
00033   public:
00034     /// Marks the IDs of the basic blocks visited during the analyzes.
00035     llvm::SmallBitVector VisitedBasicBlocks;
00036 
00037     /// Total number of blocks in the function.
00038     unsigned TotalBasicBlocks : 30;
00039 
00040     /// True if this function has been checked against the rules for which
00041     /// functions may be inlined.
00042     unsigned InlineChecked : 1;
00043 
00044     /// True if this function may be inlined.
00045     unsigned MayInline : 1;
00046 
00047     /// The number of times the function has been inlined.
00048     unsigned TimesInlined : 32;
00049 
00050     FunctionSummary() :
00051       TotalBasicBlocks(0),
00052       InlineChecked(0),
00053       TimesInlined(0) {}
00054   };
00055 
00056   typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy;
00057   MapTy Map;
00058 
00059 public:
00060   MapTy::iterator findOrInsertSummary(const Decl *D) {
00061     MapTy::iterator I = Map.find(D);
00062     if (I != Map.end())
00063       return I;
00064 
00065     typedef std::pair<const Decl *, FunctionSummary> KVPair;
00066     I = Map.insert(KVPair(D, FunctionSummary())).first;
00067     assert(I != Map.end());
00068     return I;
00069   }
00070 
00071   void markMayInline(const Decl *D) {
00072     MapTy::iterator I = findOrInsertSummary(D);
00073     I->second.InlineChecked = 1;
00074     I->second.MayInline = 1;
00075   }
00076 
00077   void markShouldNotInline(const Decl *D) {
00078     MapTy::iterator I = findOrInsertSummary(D);
00079     I->second.InlineChecked = 1;
00080     I->second.MayInline = 0;
00081   }
00082 
00083   void markReachedMaxBlockCount(const Decl *D) {
00084     markShouldNotInline(D);
00085   }
00086 
00087   Optional<bool> mayInline(const Decl *D) {
00088     MapTy::const_iterator I = Map.find(D);
00089     if (I != Map.end() && I->second.InlineChecked)
00090       return I->second.MayInline;
00091     return None;
00092   }
00093 
00094   void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
00095     MapTy::iterator I = findOrInsertSummary(D);
00096     llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
00097     assert(ID < TotalIDs);
00098     if (TotalIDs > Blocks.size()) {
00099       Blocks.resize(TotalIDs);
00100       I->second.TotalBasicBlocks = TotalIDs;
00101     }
00102     Blocks.set(ID);
00103   }
00104 
00105   unsigned getNumVisitedBasicBlocks(const Decl* D) {
00106     MapTy::const_iterator I = Map.find(D);
00107     if (I != Map.end())
00108       return I->second.VisitedBasicBlocks.count();
00109     return 0;
00110   }
00111 
00112   unsigned getNumTimesInlined(const Decl* D) {
00113     MapTy::const_iterator I = Map.find(D);
00114     if (I != Map.end())
00115       return I->second.TimesInlined;
00116     return 0;
00117   }
00118 
00119   void bumpNumTimesInlined(const Decl* D) {
00120     MapTy::iterator I = findOrInsertSummary(D);
00121     I->second.TimesInlined++;
00122   }
00123 
00124   /// Get the percentage of the reachable blocks.
00125   unsigned getPercentBlocksReachable(const Decl *D) {
00126     MapTy::const_iterator I = Map.find(D);
00127       if (I != Map.end())
00128         return ((I->second.VisitedBasicBlocks.count() * 100) /
00129                  I->second.TotalBasicBlocks);
00130     return 0;
00131   }
00132 
00133   unsigned getTotalNumBasicBlocks();
00134   unsigned getTotalNumVisitedBasicBlocks();
00135 
00136 };
00137 
00138 }} // end clang ento namespaces
00139 
00140 #endif