1 //===- IRMover.h ------------------------------------------------*- 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 #ifndef LLVM_LINKER_IRMOVER_H
10 #define LLVM_LINKER_IRMOVER_H
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/DenseSet.h"
14 #include "llvm/ADT/FunctionExtras.h"
15 #include <functional>
16 
17 namespace llvm {
18 class Error;
19 class GlobalValue;
20 class Metadata;
21 class Module;
22 class StructType;
23 class TrackingMDRef;
24 class Type;
25 
26 class IRMover {
27   struct StructTypeKeyInfo {
28     struct KeyTy {
29       ArrayRef<Type *> ETypes;
30       bool IsPacked;
31       KeyTy(ArrayRef<Type *> E, bool P);
32       KeyTy(const StructType *ST);
33       bool operator==(const KeyTy &that) const;
34       bool operator!=(const KeyTy &that) const;
35     };
36     static StructType *getEmptyKey();
37     static StructType *getTombstoneKey();
38     static unsigned getHashValue(const KeyTy &Key);
39     static unsigned getHashValue(const StructType *ST);
40     static bool isEqual(const KeyTy &LHS, const StructType *RHS);
41     static bool isEqual(const StructType *LHS, const StructType *RHS);
42   };
43 
44   /// Type of the Metadata map in \a ValueToValueMapTy.
45   typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT;
46 
47 public:
48   class IdentifiedStructTypeSet {
49     // The set of opaque types is the composite module.
50     DenseSet<StructType *> OpaqueStructTypes;
51 
52     // The set of identified but non opaque structures in the composite module.
53     DenseSet<StructType *, StructTypeKeyInfo> NonOpaqueStructTypes;
54 
55   public:
56     void addNonOpaque(StructType *Ty);
57     void switchToNonOpaque(StructType *Ty);
58     void addOpaque(StructType *Ty);
59     StructType *findNonOpaque(ArrayRef<Type *> ETypes, bool IsPacked);
60     bool hasType(StructType *Ty);
61   };
62 
63   IRMover(Module &M);
64 
65   typedef std::function<void(GlobalValue &)> ValueAdder;
66   using LazyCallback =
67       llvm::unique_function<void(GlobalValue &GV, ValueAdder Add)>;
68 
69   /// Move in the provide values in \p ValuesToLink from \p Src.
70   ///
71   /// - \p AddLazyFor is a call back that the IRMover will call when a global
72   ///   value is referenced by one of the ValuesToLink (transitively) but was
73   ///   not present in ValuesToLink. The GlobalValue and a ValueAdder callback
74   ///   are passed as an argument, and the callback is expected to be called
75   ///   if the GlobalValue needs to be added to the \p ValuesToLink and linked.
76   ///   Pass nullptr if there's no work to be done in such cases.
77   /// - \p IsPerformingImport is true when this IR link is to perform ThinLTO
78   ///   function importing from Src.
79   Error move(std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
80              LazyCallback AddLazyFor, bool IsPerformingImport);
getModule()81   Module &getModule() { return Composite; }
82 
83 private:
84   Module &Composite;
85   IdentifiedStructTypeSet IdentifiedStructTypes;
86   MDMapT SharedMDs; ///< A Metadata map to use for all calls to \a move().
87 };
88 
89 } // End llvm namespace
90 
91 #endif
92