1//===- IRMover.h ------------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_LINKER_IRMOVER_H
11#define LLVM_LINKER_IRMOVER_H
12
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/DenseSet.h"
15#include <functional>
16
17namespace llvm {
18class Error;
19class GlobalValue;
20class Metadata;
21class Module;
22class StructType;
23class TrackingMDRef;
24class Type;
25
26class 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
47public:
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
67  /// Move in the provide values in \p ValuesToLink from \p Src.
68  ///
69  /// - \p AddLazyFor is a call back that the IRMover will call when a global
70  ///   value is referenced by one of the ValuesToLink (transitively) but was
71  ///   not present in ValuesToLink. The GlobalValue and a ValueAdder callback
72  ///   are passed as an argument, and the callback is expected to be called
73  ///   if the GlobalValue needs to be added to the \p ValuesToLink and linked.
74  /// - \p IsPerformingImport is true when this IR link is to perform ThinLTO
75  ///   function importing from Src.
76  Error move(std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
77             std::function<void(GlobalValue &GV, ValueAdder Add)> AddLazyFor,
78             bool IsPerformingImport);
79  Module &getModule() { return Composite; }
80
81private:
82  Module &Composite;
83  IdentifiedStructTypeSet IdentifiedStructTypes;
84  MDMapT SharedMDs; ///< A Metadata map to use for all calls to \a move().
85};
86
87} // End llvm namespace
88
89#endif
90