//===- SplitModule.cpp - Split a module into partitions -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the function llvm::SplitModule, which splits a module
// into multiple linkable partitions. It can be used to implement parallel code
// generation for link-time optimization.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "split-module"

#include "llvm/Transforms/Utils/SplitModule.h"
#include "llvm/ADT/EquivalenceClasses.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include <queue>

using namespace llvm;

namespace {
typedef EquivalenceClasses<const GlobalValue *> ClusterMapType;
typedef DenseMap<const Comdat *, const GlobalValue *> ComdatMembersType;
typedef DenseMap<const GlobalValue *, unsigned> ClusterIDMapType;
}

static void addNonConstUser(ClusterMapType &GVtoClusterMap,
                            const GlobalValue *GV, const User *U) {
  assert((!isa<Constant>(U) || isa<GlobalValue>(U)) && "Bad user");

  if (const Instruction *I = dyn_cast<Instruction>(U)) {
    const GlobalValue *F = I->getParent()->getParent();
    GVtoClusterMap.unionSets(GV, F);
  } else if (isa<GlobalAlias>(U) || isa<Function>(U) ||
             isa<GlobalVariable>(U)) {
    GVtoClusterMap.unionSets(GV, cast<GlobalValue>(U));
  } else {
    llvm_unreachable("Underimplemented use case");
  }
}

// Adds all GlobalValue users of V to the same cluster as GV.
static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap,
                                   const GlobalValue *GV, const Value *V) {
  for (auto *U : V->users()) {
    SmallVector<const User *, 4> Worklist;
    Worklist.push_back(U);
    while (!Worklist.empty()) {
      const User *UU = Worklist.pop_back_val();
      // For each constant that is not a GV (a pure const) recurse.
      if (isa<Constant>(UU) && !isa<GlobalValue>(UU)) {
        Worklist.append(UU->user_begin(), UU->user_end());
        continue;
      }
      addNonConstUser(GVtoClusterMap, GV, UU);
    }
  }
}

// Find partitions for module in the way that no locals need to be
// globalized.
// Try to balance pack those partitions into N files since this roughly equals
// thread balancing for the backend codegen step.
static void findPartitions(Module *M, ClusterIDMapType &ClusterIDMap,
                           unsigned N) {
  // At this point module should have the proper mix of globals and locals.
  // As we attempt to partition this module, we must not change any
  // locals to globals.
  DEBUG(dbgs() << "Partition module with (" << M->size() << ")functions\n");
  ClusterMapType GVtoClusterMap;
  ComdatMembersType ComdatMembers;

  auto recordGVSet = [&GVtoClusterMap, &ComdatMembers](GlobalValue &GV) {
    if (GV.isDeclaration())
      return;

    if (!GV.hasName())
      GV.setName("__llvmsplit_unnamed");

    // Comdat groups must not be partitioned. For comdat groups that contain
    // locals, record all their members here so we can keep them together.
    // Comdat groups that only contain external globals are already handled by
    // the MD5-based partitioning.
    if (const Comdat *C = GV.getComdat()) {
      auto &Member = ComdatMembers[C];
      if (Member)
        GVtoClusterMap.unionSets(Member, &GV);
      else
        Member = &GV;
    }

    // For aliases we should not separate them from their aliasees regardless
    // of linkage.
    if (GlobalAlias *GA = dyn_cast<GlobalAlias>(&GV)) {
      if (const GlobalObject *Base = GA->getBaseObject())
        GVtoClusterMap.unionSets(&GV, Base);
    }

    if (const Function *F = dyn_cast<Function>(&GV)) {
      for (const BasicBlock &BB : *F) {
        BlockAddress *BA = BlockAddress::lookup(&BB);
        if (!BA || !BA->isConstantUsed())
          continue;
        addAllGlobalValueUsers(GVtoClusterMap, F, BA);
      }
    }

    if (GV.hasLocalLinkage())
      addAllGlobalValueUsers(GVtoClusterMap, &GV, &GV);
  };

  std::for_each(M->begin(), M->end(), recordGVSet);
  std::for_each(M->global_begin(), M->global_end(), recordGVSet);
  std::for_each(M->alias_begin(), M->alias_end(), recordGVSet);

  // Assigned all GVs to merged clusters while balancing number of objects in
  // each.
  auto CompareClusters = [](const std::pair<unsigned, unsigned> &a,
                            const std::pair<unsigned, unsigned> &b) {
    if (a.second || b.second)
      return a.second > b.second;
    else
      return a.first > b.first;
  };

  std::priority_queue<std::pair<unsigned, unsigned>,
                      std::vector<std::pair<unsigned, unsigned>>,
                      decltype(CompareClusters)>
      BalancinQueue(CompareClusters);
  // Pre-populate priority queue with N slot blanks.
  for (unsigned i = 0; i < N; ++i)
    BalancinQueue.push(std::make_pair(i, 0));

  typedef std::pair<unsigned, ClusterMapType::iterator> SortType;
  SmallVector<SortType, 64> Sets;
  SmallPtrSet<const GlobalValue *, 32> Visited;

  // To guarantee determinism, we have to sort SCC according to size.
  // When size is the same, use leader's name.
  for (ClusterMapType::iterator I = GVtoClusterMap.begin(),
                                E = GVtoClusterMap.end(); I != E; ++I)
    if (I->isLeader())
      Sets.push_back(
          std::make_pair(std::distance(GVtoClusterMap.member_begin(I),
                                       GVtoClusterMap.member_end()), I));

  std::sort(Sets.begin(), Sets.end(), [](const SortType &a, const SortType &b) {
    if (a.first == b.first)
      return a.second->getData()->getName() > b.second->getData()->getName();
    else
      return a.first > b.first;
  });

  for (auto &I : Sets) {
    unsigned CurrentClusterID = BalancinQueue.top().first;
    unsigned CurrentClusterSize = BalancinQueue.top().second;
    BalancinQueue.pop();

    DEBUG(dbgs() << "Root[" << CurrentClusterID << "] cluster_size(" << I.first
                 << ") ----> " << I.second->getData()->getName() << "\n");

    for (ClusterMapType::member_iterator MI =
             GVtoClusterMap.findLeader(I.second);
         MI != GVtoClusterMap.member_end(); ++MI) {
      if (!Visited.insert(*MI).second)
        continue;
      DEBUG(dbgs() << "----> " << (*MI)->getName()
                   << ((*MI)->hasLocalLinkage() ? " l " : " e ") << "\n");
      Visited.insert(*MI);
      ClusterIDMap[*MI] = CurrentClusterID;
      CurrentClusterSize++;
    }
    // Add this set size to the number of entries in this cluster.
    BalancinQueue.push(std::make_pair(CurrentClusterID, CurrentClusterSize));
  }
}

static void externalize(GlobalValue *GV) {
  if (GV->hasLocalLinkage()) {
    GV->setLinkage(GlobalValue::ExternalLinkage);
    GV->setVisibility(GlobalValue::HiddenVisibility);
  }

  // Unnamed entities must be named consistently between modules. setName will
  // give a distinct name to each such entity.
  if (!GV->hasName())
    GV->setName("__llvmsplit_unnamed");
}

// Returns whether GV should be in partition (0-based) I of N.
static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N) {
  if (auto GA = dyn_cast<GlobalAlias>(GV))
    if (const GlobalObject *Base = GA->getBaseObject())
      GV = Base;

  StringRef Name;
  if (const Comdat *C = GV->getComdat())
    Name = C->getName();
  else
    Name = GV->getName();

  // Partition by MD5 hash. We only need a few bits for evenness as the number
  // of partitions will generally be in the 1-2 figure range; the low 16 bits
  // are enough.
  MD5 H;
  MD5::MD5Result R;
  H.update(Name);
  H.final(R);
  return (R[0] | (R[1] << 8)) % N == I;
}

void llvm::SplitModule(
    std::unique_ptr<Module> M, unsigned N,
    std::function<void(std::unique_ptr<Module> MPart)> ModuleCallback,
    bool PreserveLocals) {
  if (!PreserveLocals) {
    for (Function &F : *M)
      externalize(&F);
    for (GlobalVariable &GV : M->globals())
      externalize(&GV);
    for (GlobalAlias &GA : M->aliases())
      externalize(&GA);
  }

  // This performs splitting without a need for externalization, which might not
  // always be possible.
  ClusterIDMapType ClusterIDMap;
  findPartitions(M.get(), ClusterIDMap, N);

  // FIXME: We should be able to reuse M as the last partition instead of
  // cloning it.
  for (unsigned I = 0; I < N; ++I) {
    ValueToValueMapTy VMap;
    std::unique_ptr<Module> MPart(
        CloneModule(M.get(), VMap, [&](const GlobalValue *GV) {
          if (ClusterIDMap.count(GV))
            return (ClusterIDMap[GV] == I);
          else
            return isInPartition(GV, I, N);
        }));
    if (I != 0)
      MPart->setModuleInlineAsm("");
    ModuleCallback(std::move(MPart));
  }
}
