//===- bolt/Rewrite/BoltDiff.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// RewriteInstance methods related to comparing one instance to another, used
// by the boltdiff tool to print a report.
//
//===----------------------------------------------------------------------===//

#include "bolt/Passes/IdenticalCodeFolding.h"
#include "bolt/Profile/ProfileReaderBase.h"
#include "bolt/Rewrite/RewriteInstance.h"
#include "bolt/Utils/Utils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/CommandLine.h"

#undef  DEBUG_TYPE
#define DEBUG_TYPE "boltdiff"

using namespace llvm;
using namespace object;
using namespace bolt;

namespace opts {
extern cl::OptionCategory BoltDiffCategory;
extern cl::opt<bool> NeverPrint;
extern cl::opt<bool> ICF;

static cl::opt<bool> IgnoreLTOSuffix(
    "ignore-lto-suffix",
    cl::desc("ignore lto_priv or const suffixes when matching functions"),
    cl::init(true), cl::cat(BoltDiffCategory));

static cl::opt<bool> PrintUnmapped(
    "print-unmapped",
    cl::desc("print functions of binary 2 that were not matched to any "
             "function in binary 1"),
    cl::cat(BoltDiffCategory));

static cl::opt<bool> PrintProfiledUnmapped(
    "print-profiled-unmapped",
    cl::desc("print functions that have profile in binary 1 but do not "
             "in binary 2"),
    cl::cat(BoltDiffCategory));

static cl::opt<bool> PrintDiffCFG(
    "print-diff-cfg",
    cl::desc("print the CFG of important functions that changed in "
             "binary 2"),
    cl::cat(BoltDiffCategory));

static cl::opt<bool>
    PrintDiffBBs("print-diff-bbs",
                 cl::desc("print the basic blocks showed in top differences"),
                 cl::cat(BoltDiffCategory));

static cl::opt<bool> MatchByHash(
    "match-by-hash",
    cl::desc("match functions in binary 2 to binary 1 if they have the same "
             "hash of a function in binary 1"),
    cl::cat(BoltDiffCategory));

static cl::opt<bool> IgnoreUnchanged(
    "ignore-unchanged",
    cl::desc("do not diff functions whose contents have not been changed from "
             "one binary to another"),
    cl::cat(BoltDiffCategory));

static cl::opt<unsigned> DisplayCount(
    "display-count",
    cl::desc("number of functions to display when printing the top largest "
             "differences in function activity"),
    cl::init(10), cl::cat(BoltDiffCategory));

static cl::opt<bool> NormalizeByBin1(
    "normalize-by-bin1",
    cl::desc("show execution count of functions in binary 2 as a ratio of the "
             "total samples in binary 1 - make sure both profiles have equal "
             "collection time and sampling rate for this to make sense"),
    cl::cat(BoltDiffCategory));

static cl::opt<bool>
    SkipNonSimple("skip-non-simple",
                  cl::desc("skip non-simple functions in reporting"),
                  cl::ReallyHidden, cl::cat(BoltDiffCategory));

} // end namespace opts

namespace llvm {
namespace bolt {

namespace {

/// Helper used to print colored numbers
void printColoredPercentage(double Perc) {
  if (outs().has_colors() && Perc > 0.0)
    outs().changeColor(raw_ostream::RED);
  else if (outs().has_colors() && Perc < 0.0)
    outs().changeColor(raw_ostream::GREEN);
  else if (outs().has_colors())
    outs().changeColor(raw_ostream::YELLOW);
  outs() << format("%.2f", Perc) << "%";
  if (outs().has_colors())
    outs().resetColor();
}

void setLightColor() {
  if (opts::PrintDiffBBs && outs().has_colors())
    outs().changeColor(raw_ostream::CYAN);
}

void setTitleColor() {
  if (outs().has_colors())
    outs().changeColor(raw_ostream::WHITE, /*Bold=*/true);
}

void setRegularColor() {
  if (outs().has_colors())
    outs().resetColor();
}

} // end anonymous namespace

/// Perform the comparison between two binaries with profiling information
class RewriteInstanceDiff {
  typedef std::tuple<const BinaryBasicBlock *, const BinaryBasicBlock *, double>
      EdgeTy;

  RewriteInstance &RI1;
  RewriteInstance &RI2;

  // The map of functions keyed by functions in binary 2, providing its
  // corresponding function in binary 1
  std::map<const BinaryFunction *, const BinaryFunction *> FuncMap;

  // The map of basic blocks correspondence, analogue to FuncMap for BBs,
  // sorted by score difference
  std::map<const BinaryBasicBlock *, const BinaryBasicBlock *> BBMap;

  // The map of edge correspondence
  std::map<double, std::pair<EdgeTy, EdgeTy>> EdgeMap;

  // Maps all known basic blocks back to their parent function
  std::map<const BinaryBasicBlock *, const BinaryFunction *> BBToFuncMap;

  // Accounting which functions were matched
  std::set<const BinaryFunction *> Bin1MappedFuncs;
  std::set<const BinaryFunction *> Bin2MappedFuncs;

  // Structures for our 3 matching strategies: by name, by hash and by lto name,
  // from the strongest to the weakest bind between two functions
  StringMap<const BinaryFunction *> NameLookup;
  DenseMap<size_t, const BinaryFunction *> HashLookup;
  StringMap<const BinaryFunction *> LTONameLookup1;
  StringMap<const BinaryFunction *> LTONameLookup2;

  // Score maps used to order and find hottest functions
  std::multimap<double, const BinaryFunction *> LargestBin1;
  std::multimap<double, const BinaryFunction *> LargestBin2;

  // Map multiple functions in the same LTO bucket to a single parent function
  // representing all functions sharing the same prefix
  std::map<const BinaryFunction *, const BinaryFunction *> LTOMap1;
  std::map<const BinaryFunction *, const BinaryFunction *> LTOMap2;
  std::map<const BinaryFunction *, double> LTOAggregatedScore1;
  std::map<const BinaryFunction *, double> LTOAggregatedScore2;

  // Map scores in bin2 and 1 keyed by a binary 2 function - post-matching
  DenseMap<const BinaryFunction *, std::pair<double, double>> ScoreMap;

  double getNormalizedScore(const BinaryFunction &Function,
                            const RewriteInstance &Ctx) {
    if (!opts::NormalizeByBin1)
      return static_cast<double>(Function.getFunctionScore()) /
             Ctx.getTotalScore();
    return static_cast<double>(Function.getFunctionScore()) /
           RI1.getTotalScore();
  }

  double getNormalizedScore(const BinaryBasicBlock &BB,
                            const RewriteInstance &Ctx) {
    if (!opts::NormalizeByBin1)
      return static_cast<double>(BB.getKnownExecutionCount()) /
             Ctx.getTotalScore();
    return static_cast<double>(BB.getKnownExecutionCount()) /
           RI1.getTotalScore();
  }

  double getNormalizedScore(BinaryBasicBlock::const_branch_info_iterator BIIter,
                            const RewriteInstance &Ctx) {
    double Score =
        BIIter->Count == BinaryBasicBlock::COUNT_NO_PROFILE ? 0 : BIIter->Count;
    if (!opts::NormalizeByBin1)
      return Score / Ctx.getTotalScore();
    return Score / RI1.getTotalScore();
  }

  /// Initialize data structures used for function lookup in binary 1, used
  /// later when matching functions in binary 2 to corresponding functions
  /// in binary 1
  void buildLookupMaps() {
    for (const auto &BFI : RI1.BC->getBinaryFunctions()) {
      StringRef LTOName;
      const BinaryFunction &Function = BFI.second;
      const double Score = getNormalizedScore(Function, RI1);
      LargestBin1.insert(std::make_pair<>(Score, &Function));
      for (const StringRef &Name : Function.getNames()) {
        if (std::optional<StringRef> OptionalLTOName = getLTOCommonName(Name))
          LTOName = *OptionalLTOName;
        NameLookup[Name] = &Function;
      }
      if (opts::MatchByHash && Function.hasCFG())
        HashLookup[Function.computeHash(/*UseDFS=*/true)] = &Function;
      if (opts::IgnoreLTOSuffix && !LTOName.empty()) {
        if (!LTONameLookup1.count(LTOName))
          LTONameLookup1[LTOName] = &Function;
        LTOMap1[&Function] = LTONameLookup1[LTOName];
      }
    }

    // Compute LTONameLookup2 and LargestBin2
    for (const auto &BFI : RI2.BC->getBinaryFunctions()) {
      StringRef LTOName;
      const BinaryFunction &Function = BFI.second;
      const double Score = getNormalizedScore(Function, RI2);
      LargestBin2.insert(std::make_pair<>(Score, &Function));
      for (const StringRef &Name : Function.getNames()) {
        if (std::optional<StringRef> OptionalLTOName = getLTOCommonName(Name))
          LTOName = *OptionalLTOName;
      }
      if (opts::IgnoreLTOSuffix && !LTOName.empty()) {
        if (!LTONameLookup2.count(LTOName))
          LTONameLookup2[LTOName] = &Function;
        LTOMap2[&Function] = LTONameLookup2[LTOName];
      }
    }
  }

  /// Match functions in binary 2 with functions in binary 1
  void matchFunctions() {
    outs() << "BOLT-DIFF: Mapping functions in Binary2 to Binary1\n";
    uint64_t BothHaveProfile = 0ull;
    std::set<const BinaryFunction *> Bin1ProfiledMapped;

    for (const auto &BFI2 : RI2.BC->getBinaryFunctions()) {
      const BinaryFunction &Function2 = BFI2.second;
      StringRef LTOName;
      bool Match = false;
      for (const StringRef &Name : Function2.getNames()) {
        auto Iter = NameLookup.find(Name);
        if (std::optional<StringRef> OptionalLTOName = getLTOCommonName(Name))
          LTOName = *OptionalLTOName;
        if (Iter == NameLookup.end())
          continue;
        FuncMap.insert(std::make_pair<>(&Function2, Iter->second));
        Bin1MappedFuncs.insert(Iter->second);
        Bin2MappedFuncs.insert(&Function2);
        if (Function2.hasValidProfile() && Iter->second->hasValidProfile()) {
          ++BothHaveProfile;
          Bin1ProfiledMapped.insert(Iter->second);
        }
        Match = true;
        break;
      }
      if (Match || !Function2.hasCFG())
        continue;
      auto Iter = HashLookup.find(Function2.computeHash(/*UseDFS*/ true));
      if (Iter != HashLookup.end()) {
        FuncMap.insert(std::make_pair<>(&Function2, Iter->second));
        Bin1MappedFuncs.insert(Iter->second);
        Bin2MappedFuncs.insert(&Function2);
        if (Function2.hasValidProfile() && Iter->second->hasValidProfile()) {
          ++BothHaveProfile;
          Bin1ProfiledMapped.insert(Iter->second);
        }
        continue;
      }
      if (LTOName.empty())
        continue;
      auto LTOIter = LTONameLookup1.find(LTOName);
      if (LTOIter != LTONameLookup1.end()) {
        FuncMap.insert(std::make_pair<>(&Function2, LTOIter->second));
        Bin1MappedFuncs.insert(LTOIter->second);
        Bin2MappedFuncs.insert(&Function2);
        if (Function2.hasValidProfile() && LTOIter->second->hasValidProfile()) {
          ++BothHaveProfile;
          Bin1ProfiledMapped.insert(LTOIter->second);
        }
      }
    }
    PrintProgramStats PPS;
    outs() << "* BOLT-DIFF: Starting print program stats pass for binary 1\n";
    RI1.BC->logBOLTErrorsAndQuitOnFatal(PPS.runOnFunctions(*RI1.BC));
    outs() << "* BOLT-DIFF: Starting print program stats pass for binary 2\n";
    RI1.BC->logBOLTErrorsAndQuitOnFatal(PPS.runOnFunctions(*RI2.BC));
    outs() << "=====\n";
    outs() << "Inputs share " << BothHaveProfile
           << " functions with valid profile.\n";
    if (opts::PrintProfiledUnmapped) {
      outs() << "\nFunctions in profile 1 that are missing in the profile 2:\n";
      std::vector<const BinaryFunction *> Unmapped;
      for (const auto &BFI : RI1.BC->getBinaryFunctions()) {
        const BinaryFunction &Function = BFI.second;
        if (!Function.hasValidProfile() || Bin1ProfiledMapped.count(&Function))
          continue;
        Unmapped.emplace_back(&Function);
      }
      llvm::sort(Unmapped,
                 [&](const BinaryFunction *A, const BinaryFunction *B) {
                   return A->getFunctionScore() > B->getFunctionScore();
                 });
      for (const BinaryFunction *Function : Unmapped) {
        outs() << Function->getPrintName() << " : ";
        outs() << Function->getFunctionScore() << "\n";
      }
      outs() << "=====\n";
    }
  }

  /// Check if opcodes in BB1 match those in BB2
  bool compareBBs(const BinaryBasicBlock &BB1,
                  const BinaryBasicBlock &BB2) const {
    auto Iter1 = BB1.begin();
    auto Iter2 = BB2.begin();
    if ((Iter1 == BB1.end() && Iter2 != BB2.end()) ||
        (Iter1 != BB1.end() && Iter2 == BB2.end()))
      return false;

    while (Iter1 != BB1.end()) {
      if (Iter2 == BB2.end() || Iter1->getOpcode() != Iter2->getOpcode())
        return false;

      ++Iter1;
      ++Iter2;
    }

    if (Iter2 != BB2.end())
      return false;
    return true;
  }

  /// For a function in binary 2 that matched one in binary 1, now match each
  /// individual basic block in it to its corresponding blocks in binary 1.
  /// Also match each edge in binary 2 to the corresponding ones in binary 1.
  void matchBasicBlocks() {
    for (const auto &MapEntry : FuncMap) {
      const BinaryFunction *const &Func1 = MapEntry.second;
      const BinaryFunction *const &Func2 = MapEntry.first;

      auto Iter1 = Func1->getLayout().block_begin();
      auto Iter2 = Func2->getLayout().block_begin();

      bool Match = true;
      std::map<const BinaryBasicBlock *, const BinaryBasicBlock *> Map;
      std::map<double, std::pair<EdgeTy, EdgeTy>> EMap;
      while (Iter1 != Func1->getLayout().block_end()) {
        if (Iter2 == Func2->getLayout().block_end()) {
          Match = false;
          break;
        }
        if (!compareBBs(**Iter1, **Iter2)) {
          Match = false;
          break;
        }
        Map.insert(std::make_pair<>(*Iter2, *Iter1));

        auto SuccIter1 = (*Iter1)->succ_begin();
        auto SuccIter2 = (*Iter2)->succ_begin();
        auto BIIter1 = (*Iter1)->branch_info_begin();
        auto BIIter2 = (*Iter2)->branch_info_begin();
        while (SuccIter1 != (*Iter1)->succ_end()) {
          if (SuccIter2 == (*Iter2)->succ_end()) {
            Match = false;
            break;
          }
          const double ScoreEdge1 = getNormalizedScore(BIIter1, RI1);
          const double ScoreEdge2 = getNormalizedScore(BIIter2, RI2);
          EMap.insert(std::make_pair<>(
              std::abs(ScoreEdge2 - ScoreEdge1),
              std::make_pair<>(
                  std::make_tuple<>(*Iter2, *SuccIter2, ScoreEdge2),
                  std::make_tuple<>(*Iter1, *SuccIter1, ScoreEdge1))));

          ++SuccIter1;
          ++SuccIter2;
          ++BIIter1;
          ++BIIter2;
        }
        if (SuccIter2 != (*Iter2)->succ_end())
          Match = false;
        if (!Match)
          break;

        BBToFuncMap[*Iter1] = Func1;
        BBToFuncMap[*Iter2] = Func2;
        ++Iter1;
        ++Iter2;
      }
      if (!Match || Iter2 != Func2->getLayout().block_end())
        continue;

      BBMap.insert(Map.begin(), Map.end());
      EdgeMap.insert(EMap.begin(), EMap.end());
    }
  }

  /// Print the largest differences in basic block performance from binary 1
  /// to binary 2
  void reportHottestBBDiffs() {
    std::map<double, const BinaryBasicBlock *> LargestDiffs;
    for (const auto &MapEntry : BBMap) {
      const BinaryBasicBlock *BB2 = MapEntry.first;
      const BinaryBasicBlock *BB1 = MapEntry.second;
      LargestDiffs.insert(
          std::make_pair<>(std::abs(getNormalizedScore(*BB2, RI2) -
                                    getNormalizedScore(*BB1, RI1)),
                           BB2));
    }

    unsigned Printed = 0;
    setTitleColor();
    outs()
        << "\nTop " << opts::DisplayCount
        << " largest differences in basic block performance bin 2 -> bin 1:\n";
    outs() << "=========================================================\n";
    setRegularColor();
    outs() << " * Functions with different contents do not appear here\n\n";
    for (const BinaryBasicBlock *BB2 :
         llvm::make_second_range(llvm::reverse(LargestDiffs))) {
      const double Score2 = getNormalizedScore(*BB2, RI2);
      const double Score1 = getNormalizedScore(*BBMap[BB2], RI1);
      const BinaryFunction *Func = BBToFuncMap[BB2];
      if (opts::SkipNonSimple && !Func->isSimple())
        continue;
      outs() << "BB " << BB2->getName() << " from " << Func->getDemangledName()
             << "\n\tScore bin1 = " << format("%.4f", Score1 * 100.0)
             << "%\n\tScore bin2 = " << format("%.4f", Score2 * 100.0);
      outs() << "%\t(Difference: ";
      printColoredPercentage((Score2 - Score1) * 100.0);
      outs() << ")\n";
      if (opts::PrintDiffBBs) {
        setLightColor();
        BB2->dump();
        setRegularColor();
      }
      if (Printed++ == opts::DisplayCount)
        break;
    }
  }

  /// Print the largest differences in edge counts from one binary to another
  void reportHottestEdgeDiffs() {
    unsigned Printed = 0;
    setTitleColor();
    outs() << "\nTop " << opts::DisplayCount
           << " largest differences in edge hotness bin 2 -> bin 1:\n";
    outs() << "=========================================================\n";
    setRegularColor();
    outs() << " * Functions with different contents do not appear here\n";
    for (std::pair<EdgeTy, EdgeTy> &EI :
         llvm::make_second_range(llvm::reverse(EdgeMap))) {
      EdgeTy &Edge2 = EI.first;
      EdgeTy &Edge1 = EI.second;
      const double Score2 = std::get<2>(Edge2);
      const double Score1 = std::get<2>(Edge1);
      const BinaryFunction *Func = BBToFuncMap[std::get<0>(Edge2)];
      if (opts::SkipNonSimple && !Func->isSimple())
        continue;
      outs() << "Edge (" << std::get<0>(Edge2)->getName() << " -> "
             << std::get<1>(Edge2)->getName() << ") in "
             << Func->getDemangledName()
             << "\n\tScore bin1 = " << format("%.4f", Score1 * 100.0)
             << "%\n\tScore bin2 = " << format("%.4f", Score2 * 100.0);
      outs() << "%\t(Difference: ";
      printColoredPercentage((Score2 - Score1) * 100.0);
      outs() << ")\n";
      if (opts::PrintDiffBBs) {
        setLightColor();
        std::get<0>(Edge2)->dump();
        std::get<1>(Edge2)->dump();
        setRegularColor();
      }
      if (Printed++ == opts::DisplayCount)
        break;
    }
  }

  /// For LTO functions sharing the same prefix (for example, func1.lto_priv.1
  /// and func1.lto_priv.2 share the func1.lto_priv prefix), compute aggregated
  /// scores for them. This is used to avoid reporting all LTO functions as
  /// having a large difference in performance because hotness shifted from
  /// LTO variant 1 to variant 2, even though they represent the same function.
  void computeAggregatedLTOScore() {
    for (const auto &BFI : RI1.BC->getBinaryFunctions()) {
      const BinaryFunction &Function = BFI.second;
      double Score = getNormalizedScore(Function, RI1);
      auto Iter = LTOMap1.find(&Function);
      if (Iter == LTOMap1.end())
        continue;
      LTOAggregatedScore1[Iter->second] += Score;
    }

    double UnmappedScore = 0;
    for (const auto &BFI : RI2.BC->getBinaryFunctions()) {
      const BinaryFunction &Function = BFI.second;
      bool Matched = FuncMap.find(&Function) != FuncMap.end();
      double Score = getNormalizedScore(Function, RI2);
      auto Iter = LTOMap2.find(&Function);
      if (Iter == LTOMap2.end()) {
        if (!Matched)
          UnmappedScore += Score;
        continue;
      }
      LTOAggregatedScore2[Iter->second] += Score;
      if (FuncMap.find(Iter->second) == FuncMap.end())
        UnmappedScore += Score;
    }
    int64_t Unmapped =
        RI2.BC->getBinaryFunctions().size() - Bin2MappedFuncs.size();
    outs() << "BOLT-DIFF: " << Unmapped
           << " functions in Binary2 have no correspondence to any other "
              "function in Binary1.\n";

    // Print the hotness score of functions in binary 2 that were not matched
    // to any function in binary 1
    outs() << "BOLT-DIFF: These unmapped functions in Binary2 represent "
           << format("%.2f", UnmappedScore * 100.0) << "% of execution.\n";
  }

  /// Print the largest hotness differences from binary 2 to binary 1
  void reportHottestFuncDiffs() {
    std::multimap<double, decltype(FuncMap)::value_type> LargestDiffs;
    for (const auto &MapEntry : FuncMap) {
      const BinaryFunction *const &Func1 = MapEntry.second;
      const BinaryFunction *const &Func2 = MapEntry.first;
      double Score1 = getNormalizedScore(*Func1, RI1);
      auto Iter1 = LTOMap1.find(Func1);
      if (Iter1 != LTOMap1.end())
        Score1 = LTOAggregatedScore1[Iter1->second];
      double Score2 = getNormalizedScore(*Func2, RI2);
      auto Iter2 = LTOMap2.find(Func2);
      if (Iter2 != LTOMap2.end())
        Score2 = LTOAggregatedScore2[Iter2->second];
      if (Score1 == 0.0 || Score2 == 0.0)
        continue;
      if (opts::SkipNonSimple && !Func1->isSimple() && !Func2->isSimple())
        continue;
      LargestDiffs.insert(
          std::make_pair<>(std::abs(Score1 - Score2), MapEntry));
      ScoreMap[Func2] = std::make_pair<>(Score1, Score2);
    }

    unsigned Printed = 0;
    setTitleColor();
    outs() << "\nTop " << opts::DisplayCount
           << " largest differences in performance bin 2 -> bin 1:\n";
    outs() << "=========================================================\n";
    setRegularColor();
    for (decltype(this->FuncMap)::value_type &MapEntry :
         llvm::make_second_range(llvm::reverse(LargestDiffs))) {
      if (opts::IgnoreUnchanged &&
          MapEntry.second->computeHash(/*UseDFS=*/true) ==
              MapEntry.first->computeHash(/*UseDFS=*/true))
        continue;
      const std::pair<double, double> &Scores = ScoreMap[MapEntry.first];
      outs() << "Function " << MapEntry.first->getDemangledName();
      if (MapEntry.first->getDemangledName() !=
          MapEntry.second->getDemangledName())
        outs() << "\nmatched  " << MapEntry.second->getDemangledName();
      outs() << "\n\tScore bin1 = " << format("%.2f", Scores.first * 100.0)
             << "%\n\tScore bin2 = " << format("%.2f", Scores.second * 100.0)
             << "%\t(Difference: ";
      printColoredPercentage((Scores.second - Scores.first) * 100.0);
      outs() << ")";
      if (MapEntry.second->computeHash(/*UseDFS=*/true) !=
          MapEntry.first->computeHash(/*UseDFS=*/true)) {
        outs() << "\t[Functions have different contents]";
        if (opts::PrintDiffCFG) {
          outs() << "\n *** CFG for function in binary 1:\n";
          setLightColor();
          MapEntry.second->dump();
          setRegularColor();
          outs() << "\n *** CFG for function in binary 2:\n";
          setLightColor();
          MapEntry.first->dump();
          setRegularColor();
        }
      }
      outs() << "\n";
      if (Printed++ == opts::DisplayCount)
        break;
    }
  }

  /// Print hottest functions from each binary
  void reportHottestFuncs() {
    unsigned Printed = 0;
    setTitleColor();
    outs() << "\nTop " << opts::DisplayCount
           << " hottest functions in binary 2:\n";
    outs() << "=====================================\n";
    setRegularColor();
    for (std::pair<const double, const BinaryFunction *> &MapEntry :
         llvm::reverse(LargestBin2)) {
      outs() << "Function " << MapEntry.second->getDemangledName() << "\n";
      auto Iter = ScoreMap.find(MapEntry.second);
      if (Iter != ScoreMap.end())
        outs() << "\tScore bin1 = "
               << format("%.2f", Iter->second.first * 100.0) << "%\n";
      outs() << "\tScore bin2 = " << format("%.2f", MapEntry.first * 100.0)
             << "%\n";
      if (Printed++ == opts::DisplayCount)
        break;
    }

    Printed = 0;
    setTitleColor();
    outs() << "\nTop " << opts::DisplayCount
           << " hottest functions in binary 1:\n";
    outs() << "=====================================\n";
    setRegularColor();
    for (const std::pair<const double, const BinaryFunction *> &MapEntry :
         llvm::reverse(LargestBin1)) {
      outs() << "Function " << MapEntry.second->getDemangledName()
             << "\n\tScore bin1 = " << format("%.2f", MapEntry.first * 100.0)
             << "%\n";
      if (Printed++ == opts::DisplayCount)
        break;
    }
  }

  /// Print functions in binary 2 that did not match anything in binary 1.
  /// Unfortunately, in an LTO build, even a small change can lead to several
  /// LTO variants being unmapped, corresponding to local functions that never
  /// appear in one of the binaries because they were previously inlined.
  void reportUnmapped() {
    outs() << "List of functions from binary 2 that were not matched with any "
           << "function in binary 1:\n";
    for (const auto &BFI2 : RI2.BC->getBinaryFunctions()) {
      const BinaryFunction &Function2 = BFI2.second;
      if (Bin2MappedFuncs.count(&Function2))
        continue;
      outs() << Function2.getPrintName() << "\n";
    }
  }

public:
  /// Main entry point: coordinate all tasks necessary to compare two binaries
  void compareAndReport() {
    buildLookupMaps();
    matchFunctions();
    if (opts::IgnoreLTOSuffix)
      computeAggregatedLTOScore();
    matchBasicBlocks();
    reportHottestFuncDiffs();
    reportHottestBBDiffs();
    reportHottestEdgeDiffs();
    reportHottestFuncs();
    if (!opts::PrintUnmapped)
      return;
    reportUnmapped();
  }

  RewriteInstanceDiff(RewriteInstance &RI1, RewriteInstance &RI2)
      : RI1(RI1), RI2(RI2) {
    compareAndReport();
  }

};

} // end namespace bolt
} // end namespace llvm

void RewriteInstance::compare(RewriteInstance &RI2) {
  outs() << "BOLT-DIFF: ======== Binary1 vs. Binary2 ========\n";
  outs() << "Trace for binary 1 has " << this->getTotalScore()
         << " instructions executed.\n";
  outs() << "Trace for binary 2 has " << RI2.getTotalScore()
         << " instructions executed.\n";
  if (opts::NormalizeByBin1) {
    double Diff2to1 =
        static_cast<double>(RI2.getTotalScore() - this->getTotalScore()) /
        this->getTotalScore();
    outs() << "Binary2 change in score with respect to Binary1: ";
    printColoredPercentage(Diff2to1 * 100.0);
    outs() << "\n";
  }

  if (!this->getTotalScore() || !RI2.getTotalScore()) {
    outs() << "BOLT-DIFF: Both binaries must have recorded activity in known "
              "functions.\n";
    return;
  }

  // Pre-pass ICF
  if (opts::ICF) {
    IdenticalCodeFolding ICF(opts::NeverPrint);
    outs() << "BOLT-DIFF: Starting ICF pass for binary 1";
    BC->logBOLTErrorsAndQuitOnFatal(ICF.runOnFunctions(*BC));
    outs() << "BOLT-DIFF: Starting ICF pass for binary 2";
    BC->logBOLTErrorsAndQuitOnFatal(ICF.runOnFunctions(*RI2.BC));
  }

  RewriteInstanceDiff RID(*this, RI2);
}
