//== FunctionSummary.h - Stores summaries of functions. ------------*- C++ -*-//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a summary of a function gathered/used by static analysis.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_GR_FUNCTIONSUMMARY_H
#define LLVM_CLANG_GR_FUNCTIONSUMMARY_H

#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallBitVector.h"
#include <deque>

namespace clang {
class Decl;

namespace ento {
typedef std::deque<Decl*> SetOfDecls;
typedef llvm::DenseSet<const Decl*> SetOfConstDecls;

class FunctionSummariesTy {
  class FunctionSummary {
  public:
    /// Marks the IDs of the basic blocks visited during the analyzes.
    llvm::SmallBitVector VisitedBasicBlocks;

    /// Total number of blocks in the function.
    unsigned TotalBasicBlocks : 30;

    /// True if this function has been checked against the rules for which
    /// functions may be inlined.
    unsigned InlineChecked : 1;

    /// True if this function may be inlined.
    unsigned MayInline : 1;

    /// The number of times the function has been inlined.
    unsigned TimesInlined : 32;

    FunctionSummary() :
      TotalBasicBlocks(0),
      InlineChecked(0),
      TimesInlined(0) {}
  };

  typedef llvm::DenseMap<const Decl *, FunctionSummary> MapTy;
  MapTy Map;

public:
  MapTy::iterator findOrInsertSummary(const Decl *D) {
    MapTy::iterator I = Map.find(D);
    if (I != Map.end())
      return I;

    typedef std::pair<const Decl *, FunctionSummary> KVPair;
    I = Map.insert(KVPair(D, FunctionSummary())).first;
    assert(I != Map.end());
    return I;
  }

  void markMayInline(const Decl *D) {
    MapTy::iterator I = findOrInsertSummary(D);
    I->second.InlineChecked = 1;
    I->second.MayInline = 1;
  }

  void markShouldNotInline(const Decl *D) {
    MapTy::iterator I = findOrInsertSummary(D);
    I->second.InlineChecked = 1;
    I->second.MayInline = 0;
  }

  void markReachedMaxBlockCount(const Decl *D) {
    markShouldNotInline(D);
  }

  Optional<bool> mayInline(const Decl *D) {
    MapTy::const_iterator I = Map.find(D);
    if (I != Map.end() && I->second.InlineChecked)
      return I->second.MayInline;
    return None;
  }

  void markVisitedBasicBlock(unsigned ID, const Decl* D, unsigned TotalIDs) {
    MapTy::iterator I = findOrInsertSummary(D);
    llvm::SmallBitVector &Blocks = I->second.VisitedBasicBlocks;
    assert(ID < TotalIDs);
    if (TotalIDs > Blocks.size()) {
      Blocks.resize(TotalIDs);
      I->second.TotalBasicBlocks = TotalIDs;
    }
    Blocks.set(ID);
  }

  unsigned getNumVisitedBasicBlocks(const Decl* D) {
    MapTy::const_iterator I = Map.find(D);
    if (I != Map.end())
      return I->second.VisitedBasicBlocks.count();
    return 0;
  }

  unsigned getNumTimesInlined(const Decl* D) {
    MapTy::const_iterator I = Map.find(D);
    if (I != Map.end())
      return I->second.TimesInlined;
    return 0;
  }

  void bumpNumTimesInlined(const Decl* D) {
    MapTy::iterator I = findOrInsertSummary(D);
    I->second.TimesInlined++;
  }

  /// Get the percentage of the reachable blocks.
  unsigned getPercentBlocksReachable(const Decl *D) {
    MapTy::const_iterator I = Map.find(D);
      if (I != Map.end())
        return ((I->second.VisitedBasicBlocks.count() * 100) /
                 I->second.TotalBasicBlocks);
    return 0;
  }

  unsigned getTotalNumBasicBlocks();
  unsigned getTotalNumVisitedBasicBlocks();

};

}} // end clang ento namespaces

#endif
