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