100
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 //===- lib/Linker/IRMover.cpp ---------------------------------------------===//
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 // The LLVM Compiler Infrastructure
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 //
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===//
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 #include "llvm/Linker/IRMover.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 #include "LinkDiagnosticInfo.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 #include "llvm/ADT/SetVector.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13 #include "llvm/ADT/SmallString.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 #include "llvm/ADT/Triple.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 #include "llvm/IR/Constants.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16 #include "llvm/IR/DebugInfo.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 #include "llvm/IR/DiagnosticPrinter.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 #include "llvm/IR/GVMaterializer.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19 #include "llvm/IR/TypeFinder.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
20 #include "llvm/Transforms/Utils/Cloning.h"
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
21 using namespace llvm;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
23 //===----------------------------------------------------------------------===//
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 // TypeMap implementation.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 //===----------------------------------------------------------------------===//
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27 namespace {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
28 class TypeMapTy : public ValueMapTypeRemapper {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
29 /// This is a mapping from a source type to a destination type to use.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
30 DenseMap<Type *, Type *> MappedTypes;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
31
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
32 /// When checking to see if two subgraphs are isomorphic, we speculatively
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
33 /// add types to MappedTypes, but keep track of them here in case we need to
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34 /// roll back.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
35 SmallVector<Type *, 16> SpeculativeTypes;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
37 SmallVector<StructType *, 16> SpeculativeDstOpaqueTypes;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
38
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
39 /// This is a list of non-opaque structs in the source module that are mapped
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
40 /// to an opaque struct in the destination module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
41 SmallVector<StructType *, 16> SrcDefinitionsToResolve;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
42
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
43 /// This is the set of opaque types in the destination modules who are
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
44 /// getting a body from the source module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
45 SmallPtrSet<StructType *, 16> DstResolvedOpaqueTypes;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
46
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
47 public:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
48 TypeMapTy(IRMover::IdentifiedStructTypeSet &DstStructTypesSet)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
49 : DstStructTypesSet(DstStructTypesSet) {}
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
50
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
51 IRMover::IdentifiedStructTypeSet &DstStructTypesSet;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
52 /// Indicate that the specified type in the destination module is conceptually
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
53 /// equivalent to the specified type in the source module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
54 void addTypeMapping(Type *DstTy, Type *SrcTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
55
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
56 /// Produce a body for an opaque type in the dest module from a type
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
57 /// definition in the source module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
58 void linkDefinedTypeBodies();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
59
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
60 /// Return the mapped type to use for the specified input type from the
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
61 /// source module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
62 Type *get(Type *SrcTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
63 Type *get(Type *SrcTy, SmallPtrSet<StructType *, 8> &Visited);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
64
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
65 void finishType(StructType *DTy, StructType *STy, ArrayRef<Type *> ETypes);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
66
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
67 FunctionType *get(FunctionType *T) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
68 return cast<FunctionType>(get((Type *)T));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
69 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
70
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
71 private:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
72 Type *remapType(Type *SrcTy) override { return get(SrcTy); }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
73
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
74 bool areTypesIsomorphic(Type *DstTy, Type *SrcTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
75 };
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
76 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
77
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
78 void TypeMapTy::addTypeMapping(Type *DstTy, Type *SrcTy) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
79 assert(SpeculativeTypes.empty());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
80 assert(SpeculativeDstOpaqueTypes.empty());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
81
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
82 // Check to see if these types are recursively isomorphic and establish a
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
83 // mapping between them if so.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
84 if (!areTypesIsomorphic(DstTy, SrcTy)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
85 // Oops, they aren't isomorphic. Just discard this request by rolling out
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
86 // any speculative mappings we've established.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
87 for (Type *Ty : SpeculativeTypes)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
88 MappedTypes.erase(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
89
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
90 SrcDefinitionsToResolve.resize(SrcDefinitionsToResolve.size() -
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
91 SpeculativeDstOpaqueTypes.size());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
92 for (StructType *Ty : SpeculativeDstOpaqueTypes)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
93 DstResolvedOpaqueTypes.erase(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
94 } else {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
95 for (Type *Ty : SpeculativeTypes)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
96 if (auto *STy = dyn_cast<StructType>(Ty))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
97 if (STy->hasName())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
98 STy->setName("");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
99 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
100 SpeculativeTypes.clear();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
101 SpeculativeDstOpaqueTypes.clear();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
102 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
103
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
104 /// Recursively walk this pair of types, returning true if they are isomorphic,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
105 /// false if they are not.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
106 bool TypeMapTy::areTypesIsomorphic(Type *DstTy, Type *SrcTy) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
107 // Two types with differing kinds are clearly not isomorphic.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
108 if (DstTy->getTypeID() != SrcTy->getTypeID())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
109 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
110
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
111 // If we have an entry in the MappedTypes table, then we have our answer.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
112 Type *&Entry = MappedTypes[SrcTy];
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
113 if (Entry)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
114 return Entry == DstTy;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
115
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
116 // Two identical types are clearly isomorphic. Remember this
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
117 // non-speculatively.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
118 if (DstTy == SrcTy) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
119 Entry = DstTy;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
120 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
121 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
122
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
123 // Okay, we have two types with identical kinds that we haven't seen before.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
124
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
125 // If this is an opaque struct type, special case it.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
126 if (StructType *SSTy = dyn_cast<StructType>(SrcTy)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
127 // Mapping an opaque type to any struct, just keep the dest struct.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
128 if (SSTy->isOpaque()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
129 Entry = DstTy;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
130 SpeculativeTypes.push_back(SrcTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
131 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
132 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
133
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
134 // Mapping a non-opaque source type to an opaque dest. If this is the first
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
135 // type that we're mapping onto this destination type then we succeed. Keep
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
136 // the dest, but fill it in later. If this is the second (different) type
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
137 // that we're trying to map onto the same opaque type then we fail.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
138 if (cast<StructType>(DstTy)->isOpaque()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
139 // We can only map one source type onto the opaque destination type.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
140 if (!DstResolvedOpaqueTypes.insert(cast<StructType>(DstTy)).second)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
141 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
142 SrcDefinitionsToResolve.push_back(SSTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
143 SpeculativeTypes.push_back(SrcTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
144 SpeculativeDstOpaqueTypes.push_back(cast<StructType>(DstTy));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
145 Entry = DstTy;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
146 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
147 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
148 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
149
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
150 // If the number of subtypes disagree between the two types, then we fail.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
151 if (SrcTy->getNumContainedTypes() != DstTy->getNumContainedTypes())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
152 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
153
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
154 // Fail if any of the extra properties (e.g. array size) of the type disagree.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
155 if (isa<IntegerType>(DstTy))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
156 return false; // bitwidth disagrees.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
157 if (PointerType *PT = dyn_cast<PointerType>(DstTy)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
158 if (PT->getAddressSpace() != cast<PointerType>(SrcTy)->getAddressSpace())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
159 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
160
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
161 } else if (FunctionType *FT = dyn_cast<FunctionType>(DstTy)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
162 if (FT->isVarArg() != cast<FunctionType>(SrcTy)->isVarArg())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
163 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
164 } else if (StructType *DSTy = dyn_cast<StructType>(DstTy)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
165 StructType *SSTy = cast<StructType>(SrcTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
166 if (DSTy->isLiteral() != SSTy->isLiteral() ||
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
167 DSTy->isPacked() != SSTy->isPacked())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
168 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
169 } else if (ArrayType *DATy = dyn_cast<ArrayType>(DstTy)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
170 if (DATy->getNumElements() != cast<ArrayType>(SrcTy)->getNumElements())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
171 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
172 } else if (VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
173 if (DVTy->getNumElements() != cast<VectorType>(SrcTy)->getNumElements())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
174 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
175 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
176
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
177 // Otherwise, we speculate that these two types will line up and recursively
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
178 // check the subelements.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
179 Entry = DstTy;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
180 SpeculativeTypes.push_back(SrcTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
181
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
182 for (unsigned I = 0, E = SrcTy->getNumContainedTypes(); I != E; ++I)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
183 if (!areTypesIsomorphic(DstTy->getContainedType(I),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
184 SrcTy->getContainedType(I)))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
185 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
186
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
187 // If everything seems to have lined up, then everything is great.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
188 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
189 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
190
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
191 void TypeMapTy::linkDefinedTypeBodies() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
192 SmallVector<Type *, 16> Elements;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
193 for (StructType *SrcSTy : SrcDefinitionsToResolve) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
194 StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
195 assert(DstSTy->isOpaque());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
196
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
197 // Map the body of the source type over to a new body for the dest type.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
198 Elements.resize(SrcSTy->getNumElements());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
199 for (unsigned I = 0, E = Elements.size(); I != E; ++I)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
200 Elements[I] = get(SrcSTy->getElementType(I));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
201
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
202 DstSTy->setBody(Elements, SrcSTy->isPacked());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
203 DstStructTypesSet.switchToNonOpaque(DstSTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
204 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
205 SrcDefinitionsToResolve.clear();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
206 DstResolvedOpaqueTypes.clear();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
207 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
208
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
209 void TypeMapTy::finishType(StructType *DTy, StructType *STy,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
210 ArrayRef<Type *> ETypes) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
211 DTy->setBody(ETypes, STy->isPacked());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
212
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
213 // Steal STy's name.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
214 if (STy->hasName()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
215 SmallString<16> TmpName = STy->getName();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
216 STy->setName("");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
217 DTy->setName(TmpName);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
218 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
219
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
220 DstStructTypesSet.addNonOpaque(DTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
221 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
222
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
223 Type *TypeMapTy::get(Type *Ty) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
224 SmallPtrSet<StructType *, 8> Visited;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
225 return get(Ty, Visited);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
226 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
227
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
228 Type *TypeMapTy::get(Type *Ty, SmallPtrSet<StructType *, 8> &Visited) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
229 // If we already have an entry for this type, return it.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
230 Type **Entry = &MappedTypes[Ty];
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
231 if (*Entry)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
232 return *Entry;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
233
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
234 // These are types that LLVM itself will unique.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
235 bool IsUniqued = !isa<StructType>(Ty) || cast<StructType>(Ty)->isLiteral();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
236
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
237 #ifndef NDEBUG
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
238 if (!IsUniqued) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
239 for (auto &Pair : MappedTypes) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
240 assert(!(Pair.first != Ty && Pair.second == Ty) &&
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
241 "mapping to a source type");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
242 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
243 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
244 #endif
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
245
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
246 if (!IsUniqued && !Visited.insert(cast<StructType>(Ty)).second) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
247 StructType *DTy = StructType::create(Ty->getContext());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
248 return *Entry = DTy;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
249 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
250
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
251 // If this is not a recursive type, then just map all of the elements and
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
252 // then rebuild the type from inside out.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
253 SmallVector<Type *, 4> ElementTypes;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
254
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
255 // If there are no element types to map, then the type is itself. This is
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
256 // true for the anonymous {} struct, things like 'float', integers, etc.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
257 if (Ty->getNumContainedTypes() == 0 && IsUniqued)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
258 return *Entry = Ty;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
259
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
260 // Remap all of the elements, keeping track of whether any of them change.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
261 bool AnyChange = false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
262 ElementTypes.resize(Ty->getNumContainedTypes());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
263 for (unsigned I = 0, E = Ty->getNumContainedTypes(); I != E; ++I) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
264 ElementTypes[I] = get(Ty->getContainedType(I), Visited);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
265 AnyChange |= ElementTypes[I] != Ty->getContainedType(I);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
266 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
267
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
268 // If we found our type while recursively processing stuff, just use it.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
269 Entry = &MappedTypes[Ty];
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
270 if (*Entry) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
271 if (auto *DTy = dyn_cast<StructType>(*Entry)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
272 if (DTy->isOpaque()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
273 auto *STy = cast<StructType>(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
274 finishType(DTy, STy, ElementTypes);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
275 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
276 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
277 return *Entry;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
278 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
279
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
280 // If all of the element types mapped directly over and the type is not
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
281 // a nomed struct, then the type is usable as-is.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
282 if (!AnyChange && IsUniqued)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
283 return *Entry = Ty;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
284
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
285 // Otherwise, rebuild a modified type.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
286 switch (Ty->getTypeID()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
287 default:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
288 llvm_unreachable("unknown derived type to remap");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
289 case Type::ArrayTyID:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
290 return *Entry = ArrayType::get(ElementTypes[0],
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
291 cast<ArrayType>(Ty)->getNumElements());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
292 case Type::VectorTyID:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
293 return *Entry = VectorType::get(ElementTypes[0],
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
294 cast<VectorType>(Ty)->getNumElements());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
295 case Type::PointerTyID:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
296 return *Entry = PointerType::get(ElementTypes[0],
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
297 cast<PointerType>(Ty)->getAddressSpace());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
298 case Type::FunctionTyID:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
299 return *Entry = FunctionType::get(ElementTypes[0],
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
300 makeArrayRef(ElementTypes).slice(1),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
301 cast<FunctionType>(Ty)->isVarArg());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
302 case Type::StructTyID: {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
303 auto *STy = cast<StructType>(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
304 bool IsPacked = STy->isPacked();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
305 if (IsUniqued)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
306 return *Entry = StructType::get(Ty->getContext(), ElementTypes, IsPacked);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
307
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
308 // If the type is opaque, we can just use it directly.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
309 if (STy->isOpaque()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
310 DstStructTypesSet.addOpaque(STy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
311 return *Entry = Ty;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
312 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
313
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
314 if (StructType *OldT =
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
315 DstStructTypesSet.findNonOpaque(ElementTypes, IsPacked)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
316 STy->setName("");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
317 return *Entry = OldT;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
318 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
319
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
320 if (!AnyChange) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
321 DstStructTypesSet.addNonOpaque(STy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
322 return *Entry = Ty;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
323 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
324
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
325 StructType *DTy = StructType::create(Ty->getContext());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
326 finishType(DTy, STy, ElementTypes);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
327 return *Entry = DTy;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
328 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
329 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
330 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
331
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
332 LinkDiagnosticInfo::LinkDiagnosticInfo(DiagnosticSeverity Severity,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
333 const Twine &Msg)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
334 : DiagnosticInfo(DK_Linker, Severity), Msg(Msg) {}
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
335 void LinkDiagnosticInfo::print(DiagnosticPrinter &DP) const { DP << Msg; }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
336
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
337 //===----------------------------------------------------------------------===//
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
338 // IRLinker implementation.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
339 //===----------------------------------------------------------------------===//
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
340
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
341 namespace {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
342 class IRLinker;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
343
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
344 /// Creates prototypes for functions that are lazily linked on the fly. This
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
345 /// speeds up linking for modules with many/ lazily linked functions of which
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
346 /// few get used.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
347 class GlobalValueMaterializer final : public ValueMaterializer {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
348 IRLinker *TheIRLinker;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
349
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
350 public:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
351 GlobalValueMaterializer(IRLinker *TheIRLinker) : TheIRLinker(TheIRLinker) {}
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
352 Value *materializeDeclFor(Value *V) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
353 void materializeInitFor(GlobalValue *New, GlobalValue *Old) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
354 Metadata *mapTemporaryMetadata(Metadata *MD) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
355 void replaceTemporaryMetadata(const Metadata *OrigMD,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
356 Metadata *NewMD) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
357 bool isMetadataNeeded(Metadata *MD) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
358 };
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
359
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
360 class LocalValueMaterializer final : public ValueMaterializer {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
361 IRLinker *TheIRLinker;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
362
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
363 public:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
364 LocalValueMaterializer(IRLinker *TheIRLinker) : TheIRLinker(TheIRLinker) {}
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
365 Value *materializeDeclFor(Value *V) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
366 void materializeInitFor(GlobalValue *New, GlobalValue *Old) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
367 Metadata *mapTemporaryMetadata(Metadata *MD) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
368 void replaceTemporaryMetadata(const Metadata *OrigMD,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
369 Metadata *NewMD) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
370 bool isMetadataNeeded(Metadata *MD) override;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
371 };
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
372
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
373 /// This is responsible for keeping track of the state used for moving data
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
374 /// from SrcM to DstM.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
375 class IRLinker {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
376 Module &DstM;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
377 Module &SrcM;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
378
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
379 std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
380
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
381 TypeMapTy TypeMap;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
382 GlobalValueMaterializer GValMaterializer;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
383 LocalValueMaterializer LValMaterializer;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
384
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
385 /// Mapping of values from what they used to be in Src, to what they are now
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
386 /// in DstM. ValueToValueMapTy is a ValueMap, which involves some overhead
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
387 /// due to the use of Value handles which the Linker doesn't actually need,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
388 /// but this allows us to reuse the ValueMapper code.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
389 ValueToValueMapTy ValueMap;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
390 ValueToValueMapTy AliasValueMap;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
391
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
392 DenseSet<GlobalValue *> ValuesToLink;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
393 std::vector<GlobalValue *> Worklist;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
394
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
395 void maybeAdd(GlobalValue *GV) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
396 if (ValuesToLink.insert(GV).second)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
397 Worklist.push_back(GV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
398 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
399
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
400 /// Set to true when all global value body linking is complete (including
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
401 /// lazy linking). Used to prevent metadata linking from creating new
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
402 /// references.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
403 bool DoneLinkingBodies = false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
404
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
405 bool HasError = false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
406
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
407 /// Flag indicating that we are just linking metadata (after function
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
408 /// importing).
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
409 bool IsMetadataLinkingPostpass;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
410
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
411 /// Flags to pass to value mapper invocations.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
412 RemapFlags ValueMapperFlags = RF_MoveDistinctMDs;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
413
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
414 /// Association between metadata values created during bitcode parsing and
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
415 /// the value id. Used to correlate temporary metadata created during
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
416 /// function importing with the final metadata parsed during the subsequent
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
417 /// metadata linking postpass.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
418 DenseMap<const Metadata *, unsigned> MetadataToIDs;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
419
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
420 /// Association between metadata value id and temporary metadata that
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
421 /// remains unmapped after function importing. Saved during function
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
422 /// importing and consumed during the metadata linking postpass.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
423 DenseMap<unsigned, MDNode *> *ValIDToTempMDMap;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
424
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
425 /// Set of subprogram metadata that does not need to be linked into the
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
426 /// destination module, because the functions were not imported directly
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
427 /// or via an inlined body in an imported function.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
428 SmallPtrSet<const Metadata *, 16> UnneededSubprograms;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
429
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
430 /// Handles cloning of a global values from the source module into
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
431 /// the destination module, including setting the attributes and visibility.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
432 GlobalValue *copyGlobalValueProto(const GlobalValue *SGV, bool ForDefinition);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
433
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
434 /// Helper method for setting a message and returning an error code.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
435 bool emitError(const Twine &Message) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
436 SrcM.getContext().diagnose(LinkDiagnosticInfo(DS_Error, Message));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
437 HasError = true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
438 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
439 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
440
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
441 void emitWarning(const Twine &Message) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
442 SrcM.getContext().diagnose(LinkDiagnosticInfo(DS_Warning, Message));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
443 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
444
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
445 /// Check whether we should be linking metadata from the source module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
446 bool shouldLinkMetadata() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
447 // ValIDToTempMDMap will be non-null when we are importing or otherwise want
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
448 // to link metadata lazily, and then when linking the metadata.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
449 // We only want to return true for the former case.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
450 return ValIDToTempMDMap == nullptr || IsMetadataLinkingPostpass;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
451 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
452
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
453 /// Given a global in the source module, return the global in the
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
454 /// destination module that is being linked to, if any.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
455 GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
456 // If the source has no name it can't link. If it has local linkage,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
457 // there is no name match-up going on.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
458 if (!SrcGV->hasName() || SrcGV->hasLocalLinkage())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
459 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
460
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
461 // Otherwise see if we have a match in the destination module's symtab.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
462 GlobalValue *DGV = DstM.getNamedValue(SrcGV->getName());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
463 if (!DGV)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
464 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
465
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
466 // If we found a global with the same name in the dest module, but it has
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
467 // internal linkage, we are really not doing any linkage here.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
468 if (DGV->hasLocalLinkage())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
469 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
470
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
471 // Otherwise, we do in fact link to the destination global.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
472 return DGV;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
473 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
474
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
475 void computeTypeMapping();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
476
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
477 Constant *linkAppendingVarProto(GlobalVariable *DstGV,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
478 const GlobalVariable *SrcGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
479
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
480 bool shouldLink(GlobalValue *DGV, GlobalValue &SGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
481 Constant *linkGlobalValueProto(GlobalValue *GV, bool ForAlias);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
482
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
483 bool linkModuleFlagsMetadata();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
484
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
485 void linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
486 bool linkFunctionBody(Function &Dst, Function &Src);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
487 void linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
488 bool linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
489
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
490 /// Functions that take care of cloning a specific global value type
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
491 /// into the destination module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
492 GlobalVariable *copyGlobalVariableProto(const GlobalVariable *SGVar);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
493 Function *copyFunctionProto(const Function *SF);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
494 GlobalValue *copyGlobalAliasProto(const GlobalAlias *SGA);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
495
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
496 void linkNamedMDNodes();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
497
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
498 /// Populate the UnneededSubprograms set with the DISubprogram metadata
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
499 /// from the source module that we don't need to link into the dest module,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
500 /// because the functions were not imported directly or via an inlined body
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
501 /// in an imported function.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
502 void findNeededSubprograms();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
503
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
504 /// Recursive helper for findNeededSubprograms to locate any DISubprogram
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
505 /// reached from the given Node, marking any found as needed.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
506 void findReachedSubprograms(const MDNode *Node,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
507 SmallPtrSet<const MDNode *, 16> &Visited);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
508
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
509 /// The value mapper leaves nulls in the list of subprograms for any
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
510 /// in the UnneededSubprograms map. Strip those out after metadata linking.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
511 void stripNullSubprograms();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
512
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
513 public:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
514 IRLinker(Module &DstM, IRMover::IdentifiedStructTypeSet &Set, Module &SrcM,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
515 ArrayRef<GlobalValue *> ValuesToLink,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
516 std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
517 DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
518 bool IsMetadataLinkingPostpass = false)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
519 : DstM(DstM), SrcM(SrcM), AddLazyFor(AddLazyFor), TypeMap(Set),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
520 GValMaterializer(this), LValMaterializer(this),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
521 IsMetadataLinkingPostpass(IsMetadataLinkingPostpass),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
522 ValIDToTempMDMap(ValIDToTempMDMap) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
523 for (GlobalValue *GV : ValuesToLink)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
524 maybeAdd(GV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
525
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
526 // If appropriate, tell the value mapper that it can expect to see
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
527 // temporary metadata.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
528 if (!shouldLinkMetadata())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
529 ValueMapperFlags = ValueMapperFlags | RF_HaveUnmaterializedMetadata;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
530 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
531
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
532 ~IRLinker() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
533 // In the case where we are not linking metadata, we unset the CanReplace
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
534 // flag on all temporary metadata in the MetadataToIDs map to ensure
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
535 // none was replaced while being a map key. Now that we are destructing
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
536 // the map, set the flag back to true, so that it is replaceable during
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
537 // metadata linking.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
538 if (!shouldLinkMetadata()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
539 for (auto MDI : MetadataToIDs) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
540 Metadata *MD = const_cast<Metadata *>(MDI.first);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
541 MDNode *Node = dyn_cast<MDNode>(MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
542 assert((Node && Node->isTemporary()) &&
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
543 "Found non-temp metadata in map when not linking metadata");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
544 Node->setCanReplace(true);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
545 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
546 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
547 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
548
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
549 bool run();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
550 Value *materializeDeclFor(Value *V, bool ForAlias);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
551 void materializeInitFor(GlobalValue *New, GlobalValue *Old, bool ForAlias);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
552
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
553 /// Save the mapping between the given temporary metadata and its metadata
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
554 /// value id. Used to support metadata linking as a postpass for function
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
555 /// importing.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
556 Metadata *mapTemporaryMetadata(Metadata *MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
557
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
558 /// Replace any temporary metadata saved for the source metadata's id with
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
559 /// the new non-temporary metadata. Used when metadata linking as a postpass
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
560 /// for function importing.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
561 void replaceTemporaryMetadata(const Metadata *OrigMD, Metadata *NewMD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
562
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
563 /// Indicates whether we need to map the given metadata into the destination
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
564 /// module. Used to prevent linking of metadata only needed by functions not
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
565 /// linked into the dest module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
566 bool isMetadataNeeded(Metadata *MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
567 };
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
568 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
569
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
570 /// The LLVM SymbolTable class autorenames globals that conflict in the symbol
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
571 /// table. This is good for all clients except for us. Go through the trouble
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
572 /// to force this back.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
573 static void forceRenaming(GlobalValue *GV, StringRef Name) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
574 // If the global doesn't force its name or if it already has the right name,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
575 // there is nothing for us to do.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
576 if (GV->hasLocalLinkage() || GV->getName() == Name)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
577 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
578
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
579 Module *M = GV->getParent();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
580
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
581 // If there is a conflict, rename the conflict.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
582 if (GlobalValue *ConflictGV = M->getNamedValue(Name)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
583 GV->takeName(ConflictGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
584 ConflictGV->setName(Name); // This will cause ConflictGV to get renamed
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
585 assert(ConflictGV->getName() != Name && "forceRenaming didn't work");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
586 } else {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
587 GV->setName(Name); // Force the name back
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
588 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
589 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
590
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
591 Value *GlobalValueMaterializer::materializeDeclFor(Value *V) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
592 return TheIRLinker->materializeDeclFor(V, false);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
593 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
594
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
595 void GlobalValueMaterializer::materializeInitFor(GlobalValue *New,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
596 GlobalValue *Old) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
597 TheIRLinker->materializeInitFor(New, Old, false);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
598 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
599
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
600 Metadata *GlobalValueMaterializer::mapTemporaryMetadata(Metadata *MD) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
601 return TheIRLinker->mapTemporaryMetadata(MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
602 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
603
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
604 void GlobalValueMaterializer::replaceTemporaryMetadata(const Metadata *OrigMD,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
605 Metadata *NewMD) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
606 TheIRLinker->replaceTemporaryMetadata(OrigMD, NewMD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
607 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
608
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
609 bool GlobalValueMaterializer::isMetadataNeeded(Metadata *MD) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
610 return TheIRLinker->isMetadataNeeded(MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
611 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
612
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
613 Value *LocalValueMaterializer::materializeDeclFor(Value *V) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
614 return TheIRLinker->materializeDeclFor(V, true);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
615 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
616
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
617 void LocalValueMaterializer::materializeInitFor(GlobalValue *New,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
618 GlobalValue *Old) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
619 TheIRLinker->materializeInitFor(New, Old, true);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
620 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
621
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
622 Metadata *LocalValueMaterializer::mapTemporaryMetadata(Metadata *MD) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
623 return TheIRLinker->mapTemporaryMetadata(MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
624 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
625
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
626 void LocalValueMaterializer::replaceTemporaryMetadata(const Metadata *OrigMD,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
627 Metadata *NewMD) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
628 TheIRLinker->replaceTemporaryMetadata(OrigMD, NewMD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
629 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
630
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
631 bool LocalValueMaterializer::isMetadataNeeded(Metadata *MD) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
632 return TheIRLinker->isMetadataNeeded(MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
633 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
634
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
635 Value *IRLinker::materializeDeclFor(Value *V, bool ForAlias) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
636 auto *SGV = dyn_cast<GlobalValue>(V);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
637 if (!SGV)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
638 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
639
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
640 return linkGlobalValueProto(SGV, ForAlias);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
641 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
642
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
643 void IRLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
644 bool ForAlias) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
645 // If we already created the body, just return.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
646 if (auto *F = dyn_cast<Function>(New)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
647 if (!F->isDeclaration())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
648 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
649 } else if (auto *V = dyn_cast<GlobalVariable>(New)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
650 if (V->hasInitializer())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
651 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
652 } else {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
653 auto *A = cast<GlobalAlias>(New);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
654 if (A->getAliasee())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
655 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
656 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
657
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
658 if (ForAlias || shouldLink(New, *Old))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
659 linkGlobalValueBody(*New, *Old);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
660 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
661
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
662 Metadata *IRLinker::mapTemporaryMetadata(Metadata *MD) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
663 if (!ValIDToTempMDMap)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
664 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
665 // If this temporary metadata has a value id recorded during function
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
666 // parsing, record that in the ValIDToTempMDMap if one was provided.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
667 auto I = MetadataToIDs.find(MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
668 if (I == MetadataToIDs.end())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
669 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
670 unsigned Idx = I->second;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
671 MDNode *Node = cast<MDNode>(MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
672 assert(Node->isTemporary());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
673 // If we created a temp MD when importing a different function from
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
674 // this module, reuse the same temporary metadata.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
675 auto IterBool = ValIDToTempMDMap->insert(std::make_pair(Idx, Node));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
676 return IterBool.first->second;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
677 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
678
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
679 void IRLinker::replaceTemporaryMetadata(const Metadata *OrigMD,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
680 Metadata *NewMD) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
681 if (!ValIDToTempMDMap)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
682 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
683 #ifndef NDEBUG
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
684 auto *N = dyn_cast_or_null<MDNode>(NewMD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
685 assert(!N || !N->isTemporary());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
686 #endif
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
687 // If a mapping between metadata value ids and temporary metadata
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
688 // created during function importing was provided, and the source
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
689 // metadata has a value id recorded during metadata parsing, replace
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
690 // the temporary metadata with the final mapped metadata now.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
691 auto I = MetadataToIDs.find(OrigMD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
692 if (I == MetadataToIDs.end())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
693 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
694 unsigned Idx = I->second;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
695 auto VI = ValIDToTempMDMap->find(Idx);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
696 // Nothing to do if we didn't need to create a temporary metadata during
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
697 // function importing.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
698 if (VI == ValIDToTempMDMap->end())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
699 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
700 MDNode *TempMD = VI->second;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
701 TempMD->replaceAllUsesWith(NewMD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
702 MDNode::deleteTemporary(TempMD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
703 ValIDToTempMDMap->erase(VI);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
704 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
705
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
706 bool IRLinker::isMetadataNeeded(Metadata *MD) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
707 // Currently only DISubprogram metadata is marked as being unneeded.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
708 if (UnneededSubprograms.empty())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
709 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
710 MDNode *Node = dyn_cast<MDNode>(MD);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
711 if (!Node)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
712 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
713 DISubprogram *SP = getDISubprogram(Node);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
714 if (!SP)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
715 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
716 return !UnneededSubprograms.count(SP);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
717 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
718
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
719 /// Loop through the global variables in the src module and merge them into the
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
720 /// dest module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
721 GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
722 // No linking to be performed or linking from the source: simply create an
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
723 // identical version of the symbol over in the dest module... the
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
724 // initializer will be filled in later by LinkGlobalInits.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
725 GlobalVariable *NewDGV =
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
726 new GlobalVariable(DstM, TypeMap.get(SGVar->getValueType()),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
727 SGVar->isConstant(), GlobalValue::ExternalLinkage,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
728 /*init*/ nullptr, SGVar->getName(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
729 /*insertbefore*/ nullptr, SGVar->getThreadLocalMode(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
730 SGVar->getType()->getAddressSpace());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
731 NewDGV->setAlignment(SGVar->getAlignment());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
732 return NewDGV;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
733 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
734
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
735 /// Link the function in the source module into the destination module if
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
736 /// needed, setting up mapping information.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
737 Function *IRLinker::copyFunctionProto(const Function *SF) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
738 // If there is no linkage to be performed or we are linking from the source,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
739 // bring SF over.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
740 return Function::Create(TypeMap.get(SF->getFunctionType()),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
741 GlobalValue::ExternalLinkage, SF->getName(), &DstM);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
742 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
743
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
744 /// Set up prototypes for any aliases that come over from the source module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
745 GlobalValue *IRLinker::copyGlobalAliasProto(const GlobalAlias *SGA) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
746 // If there is no linkage to be performed or we're linking from the source,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
747 // bring over SGA.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
748 auto *Ty = TypeMap.get(SGA->getValueType());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
749 return GlobalAlias::create(Ty, SGA->getType()->getPointerAddressSpace(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
750 GlobalValue::ExternalLinkage, SGA->getName(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
751 &DstM);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
752 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
753
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
754 GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
755 bool ForDefinition) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
756 GlobalValue *NewGV;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
757 if (auto *SGVar = dyn_cast<GlobalVariable>(SGV)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
758 NewGV = copyGlobalVariableProto(SGVar);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
759 } else if (auto *SF = dyn_cast<Function>(SGV)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
760 NewGV = copyFunctionProto(SF);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
761 } else {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
762 if (ForDefinition)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
763 NewGV = copyGlobalAliasProto(cast<GlobalAlias>(SGV));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
764 else
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
765 NewGV = new GlobalVariable(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
766 DstM, TypeMap.get(SGV->getValueType()),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
767 /*isConstant*/ false, GlobalValue::ExternalLinkage,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
768 /*init*/ nullptr, SGV->getName(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
769 /*insertbefore*/ nullptr, SGV->getThreadLocalMode(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
770 SGV->getType()->getAddressSpace());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
771 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
772
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
773 if (ForDefinition)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
774 NewGV->setLinkage(SGV->getLinkage());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
775 else if (SGV->hasExternalWeakLinkage() || SGV->hasWeakLinkage() ||
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
776 SGV->hasLinkOnceLinkage())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
777 NewGV->setLinkage(GlobalValue::ExternalWeakLinkage);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
778
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
779 NewGV->copyAttributesFrom(SGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
780
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
781 // Remove these copied constants in case this stays a declaration, since
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
782 // they point to the source module. If the def is linked the values will
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
783 // be mapped in during linkFunctionBody.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
784 if (auto *NewF = dyn_cast<Function>(NewGV)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
785 NewF->setPersonalityFn(nullptr);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
786 NewF->setPrefixData(nullptr);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
787 NewF->setPrologueData(nullptr);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
788 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
789
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
790 return NewGV;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
791 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
792
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
793 /// Loop over all of the linked values to compute type mappings. For example,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
794 /// if we link "extern Foo *x" and "Foo *x = NULL", then we have two struct
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
795 /// types 'Foo' but one got renamed when the module was loaded into the same
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
796 /// LLVMContext.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
797 void IRLinker::computeTypeMapping() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
798 for (GlobalValue &SGV : SrcM.globals()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
799 GlobalValue *DGV = getLinkedToGlobal(&SGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
800 if (!DGV)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
801 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
802
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
803 if (!DGV->hasAppendingLinkage() || !SGV.hasAppendingLinkage()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
804 TypeMap.addTypeMapping(DGV->getType(), SGV.getType());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
805 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
806 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
807
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
808 // Unify the element type of appending arrays.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
809 ArrayType *DAT = cast<ArrayType>(DGV->getValueType());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
810 ArrayType *SAT = cast<ArrayType>(SGV.getValueType());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
811 TypeMap.addTypeMapping(DAT->getElementType(), SAT->getElementType());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
812 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
813
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
814 for (GlobalValue &SGV : SrcM)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
815 if (GlobalValue *DGV = getLinkedToGlobal(&SGV))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
816 TypeMap.addTypeMapping(DGV->getType(), SGV.getType());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
817
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
818 for (GlobalValue &SGV : SrcM.aliases())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
819 if (GlobalValue *DGV = getLinkedToGlobal(&SGV))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
820 TypeMap.addTypeMapping(DGV->getType(), SGV.getType());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
821
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
822 // Incorporate types by name, scanning all the types in the source module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
823 // At this point, the destination module may have a type "%foo = { i32 }" for
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
824 // example. When the source module got loaded into the same LLVMContext, if
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
825 // it had the same type, it would have been renamed to "%foo.42 = { i32 }".
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
826 std::vector<StructType *> Types = SrcM.getIdentifiedStructTypes();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
827 for (StructType *ST : Types) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
828 if (!ST->hasName())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
829 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
830
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
831 // Check to see if there is a dot in the name followed by a digit.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
832 size_t DotPos = ST->getName().rfind('.');
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
833 if (DotPos == 0 || DotPos == StringRef::npos ||
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
834 ST->getName().back() == '.' ||
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
835 !isdigit(static_cast<unsigned char>(ST->getName()[DotPos + 1])))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
836 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
837
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
838 // Check to see if the destination module has a struct with the prefix name.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
839 StructType *DST = DstM.getTypeByName(ST->getName().substr(0, DotPos));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
840 if (!DST)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
841 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
842
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
843 // Don't use it if this actually came from the source module. They're in
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
844 // the same LLVMContext after all. Also don't use it unless the type is
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
845 // actually used in the destination module. This can happen in situations
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
846 // like this:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
847 //
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
848 // Module A Module B
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
849 // -------- --------
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
850 // %Z = type { %A } %B = type { %C.1 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
851 // %A = type { %B.1, [7 x i8] } %C.1 = type { i8* }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
852 // %B.1 = type { %C } %A.2 = type { %B.3, [5 x i8] }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
853 // %C = type { i8* } %B.3 = type { %C.1 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
854 //
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
855 // When we link Module B with Module A, the '%B' in Module B is
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
856 // used. However, that would then use '%C.1'. But when we process '%C.1',
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
857 // we prefer to take the '%C' version. So we are then left with both
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
858 // '%C.1' and '%C' being used for the same types. This leads to some
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
859 // variables using one type and some using the other.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
860 if (TypeMap.DstStructTypesSet.hasType(DST))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
861 TypeMap.addTypeMapping(DST, ST);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
862 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
863
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
864 // Now that we have discovered all of the type equivalences, get a body for
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
865 // any 'opaque' types in the dest module that are now resolved.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
866 TypeMap.linkDefinedTypeBodies();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
867 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
868
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
869 static void getArrayElements(const Constant *C,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
870 SmallVectorImpl<Constant *> &Dest) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
871 unsigned NumElements = cast<ArrayType>(C->getType())->getNumElements();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
872
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
873 for (unsigned i = 0; i != NumElements; ++i)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
874 Dest.push_back(C->getAggregateElement(i));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
875 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
876
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
877 /// If there were any appending global variables, link them together now.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
878 /// Return true on error.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
879 Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
880 const GlobalVariable *SrcGV) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
881 Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getValueType()))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
882 ->getElementType();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
883
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
884 StringRef Name = SrcGV->getName();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
885 bool IsNewStructor = false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
886 bool IsOldStructor = false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
887 if (Name == "llvm.global_ctors" || Name == "llvm.global_dtors") {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
888 if (cast<StructType>(EltTy)->getNumElements() == 3)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
889 IsNewStructor = true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
890 else
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
891 IsOldStructor = true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
892 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
893
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
894 PointerType *VoidPtrTy = Type::getInt8Ty(SrcGV->getContext())->getPointerTo();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
895 if (IsOldStructor) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
896 auto &ST = *cast<StructType>(EltTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
897 Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy};
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
898 EltTy = StructType::get(SrcGV->getContext(), Tys, false);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
899 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
900
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
901 if (DstGV) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
902 ArrayType *DstTy = cast<ArrayType>(DstGV->getValueType());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
903
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
904 if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
905 emitError(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
906 "Linking globals named '" + SrcGV->getName() +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
907 "': can only link appending global with another appending global!");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
908 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
909 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
910
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
911 // Check to see that they two arrays agree on type.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
912 if (EltTy != DstTy->getElementType()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
913 emitError("Appending variables with different element types!");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
914 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
915 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
916 if (DstGV->isConstant() != SrcGV->isConstant()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
917 emitError("Appending variables linked with different const'ness!");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
918 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
919 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
920
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
921 if (DstGV->getAlignment() != SrcGV->getAlignment()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
922 emitError(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
923 "Appending variables with different alignment need to be linked!");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
924 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
925 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
926
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
927 if (DstGV->getVisibility() != SrcGV->getVisibility()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
928 emitError(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
929 "Appending variables with different visibility need to be linked!");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
930 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
931 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
932
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
933 if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
934 emitError(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
935 "Appending variables with different unnamed_addr need to be linked!");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
936 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
937 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
938
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
939 if (StringRef(DstGV->getSection()) != SrcGV->getSection()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
940 emitError(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
941 "Appending variables with different section name need to be linked!");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
942 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
943 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
944 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
945
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
946 SmallVector<Constant *, 16> DstElements;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
947 if (DstGV)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
948 getArrayElements(DstGV->getInitializer(), DstElements);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
949
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
950 SmallVector<Constant *, 16> SrcElements;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
951 getArrayElements(SrcGV->getInitializer(), SrcElements);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
952
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
953 if (IsNewStructor)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
954 SrcElements.erase(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
955 std::remove_if(SrcElements.begin(), SrcElements.end(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
956 [this](Constant *E) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
957 auto *Key = dyn_cast<GlobalValue>(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
958 E->getAggregateElement(2)->stripPointerCasts());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
959 if (!Key)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
960 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
961 GlobalValue *DGV = getLinkedToGlobal(Key);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
962 return !shouldLink(DGV, *Key);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
963 }),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
964 SrcElements.end());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
965 uint64_t NewSize = DstElements.size() + SrcElements.size();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
966 ArrayType *NewType = ArrayType::get(EltTy, NewSize);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
967
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
968 // Create the new global variable.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
969 GlobalVariable *NG = new GlobalVariable(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
970 DstM, NewType, SrcGV->isConstant(), SrcGV->getLinkage(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
971 /*init*/ nullptr, /*name*/ "", DstGV, SrcGV->getThreadLocalMode(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
972 SrcGV->getType()->getAddressSpace());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
973
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
974 NG->copyAttributesFrom(SrcGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
975 forceRenaming(NG, SrcGV->getName());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
976
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
977 Constant *Ret = ConstantExpr::getBitCast(NG, TypeMap.get(SrcGV->getType()));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
978
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
979 // Stop recursion.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
980 ValueMap[SrcGV] = Ret;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
981
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
982 for (auto *V : SrcElements) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
983 Constant *NewV;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
984 if (IsOldStructor) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
985 auto *S = cast<ConstantStruct>(V);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
986 auto *E1 = MapValue(S->getOperand(0), ValueMap, ValueMapperFlags,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
987 &TypeMap, &GValMaterializer);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
988 auto *E2 = MapValue(S->getOperand(1), ValueMap, ValueMapperFlags,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
989 &TypeMap, &GValMaterializer);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
990 Value *Null = Constant::getNullValue(VoidPtrTy);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
991 NewV =
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
992 ConstantStruct::get(cast<StructType>(EltTy), E1, E2, Null, nullptr);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
993 } else {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
994 NewV =
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
995 MapValue(V, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
996 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
997 DstElements.push_back(NewV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
998 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
999
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1000 NG->setInitializer(ConstantArray::get(NewType, DstElements));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1001
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1002 // Replace any uses of the two global variables with uses of the new
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1003 // global.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1004 if (DstGV) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1005 DstGV->replaceAllUsesWith(ConstantExpr::getBitCast(NG, DstGV->getType()));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1006 DstGV->eraseFromParent();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1007 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1008
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1009 return Ret;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1010 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1011
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1012 bool IRLinker::shouldLink(GlobalValue *DGV, GlobalValue &SGV) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1013 // Already imported all the values. Just map to the Dest value
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1014 // in case it is referenced in the metadata.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1015 if (IsMetadataLinkingPostpass) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1016 assert(!ValuesToLink.count(&SGV) &&
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1017 "Source value unexpectedly requested for link during metadata link");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1018 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1019 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1020
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1021 if (ValuesToLink.count(&SGV))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1022 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1023
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1024 if (SGV.hasLocalLinkage())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1025 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1026
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1027 if (DGV && !DGV->isDeclarationForLinker())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1028 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1029
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1030 if (SGV.hasAvailableExternallyLinkage())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1031 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1032
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1033 if (DoneLinkingBodies)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1034 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1035
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1036 AddLazyFor(SGV, [this](GlobalValue &GV) { maybeAdd(&GV); });
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1037 return ValuesToLink.count(&SGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1038 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1039
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1040 Constant *IRLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1041 GlobalValue *DGV = getLinkedToGlobal(SGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1042
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1043 bool ShouldLink = shouldLink(DGV, *SGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1044
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1045 // just missing from map
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1046 if (ShouldLink) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1047 auto I = ValueMap.find(SGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1048 if (I != ValueMap.end())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1049 return cast<Constant>(I->second);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1050
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1051 I = AliasValueMap.find(SGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1052 if (I != AliasValueMap.end())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1053 return cast<Constant>(I->second);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1054 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1055
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1056 DGV = nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1057 if (ShouldLink || !ForAlias)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1058 DGV = getLinkedToGlobal(SGV);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1059
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1060 // Handle the ultra special appending linkage case first.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1061 assert(!DGV || SGV->hasAppendingLinkage() == DGV->hasAppendingLinkage());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1062 if (SGV->hasAppendingLinkage())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1063 return linkAppendingVarProto(cast_or_null<GlobalVariable>(DGV),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1064 cast<GlobalVariable>(SGV));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1065
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1066 GlobalValue *NewGV;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1067 if (DGV && !ShouldLink) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1068 NewGV = DGV;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1069 } else {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1070 // If we are done linking global value bodies (i.e. we are performing
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1071 // metadata linking), don't link in the global value due to this
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1072 // reference, simply map it to null.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1073 if (DoneLinkingBodies)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1074 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1075
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1076 NewGV = copyGlobalValueProto(SGV, ShouldLink);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1077 if (ShouldLink || !ForAlias)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1078 forceRenaming(NewGV, SGV->getName());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1079 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1080 if (ShouldLink || ForAlias) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1081 if (const Comdat *SC = SGV->getComdat()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1082 if (auto *GO = dyn_cast<GlobalObject>(NewGV)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1083 Comdat *DC = DstM.getOrInsertComdat(SC->getName());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1084 DC->setSelectionKind(SC->getSelectionKind());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1085 GO->setComdat(DC);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1086 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1087 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1088 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1089
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1090 if (!ShouldLink && ForAlias)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1091 NewGV->setLinkage(GlobalValue::InternalLinkage);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1092
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1093 Constant *C = NewGV;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1094 if (DGV)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1095 C = ConstantExpr::getBitCast(NewGV, TypeMap.get(SGV->getType()));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1096
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1097 if (DGV && NewGV != DGV) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1098 DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewGV, DGV->getType()));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1099 DGV->eraseFromParent();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1100 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1101
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1102 return C;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1103 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1104
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1105 /// Update the initializers in the Dest module now that all globals that may be
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1106 /// referenced are in Dest.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1107 void IRLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1108 // Figure out what the initializer looks like in the dest module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1109 Dst.setInitializer(MapValue(Src.getInitializer(), ValueMap, ValueMapperFlags,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1110 &TypeMap, &GValMaterializer));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1111 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1112
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1113 /// Copy the source function over into the dest function and fix up references
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1114 /// to values. At this point we know that Dest is an external function, and
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1115 /// that Src is not.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1116 bool IRLinker::linkFunctionBody(Function &Dst, Function &Src) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1117 assert(Dst.isDeclaration() && !Src.isDeclaration());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1118
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1119 // Materialize if needed.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1120 if (std::error_code EC = Src.materialize())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1121 return emitError(EC.message());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1122
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1123 if (!shouldLinkMetadata())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1124 // This is only supported for lazy links. Do after materialization of
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1125 // a function and before remapping metadata on instructions below
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1126 // in RemapInstruction, as the saved mapping is used to handle
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1127 // the temporary metadata hanging off instructions.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1128 SrcM.getMaterializer()->saveMetadataList(MetadataToIDs,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1129 /* OnlyTempMD = */ true);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1130
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1131 // Link in the prefix data.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1132 if (Src.hasPrefixData())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1133 Dst.setPrefixData(MapValue(Src.getPrefixData(), ValueMap, ValueMapperFlags,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1134 &TypeMap, &GValMaterializer));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1135
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1136 // Link in the prologue data.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1137 if (Src.hasPrologueData())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1138 Dst.setPrologueData(MapValue(Src.getPrologueData(), ValueMap,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1139 ValueMapperFlags, &TypeMap,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1140 &GValMaterializer));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1141
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1142 // Link in the personality function.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1143 if (Src.hasPersonalityFn())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1144 Dst.setPersonalityFn(MapValue(Src.getPersonalityFn(), ValueMap,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1145 ValueMapperFlags, &TypeMap,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1146 &GValMaterializer));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1147
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1148 // Go through and convert function arguments over, remembering the mapping.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1149 Function::arg_iterator DI = Dst.arg_begin();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1150 for (Argument &Arg : Src.args()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1151 DI->setName(Arg.getName()); // Copy the name over.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1152
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1153 // Add a mapping to our mapping.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1154 ValueMap[&Arg] = &*DI;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1155 ++DI;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1156 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1157
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1158 // Copy over the metadata attachments.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1159 SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1160 Src.getAllMetadata(MDs);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1161 for (const auto &I : MDs)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1162 Dst.setMetadata(I.first, MapMetadata(I.second, ValueMap, ValueMapperFlags,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1163 &TypeMap, &GValMaterializer));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1164
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1165 // Splice the body of the source function into the dest function.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1166 Dst.getBasicBlockList().splice(Dst.end(), Src.getBasicBlockList());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1167
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1168 // At this point, all of the instructions and values of the function are now
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1169 // copied over. The only problem is that they are still referencing values in
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1170 // the Source function as operands. Loop through all of the operands of the
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1171 // functions and patch them up to point to the local versions.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1172 for (BasicBlock &BB : Dst)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1173 for (Instruction &I : BB)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1174 RemapInstruction(&I, ValueMap, RF_IgnoreMissingEntries | ValueMapperFlags,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1175 &TypeMap, &GValMaterializer);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1176
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1177 // There is no need to map the arguments anymore.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1178 for (Argument &Arg : Src.args())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1179 ValueMap.erase(&Arg);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1180
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1181 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1182 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1183
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1184 void IRLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1185 Constant *Aliasee = Src.getAliasee();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1186 Constant *Val = MapValue(Aliasee, AliasValueMap, ValueMapperFlags, &TypeMap,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1187 &LValMaterializer);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1188 Dst.setAliasee(Val);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1189 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1190
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1191 bool IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1192 if (auto *F = dyn_cast<Function>(&Src))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1193 return linkFunctionBody(cast<Function>(Dst), *F);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1194 if (auto *GVar = dyn_cast<GlobalVariable>(&Src)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1195 linkGlobalInit(cast<GlobalVariable>(Dst), *GVar);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1196 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1197 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1198 linkAliasBody(cast<GlobalAlias>(Dst), cast<GlobalAlias>(Src));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1199 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1200 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1201
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1202 void IRLinker::findReachedSubprograms(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1203 const MDNode *Node, SmallPtrSet<const MDNode *, 16> &Visited) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1204 if (!Visited.insert(Node).second)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1205 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1206 DISubprogram *SP = getDISubprogram(Node);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1207 if (SP)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1208 UnneededSubprograms.erase(SP);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1209 for (auto &Op : Node->operands()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1210 const MDNode *OpN = dyn_cast_or_null<MDNode>(Op.get());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1211 if (!OpN)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1212 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1213 findReachedSubprograms(OpN, Visited);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1214 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1215 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1216
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1217 void IRLinker::findNeededSubprograms() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1218 // Track unneeded nodes to make it simpler to handle the case
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1219 // where we are checking if an already-mapped SP is needed.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1220 NamedMDNode *CompileUnits = SrcM.getNamedMetadata("llvm.dbg.cu");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1221 if (!CompileUnits)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1222 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1223 for (unsigned I = 0, E = CompileUnits->getNumOperands(); I != E; ++I) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1224 auto *CU = cast<DICompileUnit>(CompileUnits->getOperand(I));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1225 assert(CU && "Expected valid compile unit");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1226 // Ensure that we don't remove subprograms referenced by DIImportedEntity.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1227 // It is not legal to have a DIImportedEntity with a null entity or scope.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1228 // Using getDISubprogram handles the case where the subprogram is reached
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1229 // via an intervening DILexicalBlock.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1230 // FIXME: The DISubprogram for functions not linked in but kept due to
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1231 // being referenced by a DIImportedEntity should also get their
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1232 // IsDefinition flag is unset.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1233 SmallPtrSet<DISubprogram *, 8> ImportedEntitySPs;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1234 for (auto *IE : CU->getImportedEntities()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1235 if (auto *SP = getDISubprogram(dyn_cast<MDNode>(IE->getEntity())))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1236 ImportedEntitySPs.insert(SP);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1237 if (auto *SP = getDISubprogram(dyn_cast<MDNode>(IE->getScope())))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1238 ImportedEntitySPs.insert(SP);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1239 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1240 for (auto *Op : CU->getSubprograms()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1241 // Unless we were doing function importing and deferred metadata linking,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1242 // any needed SPs should have been mapped as they would be reached
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1243 // from the function linked in (either on the function itself for linked
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1244 // function bodies, or from DILocation on inlined instructions).
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1245 assert(!(ValueMap.MD()[Op] && IsMetadataLinkingPostpass) &&
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1246 "DISubprogram shouldn't be mapped yet");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1247 if (!ValueMap.MD()[Op] && !ImportedEntitySPs.count(Op))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1248 UnneededSubprograms.insert(Op);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1249 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1250 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1251 if (!IsMetadataLinkingPostpass)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1252 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1253 // In the case of metadata linking as a postpass (e.g. for function
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1254 // importing), see which MD from the source has an associated
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1255 // temporary metadata node, which means that any DISubprogram
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1256 // reached from that MD was needed by an imported function.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1257 SmallPtrSet<const MDNode *, 16> Visited;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1258 for (auto MDI : MetadataToIDs) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1259 const MDNode *Node = dyn_cast<MDNode>(MDI.first);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1260 if (!Node)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1261 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1262 if (!ValIDToTempMDMap->count(MDI.second))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1263 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1264 // Find any SP needed recursively from this needed Node.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1265 findReachedSubprograms(Node, Visited);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1266 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1267 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1268
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1269 // Squash null subprograms from compile unit subprogram lists.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1270 void IRLinker::stripNullSubprograms() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1271 NamedMDNode *CompileUnits = DstM.getNamedMetadata("llvm.dbg.cu");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1272 if (!CompileUnits)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1273 return;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1274 for (unsigned I = 0, E = CompileUnits->getNumOperands(); I != E; ++I) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1275 auto *CU = cast<DICompileUnit>(CompileUnits->getOperand(I));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1276 assert(CU && "Expected valid compile unit");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1277
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1278 SmallVector<Metadata *, 16> NewSPs;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1279 NewSPs.reserve(CU->getSubprograms().size());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1280 bool FoundNull = false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1281 for (DISubprogram *SP : CU->getSubprograms()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1282 if (!SP) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1283 FoundNull = true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1284 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1285 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1286 NewSPs.push_back(SP);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1287 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1288 if (FoundNull)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1289 CU->replaceSubprograms(MDTuple::get(CU->getContext(), NewSPs));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1290 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1291 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1292
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1293 /// Insert all of the named MDNodes in Src into the Dest module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1294 void IRLinker::linkNamedMDNodes() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1295 findNeededSubprograms();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1296 const NamedMDNode *SrcModFlags = SrcM.getModuleFlagsMetadata();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1297 for (const NamedMDNode &NMD : SrcM.named_metadata()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1298 // Don't link module flags here. Do them separately.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1299 if (&NMD == SrcModFlags)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1300 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1301 NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1302 // Add Src elements into Dest node.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1303 for (const MDNode *op : NMD.operands())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1304 DestNMD->addOperand(MapMetadata(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1305 op, ValueMap, ValueMapperFlags | RF_NullMapMissingGlobalValues,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1306 &TypeMap, &GValMaterializer));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1307 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1308 stripNullSubprograms();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1309 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1310
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1311 /// Merge the linker flags in Src into the Dest module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1312 bool IRLinker::linkModuleFlagsMetadata() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1313 // If the source module has no module flags, we are done.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1314 const NamedMDNode *SrcModFlags = SrcM.getModuleFlagsMetadata();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1315 if (!SrcModFlags)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1316 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1317
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1318 // If the destination module doesn't have module flags yet, then just copy
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1319 // over the source module's flags.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1320 NamedMDNode *DstModFlags = DstM.getOrInsertModuleFlagsMetadata();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1321 if (DstModFlags->getNumOperands() == 0) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1322 for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1323 DstModFlags->addOperand(SrcModFlags->getOperand(I));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1324
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1325 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1326 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1327
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1328 // First build a map of the existing module flags and requirements.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1329 DenseMap<MDString *, std::pair<MDNode *, unsigned>> Flags;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1330 SmallSetVector<MDNode *, 16> Requirements;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1331 for (unsigned I = 0, E = DstModFlags->getNumOperands(); I != E; ++I) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1332 MDNode *Op = DstModFlags->getOperand(I);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1333 ConstantInt *Behavior = mdconst::extract<ConstantInt>(Op->getOperand(0));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1334 MDString *ID = cast<MDString>(Op->getOperand(1));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1335
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1336 if (Behavior->getZExtValue() == Module::Require) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1337 Requirements.insert(cast<MDNode>(Op->getOperand(2)));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1338 } else {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1339 Flags[ID] = std::make_pair(Op, I);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1340 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1341 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1342
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1343 // Merge in the flags from the source module, and also collect its set of
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1344 // requirements.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1345 for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1346 MDNode *SrcOp = SrcModFlags->getOperand(I);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1347 ConstantInt *SrcBehavior =
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1348 mdconst::extract<ConstantInt>(SrcOp->getOperand(0));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1349 MDString *ID = cast<MDString>(SrcOp->getOperand(1));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1350 MDNode *DstOp;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1351 unsigned DstIndex;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1352 std::tie(DstOp, DstIndex) = Flags.lookup(ID);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1353 unsigned SrcBehaviorValue = SrcBehavior->getZExtValue();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1354
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1355 // If this is a requirement, add it and continue.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1356 if (SrcBehaviorValue == Module::Require) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1357 // If the destination module does not already have this requirement, add
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1358 // it.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1359 if (Requirements.insert(cast<MDNode>(SrcOp->getOperand(2)))) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1360 DstModFlags->addOperand(SrcOp);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1361 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1362 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1363 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1364
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1365 // If there is no existing flag with this ID, just add it.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1366 if (!DstOp) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1367 Flags[ID] = std::make_pair(SrcOp, DstModFlags->getNumOperands());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1368 DstModFlags->addOperand(SrcOp);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1369 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1370 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1371
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1372 // Otherwise, perform a merge.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1373 ConstantInt *DstBehavior =
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1374 mdconst::extract<ConstantInt>(DstOp->getOperand(0));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1375 unsigned DstBehaviorValue = DstBehavior->getZExtValue();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1376
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1377 // If either flag has override behavior, handle it first.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1378 if (DstBehaviorValue == Module::Override) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1379 // Diagnose inconsistent flags which both have override behavior.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1380 if (SrcBehaviorValue == Module::Override &&
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1381 SrcOp->getOperand(2) != DstOp->getOperand(2)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1382 emitError("linking module flags '" + ID->getString() +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1383 "': IDs have conflicting override values");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1384 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1385 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1386 } else if (SrcBehaviorValue == Module::Override) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1387 // Update the destination flag to that of the source.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1388 DstModFlags->setOperand(DstIndex, SrcOp);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1389 Flags[ID].first = SrcOp;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1390 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1391 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1392
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1393 // Diagnose inconsistent merge behavior types.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1394 if (SrcBehaviorValue != DstBehaviorValue) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1395 emitError("linking module flags '" + ID->getString() +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1396 "': IDs have conflicting behaviors");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1397 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1398 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1399
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1400 auto replaceDstValue = [&](MDNode *New) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1401 Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New};
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1402 MDNode *Flag = MDNode::get(DstM.getContext(), FlagOps);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1403 DstModFlags->setOperand(DstIndex, Flag);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1404 Flags[ID].first = Flag;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1405 };
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1406
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1407 // Perform the merge for standard behavior types.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1408 switch (SrcBehaviorValue) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1409 case Module::Require:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1410 case Module::Override:
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1411 llvm_unreachable("not possible");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1412 case Module::Error: {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1413 // Emit an error if the values differ.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1414 if (SrcOp->getOperand(2) != DstOp->getOperand(2)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1415 emitError("linking module flags '" + ID->getString() +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1416 "': IDs have conflicting values");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1417 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1418 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1419 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1420 case Module::Warning: {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1421 // Emit a warning if the values differ.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1422 if (SrcOp->getOperand(2) != DstOp->getOperand(2)) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1423 emitWarning("linking module flags '" + ID->getString() +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1424 "': IDs have conflicting values");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1425 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1426 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1427 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1428 case Module::Append: {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1429 MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1430 MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1431 SmallVector<Metadata *, 8> MDs;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1432 MDs.reserve(DstValue->getNumOperands() + SrcValue->getNumOperands());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1433 MDs.append(DstValue->op_begin(), DstValue->op_end());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1434 MDs.append(SrcValue->op_begin(), SrcValue->op_end());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1435
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1436 replaceDstValue(MDNode::get(DstM.getContext(), MDs));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1437 break;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1438 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1439 case Module::AppendUnique: {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1440 SmallSetVector<Metadata *, 16> Elts;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1441 MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1442 MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1443 Elts.insert(DstValue->op_begin(), DstValue->op_end());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1444 Elts.insert(SrcValue->op_begin(), SrcValue->op_end());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1445
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1446 replaceDstValue(MDNode::get(DstM.getContext(),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1447 makeArrayRef(Elts.begin(), Elts.end())));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1448 break;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1449 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1450 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1451 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1452
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1453 // Check all of the requirements.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1454 for (unsigned I = 0, E = Requirements.size(); I != E; ++I) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1455 MDNode *Requirement = Requirements[I];
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1456 MDString *Flag = cast<MDString>(Requirement->getOperand(0));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1457 Metadata *ReqValue = Requirement->getOperand(1);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1458
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1459 MDNode *Op = Flags[Flag].first;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1460 if (!Op || Op->getOperand(2) != ReqValue) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1461 emitError("linking module flags '" + Flag->getString() +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1462 "': does not have the required value");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1463 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1464 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1465 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1466
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1467 return HasError;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1468 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1469
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1470 // This function returns true if the triples match.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1471 static bool triplesMatch(const Triple &T0, const Triple &T1) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1472 // If vendor is apple, ignore the version number.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1473 if (T0.getVendor() == Triple::Apple)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1474 return T0.getArch() == T1.getArch() && T0.getSubArch() == T1.getSubArch() &&
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1475 T0.getVendor() == T1.getVendor() && T0.getOS() == T1.getOS();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1476
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1477 return T0 == T1;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1478 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1479
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1480 // This function returns the merged triple.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1481 static std::string mergeTriples(const Triple &SrcTriple,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1482 const Triple &DstTriple) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1483 // If vendor is apple, pick the triple with the larger version number.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1484 if (SrcTriple.getVendor() == Triple::Apple)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1485 if (DstTriple.isOSVersionLT(SrcTriple))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1486 return SrcTriple.str();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1487
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1488 return DstTriple.str();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1489 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1490
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1491 bool IRLinker::run() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1492 // Inherit the target data from the source module if the destination module
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1493 // doesn't have one already.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1494 if (DstM.getDataLayout().isDefault())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1495 DstM.setDataLayout(SrcM.getDataLayout());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1496
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1497 if (SrcM.getDataLayout() != DstM.getDataLayout()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1498 emitWarning("Linking two modules of different data layouts: '" +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1499 SrcM.getModuleIdentifier() + "' is '" +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1500 SrcM.getDataLayoutStr() + "' whereas '" +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1501 DstM.getModuleIdentifier() + "' is '" +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1502 DstM.getDataLayoutStr() + "'\n");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1503 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1504
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1505 // Copy the target triple from the source to dest if the dest's is empty.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1506 if (DstM.getTargetTriple().empty() && !SrcM.getTargetTriple().empty())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1507 DstM.setTargetTriple(SrcM.getTargetTriple());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1508
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1509 Triple SrcTriple(SrcM.getTargetTriple()), DstTriple(DstM.getTargetTriple());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1510
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1511 if (!SrcM.getTargetTriple().empty() && !triplesMatch(SrcTriple, DstTriple))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1512 emitWarning("Linking two modules of different target triples: " +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1513 SrcM.getModuleIdentifier() + "' is '" + SrcM.getTargetTriple() +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1514 "' whereas '" + DstM.getModuleIdentifier() + "' is '" +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1515 DstM.getTargetTriple() + "'\n");
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1516
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1517 DstM.setTargetTriple(mergeTriples(SrcTriple, DstTriple));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1518
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1519 // Append the module inline asm string.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1520 if (!SrcM.getModuleInlineAsm().empty()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1521 if (DstM.getModuleInlineAsm().empty())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1522 DstM.setModuleInlineAsm(SrcM.getModuleInlineAsm());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1523 else
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1524 DstM.setModuleInlineAsm(DstM.getModuleInlineAsm() + "\n" +
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1525 SrcM.getModuleInlineAsm());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1526 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1527
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1528 // Loop over all of the linked values to compute type mappings.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1529 computeTypeMapping();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1530
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1531 std::reverse(Worklist.begin(), Worklist.end());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1532 while (!Worklist.empty()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1533 GlobalValue *GV = Worklist.back();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1534 Worklist.pop_back();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1535
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1536 // Already mapped.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1537 if (ValueMap.find(GV) != ValueMap.end() ||
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1538 AliasValueMap.find(GV) != AliasValueMap.end())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1539 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1540
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1541 assert(!GV->isDeclaration());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1542 MapValue(GV, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1543 if (HasError)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1544 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1545 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1546
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1547 // Note that we are done linking global value bodies. This prevents
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1548 // metadata linking from creating new references.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1549 DoneLinkingBodies = true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1550
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1551 // Remap all of the named MDNodes in Src into the DstM module. We do this
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1552 // after linking GlobalValues so that MDNodes that reference GlobalValues
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1553 // are properly remapped.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1554 if (shouldLinkMetadata()) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1555 // Even if just linking metadata we should link decls above in case
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1556 // any are referenced by metadata. IRLinker::shouldLink ensures that
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1557 // we don't actually link anything from source.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1558 if (IsMetadataLinkingPostpass) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1559 // Ensure metadata materialized
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1560 if (SrcM.getMaterializer()->materializeMetadata())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1561 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1562 SrcM.getMaterializer()->saveMetadataList(MetadataToIDs,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1563 /* OnlyTempMD = */ false);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1564 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1565
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1566 linkNamedMDNodes();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1567
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1568 if (IsMetadataLinkingPostpass) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1569 // Handle anything left in the ValIDToTempMDMap, such as metadata nodes
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1570 // not reached by the dbg.cu NamedMD (i.e. only reached from
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1571 // instructions).
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1572 // Walk the MetadataToIDs once to find the set of new (imported) MD
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1573 // that still has corresponding temporary metadata, and invoke metadata
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1574 // mapping on each one.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1575 for (auto MDI : MetadataToIDs) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1576 if (!ValIDToTempMDMap->count(MDI.second))
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1577 continue;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1578 MapMetadata(MDI.first, ValueMap, ValueMapperFlags, &TypeMap,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1579 &GValMaterializer);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1580 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1581 assert(ValIDToTempMDMap->empty());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1582 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1583
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1584 // Merge the module flags into the DstM module.
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1585 if (linkModuleFlagsMetadata())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1586 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1587 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1588
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1589 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1590 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1591
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1592 IRMover::StructTypeKeyInfo::KeyTy::KeyTy(ArrayRef<Type *> E, bool P)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1593 : ETypes(E), IsPacked(P) {}
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1594
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1595 IRMover::StructTypeKeyInfo::KeyTy::KeyTy(const StructType *ST)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1596 : ETypes(ST->elements()), IsPacked(ST->isPacked()) {}
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1597
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1598 bool IRMover::StructTypeKeyInfo::KeyTy::operator==(const KeyTy &That) const {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1599 if (IsPacked != That.IsPacked)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1600 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1601 if (ETypes != That.ETypes)
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1602 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1603 return true;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1604 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1605
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1606 bool IRMover::StructTypeKeyInfo::KeyTy::operator!=(const KeyTy &That) const {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1607 return !this->operator==(That);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1608 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1609
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1610 StructType *IRMover::StructTypeKeyInfo::getEmptyKey() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1611 return DenseMapInfo<StructType *>::getEmptyKey();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1612 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1613
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1614 StructType *IRMover::StructTypeKeyInfo::getTombstoneKey() {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1615 return DenseMapInfo<StructType *>::getTombstoneKey();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1616 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1617
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1618 unsigned IRMover::StructTypeKeyInfo::getHashValue(const KeyTy &Key) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1619 return hash_combine(hash_combine_range(Key.ETypes.begin(), Key.ETypes.end()),
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1620 Key.IsPacked);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1621 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1622
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1623 unsigned IRMover::StructTypeKeyInfo::getHashValue(const StructType *ST) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1624 return getHashValue(KeyTy(ST));
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1625 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1626
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1627 bool IRMover::StructTypeKeyInfo::isEqual(const KeyTy &LHS,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1628 const StructType *RHS) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1629 if (RHS == getEmptyKey() || RHS == getTombstoneKey())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1630 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1631 return LHS == KeyTy(RHS);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1632 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1633
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1634 bool IRMover::StructTypeKeyInfo::isEqual(const StructType *LHS,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1635 const StructType *RHS) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1636 if (RHS == getEmptyKey())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1637 return LHS == getEmptyKey();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1638
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1639 if (RHS == getTombstoneKey())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1640 return LHS == getTombstoneKey();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1641
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1642 return KeyTy(LHS) == KeyTy(RHS);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1643 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1644
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1645 void IRMover::IdentifiedStructTypeSet::addNonOpaque(StructType *Ty) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1646 assert(!Ty->isOpaque());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1647 NonOpaqueStructTypes.insert(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1648 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1649
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1650 void IRMover::IdentifiedStructTypeSet::switchToNonOpaque(StructType *Ty) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1651 assert(!Ty->isOpaque());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1652 NonOpaqueStructTypes.insert(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1653 bool Removed = OpaqueStructTypes.erase(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1654 (void)Removed;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1655 assert(Removed);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1656 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1657
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1658 void IRMover::IdentifiedStructTypeSet::addOpaque(StructType *Ty) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1659 assert(Ty->isOpaque());
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1660 OpaqueStructTypes.insert(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1661 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1662
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1663 StructType *
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1664 IRMover::IdentifiedStructTypeSet::findNonOpaque(ArrayRef<Type *> ETypes,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1665 bool IsPacked) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1666 IRMover::StructTypeKeyInfo::KeyTy Key(ETypes, IsPacked);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1667 auto I = NonOpaqueStructTypes.find_as(Key);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1668 if (I == NonOpaqueStructTypes.end())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1669 return nullptr;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1670 return *I;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1671 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1672
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1673 bool IRMover::IdentifiedStructTypeSet::hasType(StructType *Ty) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1674 if (Ty->isOpaque())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1675 return OpaqueStructTypes.count(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1676 auto I = NonOpaqueStructTypes.find(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1677 if (I == NonOpaqueStructTypes.end())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1678 return false;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1679 return *I == Ty;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1680 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1681
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1682 IRMover::IRMover(Module &M) : Composite(M) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1683 TypeFinder StructTypes;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1684 StructTypes.run(M, true);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1685 for (StructType *Ty : StructTypes) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1686 if (Ty->isOpaque())
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1687 IdentifiedStructTypes.addOpaque(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1688 else
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1689 IdentifiedStructTypes.addNonOpaque(Ty);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1690 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1691 }
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1692
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1693 bool IRMover::move(
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1694 Module &Src, ArrayRef<GlobalValue *> ValuesToLink,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1695 std::function<void(GlobalValue &, ValueAdder Add)> AddLazyFor,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1696 DenseMap<unsigned, MDNode *> *ValIDToTempMDMap,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1697 bool IsMetadataLinkingPostpass) {
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1698 IRLinker TheIRLinker(Composite, IdentifiedStructTypes, Src, ValuesToLink,
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1699 AddLazyFor, ValIDToTempMDMap, IsMetadataLinkingPostpass);
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1700 bool RetCode = TheIRLinker.run();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1701 Composite.dropTriviallyDeadConstantArrays();
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1702 return RetCode;
|
Miyagi Mitsuki <e135756@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1703 }
|