14
14
#include " BinaryFunction.h"
15
15
#include " DataReader.h"
16
16
#include " Passes/MCF.h"
17
- #include " Passes/ReorderAlgorithm.h"
18
17
#include " llvm/ADT/StringRef.h"
19
18
#include " llvm/DebugInfo/DWARF/DWARFContext.h"
20
19
#include " llvm/MC/MCAsmInfo.h"
@@ -53,18 +52,32 @@ extern cl::opt<bool> Relocs;
53
52
extern cl::opt<bool > UpdateDebugSections;
54
53
extern cl::opt<IndirectCallPromotionType> IndirectCallPromotion;
55
54
extern cl::opt<unsigned > Verbosity;
56
- extern cl::opt<unsigned > PrintFuncStat;
57
55
58
56
static cl::opt<bool >
59
- AggressiveSplitting ( " split-all-cold " ,
60
- cl::desc (" outline as many cold basic blocks as possible " ),
57
+ AlignBlocks ( " align-blocks " ,
58
+ cl::desc (" try to align BBs inserting nops " ),
61
59
cl::ZeroOrMore,
62
60
cl::cat(BoltOptCategory));
63
61
64
- static cl::opt<bool >
65
- AlignBlocks (" align-blocks" ,
66
- cl::desc (" try to align BBs inserting nops" ),
62
+ static cl::opt<MCFCostFunction>
63
+ DoMCF (" mcf" ,
64
+ cl::desc (" solve a min cost flow problem on the CFG to fix edge counts "
65
+ " (default=disable)" ),
66
+ cl::init(MCF_DISABLE),
67
+ cl::values(
68
+ clEnumValN (MCF_DISABLE, " none" ,
69
+ " disable MCF" ),
70
+ clEnumValN(MCF_LINEAR, " linear" ,
71
+ " cost function is inversely proportional to edge count" ),
72
+ clEnumValN(MCF_QUADRATIC, " quadratic" ,
73
+ " cost function is inversely proportional to edge count squared" ),
74
+ clEnumValN(MCF_LOG, " log" ,
75
+ " cost function is inversely proportional to log of edge count" ),
76
+ clEnumValN(MCF_BLAMEFTS, " blamefts" ,
77
+ " tune cost to blame fall-through edges for surplus flow" ),
78
+ clEnumValEnd),
67
79
cl::ZeroOrMore,
80
+ cl::Hidden,
68
81
cl::cat(BoltOptCategory));
69
82
70
83
static cl::opt<bool >
@@ -123,34 +136,6 @@ PrintOnly("print-only",
123
136
cl::Hidden,
124
137
cl::cat(BoltCategory));
125
138
126
- static cl::opt<bool >
127
- SplitEH (" split-eh" ,
128
- cl::desc (" split C++ exception handling code (experimental)" ),
129
- cl::ZeroOrMore,
130
- cl::Hidden,
131
- cl::cat(BoltOptCategory));
132
-
133
- cl::opt<MCFCostFunction>
134
- DoMCF (" mcf" ,
135
- cl::desc (" solve a min cost flow problem on the CFG to fix edge counts "
136
- " (default=disable)" ),
137
- cl::init(MCF_DISABLE),
138
- cl::values(
139
- clEnumValN (MCF_DISABLE, " none" ,
140
- " disable MCF" ),
141
- clEnumValN(MCF_LINEAR, " linear" ,
142
- " cost function is inversely proportional to edge count" ),
143
- clEnumValN(MCF_QUADRATIC, " quadratic" ,
144
- " cost function is inversely proportional to edge count squared" ),
145
- clEnumValN(MCF_LOG, " log" ,
146
- " cost function is inversely proportional to log of edge count" ),
147
- clEnumValN(MCF_BLAMEFTS, " blamefts" ,
148
- " tune cost to blame fall-through edges for surplus flow" ),
149
- clEnumValEnd),
150
- cl::ZeroOrMore,
151
- cl::Hidden,
152
- cl::cat(BoltOptCategory));
153
-
154
139
bool shouldPrint (const BinaryFunction &Function) {
155
140
if (PrintOnly.empty ())
156
141
return true ;
@@ -386,8 +371,8 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation,
386
371
<< " \n Orc Section : " << getCodeSectionName ()
387
372
<< " \n LSDA : 0x" << Twine::utohexstr (getLSDAAddress ())
388
373
<< " \n IsSimple : " << IsSimple
389
- << " \n IsSplit : " << IsSplit
390
- << " \n BB Count : " << BasicBlocksLayout. size ();
374
+ << " \n IsSplit : " << isSplit ()
375
+ << " \n BB Count : " << size ();
391
376
392
377
if (hasCFG ()) {
393
378
OS << " \n Hash : " << Twine::utohexstr (hash ());
@@ -2415,68 +2400,6 @@ bool BinaryFunction::fixCFIState() {
2415
2400
return true ;
2416
2401
}
2417
2402
2418
- void BinaryFunction::modifyLayout (LayoutType Type, bool MinBranchClusters,
2419
- bool Split) {
2420
- if (BasicBlocksLayout.empty () || Type == LT_NONE)
2421
- return ;
2422
-
2423
- BasicBlockOrderType NewLayout;
2424
- std::unique_ptr<ReorderAlgorithm> Algo;
2425
-
2426
- // Cannot do optimal layout without profile.
2427
- if (Type != LT_REVERSE && !hasValidProfile ())
2428
- return ;
2429
-
2430
- if (Type == LT_REVERSE) {
2431
- Algo.reset (new ReverseReorderAlgorithm ());
2432
- }
2433
- else if (BasicBlocksLayout.size () <= FUNC_SIZE_THRESHOLD &&
2434
- Type != LT_OPTIMIZE_SHUFFLE) {
2435
- // Work on optimal solution if problem is small enough
2436
- DEBUG (dbgs () << " finding optimal block layout for " << *this << " \n " );
2437
- Algo.reset (new OptimalReorderAlgorithm ());
2438
- }
2439
- else {
2440
- DEBUG (dbgs () << " running block layout heuristics on " << *this << " \n " );
2441
-
2442
- std::unique_ptr<ClusterAlgorithm> CAlgo;
2443
- if (MinBranchClusters)
2444
- CAlgo.reset (new MinBranchGreedyClusterAlgorithm ());
2445
- else
2446
- CAlgo.reset (new PHGreedyClusterAlgorithm ());
2447
-
2448
- switch (Type) {
2449
- case LT_OPTIMIZE:
2450
- Algo.reset (new OptimizeReorderAlgorithm (std::move (CAlgo)));
2451
- break ;
2452
-
2453
- case LT_OPTIMIZE_BRANCH:
2454
- Algo.reset (new OptimizeBranchReorderAlgorithm (std::move (CAlgo)));
2455
- break ;
2456
-
2457
- case LT_OPTIMIZE_CACHE:
2458
- Algo.reset (new OptimizeCacheReorderAlgorithm (std::move (CAlgo)));
2459
- break ;
2460
-
2461
- case LT_OPTIMIZE_SHUFFLE:
2462
- Algo.reset (new RandomClusterReorderAlgorithm (std::move (CAlgo)));
2463
- break ;
2464
-
2465
- default :
2466
- llvm_unreachable (" unexpected layout type" );
2467
- }
2468
- }
2469
-
2470
- Algo->reorderBasicBlocks (*this , NewLayout);
2471
- if (opts::PrintFuncStat > 0 )
2472
- BasicBlocksPreviousLayout = BasicBlocksLayout;
2473
- BasicBlocksLayout.clear ();
2474
- BasicBlocksLayout.swap (NewLayout);
2475
-
2476
- if (Split)
2477
- splitFunction ();
2478
- }
2479
-
2480
2403
uint64_t BinaryFunction::getInstructionCount () const {
2481
2404
uint64_t Count = 0 ;
2482
2405
for (auto &Block : BasicBlocksLayout) {
@@ -2486,12 +2409,10 @@ uint64_t BinaryFunction::getInstructionCount() const {
2486
2409
}
2487
2410
2488
2411
bool BinaryFunction::hasLayoutChanged () const {
2489
- assert (opts::PrintFuncStat > 0 && " PrintFuncStat flag is not on" );
2490
2412
return BasicBlocksPreviousLayout != BasicBlocksLayout;
2491
2413
}
2492
2414
2493
2415
uint64_t BinaryFunction::getEditDistance () const {
2494
- assert (opts::PrintFuncStat > 0 && " PrintFuncStat flag is not on" );
2495
2416
const auto LayoutSize = BasicBlocksPreviousLayout.size ();
2496
2417
if (LayoutSize < 2 ) {
2497
2418
return 0 ;
@@ -2899,83 +2820,6 @@ void BinaryFunction::fixBranches() {
2899
2820
assert (validateCFG () && " Invalid CFG detected after fixing branches" );
2900
2821
}
2901
2822
2902
- void BinaryFunction::splitFunction () {
2903
- bool AllCold = true ;
2904
- for (BinaryBasicBlock *BB : BasicBlocksLayout) {
2905
- auto ExecCount = BB->getExecutionCount ();
2906
- if (ExecCount == BinaryBasicBlock::COUNT_NO_PROFILE)
2907
- return ;
2908
- if (ExecCount != 0 )
2909
- AllCold = false ;
2910
- }
2911
-
2912
- if (AllCold)
2913
- return ;
2914
-
2915
- assert (BasicBlocksLayout.size () > 0 );
2916
-
2917
- // Never outline the first basic block.
2918
- BasicBlocks.front ()->setCanOutline (false );
2919
- for (auto BB : BasicBlocks) {
2920
- if (!BB->canOutline ())
2921
- continue ;
2922
- if (BB->getExecutionCount () != 0 ) {
2923
- BB->setCanOutline (false );
2924
- continue ;
2925
- }
2926
- if (hasEHRanges () && !opts::SplitEH) {
2927
- // We cannot move landing pads (or rather entry points for landing
2928
- // pads).
2929
- if (BB->isLandingPad ()) {
2930
- BB->setCanOutline (false );
2931
- continue ;
2932
- }
2933
- // We cannot move a block that can throw since exception-handling
2934
- // runtime cannot deal with split functions. However, if we can guarantee
2935
- // that the block never throws, it is safe to move the block to
2936
- // decrease the size of the function.
2937
- for (auto &Instr : *BB) {
2938
- if (BC.MIA ->isInvoke (Instr)) {
2939
- BB->setCanOutline (false );
2940
- break ;
2941
- }
2942
- }
2943
- }
2944
- }
2945
-
2946
- if (opts::AggressiveSplitting) {
2947
- // All blocks with 0 count that we can move go to the end of the function.
2948
- // Even if they were natural to cluster formation and were seen in-between
2949
- // hot basic blocks.
2950
- std::stable_sort (BasicBlocksLayout.begin (), BasicBlocksLayout.end (),
2951
- [&] (BinaryBasicBlock *A, BinaryBasicBlock *B) {
2952
- return A->canOutline () < B->canOutline ();
2953
- });
2954
- } else if (hasEHRanges () && !opts::SplitEH) {
2955
- // Typically functions with exception handling have landing pads at the end.
2956
- // We cannot move beginning of landing pads, but we can move 0-count blocks
2957
- // comprising landing pads to the end and thus facilitate splitting.
2958
- auto FirstLP = BasicBlocksLayout.begin ();
2959
- while ((*FirstLP)->isLandingPad ())
2960
- ++FirstLP;
2961
-
2962
- std::stable_sort (FirstLP, BasicBlocksLayout.end (),
2963
- [&] (BinaryBasicBlock *A, BinaryBasicBlock *B) {
2964
- return A->canOutline () < B->canOutline ();
2965
- });
2966
- }
2967
-
2968
- // Separate hot from cold starting from the bottom.
2969
- for (auto I = BasicBlocksLayout.rbegin (), E = BasicBlocksLayout.rend ();
2970
- I != E; ++I) {
2971
- BinaryBasicBlock *BB = *I;
2972
- if (!BB->canOutline ())
2973
- break ;
2974
- BB->setIsCold (true );
2975
- IsSplit = true ;
2976
- }
2977
- }
2978
-
2979
2823
void BinaryFunction::propagateGnuArgsSizeInfo () {
2980
2824
assert (CurrentState == State::CFG && " unexpected function state" );
2981
2825
@@ -3443,15 +3287,6 @@ void BinaryFunction::updateLayout(BinaryBasicBlock* Start,
3443
3287
updateLayoutIndices ();
3444
3288
}
3445
3289
3446
- void BinaryFunction::updateLayout (LayoutType Type,
3447
- bool MinBranchClusters,
3448
- bool Split) {
3449
- // Recompute layout with original parameters.
3450
- BasicBlocksLayout = BasicBlocks;
3451
- modifyLayout (Type, MinBranchClusters, Split);
3452
- updateLayoutIndices ();
3453
- }
3454
-
3455
3290
bool BinaryFunction::replaceJumpTableEntryIn (BinaryBasicBlock *BB,
3456
3291
BinaryBasicBlock *OldDest,
3457
3292
BinaryBasicBlock *NewDest) {
0 commit comments