5959#include " llvm/ADT/SmallSet.h"
6060#include " llvm/ADT/Statistic.h"
6161#include " llvm/ADT/Twine.h"
62+ #include " llvm/Analysis/BlockFrequencyInfo.h"
6263#include " llvm/Analysis/ModuleSummaryAnalysis.h"
6364#include " llvm/Analysis/OptimizationRemarkEmitter.h"
65+ #include " llvm/Analysis/ProfileSummaryInfo.h"
6466#include " llvm/CGData/CodeGenDataReader.h"
6567#include " llvm/CodeGen/LivePhysRegs.h"
6668#include " llvm/CodeGen/MachineModuleInfo.h"
@@ -107,6 +109,16 @@ STATISTIC(StableHashAttempts,
107109STATISTIC (StableHashDropped,
108110 " Count of unsuccessful hashing attempts for outlined functions" );
109111STATISTIC (NumRemovedLOHs, " Total number of Linker Optimization Hints removed" );
112+ STATISTIC (NumPGOBlockedOutlined,
113+ " Number of times outlining was blocked by PGO" );
114+ STATISTIC (NumPGOAllowedCold,
115+ " Number of times outlining was allowed from cold functions" );
116+ STATISTIC (NumPGOConservativeBlockedOutlined,
117+ " Number of times outlining was blocked conservatively when profile "
118+ " counts were missing" );
119+ STATISTIC (NumPGOOptimisticOutlined,
120+ " Number of times outlining was allowed optimistically when profile "
121+ " counts were missing" );
110122
111123// Set to true if the user wants the outliner to run on linkonceodr linkage
112124// functions. This is false by default because the linker can dedupe linkonceodr
@@ -438,11 +450,10 @@ struct MachineOutliner : public ModulePass {
438450 // / The current repeat number of machine outlining.
439451 unsigned OutlineRepeatedNum = 0 ;
440452
441- // / Set to true if the outliner should run on all functions in the module
442- // / considered safe for outlining.
443- // / Set to true by default for compatibility with llc's -run-pass option.
444- // / Set when the pass is constructed in TargetPassConfig.
445- bool RunOnAllFunctions = true ;
453+ // / The mode for whether to run the outliner
454+ // / Set to always-outline by default for compatibility with llc's -run-pass
455+ // / option.
456+ RunOutliner RunOutlinerMode = RunOutliner::AlwaysOutline;
446457
447458 // / This is a compact representation of hash sequences of outlined functions.
448459 // / It is used when OutlinerMode = CGDataMode::Write.
@@ -468,6 +479,11 @@ struct MachineOutliner : public ModulePass {
468479 AU.addRequired <TargetPassConfig>();
469480 AU.addPreserved <MachineModuleInfoWrapperPass>();
470481 AU.addUsedIfAvailable <ImmutableModuleSummaryIndexWrapperPass>();
482+ if (RunOutlinerMode == RunOutliner::OptimisticPGO ||
483+ RunOutlinerMode == RunOutliner::ConservativePGO) {
484+ AU.addRequired <BlockFrequencyInfoWrapperPass>();
485+ AU.addRequired <ProfileSummaryInfoWrapperPass>();
486+ }
471487 AU.setPreservesAll ();
472488 ModulePass::getAnalysisUsage (AU);
473489 }
@@ -578,9 +594,9 @@ struct MachineOutliner : public ModulePass {
578594char MachineOutliner::ID = 0 ;
579595
580596namespace llvm {
581- ModulePass *createMachineOutlinerPass (bool RunOnAllFunctions ) {
597+ ModulePass *createMachineOutlinerPass (RunOutliner RunOutlinerMode ) {
582598 MachineOutliner *OL = new MachineOutliner ();
583- OL->RunOnAllFunctions = RunOnAllFunctions ;
599+ OL->RunOutlinerMode = RunOutlinerMode ;
584600 return OL;
585601}
586602
@@ -1198,10 +1214,49 @@ bool MachineOutliner::outline(
11981214 return OutlinedSomething;
11991215}
12001216
1217+ static bool allowPGOOutlining (RunOutliner RunOutlinerMode,
1218+ const ProfileSummaryInfo *PSI,
1219+ const BlockFrequencyInfo *BFI,
1220+ MachineBasicBlock &MBB) {
1221+ if (RunOutlinerMode != RunOutliner::OptimisticPGO &&
1222+ RunOutlinerMode != RunOutliner::ConservativePGO)
1223+ return true ;
1224+ auto *MF = MBB.getParent ();
1225+ if (MF->getFunction ().hasFnAttribute (Attribute::Cold)) {
1226+ ++NumPGOAllowedCold;
1227+ return true ;
1228+ }
1229+
1230+ auto *BB = MBB.getBasicBlock ();
1231+ if (BB && PSI && BFI)
1232+ if (auto Count = BFI->getBlockProfileCount (BB))
1233+ return *Count <= PSI->getOrCompColdCountThreshold ();
1234+
1235+ if (RunOutlinerMode == RunOutliner::OptimisticPGO) {
1236+ auto *TII = MF->getSubtarget ().getInstrInfo ();
1237+ if (TII->shouldOutlineFromFunctionByDefault (*MF)) {
1238+ // Profile data is unavailable, but we optimistically allow outlining
1239+ ++NumPGOOptimisticOutlined;
1240+ return true ;
1241+ }
1242+ return false ;
1243+ }
1244+ assert (RunOutlinerMode == RunOutliner::ConservativePGO);
1245+ // Profile data is unavailable, so we conservatively block outlining
1246+ ++NumPGOConservativeBlockedOutlined;
1247+ return false ;
1248+ }
1249+
12011250void MachineOutliner::populateMapper (InstructionMapper &Mapper, Module &M) {
12021251 // Build instruction mappings for each function in the module. Start by
12031252 // iterating over each Function in M.
12041253 LLVM_DEBUG (dbgs () << " *** Populating mapper ***\n " );
1254+ bool EnableProfileGuidedOutlining =
1255+ RunOutlinerMode == RunOutliner::OptimisticPGO ||
1256+ RunOutlinerMode == RunOutliner::ConservativePGO;
1257+ ProfileSummaryInfo *PSI = nullptr ;
1258+ if (EnableProfileGuidedOutlining)
1259+ PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI ();
12051260 for (Function &F : M) {
12061261 LLVM_DEBUG (dbgs () << " MAPPING FUNCTION: " << F.getName () << " \n " );
12071262
@@ -1222,7 +1277,11 @@ void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M) {
12221277 }
12231278
12241279 const TargetInstrInfo *TII = MF->getSubtarget ().getInstrInfo ();
1225- if (!RunOnAllFunctions && !TII->shouldOutlineFromFunctionByDefault (*MF)) {
1280+ BlockFrequencyInfo *BFI = nullptr ;
1281+ if (EnableProfileGuidedOutlining && F.hasProfileData ())
1282+ BFI = &getAnalysis<BlockFrequencyInfoWrapperPass>(F).getBFI ();
1283+ if (RunOutlinerMode == RunOutliner::TargetDefault &&
1284+ !TII->shouldOutlineFromFunctionByDefault (*MF)) {
12261285 LLVM_DEBUG (dbgs () << " SKIP: Target does not want to outline from "
12271286 " function by default\n " );
12281287 continue ;
@@ -1262,6 +1321,11 @@ void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M) {
12621321 continue ;
12631322 }
12641323
1324+ if (!allowPGOOutlining (RunOutlinerMode, PSI, BFI, MBB)) {
1325+ ++NumPGOBlockedOutlined;
1326+ continue ;
1327+ }
1328+
12651329 // MBB is suitable for outlining. Map it to a list of unsigneds.
12661330 Mapper.convertToUnsignedVec (MBB, *TII);
12671331 }
@@ -1434,10 +1498,22 @@ bool MachineOutliner::doOutline(Module &M, unsigned &OutlinedFunctionNum) {
14341498 // the user how the outliner is running.
14351499 LLVM_DEBUG ({
14361500 dbgs () << " Machine Outliner: Running on " ;
1437- if (RunOnAllFunctions)
1501+ switch (RunOutlinerMode) {
1502+ case RunOutliner::AlwaysOutline:
14381503 dbgs () << " all functions" ;
1439- else
1504+ break ;
1505+ case RunOutliner::OptimisticPGO:
1506+ dbgs () << " optimistically cold functions" ;
1507+ break ;
1508+ case RunOutliner::ConservativePGO:
1509+ dbgs () << " conservatively cold functions" ;
1510+ break ;
1511+ case RunOutliner::TargetDefault:
14401512 dbgs () << " target-default functions" ;
1513+ break ;
1514+ case RunOutliner::NeverOutline:
1515+ llvm_unreachable (" should not outline" );
1516+ }
14411517 dbgs () << " \n " ;
14421518 });
14431519
0 commit comments