//===-- R600TargetMachine.cpp - TargetMachine for hw codegen targets-------===//
//
// 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
/// This file contains both AMDGPU-R600 target machine and the CodeGen pass
/// builder. The target machine contains all of the hardware specific
/// information needed to emit code for R600 GPUs and the CodeGen pass builder
/// handles the pass pipeline for new pass manager.
//
//===----------------------------------------------------------------------===//

#include "R600TargetMachine.h"
#include "R600.h"
#include "R600MachineFunctionInfo.h"
#include "R600MachineScheduler.h"
#include "R600TargetTransformInfo.h"
#include "llvm/Passes/CodeGenPassBuilder.h"
#include "llvm/Transforms/Scalar.h"
#include <optional>

using namespace llvm;

static cl::opt<bool>
    EnableR600StructurizeCFG("r600-ir-structurize",
                             cl::desc("Use StructurizeCFG IR pass"),
                             cl::init(true));

static cl::opt<bool> EnableR600IfConvert("r600-if-convert",
                                         cl::desc("Use if conversion pass"),
                                         cl::ReallyHidden, cl::init(true));

static cl::opt<bool, true> EnableAMDGPUFunctionCallsOpt(
    "amdgpu-function-calls", cl::desc("Enable AMDGPU function call support"),
    cl::location(AMDGPUTargetMachine::EnableFunctionCalls), cl::init(true),
    cl::Hidden);

static ScheduleDAGInstrs *createR600MachineScheduler(MachineSchedContext *C) {
  return new ScheduleDAGMILive(C, std::make_unique<R600SchedStrategy>());
}

static MachineSchedRegistry R600SchedRegistry("r600",
                                              "Run R600's custom scheduler",
                                              createR600MachineScheduler);

//===----------------------------------------------------------------------===//
// R600 CodeGen Pass Builder interface.
//===----------------------------------------------------------------------===//

class R600CodeGenPassBuilder
    : public CodeGenPassBuilder<R600CodeGenPassBuilder, R600TargetMachine> {
public:
  R600CodeGenPassBuilder(R600TargetMachine &TM, const CGPassBuilderOption &Opts,
                         PassInstrumentationCallbacks *PIC);

  void addPreISel(PassManagerWrapper &PMW) const;
  void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
  void addAsmPrinter(PassManagerWrapper &PMW) const;
  void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
  Error addInstSelector(PassManagerWrapper &PMW) const;
};

//===----------------------------------------------------------------------===//
// R600 Target Machine (R600 -> Cayman)
//===----------------------------------------------------------------------===//

R600TargetMachine::R600TargetMachine(const Target &T, const Triple &TT,
                                     StringRef CPU, StringRef FS,
                                     const TargetOptions &Options,
                                     std::optional<Reloc::Model> RM,
                                     std::optional<CodeModel::Model> CM,
                                     CodeGenOptLevel OL, bool JIT)
    : AMDGPUTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL) {
  setRequiresStructuredCFG(true);

  // Override the default since calls aren't supported for r600.
  if (EnableFunctionCalls &&
      EnableAMDGPUFunctionCallsOpt.getNumOccurrences() == 0)
    EnableFunctionCalls = false;
}

const TargetSubtargetInfo *
R600TargetMachine::getSubtargetImpl(const Function &F) const {
  StringRef GPU = getGPUName(F);
  StringRef FS = getFeatureString(F);

  SmallString<128> SubtargetKey(GPU);
  SubtargetKey.append(FS);

  auto &I = SubtargetMap[SubtargetKey];
  if (!I)
    I = std::make_unique<R600Subtarget>(TargetTriple, GPU, FS, *this);

  return I.get();
}

TargetTransformInfo
R600TargetMachine::getTargetTransformInfo(const Function &F) const {
  return TargetTransformInfo(std::make_unique<R600TTIImpl>(this, F));
}

ScheduleDAGInstrs *
R600TargetMachine::createMachineScheduler(MachineSchedContext *C) const {
  return createR600MachineScheduler(C);
}

namespace {
class R600PassConfig final : public AMDGPUPassConfig {
public:
  R600PassConfig(TargetMachine &TM, PassManagerBase &PM)
      : AMDGPUPassConfig(TM, PM) {}

  bool addPreISel() override;
  bool addInstSelector() override;
  void addPreRegAlloc() override;
  void addPreSched2() override;
  void addPreEmitPass() override;
};
} // namespace

//===----------------------------------------------------------------------===//
// R600 Pass Setup
//===----------------------------------------------------------------------===//

bool R600PassConfig::addPreISel() {
  AMDGPUPassConfig::addPreISel();

  if (EnableR600StructurizeCFG)
    addPass(createStructurizeCFGPass());
  return false;
}

bool R600PassConfig::addInstSelector() {
  addPass(createR600ISelDag(getAMDGPUTargetMachine(), getOptLevel()));
  return false;
}

void R600PassConfig::addPreRegAlloc() { addPass(createR600VectorRegMerger()); }

void R600PassConfig::addPreSched2() {
  addPass(createR600EmitClauseMarkers());
  if (EnableR600IfConvert)
    addPass(&IfConverterID);
  addPass(createR600ClauseMergePass());
}

void R600PassConfig::addPreEmitPass() {
  addPass(createR600MachineCFGStructurizerPass());
  addPass(createR600ExpandSpecialInstrsPass());
  addPass(createR600Packetizer());
  addPass(createR600ControlFlowFinalizer());
}

TargetPassConfig *R600TargetMachine::createPassConfig(PassManagerBase &PM) {
  return new R600PassConfig(*this, PM);
}

Error R600TargetMachine::buildCodeGenPipeline(
    ModulePassManager &MPM, ModuleAnalysisManager &MAM, raw_pwrite_stream &Out,
    raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
    const CGPassBuilderOption &Opts, MCContext &Ctx,
    PassInstrumentationCallbacks *PIC) {
  R600CodeGenPassBuilder CGPB(*this, Opts, PIC);
  return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
}

MachineFunctionInfo *R600TargetMachine::createMachineFunctionInfo(
    BumpPtrAllocator &Allocator, const Function &F,
    const TargetSubtargetInfo *STI) const {
  return R600MachineFunctionInfo::create<R600MachineFunctionInfo>(
      Allocator, F, static_cast<const R600Subtarget *>(STI));
}

//===----------------------------------------------------------------------===//
// R600 CodeGen Pass Builder interface.
//===----------------------------------------------------------------------===//

R600CodeGenPassBuilder::R600CodeGenPassBuilder(
    R600TargetMachine &TM, const CGPassBuilderOption &Opts,
    PassInstrumentationCallbacks *PIC)
    : CodeGenPassBuilder(TM, Opts, PIC) {
  Opt.RequiresCodeGenSCCOrder = true;
}

void R600CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
  // TODO: Add passes pre instruction selection.
}

void R600CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
  // TODO: Add AsmPrinterBegin
}

void R600CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
  // TODO: Add AsmPrinter.
}

void R600CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
  // TODO: Add AsmPrinterEnd
}

Error R600CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
  // TODO: Add instruction selector.
  return Error::success();
}
