1 | //===-- Globals.cpp - Implement the GlobalValue & GlobalVariable class ----===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file implements the GlobalValue & GlobalVariable classes for the IR |
10 | // library. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "LLVMContextImpl.h" |
15 | #include "llvm/IR/ConstantRange.h" |
16 | #include "llvm/IR/Constants.h" |
17 | #include "llvm/IR/DerivedTypes.h" |
18 | #include "llvm/IR/GlobalAlias.h" |
19 | #include "llvm/IR/GlobalValue.h" |
20 | #include "llvm/IR/GlobalVariable.h" |
21 | #include "llvm/IR/Module.h" |
22 | #include "llvm/Support/Error.h" |
23 | #include "llvm/Support/ErrorHandling.h" |
24 | #include "llvm/Support/MD5.h" |
25 | #include "llvm/TargetParser/Triple.h" |
26 | using namespace llvm; |
27 | |
28 | //===----------------------------------------------------------------------===// |
29 | // GlobalValue Class |
30 | //===----------------------------------------------------------------------===// |
31 | |
32 | // GlobalValue should be a Constant, plus a type, a module, some flags, and an |
33 | // intrinsic ID. Add an assert to prevent people from accidentally growing |
34 | // GlobalValue while adding flags. |
35 | static_assert(sizeof(GlobalValue) == |
36 | sizeof(Constant) + 2 * sizeof(void *) + 2 * sizeof(unsigned), |
37 | "unexpected GlobalValue size growth" ); |
38 | |
39 | // GlobalObject adds a comdat. |
40 | static_assert(sizeof(GlobalObject) == sizeof(GlobalValue) + sizeof(void *), |
41 | "unexpected GlobalObject size growth" ); |
42 | |
43 | bool GlobalValue::isMaterializable() const { |
44 | if (const Function *F = dyn_cast<Function>(Val: this)) |
45 | return F->isMaterializable(); |
46 | return false; |
47 | } |
48 | Error GlobalValue::materialize() { return getParent()->materialize(GV: this); } |
49 | |
50 | /// Override destroyConstantImpl to make sure it doesn't get called on |
51 | /// GlobalValue's because they shouldn't be treated like other constants. |
52 | void GlobalValue::destroyConstantImpl() { |
53 | llvm_unreachable("You can't GV->destroyConstantImpl()!" ); |
54 | } |
55 | |
56 | Value *GlobalValue::handleOperandChangeImpl(Value *From, Value *To) { |
57 | llvm_unreachable("Unsupported class for handleOperandChange()!" ); |
58 | } |
59 | |
60 | /// copyAttributesFrom - copy all additional attributes (those not needed to |
61 | /// create a GlobalValue) from the GlobalValue Src to this one. |
62 | void GlobalValue::copyAttributesFrom(const GlobalValue *Src) { |
63 | setVisibility(Src->getVisibility()); |
64 | setUnnamedAddr(Src->getUnnamedAddr()); |
65 | setThreadLocalMode(Src->getThreadLocalMode()); |
66 | setDLLStorageClass(Src->getDLLStorageClass()); |
67 | setDSOLocal(Src->isDSOLocal()); |
68 | setPartition(Src->getPartition()); |
69 | if (Src->hasSanitizerMetadata()) |
70 | setSanitizerMetadata(Src->getSanitizerMetadata()); |
71 | else |
72 | removeSanitizerMetadata(); |
73 | } |
74 | |
75 | GlobalValue::GUID GlobalValue::getGUID(StringRef GlobalName) { |
76 | return MD5Hash(Str: GlobalName); |
77 | } |
78 | |
79 | void GlobalValue::removeFromParent() { |
80 | switch (getValueID()) { |
81 | #define HANDLE_GLOBAL_VALUE(NAME) \ |
82 | case Value::NAME##Val: \ |
83 | return static_cast<NAME *>(this)->removeFromParent(); |
84 | #include "llvm/IR/Value.def" |
85 | default: |
86 | break; |
87 | } |
88 | llvm_unreachable("not a global" ); |
89 | } |
90 | |
91 | void GlobalValue::eraseFromParent() { |
92 | switch (getValueID()) { |
93 | #define HANDLE_GLOBAL_VALUE(NAME) \ |
94 | case Value::NAME##Val: \ |
95 | return static_cast<NAME *>(this)->eraseFromParent(); |
96 | #include "llvm/IR/Value.def" |
97 | default: |
98 | break; |
99 | } |
100 | llvm_unreachable("not a global" ); |
101 | } |
102 | |
103 | GlobalObject::~GlobalObject() { setComdat(nullptr); } |
104 | |
105 | bool GlobalValue::isInterposable() const { |
106 | if (isInterposableLinkage(Linkage: getLinkage())) |
107 | return true; |
108 | return getParent() && getParent()->getSemanticInterposition() && |
109 | !isDSOLocal(); |
110 | } |
111 | |
112 | bool GlobalValue::canBenefitFromLocalAlias() const { |
113 | // See AsmPrinter::getSymbolPreferLocal(). For a deduplicate comdat kind, |
114 | // references to a discarded local symbol from outside the group are not |
115 | // allowed, so avoid the local alias. |
116 | auto isDeduplicateComdat = [](const Comdat *C) { |
117 | return C && C->getSelectionKind() != Comdat::NoDeduplicate; |
118 | }; |
119 | return hasDefaultVisibility() && |
120 | GlobalObject::isExternalLinkage(Linkage: getLinkage()) && !isDeclaration() && |
121 | !isa<GlobalIFunc>(Val: this) && !isDeduplicateComdat(getComdat()); |
122 | } |
123 | |
124 | const DataLayout &GlobalValue::getDataLayout() const { |
125 | return getParent()->getDataLayout(); |
126 | } |
127 | |
128 | void GlobalObject::setAlignment(MaybeAlign Align) { |
129 | assert((!Align || *Align <= MaximumAlignment) && |
130 | "Alignment is greater than MaximumAlignment!" ); |
131 | unsigned AlignmentData = encode(A: Align); |
132 | unsigned OldData = getGlobalValueSubClassData(); |
133 | setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData); |
134 | assert(getAlign() == Align && "Alignment representation error!" ); |
135 | } |
136 | |
137 | void GlobalObject::setAlignment(Align Align) { |
138 | assert(Align <= MaximumAlignment && |
139 | "Alignment is greater than MaximumAlignment!" ); |
140 | unsigned AlignmentData = encode(A: Align); |
141 | unsigned OldData = getGlobalValueSubClassData(); |
142 | setGlobalValueSubClassData((OldData & ~AlignmentMask) | AlignmentData); |
143 | assert(getAlign() && *getAlign() == Align && |
144 | "Alignment representation error!" ); |
145 | } |
146 | |
147 | void GlobalObject::copyAttributesFrom(const GlobalObject *Src) { |
148 | GlobalValue::copyAttributesFrom(Src); |
149 | setAlignment(Src->getAlign()); |
150 | setSection(Src->getSection()); |
151 | } |
152 | |
153 | std::string GlobalValue::getGlobalIdentifier(StringRef Name, |
154 | GlobalValue::LinkageTypes Linkage, |
155 | StringRef FileName) { |
156 | // Value names may be prefixed with a binary '1' to indicate |
157 | // that the backend should not modify the symbols due to any platform |
158 | // naming convention. Do not include that '1' in the PGO profile name. |
159 | Name.consume_front(Prefix: "\1" ); |
160 | |
161 | std::string GlobalName; |
162 | if (llvm::GlobalValue::isLocalLinkage(Linkage)) { |
163 | // For local symbols, prepend the main file name to distinguish them. |
164 | // Do not include the full path in the file name since there's no guarantee |
165 | // that it will stay the same, e.g., if the files are checked out from |
166 | // version control in different locations. |
167 | if (FileName.empty()) |
168 | GlobalName += "<unknown>" ; |
169 | else |
170 | GlobalName += FileName; |
171 | |
172 | GlobalName += GlobalIdentifierDelimiter; |
173 | } |
174 | GlobalName += Name; |
175 | return GlobalName; |
176 | } |
177 | |
178 | std::string GlobalValue::getGlobalIdentifier() const { |
179 | return getGlobalIdentifier(Name: getName(), Linkage: getLinkage(), |
180 | FileName: getParent()->getSourceFileName()); |
181 | } |
182 | |
183 | StringRef GlobalValue::getSection() const { |
184 | if (auto *GA = dyn_cast<GlobalAlias>(Val: this)) { |
185 | // In general we cannot compute this at the IR level, but we try. |
186 | if (const GlobalObject *GO = GA->getAliaseeObject()) |
187 | return GO->getSection(); |
188 | return "" ; |
189 | } |
190 | return cast<GlobalObject>(Val: this)->getSection(); |
191 | } |
192 | |
193 | const Comdat *GlobalValue::getComdat() const { |
194 | if (auto *GA = dyn_cast<GlobalAlias>(Val: this)) { |
195 | // In general we cannot compute this at the IR level, but we try. |
196 | if (const GlobalObject *GO = GA->getAliaseeObject()) |
197 | return const_cast<GlobalObject *>(GO)->getComdat(); |
198 | return nullptr; |
199 | } |
200 | // ifunc and its resolver are separate things so don't use resolver comdat. |
201 | if (isa<GlobalIFunc>(Val: this)) |
202 | return nullptr; |
203 | return cast<GlobalObject>(Val: this)->getComdat(); |
204 | } |
205 | |
206 | void GlobalObject::setComdat(Comdat *C) { |
207 | if (ObjComdat) |
208 | ObjComdat->removeUser(GO: this); |
209 | ObjComdat = C; |
210 | if (C) |
211 | C->addUser(GO: this); |
212 | } |
213 | |
214 | StringRef GlobalValue::getPartition() const { |
215 | if (!hasPartition()) |
216 | return "" ; |
217 | return getContext().pImpl->GlobalValuePartitions[this]; |
218 | } |
219 | |
220 | void GlobalValue::setPartition(StringRef S) { |
221 | // Do nothing if we're clearing the partition and it is already empty. |
222 | if (!hasPartition() && S.empty()) |
223 | return; |
224 | |
225 | // Get or create a stable partition name string and put it in the table in the |
226 | // context. |
227 | if (!S.empty()) |
228 | S = getContext().pImpl->Saver.save(S); |
229 | getContext().pImpl->GlobalValuePartitions[this] = S; |
230 | |
231 | // Update the HasPartition field. Setting the partition to the empty string |
232 | // means this global no longer has a partition. |
233 | HasPartition = !S.empty(); |
234 | } |
235 | |
236 | using SanitizerMetadata = GlobalValue::SanitizerMetadata; |
237 | const SanitizerMetadata &GlobalValue::getSanitizerMetadata() const { |
238 | assert(hasSanitizerMetadata()); |
239 | assert(getContext().pImpl->GlobalValueSanitizerMetadata.count(this)); |
240 | return getContext().pImpl->GlobalValueSanitizerMetadata[this]; |
241 | } |
242 | |
243 | void GlobalValue::setSanitizerMetadata(SanitizerMetadata Meta) { |
244 | getContext().pImpl->GlobalValueSanitizerMetadata[this] = Meta; |
245 | HasSanitizerMetadata = true; |
246 | } |
247 | |
248 | void GlobalValue::removeSanitizerMetadata() { |
249 | DenseMap<const GlobalValue *, SanitizerMetadata> &MetadataMap = |
250 | getContext().pImpl->GlobalValueSanitizerMetadata; |
251 | MetadataMap.erase(Val: this); |
252 | HasSanitizerMetadata = false; |
253 | } |
254 | |
255 | void GlobalValue::setNoSanitizeMetadata() { |
256 | SanitizerMetadata Meta; |
257 | Meta.NoAddress = true; |
258 | Meta.NoHWAddress = true; |
259 | setSanitizerMetadata(Meta); |
260 | } |
261 | |
262 | StringRef GlobalObject::getSectionImpl() const { |
263 | assert(hasSection()); |
264 | return getContext().pImpl->GlobalObjectSections[this]; |
265 | } |
266 | |
267 | void GlobalObject::setSection(StringRef S) { |
268 | // Do nothing if we're clearing the section and it is already empty. |
269 | if (!hasSection() && S.empty()) |
270 | return; |
271 | |
272 | // Get or create a stable section name string and put it in the table in the |
273 | // context. |
274 | if (!S.empty()) |
275 | S = getContext().pImpl->Saver.save(S); |
276 | getContext().pImpl->GlobalObjectSections[this] = S; |
277 | |
278 | // Update the HasSectionHashEntryBit. Setting the section to the empty string |
279 | // means this global no longer has a section. |
280 | setGlobalObjectFlag(Bit: HasSectionHashEntryBit, Val: !S.empty()); |
281 | } |
282 | |
283 | bool GlobalValue::isNobuiltinFnDef() const { |
284 | const Function *F = dyn_cast<Function>(Val: this); |
285 | if (!F || F->empty()) |
286 | return false; |
287 | return F->hasFnAttribute(Kind: Attribute::NoBuiltin); |
288 | } |
289 | |
290 | bool GlobalValue::isDeclaration() const { |
291 | // Globals are definitions if they have an initializer. |
292 | if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Val: this)) |
293 | return GV->getNumOperands() == 0; |
294 | |
295 | // Functions are definitions if they have a body. |
296 | if (const Function *F = dyn_cast<Function>(Val: this)) |
297 | return F->empty() && !F->isMaterializable(); |
298 | |
299 | // Aliases and ifuncs are always definitions. |
300 | assert(isa<GlobalAlias>(this) || isa<GlobalIFunc>(this)); |
301 | return false; |
302 | } |
303 | |
304 | bool GlobalObject::canIncreaseAlignment() const { |
305 | // Firstly, can only increase the alignment of a global if it |
306 | // is a strong definition. |
307 | if (!isStrongDefinitionForLinker()) |
308 | return false; |
309 | |
310 | // It also has to either not have a section defined, or, not have |
311 | // alignment specified. (If it is assigned a section, the global |
312 | // could be densely packed with other objects in the section, and |
313 | // increasing the alignment could cause padding issues.) |
314 | if (hasSection() && getAlign()) |
315 | return false; |
316 | |
317 | // On ELF platforms, we're further restricted in that we can't |
318 | // increase the alignment of any variable which might be emitted |
319 | // into a shared library, and which is exported. If the main |
320 | // executable accesses a variable found in a shared-lib, the main |
321 | // exe actually allocates memory for and exports the symbol ITSELF, |
322 | // overriding the symbol found in the library. That is, at link |
323 | // time, the observed alignment of the variable is copied into the |
324 | // executable binary. (A COPY relocation is also generated, to copy |
325 | // the initial data from the shadowed variable in the shared-lib |
326 | // into the location in the main binary, before running code.) |
327 | // |
328 | // And thus, even though you might think you are defining the |
329 | // global, and allocating the memory for the global in your object |
330 | // file, and thus should be able to set the alignment arbitrarily, |
331 | // that's not actually true. Doing so can cause an ABI breakage; an |
332 | // executable might have already been built with the previous |
333 | // alignment of the variable, and then assuming an increased |
334 | // alignment will be incorrect. |
335 | |
336 | // Conservatively assume ELF if there's no parent pointer. |
337 | bool isELF = |
338 | (!Parent || Triple(Parent->getTargetTriple()).isOSBinFormatELF()); |
339 | if (isELF && !isDSOLocal()) |
340 | return false; |
341 | |
342 | // GV with toc-data attribute is defined in a TOC entry. To mitigate TOC |
343 | // overflow, the alignment of such symbol should not be increased. Otherwise, |
344 | // padding is needed thus more TOC entries are wasted. |
345 | bool isXCOFF = |
346 | (!Parent || Triple(Parent->getTargetTriple()).isOSBinFormatXCOFF()); |
347 | if (isXCOFF) |
348 | if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Val: this)) |
349 | if (GV->hasAttribute(Kind: "toc-data" )) |
350 | return false; |
351 | |
352 | return true; |
353 | } |
354 | |
355 | template <typename Operation> |
356 | static const GlobalObject * |
357 | findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases, |
358 | const Operation &Op) { |
359 | if (auto *GO = dyn_cast<GlobalObject>(Val: C)) { |
360 | Op(*GO); |
361 | return GO; |
362 | } |
363 | if (auto *GA = dyn_cast<GlobalAlias>(Val: C)) { |
364 | Op(*GA); |
365 | if (Aliases.insert(V: GA).second) |
366 | return findBaseObject(GA->getOperand(i_nocapture: 0), Aliases, Op); |
367 | } |
368 | if (auto *CE = dyn_cast<ConstantExpr>(Val: C)) { |
369 | switch (CE->getOpcode()) { |
370 | case Instruction::Add: { |
371 | auto *LHS = findBaseObject(CE->getOperand(i_nocapture: 0), Aliases, Op); |
372 | auto *RHS = findBaseObject(CE->getOperand(i_nocapture: 1), Aliases, Op); |
373 | if (LHS && RHS) |
374 | return nullptr; |
375 | return LHS ? LHS : RHS; |
376 | } |
377 | case Instruction::Sub: { |
378 | if (findBaseObject(CE->getOperand(i_nocapture: 1), Aliases, Op)) |
379 | return nullptr; |
380 | return findBaseObject(CE->getOperand(i_nocapture: 0), Aliases, Op); |
381 | } |
382 | case Instruction::IntToPtr: |
383 | case Instruction::PtrToInt: |
384 | case Instruction::BitCast: |
385 | case Instruction::GetElementPtr: |
386 | return findBaseObject(CE->getOperand(i_nocapture: 0), Aliases, Op); |
387 | default: |
388 | break; |
389 | } |
390 | } |
391 | return nullptr; |
392 | } |
393 | |
394 | const GlobalObject *GlobalValue::getAliaseeObject() const { |
395 | DenseSet<const GlobalAlias *> Aliases; |
396 | return findBaseObject(C: this, Aliases, Op: [](const GlobalValue &) {}); |
397 | } |
398 | |
399 | bool GlobalValue::isAbsoluteSymbolRef() const { |
400 | auto *GO = dyn_cast<GlobalObject>(Val: this); |
401 | if (!GO) |
402 | return false; |
403 | |
404 | return GO->getMetadata(KindID: LLVMContext::MD_absolute_symbol); |
405 | } |
406 | |
407 | std::optional<ConstantRange> GlobalValue::getAbsoluteSymbolRange() const { |
408 | auto *GO = dyn_cast<GlobalObject>(Val: this); |
409 | if (!GO) |
410 | return std::nullopt; |
411 | |
412 | MDNode *MD = GO->getMetadata(KindID: LLVMContext::MD_absolute_symbol); |
413 | if (!MD) |
414 | return std::nullopt; |
415 | |
416 | return getConstantRangeFromMetadata(RangeMD: *MD); |
417 | } |
418 | |
419 | bool GlobalValue::canBeOmittedFromSymbolTable() const { |
420 | if (!hasLinkOnceODRLinkage()) |
421 | return false; |
422 | |
423 | // We assume that anyone who sets global unnamed_addr on a non-constant |
424 | // knows what they're doing. |
425 | if (hasGlobalUnnamedAddr()) |
426 | return true; |
427 | |
428 | // If it is a non constant variable, it needs to be uniqued across shared |
429 | // objects. |
430 | if (auto *Var = dyn_cast<GlobalVariable>(Val: this)) |
431 | if (!Var->isConstant()) |
432 | return false; |
433 | |
434 | return hasAtLeastLocalUnnamedAddr(); |
435 | } |
436 | |
437 | //===----------------------------------------------------------------------===// |
438 | // GlobalVariable Implementation |
439 | //===----------------------------------------------------------------------===// |
440 | |
441 | GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link, |
442 | Constant *InitVal, const Twine &Name, |
443 | ThreadLocalMode TLMode, unsigned AddressSpace, |
444 | bool isExternallyInitialized) |
445 | : GlobalObject(Ty, Value::GlobalVariableVal, |
446 | OperandTraits<GlobalVariable>::op_begin(U: this), |
447 | InitVal != nullptr, Link, Name, AddressSpace), |
448 | isConstantGlobal(constant), |
449 | isExternallyInitializedConstant(isExternallyInitialized) { |
450 | assert(!Ty->isFunctionTy() && PointerType::isValidElementType(Ty) && |
451 | "invalid type for global variable" ); |
452 | setThreadLocalMode(TLMode); |
453 | if (InitVal) { |
454 | assert(InitVal->getType() == Ty && |
455 | "Initializer should be the same type as the GlobalVariable!" ); |
456 | Op<0>() = InitVal; |
457 | } |
458 | } |
459 | |
460 | GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant, |
461 | LinkageTypes Link, Constant *InitVal, |
462 | const Twine &Name, GlobalVariable *Before, |
463 | ThreadLocalMode TLMode, |
464 | std::optional<unsigned> AddressSpace, |
465 | bool isExternallyInitialized) |
466 | : GlobalVariable(Ty, constant, Link, InitVal, Name, TLMode, |
467 | AddressSpace |
468 | ? *AddressSpace |
469 | : M.getDataLayout().getDefaultGlobalsAddressSpace(), |
470 | isExternallyInitialized) { |
471 | if (Before) |
472 | Before->getParent()->insertGlobalVariable(Where: Before->getIterator(), GV: this); |
473 | else |
474 | M.insertGlobalVariable(GV: this); |
475 | } |
476 | |
477 | void GlobalVariable::removeFromParent() { |
478 | getParent()->removeGlobalVariable(GV: this); |
479 | } |
480 | |
481 | void GlobalVariable::eraseFromParent() { |
482 | getParent()->eraseGlobalVariable(GV: this); |
483 | } |
484 | |
485 | void GlobalVariable::setInitializer(Constant *InitVal) { |
486 | if (!InitVal) { |
487 | if (hasInitializer()) { |
488 | // Note, the num operands is used to compute the offset of the operand, so |
489 | // the order here matters. Clearing the operand then clearing the num |
490 | // operands ensures we have the correct offset to the operand. |
491 | Op<0>().set(nullptr); |
492 | setGlobalVariableNumOperands(0); |
493 | } |
494 | } else { |
495 | assert(InitVal->getType() == getValueType() && |
496 | "Initializer type must match GlobalVariable type" ); |
497 | // Note, the num operands is used to compute the offset of the operand, so |
498 | // the order here matters. We need to set num operands to 1 first so that |
499 | // we get the correct offset to the first operand when we set it. |
500 | if (!hasInitializer()) |
501 | setGlobalVariableNumOperands(1); |
502 | Op<0>().set(InitVal); |
503 | } |
504 | } |
505 | |
506 | /// Copy all additional attributes (those not needed to create a GlobalVariable) |
507 | /// from the GlobalVariable Src to this one. |
508 | void GlobalVariable::copyAttributesFrom(const GlobalVariable *Src) { |
509 | GlobalObject::copyAttributesFrom(Src); |
510 | setExternallyInitialized(Src->isExternallyInitialized()); |
511 | setAttributes(Src->getAttributes()); |
512 | if (auto CM = Src->getCodeModel()) |
513 | setCodeModel(*CM); |
514 | } |
515 | |
516 | void GlobalVariable::dropAllReferences() { |
517 | User::dropAllReferences(); |
518 | clearMetadata(); |
519 | } |
520 | |
521 | void GlobalVariable::setCodeModel(CodeModel::Model CM) { |
522 | unsigned CodeModelData = static_cast<unsigned>(CM) + 1; |
523 | unsigned OldData = getGlobalValueSubClassData(); |
524 | unsigned NewData = (OldData & ~(CodeModelMask << CodeModelShift)) | |
525 | (CodeModelData << CodeModelShift); |
526 | setGlobalValueSubClassData(NewData); |
527 | assert(getCodeModel() == CM && "Code model representation error!" ); |
528 | } |
529 | |
530 | //===----------------------------------------------------------------------===// |
531 | // GlobalAlias Implementation |
532 | //===----------------------------------------------------------------------===// |
533 | |
534 | GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link, |
535 | const Twine &Name, Constant *Aliasee, |
536 | Module *ParentModule) |
537 | : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name, |
538 | AddressSpace) { |
539 | setAliasee(Aliasee); |
540 | if (ParentModule) |
541 | ParentModule->insertAlias(Alias: this); |
542 | } |
543 | |
544 | GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, |
545 | LinkageTypes Link, const Twine &Name, |
546 | Constant *Aliasee, Module *ParentModule) { |
547 | return new GlobalAlias(Ty, AddressSpace, Link, Name, Aliasee, ParentModule); |
548 | } |
549 | |
550 | GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, |
551 | LinkageTypes Linkage, const Twine &Name, |
552 | Module *Parent) { |
553 | return create(Ty, AddressSpace, Link: Linkage, Name, Aliasee: nullptr, ParentModule: Parent); |
554 | } |
555 | |
556 | GlobalAlias *GlobalAlias::create(Type *Ty, unsigned AddressSpace, |
557 | LinkageTypes Linkage, const Twine &Name, |
558 | GlobalValue *Aliasee) { |
559 | return create(Ty, AddressSpace, Link: Linkage, Name, Aliasee, ParentModule: Aliasee->getParent()); |
560 | } |
561 | |
562 | GlobalAlias *GlobalAlias::create(LinkageTypes Link, const Twine &Name, |
563 | GlobalValue *Aliasee) { |
564 | return create(Ty: Aliasee->getValueType(), AddressSpace: Aliasee->getAddressSpace(), Linkage: Link, Name, |
565 | Aliasee); |
566 | } |
567 | |
568 | GlobalAlias *GlobalAlias::create(const Twine &Name, GlobalValue *Aliasee) { |
569 | return create(Link: Aliasee->getLinkage(), Name, Aliasee); |
570 | } |
571 | |
572 | void GlobalAlias::removeFromParent() { getParent()->removeAlias(Alias: this); } |
573 | |
574 | void GlobalAlias::eraseFromParent() { getParent()->eraseAlias(Alias: this); } |
575 | |
576 | void GlobalAlias::setAliasee(Constant *Aliasee) { |
577 | assert((!Aliasee || Aliasee->getType() == getType()) && |
578 | "Alias and aliasee types should match!" ); |
579 | Op<0>().set(Aliasee); |
580 | } |
581 | |
582 | const GlobalObject *GlobalAlias::getAliaseeObject() const { |
583 | DenseSet<const GlobalAlias *> Aliases; |
584 | return findBaseObject(C: getOperand(i_nocapture: 0), Aliases, Op: [](const GlobalValue &) {}); |
585 | } |
586 | |
587 | //===----------------------------------------------------------------------===// |
588 | // GlobalIFunc Implementation |
589 | //===----------------------------------------------------------------------===// |
590 | |
591 | GlobalIFunc::GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Link, |
592 | const Twine &Name, Constant *Resolver, |
593 | Module *ParentModule) |
594 | : GlobalObject(Ty, Value::GlobalIFuncVal, &Op<0>(), 1, Link, Name, |
595 | AddressSpace) { |
596 | setResolver(Resolver); |
597 | if (ParentModule) |
598 | ParentModule->insertIFunc(IFunc: this); |
599 | } |
600 | |
601 | GlobalIFunc *GlobalIFunc::create(Type *Ty, unsigned AddressSpace, |
602 | LinkageTypes Link, const Twine &Name, |
603 | Constant *Resolver, Module *ParentModule) { |
604 | return new GlobalIFunc(Ty, AddressSpace, Link, Name, Resolver, ParentModule); |
605 | } |
606 | |
607 | void GlobalIFunc::removeFromParent() { getParent()->removeIFunc(IFunc: this); } |
608 | |
609 | void GlobalIFunc::eraseFromParent() { getParent()->eraseIFunc(IFunc: this); } |
610 | |
611 | const Function *GlobalIFunc::getResolverFunction() const { |
612 | return dyn_cast<Function>(Val: getResolver()->stripPointerCastsAndAliases()); |
613 | } |
614 | |
615 | void GlobalIFunc::applyAlongResolverPath( |
616 | function_ref<void(const GlobalValue &)> Op) const { |
617 | DenseSet<const GlobalAlias *> Aliases; |
618 | findBaseObject(C: getResolver(), Aliases, Op); |
619 | } |
620 | |