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