Home | History | Annotate | Line # | Download | only in Utils
      1 //===- llvm/Transforms/Utils/SizeOpts.h - size optimization -----*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file contains some shared code size optimization related code.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_TRANSFORMS_UTILS_SIZEOPTS_H
     14 #define LLVM_TRANSFORMS_UTILS_SIZEOPTS_H
     15 
     16 #include "llvm/Analysis/BlockFrequencyInfo.h"
     17 #include "llvm/Analysis/ProfileSummaryInfo.h"
     18 #include "llvm/Support/CommandLine.h"
     19 
     20 namespace llvm {
     21 extern cl::opt<bool> EnablePGSO;
     22 extern cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
     23 extern cl::opt<bool> PGSOColdCodeOnly;
     24 extern cl::opt<bool> PGSOColdCodeOnlyForInstrPGO;
     25 extern cl::opt<bool> PGSOColdCodeOnlyForSamplePGO;
     26 extern cl::opt<bool> PGSOColdCodeOnlyForPartialSamplePGO;
     27 extern cl::opt<bool> ForcePGSO;
     28 extern cl::opt<int> PgsoCutoffInstrProf;
     29 extern cl::opt<int> PgsoCutoffSampleProf;
     30 
     31 class BasicBlock;
     32 class BlockFrequencyInfo;
     33 class Function;
     34 
     35 enum class PGSOQueryType {
     36   IRPass, // A query call from an IR-level transform pass.
     37   Test,   // A query call from a unit test.
     38   Other,  // Others.
     39 };
     40 
     41 static inline bool isPGSOColdCodeOnly(ProfileSummaryInfo *PSI) {
     42   return PGSOColdCodeOnly ||
     43          (PSI->hasInstrumentationProfile() && PGSOColdCodeOnlyForInstrPGO) ||
     44          (PSI->hasSampleProfile() &&
     45           ((!PSI->hasPartialSampleProfile() && PGSOColdCodeOnlyForSamplePGO) ||
     46            (PSI->hasPartialSampleProfile() &&
     47             PGSOColdCodeOnlyForPartialSamplePGO))) ||
     48          (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize());
     49 }
     50 
     51 template<typename AdapterT, typename FuncT, typename BFIT>
     52 bool shouldFuncOptimizeForSizeImpl(const FuncT *F, ProfileSummaryInfo *PSI,
     53                                    BFIT *BFI, PGSOQueryType QueryType) {
     54   assert(F);
     55   if (!PSI || !BFI || !PSI->hasProfileSummary())
     56     return false;
     57   if (ForcePGSO)
     58     return true;
     59   if (!EnablePGSO)
     60     return false;
     61   if (isPGSOColdCodeOnly(PSI))
     62     return AdapterT::isFunctionColdInCallGraph(F, PSI, *BFI);
     63   if (PSI->hasSampleProfile())
     64     // The "isCold" check seems to work better for Sample PGO as it could have
     65     // many profile-unannotated functions.
     66     return AdapterT::isFunctionColdInCallGraphNthPercentile(
     67         PgsoCutoffSampleProf, F, PSI, *BFI);
     68   return !AdapterT::isFunctionHotInCallGraphNthPercentile(PgsoCutoffInstrProf,
     69                                                           F, PSI, *BFI);
     70 }
     71 
     72 template<typename AdapterT, typename BlockTOrBlockFreq, typename BFIT>
     73 bool shouldOptimizeForSizeImpl(BlockTOrBlockFreq BBOrBlockFreq, ProfileSummaryInfo *PSI,
     74                                BFIT *BFI, PGSOQueryType QueryType) {
     75   if (!PSI || !BFI || !PSI->hasProfileSummary())
     76     return false;
     77   if (ForcePGSO)
     78     return true;
     79   if (!EnablePGSO)
     80     return false;
     81   if (isPGSOColdCodeOnly(PSI))
     82     return AdapterT::isColdBlock(BBOrBlockFreq, PSI, BFI);
     83   if (PSI->hasSampleProfile())
     84     // The "isCold" check seems to work better for Sample PGO as it could have
     85     // many profile-unannotated functions.
     86     return AdapterT::isColdBlockNthPercentile(PgsoCutoffSampleProf,
     87                                               BBOrBlockFreq, PSI, BFI);
     88   return !AdapterT::isHotBlockNthPercentile(PgsoCutoffInstrProf, BBOrBlockFreq,
     89                                             PSI, BFI);
     90 }
     91 
     92 /// Returns true if function \p F is suggested to be size-optimized based on the
     93 /// profile.
     94 bool shouldOptimizeForSize(const Function *F, ProfileSummaryInfo *PSI,
     95                            BlockFrequencyInfo *BFI,
     96                            PGSOQueryType QueryType = PGSOQueryType::Other);
     97 
     98 /// Returns true if basic block \p BB is suggested to be size-optimized based on
     99 /// the profile.
    100 bool shouldOptimizeForSize(const BasicBlock *BB, ProfileSummaryInfo *PSI,
    101                            BlockFrequencyInfo *BFI,
    102                            PGSOQueryType QueryType = PGSOQueryType::Other);
    103 
    104 } // end namespace llvm
    105 
    106 #endif // LLVM_TRANSFORMS_UTILS_SIZEOPTS_H
    107