//===- PathProfileVerifier.cpp --------------------------------*- C++ -*---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This verifier derives an edge profile file from current path profile
// information
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "path-profile-verifier"

#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/PathProfileInfo.h"
#include "llvm/Analysis/ProfileInfoTypes.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <stdio.h>

using namespace llvm;

namespace {
  class PathProfileVerifier : public ModulePass {
  private:
    bool runOnModule(Module &M);

  public:
    static char ID; // Pass identification, replacement for typeid
    PathProfileVerifier() : ModulePass(ID) {
      initializePathProfileVerifierPass(*PassRegistry::getPassRegistry());
    }


    virtual const char *getPassName() const {
      return "Path Profiler Verifier";
    }

    // The verifier requires the path profile and edge profile.
    virtual void getAnalysisUsage(AnalysisUsage& AU) const;
  };
}

static cl::opt<std::string>
EdgeProfileFilename("path-profile-verifier-file",
  cl::init("edgefrompath.llvmprof.out"),
  cl::value_desc("filename"),
  cl::desc("Edge profile file generated by -path-profile-verifier"),
  cl::Hidden);

char PathProfileVerifier::ID = 0;
INITIALIZE_PASS(PathProfileVerifier, "path-profile-verifier",
                "Compare the path profile derived edge profile against the "
                "edge profile.", true, true)

ModulePass *llvm::createPathProfileVerifierPass() {
  return new PathProfileVerifier();
}

// The verifier requires the path profile and edge profile.
void PathProfileVerifier::getAnalysisUsage(AnalysisUsage& AU) const {
  AU.addRequired<PathProfileInfo>();
  AU.addPreserved<PathProfileInfo>();
}

typedef std::map<unsigned, unsigned> DuplicateToIndexMap;
typedef std::map<BasicBlock*,DuplicateToIndexMap> BlockToDuplicateMap;
typedef std::map<BasicBlock*,BlockToDuplicateMap> NestedBlockToIndexMap;

// the verifier iterates through each path to gather the total
// number of edge frequencies
bool PathProfileVerifier::runOnModule (Module &M) {
  PathProfileInfo& pathProfileInfo = getAnalysis<PathProfileInfo>();

  // setup a data structure to map path edges which index an
  // array of edge counters
  NestedBlockToIndexMap arrayMap;
  unsigned i = 0;
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;

    arrayMap[(BasicBlock*)0][F->begin()][0] = i++;

    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      TerminatorInst *TI = BB->getTerminator();

      unsigned duplicate = 0;
      BasicBlock* prev = 0;
      for (unsigned s = 0, e = TI->getNumSuccessors(); s != e;
           prev = TI->getSuccessor(s), ++s) {
        if (prev == TI->getSuccessor(s))
          duplicate++;
        else duplicate = 0;

        arrayMap[BB][TI->getSuccessor(s)][duplicate] = i++;
      }
    }
  }

  std::vector<unsigned> edgeArray(i);

  // iterate through each path and increment the edge counters as needed
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;

    pathProfileInfo.setCurrentFunction(F);

    DEBUG(dbgs() << "function '" << F->getName() << "' ran "
          << pathProfileInfo.pathsRun()
          << "/" << pathProfileInfo.getPotentialPathCount()
          << " potential paths\n");

    for( ProfilePathIterator nextPath = pathProfileInfo.pathBegin(),
           endPath = pathProfileInfo.pathEnd();
         nextPath != endPath; nextPath++ ) {
      ProfilePath* currentPath = nextPath->second;

      ProfilePathEdgeVector* pev = currentPath->getPathEdges();
      DEBUG(dbgs () << "path #" << currentPath->getNumber() << ": "
            << currentPath->getCount() << "\n");
      // setup the entry edge (normally path profiling doesn't care about this)
      if (currentPath->getFirstBlockInPath() == &F->getEntryBlock())
        edgeArray[arrayMap[(BasicBlock*)0][currentPath->getFirstBlockInPath()][0]]
          += currentPath->getCount();

      for( ProfilePathEdgeIterator nextEdge = pev->begin(),
             endEdge = pev->end(); nextEdge != endEdge; nextEdge++ ) {
        if (nextEdge != pev->begin())
          DEBUG(dbgs() << " :: ");

        BasicBlock* source = nextEdge->getSource();
        BasicBlock* target = nextEdge->getTarget();
        unsigned duplicateNumber = nextEdge->getDuplicateNumber();
        DEBUG(dbgs() << source->getName() << " --{" << duplicateNumber
                     << "}--> " << target->getName());

        // Ensure all the referenced edges exist
        // TODO: make this a separate function
        if( !arrayMap.count(source) ) {
          errs() << "  error [" << F->getName() << "()]: source '"
                 << source->getName()
                 << "' does not exist in the array map.\n";
        } else if( !arrayMap[source].count(target) ) {
          errs() << "  error [" << F->getName() << "()]: target '"
                 << target->getName()
                 << "' does not exist in the array map.\n";
        } else if( !arrayMap[source][target].count(duplicateNumber) ) {
          errs() << "  error [" << F->getName() << "()]: edge "
                 << source->getName() << " -> " << target->getName()
                 << " duplicate number " << duplicateNumber
                 << " does not exist in the array map.\n";
        } else {
          edgeArray[arrayMap[source][target][duplicateNumber]]
            += currentPath->getCount();
        }
      }

      DEBUG(errs() << "\n");

      delete pev;
    }
  }

  std::string errorInfo;
  std::string filename = EdgeProfileFilename;

  // Open a handle to the file
  FILE* edgeFile = fopen(filename.c_str(),"wb");

  if (!edgeFile) {
    errs() << "error: unable to open file '" << filename << "' for output.\n";
    return false;
  }

  errs() << "Generating edge profile '" << filename << "' ...\n";

  // write argument info
  unsigned type = ArgumentInfo;
  unsigned num = pathProfileInfo.argList.size();
  int zeros = 0;

  fwrite(&type,sizeof(unsigned),1,edgeFile);
  fwrite(&num,sizeof(unsigned),1,edgeFile);
  fwrite(pathProfileInfo.argList.c_str(),1,num,edgeFile);
  if (num&3)
    fwrite(&zeros, 1, 4-(num&3), edgeFile);

  type = EdgeInfo;
  num = edgeArray.size();
  fwrite(&type,sizeof(unsigned),1,edgeFile);
  fwrite(&num,sizeof(unsigned),1,edgeFile);

  // write each edge to the file
  for( std::vector<unsigned>::iterator s = edgeArray.begin(),
         e = edgeArray.end(); s != e; s++)
    fwrite(&*s, sizeof (unsigned), 1, edgeFile);

  fclose (edgeFile);

  return true;
}
