reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
//===- LazyBlockFrequencyInfo.h - Lazy Block Frequency Analysis -*- 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
//
//===----------------------------------------------------------------------===//
//
// This is an alternative analysis pass to BlockFrequencyInfoWrapperPass.  The
// difference is that with this pass the block frequencies are not computed when
// the analysis pass is executed but rather when the BFI result is explicitly
// requested by the analysis client.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H
#define LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H

#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/LazyBranchProbabilityInfo.h"
#include "llvm/Pass.h"

namespace llvm {
class AnalysisUsage;
class BranchProbabilityInfo;
class Function;
class LoopInfo;

/// Wraps a BFI to allow lazy computation of the block frequencies.
///
/// A pass that only conditionally uses BFI can uncondtionally require the
/// analysis without paying for the overhead if BFI doesn't end up being used.
template <typename FunctionT, typename BranchProbabilityInfoPassT,
          typename LoopInfoT, typename BlockFrequencyInfoT>
class LazyBlockFrequencyInfo {
public:
  LazyBlockFrequencyInfo()
      : Calculated(false), F(nullptr), BPIPass(nullptr), LI(nullptr) {}

  /// Set up the per-function input.
  void setAnalysis(const FunctionT *F, BranchProbabilityInfoPassT *BPIPass,
                   const LoopInfoT *LI) {
    this->F = F;
    this->BPIPass = BPIPass;
    this->LI = LI;
  }

  /// Retrieve the BFI with the block frequencies computed.
  BlockFrequencyInfoT &getCalculated() {
    if (!Calculated) {
      assert(F && BPIPass && LI && "call setAnalysis");
      BFI.calculate(
          *F, BPIPassTrait<BranchProbabilityInfoPassT>::getBPI(BPIPass), *LI);
      Calculated = true;
    }
    return BFI;
  }

  const BlockFrequencyInfoT &getCalculated() const {
    return const_cast<LazyBlockFrequencyInfo *>(this)->getCalculated();
  }

  void releaseMemory() {
    BFI.releaseMemory();
    Calculated = false;
    setAnalysis(nullptr, nullptr, nullptr);
  }

private:
  BlockFrequencyInfoT BFI;
  bool Calculated;
  const FunctionT *F;
  BranchProbabilityInfoPassT *BPIPass;
  const LoopInfoT *LI;
};

/// This is an alternative analysis pass to
/// BlockFrequencyInfoWrapperPass.  The difference is that with this pass the
/// block frequencies are not computed when the analysis pass is executed but
/// rather when the BFI result is explicitly requested by the analysis client.
///
/// There are some additional requirements for any client pass that wants to use
/// the analysis:
///
/// 1. The pass needs to initialize dependent passes with:
///
///   INITIALIZE_PASS_DEPENDENCY(LazyBFIPass)
///
/// 2. Similarly, getAnalysisUsage should call:
///
///   LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU)
///
/// 3. The computed BFI should be requested with
///    getAnalysis<LazyBlockFrequencyInfoPass>().getBFI() before either LoopInfo
///    or BPI could be invalidated for example by changing the CFG.
///
/// Note that it is expected that we wouldn't need this functionality for the
/// new PM since with the new PM, analyses are executed on demand.

class LazyBlockFrequencyInfoPass : public FunctionPass {
private:
  LazyBlockFrequencyInfo<Function, LazyBranchProbabilityInfoPass, LoopInfo,
                         BlockFrequencyInfo>
      LBFI;

public:
  static char ID;

  LazyBlockFrequencyInfoPass();

  /// Compute and return the block frequencies.
  BlockFrequencyInfo &getBFI() { return LBFI.getCalculated(); }

  /// Compute and return the block frequencies.
  const BlockFrequencyInfo &getBFI() const { return LBFI.getCalculated(); }

  void getAnalysisUsage(AnalysisUsage &AU) const override;

  /// Helper for client passes to set up the analysis usage on behalf of this
  /// pass.
  static void getLazyBFIAnalysisUsage(AnalysisUsage &AU);

  bool runOnFunction(Function &F) override;
  void releaseMemory() override;
  void print(raw_ostream &OS, const Module *M) const override;
};

/// Helper for client passes to initialize dependent passes for LBFI.
void initializeLazyBFIPassPass(PassRegistry &Registry);
}
#endif