59
59
#include " llvm/ADT/SmallSet.h"
60
60
#include " llvm/ADT/Statistic.h"
61
61
#include " llvm/ADT/Twine.h"
62
+ #include " llvm/Analysis/BlockFrequencyInfo.h"
62
63
#include " llvm/Analysis/ModuleSummaryAnalysis.h"
63
64
#include " llvm/Analysis/OptimizationRemarkEmitter.h"
65
+ #include " llvm/Analysis/ProfileSummaryInfo.h"
64
66
#include " llvm/CGData/CodeGenDataReader.h"
65
67
#include " llvm/CodeGen/LivePhysRegs.h"
66
68
#include " llvm/CodeGen/MachineModuleInfo.h"
@@ -107,6 +109,16 @@ STATISTIC(StableHashAttempts,
107
109
STATISTIC (StableHashDropped,
108
110
" Count of unsuccessful hashing attempts for outlined functions" );
109
111
STATISTIC (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" );
110
122
111
123
// Set to true if the user wants the outliner to run on linkonceodr linkage
112
124
// functions. This is false by default because the linker can dedupe linkonceodr
@@ -438,11 +450,10 @@ struct MachineOutliner : public ModulePass {
438
450
// / The current repeat number of machine outlining.
439
451
unsigned OutlineRepeatedNum = 0 ;
440
452
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;
446
457
447
458
// / This is a compact representation of hash sequences of outlined functions.
448
459
// / It is used when OutlinerMode = CGDataMode::Write.
@@ -468,6 +479,11 @@ struct MachineOutliner : public ModulePass {
468
479
AU.addRequired <TargetPassConfig>();
469
480
AU.addPreserved <MachineModuleInfoWrapperPass>();
470
481
AU.addUsedIfAvailable <ImmutableModuleSummaryIndexWrapperPass>();
482
+ if (RunOutlinerMode == RunOutliner::OptimisticPGO ||
483
+ RunOutlinerMode == RunOutliner::ConservativePGO) {
484
+ AU.addRequired <BlockFrequencyInfoWrapperPass>();
485
+ AU.addRequired <ProfileSummaryInfoWrapperPass>();
486
+ }
471
487
AU.setPreservesAll ();
472
488
ModulePass::getAnalysisUsage (AU);
473
489
}
@@ -578,9 +594,9 @@ struct MachineOutliner : public ModulePass {
578
594
char MachineOutliner::ID = 0 ;
579
595
580
596
namespace llvm {
581
- ModulePass *createMachineOutlinerPass (bool RunOnAllFunctions ) {
597
+ ModulePass *createMachineOutlinerPass (RunOutliner RunOutlinerMode ) {
582
598
MachineOutliner *OL = new MachineOutliner ();
583
- OL->RunOnAllFunctions = RunOnAllFunctions ;
599
+ OL->RunOutlinerMode = RunOutlinerMode ;
584
600
return OL;
585
601
}
586
602
@@ -1198,10 +1214,49 @@ bool MachineOutliner::outline(
1198
1214
return OutlinedSomething;
1199
1215
}
1200
1216
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
+
1201
1250
void MachineOutliner::populateMapper (InstructionMapper &Mapper, Module &M) {
1202
1251
// Build instruction mappings for each function in the module. Start by
1203
1252
// iterating over each Function in M.
1204
1253
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 ();
1205
1260
for (Function &F : M) {
1206
1261
LLVM_DEBUG (dbgs () << " MAPPING FUNCTION: " << F.getName () << " \n " );
1207
1262
@@ -1222,7 +1277,11 @@ void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M) {
1222
1277
}
1223
1278
1224
1279
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)) {
1226
1285
LLVM_DEBUG (dbgs () << " SKIP: Target does not want to outline from "
1227
1286
" function by default\n " );
1228
1287
continue ;
@@ -1262,6 +1321,11 @@ void MachineOutliner::populateMapper(InstructionMapper &Mapper, Module &M) {
1262
1321
continue ;
1263
1322
}
1264
1323
1324
+ if (!allowPGOOutlining (RunOutlinerMode, PSI, BFI, MBB)) {
1325
+ ++NumPGOBlockedOutlined;
1326
+ continue ;
1327
+ }
1328
+
1265
1329
// MBB is suitable for outlining. Map it to a list of unsigneds.
1266
1330
Mapper.convertToUnsignedVec (MBB, *TII);
1267
1331
}
@@ -1434,10 +1498,22 @@ bool MachineOutliner::doOutline(Module &M, unsigned &OutlinedFunctionNum) {
1434
1498
// the user how the outliner is running.
1435
1499
LLVM_DEBUG ({
1436
1500
dbgs () << " Machine Outliner: Running on " ;
1437
- if (RunOnAllFunctions)
1501
+ switch (RunOutlinerMode) {
1502
+ case RunOutliner::AlwaysOutline:
1438
1503
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:
1440
1512
dbgs () << " target-default functions" ;
1513
+ break ;
1514
+ case RunOutliner::NeverOutline:
1515
+ llvm_unreachable (" should not outline" );
1516
+ }
1441
1517
dbgs () << " \n " ;
1442
1518
});
1443
1519
0 commit comments