//===-- InsertCodePrefetch.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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Code Prefetch Insertion Pass.
//===----------------------------------------------------------------------===//
/// This pass inserts code prefetch instructions according to the prefetch
/// directives in the basic block section profile. The target of a prefetch can
/// be the beginning of any dynamic basic block, that is the beginning of a
/// machine basic block, or immediately after a callsite. A global symbol is
/// emitted at the position of the target so it can be addressed from the
/// prefetch instruction from any module. In order to insert prefetch hints,
/// `TargetInstrInfo::insertCodePrefetchInstr` must be implemented by the
/// target.
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/InsertCodePrefetch.h"

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/BasicBlockSectionUtils.h"
#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/Object/ELFTypes.h"

using namespace llvm;
#define DEBUG_TYPE "insert-code-prefetch"

SmallString<128> llvm::getPrefetchTargetSymbolName(StringRef FunctionName,
                                                   const UniqueBBID &BBID,
                                                   unsigned CallsiteIndex) {
  SmallString<128> R("__llvm_prefetch_target_");
  R += FunctionName;
  R += "_";
  R += utostr(BBID.BaseID);
  R += "_";
  R += utostr(CallsiteIndex);
  return R;
}

namespace {
class InsertCodePrefetch : public MachineFunctionPass {
public:
  static char ID;

  InsertCodePrefetch() : MachineFunctionPass(ID) {}

  StringRef getPassName() const override {
    return "Code Prefetch Inserter Pass";
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override;

  // Sets prefetch targets based on the bb section profile.
  bool runOnMachineFunction(MachineFunction &MF) override;
};

} // end anonymous namespace

//===----------------------------------------------------------------------===//
//            Implementation
//===----------------------------------------------------------------------===//

char InsertCodePrefetch::ID = 0;
INITIALIZE_PASS_BEGIN(InsertCodePrefetch, DEBUG_TYPE, "Code prefetch insertion",
                      true, false)
INITIALIZE_PASS_DEPENDENCY(BasicBlockSectionsProfileReaderWrapperPass)
INITIALIZE_PASS_END(InsertCodePrefetch, DEBUG_TYPE, "Code prefetch insertion",
                    true, false)

static bool setPrefetchTargets(MachineFunction &MF,
                               const SmallVector<CallsiteID> &PrefetchTargets) {
  if (PrefetchTargets.empty())
    return false;
  // Set each block's prefetch targets so AsmPrinter can emit a special symbol
  // there.
  DenseMap<UniqueBBID, SmallVector<unsigned>> PrefetchTargetsByBBID;
  for (const auto &Target : PrefetchTargets)
    PrefetchTargetsByBBID[Target.BBID].push_back(Target.CallsiteIndex);
  // Sort and uniquify the callsite indices for every block.
  for (auto &[K, V] : PrefetchTargetsByBBID) {
    llvm::sort(V);
    V.erase(llvm::unique(V), V.end());
  }
  MF.setPrefetchTargets(PrefetchTargetsByBBID);
  return true;
}

static bool
insertPrefetchHints(MachineFunction &MF,
                    const SmallVector<PrefetchHint> &PrefetchHints) {
  bool PrefetchInserted = false;
  bool IsELF = MF.getTarget().getTargetTriple().isOSBinFormatELF();
  const Module *M = MF.getFunction().getParent();
  DenseMap<UniqueBBID, SmallVector<PrefetchHint>> PrefetchHintsBySiteBBID;
  for (const auto &H : PrefetchHints)
    PrefetchHintsBySiteBBID[H.SiteID.BBID].push_back(H);
  // Sort prefetch hints by their callsite index so we can insert them by one
  // pass over the block's instructions.
  for (auto &[SiteBBID, Hints] : PrefetchHintsBySiteBBID) {
    llvm::stable_sort(
        Hints, [](const PrefetchHint &H1, const PrefetchHint &H2) {
          return H1.SiteID.CallsiteIndex < H2.SiteID.CallsiteIndex;
        });
  }
  auto PtrTy =
      PointerType::getUnqual(MF.getFunction().getParent()->getContext());
  const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
  for (auto &BB : MF) {
    auto It = PrefetchHintsBySiteBBID.find(*BB.getBBID());
    if (It == PrefetchHintsBySiteBBID.end())
      continue;
    const auto &BBHints = It->second;
    unsigned NumCallsInBB = 0;
    auto InstrIt = BB.begin();
    for (auto HintIt = BBHints.begin(); HintIt != BBHints.end();) {
      auto NextInstrIt = InstrIt == BB.end() ? BB.end() : std::next(InstrIt);
      // Insert all the prefetch hints which must be placed after this call (or
      // at the beginning of the block if `NumCallsInBB` is zero.
      while (HintIt != BBHints.end() &&
             HintIt->SiteID.CallsiteIndex == NumCallsInBB) {
        bool TargetFunctionDefined = false;
        if (Function *TargetFunction = M->getFunction(HintIt->TargetFunction))
          TargetFunctionDefined = !TargetFunction->isDeclaration();

        auto TargetSymbolName = getPrefetchTargetSymbolName(
            HintIt->TargetFunction, HintIt->TargetID.BBID,
            HintIt->TargetID.CallsiteIndex);
        auto *GV = MF.getFunction().getParent()->getOrInsertGlobal(
            TargetSymbolName, PtrTy);
        MachineInstr *PrefetchInstr =
            TII->insertCodePrefetchInstr(BB, InstrIt, GV);
        if (!TargetFunctionDefined && IsELF) {
          // If the target function is not defined in this module, we guard
          // against undefined prefetch target symbol by emitting a fallback
          // symbol with weak linkage right after the prefetch instruction. If
          // there is no strong symbol, the fallback will be used and we
          // prefetch the next address:
          //
          // prefetchit1 __llvm_prefetch_target_foo_x_y(%rip)
          // .weak __llvm_prefetch_target_foo_x_y
          // __llvm_prefetch_target_foo_x_y:
          MCSymbolELF *WeakFallbackSym = static_cast<MCSymbolELF *>(
              MF.getContext().getOrCreateSymbol(TargetSymbolName));
          WeakFallbackSym->setBinding(ELF::STB_WEAK);
          PrefetchInstr->setPostInstrSymbol(MF, WeakFallbackSym);
        }
        PrefetchInserted = true;
        ++HintIt;
      }
      if (InstrIt == BB.end())
        break;
      if (InstrIt->isCall())
        ++NumCallsInBB;
      InstrIt = NextInstrIt;
    }
  }
  return PrefetchInserted;
}

bool InsertCodePrefetch::runOnMachineFunction(MachineFunction &MF) {
  assert(MF.getTarget().getBBSectionsType() == BasicBlockSection::List &&
         "BB Sections list not enabled!");
  if (hasInstrProfHashMismatch(MF))
    return false;

  auto &ProfileReader =
      getAnalysis<BasicBlockSectionsProfileReaderWrapperPass>();
  bool R = setPrefetchTargets(
      MF, ProfileReader.getPrefetchTargetsForFunction(MF.getName()));
  bool S = insertPrefetchHints(
      MF, ProfileReader.getPrefetchHintsForFunction(MF.getName()));
  return R || S;
}

void InsertCodePrefetch::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AU.addRequired<BasicBlockSectionsProfileReaderWrapperPass>();
  MachineFunctionPass::getAnalysisUsage(AU);
}

MachineFunctionPass *llvm::createInsertCodePrefetchPass() {
  return new InsertCodePrefetch();
}
