[llvm] r275250 - [BFI] Add new LazyBFI analysis pass

Adam Nemet via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 12 22:01:48 PDT 2016


Author: anemet
Date: Wed Jul 13 00:01:48 2016
New Revision: 275250

URL: http://llvm.org/viewvc/llvm-project?rev=275250&view=rev
Log:
[BFI] Add new LazyBFI analysis pass

Summary:
This is necessary for D21771.  In order to add the hotness attribute to
optimization remarks we need BFI to be available in all passes that emit
optimization remarks.

However we don't want to pay for computing BFI unless the hotness
attribute is requested.

This is achieved by making BFI lazy at the very high-level through a new
analysis pass -- BFI is not calculated unless requested.

I am adding a test to check the laziness under D21771 where the first
user of the analysis is added.

Reviewers: hfinkel, dexonsmith, davidxl

Subscribers: davidxl, dexonsmith, llvm-commits

Differential Revision: http://reviews.llvm.org/D22141

Added:
    llvm/trunk/include/llvm/Analysis/LazyBlockFrequencyInfo.h
    llvm/trunk/lib/Analysis/LazyBlockFrequencyInfo.cpp
Modified:
    llvm/trunk/include/llvm/Analysis/BlockFrequencyInfo.h
    llvm/trunk/include/llvm/InitializePasses.h
    llvm/trunk/lib/Analysis/Analysis.cpp
    llvm/trunk/lib/Analysis/BlockFrequencyInfo.cpp
    llvm/trunk/lib/Analysis/CMakeLists.txt
    llvm/trunk/test/Analysis/BlockFrequencyInfo/basic.ll

Modified: llvm/trunk/include/llvm/Analysis/BlockFrequencyInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/BlockFrequencyInfo.h?rev=275250&r1=275249&r2=275250&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/BlockFrequencyInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/BlockFrequencyInfo.h Wed Jul 13 00:01:48 2016
@@ -43,6 +43,8 @@ public:
 
   BlockFrequencyInfo &operator=(BlockFrequencyInfo &&RHS);
 
+  ~BlockFrequencyInfo();
+
   const Function *getFunction() const;
   const BranchProbabilityInfo *getBPI() const;
   void view() const;

Added: llvm/trunk/include/llvm/Analysis/LazyBlockFrequencyInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/LazyBlockFrequencyInfo.h?rev=275250&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Analysis/LazyBlockFrequencyInfo.h (added)
+++ llvm/trunk/include/llvm/Analysis/LazyBlockFrequencyInfo.h Wed Jul 13 00:01:48 2016
@@ -0,0 +1,125 @@
+//===- LazyBlockFrequencyInfo.h - Lazy Block Frequency Analysis -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 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 results is explicitly
+// requested by the analysis client.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H
+#define LLVM_ANALYSIS_LAZYBLOCKFREQUENCYINFO_H
+
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+class AnalysisUsage;
+class BranchProbabilityInfo;
+class Function;
+class LoopInfo;
+
+/// \brief 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 results 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 {
+
+  /// 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.
+  class LazyBlockFrequencyInfo {
+  public:
+    LazyBlockFrequencyInfo()
+        : Calculated(false), F(nullptr), BPI(nullptr), LI(nullptr) {}
+
+    /// Set up the per-function input.
+    void setAnalysis(const Function *F, const BranchProbabilityInfo *BPI,
+                     const LoopInfo *LI) {
+      this->F = F;
+      this->BPI = BPI;
+      this->LI = LI;
+    }
+
+    /// Retrieve the BFI with the block frequencies computed.
+    BlockFrequencyInfo &getCalculated() {
+      if (!Calculated) {
+        assert(F && BPI && LI && "call setAnalysis");
+        BFI.calculate(*F, *BPI, *LI);
+        Calculated = true;
+      }
+      return BFI;
+    }
+
+    const BlockFrequencyInfo &getCalculated() const {
+      return const_cast<LazyBlockFrequencyInfo *>(this)->getCalculated();
+    }
+
+    void releaseMemory() {
+      BFI.releaseMemory();
+      Calculated = false;
+      setAnalysis(nullptr, nullptr, nullptr);
+    }
+
+  private:
+    BlockFrequencyInfo BFI;
+    bool Calculated;
+    const Function *F;
+    const BranchProbabilityInfo *BPI;
+    const LoopInfo *LI;
+  };
+
+  LazyBlockFrequencyInfo LBFI;
+
+public:
+  static char ID;
+
+  LazyBlockFrequencyInfoPass();
+
+  /// \brief Compute and return the block frequencies.
+  BlockFrequencyInfo &getBFI() { return LBFI.getCalculated(); }
+
+  /// \brief 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;
+};
+
+/// \brief Helper for client passes to initialize dependent passes for LBFI.
+void initializeLazyBFIPassPass(PassRegistry &Registry);
+}
+#endif

Modified: llvm/trunk/include/llvm/InitializePasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=275250&r1=275249&r2=275250&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InitializePasses.h (original)
+++ llvm/trunk/include/llvm/InitializePasses.h Wed Jul 13 00:01:48 2016
@@ -160,6 +160,7 @@ void initializeIntervalPartitionPass(Pas
 void initializeJumpThreadingPass(PassRegistry&);
 void initializeLCSSAWrapperPassPass(PassRegistry &);
 void initializeLegacyLICMPassPass(PassRegistry&);
+void initializeLazyBlockFrequencyInfoPassPass(PassRegistry&);
 void initializeLazyValueInfoWrapperPassPass(PassRegistry&);
 void initializeLintPass(PassRegistry&);
 void initializeLiveDebugValuesPass(PassRegistry&);

Modified: llvm/trunk/lib/Analysis/Analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Analysis.cpp?rev=275250&r1=275249&r2=275250&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/Analysis.cpp (original)
+++ llvm/trunk/lib/Analysis/Analysis.cpp Wed Jul 13 00:01:48 2016
@@ -54,6 +54,7 @@ void llvm::initializeAnalysis(PassRegist
   initializeIVUsersPass(Registry);
   initializeInstCountPass(Registry);
   initializeIntervalPartitionPass(Registry);
+  initializeLazyBlockFrequencyInfoPassPass(Registry);
   initializeLazyValueInfoWrapperPassPass(Registry);
   initializeLintPass(Registry);
   initializeLoopInfoWrapperPassPass(Registry);

Modified: llvm/trunk/lib/Analysis/BlockFrequencyInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/BlockFrequencyInfo.cpp?rev=275250&r1=275249&r2=275250&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/BlockFrequencyInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/BlockFrequencyInfo.cpp Wed Jul 13 00:01:48 2016
@@ -129,6 +129,12 @@ BlockFrequencyInfo &BlockFrequencyInfo::
   return *this;
 }
 
+// Explicitly define the default constructor otherwise it would be implicitly
+// defined at the first ODR-use which is the BFI member in the
+// LazyBlockFrequencyInfo header.  The dtor needs the BlockFrequencyInfoImpl
+// template instantiated which is not available in the header.
+BlockFrequencyInfo::~BlockFrequencyInfo() {}
+
 void BlockFrequencyInfo::calculate(const Function &F,
                                    const BranchProbabilityInfo &BPI,
                                    const LoopInfo &LI) {

Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=275250&r1=275249&r2=275250&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
+++ llvm/trunk/lib/Analysis/CMakeLists.txt Wed Jul 13 00:01:48 2016
@@ -37,6 +37,7 @@ add_llvm_library(LLVMAnalysis
   Interval.cpp
   IntervalPartition.cpp
   IteratedDominanceFrontier.cpp
+  LazyBlockFrequencyInfo.cpp
   LazyCallGraph.cpp
   LazyValueInfo.cpp
   Lint.cpp

Added: llvm/trunk/lib/Analysis/LazyBlockFrequencyInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/LazyBlockFrequencyInfo.cpp?rev=275250&view=auto
==============================================================================
--- llvm/trunk/lib/Analysis/LazyBlockFrequencyInfo.cpp (added)
+++ llvm/trunk/lib/Analysis/LazyBlockFrequencyInfo.cpp Wed Jul 13 00:01:48 2016
@@ -0,0 +1,68 @@
+//===- LazyBlockFrequencyInfo.cpp - Lazy Block Frequency Analysis ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// 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 results is explicitly
+// requested by the analysis client.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
+#include "llvm/Analysis/BranchProbabilityInfo.h"
+#include "llvm/Analysis/LoopInfo.h"
+
+using namespace llvm;
+
+#define DEBUG_TYPE "lazy-block-freq"
+
+INITIALIZE_PASS_BEGIN(LazyBlockFrequencyInfoPass, DEBUG_TYPE,
+                      "Lazy Block Frequency Analysis", true, true)
+INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
+INITIALIZE_PASS_END(LazyBlockFrequencyInfoPass, DEBUG_TYPE,
+                    "Lazy Block Frequency Analysis", true, true)
+
+char LazyBlockFrequencyInfoPass::ID = 0;
+
+LazyBlockFrequencyInfoPass::LazyBlockFrequencyInfoPass() : FunctionPass(ID) {
+  initializeLazyBlockFrequencyInfoPassPass(*PassRegistry::getPassRegistry());
+}
+
+void LazyBlockFrequencyInfoPass::print(raw_ostream &OS, const Module *) const {
+  LBFI.getCalculated().print(OS);
+}
+
+void LazyBlockFrequencyInfoPass::getAnalysisUsage(AnalysisUsage &AU) const {
+  AU.addRequired<BranchProbabilityInfoWrapperPass>();
+  AU.addRequired<LoopInfoWrapperPass>();
+  AU.setPreservesAll();
+}
+
+void LazyBlockFrequencyInfoPass::releaseMemory() { LBFI.releaseMemory(); }
+
+bool LazyBlockFrequencyInfoPass::runOnFunction(Function &F) {
+  BranchProbabilityInfo &BPI =
+      getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
+  LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
+  LBFI.setAnalysis(&F, &BPI, &LI);
+  return false;
+}
+
+void LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AnalysisUsage &AU) {
+  AU.addRequired<BranchProbabilityInfoWrapperPass>();
+  AU.addRequired<LazyBlockFrequencyInfoPass>();
+  AU.addRequired<LoopInfoWrapperPass>();
+}
+
+void llvm::initializeLazyBFIPassPass(PassRegistry &Registry) {
+  INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass);
+  INITIALIZE_PASS_DEPENDENCY(LazyBlockFrequencyInfoPass);
+  INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
+}

Modified: llvm/trunk/test/Analysis/BlockFrequencyInfo/basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/BlockFrequencyInfo/basic.ll?rev=275250&r1=275249&r2=275250&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/BlockFrequencyInfo/basic.ll (original)
+++ llvm/trunk/test/Analysis/BlockFrequencyInfo/basic.ll Wed Jul 13 00:01:48 2016
@@ -1,4 +1,5 @@
 ; RUN: opt < %s -analyze -block-freq | FileCheck %s
+; RUN: opt < %s -analyze -lazy-block-freq | FileCheck %s
 ; RUN: opt < %s -passes='print<block-freq>' -disable-output 2>&1 | FileCheck %s
 
 define i32 @test1(i32 %i, i32* %a) {




More information about the llvm-commits mailing list