//===-- SnippetRepetitor.cpp ------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "SnippetRepetitor.h"
#include "Target.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"

namespace llvm {
namespace exegesis {
namespace {

class DuplicateSnippetRepetitor : public SnippetRepetitor {
public:
  using SnippetRepetitor::SnippetRepetitor;

  // Repeats the snippet until there are at least MinInstructions in the
  // resulting code.
  FillFunction Repeat(ArrayRef<MCInst> Instructions, unsigned MinInstructions,
                      unsigned LoopBodySize,
                      bool CleanupMemory) const override {
    return [this, Instructions, MinInstructions,
            CleanupMemory](FunctionFiller &Filler) {
      auto Entry = Filler.getEntry();
      if (!Instructions.empty()) {
        // Add the whole snippet at least once.
        Entry.addInstructions(Instructions);
        for (unsigned I = Instructions.size(); I < MinInstructions; ++I) {
          Entry.addInstruction(Instructions[I % Instructions.size()]);
        }
      }
      Entry.addReturn(State.getExegesisTarget(), CleanupMemory);
    };
  }

  BitVector getReservedRegs() const override {
    // We're using no additional registers.
    return State.getRATC().emptyRegisters();
  }
};

class LoopSnippetRepetitor : public SnippetRepetitor {
public:
  explicit LoopSnippetRepetitor(const LLVMState &State)
      : SnippetRepetitor(State),
        LoopCounter(State.getExegesisTarget().getLoopCounterRegister(
            State.getTargetMachine().getTargetTriple())) {}

  // Loop over the snippet ceil(MinInstructions / Instructions.Size()) times.
  FillFunction Repeat(ArrayRef<MCInst> Instructions, unsigned MinInstructions,
                      unsigned LoopBodySize,
                      bool CleanupMemory) const override {
    return [this, Instructions, MinInstructions, LoopBodySize,
            CleanupMemory](FunctionFiller &Filler) {
      const auto &ET = State.getExegesisTarget();
      auto Entry = Filler.getEntry();

      // We can not use loop snippet repetitor for terminator instructions.
      for (const MCInst &Inst : Instructions) {
        const unsigned Opcode = Inst.getOpcode();
        const MCInstrDesc &MCID = Filler.MCII->get(Opcode);
        if (!MCID.isTerminator())
          continue;
        Entry.addReturn(State.getExegesisTarget(), CleanupMemory);
        return;
      }

      auto Loop = Filler.addBasicBlock();
      auto Exit = Filler.addBasicBlock();

      const unsigned LoopUnrollFactor =
          LoopBodySize <= Instructions.size()
              ? 1
              : divideCeil(LoopBodySize, Instructions.size());
      assert(LoopUnrollFactor >= 1 && "Should end up with at least 1 snippet.");

      // Set loop counter to the right value:
      const APInt LoopCount(
          32,
          divideCeil(MinInstructions, LoopUnrollFactor * Instructions.size()));
      assert(LoopCount.uge(1) && "Trip count should be at least 1.");
      for (const MCInst &Inst :
           ET.setRegTo(State.getSubtargetInfo(), LoopCounter, LoopCount))
        Entry.addInstruction(Inst);

      // Set up the loop basic block.
      Entry.MBB->addSuccessor(Loop.MBB, BranchProbability::getOne());
      Loop.MBB->addSuccessor(Loop.MBB, BranchProbability::getOne());
      // If the snippet setup completed, then we can track liveness.
      if (Loop.MF.getProperties().hasProperty(
              MachineFunctionProperties::Property::TracksLiveness)) {
        // The live ins are: the loop counter, the registers that were setup by
        // the entry block, and entry block live ins.
        Loop.MBB->addLiveIn(LoopCounter);
        for (unsigned Reg : Filler.getRegistersSetUp())
          Loop.MBB->addLiveIn(Reg);
        for (const auto &LiveIn : Entry.MBB->liveins())
          Loop.MBB->addLiveIn(LiveIn);
      }
      for (auto _ : seq(LoopUnrollFactor)) {
        (void)_;
        Loop.addInstructions(Instructions);
      }
      ET.decrementLoopCounterAndJump(*Loop.MBB, *Loop.MBB,
                                     State.getInstrInfo());

      // Set up the exit basic block.
      Loop.MBB->addSuccessor(Exit.MBB, BranchProbability::getZero());
      Exit.addReturn(State.getExegesisTarget(), CleanupMemory);
    };
  }

  BitVector getReservedRegs() const override {
    // We're using a single loop counter, but we have to reserve all aliasing
    // registers.
    return State.getRATC().getRegister(LoopCounter).aliasedBits();
  }

private:
  const unsigned LoopCounter;
};

} // namespace

SnippetRepetitor::~SnippetRepetitor() {}

std::unique_ptr<const SnippetRepetitor>
SnippetRepetitor::Create(Benchmark::RepetitionModeE Mode,
                         const LLVMState &State) {
  switch (Mode) {
  case Benchmark::Duplicate:
    return std::make_unique<DuplicateSnippetRepetitor>(State);
  case Benchmark::Loop:
    return std::make_unique<LoopSnippetRepetitor>(State);
  case Benchmark::AggregateMin:
    break;
  }
  llvm_unreachable("Unknown RepetitionModeE enum");
}

} // namespace exegesis
} // namespace llvm
