[llvm] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 30 19:57:29 PST 2024


================
@@ -0,0 +1,73 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Instrumentation/PGOForceFunctionAttrs.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/ProfileSummaryInfo.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+static bool shouldRunOnFunction(Function &F, ProfileSummaryInfo &PSI,
+                                FunctionAnalysisManager &FAM) {
+  if (F.hasFnAttribute(Attribute::Cold))
+    return true;
+  if (!PSI.hasProfileSummary())
+    return false;
+  BlockFrequencyInfo &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
+  return PSI.isFunctionColdInCallGraph(&F, BFI);
+}
+
+PreservedAnalyses PGOForceFunctionAttrsPass::run(Module &M,
+                                                 ModuleAnalysisManager &AM) {
+  if (ColdType == PGOOptions::ColdFuncOpt::Default)
+    return PreservedAnalyses::all();
+  ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
+  FunctionAnalysisManager &FAM =
+      AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+  bool MadeChange = false;
+  for (Function &F : M) {
+    if (F.isDeclaration())
+      continue;
+    if (!shouldRunOnFunction(F, PSI, FAM))
+      continue;
+    // Add optsize/minsize/optnone if requested.
+    switch (ColdType) {
+    case PGOOptions::ColdFuncOpt::Default:
+      llvm_unreachable("bailed out for default above");
+      break;
+    case PGOOptions::ColdFuncOpt::OptSize:
+      if (!F.hasFnAttribute(Attribute::OptimizeNone) &&
+          !F.hasFnAttribute(Attribute::OptimizeForSize) &&
+          !F.hasFnAttribute(Attribute::MinSize)) {
+        F.addFnAttr(Attribute::OptimizeForSize);
+        MadeChange = true;
+      }
+      break;
+    case PGOOptions::ColdFuncOpt::MinSize:
+      // Change optsize to minsize.
+      if (!F.hasFnAttribute(Attribute::OptimizeNone) &&
+          !F.hasFnAttribute(Attribute::MinSize)) {
+        F.removeFnAttr(Attribute::OptimizeForSize);
----------------
WenleiHe wrote:

Inclined to say that we should honor existing attributes which may come from source annotations (optnone can be used for correctness reasons, e.g. workaround bugs etc). For this reason, I'm thinking about it as `PGODerivedFunctionAttrs` instead of `PGOForceFunctionAttrs`.

I'm also seeing inconsistency here in how different attributes are handled, e.g. `OptNone` seems to take precedence over any existing attributes, but not the case for some others. 

https://github.com/llvm/llvm-project/pull/69030


More information about the cfe-commits mailing list