1292915Sdim//===- IRMover.h ------------------------------------------------*- C++ -*-===//
2292915Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6292915Sdim//
7292915Sdim//===----------------------------------------------------------------------===//
8292915Sdim
9292915Sdim#ifndef LLVM_LINKER_IRMOVER_H
10292915Sdim#define LLVM_LINKER_IRMOVER_H
11292915Sdim
12292915Sdim#include "llvm/ADT/ArrayRef.h"
13292915Sdim#include "llvm/ADT/DenseSet.h"
14292915Sdim#include <functional>
15292915Sdim
16292915Sdimnamespace llvm {
17309124Sdimclass Error;
18292915Sdimclass GlobalValue;
19309124Sdimclass Metadata;
20292915Sdimclass Module;
21292915Sdimclass StructType;
22309124Sdimclass TrackingMDRef;
23292915Sdimclass Type;
24292915Sdim
25292915Sdimclass IRMover {
26292915Sdim  struct StructTypeKeyInfo {
27292915Sdim    struct KeyTy {
28292915Sdim      ArrayRef<Type *> ETypes;
29292915Sdim      bool IsPacked;
30292915Sdim      KeyTy(ArrayRef<Type *> E, bool P);
31292915Sdim      KeyTy(const StructType *ST);
32292915Sdim      bool operator==(const KeyTy &that) const;
33292915Sdim      bool operator!=(const KeyTy &that) const;
34292915Sdim    };
35292915Sdim    static StructType *getEmptyKey();
36292915Sdim    static StructType *getTombstoneKey();
37292915Sdim    static unsigned getHashValue(const KeyTy &Key);
38292915Sdim    static unsigned getHashValue(const StructType *ST);
39292915Sdim    static bool isEqual(const KeyTy &LHS, const StructType *RHS);
40292915Sdim    static bool isEqual(const StructType *LHS, const StructType *RHS);
41292915Sdim  };
42292915Sdim
43309124Sdim  /// Type of the Metadata map in \a ValueToValueMapTy.
44309124Sdim  typedef DenseMap<const Metadata *, TrackingMDRef> MDMapT;
45309124Sdim
46292915Sdimpublic:
47292915Sdim  class IdentifiedStructTypeSet {
48292915Sdim    // The set of opaque types is the composite module.
49292915Sdim    DenseSet<StructType *> OpaqueStructTypes;
50292915Sdim
51292915Sdim    // The set of identified but non opaque structures in the composite module.
52292915Sdim    DenseSet<StructType *, StructTypeKeyInfo> NonOpaqueStructTypes;
53292915Sdim
54292915Sdim  public:
55292915Sdim    void addNonOpaque(StructType *Ty);
56292915Sdim    void switchToNonOpaque(StructType *Ty);
57292915Sdim    void addOpaque(StructType *Ty);
58292915Sdim    StructType *findNonOpaque(ArrayRef<Type *> ETypes, bool IsPacked);
59292915Sdim    bool hasType(StructType *Ty);
60292915Sdim  };
61292915Sdim
62292915Sdim  IRMover(Module &M);
63292915Sdim
64292915Sdim  typedef std::function<void(GlobalValue &)> ValueAdder;
65309124Sdim
66309124Sdim  /// Move in the provide values in \p ValuesToLink from \p Src.
67309124Sdim  ///
68309124Sdim  /// - \p AddLazyFor is a call back that the IRMover will call when a global
69309124Sdim  ///   value is referenced by one of the ValuesToLink (transitively) but was
70309124Sdim  ///   not present in ValuesToLink. The GlobalValue and a ValueAdder callback
71309124Sdim  ///   are passed as an argument, and the callback is expected to be called
72309124Sdim  ///   if the GlobalValue needs to be added to the \p ValuesToLink and linked.
73314564Sdim  /// - \p IsPerformingImport is true when this IR link is to perform ThinLTO
74314564Sdim  ///   function importing from Src.
75309124Sdim  Error move(std::unique_ptr<Module> Src, ArrayRef<GlobalValue *> ValuesToLink,
76314564Sdim             std::function<void(GlobalValue &GV, ValueAdder Add)> AddLazyFor,
77321369Sdim             bool IsPerformingImport);
78292915Sdim  Module &getModule() { return Composite; }
79292915Sdim
80292915Sdimprivate:
81292915Sdim  Module &Composite;
82292915Sdim  IdentifiedStructTypeSet IdentifiedStructTypes;
83309124Sdim  MDMapT SharedMDs; ///< A Metadata map to use for all calls to \a move().
84292915Sdim};
85292915Sdim
86292915Sdim} // End llvm namespace
87292915Sdim
88292915Sdim#endif
89