//===- StaticDataSplitter.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
//
//===----------------------------------------------------------------------===//
//
// The pass uses branch profile data to assign hotness based section qualifiers
// for the following types of static data:
// - Jump tables
// - Constant pools (TODO)
// - Other module-internal data (TODO)
//
// For the original RFC of this pass please see
// https://discourse.llvm.org/t/rfc-profile-guided-static-data-partitioning/83744

#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/CodeGen/MBFIWrapper.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"

using namespace llvm;

#define DEBUG_TYPE "static-data-splitter"

STATISTIC(NumHotJumpTables, "Number of hot jump tables seen");
STATISTIC(NumColdJumpTables, "Number of cold jump tables seen");
STATISTIC(NumUnknownJumpTables,
          "Number of jump tables with unknown hotness. Option "
          "-static-data-default-hotness specifies the hotness.");

static cl::opt<MachineFunctionDataHotness> StaticDataDefaultHotness(
    "static-data-default-hotness", cl::Hidden,
    cl::desc("This option specifies the hotness of static data when profile "
             "information is unavailable"),
    cl::init(MachineFunctionDataHotness::Hot),
    cl::values(clEnumValN(MachineFunctionDataHotness::Hot, "hot", "Hot"),
               clEnumValN(MachineFunctionDataHotness::Cold, "cold", "Cold")));

class StaticDataSplitter : public MachineFunctionPass {
  const MachineBranchProbabilityInfo *MBPI = nullptr;
  const MachineBlockFrequencyInfo *MBFI = nullptr;
  const ProfileSummaryInfo *PSI = nullptr;

  // Returns true iff any jump table is hot-cold categorized.
  bool splitJumpTables(MachineFunction &MF);

  // Same as above but works on functions with profile information.
  bool splitJumpTablesWithProfiles(const MachineFunction &MF,
                                   MachineJumpTableInfo &MJTI);

public:
  static char ID;

  StaticDataSplitter() : MachineFunctionPass(ID) {
    initializeStaticDataSplitterPass(*PassRegistry::getPassRegistry());
  }

  StringRef getPassName() const override { return "Static Data Splitter"; }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    MachineFunctionPass::getAnalysisUsage(AU);
    AU.addRequired<MachineBranchProbabilityInfoWrapperPass>();
    AU.addRequired<MachineBlockFrequencyInfoWrapperPass>();
    AU.addRequired<ProfileSummaryInfoWrapperPass>();
  }

  bool runOnMachineFunction(MachineFunction &MF) override;
};

bool StaticDataSplitter::runOnMachineFunction(MachineFunction &MF) {
  MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
  MBFI = &getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
  PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();

  return splitJumpTables(MF);
}

bool StaticDataSplitter::splitJumpTablesWithProfiles(
    const MachineFunction &MF, MachineJumpTableInfo &MJTI) {
  int NumChangedJumpTables = 0;

  // Jump table could be used by either terminating instructions or
  // non-terminating ones, so we walk all instructions and use
  // `MachineOperand::isJTI()` to identify jump table operands.
  // Similarly, `MachineOperand::isCPI()` can identify constant pool usages
  // in the same loop.
  for (const auto &MBB : MF) {
    for (const MachineInstr &I : MBB) {
      for (const MachineOperand &Op : I.operands()) {
        if (!Op.isJTI())
          continue;
        const int JTI = Op.getIndex();
        // This is not a source block of jump table.
        if (JTI == -1)
          continue;

        auto Hotness = MachineFunctionDataHotness::Hot;

        // Hotness is based on source basic block hotness.
        // TODO: PSI APIs are about instruction hotness. Introduce API for data
        // access hotness.
        if (PSI->isColdBlock(&MBB, MBFI))
          Hotness = MachineFunctionDataHotness::Cold;

        if (MJTI.updateJumpTableEntryHotness(JTI, Hotness))
          ++NumChangedJumpTables;
      }
    }
  }
  return NumChangedJumpTables > 0;
}

bool StaticDataSplitter::splitJumpTables(MachineFunction &MF) {
  MachineJumpTableInfo *MJTI = MF.getJumpTableInfo();
  if (!MJTI || MJTI->getJumpTables().empty())
    return false;

  const bool ProfileAvailable = PSI && PSI->hasProfileSummary() && MBFI &&
                                MF.getFunction().hasProfileData();
  auto statOnExit = llvm::make_scope_exit([&] {
    if (!AreStatisticsEnabled())
      return;

    if (!ProfileAvailable) {
      NumUnknownJumpTables += MJTI->getJumpTables().size();
      return;
    }

    for (size_t JTI = 0; JTI < MJTI->getJumpTables().size(); JTI++) {
      auto Hotness = MJTI->getJumpTables()[JTI].Hotness;
      if (Hotness == MachineFunctionDataHotness::Hot) {
        ++NumHotJumpTables;
      } else {
        assert(Hotness == MachineFunctionDataHotness::Cold &&
               "A jump table is either hot or cold when profile information is "
               "available.");
        ++NumColdJumpTables;
      }
    }
  });

  // Place jump tables according to block hotness if function has profile data.
  if (ProfileAvailable)
    return splitJumpTablesWithProfiles(MF, *MJTI);

  // If function profile is unavailable (e.g., module not instrumented, or new
  // code paths lacking samples), -static-data-default-hotness specifies the
  // hotness.
  for (size_t JTI = 0; JTI < MJTI->getJumpTables().size(); JTI++)
    MF.getJumpTableInfo()->updateJumpTableEntryHotness(
        JTI, StaticDataDefaultHotness);

  return true;
}

char StaticDataSplitter::ID = 0;

INITIALIZE_PASS_BEGIN(StaticDataSplitter, DEBUG_TYPE, "Split static data",
                      false, false)
INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
INITIALIZE_PASS_END(StaticDataSplitter, DEBUG_TYPE, "Split static data", false,
                    false)

MachineFunctionPass *llvm::createStaticDataSplitterPass() {
  return new StaticDataSplitter();
}
