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
16namespace llvm {
17class Error;
18class GlobalValue;
19class Metadata;
20class Module;
21class StructType;
22class TrackingMDRef;
23class Type;
24
25class 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
46public:
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
80private:
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