| //===----------------------------------------------------------------------===// | |
| // | |
| // 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/Module.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.isDeclaration()) | |
| return false; | |
| // Respect existing attributes. | |
| if (F.hasOptNone() || F.hasOptSize()) | |
| return false; | |
| 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 (!shouldRunOnFunction(F, PSI, FAM)) | |
| continue; | |
| switch (ColdType) { | |
| case PGOOptions::ColdFuncOpt::Default: | |
| llvm_unreachable("bailed out for default above"); | |
| break; | |
| case PGOOptions::ColdFuncOpt::OptSize: | |
| F.addFnAttr(Attribute::OptimizeForSize); | |
| break; | |
| case PGOOptions::ColdFuncOpt::MinSize: | |
| F.addFnAttr(Attribute::MinSize); | |
| break; | |
| case PGOOptions::ColdFuncOpt::OptNone: | |
| // alwaysinline is incompatible with optnone. | |
| if (F.hasFnAttribute(Attribute::AlwaysInline)) | |
| continue; | |
| F.addFnAttr(Attribute::OptimizeNone); | |
| F.addFnAttr(Attribute::NoInline); | |
| break; | |
| } | |
| MadeChange = true; | |
| } | |
| return MadeChange ? PreservedAnalyses::none() : PreservedAnalyses::all(); | |
| } |