1*8d943a92SSnehasish Kumar //===-- BasicBlockSections.cpp ---=========--------------------------------===//
2*8d943a92SSnehasish Kumar //
3*8d943a92SSnehasish Kumar // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*8d943a92SSnehasish Kumar // See https://llvm.org/LICENSE.txt for license information.
5*8d943a92SSnehasish Kumar // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*8d943a92SSnehasish Kumar //
7*8d943a92SSnehasish Kumar //===----------------------------------------------------------------------===//
8*8d943a92SSnehasish Kumar //
9*8d943a92SSnehasish Kumar // BasicBlockSections implementation.
10*8d943a92SSnehasish Kumar //
11*8d943a92SSnehasish Kumar // The purpose of this pass is to assign sections to basic blocks when
12*8d943a92SSnehasish Kumar // -fbasic-block-sections= option is used. Further, with profile information
13*8d943a92SSnehasish Kumar // only the subset of basic blocks with profiles are placed in separate sections
14*8d943a92SSnehasish Kumar // and the rest are grouped in a cold section. The exception handling blocks are
15*8d943a92SSnehasish Kumar // treated specially to ensure they are all in one seciton.
16*8d943a92SSnehasish Kumar //
17*8d943a92SSnehasish Kumar // Basic Block Sections
18*8d943a92SSnehasish Kumar // ====================
19*8d943a92SSnehasish Kumar //
20*8d943a92SSnehasish Kumar // With option, -fbasic-block-sections=list, every function may be split into
21*8d943a92SSnehasish Kumar // clusters of basic blocks. Every cluster will be emitted into a separate
22*8d943a92SSnehasish Kumar // section with its basic blocks sequenced in the given order. To get the
23*8d943a92SSnehasish Kumar // optimized performance, the clusters must form an optimal BB layout for the
24*8d943a92SSnehasish Kumar // function. Every cluster's section is labeled with a symbol to allow the
25*8d943a92SSnehasish Kumar // linker to reorder the sections in any arbitrary sequence. A global order of
26*8d943a92SSnehasish Kumar // these sections would encapsulate the function layout.
27*8d943a92SSnehasish Kumar //
28*8d943a92SSnehasish Kumar // There are a couple of challenges to be addressed:
29*8d943a92SSnehasish Kumar //
30*8d943a92SSnehasish Kumar // 1. The last basic block of every cluster should not have any implicit
31*8d943a92SSnehasish Kumar //    fallthrough to its next basic block, as it can be reordered by the linker.
32*8d943a92SSnehasish Kumar //    The compiler should make these fallthroughs explicit by adding
33*8d943a92SSnehasish Kumar //    unconditional jumps..
34*8d943a92SSnehasish Kumar //
35*8d943a92SSnehasish Kumar // 2. All inter-cluster branch targets would now need to be resolved by the
36*8d943a92SSnehasish Kumar //    linker as they cannot be calculated during compile time. This is done
37*8d943a92SSnehasish Kumar //    using static relocations. Further, the compiler tries to use short branch
38*8d943a92SSnehasish Kumar //    instructions on some ISAs for small branch offsets. This is not possible
39*8d943a92SSnehasish Kumar //    for inter-cluster branches as the offset is not determined at compile
40*8d943a92SSnehasish Kumar //    time, and therefore, long branch instructions have to be used for those.
41*8d943a92SSnehasish Kumar //
42*8d943a92SSnehasish Kumar // 3. Debug Information (DebugInfo) and Call Frame Information (CFI) emission
43*8d943a92SSnehasish Kumar //    needs special handling with basic block sections. DebugInfo needs to be
44*8d943a92SSnehasish Kumar //    emitted with more relocations as basic block sections can break a
45*8d943a92SSnehasish Kumar //    function into potentially several disjoint pieces, and CFI needs to be
46*8d943a92SSnehasish Kumar //    emitted per cluster. This also bloats the object file and binary sizes.
47*8d943a92SSnehasish Kumar //
48*8d943a92SSnehasish Kumar // Basic Block Labels
49*8d943a92SSnehasish Kumar // ==================
50*8d943a92SSnehasish Kumar //
51*8d943a92SSnehasish Kumar // With -fbasic-block-sections=labels, or when a basic block is placed in a
52*8d943a92SSnehasish Kumar // unique section, it is labelled with a symbol.  This allows easy mapping of
53*8d943a92SSnehasish Kumar // virtual addresses from PMU profiles back to the corresponding basic blocks.
54*8d943a92SSnehasish Kumar // Since the number of basic blocks is large, the labeling bloats the symbol
55*8d943a92SSnehasish Kumar // table sizes and the string table sizes significantly. While the binary size
56*8d943a92SSnehasish Kumar // does increase, it does not affect performance as the symbol table is not
57*8d943a92SSnehasish Kumar // loaded in memory during run-time. The string table size bloat is kept very
58*8d943a92SSnehasish Kumar // minimal using a unary naming scheme that uses string suffix compression. The
59*8d943a92SSnehasish Kumar // basic blocks for function foo are named "a.BB.foo", "aa.BB.foo", ... This
60*8d943a92SSnehasish Kumar // turns out to be very good for string table sizes and the bloat in the string
61*8d943a92SSnehasish Kumar // table size for a very large binary is ~8 %.  The naming also allows using
62*8d943a92SSnehasish Kumar // the --symbol-ordering-file option in LLD to arbitrarily reorder the
63*8d943a92SSnehasish Kumar // sections.
64*8d943a92SSnehasish Kumar //
65*8d943a92SSnehasish Kumar //===----------------------------------------------------------------------===//
66*8d943a92SSnehasish Kumar 
67*8d943a92SSnehasish Kumar #include "llvm/ADT/Optional.h"
68*8d943a92SSnehasish Kumar #include "llvm/ADT/SmallSet.h"
69*8d943a92SSnehasish Kumar #include "llvm/ADT/SmallVector.h"
70*8d943a92SSnehasish Kumar #include "llvm/ADT/StringMap.h"
71*8d943a92SSnehasish Kumar #include "llvm/ADT/StringRef.h"
72*8d943a92SSnehasish Kumar #include "llvm/CodeGen/MachineFunction.h"
73*8d943a92SSnehasish Kumar #include "llvm/CodeGen/MachineFunctionPass.h"
74*8d943a92SSnehasish Kumar #include "llvm/CodeGen/MachineModuleInfo.h"
75*8d943a92SSnehasish Kumar #include "llvm/CodeGen/Passes.h"
76*8d943a92SSnehasish Kumar #include "llvm/CodeGen/TargetInstrInfo.h"
77*8d943a92SSnehasish Kumar #include "llvm/InitializePasses.h"
78*8d943a92SSnehasish Kumar #include "llvm/Support/Error.h"
79*8d943a92SSnehasish Kumar #include "llvm/Support/LineIterator.h"
80*8d943a92SSnehasish Kumar #include "llvm/Support/MemoryBuffer.h"
81*8d943a92SSnehasish Kumar #include "llvm/Target/TargetMachine.h"
82*8d943a92SSnehasish Kumar 
83*8d943a92SSnehasish Kumar using llvm::SmallSet;
84*8d943a92SSnehasish Kumar using llvm::SmallVector;
85*8d943a92SSnehasish Kumar using llvm::StringMap;
86*8d943a92SSnehasish Kumar using llvm::StringRef;
87*8d943a92SSnehasish Kumar using namespace llvm;
88*8d943a92SSnehasish Kumar 
89*8d943a92SSnehasish Kumar namespace {
90*8d943a92SSnehasish Kumar 
91*8d943a92SSnehasish Kumar // This struct represents the cluster information for a machine basic block.
92*8d943a92SSnehasish Kumar struct BBClusterInfo {
93*8d943a92SSnehasish Kumar   // MachineBasicBlock ID.
94*8d943a92SSnehasish Kumar   unsigned MBBNumber;
95*8d943a92SSnehasish Kumar   // Cluster ID this basic block belongs to.
96*8d943a92SSnehasish Kumar   unsigned ClusterID;
97*8d943a92SSnehasish Kumar   // Position of basic block within the cluster.
98*8d943a92SSnehasish Kumar   unsigned PositionInCluster;
99*8d943a92SSnehasish Kumar };
100*8d943a92SSnehasish Kumar 
101*8d943a92SSnehasish Kumar using ProgramBBClusterInfoMapTy = StringMap<SmallVector<BBClusterInfo, 4>>;
102*8d943a92SSnehasish Kumar 
103*8d943a92SSnehasish Kumar class BasicBlockSections : public MachineFunctionPass {
104*8d943a92SSnehasish Kumar public:
105*8d943a92SSnehasish Kumar   static char ID;
106*8d943a92SSnehasish Kumar 
107*8d943a92SSnehasish Kumar   // This contains the basic-block-sections profile.
108*8d943a92SSnehasish Kumar   const MemoryBuffer *MBuf = nullptr;
109*8d943a92SSnehasish Kumar 
110*8d943a92SSnehasish Kumar   // This encapsulates the BB cluster information for the whole program.
111*8d943a92SSnehasish Kumar   //
112*8d943a92SSnehasish Kumar   // For every function name, it contains the cluster information for (all or
113*8d943a92SSnehasish Kumar   // some of) its basic blocks. The cluster information for every basic block
114*8d943a92SSnehasish Kumar   // includes its cluster ID along with the position of the basic block in that
115*8d943a92SSnehasish Kumar   // cluster.
116*8d943a92SSnehasish Kumar   ProgramBBClusterInfoMapTy ProgramBBClusterInfo;
117*8d943a92SSnehasish Kumar 
118*8d943a92SSnehasish Kumar   // Some functions have alias names. We use this map to find the main alias
119*8d943a92SSnehasish Kumar   // name for which we have mapping in ProgramBBClusterInfo.
120*8d943a92SSnehasish Kumar   StringMap<StringRef> FuncAliasMap;
121*8d943a92SSnehasish Kumar 
122*8d943a92SSnehasish Kumar   BasicBlockSections(const MemoryBuffer *Buf)
123*8d943a92SSnehasish Kumar       : MachineFunctionPass(ID), MBuf(Buf) {
124*8d943a92SSnehasish Kumar     initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry());
125*8d943a92SSnehasish Kumar   };
126*8d943a92SSnehasish Kumar 
127*8d943a92SSnehasish Kumar   BasicBlockSections() : MachineFunctionPass(ID) {
128*8d943a92SSnehasish Kumar     initializeBasicBlockSectionsPass(*PassRegistry::getPassRegistry());
129*8d943a92SSnehasish Kumar   }
130*8d943a92SSnehasish Kumar 
131*8d943a92SSnehasish Kumar   StringRef getPassName() const override {
132*8d943a92SSnehasish Kumar     return "Basic Block Sections Analysis";
133*8d943a92SSnehasish Kumar   }
134*8d943a92SSnehasish Kumar 
135*8d943a92SSnehasish Kumar   void getAnalysisUsage(AnalysisUsage &AU) const override;
136*8d943a92SSnehasish Kumar 
137*8d943a92SSnehasish Kumar   /// Read profiles of basic blocks if available here.
138*8d943a92SSnehasish Kumar   bool doInitialization(Module &M) override;
139*8d943a92SSnehasish Kumar 
140*8d943a92SSnehasish Kumar   /// Identify basic blocks that need separate sections and prepare to emit them
141*8d943a92SSnehasish Kumar   /// accordingly.
142*8d943a92SSnehasish Kumar   bool runOnMachineFunction(MachineFunction &MF) override;
143*8d943a92SSnehasish Kumar };
144*8d943a92SSnehasish Kumar 
145*8d943a92SSnehasish Kumar } // end anonymous namespace
146*8d943a92SSnehasish Kumar 
147*8d943a92SSnehasish Kumar char BasicBlockSections::ID = 0;
148*8d943a92SSnehasish Kumar INITIALIZE_PASS(BasicBlockSections, "bbsections-prepare",
149*8d943a92SSnehasish Kumar                 "Prepares for basic block sections, by splitting functions "
150*8d943a92SSnehasish Kumar                 "into clusters of basic blocks.",
151*8d943a92SSnehasish Kumar                 false, false)
152*8d943a92SSnehasish Kumar 
153*8d943a92SSnehasish Kumar // This function updates and optimizes the branching instructions of every basic
154*8d943a92SSnehasish Kumar // block in a given function to account for changes in the layout.
155*8d943a92SSnehasish Kumar static void updateBranches(
156*8d943a92SSnehasish Kumar     MachineFunction &MF,
157*8d943a92SSnehasish Kumar     const SmallVector<MachineBasicBlock *, 4> &PreLayoutFallThroughs) {
158*8d943a92SSnehasish Kumar   const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
159*8d943a92SSnehasish Kumar   SmallVector<MachineOperand, 4> Cond;
160*8d943a92SSnehasish Kumar   for (auto &MBB : MF) {
161*8d943a92SSnehasish Kumar     auto NextMBBI = std::next(MBB.getIterator());
162*8d943a92SSnehasish Kumar     auto *FTMBB = PreLayoutFallThroughs[MBB.getNumber()];
163*8d943a92SSnehasish Kumar     // If this block had a fallthrough before we need an explicit unconditional
164*8d943a92SSnehasish Kumar     // branch to that block if either
165*8d943a92SSnehasish Kumar     //     1- the block ends a section, which means its next block may be
166*8d943a92SSnehasish Kumar     //        reorderd by the linker, or
167*8d943a92SSnehasish Kumar     //     2- the fallthrough block is not adjacent to the block in the new
168*8d943a92SSnehasish Kumar     //        order.
169*8d943a92SSnehasish Kumar     if (FTMBB && (MBB.isEndSection() || &*NextMBBI != FTMBB))
170*8d943a92SSnehasish Kumar       TII->insertUnconditionalBranch(MBB, FTMBB, MBB.findBranchDebugLoc());
171*8d943a92SSnehasish Kumar 
172*8d943a92SSnehasish Kumar     // We do not optimize branches for machine basic blocks ending sections, as
173*8d943a92SSnehasish Kumar     // their adjacent block might be reordered by the linker.
174*8d943a92SSnehasish Kumar     if (MBB.isEndSection())
175*8d943a92SSnehasish Kumar       continue;
176*8d943a92SSnehasish Kumar 
177*8d943a92SSnehasish Kumar     // It might be possible to optimize branches by flipping the branch
178*8d943a92SSnehasish Kumar     // condition.
179*8d943a92SSnehasish Kumar     Cond.clear();
180*8d943a92SSnehasish Kumar     MachineBasicBlock *TBB = nullptr, *FBB = nullptr; // For analyzeBranch.
181*8d943a92SSnehasish Kumar     if (TII->analyzeBranch(MBB, TBB, FBB, Cond))
182*8d943a92SSnehasish Kumar       continue;
183*8d943a92SSnehasish Kumar     MBB.updateTerminator(FTMBB);
184*8d943a92SSnehasish Kumar   }
185*8d943a92SSnehasish Kumar }
186*8d943a92SSnehasish Kumar 
187*8d943a92SSnehasish Kumar // This function provides the BBCluster information associated with a function.
188*8d943a92SSnehasish Kumar // Returns true if a valid association exists and false otherwise.
189*8d943a92SSnehasish Kumar static bool getBBClusterInfoForFunction(
190*8d943a92SSnehasish Kumar     const MachineFunction &MF, const StringMap<StringRef> FuncAliasMap,
191*8d943a92SSnehasish Kumar     const ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
192*8d943a92SSnehasish Kumar     std::vector<Optional<BBClusterInfo>> &V) {
193*8d943a92SSnehasish Kumar   // Get the main alias name for the function.
194*8d943a92SSnehasish Kumar   auto FuncName = MF.getName();
195*8d943a92SSnehasish Kumar   auto R = FuncAliasMap.find(FuncName);
196*8d943a92SSnehasish Kumar   StringRef AliasName = R == FuncAliasMap.end() ? FuncName : R->second;
197*8d943a92SSnehasish Kumar 
198*8d943a92SSnehasish Kumar   // Find the assoicated cluster information.
199*8d943a92SSnehasish Kumar   auto P = ProgramBBClusterInfo.find(AliasName);
200*8d943a92SSnehasish Kumar   if (P == ProgramBBClusterInfo.end())
201*8d943a92SSnehasish Kumar     return false;
202*8d943a92SSnehasish Kumar 
203*8d943a92SSnehasish Kumar   if (P->second.empty()) {
204*8d943a92SSnehasish Kumar     // This indicates that sections are desired for all basic blocks of this
205*8d943a92SSnehasish Kumar     // function. We clear the BBClusterInfo vector to denote this.
206*8d943a92SSnehasish Kumar     V.clear();
207*8d943a92SSnehasish Kumar     return true;
208*8d943a92SSnehasish Kumar   }
209*8d943a92SSnehasish Kumar 
210*8d943a92SSnehasish Kumar   V.resize(MF.getNumBlockIDs());
211*8d943a92SSnehasish Kumar   for (auto bbClusterInfo : P->second) {
212*8d943a92SSnehasish Kumar     // Bail out if the cluster information contains invalid MBB numbers.
213*8d943a92SSnehasish Kumar     if (bbClusterInfo.MBBNumber >= MF.getNumBlockIDs())
214*8d943a92SSnehasish Kumar       return false;
215*8d943a92SSnehasish Kumar     V[bbClusterInfo.MBBNumber] = bbClusterInfo;
216*8d943a92SSnehasish Kumar   }
217*8d943a92SSnehasish Kumar   return true;
218*8d943a92SSnehasish Kumar }
219*8d943a92SSnehasish Kumar 
220*8d943a92SSnehasish Kumar // This function sorts basic blocks according to the cluster's information.
221*8d943a92SSnehasish Kumar // All explicitly specified clusters of basic blocks will be ordered
222*8d943a92SSnehasish Kumar // accordingly. All non-specified BBs go into a separate "Cold" section.
223*8d943a92SSnehasish Kumar // Additionally, if exception handling landing pads end up in more than one
224*8d943a92SSnehasish Kumar // clusters, they are moved into a single "Exception" section. Eventually,
225*8d943a92SSnehasish Kumar // clusters are ordered in increasing order of their IDs, with the "Exception"
226*8d943a92SSnehasish Kumar // and "Cold" succeeding all other clusters.
227*8d943a92SSnehasish Kumar // FuncBBClusterInfo represent the cluster information for basic blocks. If this
228*8d943a92SSnehasish Kumar // is empty, it means unique sections for all basic blocks in the function.
229*8d943a92SSnehasish Kumar static bool assignSectionsAndSortBasicBlocks(
230*8d943a92SSnehasish Kumar     MachineFunction &MF,
231*8d943a92SSnehasish Kumar     const std::vector<Optional<BBClusterInfo>> &FuncBBClusterInfo) {
232*8d943a92SSnehasish Kumar   assert(MF.hasBBSections() && "BB Sections is not set for function.");
233*8d943a92SSnehasish Kumar   // This variable stores the section ID of the cluster containing eh_pads (if
234*8d943a92SSnehasish Kumar   // all eh_pads are one cluster). If more than one cluster contain eh_pads, we
235*8d943a92SSnehasish Kumar   // set it equal to ExceptionSectionID.
236*8d943a92SSnehasish Kumar   Optional<MBBSectionID> EHPadsSectionID;
237*8d943a92SSnehasish Kumar 
238*8d943a92SSnehasish Kumar   for (auto &MBB : MF) {
239*8d943a92SSnehasish Kumar     // With the 'all' option, every basic block is placed in a unique section.
240*8d943a92SSnehasish Kumar     // With the 'list' option, every basic block is placed in a section
241*8d943a92SSnehasish Kumar     // associated with its cluster, unless we want individual unique sections
242*8d943a92SSnehasish Kumar     // for every basic block in this function (if FuncBBClusterInfo is empty).
243*8d943a92SSnehasish Kumar     if (MF.getTarget().getBBSectionsType() == llvm::BasicBlockSection::All ||
244*8d943a92SSnehasish Kumar         FuncBBClusterInfo.empty()) {
245*8d943a92SSnehasish Kumar       // If unique sections are desired for all basic blocks of the function, we
246*8d943a92SSnehasish Kumar       // set every basic block's section ID equal to its number (basic block
247*8d943a92SSnehasish Kumar       // id). This further ensures that basic blocks are ordered canonically.
248*8d943a92SSnehasish Kumar       MBB.setSectionID({static_cast<unsigned int>(MBB.getNumber())});
249*8d943a92SSnehasish Kumar     } else if (FuncBBClusterInfo[MBB.getNumber()].hasValue())
250*8d943a92SSnehasish Kumar       MBB.setSectionID(FuncBBClusterInfo[MBB.getNumber()]->ClusterID);
251*8d943a92SSnehasish Kumar     else {
252*8d943a92SSnehasish Kumar       // BB goes into the special cold section if it is not specified in the
253*8d943a92SSnehasish Kumar       // cluster info map.
254*8d943a92SSnehasish Kumar       MBB.setSectionID(MBBSectionID::ColdSectionID);
255*8d943a92SSnehasish Kumar     }
256*8d943a92SSnehasish Kumar 
257*8d943a92SSnehasish Kumar     if (MBB.isEHPad() && EHPadsSectionID != MBB.getSectionID() &&
258*8d943a92SSnehasish Kumar         EHPadsSectionID != MBBSectionID::ExceptionSectionID) {
259*8d943a92SSnehasish Kumar       // If we already have one cluster containing eh_pads, this must be updated
260*8d943a92SSnehasish Kumar       // to ExceptionSectionID. Otherwise, we set it equal to the current
261*8d943a92SSnehasish Kumar       // section ID.
262*8d943a92SSnehasish Kumar       EHPadsSectionID = EHPadsSectionID.hasValue()
263*8d943a92SSnehasish Kumar                             ? MBBSectionID::ExceptionSectionID
264*8d943a92SSnehasish Kumar                             : MBB.getSectionID();
265*8d943a92SSnehasish Kumar     }
266*8d943a92SSnehasish Kumar   }
267*8d943a92SSnehasish Kumar 
268*8d943a92SSnehasish Kumar   // If EHPads are in more than one section, this places all of them in the
269*8d943a92SSnehasish Kumar   // special exception section.
270*8d943a92SSnehasish Kumar   if (EHPadsSectionID == MBBSectionID::ExceptionSectionID)
271*8d943a92SSnehasish Kumar     for (auto &MBB : MF)
272*8d943a92SSnehasish Kumar       if (MBB.isEHPad())
273*8d943a92SSnehasish Kumar         MBB.setSectionID(EHPadsSectionID.getValue());
274*8d943a92SSnehasish Kumar 
275*8d943a92SSnehasish Kumar   SmallVector<MachineBasicBlock *, 4> PreLayoutFallThroughs(
276*8d943a92SSnehasish Kumar       MF.getNumBlockIDs());
277*8d943a92SSnehasish Kumar   for (auto &MBB : MF)
278*8d943a92SSnehasish Kumar     PreLayoutFallThroughs[MBB.getNumber()] = MBB.getFallThrough();
279*8d943a92SSnehasish Kumar 
280*8d943a92SSnehasish Kumar   // We make sure that the cluster including the entry basic block precedes all
281*8d943a92SSnehasish Kumar   // other clusters.
282*8d943a92SSnehasish Kumar   auto EntryBBSectionID = MF.front().getSectionID();
283*8d943a92SSnehasish Kumar 
284*8d943a92SSnehasish Kumar   // Helper function for ordering BB sections as follows:
285*8d943a92SSnehasish Kumar   //   * Entry section (section including the entry block).
286*8d943a92SSnehasish Kumar   //   * Regular sections (in increasing order of their Number).
287*8d943a92SSnehasish Kumar   //     ...
288*8d943a92SSnehasish Kumar   //   * Exception section
289*8d943a92SSnehasish Kumar   //   * Cold section
290*8d943a92SSnehasish Kumar   auto MBBSectionOrder = [EntryBBSectionID](const MBBSectionID &LHS,
291*8d943a92SSnehasish Kumar                                             const MBBSectionID &RHS) {
292*8d943a92SSnehasish Kumar     // We make sure that the section containing the entry block precedes all the
293*8d943a92SSnehasish Kumar     // other sections.
294*8d943a92SSnehasish Kumar     if (LHS == EntryBBSectionID || RHS == EntryBBSectionID)
295*8d943a92SSnehasish Kumar       return LHS == EntryBBSectionID;
296*8d943a92SSnehasish Kumar     return LHS.Type == RHS.Type ? LHS.Number < RHS.Number : LHS.Type < RHS.Type;
297*8d943a92SSnehasish Kumar   };
298*8d943a92SSnehasish Kumar 
299*8d943a92SSnehasish Kumar   // We sort all basic blocks to make sure the basic blocks of every cluster are
300*8d943a92SSnehasish Kumar   // contiguous and ordered accordingly. Furthermore, clusters are ordered in
301*8d943a92SSnehasish Kumar   // increasing order of their section IDs, with the exception and the
302*8d943a92SSnehasish Kumar   // cold section placed at the end of the function.
303*8d943a92SSnehasish Kumar   MF.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) {
304*8d943a92SSnehasish Kumar     auto XSectionID = X.getSectionID();
305*8d943a92SSnehasish Kumar     auto YSectionID = Y.getSectionID();
306*8d943a92SSnehasish Kumar     if (XSectionID != YSectionID)
307*8d943a92SSnehasish Kumar       return MBBSectionOrder(XSectionID, YSectionID);
308*8d943a92SSnehasish Kumar     // If the two basic block are in the same section, the order is decided by
309*8d943a92SSnehasish Kumar     // their position within the section.
310*8d943a92SSnehasish Kumar     if (XSectionID.Type == MBBSectionID::SectionType::Default)
311*8d943a92SSnehasish Kumar       return FuncBBClusterInfo[X.getNumber()]->PositionInCluster <
312*8d943a92SSnehasish Kumar              FuncBBClusterInfo[Y.getNumber()]->PositionInCluster;
313*8d943a92SSnehasish Kumar     return X.getNumber() < Y.getNumber();
314*8d943a92SSnehasish Kumar   });
315*8d943a92SSnehasish Kumar 
316*8d943a92SSnehasish Kumar   // Set IsBeginSection and IsEndSection according to the assigned section IDs.
317*8d943a92SSnehasish Kumar   MF.assignBeginEndSections();
318*8d943a92SSnehasish Kumar 
319*8d943a92SSnehasish Kumar   // After reordering basic blocks, we must update basic block branches to
320*8d943a92SSnehasish Kumar   // insert explicit fallthrough branches when required and optimize branches
321*8d943a92SSnehasish Kumar   // when possible.
322*8d943a92SSnehasish Kumar   updateBranches(MF, PreLayoutFallThroughs);
323*8d943a92SSnehasish Kumar 
324*8d943a92SSnehasish Kumar   return true;
325*8d943a92SSnehasish Kumar }
326*8d943a92SSnehasish Kumar 
327*8d943a92SSnehasish Kumar bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
328*8d943a92SSnehasish Kumar   auto BBSectionsType = MF.getTarget().getBBSectionsType();
329*8d943a92SSnehasish Kumar   assert(BBSectionsType != BasicBlockSection::None &&
330*8d943a92SSnehasish Kumar          "BB Sections not enabled!");
331*8d943a92SSnehasish Kumar   // Renumber blocks before sorting them for basic block sections.  This is
332*8d943a92SSnehasish Kumar   // useful during sorting, basic blocks in the same section will retain the
333*8d943a92SSnehasish Kumar   // default order.  This renumbering should also be done for basic block
334*8d943a92SSnehasish Kumar   // labels to match the profiles with the correct blocks.
335*8d943a92SSnehasish Kumar   MF.RenumberBlocks();
336*8d943a92SSnehasish Kumar 
337*8d943a92SSnehasish Kumar   if (BBSectionsType == BasicBlockSection::Labels) {
338*8d943a92SSnehasish Kumar     MF.setBBSectionsType(BBSectionsType);
339*8d943a92SSnehasish Kumar     MF.createBBLabels();
340*8d943a92SSnehasish Kumar     return true;
341*8d943a92SSnehasish Kumar   }
342*8d943a92SSnehasish Kumar 
343*8d943a92SSnehasish Kumar   std::vector<Optional<BBClusterInfo>> FuncBBClusterInfo;
344*8d943a92SSnehasish Kumar   if (BBSectionsType == BasicBlockSection::List &&
345*8d943a92SSnehasish Kumar       !getBBClusterInfoForFunction(MF, FuncAliasMap, ProgramBBClusterInfo,
346*8d943a92SSnehasish Kumar                                    FuncBBClusterInfo))
347*8d943a92SSnehasish Kumar     return true;
348*8d943a92SSnehasish Kumar   MF.setBBSectionsType(BBSectionsType);
349*8d943a92SSnehasish Kumar   MF.createBBLabels();
350*8d943a92SSnehasish Kumar   assignSectionsAndSortBasicBlocks(MF, FuncBBClusterInfo);
351*8d943a92SSnehasish Kumar   return true;
352*8d943a92SSnehasish Kumar }
353*8d943a92SSnehasish Kumar 
354*8d943a92SSnehasish Kumar // Basic Block Sections can be enabled for a subset of machine basic blocks.
355*8d943a92SSnehasish Kumar // This is done by passing a file containing names of functions for which basic
356*8d943a92SSnehasish Kumar // block sections are desired.  Additionally, machine basic block ids of the
357*8d943a92SSnehasish Kumar // functions can also be specified for a finer granularity. Moreover, a cluster
358*8d943a92SSnehasish Kumar // of basic blocks could be assigned to the same section.
359*8d943a92SSnehasish Kumar // A file with basic block sections for all of function main and three blocks
360*8d943a92SSnehasish Kumar // for function foo (of which 1 and 2 are placed in a cluster) looks like this:
361*8d943a92SSnehasish Kumar // ----------------------------
362*8d943a92SSnehasish Kumar // list.txt:
363*8d943a92SSnehasish Kumar // !main
364*8d943a92SSnehasish Kumar // !foo
365*8d943a92SSnehasish Kumar // !!1 2
366*8d943a92SSnehasish Kumar // !!4
367*8d943a92SSnehasish Kumar static Error getBBClusterInfo(const MemoryBuffer *MBuf,
368*8d943a92SSnehasish Kumar                               ProgramBBClusterInfoMapTy &ProgramBBClusterInfo,
369*8d943a92SSnehasish Kumar                               StringMap<StringRef> &FuncAliasMap) {
370*8d943a92SSnehasish Kumar   assert(MBuf);
371*8d943a92SSnehasish Kumar   line_iterator LineIt(*MBuf, /*SkipBlanks=*/true, /*CommentMarker=*/'#');
372*8d943a92SSnehasish Kumar 
373*8d943a92SSnehasish Kumar   auto invalidProfileError = [&](auto Message) {
374*8d943a92SSnehasish Kumar     return make_error<StringError>(
375*8d943a92SSnehasish Kumar         Twine("Invalid profile " + MBuf->getBufferIdentifier() + " at line " +
376*8d943a92SSnehasish Kumar               Twine(LineIt.line_number()) + ": " + Message),
377*8d943a92SSnehasish Kumar         inconvertibleErrorCode());
378*8d943a92SSnehasish Kumar   };
379*8d943a92SSnehasish Kumar 
380*8d943a92SSnehasish Kumar   auto FI = ProgramBBClusterInfo.end();
381*8d943a92SSnehasish Kumar 
382*8d943a92SSnehasish Kumar   // Current cluster ID corresponding to this function.
383*8d943a92SSnehasish Kumar   unsigned CurrentCluster = 0;
384*8d943a92SSnehasish Kumar   // Current position in the current cluster.
385*8d943a92SSnehasish Kumar   unsigned CurrentPosition = 0;
386*8d943a92SSnehasish Kumar 
387*8d943a92SSnehasish Kumar   // Temporary set to ensure every basic block ID appears once in the clusters
388*8d943a92SSnehasish Kumar   // of a function.
389*8d943a92SSnehasish Kumar   SmallSet<unsigned, 4> FuncBBIDs;
390*8d943a92SSnehasish Kumar 
391*8d943a92SSnehasish Kumar   for (; !LineIt.is_at_eof(); ++LineIt) {
392*8d943a92SSnehasish Kumar     StringRef S(*LineIt);
393*8d943a92SSnehasish Kumar     if (S[0] == '@')
394*8d943a92SSnehasish Kumar       continue;
395*8d943a92SSnehasish Kumar     // Check for the leading "!"
396*8d943a92SSnehasish Kumar     if (!S.consume_front("!") || S.empty())
397*8d943a92SSnehasish Kumar       break;
398*8d943a92SSnehasish Kumar     // Check for second "!" which indicates a cluster of basic blocks.
399*8d943a92SSnehasish Kumar     if (S.consume_front("!")) {
400*8d943a92SSnehasish Kumar       if (FI == ProgramBBClusterInfo.end())
401*8d943a92SSnehasish Kumar         return invalidProfileError(
402*8d943a92SSnehasish Kumar             "Cluster list does not follow a function name specifier.");
403*8d943a92SSnehasish Kumar       SmallVector<StringRef, 4> BBIndexes;
404*8d943a92SSnehasish Kumar       S.split(BBIndexes, ' ');
405*8d943a92SSnehasish Kumar       // Reset current cluster position.
406*8d943a92SSnehasish Kumar       CurrentPosition = 0;
407*8d943a92SSnehasish Kumar       for (auto BBIndexStr : BBIndexes) {
408*8d943a92SSnehasish Kumar         unsigned long long BBIndex;
409*8d943a92SSnehasish Kumar         if (getAsUnsignedInteger(BBIndexStr, 10, BBIndex))
410*8d943a92SSnehasish Kumar           return invalidProfileError(Twine("Unsigned integer expected: '") +
411*8d943a92SSnehasish Kumar                                      BBIndexStr + "'.");
412*8d943a92SSnehasish Kumar         if (!FuncBBIDs.insert(BBIndex).second)
413*8d943a92SSnehasish Kumar           return invalidProfileError(Twine("Duplicate basic block id found '") +
414*8d943a92SSnehasish Kumar                                      BBIndexStr + "'.");
415*8d943a92SSnehasish Kumar         if (!BBIndex && CurrentPosition)
416*8d943a92SSnehasish Kumar           return invalidProfileError("Entry BB (0) does not begin a cluster.");
417*8d943a92SSnehasish Kumar 
418*8d943a92SSnehasish Kumar         FI->second.emplace_back(BBClusterInfo{
419*8d943a92SSnehasish Kumar             ((unsigned)BBIndex), CurrentCluster, CurrentPosition++});
420*8d943a92SSnehasish Kumar       }
421*8d943a92SSnehasish Kumar       CurrentCluster++;
422*8d943a92SSnehasish Kumar     } else { // This is a function name specifier.
423*8d943a92SSnehasish Kumar       // Function aliases are separated using '/'. We use the first function
424*8d943a92SSnehasish Kumar       // name for the cluster info mapping and delegate all other aliases to
425*8d943a92SSnehasish Kumar       // this one.
426*8d943a92SSnehasish Kumar       SmallVector<StringRef, 4> Aliases;
427*8d943a92SSnehasish Kumar       S.split(Aliases, '/');
428*8d943a92SSnehasish Kumar       for (size_t i = 1; i < Aliases.size(); ++i)
429*8d943a92SSnehasish Kumar         FuncAliasMap.try_emplace(Aliases[i], Aliases.front());
430*8d943a92SSnehasish Kumar 
431*8d943a92SSnehasish Kumar       // Prepare for parsing clusters of this function name.
432*8d943a92SSnehasish Kumar       // Start a new cluster map for this function name.
433*8d943a92SSnehasish Kumar       FI = ProgramBBClusterInfo.try_emplace(Aliases.front()).first;
434*8d943a92SSnehasish Kumar       CurrentCluster = 0;
435*8d943a92SSnehasish Kumar       FuncBBIDs.clear();
436*8d943a92SSnehasish Kumar     }
437*8d943a92SSnehasish Kumar   }
438*8d943a92SSnehasish Kumar   return Error::success();
439*8d943a92SSnehasish Kumar }
440*8d943a92SSnehasish Kumar 
441*8d943a92SSnehasish Kumar bool BasicBlockSections::doInitialization(Module &M) {
442*8d943a92SSnehasish Kumar   if (!MBuf)
443*8d943a92SSnehasish Kumar     return false;
444*8d943a92SSnehasish Kumar   if (auto Err = getBBClusterInfo(MBuf, ProgramBBClusterInfo, FuncAliasMap))
445*8d943a92SSnehasish Kumar     report_fatal_error(std::move(Err));
446*8d943a92SSnehasish Kumar   return false;
447*8d943a92SSnehasish Kumar }
448*8d943a92SSnehasish Kumar 
449*8d943a92SSnehasish Kumar void BasicBlockSections::getAnalysisUsage(AnalysisUsage &AU) const {
450*8d943a92SSnehasish Kumar   AU.setPreservesAll();
451*8d943a92SSnehasish Kumar   MachineFunctionPass::getAnalysisUsage(AU);
452*8d943a92SSnehasish Kumar }
453*8d943a92SSnehasish Kumar 
454*8d943a92SSnehasish Kumar MachineFunctionPass *
455*8d943a92SSnehasish Kumar llvm::createBasicBlockSectionsPass(const MemoryBuffer *Buf) {
456*8d943a92SSnehasish Kumar   return new BasicBlockSections(Buf);
457*8d943a92SSnehasish Kumar }
458