xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/IPO/MergeFunctions.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- MergeFunctions.cpp - Merge identical functions ---------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This pass looks for equivalent functions that are mergable and folds them.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric // Order relation is defined on set of functions. It was made through
120b57cec5SDimitry Andric // special function comparison procedure that returns
130b57cec5SDimitry Andric // 0 when functions are equal,
140b57cec5SDimitry Andric // -1 when Left function is less than right function, and
150b57cec5SDimitry Andric // 1 for opposite case. We need total-ordering, so we need to maintain
160b57cec5SDimitry Andric // four properties on the functions set:
170b57cec5SDimitry Andric // a <= a (reflexivity)
180b57cec5SDimitry Andric // if a <= b and b <= a then a = b (antisymmetry)
190b57cec5SDimitry Andric // if a <= b and b <= c then a <= c (transitivity).
200b57cec5SDimitry Andric // for all a and b: a <= b or b <= a (totality).
210b57cec5SDimitry Andric //
220b57cec5SDimitry Andric // Comparison iterates through each instruction in each basic block.
230b57cec5SDimitry Andric // Functions are kept on binary tree. For each new function F we perform
240b57cec5SDimitry Andric // lookup in binary tree.
250b57cec5SDimitry Andric // In practice it works the following way:
260b57cec5SDimitry Andric // -- We define Function* container class with custom "operator<" (FunctionPtr).
270b57cec5SDimitry Andric // -- "FunctionPtr" instances are stored in std::set collection, so every
280b57cec5SDimitry Andric //    std::set::insert operation will give you result in log(N) time.
290b57cec5SDimitry Andric //
300b57cec5SDimitry Andric // As an optimization, a hash of the function structure is calculated first, and
310b57cec5SDimitry Andric // two functions are only compared if they have the same hash. This hash is
320b57cec5SDimitry Andric // cheap to compute, and has the property that if function F == G according to
330b57cec5SDimitry Andric // the comparison function, then hash(F) == hash(G). This consistency property
340b57cec5SDimitry Andric // is critical to ensuring all possible merging opportunities are exploited.
350b57cec5SDimitry Andric // Collisions in the hash affect the speed of the pass but not the correctness
360b57cec5SDimitry Andric // or determinism of the resulting transformation.
370b57cec5SDimitry Andric //
380b57cec5SDimitry Andric // When a match is found the functions are folded. If both functions are
390b57cec5SDimitry Andric // overridable, we move the functionality into a new internal function and
400b57cec5SDimitry Andric // leave two overridable thunks to it.
410b57cec5SDimitry Andric //
420b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
430b57cec5SDimitry Andric //
440b57cec5SDimitry Andric // Future work:
450b57cec5SDimitry Andric //
460b57cec5SDimitry Andric // * virtual functions.
470b57cec5SDimitry Andric //
480b57cec5SDimitry Andric // Many functions have their address taken by the virtual function table for
490b57cec5SDimitry Andric // the object they belong to. However, as long as it's only used for a lookup
500b57cec5SDimitry Andric // and call, this is irrelevant, and we'd like to fold such functions.
510b57cec5SDimitry Andric //
520b57cec5SDimitry Andric // * be smarter about bitcasts.
530b57cec5SDimitry Andric //
540b57cec5SDimitry Andric // In order to fold functions, we will sometimes add either bitcast instructions
550b57cec5SDimitry Andric // or bitcast constant expressions. Unfortunately, this can confound further
560b57cec5SDimitry Andric // analysis since the two functions differ where one has a bitcast and the
570b57cec5SDimitry Andric // other doesn't. We should learn to look through bitcasts.
580b57cec5SDimitry Andric //
590b57cec5SDimitry Andric // * Compare complex types with pointer types inside.
600b57cec5SDimitry Andric // * Compare cross-reference cases.
610b57cec5SDimitry Andric // * Compare complex expressions.
620b57cec5SDimitry Andric //
630b57cec5SDimitry Andric // All the three issues above could be described as ability to prove that
640b57cec5SDimitry Andric // fA == fB == fC == fE == fF == fG in example below:
650b57cec5SDimitry Andric //
660b57cec5SDimitry Andric //  void fA() {
670b57cec5SDimitry Andric //    fB();
680b57cec5SDimitry Andric //  }
690b57cec5SDimitry Andric //  void fB() {
700b57cec5SDimitry Andric //    fA();
710b57cec5SDimitry Andric //  }
720b57cec5SDimitry Andric //
730b57cec5SDimitry Andric //  void fE() {
740b57cec5SDimitry Andric //    fF();
750b57cec5SDimitry Andric //  }
760b57cec5SDimitry Andric //  void fF() {
770b57cec5SDimitry Andric //    fG();
780b57cec5SDimitry Andric //  }
790b57cec5SDimitry Andric //  void fG() {
800b57cec5SDimitry Andric //    fE();
810b57cec5SDimitry Andric //  }
820b57cec5SDimitry Andric //
830b57cec5SDimitry Andric // Simplest cross-reference case (fA <--> fB) was implemented in previous
840b57cec5SDimitry Andric // versions of MergeFunctions, though it presented only in two function pairs
850b57cec5SDimitry Andric // in test-suite (that counts >50k functions)
860b57cec5SDimitry Andric // Though possibility to detect complex cross-referencing (e.g.: A->B->C->D->A)
870b57cec5SDimitry Andric // could cover much more cases.
880b57cec5SDimitry Andric //
890b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
900b57cec5SDimitry Andric 
9181ad6265SDimitry Andric #include "llvm/Transforms/IPO/MergeFunctions.h"
920b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
930b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
940b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
950b57cec5SDimitry Andric #include "llvm/IR/Argument.h"
960b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
970b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
980b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
990b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
1000b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
1010b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
1020b57cec5SDimitry Andric #include "llvm/IR/Function.h"
1030b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
1040b57cec5SDimitry Andric #include "llvm/IR/IRBuilder.h"
1050b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
1060b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
1070b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
1080b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
1090b57cec5SDimitry Andric #include "llvm/IR/Module.h"
1105f757f3fSDimitry Andric #include "llvm/IR/StructuralHash.h"
1110b57cec5SDimitry Andric #include "llvm/IR/Type.h"
1120b57cec5SDimitry Andric #include "llvm/IR/Use.h"
1130b57cec5SDimitry Andric #include "llvm/IR/User.h"
1140b57cec5SDimitry Andric #include "llvm/IR/Value.h"
1150b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h"
1160b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
1170b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
1180b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
1190b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
1200b57cec5SDimitry Andric #include "llvm/Transforms/IPO.h"
1210b57cec5SDimitry Andric #include "llvm/Transforms/Utils/FunctionComparator.h"
12281ad6265SDimitry Andric #include "llvm/Transforms/Utils/ModuleUtils.h"
1230b57cec5SDimitry Andric #include <algorithm>
1240b57cec5SDimitry Andric #include <cassert>
1250b57cec5SDimitry Andric #include <iterator>
1260b57cec5SDimitry Andric #include <set>
1270b57cec5SDimitry Andric #include <utility>
1280b57cec5SDimitry Andric #include <vector>
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric using namespace llvm;
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric #define DEBUG_TYPE "mergefunc"
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric STATISTIC(NumFunctionsMerged, "Number of functions merged");
1350b57cec5SDimitry Andric STATISTIC(NumThunksWritten, "Number of thunks generated");
1360b57cec5SDimitry Andric STATISTIC(NumAliasesWritten, "Number of aliases generated");
1370b57cec5SDimitry Andric STATISTIC(NumDoubleWeak, "Number of new functions created");
1380b57cec5SDimitry Andric 
13981ad6265SDimitry Andric static cl::opt<unsigned> NumFunctionsForVerificationCheck(
14081ad6265SDimitry Andric     "mergefunc-verify",
14181ad6265SDimitry Andric     cl::desc("How many functions in a module could be used for "
14281ad6265SDimitry Andric              "MergeFunctions to pass a basic correctness check. "
1430b57cec5SDimitry Andric              "'0' disables this check. Works only with '-debug' key."),
1440b57cec5SDimitry Andric     cl::init(0), cl::Hidden);
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric // Under option -mergefunc-preserve-debug-info we:
1470b57cec5SDimitry Andric // - Do not create a new function for a thunk.
1480b57cec5SDimitry Andric // - Retain the debug info for a thunk's parameters (and associated
1490b57cec5SDimitry Andric //   instructions for the debug info) from the entry block.
1500b57cec5SDimitry Andric //   Note: -debug will display the algorithm at work.
1510b57cec5SDimitry Andric // - Create debug-info for the call (to the shared implementation) made by
1520b57cec5SDimitry Andric //   a thunk and its return value.
1530b57cec5SDimitry Andric // - Erase the rest of the function, retaining the (minimally sized) entry
1540b57cec5SDimitry Andric //   block to create a thunk.
1550b57cec5SDimitry Andric // - Preserve a thunk's call site to point to the thunk even when both occur
1560b57cec5SDimitry Andric //   within the same translation unit, to aid debugability. Note that this
1570b57cec5SDimitry Andric //   behaviour differs from the underlying -mergefunc implementation which
1580b57cec5SDimitry Andric //   modifies the thunk's call site to point to the shared implementation
1590b57cec5SDimitry Andric //   when both occur within the same translation unit.
1600b57cec5SDimitry Andric static cl::opt<bool>
1610b57cec5SDimitry Andric     MergeFunctionsPDI("mergefunc-preserve-debug-info", cl::Hidden,
1620b57cec5SDimitry Andric                       cl::init(false),
1630b57cec5SDimitry Andric                       cl::desc("Preserve debug info in thunk when mergefunc "
1640b57cec5SDimitry Andric                                "transformations are made."));
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric static cl::opt<bool>
1670b57cec5SDimitry Andric     MergeFunctionsAliases("mergefunc-use-aliases", cl::Hidden,
1680b57cec5SDimitry Andric                           cl::init(false),
1690b57cec5SDimitry Andric                           cl::desc("Allow mergefunc to create aliases"));
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric namespace {
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric class FunctionNode {
1740b57cec5SDimitry Andric   mutable AssertingVH<Function> F;
1755f757f3fSDimitry Andric   IRHash Hash;
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric public:
1780b57cec5SDimitry Andric   // Note the hash is recalculated potentially multiple times, but it is cheap.
1795f757f3fSDimitry Andric   FunctionNode(Function *F) : F(F), Hash(StructuralHash(*F)) {}
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   Function *getFunc() const { return F; }
1825f757f3fSDimitry Andric   IRHash getHash() const { return Hash; }
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   /// Replace the reference to the function F by the function G, assuming their
1850b57cec5SDimitry Andric   /// implementations are equal.
1860b57cec5SDimitry Andric   void replaceBy(Function *G) const {
1870b57cec5SDimitry Andric     F = G;
1880b57cec5SDimitry Andric   }
1890b57cec5SDimitry Andric };
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric /// MergeFunctions finds functions which will generate identical machine code,
1920b57cec5SDimitry Andric /// by considering all pointer types to be equivalent. Once identified,
1930b57cec5SDimitry Andric /// MergeFunctions will fold them by replacing a call to one to a call to a
1940b57cec5SDimitry Andric /// bitcast of the other.
195480093f4SDimitry Andric class MergeFunctions {
1960b57cec5SDimitry Andric public:
197480093f4SDimitry Andric   MergeFunctions() : FnTree(FunctionNodeCmp(&GlobalNumbers)) {
1980b57cec5SDimitry Andric   }
1990b57cec5SDimitry Andric 
200480093f4SDimitry Andric   bool runOnModule(Module &M);
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric private:
2030b57cec5SDimitry Andric   // The function comparison operator is provided here so that FunctionNodes do
2040b57cec5SDimitry Andric   // not need to become larger with another pointer.
2050b57cec5SDimitry Andric   class FunctionNodeCmp {
2060b57cec5SDimitry Andric     GlobalNumberState* GlobalNumbers;
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   public:
2090b57cec5SDimitry Andric     FunctionNodeCmp(GlobalNumberState* GN) : GlobalNumbers(GN) {}
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric     bool operator()(const FunctionNode &LHS, const FunctionNode &RHS) const {
2120b57cec5SDimitry Andric       // Order first by hashes, then full function comparison.
2130b57cec5SDimitry Andric       if (LHS.getHash() != RHS.getHash())
2140b57cec5SDimitry Andric         return LHS.getHash() < RHS.getHash();
2150b57cec5SDimitry Andric       FunctionComparator FCmp(LHS.getFunc(), RHS.getFunc(), GlobalNumbers);
216bdd1243dSDimitry Andric       return FCmp.compare() < 0;
2170b57cec5SDimitry Andric     }
2180b57cec5SDimitry Andric   };
2190b57cec5SDimitry Andric   using FnTreeType = std::set<FunctionNode, FunctionNodeCmp>;
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric   GlobalNumberState GlobalNumbers;
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   /// A work queue of functions that may have been modified and should be
2240b57cec5SDimitry Andric   /// analyzed again.
2250b57cec5SDimitry Andric   std::vector<WeakTrackingVH> Deferred;
2260b57cec5SDimitry Andric 
22781ad6265SDimitry Andric   /// Set of values marked as used in llvm.used and llvm.compiler.used.
22881ad6265SDimitry Andric   SmallPtrSet<GlobalValue *, 4> Used;
22981ad6265SDimitry Andric 
2300b57cec5SDimitry Andric #ifndef NDEBUG
2310b57cec5SDimitry Andric   /// Checks the rules of order relation introduced among functions set.
23281ad6265SDimitry Andric   /// Returns true, if check has been passed, and false if failed.
23381ad6265SDimitry Andric   bool doFunctionalCheck(std::vector<WeakTrackingVH> &Worklist);
2340b57cec5SDimitry Andric #endif
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric   /// Insert a ComparableFunction into the FnTree, or merge it away if it's
2370b57cec5SDimitry Andric   /// equal to one that's already present.
2380b57cec5SDimitry Andric   bool insert(Function *NewFunction);
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   /// Remove a Function from the FnTree and queue it up for a second sweep of
2410b57cec5SDimitry Andric   /// analysis.
2420b57cec5SDimitry Andric   void remove(Function *F);
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   /// Find the functions that use this Value and remove them from FnTree and
2450b57cec5SDimitry Andric   /// queue the functions.
2460b57cec5SDimitry Andric   void removeUsers(Value *V);
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   /// Replace all direct calls of Old with calls of New. Will bitcast New if
2490b57cec5SDimitry Andric   /// necessary to make types match.
2500b57cec5SDimitry Andric   void replaceDirectCallers(Function *Old, Function *New);
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric   /// Merge two equivalent functions. Upon completion, G may be deleted, or may
2530b57cec5SDimitry Andric   /// be converted into a thunk. In either case, it should never be visited
2540b57cec5SDimitry Andric   /// again.
2550b57cec5SDimitry Andric   void mergeTwoFunctions(Function *F, Function *G);
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric   /// Fill PDIUnrelatedWL with instructions from the entry block that are
2580b57cec5SDimitry Andric   /// unrelated to parameter related debug info.
259*0fca6ea1SDimitry Andric   /// \param PDVRUnrelatedWL The equivalent non-intrinsic debug records.
260*0fca6ea1SDimitry Andric   void
261*0fca6ea1SDimitry Andric   filterInstsUnrelatedToPDI(BasicBlock *GEntryBlock,
262*0fca6ea1SDimitry Andric                             std::vector<Instruction *> &PDIUnrelatedWL,
263*0fca6ea1SDimitry Andric                             std::vector<DbgVariableRecord *> &PDVRUnrelatedWL);
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   /// Erase the rest of the CFG (i.e. barring the entry block).
2660b57cec5SDimitry Andric   void eraseTail(Function *G);
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric   /// Erase the instructions in PDIUnrelatedWL as they are unrelated to the
2690b57cec5SDimitry Andric   /// parameter debug info, from the entry block.
270*0fca6ea1SDimitry Andric   /// \param PDVRUnrelatedWL contains the equivalent set of non-instruction
271*0fca6ea1SDimitry Andric   /// debug-info records.
272*0fca6ea1SDimitry Andric   void
273*0fca6ea1SDimitry Andric   eraseInstsUnrelatedToPDI(std::vector<Instruction *> &PDIUnrelatedWL,
274*0fca6ea1SDimitry Andric                            std::vector<DbgVariableRecord *> &PDVRUnrelatedWL);
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric   /// Replace G with a simple tail call to bitcast(F). Also (unless
2770b57cec5SDimitry Andric   /// MergeFunctionsPDI holds) replace direct uses of G with bitcast(F),
2780b57cec5SDimitry Andric   /// delete G.
2790b57cec5SDimitry Andric   void writeThunk(Function *F, Function *G);
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   // Replace G with an alias to F (deleting function G)
2820b57cec5SDimitry Andric   void writeAlias(Function *F, Function *G);
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric   // Replace G with an alias to F if possible, or a thunk to F if possible.
2850b57cec5SDimitry Andric   // Returns false if neither is the case.
2860b57cec5SDimitry Andric   bool writeThunkOrAlias(Function *F, Function *G);
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric   /// Replace function F with function G in the function tree.
2890b57cec5SDimitry Andric   void replaceFunctionInTree(const FunctionNode &FN, Function *G);
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   /// The set of all distinct functions. Use the insert() and remove() methods
2920b57cec5SDimitry Andric   /// to modify it. The map allows efficient lookup and deferring of Functions.
2930b57cec5SDimitry Andric   FnTreeType FnTree;
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   // Map functions to the iterators of the FunctionNode which contains them
2960b57cec5SDimitry Andric   // in the FnTree. This must be updated carefully whenever the FnTree is
2970b57cec5SDimitry Andric   // modified, i.e. in insert(), remove(), and replaceFunctionInTree(), to avoid
2980b57cec5SDimitry Andric   // dangling iterators into FnTree. The invariant that preserves this is that
2990b57cec5SDimitry Andric   // there is exactly one mapping F -> FN for each FunctionNode FN in FnTree.
3000b57cec5SDimitry Andric   DenseMap<AssertingVH<Function>, FnTreeType::iterator> FNodesInTree;
3010b57cec5SDimitry Andric };
3020b57cec5SDimitry Andric } // end anonymous namespace
3030b57cec5SDimitry Andric 
304480093f4SDimitry Andric PreservedAnalyses MergeFunctionsPass::run(Module &M,
305480093f4SDimitry Andric                                           ModuleAnalysisManager &AM) {
306480093f4SDimitry Andric   MergeFunctions MF;
307480093f4SDimitry Andric   if (!MF.runOnModule(M))
308480093f4SDimitry Andric     return PreservedAnalyses::all();
309480093f4SDimitry Andric   return PreservedAnalyses::none();
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric #ifndef NDEBUG
31381ad6265SDimitry Andric bool MergeFunctions::doFunctionalCheck(std::vector<WeakTrackingVH> &Worklist) {
31481ad6265SDimitry Andric   if (const unsigned Max = NumFunctionsForVerificationCheck) {
3150b57cec5SDimitry Andric     unsigned TripleNumber = 0;
3160b57cec5SDimitry Andric     bool Valid = true;
3170b57cec5SDimitry Andric 
31881ad6265SDimitry Andric     dbgs() << "MERGEFUNC-VERIFY: Started for first " << Max << " functions.\n";
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric     unsigned i = 0;
3210b57cec5SDimitry Andric     for (std::vector<WeakTrackingVH>::iterator I = Worklist.begin(),
3220b57cec5SDimitry Andric                                                E = Worklist.end();
3230b57cec5SDimitry Andric          I != E && i < Max; ++I, ++i) {
3240b57cec5SDimitry Andric       unsigned j = i;
3250b57cec5SDimitry Andric       for (std::vector<WeakTrackingVH>::iterator J = I; J != E && j < Max;
3260b57cec5SDimitry Andric            ++J, ++j) {
3270b57cec5SDimitry Andric         Function *F1 = cast<Function>(*I);
3280b57cec5SDimitry Andric         Function *F2 = cast<Function>(*J);
3290b57cec5SDimitry Andric         int Res1 = FunctionComparator(F1, F2, &GlobalNumbers).compare();
3300b57cec5SDimitry Andric         int Res2 = FunctionComparator(F2, F1, &GlobalNumbers).compare();
3310b57cec5SDimitry Andric 
3320b57cec5SDimitry Andric         // If F1 <= F2, then F2 >= F1, otherwise report failure.
3330b57cec5SDimitry Andric         if (Res1 != -Res2) {
33481ad6265SDimitry Andric           dbgs() << "MERGEFUNC-VERIFY: Non-symmetric; triple: " << TripleNumber
3350b57cec5SDimitry Andric                  << "\n";
3360b57cec5SDimitry Andric           dbgs() << *F1 << '\n' << *F2 << '\n';
3370b57cec5SDimitry Andric           Valid = false;
3380b57cec5SDimitry Andric         }
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric         if (Res1 == 0)
3410b57cec5SDimitry Andric           continue;
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric         unsigned k = j;
3440b57cec5SDimitry Andric         for (std::vector<WeakTrackingVH>::iterator K = J; K != E && k < Max;
3450b57cec5SDimitry Andric              ++k, ++K, ++TripleNumber) {
3460b57cec5SDimitry Andric           if (K == J)
3470b57cec5SDimitry Andric             continue;
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric           Function *F3 = cast<Function>(*K);
3500b57cec5SDimitry Andric           int Res3 = FunctionComparator(F1, F3, &GlobalNumbers).compare();
3510b57cec5SDimitry Andric           int Res4 = FunctionComparator(F2, F3, &GlobalNumbers).compare();
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric           bool Transitive = true;
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric           if (Res1 != 0 && Res1 == Res4) {
3560b57cec5SDimitry Andric             // F1 > F2, F2 > F3 => F1 > F3
3570b57cec5SDimitry Andric             Transitive = Res3 == Res1;
3580b57cec5SDimitry Andric           } else if (Res3 != 0 && Res3 == -Res4) {
3590b57cec5SDimitry Andric             // F1 > F3, F3 > F2 => F1 > F2
3600b57cec5SDimitry Andric             Transitive = Res3 == Res1;
3610b57cec5SDimitry Andric           } else if (Res4 != 0 && -Res3 == Res4) {
3620b57cec5SDimitry Andric             // F2 > F3, F3 > F1 => F2 > F1
3630b57cec5SDimitry Andric             Transitive = Res4 == -Res1;
3640b57cec5SDimitry Andric           }
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric           if (!Transitive) {
36781ad6265SDimitry Andric             dbgs() << "MERGEFUNC-VERIFY: Non-transitive; triple: "
3680b57cec5SDimitry Andric                    << TripleNumber << "\n";
3690b57cec5SDimitry Andric             dbgs() << "Res1, Res3, Res4: " << Res1 << ", " << Res3 << ", "
3700b57cec5SDimitry Andric                    << Res4 << "\n";
3710b57cec5SDimitry Andric             dbgs() << *F1 << '\n' << *F2 << '\n' << *F3 << '\n';
3720b57cec5SDimitry Andric             Valid = false;
3730b57cec5SDimitry Andric           }
3740b57cec5SDimitry Andric         }
3750b57cec5SDimitry Andric       }
3760b57cec5SDimitry Andric     }
3770b57cec5SDimitry Andric 
37881ad6265SDimitry Andric     dbgs() << "MERGEFUNC-VERIFY: " << (Valid ? "Passed." : "Failed.") << "\n";
3790b57cec5SDimitry Andric     return Valid;
3800b57cec5SDimitry Andric   }
3810b57cec5SDimitry Andric   return true;
3820b57cec5SDimitry Andric }
3830b57cec5SDimitry Andric #endif
3840b57cec5SDimitry Andric 
3855f757f3fSDimitry Andric /// Check whether \p F has an intrinsic which references
3865f757f3fSDimitry Andric /// distinct metadata as an operand. The most common
3875f757f3fSDimitry Andric /// instance of this would be CFI checks for function-local types.
3885f757f3fSDimitry Andric static bool hasDistinctMetadataIntrinsic(const Function &F) {
3895f757f3fSDimitry Andric   for (const BasicBlock &BB : F) {
3905f757f3fSDimitry Andric     for (const Instruction &I : BB.instructionsWithoutDebug()) {
3915f757f3fSDimitry Andric       if (!isa<IntrinsicInst>(&I))
3925f757f3fSDimitry Andric         continue;
3935f757f3fSDimitry Andric 
3945f757f3fSDimitry Andric       for (Value *Op : I.operands()) {
3955f757f3fSDimitry Andric         auto *MDL = dyn_cast<MetadataAsValue>(Op);
3965f757f3fSDimitry Andric         if (!MDL)
3975f757f3fSDimitry Andric           continue;
3985f757f3fSDimitry Andric         if (MDNode *N = dyn_cast<MDNode>(MDL->getMetadata()))
3995f757f3fSDimitry Andric           if (N->isDistinct())
4005f757f3fSDimitry Andric             return true;
4015f757f3fSDimitry Andric       }
4025f757f3fSDimitry Andric     }
4035f757f3fSDimitry Andric   }
4045f757f3fSDimitry Andric   return false;
4055f757f3fSDimitry Andric }
4065f757f3fSDimitry Andric 
4070b57cec5SDimitry Andric /// Check whether \p F is eligible for function merging.
4080b57cec5SDimitry Andric static bool isEligibleForMerging(Function &F) {
4095f757f3fSDimitry Andric   return !F.isDeclaration() && !F.hasAvailableExternallyLinkage() &&
4105f757f3fSDimitry Andric          !hasDistinctMetadataIntrinsic(F);
4110b57cec5SDimitry Andric }
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric bool MergeFunctions::runOnModule(Module &M) {
4140b57cec5SDimitry Andric   bool Changed = false;
4150b57cec5SDimitry Andric 
41681ad6265SDimitry Andric   SmallVector<GlobalValue *, 4> UsedV;
41781ad6265SDimitry Andric   collectUsedGlobalVariables(M, UsedV, /*CompilerUsed=*/false);
41881ad6265SDimitry Andric   collectUsedGlobalVariables(M, UsedV, /*CompilerUsed=*/true);
41981ad6265SDimitry Andric   Used.insert(UsedV.begin(), UsedV.end());
42081ad6265SDimitry Andric 
4210b57cec5SDimitry Andric   // All functions in the module, ordered by hash. Functions with a unique
4220b57cec5SDimitry Andric   // hash value are easily eliminated.
4235f757f3fSDimitry Andric   std::vector<std::pair<IRHash, Function *>> HashedFuncs;
4240b57cec5SDimitry Andric   for (Function &Func : M) {
4250b57cec5SDimitry Andric     if (isEligibleForMerging(Func)) {
4265f757f3fSDimitry Andric       HashedFuncs.push_back({StructuralHash(Func), &Func});
4270b57cec5SDimitry Andric     }
4280b57cec5SDimitry Andric   }
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric   llvm::stable_sort(HashedFuncs, less_first());
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric   auto S = HashedFuncs.begin();
4330b57cec5SDimitry Andric   for (auto I = HashedFuncs.begin(), IE = HashedFuncs.end(); I != IE; ++I) {
4340b57cec5SDimitry Andric     // If the hash value matches the previous value or the next one, we must
4350b57cec5SDimitry Andric     // consider merging it. Otherwise it is dropped and never considered again.
4360b57cec5SDimitry Andric     if ((I != S && std::prev(I)->first == I->first) ||
4370b57cec5SDimitry Andric         (std::next(I) != IE && std::next(I)->first == I->first) ) {
4380b57cec5SDimitry Andric       Deferred.push_back(WeakTrackingVH(I->second));
4390b57cec5SDimitry Andric     }
4400b57cec5SDimitry Andric   }
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   do {
4430b57cec5SDimitry Andric     std::vector<WeakTrackingVH> Worklist;
4440b57cec5SDimitry Andric     Deferred.swap(Worklist);
4450b57cec5SDimitry Andric 
44681ad6265SDimitry Andric     LLVM_DEBUG(doFunctionalCheck(Worklist));
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "size of module: " << M.size() << '\n');
4490b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n');
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric     // Insert functions and merge them.
4520b57cec5SDimitry Andric     for (WeakTrackingVH &I : Worklist) {
4530b57cec5SDimitry Andric       if (!I)
4540b57cec5SDimitry Andric         continue;
4550b57cec5SDimitry Andric       Function *F = cast<Function>(I);
4560b57cec5SDimitry Andric       if (!F->isDeclaration() && !F->hasAvailableExternallyLinkage()) {
4570b57cec5SDimitry Andric         Changed |= insert(F);
4580b57cec5SDimitry Andric       }
4590b57cec5SDimitry Andric     }
4600b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "size of FnTree: " << FnTree.size() << '\n');
4610b57cec5SDimitry Andric   } while (!Deferred.empty());
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric   FnTree.clear();
4640b57cec5SDimitry Andric   FNodesInTree.clear();
4650b57cec5SDimitry Andric   GlobalNumbers.clear();
46681ad6265SDimitry Andric   Used.clear();
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   return Changed;
4690b57cec5SDimitry Andric }
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric // Replace direct callers of Old with New.
4720b57cec5SDimitry Andric void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) {
473349cc55cSDimitry Andric   for (Use &U : llvm::make_early_inc_range(Old->uses())) {
474349cc55cSDimitry Andric     CallBase *CB = dyn_cast<CallBase>(U.getUser());
475349cc55cSDimitry Andric     if (CB && CB->isCallee(&U)) {
476480093f4SDimitry Andric       // Do not copy attributes from the called function to the call-site.
477480093f4SDimitry Andric       // Function comparison ensures that the attributes are the same up to
478480093f4SDimitry Andric       // type congruences in byval(), in which case we need to keep the byval
479480093f4SDimitry Andric       // type of the call-site, not the callee function.
4805ffd83dbSDimitry Andric       remove(CB->getFunction());
4815f757f3fSDimitry Andric       U.set(New);
4820b57cec5SDimitry Andric     }
4830b57cec5SDimitry Andric   }
4840b57cec5SDimitry Andric }
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric // Helper for writeThunk,
4870b57cec5SDimitry Andric // Selects proper bitcast operation,
4880b57cec5SDimitry Andric // but a bit simpler then CastInst::getCastOpcode.
4890b57cec5SDimitry Andric static Value *createCast(IRBuilder<> &Builder, Value *V, Type *DestTy) {
4900b57cec5SDimitry Andric   Type *SrcTy = V->getType();
4910b57cec5SDimitry Andric   if (SrcTy->isStructTy()) {
4920b57cec5SDimitry Andric     assert(DestTy->isStructTy());
4930b57cec5SDimitry Andric     assert(SrcTy->getStructNumElements() == DestTy->getStructNumElements());
49481ad6265SDimitry Andric     Value *Result = PoisonValue::get(DestTy);
4950b57cec5SDimitry Andric     for (unsigned int I = 0, E = SrcTy->getStructNumElements(); I < E; ++I) {
496bdd1243dSDimitry Andric       Value *Element =
497bdd1243dSDimitry Andric           createCast(Builder, Builder.CreateExtractValue(V, ArrayRef(I)),
4980b57cec5SDimitry Andric                      DestTy->getStructElementType(I));
4990b57cec5SDimitry Andric 
500bdd1243dSDimitry Andric       Result = Builder.CreateInsertValue(Result, Element, ArrayRef(I));
5010b57cec5SDimitry Andric     }
5020b57cec5SDimitry Andric     return Result;
5030b57cec5SDimitry Andric   }
5040b57cec5SDimitry Andric   assert(!DestTy->isStructTy());
5050b57cec5SDimitry Andric   if (SrcTy->isIntegerTy() && DestTy->isPointerTy())
5060b57cec5SDimitry Andric     return Builder.CreateIntToPtr(V, DestTy);
5070b57cec5SDimitry Andric   else if (SrcTy->isPointerTy() && DestTy->isIntegerTy())
5080b57cec5SDimitry Andric     return Builder.CreatePtrToInt(V, DestTy);
5090b57cec5SDimitry Andric   else
5100b57cec5SDimitry Andric     return Builder.CreateBitCast(V, DestTy);
5110b57cec5SDimitry Andric }
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric // Erase the instructions in PDIUnrelatedWL as they are unrelated to the
5140b57cec5SDimitry Andric // parameter debug info, from the entry block.
5150b57cec5SDimitry Andric void MergeFunctions::eraseInstsUnrelatedToPDI(
516*0fca6ea1SDimitry Andric     std::vector<Instruction *> &PDIUnrelatedWL,
517*0fca6ea1SDimitry Andric     std::vector<DbgVariableRecord *> &PDVRUnrelatedWL) {
5180b57cec5SDimitry Andric   LLVM_DEBUG(
5190b57cec5SDimitry Andric       dbgs() << " Erasing instructions (in reverse order of appearance in "
5200b57cec5SDimitry Andric                 "entry block) unrelated to parameter debug info from entry "
5210b57cec5SDimitry Andric                 "block: {\n");
5220b57cec5SDimitry Andric   while (!PDIUnrelatedWL.empty()) {
5230b57cec5SDimitry Andric     Instruction *I = PDIUnrelatedWL.back();
5240b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "  Deleting Instruction: ");
5250b57cec5SDimitry Andric     LLVM_DEBUG(I->print(dbgs()));
5260b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\n");
5270b57cec5SDimitry Andric     I->eraseFromParent();
5280b57cec5SDimitry Andric     PDIUnrelatedWL.pop_back();
5290b57cec5SDimitry Andric   }
530*0fca6ea1SDimitry Andric 
531*0fca6ea1SDimitry Andric   while (!PDVRUnrelatedWL.empty()) {
532*0fca6ea1SDimitry Andric     DbgVariableRecord *DVR = PDVRUnrelatedWL.back();
533*0fca6ea1SDimitry Andric     LLVM_DEBUG(dbgs() << "  Deleting DbgVariableRecord ");
534*0fca6ea1SDimitry Andric     LLVM_DEBUG(DVR->print(dbgs()));
535*0fca6ea1SDimitry Andric     LLVM_DEBUG(dbgs() << "\n");
536*0fca6ea1SDimitry Andric     DVR->eraseFromParent();
537*0fca6ea1SDimitry Andric     PDVRUnrelatedWL.pop_back();
538*0fca6ea1SDimitry Andric   }
539*0fca6ea1SDimitry Andric 
5400b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << " } // Done erasing instructions unrelated to parameter "
5410b57cec5SDimitry Andric                        "debug info from entry block. \n");
5420b57cec5SDimitry Andric }
5430b57cec5SDimitry Andric 
5440b57cec5SDimitry Andric // Reduce G to its entry block.
5450b57cec5SDimitry Andric void MergeFunctions::eraseTail(Function *G) {
5460b57cec5SDimitry Andric   std::vector<BasicBlock *> WorklistBB;
547fe6060f1SDimitry Andric   for (BasicBlock &BB : drop_begin(*G)) {
548fe6060f1SDimitry Andric     BB.dropAllReferences();
549fe6060f1SDimitry Andric     WorklistBB.push_back(&BB);
5500b57cec5SDimitry Andric   }
5510b57cec5SDimitry Andric   while (!WorklistBB.empty()) {
5520b57cec5SDimitry Andric     BasicBlock *BB = WorklistBB.back();
5530b57cec5SDimitry Andric     BB->eraseFromParent();
5540b57cec5SDimitry Andric     WorklistBB.pop_back();
5550b57cec5SDimitry Andric   }
5560b57cec5SDimitry Andric }
5570b57cec5SDimitry Andric 
5580b57cec5SDimitry Andric // We are interested in the following instructions from the entry block as being
5590b57cec5SDimitry Andric // related to parameter debug info:
5600b57cec5SDimitry Andric // - @llvm.dbg.declare
5610b57cec5SDimitry Andric // - stores from the incoming parameters to locations on the stack-frame
5620b57cec5SDimitry Andric // - allocas that create these locations on the stack-frame
5630b57cec5SDimitry Andric // - @llvm.dbg.value
5640b57cec5SDimitry Andric // - the entry block's terminator
5650b57cec5SDimitry Andric // The rest are unrelated to debug info for the parameters; fill up
5660b57cec5SDimitry Andric // PDIUnrelatedWL with such instructions.
5670b57cec5SDimitry Andric void MergeFunctions::filterInstsUnrelatedToPDI(
568*0fca6ea1SDimitry Andric     BasicBlock *GEntryBlock, std::vector<Instruction *> &PDIUnrelatedWL,
569*0fca6ea1SDimitry Andric     std::vector<DbgVariableRecord *> &PDVRUnrelatedWL) {
5700b57cec5SDimitry Andric   std::set<Instruction *> PDIRelated;
571*0fca6ea1SDimitry Andric   std::set<DbgVariableRecord *> PDVRRelated;
572*0fca6ea1SDimitry Andric 
573*0fca6ea1SDimitry Andric   // Work out whether a dbg.value intrinsic or an equivalent DbgVariableRecord
574*0fca6ea1SDimitry Andric   // is a parameter to be preserved.
575*0fca6ea1SDimitry Andric   auto ExamineDbgValue = [](auto *DbgVal, auto &Container) {
5760b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << " Deciding: ");
577*0fca6ea1SDimitry Andric     LLVM_DEBUG(DbgVal->print(dbgs()));
5780b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\n");
579*0fca6ea1SDimitry Andric     DILocalVariable *DILocVar = DbgVal->getVariable();
5800b57cec5SDimitry Andric     if (DILocVar->isParameter()) {
5810b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "  Include (parameter): ");
582*0fca6ea1SDimitry Andric       LLVM_DEBUG(DbgVal->print(dbgs()));
5830b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\n");
584*0fca6ea1SDimitry Andric       Container.insert(DbgVal);
5850b57cec5SDimitry Andric     } else {
5860b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "  Delete (!parameter): ");
587*0fca6ea1SDimitry Andric       LLVM_DEBUG(DbgVal->print(dbgs()));
5880b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\n");
5890b57cec5SDimitry Andric     }
590*0fca6ea1SDimitry Andric   };
591*0fca6ea1SDimitry Andric 
592*0fca6ea1SDimitry Andric   auto ExamineDbgDeclare = [&PDIRelated](auto *DbgDecl, auto &Container) {
5930b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << " Deciding: ");
594*0fca6ea1SDimitry Andric     LLVM_DEBUG(DbgDecl->print(dbgs()));
5950b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "\n");
596*0fca6ea1SDimitry Andric     DILocalVariable *DILocVar = DbgDecl->getVariable();
5970b57cec5SDimitry Andric     if (DILocVar->isParameter()) {
5980b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "  Parameter: ");
5990b57cec5SDimitry Andric       LLVM_DEBUG(DILocVar->print(dbgs()));
600*0fca6ea1SDimitry Andric       AllocaInst *AI = dyn_cast_or_null<AllocaInst>(DbgDecl->getAddress());
6010b57cec5SDimitry Andric       if (AI) {
6020b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "  Processing alloca users: ");
6030b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "\n");
6040b57cec5SDimitry Andric         for (User *U : AI->users()) {
6050b57cec5SDimitry Andric           if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
6060b57cec5SDimitry Andric             if (Value *Arg = SI->getValueOperand()) {
607fe6060f1SDimitry Andric               if (isa<Argument>(Arg)) {
6080b57cec5SDimitry Andric                 LLVM_DEBUG(dbgs() << "  Include: ");
6090b57cec5SDimitry Andric                 LLVM_DEBUG(AI->print(dbgs()));
6100b57cec5SDimitry Andric                 LLVM_DEBUG(dbgs() << "\n");
6110b57cec5SDimitry Andric                 PDIRelated.insert(AI);
6120b57cec5SDimitry Andric                 LLVM_DEBUG(dbgs() << "   Include (parameter): ");
6130b57cec5SDimitry Andric                 LLVM_DEBUG(SI->print(dbgs()));
6140b57cec5SDimitry Andric                 LLVM_DEBUG(dbgs() << "\n");
6150b57cec5SDimitry Andric                 PDIRelated.insert(SI);
6160b57cec5SDimitry Andric                 LLVM_DEBUG(dbgs() << "  Include: ");
617*0fca6ea1SDimitry Andric                 LLVM_DEBUG(DbgDecl->print(dbgs()));
6180b57cec5SDimitry Andric                 LLVM_DEBUG(dbgs() << "\n");
619*0fca6ea1SDimitry Andric                 Container.insert(DbgDecl);
6200b57cec5SDimitry Andric               } else {
6210b57cec5SDimitry Andric                 LLVM_DEBUG(dbgs() << "   Delete (!parameter): ");
6220b57cec5SDimitry Andric                 LLVM_DEBUG(SI->print(dbgs()));
6230b57cec5SDimitry Andric                 LLVM_DEBUG(dbgs() << "\n");
6240b57cec5SDimitry Andric               }
6250b57cec5SDimitry Andric             }
6260b57cec5SDimitry Andric           } else {
6270b57cec5SDimitry Andric             LLVM_DEBUG(dbgs() << "   Defer: ");
6280b57cec5SDimitry Andric             LLVM_DEBUG(U->print(dbgs()));
6290b57cec5SDimitry Andric             LLVM_DEBUG(dbgs() << "\n");
6300b57cec5SDimitry Andric           }
6310b57cec5SDimitry Andric         }
6320b57cec5SDimitry Andric       } else {
6330b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "  Delete (alloca NULL): ");
634*0fca6ea1SDimitry Andric         LLVM_DEBUG(DbgDecl->print(dbgs()));
6350b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "\n");
6360b57cec5SDimitry Andric       }
6370b57cec5SDimitry Andric     } else {
6380b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "  Delete (!parameter): ");
639*0fca6ea1SDimitry Andric       LLVM_DEBUG(DbgDecl->print(dbgs()));
6400b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\n");
6410b57cec5SDimitry Andric     }
642*0fca6ea1SDimitry Andric   };
643*0fca6ea1SDimitry Andric 
644*0fca6ea1SDimitry Andric   for (BasicBlock::iterator BI = GEntryBlock->begin(), BIE = GEntryBlock->end();
645*0fca6ea1SDimitry Andric        BI != BIE; ++BI) {
646*0fca6ea1SDimitry Andric     // Examine DbgVariableRecords as they happen "before" the instruction. Are
647*0fca6ea1SDimitry Andric     // they connected to parameters?
648*0fca6ea1SDimitry Andric     for (DbgVariableRecord &DVR : filterDbgVars(BI->getDbgRecordRange())) {
649*0fca6ea1SDimitry Andric       if (DVR.isDbgValue() || DVR.isDbgAssign()) {
650*0fca6ea1SDimitry Andric         ExamineDbgValue(&DVR, PDVRRelated);
651*0fca6ea1SDimitry Andric       } else {
652*0fca6ea1SDimitry Andric         assert(DVR.isDbgDeclare());
653*0fca6ea1SDimitry Andric         ExamineDbgDeclare(&DVR, PDVRRelated);
654*0fca6ea1SDimitry Andric       }
655*0fca6ea1SDimitry Andric     }
656*0fca6ea1SDimitry Andric 
657*0fca6ea1SDimitry Andric     if (auto *DVI = dyn_cast<DbgValueInst>(&*BI)) {
658*0fca6ea1SDimitry Andric       ExamineDbgValue(DVI, PDIRelated);
659*0fca6ea1SDimitry Andric     } else if (auto *DDI = dyn_cast<DbgDeclareInst>(&*BI)) {
660*0fca6ea1SDimitry Andric       ExamineDbgDeclare(DDI, PDIRelated);
6610b57cec5SDimitry Andric     } else if (BI->isTerminator() && &*BI == GEntryBlock->getTerminator()) {
6620b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << " Will Include Terminator: ");
6630b57cec5SDimitry Andric       LLVM_DEBUG(BI->print(dbgs()));
6640b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\n");
6650b57cec5SDimitry Andric       PDIRelated.insert(&*BI);
6660b57cec5SDimitry Andric     } else {
6670b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << " Defer: ");
6680b57cec5SDimitry Andric       LLVM_DEBUG(BI->print(dbgs()));
6690b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\n");
6700b57cec5SDimitry Andric     }
6710b57cec5SDimitry Andric   }
6720b57cec5SDimitry Andric   LLVM_DEBUG(
6730b57cec5SDimitry Andric       dbgs()
6740b57cec5SDimitry Andric       << " Report parameter debug info related/related instructions: {\n");
675*0fca6ea1SDimitry Andric 
676*0fca6ea1SDimitry Andric   auto IsPDIRelated = [](auto *Rec, auto &Container, auto &UnrelatedCont) {
677*0fca6ea1SDimitry Andric     if (Container.find(Rec) == Container.end()) {
6780b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "  !PDIRelated: ");
679*0fca6ea1SDimitry Andric       LLVM_DEBUG(Rec->print(dbgs()));
6800b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\n");
681*0fca6ea1SDimitry Andric       UnrelatedCont.push_back(Rec);
6820b57cec5SDimitry Andric     } else {
6830b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "   PDIRelated: ");
684*0fca6ea1SDimitry Andric       LLVM_DEBUG(Rec->print(dbgs()));
6850b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "\n");
6860b57cec5SDimitry Andric     }
687*0fca6ea1SDimitry Andric   };
688*0fca6ea1SDimitry Andric 
689*0fca6ea1SDimitry Andric   // Collect the set of unrelated instructions and debug records.
690*0fca6ea1SDimitry Andric   for (Instruction &I : *GEntryBlock) {
691*0fca6ea1SDimitry Andric     for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
692*0fca6ea1SDimitry Andric       IsPDIRelated(&DVR, PDVRRelated, PDVRUnrelatedWL);
693*0fca6ea1SDimitry Andric     IsPDIRelated(&I, PDIRelated, PDIUnrelatedWL);
6940b57cec5SDimitry Andric   }
6950b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << " }\n");
6960b57cec5SDimitry Andric }
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric /// Whether this function may be replaced by a forwarding thunk.
6990b57cec5SDimitry Andric static bool canCreateThunkFor(Function *F) {
7000b57cec5SDimitry Andric   if (F->isVarArg())
7010b57cec5SDimitry Andric     return false;
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric   // Don't merge tiny functions using a thunk, since it can just end up
7040b57cec5SDimitry Andric   // making the function larger.
7050b57cec5SDimitry Andric   if (F->size() == 1) {
7065f757f3fSDimitry Andric     if (F->front().sizeWithoutDebug() < 2) {
7070b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "canCreateThunkFor: " << F->getName()
7080b57cec5SDimitry Andric                         << " is too small to bother creating a thunk for\n");
7090b57cec5SDimitry Andric       return false;
7100b57cec5SDimitry Andric     }
7110b57cec5SDimitry Andric   }
7120b57cec5SDimitry Andric   return true;
7130b57cec5SDimitry Andric }
7140b57cec5SDimitry Andric 
715*0fca6ea1SDimitry Andric /// Copy all metadata of a specific kind from one function to another.
716*0fca6ea1SDimitry Andric static void copyMetadataIfPresent(Function *From, Function *To,
717*0fca6ea1SDimitry Andric                                   StringRef Kind) {
718*0fca6ea1SDimitry Andric   SmallVector<MDNode *, 4> MDs;
719*0fca6ea1SDimitry Andric   From->getMetadata(Kind, MDs);
720*0fca6ea1SDimitry Andric   for (MDNode *MD : MDs)
721*0fca6ea1SDimitry Andric     To->addMetadata(Kind, *MD);
7225f757f3fSDimitry Andric }
7235f757f3fSDimitry Andric 
7240b57cec5SDimitry Andric // Replace G with a simple tail call to bitcast(F). Also (unless
7250b57cec5SDimitry Andric // MergeFunctionsPDI holds) replace direct uses of G with bitcast(F),
7260b57cec5SDimitry Andric // delete G. Under MergeFunctionsPDI, we use G itself for creating
7270b57cec5SDimitry Andric // the thunk as we preserve the debug info (and associated instructions)
7280b57cec5SDimitry Andric // from G's entry block pertaining to G's incoming arguments which are
7290b57cec5SDimitry Andric // passed on as corresponding arguments in the call that G makes to F.
7300b57cec5SDimitry Andric // For better debugability, under MergeFunctionsPDI, we do not modify G's
7310b57cec5SDimitry Andric // call sites to point to F even when within the same translation unit.
7320b57cec5SDimitry Andric void MergeFunctions::writeThunk(Function *F, Function *G) {
7330b57cec5SDimitry Andric   BasicBlock *GEntryBlock = nullptr;
7340b57cec5SDimitry Andric   std::vector<Instruction *> PDIUnrelatedWL;
735*0fca6ea1SDimitry Andric   std::vector<DbgVariableRecord *> PDVRUnrelatedWL;
7360b57cec5SDimitry Andric   BasicBlock *BB = nullptr;
7370b57cec5SDimitry Andric   Function *NewG = nullptr;
7380b57cec5SDimitry Andric   if (MergeFunctionsPDI) {
7390b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "writeThunk: (MergeFunctionsPDI) Do not create a new "
7400b57cec5SDimitry Andric                          "function as thunk; retain original: "
7410b57cec5SDimitry Andric                       << G->getName() << "()\n");
7420b57cec5SDimitry Andric     GEntryBlock = &G->getEntryBlock();
7430b57cec5SDimitry Andric     LLVM_DEBUG(
7440b57cec5SDimitry Andric         dbgs() << "writeThunk: (MergeFunctionsPDI) filter parameter related "
7450b57cec5SDimitry Andric                   "debug info for "
7460b57cec5SDimitry Andric                << G->getName() << "() {\n");
747*0fca6ea1SDimitry Andric     filterInstsUnrelatedToPDI(GEntryBlock, PDIUnrelatedWL, PDVRUnrelatedWL);
7480b57cec5SDimitry Andric     GEntryBlock->getTerminator()->eraseFromParent();
7490b57cec5SDimitry Andric     BB = GEntryBlock;
7500b57cec5SDimitry Andric   } else {
7510b57cec5SDimitry Andric     NewG = Function::Create(G->getFunctionType(), G->getLinkage(),
7520b57cec5SDimitry Andric                             G->getAddressSpace(), "", G->getParent());
7530b57cec5SDimitry Andric     NewG->setComdat(G->getComdat());
754*0fca6ea1SDimitry Andric     NewG->IsNewDbgInfoFormat = G->IsNewDbgInfoFormat;
7550b57cec5SDimitry Andric     BB = BasicBlock::Create(F->getContext(), "", NewG);
7560b57cec5SDimitry Andric   }
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric   IRBuilder<> Builder(BB);
7590b57cec5SDimitry Andric   Function *H = MergeFunctionsPDI ? G : NewG;
7600b57cec5SDimitry Andric   SmallVector<Value *, 16> Args;
7610b57cec5SDimitry Andric   unsigned i = 0;
7620b57cec5SDimitry Andric   FunctionType *FFTy = F->getFunctionType();
7630b57cec5SDimitry Andric   for (Argument &AI : H->args()) {
7640b57cec5SDimitry Andric     Args.push_back(createCast(Builder, &AI, FFTy->getParamType(i)));
7650b57cec5SDimitry Andric     ++i;
7660b57cec5SDimitry Andric   }
7670b57cec5SDimitry Andric 
7680b57cec5SDimitry Andric   CallInst *CI = Builder.CreateCall(F, Args);
7690b57cec5SDimitry Andric   ReturnInst *RI = nullptr;
770fe6060f1SDimitry Andric   bool isSwiftTailCall = F->getCallingConv() == CallingConv::SwiftTail &&
771fe6060f1SDimitry Andric                          G->getCallingConv() == CallingConv::SwiftTail;
772fe6060f1SDimitry Andric   CI->setTailCallKind(isSwiftTailCall ? llvm::CallInst::TCK_MustTail
773fe6060f1SDimitry Andric                                       : llvm::CallInst::TCK_Tail);
7740b57cec5SDimitry Andric   CI->setCallingConv(F->getCallingConv());
7750b57cec5SDimitry Andric   CI->setAttributes(F->getAttributes());
7760b57cec5SDimitry Andric   if (H->getReturnType()->isVoidTy()) {
7770b57cec5SDimitry Andric     RI = Builder.CreateRetVoid();
7780b57cec5SDimitry Andric   } else {
7790b57cec5SDimitry Andric     RI = Builder.CreateRet(createCast(Builder, CI, H->getReturnType()));
7800b57cec5SDimitry Andric   }
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   if (MergeFunctionsPDI) {
7830b57cec5SDimitry Andric     DISubprogram *DIS = G->getSubprogram();
7840b57cec5SDimitry Andric     if (DIS) {
785e8d8bef9SDimitry Andric       DebugLoc CIDbgLoc =
786e8d8bef9SDimitry Andric           DILocation::get(DIS->getContext(), DIS->getScopeLine(), 0, DIS);
787e8d8bef9SDimitry Andric       DebugLoc RIDbgLoc =
788e8d8bef9SDimitry Andric           DILocation::get(DIS->getContext(), DIS->getScopeLine(), 0, DIS);
7890b57cec5SDimitry Andric       CI->setDebugLoc(CIDbgLoc);
7900b57cec5SDimitry Andric       RI->setDebugLoc(RIDbgLoc);
7910b57cec5SDimitry Andric     } else {
7920b57cec5SDimitry Andric       LLVM_DEBUG(
7930b57cec5SDimitry Andric           dbgs() << "writeThunk: (MergeFunctionsPDI) No DISubprogram for "
7940b57cec5SDimitry Andric                  << G->getName() << "()\n");
7950b57cec5SDimitry Andric     }
7960b57cec5SDimitry Andric     eraseTail(G);
797*0fca6ea1SDimitry Andric     eraseInstsUnrelatedToPDI(PDIUnrelatedWL, PDVRUnrelatedWL);
7980b57cec5SDimitry Andric     LLVM_DEBUG(
7990b57cec5SDimitry Andric         dbgs() << "} // End of parameter related debug info filtering for: "
8000b57cec5SDimitry Andric                << G->getName() << "()\n");
8010b57cec5SDimitry Andric   } else {
8020b57cec5SDimitry Andric     NewG->copyAttributesFrom(G);
8030b57cec5SDimitry Andric     NewG->takeName(G);
8045f757f3fSDimitry Andric     // Ensure CFI type metadata is propagated to the new function.
8055f757f3fSDimitry Andric     copyMetadataIfPresent(G, NewG, "type");
8065f757f3fSDimitry Andric     copyMetadataIfPresent(G, NewG, "kcfi_type");
8070b57cec5SDimitry Andric     removeUsers(G);
8080b57cec5SDimitry Andric     G->replaceAllUsesWith(NewG);
8090b57cec5SDimitry Andric     G->eraseFromParent();
8100b57cec5SDimitry Andric   }
8110b57cec5SDimitry Andric 
8120b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "writeThunk: " << H->getName() << '\n');
8130b57cec5SDimitry Andric   ++NumThunksWritten;
8140b57cec5SDimitry Andric }
8150b57cec5SDimitry Andric 
8160b57cec5SDimitry Andric // Whether this function may be replaced by an alias
8170b57cec5SDimitry Andric static bool canCreateAliasFor(Function *F) {
8180b57cec5SDimitry Andric   if (!MergeFunctionsAliases || !F->hasGlobalUnnamedAddr())
8190b57cec5SDimitry Andric     return false;
8200b57cec5SDimitry Andric 
8210b57cec5SDimitry Andric   // We should only see linkages supported by aliases here
8220b57cec5SDimitry Andric   assert(F->hasLocalLinkage() || F->hasExternalLinkage()
8230b57cec5SDimitry Andric       || F->hasWeakLinkage() || F->hasLinkOnceLinkage());
8240b57cec5SDimitry Andric   return true;
8250b57cec5SDimitry Andric }
8260b57cec5SDimitry Andric 
8270b57cec5SDimitry Andric // Replace G with an alias to F (deleting function G)
8280b57cec5SDimitry Andric void MergeFunctions::writeAlias(Function *F, Function *G) {
8290b57cec5SDimitry Andric   PointerType *PtrType = G->getType();
830fe6060f1SDimitry Andric   auto *GA = GlobalAlias::create(G->getValueType(), PtrType->getAddressSpace(),
8315f757f3fSDimitry Andric                                  G->getLinkage(), "", F, G->getParent());
8320b57cec5SDimitry Andric 
833bdd1243dSDimitry Andric   const MaybeAlign FAlign = F->getAlign();
834bdd1243dSDimitry Andric   const MaybeAlign GAlign = G->getAlign();
835bdd1243dSDimitry Andric   if (FAlign || GAlign)
836bdd1243dSDimitry Andric     F->setAlignment(std::max(FAlign.valueOrOne(), GAlign.valueOrOne()));
837bdd1243dSDimitry Andric   else
838bdd1243dSDimitry Andric     F->setAlignment(std::nullopt);
8390b57cec5SDimitry Andric   GA->takeName(G);
8400b57cec5SDimitry Andric   GA->setVisibility(G->getVisibility());
8410b57cec5SDimitry Andric   GA->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
8420b57cec5SDimitry Andric 
8430b57cec5SDimitry Andric   removeUsers(G);
8440b57cec5SDimitry Andric   G->replaceAllUsesWith(GA);
8450b57cec5SDimitry Andric   G->eraseFromParent();
8460b57cec5SDimitry Andric 
8470b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "writeAlias: " << GA->getName() << '\n');
8480b57cec5SDimitry Andric   ++NumAliasesWritten;
8490b57cec5SDimitry Andric }
8500b57cec5SDimitry Andric 
8510b57cec5SDimitry Andric // Replace G with an alias to F if possible, or a thunk to F if
8520b57cec5SDimitry Andric // profitable. Returns false if neither is the case.
8530b57cec5SDimitry Andric bool MergeFunctions::writeThunkOrAlias(Function *F, Function *G) {
8540b57cec5SDimitry Andric   if (canCreateAliasFor(G)) {
8550b57cec5SDimitry Andric     writeAlias(F, G);
8560b57cec5SDimitry Andric     return true;
8570b57cec5SDimitry Andric   }
8580b57cec5SDimitry Andric   if (canCreateThunkFor(F)) {
8590b57cec5SDimitry Andric     writeThunk(F, G);
8600b57cec5SDimitry Andric     return true;
8610b57cec5SDimitry Andric   }
8620b57cec5SDimitry Andric   return false;
8630b57cec5SDimitry Andric }
8640b57cec5SDimitry Andric 
8650b57cec5SDimitry Andric // Merge two equivalent functions. Upon completion, Function G is deleted.
8660b57cec5SDimitry Andric void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) {
8670b57cec5SDimitry Andric   if (F->isInterposable()) {
8680b57cec5SDimitry Andric     assert(G->isInterposable());
8690b57cec5SDimitry Andric 
8700b57cec5SDimitry Andric     // Both writeThunkOrAlias() calls below must succeed, either because we can
8710b57cec5SDimitry Andric     // create aliases for G and NewF, or because a thunk for F is profitable.
8720b57cec5SDimitry Andric     // F here has the same signature as NewF below, so that's what we check.
8730b57cec5SDimitry Andric     if (!canCreateThunkFor(F) &&
8740b57cec5SDimitry Andric         (!canCreateAliasFor(F) || !canCreateAliasFor(G)))
8750b57cec5SDimitry Andric       return;
8760b57cec5SDimitry Andric 
8770b57cec5SDimitry Andric     // Make them both thunks to the same internal function.
8780b57cec5SDimitry Andric     Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(),
8790b57cec5SDimitry Andric                                       F->getAddressSpace(), "", F->getParent());
8800b57cec5SDimitry Andric     NewF->copyAttributesFrom(F);
8810b57cec5SDimitry Andric     NewF->takeName(F);
882*0fca6ea1SDimitry Andric     NewF->IsNewDbgInfoFormat = F->IsNewDbgInfoFormat;
8835f757f3fSDimitry Andric     // Ensure CFI type metadata is propagated to the new function.
8845f757f3fSDimitry Andric     copyMetadataIfPresent(F, NewF, "type");
8855f757f3fSDimitry Andric     copyMetadataIfPresent(F, NewF, "kcfi_type");
8860b57cec5SDimitry Andric     removeUsers(F);
8870b57cec5SDimitry Andric     F->replaceAllUsesWith(NewF);
8880b57cec5SDimitry Andric 
889bdd1243dSDimitry Andric     // We collect alignment before writeThunkOrAlias that overwrites NewF and
890bdd1243dSDimitry Andric     // G's content.
891bdd1243dSDimitry Andric     const MaybeAlign NewFAlign = NewF->getAlign();
892bdd1243dSDimitry Andric     const MaybeAlign GAlign = G->getAlign();
8930b57cec5SDimitry Andric 
8940b57cec5SDimitry Andric     writeThunkOrAlias(F, G);
8950b57cec5SDimitry Andric     writeThunkOrAlias(F, NewF);
8960b57cec5SDimitry Andric 
897bdd1243dSDimitry Andric     if (NewFAlign || GAlign)
898bdd1243dSDimitry Andric       F->setAlignment(std::max(NewFAlign.valueOrOne(), GAlign.valueOrOne()));
899bdd1243dSDimitry Andric     else
900bdd1243dSDimitry Andric       F->setAlignment(std::nullopt);
9010b57cec5SDimitry Andric     F->setLinkage(GlobalValue::PrivateLinkage);
9020b57cec5SDimitry Andric     ++NumDoubleWeak;
9030b57cec5SDimitry Andric     ++NumFunctionsMerged;
9040b57cec5SDimitry Andric   } else {
9050b57cec5SDimitry Andric     // For better debugability, under MergeFunctionsPDI, we do not modify G's
9060b57cec5SDimitry Andric     // call sites to point to F even when within the same translation unit.
9070b57cec5SDimitry Andric     if (!G->isInterposable() && !MergeFunctionsPDI) {
90881ad6265SDimitry Andric       // Functions referred to by llvm.used/llvm.compiler.used are special:
90981ad6265SDimitry Andric       // there are uses of the symbol name that are not visible to LLVM,
91081ad6265SDimitry Andric       // usually from inline asm.
91181ad6265SDimitry Andric       if (G->hasGlobalUnnamedAddr() && !Used.contains(G)) {
9120b57cec5SDimitry Andric         // G might have been a key in our GlobalNumberState, and it's illegal
9130b57cec5SDimitry Andric         // to replace a key in ValueMap<GlobalValue *> with a non-global.
9140b57cec5SDimitry Andric         GlobalNumbers.erase(G);
9150b57cec5SDimitry Andric         // If G's address is not significant, replace it entirely.
9160b57cec5SDimitry Andric         removeUsers(G);
9175f757f3fSDimitry Andric         G->replaceAllUsesWith(F);
9180b57cec5SDimitry Andric       } else {
9190b57cec5SDimitry Andric         // Redirect direct callers of G to F. (See note on MergeFunctionsPDI
9200b57cec5SDimitry Andric         // above).
9210b57cec5SDimitry Andric         replaceDirectCallers(G, F);
9220b57cec5SDimitry Andric       }
9230b57cec5SDimitry Andric     }
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric     // If G was internal then we may have replaced all uses of G with F. If so,
9260b57cec5SDimitry Andric     // stop here and delete G. There's no need for a thunk. (See note on
9270b57cec5SDimitry Andric     // MergeFunctionsPDI above).
9280b57cec5SDimitry Andric     if (G->isDiscardableIfUnused() && G->use_empty() && !MergeFunctionsPDI) {
9290b57cec5SDimitry Andric       G->eraseFromParent();
9300b57cec5SDimitry Andric       ++NumFunctionsMerged;
9310b57cec5SDimitry Andric       return;
9320b57cec5SDimitry Andric     }
9330b57cec5SDimitry Andric 
9340b57cec5SDimitry Andric     if (writeThunkOrAlias(F, G)) {
9350b57cec5SDimitry Andric       ++NumFunctionsMerged;
9360b57cec5SDimitry Andric     }
9370b57cec5SDimitry Andric   }
9380b57cec5SDimitry Andric }
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric /// Replace function F by function G.
9410b57cec5SDimitry Andric void MergeFunctions::replaceFunctionInTree(const FunctionNode &FN,
9420b57cec5SDimitry Andric                                            Function *G) {
9430b57cec5SDimitry Andric   Function *F = FN.getFunc();
9440b57cec5SDimitry Andric   assert(FunctionComparator(F, G, &GlobalNumbers).compare() == 0 &&
9450b57cec5SDimitry Andric          "The two functions must be equal");
9460b57cec5SDimitry Andric 
9470b57cec5SDimitry Andric   auto I = FNodesInTree.find(F);
9480b57cec5SDimitry Andric   assert(I != FNodesInTree.end() && "F should be in FNodesInTree");
9490b57cec5SDimitry Andric   assert(FNodesInTree.count(G) == 0 && "FNodesInTree should not contain G");
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric   FnTreeType::iterator IterToFNInFnTree = I->second;
9520b57cec5SDimitry Andric   assert(&(*IterToFNInFnTree) == &FN && "F should map to FN in FNodesInTree.");
9530b57cec5SDimitry Andric   // Remove F -> FN and insert G -> FN
9540b57cec5SDimitry Andric   FNodesInTree.erase(I);
9550b57cec5SDimitry Andric   FNodesInTree.insert({G, IterToFNInFnTree});
9560b57cec5SDimitry Andric   // Replace F with G in FN, which is stored inside the FnTree.
9570b57cec5SDimitry Andric   FN.replaceBy(G);
9580b57cec5SDimitry Andric }
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric // Ordering for functions that are equal under FunctionComparator
9610b57cec5SDimitry Andric static bool isFuncOrderCorrect(const Function *F, const Function *G) {
9620b57cec5SDimitry Andric   if (F->isInterposable() != G->isInterposable()) {
9630b57cec5SDimitry Andric     // Strong before weak, because the weak function may call the strong
9640b57cec5SDimitry Andric     // one, but not the other way around.
9650b57cec5SDimitry Andric     return !F->isInterposable();
9660b57cec5SDimitry Andric   }
9670b57cec5SDimitry Andric   if (F->hasLocalLinkage() != G->hasLocalLinkage()) {
9680b57cec5SDimitry Andric     // External before local, because we definitely have to keep the external
9690b57cec5SDimitry Andric     // function, but may be able to drop the local one.
9700b57cec5SDimitry Andric     return !F->hasLocalLinkage();
9710b57cec5SDimitry Andric   }
9720b57cec5SDimitry Andric   // Impose a total order (by name) on the replacement of functions. This is
9730b57cec5SDimitry Andric   // important when operating on more than one module independently to prevent
9740b57cec5SDimitry Andric   // cycles of thunks calling each other when the modules are linked together.
9750b57cec5SDimitry Andric   return F->getName() <= G->getName();
9760b57cec5SDimitry Andric }
9770b57cec5SDimitry Andric 
9780b57cec5SDimitry Andric // Insert a ComparableFunction into the FnTree, or merge it away if equal to one
9790b57cec5SDimitry Andric // that was already inserted.
9800b57cec5SDimitry Andric bool MergeFunctions::insert(Function *NewFunction) {
9810b57cec5SDimitry Andric   std::pair<FnTreeType::iterator, bool> Result =
9820b57cec5SDimitry Andric       FnTree.insert(FunctionNode(NewFunction));
9830b57cec5SDimitry Andric 
9840b57cec5SDimitry Andric   if (Result.second) {
9850b57cec5SDimitry Andric     assert(FNodesInTree.count(NewFunction) == 0);
9860b57cec5SDimitry Andric     FNodesInTree.insert({NewFunction, Result.first});
9870b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Inserting as unique: " << NewFunction->getName()
9880b57cec5SDimitry Andric                       << '\n');
9890b57cec5SDimitry Andric     return false;
9900b57cec5SDimitry Andric   }
9910b57cec5SDimitry Andric 
9920b57cec5SDimitry Andric   const FunctionNode &OldF = *Result.first;
9930b57cec5SDimitry Andric 
9940b57cec5SDimitry Andric   if (!isFuncOrderCorrect(OldF.getFunc(), NewFunction)) {
9950b57cec5SDimitry Andric     // Swap the two functions.
9960b57cec5SDimitry Andric     Function *F = OldF.getFunc();
9970b57cec5SDimitry Andric     replaceFunctionInTree(*Result.first, NewFunction);
9980b57cec5SDimitry Andric     NewFunction = F;
9990b57cec5SDimitry Andric     assert(OldF.getFunc() != F && "Must have swapped the functions.");
10000b57cec5SDimitry Andric   }
10010b57cec5SDimitry Andric 
10020b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "  " << OldF.getFunc()->getName()
10030b57cec5SDimitry Andric                     << " == " << NewFunction->getName() << '\n');
10040b57cec5SDimitry Andric 
10050b57cec5SDimitry Andric   Function *DeleteF = NewFunction;
10060b57cec5SDimitry Andric   mergeTwoFunctions(OldF.getFunc(), DeleteF);
10070b57cec5SDimitry Andric   return true;
10080b57cec5SDimitry Andric }
10090b57cec5SDimitry Andric 
10100b57cec5SDimitry Andric // Remove a function from FnTree. If it was already in FnTree, add
10110b57cec5SDimitry Andric // it to Deferred so that we'll look at it in the next round.
10120b57cec5SDimitry Andric void MergeFunctions::remove(Function *F) {
10130b57cec5SDimitry Andric   auto I = FNodesInTree.find(F);
10140b57cec5SDimitry Andric   if (I != FNodesInTree.end()) {
10150b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Deferred " << F->getName() << ".\n");
10160b57cec5SDimitry Andric     FnTree.erase(I->second);
10170b57cec5SDimitry Andric     // I->second has been invalidated, remove it from the FNodesInTree map to
10180b57cec5SDimitry Andric     // preserve the invariant.
10190b57cec5SDimitry Andric     FNodesInTree.erase(I);
10200b57cec5SDimitry Andric     Deferred.emplace_back(F);
10210b57cec5SDimitry Andric   }
10220b57cec5SDimitry Andric }
10230b57cec5SDimitry Andric 
10240b57cec5SDimitry Andric // For each instruction used by the value, remove() the function that contains
10250b57cec5SDimitry Andric // the instruction. This should happen right before a call to RAUW.
10260b57cec5SDimitry Andric void MergeFunctions::removeUsers(Value *V) {
10270b57cec5SDimitry Andric   for (User *U : V->users())
10280b57cec5SDimitry Andric     if (auto *I = dyn_cast<Instruction>(U))
10290b57cec5SDimitry Andric       remove(I->getFunction());
10300b57cec5SDimitry Andric }
1031