//===---------- MachinePassManager.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
//
//===----------------------------------------------------------------------===//
//
// This file contains the pass management machinery for machine functions.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/PassManagerImpl.h"

using namespace llvm;

namespace llvm {
template class AllAnalysesOn<MachineFunction>;
template class AnalysisManager<MachineFunction>;
template class PassManager<MachineFunction>;

Error MachineFunctionPassManager::run(Module &M,
                                      MachineFunctionAnalysisManager &MFAM) {
  // MachineModuleAnalysis is a module analysis pass that is never invalidated
  // because we don't run any module pass in codegen pipeline. This is very
  // important because the codegen state is stored in MMI which is the analysis
  // result of MachineModuleAnalysis. MMI should not be recomputed.
  auto &MMI = MFAM.getResult<MachineModuleAnalysis>(M);

  (void)RequireCodeGenSCCOrder;
  assert(!RequireCodeGenSCCOrder && "not implemented");

  // Add a PIC to verify machine functions.
  if (VerifyMachineFunction) {
    PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(M);

    // No need to pop this callback later since MIR pipeline is flat which means
    // current pipeline is the top-level pipeline. Callbacks are not used after
    // current pipeline.
    PI.pushBeforeNonSkippedPassCallback([&MFAM](StringRef PassID, Any IR) {
      assert(any_cast<const MachineFunction *>(&IR));
      const MachineFunction *MF = any_cast<const MachineFunction *>(IR);
      assert(MF && "Machine function should be valid for printing");
      std::string Banner = std::string("After ") + std::string(PassID);
      verifyMachineFunction(&MFAM, Banner, *MF);
    });
  }

  for (auto &F : InitializationFuncs) {
    if (auto Err = F(M, MFAM))
      return Err;
  }

  unsigned Idx = 0;
  size_t Size = Passes.size();
  do {
    // Run machine module passes
    for (; MachineModulePasses.count(Idx) && Idx != Size; ++Idx) {
      if (auto Err = MachineModulePasses.at(Idx)(M, MFAM))
        return Err;
    }

    // Finish running all passes.
    if (Idx == Size)
      break;

    // Run machine function passes

    // Get index range of machine function passes.
    unsigned Begin = Idx;
    for (; !MachineModulePasses.count(Idx) && Idx != Size; ++Idx)
      ;

    for (Function &F : M) {
      // Do not codegen any 'available_externally' functions at all, they have
      // definitions outside the translation unit.
      if (F.hasAvailableExternallyLinkage())
        continue;

      MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
      PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF);

      for (unsigned I = Begin, E = Idx; I != E; ++I) {
        auto *P = Passes[I].get();

        if (!PI.runBeforePass<MachineFunction>(*P, MF))
          continue;

        // TODO: EmitSizeRemarks
        PreservedAnalyses PassPA = P->run(MF, MFAM);
        PI.runAfterPass(*P, MF, PassPA);
        MFAM.invalidate(MF, PassPA);
      }
    }
  } while (true);

  for (auto &F : FinalizationFuncs) {
    if (auto Err = F(M, MFAM))
      return Err;
  }

  return Error::success();
}

} // namespace llvm
