//===- ScopPass.cpp - The base class of Passes that operate on Polly IR ---===//
//
// 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 definitions of the ScopPass members.
//
//===----------------------------------------------------------------------===//

#include "polly/ScopPass.h"
#include "polly/ScopInfo.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/LazyBranchProbabilityInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/Analysis/TargetTransformInfo.h"

using namespace llvm;
using namespace polly;

bool ScopPass::runOnRegion(Region *R, RGPassManager &RGM) {
  S = nullptr;

  if (skipRegion(*R))
    return false;

  if ((S = getAnalysis<ScopInfoRegionPass>().getScop()))
    return runOnScop(*S);

  return false;
}

void ScopPass::print(raw_ostream &OS, const Module *M) const {
  if (S)
    printScop(OS, *S);
}

void ScopPass::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<ScopInfoRegionPass>();

  AU.addPreserved<AAResultsWrapperPass>();
  AU.addPreserved<BasicAAWrapperPass>();
  AU.addPreserved<LoopInfoWrapperPass>();
  AU.addPreserved<DominatorTreeWrapperPass>();
  AU.addPreserved<GlobalsAAWrapperPass>();
  AU.addPreserved<ScopDetectionWrapperPass>();
  AU.addPreserved<ScalarEvolutionWrapperPass>();
  AU.addPreserved<SCEVAAWrapperPass>();
  AU.addPreserved<OptimizationRemarkEmitterWrapperPass>();
  AU.addPreserved<LazyBlockFrequencyInfoPass>();
  AU.addPreserved<LazyBranchProbabilityInfoPass>();
  AU.addPreserved<RegionInfoPass>();
  AU.addPreserved<ScopInfoRegionPass>();
  AU.addPreserved<TargetTransformInfoWrapperPass>();
}

namespace polly {
template class OwningInnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
}

namespace llvm {

template class PassManager<Scop, ScopAnalysisManager,
                           ScopStandardAnalysisResults &, SPMUpdater &>;
template class InnerAnalysisManagerProxy<ScopAnalysisManager, Function>;
template class OuterAnalysisManagerProxy<FunctionAnalysisManager, Scop,
                                         ScopStandardAnalysisResults &>;

template <>
PreservedAnalyses
PassManager<Scop, ScopAnalysisManager, ScopStandardAnalysisResults &,
            SPMUpdater &>::run(Scop &S, ScopAnalysisManager &AM,
                               ScopStandardAnalysisResults &AR, SPMUpdater &U) {
  auto PA = PreservedAnalyses::all();
  for (auto &Pass : Passes) {
    auto PassPA = Pass->run(S, AM, AR, U);

    AM.invalidate(S, PassPA);
    PA.intersect(std::move(PassPA));
  }

  // All analyses for 'this' Scop have been invalidated above.
  // If ScopPasses affect break other scops they have to propagate this
  // information through the updater
  PA.preserveSet<AllAnalysesOn<Scop>>();
  return PA;
}

bool ScopAnalysisManagerFunctionProxy::Result::invalidate(
    Function &F, const PreservedAnalyses &PA,
    FunctionAnalysisManager::Invalidator &Inv) {

  // First, check whether our ScopInfo is about to be invalidated
  auto PAC = PA.getChecker<ScopAnalysisManagerFunctionProxy>();
  if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
      Inv.invalidate<ScopInfoAnalysis>(F, PA) ||
      Inv.invalidate<ScalarEvolutionAnalysis>(F, PA) ||
      Inv.invalidate<LoopAnalysis>(F, PA) ||
      Inv.invalidate<DominatorTreeAnalysis>(F, PA)) {

    // As everything depends on ScopInfo, we must drop all existing results
    for (auto &S : *SI)
      if (auto *scop = S.second.get())
        if (InnerAM)
          InnerAM->clear(*scop, scop->getName());

    InnerAM = nullptr;
    return true; // Invalidate the proxy result as well.
  }

  bool allPreserved = PA.allAnalysesInSetPreserved<AllAnalysesOn<Scop>>();

  // Invalidate all non-preserved analyses
  // Even if all analyses were preserved, we still need to run deferred
  // invalidation
  for (auto &S : *SI) {
    Optional<PreservedAnalyses> InnerPA;
    auto *scop = S.second.get();
    if (!scop)
      continue;

    if (auto *OuterProxy =
            InnerAM->getCachedResult<FunctionAnalysisManagerScopProxy>(*scop)) {
      for (const auto &InvPair : OuterProxy->getOuterInvalidations()) {
        auto *OuterAnalysisID = InvPair.first;
        const auto &InnerAnalysisIDs = InvPair.second;

        if (Inv.invalidate(OuterAnalysisID, F, PA)) {
          if (!InnerPA)
            InnerPA = PA;
          for (auto *InnerAnalysisID : InnerAnalysisIDs)
            InnerPA->abandon(InnerAnalysisID);
        }
      }

      if (InnerPA) {
        InnerAM->invalidate(*scop, *InnerPA);
        continue;
      }
    }

    if (!allPreserved)
      InnerAM->invalidate(*scop, PA);
  }

  return false; // This proxy is still valid
}

template <>
ScopAnalysisManagerFunctionProxy::Result
ScopAnalysisManagerFunctionProxy::run(Function &F,
                                      FunctionAnalysisManager &FAM) {
  return Result(*InnerAM, FAM.getResult<ScopInfoAnalysis>(F));
}
} // namespace llvm

namespace polly {
template <>
OwningScopAnalysisManagerFunctionProxy::Result
OwningScopAnalysisManagerFunctionProxy::run(Function &F,
                                            FunctionAnalysisManager &FAM) {
  return Result(InnerAM, FAM.getResult<ScopInfoAnalysis>(F));
}
} // namespace polly
