1 //===- bolt/Core/BinaryFunction.h - Low-level function ----------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the declaration of the BinaryFunction class. It represents
10 // a function at the lowest IR level. Typically, a BinaryFunction represents a
11 // function object in a compiled and linked binary file. However, a
12 // BinaryFunction can also be constructed manually, e.g. for injecting into a
13 // binary file.
14 //
15 // A BinaryFunction could be in one of the several states described in
16 // BinaryFunction::State. While in the disassembled state, it will contain a
17 // list of instructions with their offsets. In the CFG state, it will contain a
18 // list of BinaryBasicBlocks that form a control-flow graph. This state is best
19 // suited for binary analysis and optimizations. However, sometimes it's
20 // impossible to build the precise CFG due to the ambiguity of indirect
21 // branches.
22 //
23 //===----------------------------------------------------------------------===//
24 
25 #ifndef BOLT_CORE_BINARY_FUNCTION_H
26 #define BOLT_CORE_BINARY_FUNCTION_H
27 
28 #include "bolt/Core/BinaryBasicBlock.h"
29 #include "bolt/Core/BinaryContext.h"
30 #include "bolt/Core/BinaryLoop.h"
31 #include "bolt/Core/BinarySection.h"
32 #include "bolt/Core/DebugData.h"
33 #include "bolt/Core/JumpTable.h"
34 #include "bolt/Core/MCPlus.h"
35 #include "bolt/Utils/NameResolver.h"
36 #include "llvm/ADT/StringRef.h"
37 #include "llvm/ADT/iterator.h"
38 #include "llvm/BinaryFormat/Dwarf.h"
39 #include "llvm/MC/MCContext.h"
40 #include "llvm/MC/MCDwarf.h"
41 #include "llvm/MC/MCInst.h"
42 #include "llvm/MC/MCSymbol.h"
43 #include "llvm/Object/ObjectFile.h"
44 #include "llvm/Support/raw_ostream.h"
45 #include <algorithm>
46 #include <limits>
47 #include <unordered_map>
48 #include <unordered_set>
49 #include <vector>
50 
51 using namespace llvm::object;
52 
53 namespace llvm {
54 
55 class DWARFUnit;
56 
57 namespace bolt {
58 
59 using InputOffsetToAddressMapTy = std::unordered_multimap<uint64_t, uint64_t>;
60 
61 /// Types of macro-fusion alignment corrections.
62 enum MacroFusionType { MFT_NONE, MFT_HOT, MFT_ALL };
63 
64 enum IndirectCallPromotionType : char {
65   ICP_NONE,        /// Don't perform ICP.
66   ICP_CALLS,       /// Perform ICP on indirect calls.
67   ICP_JUMP_TABLES, /// Perform ICP on jump tables.
68   ICP_ALL          /// Perform ICP on calls and jump tables.
69 };
70 
71 /// Information on a single indirect call to a particular callee.
72 struct IndirectCallProfile {
73   MCSymbol *Symbol;
74   uint32_t Offset;
75   uint64_t Count;
76   uint64_t Mispreds;
77 
78   IndirectCallProfile(MCSymbol *Symbol, uint64_t Count, uint64_t Mispreds,
79                       uint32_t Offset = 0)
80       : Symbol(Symbol), Offset(Offset), Count(Count), Mispreds(Mispreds) {}
81 
82   bool operator==(const IndirectCallProfile &Other) const {
83     return Symbol == Other.Symbol && Offset == Other.Offset;
84   }
85 };
86 
87 /// Aggregated information for an indirect call site.
88 using IndirectCallSiteProfile = SmallVector<IndirectCallProfile, 4>;
89 
90 inline raw_ostream &operator<<(raw_ostream &OS,
91                                const bolt::IndirectCallSiteProfile &ICSP) {
92   std::string TempString;
93   raw_string_ostream SS(TempString);
94 
95   const char *Sep = "\n        ";
96   uint64_t TotalCount = 0;
97   uint64_t TotalMispreds = 0;
98   for (const IndirectCallProfile &CSP : ICSP) {
99     SS << Sep << "{ " << (CSP.Symbol ? CSP.Symbol->getName() : "<unknown>")
100        << ": " << CSP.Count << " (" << CSP.Mispreds << " misses) }";
101     Sep = ",\n        ";
102     TotalCount += CSP.Count;
103     TotalMispreds += CSP.Mispreds;
104   }
105   SS.flush();
106 
107   OS << TotalCount << " (" << TotalMispreds << " misses) :" << TempString;
108   return OS;
109 }
110 
111 /// BinaryFunction is a representation of machine-level function.
112 ///
113 /// In the input binary, an instance of BinaryFunction can represent a fragment
114 /// of a function if the higher-level function was split, e.g. into hot and cold
115 /// parts. The fragment containing the main entry point is called a parent
116 /// or the main fragment.
117 class BinaryFunction {
118 public:
119   enum class State : char {
120     Empty = 0,     /// Function body is empty.
121     Disassembled,  /// Function have been disassembled.
122     CFG,           /// Control flow graph has been built.
123     CFG_Finalized, /// CFG is finalized. No optimizations allowed.
124     EmittedCFG,    /// Instructions have been emitted to output.
125     Emitted,       /// Same as above plus CFG is destroyed.
126   };
127 
128   /// Types of profile the function can use. Could be a combination.
129   enum {
130     PF_NONE = 0,     /// No profile.
131     PF_LBR = 1,      /// Profile is based on last branch records.
132     PF_SAMPLE = 2,   /// Non-LBR sample-based profile.
133     PF_MEMEVENT = 4, /// Profile has mem events.
134   };
135 
136   /// Struct for tracking exception handling ranges.
137   struct CallSite {
138     const MCSymbol *Start;
139     const MCSymbol *End;
140     const MCSymbol *LP;
141     uint64_t Action;
142   };
143 
144   using CallSitesType = SmallVector<CallSite, 0>;
145 
146   using IslandProxiesType =
147       std::map<BinaryFunction *, std::map<const MCSymbol *, MCSymbol *>>;
148 
149   struct IslandInfo {
150     /// Temporary holder of offsets that are data markers (used in AArch)
151     /// It is possible to have data in code sections. To ease the identification
152     /// of data in code sections, the ABI requires the symbol table to have
153     /// symbols named "$d" identifying the start of data inside code and "$x"
154     /// identifying the end of a chunk of data inside code. DataOffsets contain
155     /// all offsets of $d symbols and CodeOffsets all offsets of $x symbols.
156     std::set<uint64_t> DataOffsets;
157     std::set<uint64_t> CodeOffsets;
158 
159     /// List of relocations associated with data in the constant island
160     std::map<uint64_t, Relocation> Relocations;
161 
162     /// Offsets in function that are data values in a constant island identified
163     /// after disassembling
164     std::map<uint64_t, MCSymbol *> Offsets;
165     SmallPtrSet<MCSymbol *, 4> Symbols;
166     DenseMap<const MCSymbol *, BinaryFunction *> ProxySymbols;
167     DenseMap<const MCSymbol *, MCSymbol *> ColdSymbols;
168     /// Keeps track of other functions we depend on because there is a reference
169     /// to the constant islands in them.
170     IslandProxiesType Proxies, ColdProxies;
171     SmallPtrSet<BinaryFunction *, 1> Dependency; // The other way around
172 
173     mutable MCSymbol *FunctionConstantIslandLabel{nullptr};
174     mutable MCSymbol *FunctionColdConstantIslandLabel{nullptr};
175 
176     // Returns constant island alignment
177     uint16_t getAlignment() const { return sizeof(uint64_t); }
178   };
179 
180   static constexpr uint64_t COUNT_NO_PROFILE =
181       BinaryBasicBlock::COUNT_NO_PROFILE;
182 
183   /// We have to use at least 2-byte alignment for functions because of C++ ABI.
184   static constexpr unsigned MinAlign = 2;
185 
186   static const char TimerGroupName[];
187   static const char TimerGroupDesc[];
188 
189   using BasicBlockOrderType = SmallVector<BinaryBasicBlock *, 0>;
190 
191   /// Mark injected functions
192   bool IsInjected = false;
193 
194   using LSDATypeTableTy = SmallVector<uint64_t, 0>;
195 
196   /// List of DWARF CFI instructions. Original CFI from the binary must be
197   /// sorted w.r.t. offset that it appears. We rely on this to replay CFIs
198   /// if needed (to fix state after reordering BBs).
199   using CFIInstrMapType = SmallVector<MCCFIInstruction, 0>;
200   using cfi_iterator = CFIInstrMapType::iterator;
201   using const_cfi_iterator = CFIInstrMapType::const_iterator;
202 
203 private:
204   /// Current state of the function.
205   State CurrentState{State::Empty};
206 
207   /// A list of symbols associated with the function entry point.
208   ///
209   /// Multiple symbols would typically result from identical code-folding
210   /// optimization.
211   typedef SmallVector<MCSymbol *, 1> SymbolListTy;
212   SymbolListTy Symbols;
213 
214   /// The list of names this function is known under. Used for fuzzy-matching
215   /// the function to its name in a profile, command line, etc.
216   SmallVector<std::string, 0> Aliases;
217 
218   /// Containing section in the input file.
219   BinarySection *OriginSection = nullptr;
220 
221   /// Address of the function in memory. Also could be an offset from
222   /// base address for position independent binaries.
223   uint64_t Address;
224 
225   /// Original size of the function.
226   uint64_t Size;
227 
228   /// Address of the function in output.
229   uint64_t OutputAddress{0};
230 
231   /// Size of the function in the output file.
232   uint64_t OutputSize{0};
233 
234   /// Offset in the file.
235   uint64_t FileOffset{0};
236 
237   /// Maximum size this function is allowed to have.
238   uint64_t MaxSize{std::numeric_limits<uint64_t>::max()};
239 
240   /// Alignment requirements for the function.
241   uint16_t Alignment{2};
242 
243   /// Maximum number of bytes used for alignment of hot part of the function.
244   uint16_t MaxAlignmentBytes{0};
245 
246   /// Maximum number of bytes used for alignment of cold part of the function.
247   uint16_t MaxColdAlignmentBytes{0};
248 
249   const MCSymbol *PersonalityFunction{nullptr};
250   uint8_t PersonalityEncoding{dwarf::DW_EH_PE_sdata4 | dwarf::DW_EH_PE_pcrel};
251 
252   BinaryContext &BC;
253 
254   std::unique_ptr<BinaryLoopInfo> BLI;
255 
256   /// All labels in the function that are referenced via relocations from
257   /// data objects. Typically these are jump table destinations and computed
258   /// goto labels.
259   std::set<uint64_t> ExternallyReferencedOffsets;
260 
261   /// Offsets of indirect branches with unknown destinations.
262   std::set<uint64_t> UnknownIndirectBranchOffsets;
263 
264   /// A set of local and global symbols corresponding to secondary entry points.
265   /// Each additional function entry point has a corresponding entry in the map.
266   /// The key is a local symbol corresponding to a basic block and the value
267   /// is a global symbol corresponding to an external entry point.
268   DenseMap<const MCSymbol *, MCSymbol *> SecondaryEntryPoints;
269 
270   /// False if the function is too complex to reconstruct its control
271   /// flow graph.
272   /// In relocation mode we still disassemble and re-assemble such functions.
273   bool IsSimple{true};
274 
275   /// Indication that the function should be ignored for optimization purposes.
276   /// If we can skip emission of some functions, then ignored functions could
277   /// be not fully disassembled and will not be emitted.
278   bool IsIgnored{false};
279 
280   /// Pseudo functions should not be disassembled or emitted.
281   bool IsPseudo{false};
282 
283   /// True if the original function code has all necessary relocations to track
284   /// addresses of functions emitted to new locations. Typically set for
285   /// functions that we are not going to emit.
286   bool HasExternalRefRelocations{false};
287 
288   /// True if the function has an indirect branch with unknown destination.
289   bool HasUnknownControlFlow{false};
290 
291   /// The code from inside the function references one of the code locations
292   /// from the same function as a data, i.e. it's possible the label is used
293   /// inside an address calculation or could be referenced from outside.
294   bool HasInternalLabelReference{false};
295 
296   /// In AArch64, preserve nops to maintain code equal to input (assuming no
297   /// optimizations are done).
298   bool PreserveNops{false};
299 
300   /// Indicate if this function has associated exception handling metadata.
301   bool HasEHRanges{false};
302 
303   /// True if the function uses DW_CFA_GNU_args_size CFIs.
304   bool UsesGnuArgsSize{false};
305 
306   /// True if the function might have a profile available externally.
307   /// Used to check if processing of the function is required under certain
308   /// conditions.
309   bool HasProfileAvailable{false};
310 
311   bool HasMemoryProfile{false};
312 
313   /// Execution halts whenever this function is entered.
314   bool TrapsOnEntry{false};
315 
316   /// True if the function had an indirect branch with a fixed internal
317   /// destination.
318   bool HasFixedIndirectBranch{false};
319 
320   /// True if the function is a fragment of another function. This means that
321   /// this function could only be entered via its parent or one of its sibling
322   /// fragments. It could be entered at any basic block. It can also return
323   /// the control to any basic block of its parent or its sibling.
324   bool IsFragment{false};
325 
326   /// Indicate that the function body has SDT marker
327   bool HasSDTMarker{false};
328 
329   /// Indicate that the function body has Pseudo Probe
330   bool HasPseudoProbe{BC.getUniqueSectionByName(".pseudo_probe_desc") &&
331                       BC.getUniqueSectionByName(".pseudo_probe")};
332 
333   /// True if the original entry point was patched.
334   bool IsPatched{false};
335 
336   /// True if the function contains explicit or implicit indirect branch to its
337   /// split fragments, e.g., split jump table, landing pad in split fragment
338   bool HasIndirectTargetToSplitFragment{false};
339 
340   /// True if there are no control-flow edges with successors in other functions
341   /// (i.e. if tail calls have edges to function-local basic blocks).
342   /// Set to false by SCTC. Dynostats can't be reliably computed for
343   /// functions with non-canonical CFG.
344   /// This attribute is only valid when hasCFG() == true.
345   bool HasCanonicalCFG{true};
346 
347   /// The address for the code for this function in codegen memory.
348   /// Used for functions that are emitted in a dedicated section with a fixed
349   /// address. E.g. for functions that are overwritten in-place.
350   uint64_t ImageAddress{0};
351 
352   /// The size of the code in memory.
353   uint64_t ImageSize{0};
354 
355   /// Name for the section this function code should reside in.
356   std::string CodeSectionName;
357 
358   /// Name for the corresponding cold code section.
359   std::string ColdCodeSectionName;
360 
361   /// Parent function fragment for split function fragments.
362   SmallPtrSet<BinaryFunction *, 1> ParentFragments;
363 
364   /// Indicate if the function body was folded into another function.
365   /// Used by ICF optimization.
366   BinaryFunction *FoldedIntoFunction{nullptr};
367 
368   /// All fragments for a parent function.
369   SmallPtrSet<BinaryFunction *, 1> Fragments;
370 
371   /// The profile data for the number of times the function was executed.
372   uint64_t ExecutionCount{COUNT_NO_PROFILE};
373 
374   /// Profile match ratio.
375   float ProfileMatchRatio{0.0f};
376 
377   /// Raw branch count for this function in the profile
378   uint64_t RawBranchCount{0};
379 
380   /// Indicates the type of profile the function is using.
381   uint16_t ProfileFlags{PF_NONE};
382 
383   /// For functions with mismatched profile we store all call profile
384   /// information at a function level (as opposed to tying it to
385   /// specific call sites).
386   IndirectCallSiteProfile AllCallSites;
387 
388   /// Score of the function (estimated number of instructions executed,
389   /// according to profile data). -1 if the score has not been calculated yet.
390   mutable int64_t FunctionScore{-1};
391 
392   /// Original LSDA address for the function.
393   uint64_t LSDAAddress{0};
394 
395   /// Containing compilation unit for the function.
396   DWARFUnit *DwarfUnit{nullptr};
397 
398   /// Last computed hash value. Note that the value could be recomputed using
399   /// different parameters by every pass.
400   mutable uint64_t Hash{0};
401 
402   /// For PLT functions it contains a symbol associated with a function
403   /// reference. It is nullptr for non-PLT functions.
404   const MCSymbol *PLTSymbol{nullptr};
405 
406   /// Function order for streaming into the destination binary.
407   uint32_t Index{-1U};
408 
409   /// Get basic block index assuming it belongs to this function.
410   unsigned getIndex(const BinaryBasicBlock *BB) const {
411     assert(BB->getIndex() < BasicBlocks.size());
412     return BB->getIndex();
413   }
414 
415   /// Return basic block that originally contained offset \p Offset
416   /// from the function start.
417   BinaryBasicBlock *getBasicBlockContainingOffset(uint64_t Offset);
418 
419   const BinaryBasicBlock *getBasicBlockContainingOffset(uint64_t Offset) const {
420     return const_cast<BinaryFunction *>(this)->getBasicBlockContainingOffset(
421         Offset);
422   }
423 
424   /// Return basic block that started at offset \p Offset.
425   BinaryBasicBlock *getBasicBlockAtOffset(uint64_t Offset) {
426     BinaryBasicBlock *BB = getBasicBlockContainingOffset(Offset);
427     return BB && BB->getOffset() == Offset ? BB : nullptr;
428   }
429 
430   /// Release memory taken by the list.
431   template <typename T> BinaryFunction &clearList(T &List) {
432     T TempList;
433     TempList.swap(List);
434     return *this;
435   }
436 
437   /// Update the indices of all the basic blocks starting at StartIndex.
438   void updateBBIndices(const unsigned StartIndex);
439 
440   /// Annotate each basic block entry with its current CFI state. This is
441   /// run right after the construction of CFG while basic blocks are in their
442   /// original order.
443   void annotateCFIState();
444 
445   /// Associate DW_CFA_GNU_args_size info with invoke instructions
446   /// (call instructions with non-empty landing pad).
447   void propagateGnuArgsSizeInfo(MCPlusBuilder::AllocatorIdTy AllocId);
448 
449   /// Synchronize branch instructions with CFG.
450   void postProcessBranches();
451 
452   /// The address offset where we emitted the constant island, that is, the
453   /// chunk of data in the function code area (AArch only)
454   int64_t OutputDataOffset{0};
455   int64_t OutputColdDataOffset{0};
456 
457   /// Map labels to corresponding basic blocks.
458   DenseMap<const MCSymbol *, BinaryBasicBlock *> LabelToBB;
459 
460   using BranchListType = SmallVector<std::pair<uint32_t, uint32_t>, 0>;
461   BranchListType TakenBranches;   /// All local taken branches.
462   BranchListType IgnoredBranches; /// Branches ignored by CFG purposes.
463 
464   /// Map offset in the function to a label.
465   /// Labels are used for building CFG for simple functions. For non-simple
466   /// function in relocation mode we need to emit them for relocations
467   /// referencing function internals to work (e.g. jump tables).
468   using LabelsMapType = std::map<uint32_t, MCSymbol *>;
469   LabelsMapType Labels;
470 
471   /// Temporary holder of instructions before CFG is constructed.
472   /// Map offset in the function to MCInst.
473   using InstrMapType = std::map<uint32_t, MCInst>;
474   InstrMapType Instructions;
475 
476   /// We don't decode Call Frame Info encoded in DWARF program state
477   /// machine. Instead we define a "CFI State" - a frame information that
478   /// is a result of executing FDE CFI program up to a given point. The
479   /// program consists of opaque Call Frame Instructions:
480   ///
481   ///   CFI #0
482   ///   CFI #1
483   ///   ....
484   ///   CFI #N
485   ///
486   /// When we refer to "CFI State K" - it corresponds to a row in an abstract
487   /// Call Frame Info table. This row is reached right before executing CFI #K.
488   ///
489   /// At any point of execution in a function we are in any one of (N + 2)
490   /// states described in the original FDE program. We can't have more states
491   /// without intelligent processing of CFIs.
492   ///
493   /// When the final layout of basic blocks is known, and we finalize CFG,
494   /// we modify the original program to make sure the same state could be
495   /// reached even when basic blocks containing CFI instructions are executed
496   /// in a different order.
497   CFIInstrMapType FrameInstructions;
498 
499   /// A map of restore state CFI instructions to their equivalent CFI
500   /// instructions that produce the same state, in order to eliminate
501   /// remember-restore CFI instructions when rewriting CFI.
502   DenseMap<int32_t, SmallVector<int32_t, 4>> FrameRestoreEquivalents;
503 
504   // For tracking exception handling ranges.
505   CallSitesType CallSites;
506   CallSitesType ColdCallSites;
507 
508   /// Binary blobs representing action, type, and type index tables for this
509   /// function' LSDA (exception handling).
510   ArrayRef<uint8_t> LSDAActionTable;
511   ArrayRef<uint8_t> LSDATypeIndexTable;
512 
513   /// Vector of addresses of types referenced by LSDA.
514   LSDATypeTableTy LSDATypeTable;
515 
516   /// Vector of addresses of entries in LSDATypeTable used for indirect
517   /// addressing.
518   LSDATypeTableTy LSDATypeAddressTable;
519 
520   /// Marking for the beginning of language-specific data area for the function.
521   MCSymbol *LSDASymbol{nullptr};
522   MCSymbol *ColdLSDASymbol{nullptr};
523 
524   /// Map to discover which CFIs are attached to a given instruction offset.
525   /// Maps an instruction offset into a FrameInstructions offset.
526   /// This is only relevant to the buildCFG phase and is discarded afterwards.
527   std::multimap<uint32_t, uint32_t> OffsetToCFI;
528 
529   /// List of CFI instructions associated with the CIE (common to more than one
530   /// function and that apply before the entry basic block).
531   CFIInstrMapType CIEFrameInstructions;
532 
533   /// All compound jump tables for this function. This duplicates what's stored
534   /// in the BinaryContext, but additionally it gives quick access for all
535   /// jump tables used by this function.
536   ///
537   /// <OriginalAddress> -> <JumpTable *>
538   std::map<uint64_t, JumpTable *> JumpTables;
539 
540   /// All jump table sites in the function before CFG is built.
541   SmallVector<std::pair<uint64_t, uint64_t>, 0> JTSites;
542 
543   /// List of relocations in this function.
544   std::map<uint64_t, Relocation> Relocations;
545 
546   /// Information on function constant islands.
547   std::unique_ptr<IslandInfo> Islands;
548 
549   // Blocks are kept sorted in the layout order. If we need to change the
550   // layout (if BasicBlocksLayout stores a different order than BasicBlocks),
551   // the terminating instructions need to be modified.
552   using BasicBlockListType = SmallVector<BinaryBasicBlock *, 0>;
553   BasicBlockListType BasicBlocks;
554   BasicBlockListType DeletedBasicBlocks;
555   BasicBlockOrderType BasicBlocksLayout;
556   /// Previous layout replaced by modifyLayout
557   BasicBlockOrderType BasicBlocksPreviousLayout;
558   bool ModifiedLayout{false};
559 
560   /// BasicBlockOffsets are used during CFG construction to map from code
561   /// offsets to BinaryBasicBlocks.  Any modifications made to the CFG
562   /// after initial construction are not reflected in this data structure.
563   using BasicBlockOffset = std::pair<uint64_t, BinaryBasicBlock *>;
564   struct CompareBasicBlockOffsets {
565     bool operator()(const BasicBlockOffset &A,
566                     const BasicBlockOffset &B) const {
567       return A.first < B.first;
568     }
569   };
570   SmallVector<BasicBlockOffset, 0> BasicBlockOffsets;
571 
572   MCSymbol *ColdSymbol{nullptr};
573 
574   /// Symbol at the end of the function.
575   mutable MCSymbol *FunctionEndLabel{nullptr};
576 
577   /// Symbol at the end of the cold part of split function.
578   mutable MCSymbol *FunctionColdEndLabel{nullptr};
579 
580   /// Unique number associated with the function.
581   uint64_t FunctionNumber;
582 
583   /// Count the number of functions created.
584   static uint64_t Count;
585 
586   /// Map offsets of special instructions to addresses in the output.
587   InputOffsetToAddressMapTy InputOffsetToAddressMap;
588 
589   /// Register alternative function name.
590   void addAlternativeName(std::string NewName) {
591     Aliases.push_back(std::move(NewName));
592   }
593 
594   /// Return a label at a given \p Address in the function. If the label does
595   /// not exist - create it. Assert if the \p Address does not belong to
596   /// the function. If \p CreatePastEnd is true, then return the function
597   /// end label when the \p Address points immediately past the last byte
598   /// of the function.
599   /// NOTE: the function always returns a local (temp) symbol, even if there's
600   ///       a global symbol that corresponds to an entry at this address.
601   MCSymbol *getOrCreateLocalLabel(uint64_t Address, bool CreatePastEnd = false);
602 
603   /// Register an data entry at a given \p Offset into the function.
604   void markDataAtOffset(uint64_t Offset) {
605     if (!Islands)
606       Islands = std::make_unique<IslandInfo>();
607     Islands->DataOffsets.emplace(Offset);
608   }
609 
610   /// Register an entry point at a given \p Offset into the function.
611   void markCodeAtOffset(uint64_t Offset) {
612     if (!Islands)
613       Islands = std::make_unique<IslandInfo>();
614     Islands->CodeOffsets.emplace(Offset);
615   }
616 
617   /// Register secondary entry point at a given \p Offset into the function.
618   /// Return global symbol for use by extern function references.
619   MCSymbol *addEntryPointAtOffset(uint64_t Offset);
620 
621   /// Register an internal offset in a function referenced from outside.
622   void registerReferencedOffset(uint64_t Offset) {
623     ExternallyReferencedOffsets.emplace(Offset);
624   }
625 
626   /// True if there are references to internals of this function from data,
627   /// e.g. from jump tables.
628   bool hasInternalReference() const {
629     return !ExternallyReferencedOffsets.empty();
630   }
631 
632   /// Return an entry ID corresponding to a symbol known to belong to
633   /// the function.
634   ///
635   /// Prefer to use BinaryContext::getFunctionForSymbol(EntrySymbol, &ID)
636   /// instead of calling this function directly.
637   uint64_t getEntryIDForSymbol(const MCSymbol *EntrySymbol) const;
638 
639   /// If the function represents a secondary split function fragment, set its
640   /// parent fragment to \p BF.
641   void addParentFragment(BinaryFunction &BF) {
642     assert(this != &BF);
643     assert(IsFragment && "function must be a fragment to have a parent");
644     ParentFragments.insert(&BF);
645   }
646 
647   /// Register a child fragment for the main fragment of a split function.
648   void addFragment(BinaryFunction &BF) {
649     assert(this != &BF);
650     Fragments.insert(&BF);
651   }
652 
653   void addInstruction(uint64_t Offset, MCInst &&Instruction) {
654     Instructions.emplace(Offset, std::forward<MCInst>(Instruction));
655   }
656 
657   /// Convert CFI instructions to a standard form (remove remember/restore).
658   void normalizeCFIState();
659 
660   /// Analyze and process indirect branch \p Instruction before it is
661   /// added to Instructions list.
662   IndirectBranchType processIndirectBranch(MCInst &Instruction, unsigned Size,
663                                            uint64_t Offset,
664                                            uint64_t &TargetAddress);
665 
666   BinaryFunction &operator=(const BinaryFunction &) = delete;
667   BinaryFunction(const BinaryFunction &) = delete;
668 
669   friend class MachORewriteInstance;
670   friend class RewriteInstance;
671   friend class BinaryContext;
672   friend class DataReader;
673   friend class DataAggregator;
674 
675   static std::string buildCodeSectionName(StringRef Name,
676                                           const BinaryContext &BC);
677   static std::string buildColdCodeSectionName(StringRef Name,
678                                               const BinaryContext &BC);
679 
680   /// Creation should be handled by RewriteInstance or BinaryContext
681   BinaryFunction(const std::string &Name, BinarySection &Section,
682                  uint64_t Address, uint64_t Size, BinaryContext &BC)
683       : OriginSection(&Section), Address(Address), Size(Size), BC(BC),
684         CodeSectionName(buildCodeSectionName(Name, BC)),
685         ColdCodeSectionName(buildColdCodeSectionName(Name, BC)),
686         FunctionNumber(++Count) {
687     Symbols.push_back(BC.Ctx->getOrCreateSymbol(Name));
688   }
689 
690   /// This constructor is used to create an injected function
691   BinaryFunction(const std::string &Name, BinaryContext &BC, bool IsSimple)
692       : Address(0), Size(0), BC(BC), IsSimple(IsSimple),
693         CodeSectionName(buildCodeSectionName(Name, BC)),
694         ColdCodeSectionName(buildColdCodeSectionName(Name, BC)),
695         FunctionNumber(++Count) {
696     Symbols.push_back(BC.Ctx->getOrCreateSymbol(Name));
697     IsInjected = true;
698   }
699 
700   /// Create a basic block at a given \p Offset in the function and append it
701   /// to the end of list of blocks. Used during CFG construction only.
702   BinaryBasicBlock *addBasicBlockAt(uint64_t Offset, MCSymbol *Label) {
703     assert(CurrentState == State::Disassembled &&
704            "Cannot add block with an offset in non-disassembled state.");
705     assert(!getBasicBlockAtOffset(Offset) &&
706            "Basic block already exists at the offset.");
707 
708     BasicBlocks.emplace_back(createBasicBlock(Label).release());
709     BinaryBasicBlock *BB = BasicBlocks.back();
710 
711     BB->setIndex(BasicBlocks.size() - 1);
712     BB->setOffset(Offset);
713 
714     BasicBlockOffsets.emplace_back(Offset, BB);
715     assert(llvm::is_sorted(BasicBlockOffsets, CompareBasicBlockOffsets()) &&
716            llvm::is_sorted(blocks()));
717 
718     return BB;
719   }
720 
721   /// Clear state of the function that could not be disassembled or if its
722   /// disassembled state was later invalidated.
723   void clearDisasmState();
724 
725   /// Release memory allocated for CFG and instructions.
726   /// We still keep basic blocks for address translation/mapping purposes.
727   void releaseCFG() {
728     for (BinaryBasicBlock *BB : BasicBlocks)
729       BB->releaseCFG();
730     for (BinaryBasicBlock *BB : DeletedBasicBlocks)
731       BB->releaseCFG();
732 
733     clearList(CallSites);
734     clearList(ColdCallSites);
735     clearList(LSDATypeTable);
736     clearList(LSDATypeAddressTable);
737 
738     clearList(LabelToBB);
739 
740     if (!isMultiEntry())
741       clearList(Labels);
742 
743     clearList(FrameInstructions);
744     clearList(FrameRestoreEquivalents);
745   }
746 
747 public:
748   BinaryFunction(BinaryFunction &&) = default;
749 
750   using iterator = pointee_iterator<BasicBlockListType::iterator>;
751   using const_iterator = pointee_iterator<BasicBlockListType::const_iterator>;
752   using reverse_iterator =
753       pointee_iterator<BasicBlockListType::reverse_iterator>;
754   using const_reverse_iterator =
755       pointee_iterator<BasicBlockListType::const_reverse_iterator>;
756 
757   typedef BasicBlockOrderType::iterator order_iterator;
758   typedef BasicBlockOrderType::const_iterator const_order_iterator;
759   typedef BasicBlockOrderType::reverse_iterator reverse_order_iterator;
760   typedef BasicBlockOrderType::const_reverse_iterator
761       const_reverse_order_iterator;
762 
763   // CFG iterators.
764   iterator                 begin()       { return BasicBlocks.begin(); }
765   const_iterator           begin() const { return BasicBlocks.begin(); }
766   iterator                 end  ()       { return BasicBlocks.end();   }
767   const_iterator           end  () const { return BasicBlocks.end();   }
768 
769   reverse_iterator        rbegin()       { return BasicBlocks.rbegin(); }
770   const_reverse_iterator  rbegin() const { return BasicBlocks.rbegin(); }
771   reverse_iterator        rend  ()       { return BasicBlocks.rend();   }
772   const_reverse_iterator  rend  () const { return BasicBlocks.rend();   }
773 
774   size_t                    size() const { return BasicBlocks.size();}
775   bool                     empty() const { return BasicBlocks.empty(); }
776   const BinaryBasicBlock &front() const  { return *BasicBlocks.front(); }
777         BinaryBasicBlock &front()        { return *BasicBlocks.front(); }
778   const BinaryBasicBlock & back() const  { return *BasicBlocks.back(); }
779         BinaryBasicBlock & back()        { return *BasicBlocks.back(); }
780   inline iterator_range<iterator> blocks() {
781     return iterator_range<iterator>(begin(), end());
782   }
783   inline iterator_range<const_iterator> blocks() const {
784     return iterator_range<const_iterator>(begin(), end());
785   }
786 
787   // Iterators by pointer.
788   BasicBlockListType::iterator pbegin()  { return BasicBlocks.begin(); }
789   BasicBlockListType::iterator pend()    { return BasicBlocks.end(); }
790 
791   order_iterator       layout_begin()    { return BasicBlocksLayout.begin(); }
792   const_order_iterator layout_begin()    const
793                                          { return BasicBlocksLayout.begin(); }
794   order_iterator       layout_end()      { return BasicBlocksLayout.end(); }
795   const_order_iterator layout_end()      const
796                                          { return BasicBlocksLayout.end(); }
797   reverse_order_iterator       layout_rbegin()
798                                          { return BasicBlocksLayout.rbegin(); }
799   const_reverse_order_iterator layout_rbegin() const
800                                          { return BasicBlocksLayout.rbegin(); }
801   reverse_order_iterator       layout_rend()
802                                          { return BasicBlocksLayout.rend(); }
803   const_reverse_order_iterator layout_rend()   const
804                                          { return BasicBlocksLayout.rend(); }
805   size_t   layout_size()  const { return BasicBlocksLayout.size(); }
806   bool     layout_empty() const { return BasicBlocksLayout.empty(); }
807   const BinaryBasicBlock *layout_front() const
808                                          { return BasicBlocksLayout.front(); }
809         BinaryBasicBlock *layout_front() { return BasicBlocksLayout.front(); }
810   const BinaryBasicBlock *layout_back()  const
811                                          { return BasicBlocksLayout.back(); }
812         BinaryBasicBlock *layout_back()  { return BasicBlocksLayout.back(); }
813 
814   inline iterator_range<order_iterator> layout() {
815     return iterator_range<order_iterator>(BasicBlocksLayout.begin(),
816                                           BasicBlocksLayout.end());
817   }
818 
819   inline iterator_range<const_order_iterator> layout() const {
820     return iterator_range<const_order_iterator>(BasicBlocksLayout.begin(),
821                                                 BasicBlocksLayout.end());
822   }
823 
824   inline iterator_range<reverse_order_iterator> rlayout() {
825     return iterator_range<reverse_order_iterator>(BasicBlocksLayout.rbegin(),
826                                                   BasicBlocksLayout.rend());
827   }
828 
829   inline iterator_range<const_reverse_order_iterator> rlayout() const {
830     return iterator_range<const_reverse_order_iterator>(
831         BasicBlocksLayout.rbegin(), BasicBlocksLayout.rend());
832   }
833 
834   cfi_iterator        cie_begin()       { return CIEFrameInstructions.begin(); }
835   const_cfi_iterator  cie_begin() const { return CIEFrameInstructions.begin(); }
836   cfi_iterator        cie_end()         { return CIEFrameInstructions.end(); }
837   const_cfi_iterator  cie_end()   const { return CIEFrameInstructions.end(); }
838   bool                cie_empty() const { return CIEFrameInstructions.empty(); }
839 
840   inline iterator_range<cfi_iterator> cie() {
841     return iterator_range<cfi_iterator>(cie_begin(), cie_end());
842   }
843   inline iterator_range<const_cfi_iterator> cie() const {
844     return iterator_range<const_cfi_iterator>(cie_begin(), cie_end());
845   }
846 
847   /// Iterate over all jump tables associated with this function.
848   iterator_range<std::map<uint64_t, JumpTable *>::const_iterator>
849   jumpTables() const {
850     return make_range(JumpTables.begin(), JumpTables.end());
851   }
852 
853   /// Return relocation associated with a given \p Offset in the function,
854   /// or nullptr if no such relocation exists.
855   const Relocation *getRelocationAt(uint64_t Offset) const {
856     assert(CurrentState == State::Empty &&
857            "Relocations unavailable in the current function state.");
858     auto RI = Relocations.find(Offset);
859     return (RI == Relocations.end()) ? nullptr : &RI->second;
860   }
861 
862   /// Return the first relocation in the function that starts at an address in
863   /// the [StartOffset, EndOffset) range. Return nullptr if no such relocation
864   /// exists.
865   const Relocation *getRelocationInRange(uint64_t StartOffset,
866                                          uint64_t EndOffset) const {
867     assert(CurrentState == State::Empty &&
868            "Relocations unavailable in the current function state.");
869     auto RI = Relocations.lower_bound(StartOffset);
870     if (RI != Relocations.end() && RI->first < EndOffset)
871       return &RI->second;
872 
873     return nullptr;
874   }
875 
876   /// Returns the raw binary encoding of this function.
877   ErrorOr<ArrayRef<uint8_t>> getData() const;
878 
879   BinaryFunction &updateState(BinaryFunction::State State) {
880     CurrentState = State;
881     return *this;
882   }
883 
884   /// Update layout of basic blocks used for output.
885   void updateBasicBlockLayout(BasicBlockOrderType &NewLayout) {
886     assert(NewLayout.size() == BasicBlocks.size() && "Layout size mismatch.");
887 
888     BasicBlocksPreviousLayout = BasicBlocksLayout;
889     if (NewLayout != BasicBlocksLayout) {
890       ModifiedLayout = true;
891       BasicBlocksLayout.clear();
892       BasicBlocksLayout.swap(NewLayout);
893     }
894   }
895 
896   /// Recompute landing pad information for the function and all its blocks.
897   void recomputeLandingPads();
898 
899   /// Return current basic block layout.
900   const BasicBlockOrderType &getLayout() const { return BasicBlocksLayout; }
901 
902   /// Return a list of basic blocks sorted using DFS and update layout indices
903   /// using the same order. Does not modify the current layout.
904   BasicBlockOrderType dfs() const;
905 
906   /// Find the loops in the CFG of the function and store information about
907   /// them.
908   void calculateLoopInfo();
909 
910   /// Calculate missed macro-fusion opportunities and update BinaryContext
911   /// stats.
912   void calculateMacroOpFusionStats();
913 
914   /// Returns if loop detection has been run for this function.
915   bool hasLoopInfo() const { return BLI != nullptr; }
916 
917   const BinaryLoopInfo &getLoopInfo() { return *BLI.get(); }
918 
919   bool isLoopFree() {
920     if (!hasLoopInfo())
921       calculateLoopInfo();
922     return BLI->empty();
923   }
924 
925   /// Print loop information about the function.
926   void printLoopInfo(raw_ostream &OS) const;
927 
928   /// View CFG in graphviz program
929   void viewGraph() const;
930 
931   /// Dump CFG in graphviz format
932   void dumpGraph(raw_ostream &OS) const;
933 
934   /// Dump CFG in graphviz format to file.
935   void dumpGraphToFile(std::string Filename) const;
936 
937   /// Dump CFG in graphviz format to a file with a filename that is derived
938   /// from the function name and Annotation strings.  Useful for dumping the
939   /// CFG after an optimization pass.
940   void dumpGraphForPass(std::string Annotation = "") const;
941 
942   /// Return BinaryContext for the function.
943   const BinaryContext &getBinaryContext() const { return BC; }
944 
945   /// Return BinaryContext for the function.
946   BinaryContext &getBinaryContext() { return BC; }
947 
948   /// Attempt to validate CFG invariants.
949   bool validateCFG() const;
950 
951   BinaryBasicBlock *getBasicBlockForLabel(const MCSymbol *Label) {
952     auto I = LabelToBB.find(Label);
953     return I == LabelToBB.end() ? nullptr : I->second;
954   }
955 
956   const BinaryBasicBlock *getBasicBlockForLabel(const MCSymbol *Label) const {
957     auto I = LabelToBB.find(Label);
958     return I == LabelToBB.end() ? nullptr : I->second;
959   }
960 
961   /// Returns the basic block after the given basic block in the layout or
962   /// nullptr the last basic block is given.
963   const BinaryBasicBlock *getBasicBlockAfter(const BinaryBasicBlock *BB,
964                                              bool IgnoreSplits = true) const {
965     return const_cast<BinaryFunction *>(this)->getBasicBlockAfter(BB,
966                                                                   IgnoreSplits);
967   }
968 
969   BinaryBasicBlock *getBasicBlockAfter(const BinaryBasicBlock *BB,
970                                        bool IgnoreSplits = true) {
971     for (auto I = layout_begin(), E = layout_end(); I != E; ++I) {
972       auto Next = std::next(I);
973       if (*I == BB && Next != E) {
974         return (IgnoreSplits || (*I)->isCold() == (*Next)->isCold()) ? *Next
975                                                                      : nullptr;
976       }
977     }
978     return nullptr;
979   }
980 
981   /// Retrieve the landing pad BB associated with invoke instruction \p Invoke
982   /// that is in \p BB. Return nullptr if none exists
983   BinaryBasicBlock *getLandingPadBBFor(const BinaryBasicBlock &BB,
984                                        const MCInst &InvokeInst) const {
985     assert(BC.MIB->isInvoke(InvokeInst) && "must be invoke instruction");
986     const Optional<MCPlus::MCLandingPad> LP = BC.MIB->getEHInfo(InvokeInst);
987     if (LP && LP->first) {
988       BinaryBasicBlock *LBB = BB.getLandingPad(LP->first);
989       assert(LBB && "Landing pad should be defined");
990       return LBB;
991     }
992     return nullptr;
993   }
994 
995   /// Return instruction at a given offset in the function. Valid before
996   /// CFG is constructed or while instruction offsets are available in CFG.
997   MCInst *getInstructionAtOffset(uint64_t Offset);
998 
999   const MCInst *getInstructionAtOffset(uint64_t Offset) const {
1000     return const_cast<BinaryFunction *>(this)->getInstructionAtOffset(Offset);
1001   }
1002 
1003   /// Return offset for the first instruction. If there is data at the
1004   /// beginning of a function then offset of the first instruction could
1005   /// be different from 0
1006   uint64_t getFirstInstructionOffset() const {
1007     if (Instructions.empty())
1008       return 0;
1009     return Instructions.begin()->first;
1010   }
1011 
1012   /// Return jump table that covers a given \p Address in memory.
1013   JumpTable *getJumpTableContainingAddress(uint64_t Address) {
1014     auto JTI = JumpTables.upper_bound(Address);
1015     if (JTI == JumpTables.begin())
1016       return nullptr;
1017     --JTI;
1018     if (JTI->first + JTI->second->getSize() > Address)
1019       return JTI->second;
1020     if (JTI->second->getSize() == 0 && JTI->first == Address)
1021       return JTI->second;
1022     return nullptr;
1023   }
1024 
1025   const JumpTable *getJumpTableContainingAddress(uint64_t Address) const {
1026     return const_cast<BinaryFunction *>(this)->getJumpTableContainingAddress(
1027         Address);
1028   }
1029 
1030   /// Return the name of the function if the function has just one name.
1031   /// If the function has multiple names - return one followed
1032   /// by "(*#<numnames>)".
1033   ///
1034   /// We should use getPrintName() for diagnostics and use
1035   /// hasName() to match function name against a given string.
1036   ///
1037   /// NOTE: for disambiguating names of local symbols we use the following
1038   ///       naming schemes:
1039   ///           primary:     <function>/<id>
1040   ///           alternative: <function>/<file>/<id2>
1041   std::string getPrintName() const {
1042     const size_t NumNames = Symbols.size() + Aliases.size();
1043     return NumNames == 1
1044                ? getOneName().str()
1045                : (getOneName().str() + "(*" + std::to_string(NumNames) + ")");
1046   }
1047 
1048   /// The function may have many names. For that reason, we avoid having
1049   /// getName() method as most of the time the user needs a different
1050   /// interface, such as forEachName(), hasName(), hasNameRegex(), etc.
1051   /// In some cases though, we need just a name uniquely identifying
1052   /// the function, and that's what this method is for.
1053   StringRef getOneName() const { return Symbols[0]->getName(); }
1054 
1055   /// Return the name of the function as getPrintName(), but also trying
1056   /// to demangle it.
1057   std::string getDemangledName() const;
1058 
1059   /// Call \p Callback for every name of this function as long as the Callback
1060   /// returns false. Stop if Callback returns true or all names have been used.
1061   /// Return the name for which the Callback returned true if any.
1062   template <typename FType>
1063   Optional<StringRef> forEachName(FType Callback) const {
1064     for (MCSymbol *Symbol : Symbols)
1065       if (Callback(Symbol->getName()))
1066         return Symbol->getName();
1067 
1068     for (const std::string &Name : Aliases)
1069       if (Callback(StringRef(Name)))
1070         return StringRef(Name);
1071 
1072     return NoneType();
1073   }
1074 
1075   /// Check if (possibly one out of many) function name matches the given
1076   /// string. Use this member function instead of direct name comparison.
1077   bool hasName(const std::string &FunctionName) const {
1078     auto Res =
1079         forEachName([&](StringRef Name) { return Name == FunctionName; });
1080     return Res.hasValue();
1081   }
1082 
1083   /// Check if any of function names matches the given regex.
1084   Optional<StringRef> hasNameRegex(const StringRef NameRegex) const;
1085 
1086   /// Check if any of restored function names matches the given regex.
1087   /// Restored name means stripping BOLT-added suffixes like "/1",
1088   Optional<StringRef> hasRestoredNameRegex(const StringRef NameRegex) const;
1089 
1090   /// Return a vector of all possible names for the function.
1091   const std::vector<StringRef> getNames() const {
1092     std::vector<StringRef> AllNames;
1093     forEachName([&AllNames](StringRef Name) {
1094       AllNames.push_back(Name);
1095       return false;
1096     });
1097 
1098     return AllNames;
1099   }
1100 
1101   /// Return a state the function is in (see BinaryFunction::State definition
1102   /// for description).
1103   State getState() const { return CurrentState; }
1104 
1105   /// Return true if function has a control flow graph available.
1106   bool hasCFG() const {
1107     return getState() == State::CFG || getState() == State::CFG_Finalized ||
1108            getState() == State::EmittedCFG;
1109   }
1110 
1111   /// Return true if the function state implies that it includes instructions.
1112   bool hasInstructions() const {
1113     return getState() == State::Disassembled || hasCFG();
1114   }
1115 
1116   bool isEmitted() const {
1117     return getState() == State::EmittedCFG || getState() == State::Emitted;
1118   }
1119 
1120   /// Return the section in the input binary this function originated from or
1121   /// nullptr if the function did not originate from the file.
1122   BinarySection *getOriginSection() const { return OriginSection; }
1123 
1124   void setOriginSection(BinarySection *Section) { OriginSection = Section; }
1125 
1126   /// Return true if the function did not originate from the primary input file.
1127   bool isInjected() const { return IsInjected; }
1128 
1129   /// Return original address of the function (or offset from base for PIC).
1130   uint64_t getAddress() const { return Address; }
1131 
1132   uint64_t getOutputAddress() const { return OutputAddress; }
1133 
1134   uint64_t getOutputSize() const { return OutputSize; }
1135 
1136   /// Does this function have a valid streaming order index?
1137   bool hasValidIndex() const { return Index != -1U; }
1138 
1139   /// Get the streaming order index for this function.
1140   uint32_t getIndex() const { return Index; }
1141 
1142   /// Set the streaming order index for this function.
1143   void setIndex(uint32_t Idx) {
1144     assert(!hasValidIndex());
1145     Index = Idx;
1146   }
1147 
1148   /// Return offset of the function body in the binary file.
1149   uint64_t getFileOffset() const { return FileOffset; }
1150 
1151   /// Return (original) byte size of the function.
1152   uint64_t getSize() const { return Size; }
1153 
1154   /// Return the maximum size the body of the function could have.
1155   uint64_t getMaxSize() const { return MaxSize; }
1156 
1157   /// Return the number of emitted instructions for this function.
1158   uint32_t getNumNonPseudos() const {
1159     uint32_t N = 0;
1160     for (const BinaryBasicBlock &BB : blocks())
1161       N += BB.getNumNonPseudos();
1162     return N;
1163   }
1164 
1165   /// Return MC symbol associated with the function.
1166   /// All references to the function should use this symbol.
1167   MCSymbol *getSymbol() { return Symbols[0]; }
1168 
1169   /// Return MC symbol associated with the function (const version).
1170   /// All references to the function should use this symbol.
1171   const MCSymbol *getSymbol() const { return Symbols[0]; }
1172 
1173   /// Return a list of symbols associated with the main entry of the function.
1174   SymbolListTy &getSymbols() { return Symbols; }
1175   const SymbolListTy &getSymbols() const { return Symbols; }
1176 
1177   /// If a local symbol \p BBLabel corresponds to a basic block that is a
1178   /// secondary entry point into the function, then return a global symbol
1179   /// that represents the secondary entry point. Otherwise return nullptr.
1180   MCSymbol *getSecondaryEntryPointSymbol(const MCSymbol *BBLabel) const {
1181     auto I = SecondaryEntryPoints.find(BBLabel);
1182     if (I == SecondaryEntryPoints.end())
1183       return nullptr;
1184 
1185     return I->second;
1186   }
1187 
1188   /// If the basic block serves as a secondary entry point to the function,
1189   /// return a global symbol representing the entry. Otherwise return nullptr.
1190   MCSymbol *getSecondaryEntryPointSymbol(const BinaryBasicBlock &BB) const {
1191     return getSecondaryEntryPointSymbol(BB.getLabel());
1192   }
1193 
1194   /// Return true if the basic block is an entry point into the function
1195   /// (either primary or secondary).
1196   bool isEntryPoint(const BinaryBasicBlock &BB) const {
1197     if (&BB == BasicBlocks.front())
1198       return true;
1199     return getSecondaryEntryPointSymbol(BB);
1200   }
1201 
1202   /// Return MC symbol corresponding to an enumerated entry for multiple-entry
1203   /// functions.
1204   MCSymbol *getSymbolForEntryID(uint64_t EntryNum);
1205   const MCSymbol *getSymbolForEntryID(uint64_t EntryNum) const {
1206     return const_cast<BinaryFunction *>(this)->getSymbolForEntryID(EntryNum);
1207   }
1208 
1209   using EntryPointCallbackTy = function_ref<bool(uint64_t, const MCSymbol *)>;
1210 
1211   /// Invoke \p Callback function for every entry point in the function starting
1212   /// with the main entry and using entries in the ascending address order.
1213   /// Stop calling the function after false is returned by the callback.
1214   ///
1215   /// Pass an offset of the entry point in the input binary and a corresponding
1216   /// global symbol to the callback function.
1217   ///
1218   /// Return true of all callbacks returned true, false otherwise.
1219   bool forEachEntryPoint(EntryPointCallbackTy Callback) const;
1220 
1221   MCSymbol *getColdSymbol() {
1222     if (ColdSymbol)
1223       return ColdSymbol;
1224 
1225     ColdSymbol = BC.Ctx->getOrCreateSymbol(
1226         NameResolver::append(getSymbol()->getName(), ".cold.0"));
1227 
1228     return ColdSymbol;
1229   }
1230 
1231   /// Return MC symbol associated with the end of the function.
1232   MCSymbol *getFunctionEndLabel() const {
1233     assert(BC.Ctx && "cannot be called with empty context");
1234     if (!FunctionEndLabel) {
1235       std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
1236       FunctionEndLabel = BC.Ctx->createNamedTempSymbol("func_end");
1237     }
1238     return FunctionEndLabel;
1239   }
1240 
1241   /// Return MC symbol associated with the end of the cold part of the function.
1242   MCSymbol *getFunctionColdEndLabel() const {
1243     if (!FunctionColdEndLabel) {
1244       std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
1245       FunctionColdEndLabel = BC.Ctx->createNamedTempSymbol("func_cold_end");
1246     }
1247     return FunctionColdEndLabel;
1248   }
1249 
1250   /// Return a label used to identify where the constant island was emitted
1251   /// (AArch only). This is used to update the symbol table accordingly,
1252   /// emitting data marker symbols as required by the ABI.
1253   MCSymbol *getFunctionConstantIslandLabel() const {
1254     assert(Islands && "function expected to have constant islands");
1255 
1256     if (!Islands->FunctionConstantIslandLabel) {
1257       Islands->FunctionConstantIslandLabel =
1258           BC.Ctx->createNamedTempSymbol("func_const_island");
1259     }
1260     return Islands->FunctionConstantIslandLabel;
1261   }
1262 
1263   MCSymbol *getFunctionColdConstantIslandLabel() const {
1264     assert(Islands && "function expected to have constant islands");
1265 
1266     if (!Islands->FunctionColdConstantIslandLabel) {
1267       Islands->FunctionColdConstantIslandLabel =
1268           BC.Ctx->createNamedTempSymbol("func_cold_const_island");
1269     }
1270     return Islands->FunctionColdConstantIslandLabel;
1271   }
1272 
1273   /// Return true if this is a function representing a PLT entry.
1274   bool isPLTFunction() const { return PLTSymbol != nullptr; }
1275 
1276   /// Return PLT function reference symbol for PLT functions and nullptr for
1277   /// non-PLT functions.
1278   const MCSymbol *getPLTSymbol() const { return PLTSymbol; }
1279 
1280   /// Set function PLT reference symbol for PLT functions.
1281   void setPLTSymbol(const MCSymbol *Symbol) {
1282     assert(Size == 0 && "function size should be 0 for PLT functions");
1283     PLTSymbol = Symbol;
1284     IsPseudo = true;
1285   }
1286 
1287   /// Update output values of the function based on the final \p Layout.
1288   void updateOutputValues(const MCAsmLayout &Layout);
1289 
1290   /// Return mapping of input to output addresses. Most users should call
1291   /// translateInputToOutputAddress() for address translation.
1292   InputOffsetToAddressMapTy &getInputOffsetToAddressMap() {
1293     assert(isEmitted() && "cannot use address mapping before code emission");
1294     return InputOffsetToAddressMap;
1295   }
1296 
1297   void addRelocationAArch64(uint64_t Offset, MCSymbol *Symbol, uint64_t RelType,
1298                             uint64_t Addend, uint64_t Value, bool IsCI) {
1299     std::map<uint64_t, Relocation> &Rels =
1300         (IsCI) ? Islands->Relocations : Relocations;
1301     switch (RelType) {
1302     case ELF::R_AARCH64_ABS64:
1303     case ELF::R_AARCH64_ABS32:
1304     case ELF::R_AARCH64_ABS16:
1305     case ELF::R_AARCH64_ADD_ABS_LO12_NC:
1306     case ELF::R_AARCH64_ADR_GOT_PAGE:
1307     case ELF::R_AARCH64_ADR_PREL_LO21:
1308     case ELF::R_AARCH64_ADR_PREL_PG_HI21:
1309     case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:
1310     case ELF::R_AARCH64_LD64_GOT_LO12_NC:
1311     case ELF::R_AARCH64_LDST8_ABS_LO12_NC:
1312     case ELF::R_AARCH64_LDST16_ABS_LO12_NC:
1313     case ELF::R_AARCH64_LDST32_ABS_LO12_NC:
1314     case ELF::R_AARCH64_LDST64_ABS_LO12_NC:
1315     case ELF::R_AARCH64_LDST128_ABS_LO12_NC:
1316     case ELF::R_AARCH64_TLSDESC_ADD_LO12:
1317     case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:
1318     case ELF::R_AARCH64_TLSDESC_ADR_PREL21:
1319     case ELF::R_AARCH64_TLSDESC_LD64_LO12:
1320     case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
1321     case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
1322     case ELF::R_AARCH64_MOVW_UABS_G0:
1323     case ELF::R_AARCH64_MOVW_UABS_G0_NC:
1324     case ELF::R_AARCH64_MOVW_UABS_G1:
1325     case ELF::R_AARCH64_MOVW_UABS_G1_NC:
1326     case ELF::R_AARCH64_MOVW_UABS_G2:
1327     case ELF::R_AARCH64_MOVW_UABS_G2_NC:
1328     case ELF::R_AARCH64_MOVW_UABS_G3:
1329     case ELF::R_AARCH64_PREL16:
1330     case ELF::R_AARCH64_PREL32:
1331     case ELF::R_AARCH64_PREL64:
1332       Rels[Offset] = Relocation{Offset, Symbol, RelType, Addend, Value};
1333       return;
1334     case ELF::R_AARCH64_CALL26:
1335     case ELF::R_AARCH64_JUMP26:
1336     case ELF::R_AARCH64_TSTBR14:
1337     case ELF::R_AARCH64_CONDBR19:
1338     case ELF::R_AARCH64_TLSDESC_CALL:
1339     case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:
1340     case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
1341       return;
1342     default:
1343       llvm_unreachable("Unexpected AArch64 relocation type in code");
1344     }
1345   }
1346 
1347   void addRelocationX86(uint64_t Offset, MCSymbol *Symbol, uint64_t RelType,
1348                         uint64_t Addend, uint64_t Value) {
1349     switch (RelType) {
1350     case ELF::R_X86_64_8:
1351     case ELF::R_X86_64_16:
1352     case ELF::R_X86_64_32:
1353     case ELF::R_X86_64_32S:
1354     case ELF::R_X86_64_64:
1355     case ELF::R_X86_64_PC8:
1356     case ELF::R_X86_64_PC32:
1357     case ELF::R_X86_64_PC64:
1358     case ELF::R_X86_64_GOTPCRELX:
1359     case ELF::R_X86_64_REX_GOTPCRELX:
1360       Relocations[Offset] = Relocation{Offset, Symbol, RelType, Addend, Value};
1361       return;
1362     case ELF::R_X86_64_PLT32:
1363     case ELF::R_X86_64_GOTPCREL:
1364     case ELF::R_X86_64_TPOFF32:
1365     case ELF::R_X86_64_GOTTPOFF:
1366       return;
1367     default:
1368       llvm_unreachable("Unexpected x86 relocation type in code");
1369     }
1370   }
1371 
1372   /// Register relocation type \p RelType at a given \p Address in the function
1373   /// against \p Symbol.
1374   /// Assert if the \p Address is not inside this function.
1375   void addRelocation(uint64_t Address, MCSymbol *Symbol, uint64_t RelType,
1376                      uint64_t Addend, uint64_t Value) {
1377     assert(Address >= getAddress() && Address < getAddress() + getMaxSize() &&
1378            "address is outside of the function");
1379     uint64_t Offset = Address - getAddress();
1380     if (BC.isAArch64()) {
1381       return addRelocationAArch64(Offset, Symbol, RelType, Addend, Value,
1382                                   isInConstantIsland(Address));
1383     }
1384 
1385     return addRelocationX86(Offset, Symbol, RelType, Addend, Value);
1386   }
1387 
1388   /// Return the name of the section this function originated from.
1389   Optional<StringRef> getOriginSectionName() const {
1390     if (!OriginSection)
1391       return NoneType();
1392     return OriginSection->getName();
1393   }
1394 
1395   /// Return internal section name for this function.
1396   StringRef getCodeSectionName() const { return StringRef(CodeSectionName); }
1397 
1398   /// Assign a code section name to the function.
1399   void setCodeSectionName(StringRef Name) {
1400     CodeSectionName = std::string(Name);
1401   }
1402 
1403   /// Get output code section.
1404   ErrorOr<BinarySection &> getCodeSection() const {
1405     return BC.getUniqueSectionByName(getCodeSectionName());
1406   }
1407 
1408   /// Return cold code section name for the function.
1409   StringRef getColdCodeSectionName() const {
1410     return StringRef(ColdCodeSectionName);
1411   }
1412 
1413   /// Assign a section name for the cold part of the function.
1414   void setColdCodeSectionName(StringRef Name) {
1415     ColdCodeSectionName = std::string(Name);
1416   }
1417 
1418   /// Get output code section for cold code of this function.
1419   ErrorOr<BinarySection &> getColdCodeSection() const {
1420     return BC.getUniqueSectionByName(getColdCodeSectionName());
1421   }
1422 
1423   /// Return true iif the function will halt execution on entry.
1424   bool trapsOnEntry() const { return TrapsOnEntry; }
1425 
1426   /// Make the function always trap on entry. Other than the trap instruction,
1427   /// the function body will be empty.
1428   void setTrapOnEntry();
1429 
1430   /// Return true if the function could be correctly processed.
1431   bool isSimple() const { return IsSimple; }
1432 
1433   /// Return true if the function should be ignored for optimization purposes.
1434   bool isIgnored() const { return IsIgnored; }
1435 
1436   /// Return true if the function should not be disassembled, emitted, or
1437   /// otherwise processed.
1438   bool isPseudo() const { return IsPseudo; }
1439 
1440   /// Return true if the function contains explicit or implicit indirect branch
1441   /// to its split fragments, e.g., split jump table, landing pad in split
1442   /// fragment.
1443   bool hasIndirectTargetToSplitFragment() const {
1444     return HasIndirectTargetToSplitFragment;
1445   }
1446 
1447   /// Return true if all CFG edges have local successors.
1448   bool hasCanonicalCFG() const { return HasCanonicalCFG; }
1449 
1450   /// Return true if the original function code has all necessary relocations
1451   /// to track addresses of functions emitted to new locations.
1452   bool hasExternalRefRelocations() const { return HasExternalRefRelocations; }
1453 
1454   /// Return true if the function has instruction(s) with unknown control flow.
1455   bool hasUnknownControlFlow() const { return HasUnknownControlFlow; }
1456 
1457   /// Return true if the function body is non-contiguous.
1458   bool isSplit() const {
1459     return isSimple() && layout_size() &&
1460            layout_front()->isCold() != layout_back()->isCold();
1461   }
1462 
1463   bool shouldPreserveNops() const { return PreserveNops; }
1464 
1465   /// Return true if the function has exception handling tables.
1466   bool hasEHRanges() const { return HasEHRanges; }
1467 
1468   /// Return true if the function uses DW_CFA_GNU_args_size CFIs.
1469   bool usesGnuArgsSize() const { return UsesGnuArgsSize; }
1470 
1471   /// Return true if the function has more than one entry point.
1472   bool isMultiEntry() const { return !SecondaryEntryPoints.empty(); }
1473 
1474   /// Return true if the function might have a profile available externally,
1475   /// but not yet populated into the function.
1476   bool hasProfileAvailable() const { return HasProfileAvailable; }
1477 
1478   bool hasMemoryProfile() const { return HasMemoryProfile; }
1479 
1480   /// Return true if the body of the function was merged into another function.
1481   bool isFolded() const { return FoldedIntoFunction != nullptr; }
1482 
1483   /// If this function was folded, return the function it was folded into.
1484   BinaryFunction *getFoldedIntoFunction() const { return FoldedIntoFunction; }
1485 
1486   /// Return true if the function uses jump tables.
1487   bool hasJumpTables() const { return !JumpTables.empty(); }
1488 
1489   /// Return true if the function has SDT marker
1490   bool hasSDTMarker() const { return HasSDTMarker; }
1491 
1492   /// Return true if the function has Pseudo Probe
1493   bool hasPseudoProbe() const { return HasPseudoProbe; }
1494 
1495   /// Return true if the original entry point was patched.
1496   bool isPatched() const { return IsPatched; }
1497 
1498   const JumpTable *getJumpTable(const MCInst &Inst) const {
1499     const uint64_t Address = BC.MIB->getJumpTable(Inst);
1500     return getJumpTableContainingAddress(Address);
1501   }
1502 
1503   JumpTable *getJumpTable(const MCInst &Inst) {
1504     const uint64_t Address = BC.MIB->getJumpTable(Inst);
1505     return getJumpTableContainingAddress(Address);
1506   }
1507 
1508   const MCSymbol *getPersonalityFunction() const { return PersonalityFunction; }
1509 
1510   uint8_t getPersonalityEncoding() const { return PersonalityEncoding; }
1511 
1512   const CallSitesType &getCallSites() const { return CallSites; }
1513 
1514   const CallSitesType &getColdCallSites() const { return ColdCallSites; }
1515 
1516   const ArrayRef<uint8_t> getLSDAActionTable() const { return LSDAActionTable; }
1517 
1518   const LSDATypeTableTy &getLSDATypeTable() const { return LSDATypeTable; }
1519 
1520   const LSDATypeTableTy &getLSDATypeAddressTable() const {
1521     return LSDATypeAddressTable;
1522   }
1523 
1524   const ArrayRef<uint8_t> getLSDATypeIndexTable() const {
1525     return LSDATypeIndexTable;
1526   }
1527 
1528   const LabelsMapType &getLabels() const { return Labels; }
1529 
1530   IslandInfo &getIslandInfo() {
1531     assert(Islands && "function expected to have constant islands");
1532     return *Islands;
1533   }
1534 
1535   const IslandInfo &getIslandInfo() const {
1536     assert(Islands && "function expected to have constant islands");
1537     return *Islands;
1538   }
1539 
1540   /// Return true if the function has CFI instructions
1541   bool hasCFI() const {
1542     return !FrameInstructions.empty() || !CIEFrameInstructions.empty();
1543   }
1544 
1545   /// Return unique number associated with the function.
1546   uint64_t getFunctionNumber() const { return FunctionNumber; }
1547 
1548   /// Return true if the given address \p PC is inside the function body.
1549   bool containsAddress(uint64_t PC, bool UseMaxSize = false) const {
1550     if (UseMaxSize)
1551       return Address <= PC && PC < Address + MaxSize;
1552     return Address <= PC && PC < Address + Size;
1553   }
1554 
1555   /// Create a basic block in the function. The new block is *NOT* inserted
1556   /// into the CFG. The caller must use insertBasicBlocks() to add any new
1557   /// blocks to the CFG.
1558   std::unique_ptr<BinaryBasicBlock>
1559   createBasicBlock(MCSymbol *Label = nullptr) {
1560     if (!Label) {
1561       std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
1562       Label = BC.Ctx->createNamedTempSymbol("BB");
1563     }
1564     auto BB =
1565         std::unique_ptr<BinaryBasicBlock>(new BinaryBasicBlock(this, Label));
1566 
1567     LabelToBB[Label] = BB.get();
1568 
1569     return BB;
1570   }
1571 
1572   /// Create a new basic block with an optional \p Label and add it to the list
1573   /// of basic blocks of this function.
1574   BinaryBasicBlock *addBasicBlock(MCSymbol *Label = nullptr) {
1575     assert(CurrentState == State::CFG && "Can only add blocks in CFG state");
1576 
1577     BasicBlocks.emplace_back(createBasicBlock(Label).release());
1578     BinaryBasicBlock *BB = BasicBlocks.back();
1579 
1580     BB->setIndex(BasicBlocks.size() - 1);
1581     BB->setLayoutIndex(layout_size());
1582     BasicBlocksLayout.emplace_back(BB);
1583 
1584     return BB;
1585   }
1586 
1587   /// Add basic block \BB as an entry point to the function. Return global
1588   /// symbol associated with the entry.
1589   MCSymbol *addEntryPoint(const BinaryBasicBlock &BB);
1590 
1591   /// Mark all blocks that are unreachable from a root (entry point
1592   /// or landing pad) as invalid.
1593   void markUnreachableBlocks();
1594 
1595   /// Rebuilds BBs layout, ignoring dead BBs. Returns the number of removed
1596   /// BBs and the removed number of bytes of code.
1597   std::pair<unsigned, uint64_t> eraseInvalidBBs();
1598 
1599   /// Get the relative order between two basic blocks in the original
1600   /// layout.  The result is > 0 if B occurs before A and < 0 if B
1601   /// occurs after A.  If A and B are the same block, the result is 0.
1602   signed getOriginalLayoutRelativeOrder(const BinaryBasicBlock *A,
1603                                         const BinaryBasicBlock *B) const {
1604     return getIndex(A) - getIndex(B);
1605   }
1606 
1607   /// Insert the BBs contained in NewBBs into the basic blocks for this
1608   /// function. Update the associated state of all blocks as needed, i.e.
1609   /// BB offsets and BB indices. The new BBs are inserted after Start.
1610   /// This operation could affect fallthrough branches for Start.
1611   ///
1612   void
1613   insertBasicBlocks(BinaryBasicBlock *Start,
1614                     std::vector<std::unique_ptr<BinaryBasicBlock>> &&NewBBs,
1615                     const bool UpdateLayout = true,
1616                     const bool UpdateCFIState = true,
1617                     const bool RecomputeLandingPads = true);
1618 
1619   iterator insertBasicBlocks(
1620       iterator StartBB, std::vector<std::unique_ptr<BinaryBasicBlock>> &&NewBBs,
1621       const bool UpdateLayout = true, const bool UpdateCFIState = true,
1622       const bool RecomputeLandingPads = true);
1623 
1624   /// Update the basic block layout for this function.  The BBs from
1625   /// [Start->Index, Start->Index + NumNewBlocks) are inserted into the
1626   /// layout after the BB indicated by Start.
1627   void updateLayout(BinaryBasicBlock *Start, const unsigned NumNewBlocks);
1628 
1629   /// Make sure basic blocks' indices match the current layout.
1630   void updateLayoutIndices() const {
1631     unsigned Index = 0;
1632     for (BinaryBasicBlock *BB : layout())
1633       BB->setLayoutIndex(Index++);
1634   }
1635 
1636   /// Recompute the CFI state for NumNewBlocks following Start after inserting
1637   /// new blocks into the CFG.  This must be called after updateLayout.
1638   void updateCFIState(BinaryBasicBlock *Start, const unsigned NumNewBlocks);
1639 
1640   /// Return true if we detected ambiguous jump tables in this function, which
1641   /// happen when one JT is used in more than one indirect jumps. This precludes
1642   /// us from splitting edges for this JT unless we duplicate the JT (see
1643   /// disambiguateJumpTables).
1644   bool checkForAmbiguousJumpTables();
1645 
1646   /// Detect when two distinct indirect jumps are using the same jump table and
1647   /// duplicate it, allocating a separate JT for each indirect branch. This is
1648   /// necessary for code transformations on the CFG that change an edge induced
1649   /// by an indirect branch, e.g.: instrumentation or shrink wrapping. However,
1650   /// this is only possible if we are not updating jump tables in place, but are
1651   /// writing it to a new location (moving them).
1652   void disambiguateJumpTables(MCPlusBuilder::AllocatorIdTy AllocId);
1653 
1654   /// Change \p OrigDest to \p NewDest in the jump table used at the end of
1655   /// \p BB. Returns false if \p OrigDest couldn't be find as a valid target
1656   /// and no replacement took place.
1657   bool replaceJumpTableEntryIn(BinaryBasicBlock *BB, BinaryBasicBlock *OldDest,
1658                                BinaryBasicBlock *NewDest);
1659 
1660   /// Split the CFG edge <From, To> by inserting an intermediate basic block.
1661   /// Returns a pointer to this new intermediate basic block. BB "From" will be
1662   /// updated to jump to the intermediate block, which in turn will have an
1663   /// unconditional branch to BB "To".
1664   /// User needs to manually call fixBranches(). This function only creates the
1665   /// correct CFG edges.
1666   BinaryBasicBlock *splitEdge(BinaryBasicBlock *From, BinaryBasicBlock *To);
1667 
1668   /// We may have built an overly conservative CFG for functions with calls
1669   /// to functions that the compiler knows will never return. In this case,
1670   /// clear all successors from these blocks.
1671   void deleteConservativeEdges();
1672 
1673   /// Determine direction of the branch based on the current layout.
1674   /// Callee is responsible of updating basic block indices prior to using
1675   /// this function (e.g. by calling BinaryFunction::updateLayoutIndices()).
1676   static bool isForwardBranch(const BinaryBasicBlock *From,
1677                               const BinaryBasicBlock *To) {
1678     assert(From->getFunction() == To->getFunction() &&
1679            "basic blocks should be in the same function");
1680     return To->getLayoutIndex() > From->getLayoutIndex();
1681   }
1682 
1683   /// Determine direction of the call to callee symbol relative to the start
1684   /// of this function.
1685   /// Note: this doesn't take function splitting into account.
1686   bool isForwardCall(const MCSymbol *CalleeSymbol) const;
1687 
1688   /// Dump function information to debug output. If \p PrintInstructions
1689   /// is true - include instruction disassembly.
1690   void dump(bool PrintInstructions = true) const;
1691 
1692   /// Print function information to the \p OS stream.
1693   void print(raw_ostream &OS, std::string Annotation = "",
1694              bool PrintInstructions = true) const;
1695 
1696   /// Print all relocations between \p Offset and \p Offset + \p Size in
1697   /// this function.
1698   void printRelocations(raw_ostream &OS, uint64_t Offset, uint64_t Size) const;
1699 
1700   /// Return true if function has a profile, even if the profile does not
1701   /// match CFG 100%.
1702   bool hasProfile() const { return ExecutionCount != COUNT_NO_PROFILE; }
1703 
1704   /// Return true if function profile is present and accurate.
1705   bool hasValidProfile() const {
1706     return ExecutionCount != COUNT_NO_PROFILE && ProfileMatchRatio == 1.0f;
1707   }
1708 
1709   /// Mark this function as having a valid profile.
1710   void markProfiled(uint16_t Flags) {
1711     if (ExecutionCount == COUNT_NO_PROFILE)
1712       ExecutionCount = 0;
1713     ProfileFlags = Flags;
1714     ProfileMatchRatio = 1.0f;
1715   }
1716 
1717   /// Return flags describing a profile for this function.
1718   uint16_t getProfileFlags() const { return ProfileFlags; }
1719 
1720   void addCFIInstruction(uint64_t Offset, MCCFIInstruction &&Inst) {
1721     assert(!Instructions.empty());
1722 
1723     // Fix CFI instructions skipping NOPs. We need to fix this because changing
1724     // CFI state after a NOP, besides being wrong and inaccurate,  makes it
1725     // harder for us to recover this information, since we can create empty BBs
1726     // with NOPs and then reorder it away.
1727     // We fix this by moving the CFI instruction just before any NOPs.
1728     auto I = Instructions.lower_bound(Offset);
1729     if (Offset == getSize()) {
1730       assert(I == Instructions.end() && "unexpected iterator value");
1731       // Sometimes compiler issues restore_state after all instructions
1732       // in the function (even after nop).
1733       --I;
1734       Offset = I->first;
1735     }
1736     assert(I->first == Offset && "CFI pointing to unknown instruction");
1737     if (I == Instructions.begin()) {
1738       CIEFrameInstructions.emplace_back(std::forward<MCCFIInstruction>(Inst));
1739       return;
1740     }
1741 
1742     --I;
1743     while (I != Instructions.begin() && BC.MIB->isNoop(I->second)) {
1744       Offset = I->first;
1745       --I;
1746     }
1747     OffsetToCFI.emplace(Offset, FrameInstructions.size());
1748     FrameInstructions.emplace_back(std::forward<MCCFIInstruction>(Inst));
1749     return;
1750   }
1751 
1752   BinaryBasicBlock::iterator addCFIInstruction(BinaryBasicBlock *BB,
1753                                                BinaryBasicBlock::iterator Pos,
1754                                                MCCFIInstruction &&Inst) {
1755     size_t Idx = FrameInstructions.size();
1756     FrameInstructions.emplace_back(std::forward<MCCFIInstruction>(Inst));
1757     return addCFIPseudo(BB, Pos, Idx);
1758   }
1759 
1760   /// Insert a CFI pseudo instruction in a basic block. This pseudo instruction
1761   /// is a placeholder that refers to a real MCCFIInstruction object kept by
1762   /// this function that will be emitted at that position.
1763   BinaryBasicBlock::iterator addCFIPseudo(BinaryBasicBlock *BB,
1764                                           BinaryBasicBlock::iterator Pos,
1765                                           uint32_t Offset) {
1766     MCInst CFIPseudo;
1767     BC.MIB->createCFI(CFIPseudo, Offset);
1768     return BB->insertPseudoInstr(Pos, CFIPseudo);
1769   }
1770 
1771   /// Retrieve the MCCFIInstruction object associated with a CFI pseudo.
1772   const MCCFIInstruction *getCFIFor(const MCInst &Instr) const {
1773     if (!BC.MIB->isCFI(Instr))
1774       return nullptr;
1775     uint32_t Offset = Instr.getOperand(0).getImm();
1776     assert(Offset < FrameInstructions.size() && "Invalid CFI offset");
1777     return &FrameInstructions[Offset];
1778   }
1779 
1780   void setCFIFor(const MCInst &Instr, MCCFIInstruction &&CFIInst) {
1781     assert(BC.MIB->isCFI(Instr) &&
1782            "attempting to change CFI in a non-CFI inst");
1783     uint32_t Offset = Instr.getOperand(0).getImm();
1784     assert(Offset < FrameInstructions.size() && "Invalid CFI offset");
1785     FrameInstructions[Offset] = std::move(CFIInst);
1786   }
1787 
1788   void mutateCFIRegisterFor(const MCInst &Instr, MCPhysReg NewReg);
1789 
1790   const MCCFIInstruction *mutateCFIOffsetFor(const MCInst &Instr,
1791                                              int64_t NewOffset);
1792 
1793   BinaryFunction &setFileOffset(uint64_t Offset) {
1794     FileOffset = Offset;
1795     return *this;
1796   }
1797 
1798   BinaryFunction &setSize(uint64_t S) {
1799     Size = S;
1800     return *this;
1801   }
1802 
1803   BinaryFunction &setMaxSize(uint64_t Size) {
1804     MaxSize = Size;
1805     return *this;
1806   }
1807 
1808   BinaryFunction &setOutputAddress(uint64_t Address) {
1809     OutputAddress = Address;
1810     return *this;
1811   }
1812 
1813   BinaryFunction &setOutputSize(uint64_t Size) {
1814     OutputSize = Size;
1815     return *this;
1816   }
1817 
1818   BinaryFunction &setSimple(bool Simple) {
1819     IsSimple = Simple;
1820     return *this;
1821   }
1822 
1823   void setPseudo(bool Pseudo) { IsPseudo = Pseudo; }
1824 
1825   BinaryFunction &setUsesGnuArgsSize(bool Uses = true) {
1826     UsesGnuArgsSize = Uses;
1827     return *this;
1828   }
1829 
1830   BinaryFunction &setHasProfileAvailable(bool V = true) {
1831     HasProfileAvailable = V;
1832     return *this;
1833   }
1834 
1835   /// Mark function that should not be emitted.
1836   void setIgnored();
1837 
1838   void setIsPatched(bool V) { IsPatched = V; }
1839 
1840   void setHasIndirectTargetToSplitFragment(bool V) {
1841     HasIndirectTargetToSplitFragment = V;
1842   }
1843 
1844   void setHasCanonicalCFG(bool V) { HasCanonicalCFG = V; }
1845 
1846   void setFolded(BinaryFunction *BF) { FoldedIntoFunction = BF; }
1847 
1848   BinaryFunction &setPersonalityFunction(uint64_t Addr) {
1849     assert(!PersonalityFunction && "can't set personality function twice");
1850     PersonalityFunction = BC.getOrCreateGlobalSymbol(Addr, "FUNCat");
1851     return *this;
1852   }
1853 
1854   BinaryFunction &setPersonalityEncoding(uint8_t Encoding) {
1855     PersonalityEncoding = Encoding;
1856     return *this;
1857   }
1858 
1859   BinaryFunction &setAlignment(uint16_t Align) {
1860     Alignment = Align;
1861     return *this;
1862   }
1863 
1864   uint16_t getAlignment() const { return Alignment; }
1865 
1866   BinaryFunction &setMaxAlignmentBytes(uint16_t MaxAlignBytes) {
1867     MaxAlignmentBytes = MaxAlignBytes;
1868     return *this;
1869   }
1870 
1871   uint16_t getMaxAlignmentBytes() const { return MaxAlignmentBytes; }
1872 
1873   BinaryFunction &setMaxColdAlignmentBytes(uint16_t MaxAlignBytes) {
1874     MaxColdAlignmentBytes = MaxAlignBytes;
1875     return *this;
1876   }
1877 
1878   uint16_t getMaxColdAlignmentBytes() const { return MaxColdAlignmentBytes; }
1879 
1880   BinaryFunction &setImageAddress(uint64_t Address) {
1881     ImageAddress = Address;
1882     return *this;
1883   }
1884 
1885   /// Return the address of this function' image in memory.
1886   uint64_t getImageAddress() const { return ImageAddress; }
1887 
1888   BinaryFunction &setImageSize(uint64_t Size) {
1889     ImageSize = Size;
1890     return *this;
1891   }
1892 
1893   /// Return the size of this function' image in memory.
1894   uint64_t getImageSize() const { return ImageSize; }
1895 
1896   /// Return true if the function is a secondary fragment of another function.
1897   bool isFragment() const { return IsFragment; }
1898 
1899   /// Returns if the given function is a parent fragment of this function.
1900   bool isParentFragment(BinaryFunction *Parent) const {
1901     return ParentFragments.count(Parent);
1902   }
1903 
1904   /// Set the profile data for the number of times the function was called.
1905   BinaryFunction &setExecutionCount(uint64_t Count) {
1906     ExecutionCount = Count;
1907     return *this;
1908   }
1909 
1910   /// Adjust execution count for the function by a given \p Count. The value
1911   /// \p Count will be subtracted from the current function count.
1912   ///
1913   /// The function will proportionally adjust execution count for all
1914   /// basic blocks and edges in the control flow graph.
1915   void adjustExecutionCount(uint64_t Count);
1916 
1917   /// Set LSDA address for the function.
1918   BinaryFunction &setLSDAAddress(uint64_t Address) {
1919     LSDAAddress = Address;
1920     return *this;
1921   }
1922 
1923   /// Set LSDA symbol for the function.
1924   BinaryFunction &setLSDASymbol(MCSymbol *Symbol) {
1925     LSDASymbol = Symbol;
1926     return *this;
1927   }
1928 
1929   /// Return the profile information about the number of times
1930   /// the function was executed.
1931   ///
1932   /// Return COUNT_NO_PROFILE if there's no profile info.
1933   uint64_t getExecutionCount() const { return ExecutionCount; }
1934 
1935   /// Return the raw profile information about the number of branch
1936   /// executions corresponding to this function.
1937   uint64_t getRawBranchCount() const { return RawBranchCount; }
1938 
1939   /// Return the execution count for functions with known profile.
1940   /// Return 0 if the function has no profile.
1941   uint64_t getKnownExecutionCount() const {
1942     return ExecutionCount == COUNT_NO_PROFILE ? 0 : ExecutionCount;
1943   }
1944 
1945   /// Return original LSDA address for the function or NULL.
1946   uint64_t getLSDAAddress() const { return LSDAAddress; }
1947 
1948   /// Return symbol pointing to function's LSDA.
1949   MCSymbol *getLSDASymbol() {
1950     if (LSDASymbol)
1951       return LSDASymbol;
1952     if (CallSites.empty())
1953       return nullptr;
1954 
1955     LSDASymbol = BC.Ctx->getOrCreateSymbol(
1956         Twine("GCC_except_table") + Twine::utohexstr(getFunctionNumber()));
1957 
1958     return LSDASymbol;
1959   }
1960 
1961   /// Return symbol pointing to function's LSDA for the cold part.
1962   MCSymbol *getColdLSDASymbol() {
1963     if (ColdLSDASymbol)
1964       return ColdLSDASymbol;
1965     if (ColdCallSites.empty())
1966       return nullptr;
1967 
1968     ColdLSDASymbol = BC.Ctx->getOrCreateSymbol(
1969         Twine("GCC_cold_except_table") + Twine::utohexstr(getFunctionNumber()));
1970 
1971     return ColdLSDASymbol;
1972   }
1973 
1974   void setOutputDataAddress(uint64_t Address) { OutputDataOffset = Address; }
1975 
1976   uint64_t getOutputDataAddress() const { return OutputDataOffset; }
1977 
1978   void setOutputColdDataAddress(uint64_t Address) {
1979     OutputColdDataOffset = Address;
1980   }
1981 
1982   uint64_t getOutputColdDataAddress() const { return OutputColdDataOffset; }
1983 
1984   /// If \p Address represents an access to a constant island managed by this
1985   /// function, return a symbol so code can safely refer to it. Otherwise,
1986   /// return nullptr. First return value is the symbol for reference in the
1987   /// hot code area while the second return value is the symbol for reference
1988   /// in the cold code area, as when the function is split the islands are
1989   /// duplicated.
1990   MCSymbol *getOrCreateIslandAccess(uint64_t Address) {
1991     if (!Islands)
1992       return nullptr;
1993 
1994     MCSymbol *Symbol;
1995     if (!isInConstantIsland(Address))
1996       return nullptr;
1997 
1998     // Register our island at global namespace
1999     Symbol = BC.getOrCreateGlobalSymbol(Address, "ISLANDat");
2000 
2001     // Internal bookkeeping
2002     const uint64_t Offset = Address - getAddress();
2003     assert((!Islands->Offsets.count(Offset) ||
2004             Islands->Offsets[Offset] == Symbol) &&
2005            "Inconsistent island symbol management");
2006     if (!Islands->Offsets.count(Offset)) {
2007       Islands->Offsets[Offset] = Symbol;
2008       Islands->Symbols.insert(Symbol);
2009     }
2010     return Symbol;
2011   }
2012 
2013   /// Called by an external function which wishes to emit references to constant
2014   /// island symbols of this function. We create a proxy for it, so we emit
2015   /// separate symbols when emitting our constant island on behalf of this other
2016   /// function.
2017   MCSymbol *getOrCreateProxyIslandAccess(uint64_t Address,
2018                                          BinaryFunction &Referrer) {
2019     MCSymbol *Symbol = getOrCreateIslandAccess(Address);
2020     if (!Symbol)
2021       return nullptr;
2022 
2023     MCSymbol *Proxy;
2024     if (!Islands->Proxies[&Referrer].count(Symbol)) {
2025       Proxy = BC.Ctx->getOrCreateSymbol(Symbol->getName() + ".proxy.for." +
2026                                         Referrer.getPrintName());
2027       Islands->Proxies[&Referrer][Symbol] = Proxy;
2028       Islands->Proxies[&Referrer][Proxy] = Symbol;
2029     }
2030     Proxy = Islands->Proxies[&Referrer][Symbol];
2031     return Proxy;
2032   }
2033 
2034   /// Make this function depend on \p BF because we have a reference to its
2035   /// constant island. When emitting this function,  we will also emit
2036   //  \p BF's constants. This only happens in custom AArch64 assembly code.
2037   void createIslandDependency(MCSymbol *Island, BinaryFunction *BF) {
2038     if (!Islands)
2039       Islands = std::make_unique<IslandInfo>();
2040 
2041     Islands->Dependency.insert(BF);
2042     Islands->ProxySymbols[Island] = BF;
2043   }
2044 
2045   /// Detects whether \p Address is inside a data region in this function
2046   /// (constant islands).
2047   bool isInConstantIsland(uint64_t Address) const {
2048     if (!Islands)
2049       return false;
2050 
2051     if (Address < getAddress())
2052       return false;
2053 
2054     uint64_t Offset = Address - getAddress();
2055 
2056     if (Offset >= getMaxSize())
2057       return false;
2058 
2059     auto DataIter = Islands->DataOffsets.upper_bound(Offset);
2060     if (DataIter == Islands->DataOffsets.begin())
2061       return false;
2062     DataIter = std::prev(DataIter);
2063 
2064     auto CodeIter = Islands->CodeOffsets.upper_bound(Offset);
2065     if (CodeIter == Islands->CodeOffsets.begin())
2066       return true;
2067 
2068     return *std::prev(CodeIter) <= *DataIter;
2069   }
2070 
2071   uint16_t getConstantIslandAlignment() const {
2072     return Islands ? Islands->getAlignment() : 1;
2073   }
2074 
2075   uint64_t
2076   estimateConstantIslandSize(const BinaryFunction *OnBehalfOf = nullptr) const {
2077     if (!Islands)
2078       return 0;
2079 
2080     uint64_t Size = 0;
2081     for (auto DataIter = Islands->DataOffsets.begin();
2082          DataIter != Islands->DataOffsets.end(); ++DataIter) {
2083       auto NextData = std::next(DataIter);
2084       auto CodeIter = Islands->CodeOffsets.lower_bound(*DataIter);
2085       if (CodeIter == Islands->CodeOffsets.end() &&
2086           NextData == Islands->DataOffsets.end()) {
2087         Size += getMaxSize() - *DataIter;
2088         continue;
2089       }
2090 
2091       uint64_t NextMarker;
2092       if (CodeIter == Islands->CodeOffsets.end())
2093         NextMarker = *NextData;
2094       else if (NextData == Islands->DataOffsets.end())
2095         NextMarker = *CodeIter;
2096       else
2097         NextMarker = (*CodeIter > *NextData) ? *NextData : *CodeIter;
2098 
2099       Size += NextMarker - *DataIter;
2100     }
2101 
2102     if (!OnBehalfOf) {
2103       for (BinaryFunction *ExternalFunc : Islands->Dependency) {
2104         Size = alignTo(Size, ExternalFunc->getConstantIslandAlignment());
2105         Size += ExternalFunc->estimateConstantIslandSize(this);
2106       }
2107     }
2108 
2109     return Size;
2110   }
2111 
2112   bool hasIslandsInfo() const { return !!Islands; }
2113 
2114   bool hasConstantIsland() const {
2115     return Islands && !Islands->DataOffsets.empty();
2116   }
2117 
2118   /// Return true iff the symbol could be seen inside this function otherwise
2119   /// it is probably another function.
2120   bool isSymbolValidInScope(const SymbolRef &Symbol, uint64_t SymbolSize) const;
2121 
2122   /// Disassemble function from raw data.
2123   /// If successful, this function will populate the list of instructions
2124   /// for this function together with offsets from the function start
2125   /// in the input. It will also populate Labels with destinations for
2126   /// local branches, and TakenBranches with [from, to] info.
2127   ///
2128   /// The Function should be properly initialized before this function
2129   /// is called. I.e. function address and size should be set.
2130   ///
2131   /// Returns true on successful disassembly, and updates the current
2132   /// state to State:Disassembled.
2133   ///
2134   /// Returns false if disassembly failed.
2135   bool disassemble();
2136 
2137   /// Scan function for references to other functions. In relocation mode,
2138   /// add relocations for external references.
2139   ///
2140   /// Return true on success.
2141   bool scanExternalRefs();
2142 
2143   /// Return the size of a data object located at \p Offset in the function.
2144   /// Return 0 if there is no data object at the \p Offset.
2145   size_t getSizeOfDataInCodeAt(uint64_t Offset) const;
2146 
2147   /// Verify that starting at \p Offset function contents are filled with
2148   /// zero-value bytes.
2149   bool isZeroPaddingAt(uint64_t Offset) const;
2150 
2151   /// Check that entry points have an associated instruction at their
2152   /// offsets after disassembly.
2153   void postProcessEntryPoints();
2154 
2155   /// Post-processing for jump tables after disassembly. Since their
2156   /// boundaries are not known until all call sites are seen, we need this
2157   /// extra pass to perform any final adjustments.
2158   void postProcessJumpTables();
2159 
2160   /// Builds a list of basic blocks with successor and predecessor info.
2161   ///
2162   /// The function should in Disassembled state prior to call.
2163   ///
2164   /// Returns true on success and update the current function state to
2165   /// State::CFG. Returns false if CFG cannot be built.
2166   bool buildCFG(MCPlusBuilder::AllocatorIdTy);
2167 
2168   /// Perform post-processing of the CFG.
2169   void postProcessCFG();
2170 
2171   /// Verify that any assumptions we've made about indirect branches were
2172   /// correct and also make any necessary changes to unknown indirect branches.
2173   ///
2174   /// Catch-22: we need to know indirect branch targets to build CFG, and
2175   /// in order to determine the value for indirect branches we need to know CFG.
2176   ///
2177   /// As such, the process of decoding indirect branches is broken into 2 steps:
2178   /// first we make our best guess about a branch without knowing the CFG,
2179   /// and later after we have the CFG for the function, we verify our earlier
2180   /// assumptions and also do our best at processing unknown indirect branches.
2181   ///
2182   /// Return true upon successful processing, or false if the control flow
2183   /// cannot be statically evaluated for any given indirect branch.
2184   bool postProcessIndirectBranches(MCPlusBuilder::AllocatorIdTy AllocId);
2185 
2186   /// Return all call site profile info for this function.
2187   IndirectCallSiteProfile &getAllCallSites() { return AllCallSites; }
2188 
2189   const IndirectCallSiteProfile &getAllCallSites() const {
2190     return AllCallSites;
2191   }
2192 
2193   /// Walks the list of basic blocks filling in missing information about
2194   /// edge frequency for fall-throughs.
2195   ///
2196   /// Assumes the CFG has been built and edge frequency for taken branches
2197   /// has been filled with LBR data.
2198   void inferFallThroughCounts();
2199 
2200   /// Clear execution profile of the function.
2201   void clearProfile();
2202 
2203   /// Converts conditional tail calls to unconditional tail calls. We do this to
2204   /// handle conditional tail calls correctly and to give a chance to the
2205   /// simplify conditional tail call pass to decide whether to re-optimize them
2206   /// using profile information.
2207   void removeConditionalTailCalls();
2208 
2209   // Convert COUNT_NO_PROFILE to 0
2210   void removeTagsFromProfile();
2211 
2212   /// Computes a function hotness score: the sum of the products of BB frequency
2213   /// and size.
2214   uint64_t getFunctionScore() const;
2215 
2216   /// Return true if the layout has been changed by basic block reordering,
2217   /// false otherwise.
2218   bool hasLayoutChanged() const;
2219 
2220   /// Get the edit distance of the new layout with respect to the previous
2221   /// layout after basic block reordering.
2222   uint64_t getEditDistance() const;
2223 
2224   /// Get the number of instructions within this function.
2225   uint64_t getInstructionCount() const;
2226 
2227   const CFIInstrMapType &getFDEProgram() const { return FrameInstructions; }
2228 
2229   void moveRememberRestorePair(BinaryBasicBlock *BB);
2230 
2231   bool replayCFIInstrs(int32_t FromState, int32_t ToState,
2232                        BinaryBasicBlock *InBB,
2233                        BinaryBasicBlock::iterator InsertIt);
2234 
2235   /// unwindCFIState is used to unwind from a higher to a lower state number
2236   /// without using remember-restore instructions. We do that by keeping track
2237   /// of what values have been changed from state A to B and emitting
2238   /// instructions that undo this change.
2239   SmallVector<int32_t, 4> unwindCFIState(int32_t FromState, int32_t ToState,
2240                                          BinaryBasicBlock *InBB,
2241                                          BinaryBasicBlock::iterator &InsertIt);
2242 
2243   /// After reordering, this function checks the state of CFI and fixes it if it
2244   /// is corrupted. If it is unable to fix it, it returns false.
2245   bool finalizeCFIState();
2246 
2247   /// Return true if this function needs an address-transaltion table after
2248   /// its code emission.
2249   bool requiresAddressTranslation() const;
2250 
2251   /// Adjust branch instructions to match the CFG.
2252   ///
2253   /// As it comes to internal branches, the CFG represents "the ultimate source
2254   /// of truth". Transformations on functions and blocks have to update the CFG
2255   /// and fixBranches() would make sure the correct branch instructions are
2256   /// inserted at the end of basic blocks.
2257   ///
2258   /// We do require a conditional branch at the end of the basic block if
2259   /// the block has 2 successors as CFG currently lacks the conditional
2260   /// code support (it will probably stay that way). We only use this
2261   /// branch instruction for its conditional code, the destination is
2262   /// determined by CFG - first successor representing true/taken branch,
2263   /// while the second successor - false/fall-through branch.
2264   ///
2265   /// When we reverse the branch condition, the CFG is updated accordingly.
2266   void fixBranches();
2267 
2268   /// Mark function as finalized. No further optimizations are permitted.
2269   void setFinalized() { CurrentState = State::CFG_Finalized; }
2270 
2271   void setEmitted(bool KeepCFG = false) {
2272     CurrentState = State::EmittedCFG;
2273     if (!KeepCFG) {
2274       releaseCFG();
2275       CurrentState = State::Emitted;
2276     }
2277   }
2278 
2279   /// Process LSDA information for the function.
2280   void parseLSDA(ArrayRef<uint8_t> LSDAData, uint64_t LSDAAddress);
2281 
2282   /// Update exception handling ranges for the function.
2283   void updateEHRanges();
2284 
2285   /// Traverse cold basic blocks and replace references to constants in islands
2286   /// with a proxy symbol for the duplicated constant island that is going to be
2287   /// emitted in the cold region.
2288   void duplicateConstantIslands();
2289 
2290   /// Merge profile data of this function into those of the given
2291   /// function. The functions should have been proven identical with
2292   /// isIdenticalWith.
2293   void mergeProfileDataInto(BinaryFunction &BF) const;
2294 
2295   /// Returns the last computed hash value of the function.
2296   size_t getHash() const { return Hash; }
2297 
2298   using OperandHashFuncTy =
2299       function_ref<typename std::string(const MCOperand &)>;
2300 
2301   /// Compute the hash value of the function based on its contents.
2302   ///
2303   /// If \p UseDFS is set, process basic blocks in DFS order. Otherwise, use
2304   /// the existing layout order.
2305   ///
2306   /// By default, instruction operands are ignored while calculating the hash.
2307   /// The caller can change this via passing \p OperandHashFunc function.
2308   /// The return result of this function will be mixed with internal hash.
2309   size_t computeHash(
2310       bool UseDFS = false,
2311       OperandHashFuncTy OperandHashFunc = [](const MCOperand &) {
2312         return std::string();
2313       }) const;
2314 
2315   void setDWARFUnit(DWARFUnit *Unit) { DwarfUnit = Unit; }
2316 
2317   /// Return DWARF compile unit for this function.
2318   DWARFUnit *getDWARFUnit() const { return DwarfUnit; }
2319 
2320   /// Return line info table for this function.
2321   const DWARFDebugLine::LineTable *getDWARFLineTable() const {
2322     return getDWARFUnit() ? BC.DwCtx->getLineTableForUnit(getDWARFUnit())
2323                           : nullptr;
2324   }
2325 
2326   /// Finalize profile for the function.
2327   void postProcessProfile();
2328 
2329   /// Returns an estimate of the function's hot part after splitting.
2330   /// This is a very rough estimate, as with C++ exceptions there are
2331   /// blocks we don't move, and it makes no attempt at estimating the size
2332   /// of the added/removed branch instructions.
2333   /// Note that this size is optimistic and the actual size may increase
2334   /// after relaxation.
2335   size_t estimateHotSize(const bool UseSplitSize = true) const {
2336     size_t Estimate = 0;
2337     if (UseSplitSize && isSplit()) {
2338       for (const BinaryBasicBlock &BB : blocks())
2339         if (!BB.isCold())
2340           Estimate += BC.computeCodeSize(BB.begin(), BB.end());
2341     } else {
2342       for (const BinaryBasicBlock &BB : blocks())
2343         if (BB.getKnownExecutionCount() != 0)
2344           Estimate += BC.computeCodeSize(BB.begin(), BB.end());
2345     }
2346     return Estimate;
2347   }
2348 
2349   size_t estimateColdSize() const {
2350     if (!isSplit())
2351       return estimateSize();
2352     size_t Estimate = 0;
2353     for (const BinaryBasicBlock &BB : blocks())
2354       if (BB.isCold())
2355         Estimate += BC.computeCodeSize(BB.begin(), BB.end());
2356     return Estimate;
2357   }
2358 
2359   size_t estimateSize() const {
2360     size_t Estimate = 0;
2361     for (const BinaryBasicBlock &BB : blocks())
2362       Estimate += BC.computeCodeSize(BB.begin(), BB.end());
2363     return Estimate;
2364   }
2365 
2366   /// Return output address ranges for a function.
2367   DebugAddressRangesVector getOutputAddressRanges() const;
2368 
2369   /// Given an address corresponding to an instruction in the input binary,
2370   /// return an address of this instruction in output binary.
2371   ///
2372   /// Return 0 if no matching address could be found or the instruction was
2373   /// removed.
2374   uint64_t translateInputToOutputAddress(uint64_t Address) const;
2375 
2376   /// Take address ranges corresponding to the input binary and translate
2377   /// them to address ranges in the output binary.
2378   DebugAddressRangesVector translateInputToOutputRanges(
2379       const DWARFAddressRangesVector &InputRanges) const;
2380 
2381   /// Similar to translateInputToOutputRanges() but operates on location lists
2382   /// and moves associated data to output location lists.
2383   DebugLocationsVector
2384   translateInputToOutputLocationList(const DebugLocationsVector &InputLL) const;
2385 
2386   /// Return true if the function is an AArch64 linker inserted veneer
2387   bool isAArch64Veneer() const;
2388 
2389   virtual ~BinaryFunction();
2390 
2391   /// Info for fragmented functions.
2392   class FragmentInfo {
2393   private:
2394     uint64_t Address{0};
2395     uint64_t ImageAddress{0};
2396     uint64_t ImageSize{0};
2397     uint64_t FileOffset{0};
2398 
2399   public:
2400     uint64_t getAddress() const { return Address; }
2401     uint64_t getImageAddress() const { return ImageAddress; }
2402     uint64_t getImageSize() const { return ImageSize; }
2403     uint64_t getFileOffset() const { return FileOffset; }
2404 
2405     void setAddress(uint64_t VAddress) { Address = VAddress; }
2406     void setImageAddress(uint64_t Address) { ImageAddress = Address; }
2407     void setImageSize(uint64_t Size) { ImageSize = Size; }
2408     void setFileOffset(uint64_t Offset) { FileOffset = Offset; }
2409   };
2410 
2411   /// Cold fragment of the function.
2412   FragmentInfo ColdFragment;
2413 
2414   FragmentInfo &cold() { return ColdFragment; }
2415 
2416   const FragmentInfo &cold() const { return ColdFragment; }
2417 };
2418 
2419 inline raw_ostream &operator<<(raw_ostream &OS,
2420                                const BinaryFunction &Function) {
2421   OS << Function.getPrintName();
2422   return OS;
2423 }
2424 
2425 } // namespace bolt
2426 
2427 // GraphTraits specializations for function basic block graphs (CFGs)
2428 template <>
2429 struct GraphTraits<bolt::BinaryFunction *>
2430     : public GraphTraits<bolt::BinaryBasicBlock *> {
2431   static NodeRef getEntryNode(bolt::BinaryFunction *F) {
2432     return *F->layout_begin();
2433   }
2434 
2435   using nodes_iterator = pointer_iterator<bolt::BinaryFunction::iterator>;
2436 
2437   static nodes_iterator nodes_begin(bolt::BinaryFunction *F) {
2438     llvm_unreachable("Not implemented");
2439     return nodes_iterator(F->begin());
2440   }
2441   static nodes_iterator nodes_end(bolt::BinaryFunction *F) {
2442     llvm_unreachable("Not implemented");
2443     return nodes_iterator(F->end());
2444   }
2445   static size_t size(bolt::BinaryFunction *F) { return F->size(); }
2446 };
2447 
2448 template <>
2449 struct GraphTraits<const bolt::BinaryFunction *>
2450     : public GraphTraits<const bolt::BinaryBasicBlock *> {
2451   static NodeRef getEntryNode(const bolt::BinaryFunction *F) {
2452     return *F->layout_begin();
2453   }
2454 
2455   using nodes_iterator = pointer_iterator<bolt::BinaryFunction::const_iterator>;
2456 
2457   static nodes_iterator nodes_begin(const bolt::BinaryFunction *F) {
2458     llvm_unreachable("Not implemented");
2459     return nodes_iterator(F->begin());
2460   }
2461   static nodes_iterator nodes_end(const bolt::BinaryFunction *F) {
2462     llvm_unreachable("Not implemented");
2463     return nodes_iterator(F->end());
2464   }
2465   static size_t size(const bolt::BinaryFunction *F) { return F->size(); }
2466 };
2467 
2468 template <>
2469 struct GraphTraits<Inverse<bolt::BinaryFunction *>>
2470     : public GraphTraits<Inverse<bolt::BinaryBasicBlock *>> {
2471   static NodeRef getEntryNode(Inverse<bolt::BinaryFunction *> G) {
2472     return *G.Graph->layout_begin();
2473   }
2474 };
2475 
2476 template <>
2477 struct GraphTraits<Inverse<const bolt::BinaryFunction *>>
2478     : public GraphTraits<Inverse<const bolt::BinaryBasicBlock *>> {
2479   static NodeRef getEntryNode(Inverse<const bolt::BinaryFunction *> G) {
2480     return *G.Graph->layout_begin();
2481   }
2482 };
2483 
2484 } // namespace llvm
2485 
2486 #endif
2487