xref: /freebsd/contrib/llvm-project/llvm/lib/Transforms/Instrumentation/PGOForceFunctionAttrs.cpp (revision 27ef5d48c729defb83a8822143dc71ab17f9d68b)
1  //===----------------------------------------------------------------------===//
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  #include "llvm/Transforms/Instrumentation/PGOForceFunctionAttrs.h"
10  #include "llvm/Analysis/BlockFrequencyInfo.h"
11  #include "llvm/Analysis/ProfileSummaryInfo.h"
12  #include "llvm/IR/Module.h"
13  #include "llvm/IR/PassManager.h"
14  #include "llvm/Support/ErrorHandling.h"
15  
16  using namespace llvm;
17  
18  static bool shouldRunOnFunction(Function &F, ProfileSummaryInfo &PSI,
19                                  FunctionAnalysisManager &FAM) {
20    if (F.isDeclaration())
21      return false;
22    // Respect existing attributes.
23    if (F.hasOptNone() || F.hasOptSize() || F.hasMinSize())
24      return false;
25    if (F.hasFnAttribute(Attribute::Cold))
26      return true;
27    if (!PSI.hasProfileSummary())
28      return false;
29    BlockFrequencyInfo &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
30    return PSI.isFunctionColdInCallGraph(&F, BFI);
31  }
32  
33  PreservedAnalyses PGOForceFunctionAttrsPass::run(Module &M,
34                                                   ModuleAnalysisManager &AM) {
35    if (ColdType == PGOOptions::ColdFuncOpt::Default)
36      return PreservedAnalyses::all();
37    ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
38    FunctionAnalysisManager &FAM =
39        AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
40    bool MadeChange = false;
41    for (Function &F : M) {
42      if (!shouldRunOnFunction(F, PSI, FAM))
43        continue;
44      switch (ColdType) {
45      case PGOOptions::ColdFuncOpt::Default:
46        llvm_unreachable("bailed out for default above");
47        break;
48      case PGOOptions::ColdFuncOpt::OptSize:
49        F.addFnAttr(Attribute::OptimizeForSize);
50        break;
51      case PGOOptions::ColdFuncOpt::MinSize:
52        F.addFnAttr(Attribute::MinSize);
53        break;
54      case PGOOptions::ColdFuncOpt::OptNone:
55        // alwaysinline is incompatible with optnone.
56        if (F.hasFnAttribute(Attribute::AlwaysInline))
57          continue;
58        F.addFnAttr(Attribute::OptimizeNone);
59        F.addFnAttr(Attribute::NoInline);
60        break;
61      }
62      MadeChange = true;
63    }
64    return MadeChange ? PreservedAnalyses::none() : PreservedAnalyses::all();
65  }
66