[llvm] [clang-tools-extra] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
david-xl wrote: > > > > I don't understand, if you're saying the profile is accurate, then > > > > those functions are actually cold, so we should be able to mark them as > > > > optsize? > > > > > > > > > Accurate is not black or white. The current heuristic requires certain > > > level of accuracy to be effective. If you make the heuristics more > > > aggressive (like what this patch is doing), you're raising the > > > requirement of what can be considered accurate, and profile not meeting > > > that new requirement could see regression with new heuristic. > > > Whether a function is cold or not also depends on what is the calling > > > context and how inlining is done. All that makes function level > > > annotation inherently inaccurate when done before inlining. Not that we > > > shouldn't try it, but it's not as clear cut as it appears to be, and we > > > need to be careful. > > > > > > It will be more conservative (pre-inlining), so won't cause additional > > optimization suppression compared with the current PGSO. > > Sample PGO profile has inline context, so in the profile, we may have `foo` > as cold and `bar->foo` as hot, but if later inliner rejects `bar->foo` > inlining, `foo` can be hot. So marking `foo` as cold pre-inline can still be > inaccurate (and not conservative). > > In this PR, you have `PGOColdFuncAttr` default to `ColdFuncOpt::Default`. As > long as you keep it that way, this PR is fine for sample pgo (it's no-op > unless `pgo-cold-func-opt` is used explicitly). Good example. This pass should be run post-inline. @aeubanks, any reason we want to run it early in the pipeline? https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang-tools-extra] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
david-xl wrote: > > I don't understand, if you're saying the profile is accurate, then those > > functions are actually cold, so we should be able to mark them as optsize? > > Accurate is not black or white. The current heuristic requires certain level > of accuracy to be effective. If you make the heuristics more aggressive (like > what this patch is doing), you're raising the requirement of what can be > considered accurate, and profile not meeting that new requirement could see > regression with new heuristic. > > Whether a function is cold or not also depends on what is the calling context > and how inlining is done. All that makes function level annotation inherently > inaccurate when done before inlining. Not that we shouldn't try it, but it's > not as clear cut as it appears to be, and we need to be careful. It will be more conservative (pre-inlining), so won't cause additional optimization suppression compared with the current PGSO. https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [llvm] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
WenleiHe wrote: > I don't understand, if you're saying the profile is accurate, then those > functions are actually cold, so we should be able to mark them as optsize? Accurate is not black or white. The current heuristic requires certain level of accuracy to be effective. If you make the heuristics more aggressive (like what this patch is doing), you're raising the requirement of what can be considered accurate, and profile not meeting that new requirement could see regression with new heuristic. Whether a function is cold or not also depends on what is the calling context and how inlining is done. All that makes function level annotation inherently inaccurate when done before inlining. Not that we shouldn't try it, but it's not as clear cut as it appears to be, and we need to be careful. https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -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(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(M); + FunctionAnalysisManager &FAM = + AM.getResult(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); aeubanks wrote: it was intentional for optnone to take precedence, but I've changed it to bail out if we see optnone/minsize/optsize at all https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
aeubanks wrote: > FWIW we've tried this with sampling PGO in the past. While on paper this > seems like an obvious thing to do, in reality aggressively tuning down opt > level for cold functions can lead to regression since profile isn't always > accurate. > > That said, as long as this change only provides options for users to make > decision and not changing the default behavior, it's probably fine. IIUC, this won't affect sample profile unless you mark the sample profile as "accurate" (e.g. `-profile-sample-accurate`). But I should double check. https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
aeubanks wrote: > How does this relate to the existing `shouldOptimizeForSize(Function&, ...)` > and `shouldOptimizeForSize(MachineFunction&, ...)` APIs which appear to > provide similar functionality at a first glance. If they are the same, then > we should have a plan in place to cleanup and only have one system > afterwards, if there are important differences, then I wouldn't mind some > comments explaining them. This is intended to replace `shouldOptimizeForSize()`. We've seen multiple cases of calls to `shouldOptimizeForSize()` blowing up compile times if we're not being careful with the calls to it, since it ends up calling expensive profile information code. The replacement is to just check if the function has the `optsize`/`minsize` attribute. I'll mention this in the description. The basic block versions of these should remain as they are since they actually do need to look at profile information to determine per-block information. https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
WenleiHe wrote: > > How does this relate to the existing `shouldOptimizeForSize(Function&, > > ...)` and `shouldOptimizeForSize(MachineFunction&, ...)` APIs which appear > > to provide similar functionality at a first glance. If they are the same, > > then we should have a plan in place to cleanup and only have one system > > afterwards, if there are important differences, then I wouldn't mind some > > comments explaining them. > > This patch allows more user control on the cold function action types. > > Another difference is that the existing API can be invoked in postInline > passes which can see more cold functions after inlining. To replace those > APIs, the new pass will need to run again post-inlining. They provide similar but different controls. However, the fact that the two mechanisms are completely disconnected is not ideal. If we want to apply an opt strategy for cold code, we should do it at both function level and block level consistently. In fact the unification was also discussed on the original RFC: https://discourse.llvm.org/t/rfc-new-feature-proposal-de-optimizing-cold-functions-using-pgo-info/56388/16?u=wenleihe Is there a plan on that front? https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -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(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(M); + FunctionAnalysisManager &FAM = + AM.getResult(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 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
MatzeB wrote: How does this relate to the existing `shouldOptimizeForSize(Function&)` and similar APIs which appear to provide similar functionality at a first glance. If they are the same, then we should have a plan in place to cleanup and only have one system afterwards, if there are important differences, then I wouldn't mind some comments getting added :) https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -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(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(M); + FunctionAnalysisManager &FAM = + AM.getResult(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); david-xl wrote: should it overwrite the existing attribute? https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -0,0 +1,65 @@ +//===--===// +// +// 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/MarkColdFunctions.h" +#include "llvm/Analysis/BlockFrequencyInfo.h" +#include "llvm/Analysis/ProfileSummaryInfo.h" +#include "llvm/IR/PassManager.h" + +using namespace llvm; + +PreservedAnalyses MarkColdFunctionsPass::run(Module &M, + ModuleAnalysisManager &AM) { + if (ColdType == PGOOptions::ColdFuncAttr::None) +return PreservedAnalyses::all(); + ProfileSummaryInfo &PSI = AM.getResult(M); + if (!PSI.hasProfileSummary()) +return PreservedAnalyses::all(); + FunctionAnalysisManager &FAM = + AM.getResult(M).getManager(); + bool MadeChange = false; + for (Function &F : M) { +if (F.isDeclaration()) + continue; +BlockFrequencyInfo &BFI = FAM.getResult(F); +if (!PSI.isFunctionColdInCallGraph(&F, BFI)) david-xl wrote: The same optimization strategy should also be applied to function already marked with cold attribute (either by user or previous passes). https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -0,0 +1,28 @@ +//===- MarkColdFunctions.h - *- 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 +// +//===--===// + +#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_MARKCOLDFUNCTIONS_H +#define LLVM_TRANSFORMS_INSTRUMENTATION_MARKCOLDFUNCTIONS_H + +#include "llvm/IR/PassManager.h" +#include "llvm/Support/PGOOptions.h" + +namespace llvm { + +struct MarkColdFunctionsPass : public PassInfoMixin { ellishg wrote: I think this pass could be generalized a bit. It seems that the goal for this pr is to reduce the size overhead of `-O2` by forcing cold functions to be `optsize`/`minsize`. Another goal could be to improve the performance of `-Oz` by forcing very hot functions to be `optsize` (as opposed to `minsize`) or remove `optsize`/`minsize` from them entirely. This is actually something we explored in [this paper](https://dl.acm.org/doi/10.1145/3497776.3517764) a while back and I would eventually like to upstream something similar. I believe this could be incorporated into this pass, but the name seems to be too vague. I think "PGO" should to be in the name so users know that it is involved. Maybe `PGOForceFuncAttrsPass` or `ProfileGuidedFuncAttrsPass`? CC @kyulee-com https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -1127,6 +1134,11 @@ PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level, if (EnableSyntheticCounts && !PGOOpt) MPM.addPass(SyntheticCountsPropagation()); + if (EnableMarkColdFunctions && PGOOpt && + (PGOOpt->Action == PGOOptions::SampleUse || + PGOOpt->Action == PGOOptions::IRUse)) ellishg wrote: It seems that this pass isn't enabled for CS profiles. Can they benefit from this pass? https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -0,0 +1,65 @@ +//===--===// +// +// 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/MarkColdFunctions.h" +#include "llvm/Analysis/BlockFrequencyInfo.h" +#include "llvm/Analysis/ProfileSummaryInfo.h" +#include "llvm/IR/PassManager.h" + +using namespace llvm; + +PreservedAnalyses MarkColdFunctionsPass::run(Module &M, david-xl wrote: yes, you can use profile-sample-accurate or profile-accurate-for-syminlist to control the behavior, similar to how AFDO is selecting functions to put in .text.unlikely. https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -0,0 +1,65 @@ +//===--===// +// +// 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/MarkColdFunctions.h" +#include "llvm/Analysis/BlockFrequencyInfo.h" +#include "llvm/Analysis/ProfileSummaryInfo.h" +#include "llvm/IR/PassManager.h" + +using namespace llvm; + +PreservedAnalyses MarkColdFunctionsPass::run(Module &M, aeubanks wrote: Having a global option determine how to handle `cold` makes the IR more complicated. Reusing something that already exists and is being used is nicer. Another alternative is to rely on the profile loaders to mark functions as `cold`, then this pass only looks at functions marked `cold`. WDYT? It looks like iFDO marks cold functions as `cold`, but sample FDO doesn't. If sample FDO is inaccurate then marking functions as `cold` may be bad, so I assume that's why we don't mark functions as `cold` for sample FDO. But there's also the "accurate" flag that says that the sample profile is accurate and functions not in the profile are actually cold. In that case we should mark functions as `cold`? https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -202,6 +202,18 @@ static cl::opt cl::desc("Path to the profile remapping file."), cl::Hidden); +static cl::opt PGOColdFuncAttr( +"pgo-cold-func-attr", cl::init(PGOOptions::ColdFuncAttr::None), cl::Hidden, david-xl wrote: pgo-cold-func-opt https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -0,0 +1,65 @@ +//===--===// +// +// 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/MarkColdFunctions.h" +#include "llvm/Analysis/BlockFrequencyInfo.h" +#include "llvm/Analysis/ProfileSummaryInfo.h" +#include "llvm/IR/PassManager.h" + +using namespace llvm; + +PreservedAnalyses MarkColdFunctionsPass::run(Module &M, david-xl wrote: why not just mark those function with 'cold' attribute, and have one global option to determine the optimization strategy of cold attributed functions? These functions are not different from functions annotated by a developer. https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -27,10 +27,12 @@ class FileSystem; struct PGOOptions { enum PGOAction { NoAction, IRInstr, IRUse, SampleUse }; enum CSPGOAction { NoCSAction, CSIRInstr, CSIRUse }; + enum class ColdFuncAttr { None, OptSize, MinSize, OptNone }; david-xl wrote: None --> Default https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -44,6 +46,7 @@ struct PGOOptions { std::string MemoryProfile; PGOAction Action; CSPGOAction CSAction; + ColdFuncAttr ColdType; david-xl wrote: ColdType --> ColdOptType https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
@@ -27,10 +27,12 @@ class FileSystem; struct PGOOptions { enum PGOAction { NoAction, IRInstr, IRUse, SampleUse }; enum CSPGOAction { NoCSAction, CSIRInstr, CSIRUse }; + enum class ColdFuncAttr { None, OptSize, MinSize, OptNone }; david-xl wrote: Even though the optimization directive is implemented as a function attribute, it might be better to express the real intention is to decide 'optimization strategy', so perhaps ColdFuncOpt as name or ColdFuncOptAttr? ColdFuncAttr feels too broad. https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
llvmbot wrote: @llvm/pr-subscribers-lto Author: Arthur Eubanks (aeubanks) Changes The performance of cold functions shouldn't matter too much, so if we care about binary sizes, add an option to mark cold functions as optsize/minsize for binary size, or optnone for compile times [1]. Clang patch will be in a future patch Initial version: https://reviews.llvm.org/D149800 [1] https://discourse.llvm.org/t/rfc-new-feature-proposal-de-optimizing-cold-functions-using-pgo-info/56388 --- Patch is 22.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/69030.diff 13 Files Affected: - (modified) clang/lib/CodeGen/BackendUtil.cpp (+12-6) - (modified) llvm/include/llvm/Support/PGOOptions.h (+3) - (added) llvm/include/llvm/Transforms/Instrumentation/MarkColdFunctions.h (+28) - (modified) llvm/lib/LTO/LTOBackend.cpp (+8-4) - (modified) llvm/lib/Passes/PassBuilder.cpp (+2-1) - (modified) llvm/lib/Passes/PassBuilderPipelines.cpp (+12) - (modified) llvm/lib/Passes/PassRegistry.def (+1) - (modified) llvm/lib/Support/PGOOptions.cpp (+4-3) - (modified) llvm/lib/Transforms/Instrumentation/CMakeLists.txt (+1) - (added) llvm/lib/Transforms/Instrumentation/MarkColdFunctions.cpp (+65) - (added) llvm/test/Transforms/MarkColdFunctions/basic.ll (+97) - (modified) llvm/tools/opt/NewPMDriver.cpp (+19-5) - (modified) llvm/utils/gn/secondary/llvm/lib/Transforms/Instrumentation/BUILD.gn (+1) ``diff diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index d066819871dfde3..f0c9b9d4daf08b5 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -770,7 +770,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName() : CodeGenOpts.InstrProfileOutput, "", "", CodeGenOpts.MemoryProfileUsePath, nullptr, PGOOptions::IRInstr, -PGOOptions::NoCSAction, CodeGenOpts.DebugInfoForProfiling, +PGOOptions::NoCSAction, PGOOptions::ColdFuncAttr::None, +CodeGenOpts.DebugInfoForProfiling, /*PseudoProbeForProfiling=*/false, CodeGenOpts.AtomicProfileUpdate); else if (CodeGenOpts.hasProfileIRUse()) { // -fprofile-use. @@ -779,28 +780,32 @@ void EmitAssemblyHelper::RunOptimizationPipeline( PGOOpt = PGOOptions( CodeGenOpts.ProfileInstrumentUsePath, "", CodeGenOpts.ProfileRemappingFile, CodeGenOpts.MemoryProfileUsePath, VFS, -PGOOptions::IRUse, CSAction, CodeGenOpts.DebugInfoForProfiling); +PGOOptions::IRUse, CSAction, PGOOptions::ColdFuncAttr::None, +CodeGenOpts.DebugInfoForProfiling); } else if (!CodeGenOpts.SampleProfileFile.empty()) // -fprofile-sample-use PGOOpt = PGOOptions( CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile, CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::SampleUse, -PGOOptions::NoCSAction, CodeGenOpts.DebugInfoForProfiling, -CodeGenOpts.PseudoProbeForProfiling); +PGOOptions::NoCSAction, PGOOptions::ColdFuncAttr::None, +CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling); else if (!CodeGenOpts.MemoryProfileUsePath.empty()) // -fmemory-profile-use (without any of the above options) PGOOpt = PGOOptions("", "", "", CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::NoAction, PGOOptions::NoCSAction, +PGOOptions::ColdFuncAttr::None, CodeGenOpts.DebugInfoForProfiling); else if (CodeGenOpts.PseudoProbeForProfiling) // -fpseudo-probe-for-profiling PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, PGOOptions::NoAction, PGOOptions::NoCSAction, +PGOOptions::ColdFuncAttr::None, CodeGenOpts.DebugInfoForProfiling, true); else if (CodeGenOpts.DebugInfoForProfiling) // -fdebug-info-for-profiling PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, -PGOOptions::NoAction, PGOOptions::NoCSAction, true); +PGOOptions::NoAction, PGOOptions::NoCSAction, +PGOOptions::ColdFuncAttr::None, true); // Check to see if we want to generate a CS profile. if (CodeGenOpts.hasProfileCSIRInstr()) { @@ -823,7 +828,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( ? getDefaultProfileGenName() : CodeGenOpts.InstrProfileOutput, "", /*MemoryProfile=*/"", nullptr, PGOOptions::NoAction, - PGOOptions::CSIRInstr, CodeGenOpts.DebugInfoForProfiling); + PGOOptions::CSIRInstr, PGOOptions::ColdFuncAttr::None, + CodeGenOpts.DebugInfoForProfiling); } if (TM) TM->setPGOOption(PGOOpt); diff --git a
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
aeubanks wrote: still need to do measurements with this new approach, but lmk if this makes sense https://github.com/llvm/llvm-project/pull/69030 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PGO] Add ability to mark cold functions as optsize/minsize/optnone (PR #69030)
https://github.com/aeubanks created https://github.com/llvm/llvm-project/pull/69030 The performance of cold functions shouldn't matter too much, so if we care about binary sizes, add an option to mark cold functions as optsize/minsize for binary size, or optnone for compile times [1]. Clang patch will be in a future patch Initial version: https://reviews.llvm.org/D149800 [1] https://discourse.llvm.org/t/rfc-new-feature-proposal-de-optimizing-cold-functions-using-pgo-info/56388 >From 81083bddc68864a96f265910019b519d28601e60 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Fri, 13 Oct 2023 14:40:28 -0700 Subject: [PATCH] [PGO] Add ability to mark cold functions as optsize/minsize/optnone The performance of cold functions shouldn't matter too much, so if we care about binary sizes, add an option to mark cold functions as optsize/minsize for binary size, or optnone for compile times [1]. Clang patch will be in a future patch Initial version: https://reviews.llvm.org/D149800 [1] https://discourse.llvm.org/t/rfc-new-feature-proposal-de-optimizing-cold-functions-using-pgo-info/56388 --- clang/lib/CodeGen/BackendUtil.cpp | 18 ++-- llvm/include/llvm/Support/PGOOptions.h| 3 + .../Instrumentation/MarkColdFunctions.h | 28 ++ llvm/lib/LTO/LTOBackend.cpp | 12 ++- llvm/lib/Passes/PassBuilder.cpp | 3 +- llvm/lib/Passes/PassBuilderPipelines.cpp | 12 +++ llvm/lib/Passes/PassRegistry.def | 1 + llvm/lib/Support/PGOOptions.cpp | 7 +- .../Transforms/Instrumentation/CMakeLists.txt | 1 + .../Instrumentation/MarkColdFunctions.cpp | 65 + .../Transforms/MarkColdFunctions/basic.ll | 97 +++ llvm/tools/opt/NewPMDriver.cpp| 24 - .../lib/Transforms/Instrumentation/BUILD.gn | 1 + 13 files changed, 253 insertions(+), 19 deletions(-) create mode 100644 llvm/include/llvm/Transforms/Instrumentation/MarkColdFunctions.h create mode 100644 llvm/lib/Transforms/Instrumentation/MarkColdFunctions.cpp create mode 100644 llvm/test/Transforms/MarkColdFunctions/basic.ll diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index d066819871dfde3..f0c9b9d4daf08b5 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -770,7 +770,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline( CodeGenOpts.InstrProfileOutput.empty() ? getDefaultProfileGenName() : CodeGenOpts.InstrProfileOutput, "", "", CodeGenOpts.MemoryProfileUsePath, nullptr, PGOOptions::IRInstr, -PGOOptions::NoCSAction, CodeGenOpts.DebugInfoForProfiling, +PGOOptions::NoCSAction, PGOOptions::ColdFuncAttr::None, +CodeGenOpts.DebugInfoForProfiling, /*PseudoProbeForProfiling=*/false, CodeGenOpts.AtomicProfileUpdate); else if (CodeGenOpts.hasProfileIRUse()) { // -fprofile-use. @@ -779,28 +780,32 @@ void EmitAssemblyHelper::RunOptimizationPipeline( PGOOpt = PGOOptions( CodeGenOpts.ProfileInstrumentUsePath, "", CodeGenOpts.ProfileRemappingFile, CodeGenOpts.MemoryProfileUsePath, VFS, -PGOOptions::IRUse, CSAction, CodeGenOpts.DebugInfoForProfiling); +PGOOptions::IRUse, CSAction, PGOOptions::ColdFuncAttr::None, +CodeGenOpts.DebugInfoForProfiling); } else if (!CodeGenOpts.SampleProfileFile.empty()) // -fprofile-sample-use PGOOpt = PGOOptions( CodeGenOpts.SampleProfileFile, "", CodeGenOpts.ProfileRemappingFile, CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::SampleUse, -PGOOptions::NoCSAction, CodeGenOpts.DebugInfoForProfiling, -CodeGenOpts.PseudoProbeForProfiling); +PGOOptions::NoCSAction, PGOOptions::ColdFuncAttr::None, +CodeGenOpts.DebugInfoForProfiling, CodeGenOpts.PseudoProbeForProfiling); else if (!CodeGenOpts.MemoryProfileUsePath.empty()) // -fmemory-profile-use (without any of the above options) PGOOpt = PGOOptions("", "", "", CodeGenOpts.MemoryProfileUsePath, VFS, PGOOptions::NoAction, PGOOptions::NoCSAction, +PGOOptions::ColdFuncAttr::None, CodeGenOpts.DebugInfoForProfiling); else if (CodeGenOpts.PseudoProbeForProfiling) // -fpseudo-probe-for-profiling PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, PGOOptions::NoAction, PGOOptions::NoCSAction, +PGOOptions::ColdFuncAttr::None, CodeGenOpts.DebugInfoForProfiling, true); else if (CodeGenOpts.DebugInfoForProfiling) // -fdebug-info-for-profiling PGOOpt = PGOOptions("", "", "", /*MemoryProfile=*/"", nullptr, -PGOOptions::NoAction, PGOOptions::NoCSAction, true); +PGOOptions::NoAction, PGOOptions::NoCSAction, +