//===- ProfileDataLoaderPass.cpp - Set branch weight metadata from prof ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass loads profiling data from a dump file and sets branch weight
// metadata.
//
// TODO: Replace all "profile-metadata-loader" strings with "profile-loader"
// once ProfileInfo etc. has been removed.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "profile-metadata-loader"
#include "llvm/Analysis/Passes.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ProfileDataLoader.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

STATISTIC(NumEdgesRead, "The # of edges read.");
STATISTIC(NumTermsAnnotated, "The # of terminator instructions annotated.");

static cl::opt<std::string>
ProfileMetadataFilename("profile-file", cl::init("llvmprof.out"),
                  cl::value_desc("filename"),
                  cl::desc("Profile file loaded by -profile-metadata-loader"));

namespace {
  /// This pass loads profiling data from a dump file and sets branch weight
  /// metadata.
  class ProfileMetadataLoaderPass : public ModulePass {
    std::string Filename;
  public:
    static char ID; // Class identification, replacement for typeinfo
    explicit ProfileMetadataLoaderPass(const std::string &filename = "")
        : ModulePass(ID), Filename(filename) {
      initializeProfileMetadataLoaderPassPass(*PassRegistry::getPassRegistry());
      if (filename.empty()) Filename = ProfileMetadataFilename;
    }

    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AU.setPreservesAll();
    }

    virtual const char *getPassName() const {
      return "Profile loader";
    }

    virtual void readEdge(unsigned, ProfileData&, ProfileData::Edge,
                          ArrayRef<unsigned>);
    virtual unsigned matchEdges(Module&, ProfileData&, ArrayRef<unsigned>);
    virtual void setBranchWeightMetadata(Module&, ProfileData&);

    virtual bool runOnModule(Module &M);
  };
}  // End of anonymous namespace

char ProfileMetadataLoaderPass::ID = 0;
INITIALIZE_PASS_BEGIN(ProfileMetadataLoaderPass, "profile-metadata-loader",
              "Load profile information from llvmprof.out", false, true)
INITIALIZE_PASS_END(ProfileMetadataLoaderPass, "profile-metadata-loader",
              "Load profile information from llvmprof.out", false, true)

char &llvm::ProfileMetadataLoaderPassID = ProfileMetadataLoaderPass::ID;

/// createProfileMetadataLoaderPass - This function returns a Pass that loads
/// the profiling information for the module from the specified filename,
/// making it available to the optimizers.
ModulePass *llvm::createProfileMetadataLoaderPass() { 
    return new ProfileMetadataLoaderPass();
}
ModulePass *llvm::createProfileMetadataLoaderPass(const std::string &Filename) {
  return new ProfileMetadataLoaderPass(Filename);
}

/// readEdge - Take the value from a profile counter and assign it to an edge.
void ProfileMetadataLoaderPass::readEdge(unsigned ReadCount,
                                         ProfileData &PB, ProfileData::Edge e,
                                         ArrayRef<unsigned> Counters) {
  if (ReadCount >= Counters.size()) return;

  unsigned weight = Counters[ReadCount];
  assert(weight != ProfileDataLoader::Uncounted);
  PB.addEdgeWeight(e, weight);

  DEBUG(dbgs() << "-- Read Edge Counter for " << e
               << " (# "<< (ReadCount) << "): "
               << PB.getEdgeWeight(e) << "\n");
}

/// matchEdges - Link every profile counter with an edge.
unsigned ProfileMetadataLoaderPass::matchEdges(Module &M, ProfileData &PB,
                                               ArrayRef<unsigned> Counters) {
  if (Counters.size() == 0) return 0;

  unsigned ReadCount = 0;

  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;
    DEBUG(dbgs() << "Loading edges in '" << F->getName() << "'\n");
    readEdge(ReadCount++, PB, PB.getEdge(0, &F->getEntryBlock()), Counters);
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      TerminatorInst *TI = BB->getTerminator();
      for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
        readEdge(ReadCount++, PB, PB.getEdge(BB,TI->getSuccessor(s)),
                 Counters);
      }
    }
  }

  return ReadCount;
}

/// setBranchWeightMetadata - Translate the counter values associated with each
/// edge into branch weights for each conditional branch (a branch with 2 or
/// more desinations).
void ProfileMetadataLoaderPass::setBranchWeightMetadata(Module &M,
                                                        ProfileData &PB) {
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;
    DEBUG(dbgs() << "Setting branch metadata in '" << F->getName() << "'\n");

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

      // If there is only one successor then we can not set a branch
      // probability as the target is certain.
      if (NumSuccessors < 2) continue;

      // Load the weights of all edges leading from this terminator.
      DEBUG(dbgs() << "-- Terminator with " << NumSuccessors
                   << " successors:\n");
      SmallVector<uint32_t, 4> Weights(NumSuccessors);
      for (unsigned s = 0 ; s < NumSuccessors ; ++s) {
          ProfileData::Edge edge = PB.getEdge(BB, TI->getSuccessor(s));
          Weights[s] = (uint32_t)PB.getEdgeWeight(edge);
          DEBUG(dbgs() << "---- Edge '" << edge << "' has weight "
                       << Weights[s] << "\n");
      }

      // Set branch weight metadata.  This will set branch probabilities of
      // 100%/0% if that is true of the dynamic execution.
      // BranchProbabilityInfo can account for this when it loads this metadata
      // (it gives the unexectuted branch a weight of 1 for the purposes of
      // probability calculations).
      MDBuilder MDB(TI->getContext());
      MDNode *Node = MDB.createBranchWeights(Weights);
      TI->setMetadata(LLVMContext::MD_prof, Node);
      NumTermsAnnotated++;
    }
  }
}

bool ProfileMetadataLoaderPass::runOnModule(Module &M) {
  ProfileDataLoader PDL("profile-data-loader", Filename);
  ProfileData PB;

  ArrayRef<unsigned> Counters = PDL.getRawEdgeCounts();

  unsigned ReadCount = matchEdges(M, PB, Counters);

  if (ReadCount != Counters.size()) {
    errs() << "WARNING: profile information is inconsistent with "
           << "the current program!\n";
  }
  NumEdgesRead = ReadCount;

  setBranchWeightMetadata(M, PB);

  return ReadCount > 0;
}
