llvm.org GIT mirror llvm / ba49223
[GCC] Attribute ifunc support in llvm This patch add support for GCC attribute((ifunc("resolver"))) for targets that use ELF as object file format. In general ifunc is a special kind of function alias with type @gnu_indirect_function. Patch for Clang http://reviews.llvm.org/D15524 Differential Revision: http://reviews.llvm.org/D15525 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265667 91177308-0d34-0410-b5e6-96231b3b80d8 Dmitry Polukhin 3 years ago
24 changed file(s) with 369 addition(s) and 22 deletion(s). Raw diff Collapse all Expand all
762762
763763 * No global value in the expression can be a declaration, since that
764764 would require a relocation, which is not possible.
765
766 .. _langref_ifunc:
767
768 IFuncs
769 -------
770
771 IFuncs, like as aliases, don't create any new data or func. They are just a new
772 symbol that dynamic linker resolves at runtime by calling a resolver function.
773
774 IFuncs have a name and a resolver that is a function called by dynamic linker
775 that returns address of another function associated with the name.
776
777 IFunc may have an optional :ref:`linkage type ` and an optional
778 :ref:`visibility style `.
779
780 Syntax::
781
782 @ = [Linkage] [Visibility] ifunc , * @
783
765784
766785 .. _langref_comdats:
767786
109109
110110 // HASH: [5*i32]
111111 MODULE_CODE_HASH = 17,
112
113 // IFUNC: [ifunc value type, addrspace, resolver val#, linkage, visibility]
114 MODULE_CODE_IFUNC = 18,
112115 };
113116
114117 /// PARAMATTR blocks have code for defining a parameter attribute set.
0 //===-------- llvm/GlobalIFunc.h - GlobalIFunc class ------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \brief
10 /// This file contains the declaration of the GlobalIFunc class, which
11 /// represents a single indirect function in the IR. Indirect function uses
12 /// ELF symbol type extension to mark that the address of a declaration should
13 /// be resolved at runtime by calling a resolver function.
14 ///
15 //===----------------------------------------------------------------------===//
16
17 #ifndef LLVM_IR_GLOBALIFUNC_H
18 #define LLVM_IR_GLOBALIFUNC_H
19
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/ADT/ilist_node.h"
22 #include "llvm/IR/GlobalIndirectSymbol.h"
23
24 namespace llvm {
25
26 class Module;
27
28 // Traits class for using GlobalIFunc in symbol table in Module.
29 template class SymbolTableListTraits;
30
31 class GlobalIFunc final : public GlobalIndirectSymbol,
32 public ilist_node {
33 friend class SymbolTableListTraits;
34 void operator=(const GlobalIFunc &) = delete;
35 GlobalIFunc(const GlobalIFunc &) = delete;
36
37 void setParent(Module *parent);
38
39 GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage,
40 const Twine &Name, Constant *Resolver, Module *Parent);
41
42 public:
43 /// If a parent module is specified, the ifunc is automatically inserted into
44 /// the end of the specified module's ifunc list.
45 static GlobalIFunc *create(Type *Ty, unsigned AddressSpace,
46 LinkageTypes Linkage, const Twine &Name,
47 Constant *Resolver, Module *Parent);
48
49 /// This method unlinks 'this' from the containing module, but does not
50 /// delete it.
51 void removeFromParent() final;
52
53 /// This method unlinks 'this' from the containing module and deletes it.
54 void eraseFromParent() final;
55
56 /// These methods retrieve and set ifunc resolver function.
57 void setResolver(Constant *Resolver) {
58 setIndirectSymbol(Resolver);
59 }
60 const Constant *getResolver() const {
61 return getIndirectSymbol();
62 }
63 Constant *getResolver() {
64 return getIndirectSymbol();
65 }
66
67 // Methods for support type inquiry through isa, cast, and dyn_cast:
68 static inline bool classof(const Value *V) {
69 return V->getValueID() == Value::GlobalIFuncVal;
70 }
71 };
72
73 } // End llvm namespace
74
75 #endif
5050
5151 // Methods for support type inquiry through isa, cast, and dyn_cast:
5252 static inline bool classof(const Value *V) {
53 return V->getValueID() == Value::GlobalAliasVal;
53 return V->getValueID() == Value::GlobalAliasVal ||
54 V->getValueID() == Value::GlobalIFuncVal;
5455 }
5556 };
5657
387387 static bool classof(const Value *V) {
388388 return V->getValueID() == Value::FunctionVal ||
389389 V->getValueID() == Value::GlobalVariableVal ||
390 V->getValueID() == Value::GlobalAliasVal;
390 V->getValueID() == Value::GlobalAliasVal ||
391 V->getValueID() == Value::GlobalIFuncVal;
391392 }
392393 };
393394
2020 #include "llvm/IR/DataLayout.h"
2121 #include "llvm/IR/Function.h"
2222 #include "llvm/IR/GlobalAlias.h"
23 #include "llvm/IR/GlobalIFunc.h"
2324 #include "llvm/IR/GlobalVariable.h"
2425 #include "llvm/IR/Metadata.h"
2526 #include "llvm/Support/CBindingWrapping.h"
7475 typedef SymbolTableList FunctionListType;
7576 /// The type for the list of aliases.
7677 typedef SymbolTableList AliasListType;
78 /// The type for the list of ifuncs.
79 typedef SymbolTableList IFuncListType;
7780 /// The type for the list of named metadata.
7881 typedef ilist NamedMDListType;
7982 /// The type of the comdat "symbol" table.
98101 typedef AliasListType::iterator alias_iterator;
99102 /// The Global Alias constant iterator
100103 typedef AliasListType::const_iterator const_alias_iterator;
104
105 /// The Global IFunc iterators.
106 typedef IFuncListType::iterator ifunc_iterator;
107 /// The Global IFunc constant iterator
108 typedef IFuncListType::const_iterator const_ifunc_iterator;
101109
102110 /// The named metadata iterators.
103111 typedef NamedMDListType::iterator named_metadata_iterator;
162170 GlobalListType GlobalList; ///< The Global Variables in the module
163171 FunctionListType FunctionList; ///< The Functions in the module
164172 AliasListType AliasList; ///< The Aliases in the module
173 IFuncListType IFuncList; ///< The IFuncs in the module
165174 NamedMDListType NamedMDList; ///< The named metadata in the module
166175 std::string GlobalScopeAsm; ///< Inline Asm at global scope.
167176 ValueSymbolTable *ValSymTab; ///< Symbol table for values
383392 GlobalAlias *getNamedAlias(StringRef Name) const;
384393
385394 /// @}
395 /// @name Global IFunc Accessors
396 /// @{
397
398 /// Return the global ifunc in the module with the specified name, of
399 /// arbitrary type. This method returns null if a global with the specified
400 /// name is not found.
401 GlobalIFunc *getNamedIFunc(StringRef Name) const;
402
403 /// @}
386404 /// @name Named Metadata Accessors
387405 /// @{
388406
485503 static AliasListType Module::*getSublistAccess(GlobalAlias*) {
486504 return &Module::AliasList;
487505 }
506 /// Get the Module's list of ifuncs (constant).
507 const IFuncListType &getIFuncList() const { return IFuncList; }
508 /// Get the Module's list of ifuncs.
509 IFuncListType &getIFuncList() { return IFuncList; }
510 static IFuncListType Module::*getSublistAccess(GlobalIFunc*) {
511 return &Module::IFuncList;
512 }
488513 /// Get the Module's list of named metadata (constant).
489514 const NamedMDListType &getNamedMDList() const { return NamedMDList; }
490515 /// Get the Module's list of named metadata.
559584 }
560585
561586 /// @}
587 /// @name IFunc Iteration
588 /// @{
589
590 ifunc_iterator ifunc_begin() { return IFuncList.begin(); }
591 const_ifunc_iterator ifunc_begin() const { return IFuncList.begin(); }
592 ifunc_iterator ifunc_end () { return IFuncList.end(); }
593 const_ifunc_iterator ifunc_end () const { return IFuncList.end(); }
594 size_t ifunc_size () const { return IFuncList.size(); }
595 bool ifunc_empty() const { return IFuncList.empty(); }
596
597 iterator_range ifuncs() {
598 return make_range(ifunc_begin(), ifunc_end());
599 }
600 iterator_range ifuncs() const {
601 return make_range(ifunc_begin(), ifunc_end());
602 }
603
604 /// @}
562605 /// @name Named Metadata Iteration
563606 /// @{
564607
4848 class Instruction;
4949 class GlobalVariable;
5050 class GlobalAlias;
51 class GlobalIFunc;
5152 class Module;
5253 #define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT) \
5354 template <> struct SymbolTableListParentType { typedef PARENT type; };
5758 DEFINE_SYMBOL_TABLE_PARENT_TYPE(Function, Module)
5859 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable, Module)
5960 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalAlias, Module)
61 DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalIFunc, Module)
6062 #undef DEFINE_SYMBOL_TABLE_PARENT_TYPE
6163
6264 template class SymbolTableList;
5959
6060 HANDLE_GLOBAL_VALUE(Function)
6161 HANDLE_GLOBAL_VALUE(GlobalAlias)
62 HANDLE_GLOBAL_VALUE(GlobalIFunc)
6263 HANDLE_GLOBAL_VALUE(GlobalVariable)
6364 HANDLE_CONSTANT(BlockAddress)
6465 HANDLE_CONSTANT(ConstantExpr)
3131 class DataLayout;
3232 class Function;
3333 class GlobalAlias;
34 class GlobalIFunc;
3435 class GlobalIndirectSymbol;
3536 class GlobalObject;
3637 class GlobalValue;
750751 }
751752 };
752753
754 template <> struct isa_impl {
755 static inline bool doit(const Value &Val) {
756 return Val.getValueID() == Value::GlobalIFuncVal;
757 }
758 };
759
753760 template <> struct isa_impl {
754761 static inline bool doit(const Value &Val) {
755 return isa(Val);
762 return isa(Val) || isa(Val);
756763 }
757764 };
758765
3838 friend class SymbolTableListTraits;
3939 friend class SymbolTableListTraits;
4040 friend class SymbolTableListTraits;
41 friend class SymbolTableListTraits;
4142 /// @name Types
4243 /// @{
4344 public:
255255
256256 LLVMFunctionValueKind,
257257 LLVMGlobalAliasValueKind,
258 LLVMGlobalIFuncValueKind,
258259 LLVMGlobalVariableValueKind,
259260 LLVMBlockAddressValueKind,
260261 LLVMConstantExprValueKind,
559559 KEYWORD(addrspace);
560560 KEYWORD(section);
561561 KEYWORD(alias);
562 KEYWORD(ifunc);
562563 KEYWORD(module);
563564 KEYWORD(asm);
564565 KEYWORD(sideeffect);
466466 }
467467
468468 /// ParseUnnamedGlobal:
469 /// OptionalVisibility ALIAS ...
469 /// OptionalVisibility (ALIAS | IFUNC) ...
470470 /// OptionalLinkage OptionalVisibility OptionalDLLStorageClass
471471 /// ... -> global variable
472 /// GlobalID '=' OptionalVisibility ALIAS ...
472 /// GlobalID '=' OptionalVisibility (ALIAS | IFUNC) ...
473473 /// GlobalID '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
474474 /// ... -> global variable
475475 bool LLParser::ParseUnnamedGlobal() {
499499 parseOptionalUnnamedAddr(UnnamedAddr))
500500 return true;
501501
502 if (Lex.getKind() != lltok::kw_alias)
502 if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
503503 return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
504504 DLLStorageClass, TLM, UnnamedAddr);
505505
508508 }
509509
510510 /// ParseNamedGlobal:
511 /// GlobalVar '=' OptionalVisibility ALIAS ...
511 /// GlobalVar '=' OptionalVisibility (ALIAS | IFUNC) ...
512512 /// GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
513513 /// ... -> global variable
514514 bool LLParser::ParseNamedGlobal() {
529529 parseOptionalUnnamedAddr(UnnamedAddr))
530530 return true;
531531
532 if (Lex.getKind() != lltok::kw_alias)
532 if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
533533 return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
534534 DLLStorageClass, TLM, UnnamedAddr);
535535
694694 /// parseIndirectSymbol:
695695 /// ::= GlobalVar '=' OptionalLinkage OptionalVisibility
696696 /// OptionalDLLStorageClass OptionalThreadLocal
697 /// OptionalUnnamedAddr 'alias' IndirectSymbol
697 /// OptionalUnnamedAddr 'alias|ifunc' IndirectSymbol
698698 ///
699699 /// IndirectSymbol
700700 /// ::= TypeAndValue
709709 bool IsAlias;
710710 if (Lex.getKind() == lltok::kw_alias)
711711 IsAlias = true;
712 else if (Lex.getKind() == lltok::kw_ifunc)
713 IsAlias = false;
712714 else
713 llvm_unreachable("Not an alias!");
715 llvm_unreachable("Not an alias or ifunc!");
714716 Lex.Lex();
715717
716718 GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes) L;
725727 Type *Ty;
726728 LocTy ExplicitTypeLoc = Lex.getLoc();
727729 if (ParseType(Ty) ||
728 ParseToken(lltok::comma, "expected comma after alias's type"))
730 ParseToken(lltok::comma, "expected comma after alias or ifunc's type"))
729731 return true;
730732
731733 Constant *Aliasee;
749751 Type *AliaseeType = Aliasee->getType();
750752 auto *PTy = dyn_cast(AliaseeType);
751753 if (!PTy)
752 return Error(AliaseeLoc, "An alias must have pointer type");
754 return Error(AliaseeLoc, "An alias or ifunc must have pointer type");
753755 unsigned AddrSpace = PTy->getAddressSpace();
754756
755757 if (IsAlias && Ty != PTy->getElementType())
787789 (GlobalValue::LinkageTypes)Linkage, Name,
788790 Aliasee, /*Parent*/ nullptr));
789791 else
790 llvm_unreachable("Not an alias!");
792 GA.reset(GlobalIFunc::create(Ty, AddrSpace,
793 (GlobalValue::LinkageTypes)Linkage, Name,
794 Aliasee, /*Parent*/ nullptr));
791795 GA->setThreadLocalMode(TLM);
792796 GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
793797 GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
813817 if (IsAlias)
814818 M->getAliasList().push_back(cast(GA.get()));
815819 else
816 llvm_unreachable("Not an alias!");
820 M->getIFuncList().push_back(cast(GA.get()));
817821 assert(GA->getName() == Name && "Should not be a name conflict!");
818822
819823 // The module owns this now
7979 kw_addrspace,
8080 kw_section,
8181 kw_alias,
82 kw_ifunc,
8283 kw_module,
8384 kw_asm,
8485 kw_sideeffect,
36573657 }
36583658 // ALIAS: [alias type, addrspace, aliasee val#, linkage]
36593659 // ALIAS: [alias type, addrspace, aliasee val#, linkage, visibility, dllstorageclass]
3660 // IFUNC: [alias type, addrspace, aliasee val#, linkage, visibility, dllstorageclass]
3661 case bitc::MODULE_CODE_IFUNC:
36603662 case bitc::MODULE_CODE_ALIAS:
36613663 case bitc::MODULE_CODE_ALIAS_OLD: {
36623664 bool NewRecord = BitCode != bitc::MODULE_CODE_ALIAS_OLD;
36833685 GlobalIndirectSymbol *NewGA;
36843686 if (BitCode == bitc::MODULE_CODE_ALIAS ||
36853687 BitCode == bitc::MODULE_CODE_ALIAS_OLD)
3686 NewGA = GlobalAlias::create(
3687 Ty, AddrSpace, getDecodedLinkage(Linkage), "", TheModule);
3688 NewGA = GlobalAlias::create(Ty, AddrSpace, getDecodedLinkage(Linkage),
3689 "", TheModule);
36883690 else
3689 llvm_unreachable("Not an alias!");
3691 NewGA = GlobalIFunc::create(Ty, AddrSpace, getDecodedLinkage(Linkage),
3692 "", nullptr, TheModule);
36903693 // Old bitcode files didn't have visibility field.
36913694 // Local linkage must have default visibility.
36923695 if (OpNum != Record.size()) {
805805 Vals.push_back(A.hasUnnamedAddr());
806806 unsigned AbbrevToUse = 0;
807807 Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
808 Vals.clear();
809 }
810
811 // Emit the ifunc information.
812 for (const GlobalIFunc &I : M->ifuncs()) {
813 // IFUNC: [ifunc type, address space, resolver val#, linkage, visibility]
814 Vals.push_back(VE.getTypeID(I.getValueType()));
815 Vals.push_back(I.getType()->getAddressSpace());
816 Vals.push_back(VE.getValueID(I.getResolver()));
817 Vals.push_back(getEncodedLinkage(I));
818 Vals.push_back(getEncodedVisibility(I));
819 Stream.EmitRecord(bitc::MODULE_CODE_IFUNC, Vals);
808820 Vals.clear();
809821 }
810822
8585 for (const GlobalAlias &A : M.aliases())
8686 if (!isa(A.getAliasee()))
8787 orderValue(A.getAliasee(), OM);
88 for (const GlobalIFunc &I : M.ifuncs())
89 if (!isa(I.getResolver()))
90 orderValue(I.getResolver(), OM);
8891 for (const Function &F : M) {
8992 for (const Use &U : F.operands())
9093 if (!isa(U.get()))
104107 orderValue(&F, OM);
105108 for (const GlobalAlias &A : M.aliases())
106109 orderValue(&A, OM);
110 for (const GlobalIFunc &I : M.ifuncs())
111 orderValue(&I, OM);
107112 for (const GlobalVariable &G : M.globals())
108113 orderValue(&G, OM);
109114 OM.LastGlobalValueID = OM.size();
260265 predictValueUseListOrder(&F, nullptr, OM, Stack);
261266 for (const GlobalAlias &A : M.aliases())
262267 predictValueUseListOrder(&A, nullptr, OM, Stack);
268 for (const GlobalIFunc &I : M.ifuncs())
269 predictValueUseListOrder(&I, nullptr, OM, Stack);
263270 for (const GlobalVariable &G : M.globals())
264271 if (G.hasInitializer())
265272 predictValueUseListOrder(G.getInitializer(), nullptr, OM, Stack);
266273 for (const GlobalAlias &A : M.aliases())
267274 predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack);
275 for (const GlobalIFunc &I : M.ifuncs())
276 predictValueUseListOrder(I.getResolver(), nullptr, OM, Stack);
268277 for (const Function &F : M) {
269278 for (const Use &U : F.operands())
270279 predictValueUseListOrder(U.get(), nullptr, OM, Stack);
297306 for (const GlobalAlias &GA : M.aliases())
298307 EnumerateValue(&GA);
299308
309 // Enumerate the ifuncs.
310 for (const GlobalIFunc &GIF : M.ifuncs())
311 EnumerateValue(&GIF);
312
300313 // Remember what is the cutoff between globalvalue's and other constants.
301314 unsigned FirstConstant = Values.size();
302315
308321 // Enumerate the aliasees.
309322 for (const GlobalAlias &GA : M.aliases())
310323 EnumerateValue(GA.getAliasee());
324
325 // Enumerate the ifunc resolvers.
326 for (const GlobalIFunc &GIF : M.ifuncs())
327 EnumerateValue(GIF.getResolver());
311328
312329 // Enumerate any optional Function data.
313330 for (const Function &F : M)
10681068 else if (GIS.hasWeakLinkage() || GIS.hasLinkOnceLinkage())
10691069 OutStreamer->EmitSymbolAttribute(Name, MCSA_WeakReference);
10701070 else
1071 assert(GIS.hasLocalLinkage() && "Invalid alias linkage");
1071 assert(GIS.hasLocalLinkage() && "Invalid alias or ifunc linkage");
10721072
10731073 // Set the symbol type to function if the alias has a function type.
10741074 // This affects codegen when the aliasee is not a function.
1075 if (GIS.getType()->getPointerElementType()->isFunctionTy())
1075 if (GIS.getType()->getPointerElementType()->isFunctionTy()) {
10761076 OutStreamer->EmitSymbolAttribute(Name, MCSA_ELF_TypeFunction);
1077 if (isa(GIS))
1078 OutStreamer->EmitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction);
1079 }
10771080
10781081 EmitVisibility(Name, GIS.getVisibility());
10791082
12081211 emitGlobalIndirectSymbol(M, *AncestorAlias);
12091212 AliasStack.clear();
12101213 }
1214 for (const auto &IFunc : M.ifuncs())
1215 emitGlobalIndirectSymbol(M, IFunc);
12111216
12121217 GCModuleInfo *MI = getAnalysisIfAvailable();
12131218 assert(MI && "AsmPrinter didn't require GCModuleInfo?");
101101 orderValue(A.getAliasee(), OM);
102102 orderValue(&A, OM);
103103 }
104 for (const GlobalIFunc &I : M->ifuncs()) {
105 if (!isa(I.getResolver()))
106 orderValue(I.getResolver(), OM);
107 orderValue(&I, OM);
108 }
104109 for (const Function &F : *M) {
105110 for (const Use &U : F.operands())
106111 if (!isa(U.get()))
248253 predictValueUseListOrder(&F, nullptr, OM, Stack);
249254 for (const GlobalAlias &A : M->aliases())
250255 predictValueUseListOrder(&A, nullptr, OM, Stack);
256 for (const GlobalIFunc &I : M->ifuncs())
257 predictValueUseListOrder(&I, nullptr, OM, Stack);
251258 for (const GlobalVariable &G : M->globals())
252259 if (G.hasInitializer())
253260 predictValueUseListOrder(G.getInitializer(), nullptr, OM, Stack);
254261 for (const GlobalAlias &A : M->aliases())
255262 predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack);
263 for (const GlobalIFunc &I : M->ifuncs())
264 predictValueUseListOrder(I.getResolver(), nullptr, OM, Stack);
256265 for (const Function &F : *M)
257266 for (const Use &U : F.operands())
258267 predictValueUseListOrder(U.get(), nullptr, OM, Stack);
728737 if (const GlobalAlias *GA = dyn_cast(V))
729738 return new SlotTracker(GA->getParent());
730739
740 if (const GlobalIFunc *GIF = dyn_cast(V))
741 return new SlotTracker(GIF->getParent());
742
731743 if (const Function *Func = dyn_cast(V))
732744 return new SlotTracker(Func);
733745
779791 for (const GlobalAlias &A : TheModule->aliases()) {
780792 if (!A.hasName())
781793 CreateModuleSlot(&A);
794 }
795
796 for (const GlobalIFunc &I : TheModule->ifuncs()) {
797 if (!I.hasName())
798 CreateModuleSlot(&I);
782799 }
783800
784801 // Add metadata used by named metadata.
944961
945962 ST_DEBUG(" Inserting value [" << V->getType() << "] = " << V << " slot=" <<
946963 DestSlot << " [");
947 // G = Global, F = Function, A = Alias, o = other
964 // G = Global, F = Function, A = Alias, I = IFunc, o = other
948965 ST_DEBUG((isa(V) ? 'G' :
949966 (isa(V) ? 'F' :
950 (isa(V) ? 'A' : 'o'))) << "]\n");
967 (isa(V) ? 'A' :
968 (isa(V) ? 'I' : 'o')))) << "]\n");
951969 }
952970
953971 /// CreateSlot - Create a new slot for the specified value if it has no name.
22522270 for (const GlobalAlias &GA : M->aliases())
22532271 printIndirectSymbol(&GA);
22542272
2273 // Output all ifuncs.
2274 if (!M->ifunc_empty()) Out << "\n";
2275 for (const GlobalIFunc &GI : M->ifuncs())
2276 printIndirectSymbol(&GI);
2277
22552278 // Output global use-lists.
22562279 printUseLists(nullptr);
22572280
24472470
24482471 if (isa(GIS))
24492472 Out << "alias ";
2473 else if (isa(GIS))
2474 Out << "ifunc ";
24502475 else
2451 llvm_unreachable("Not an alias!");
2476 llvm_unreachable("Not an alias or ifunc!");
24522477
24532478 TypePrinter.print(GIS->getValueType(), Out);
24542479
144144 return const_cast(GO)->getComdat();
145145 return nullptr;
146146 }
147 // ifunc and its resolver are separate things so don't use resolver comdat.
148 if (isa(this))
149 return nullptr;
147150 return cast(this)->getComdat();
148151 }
149152
363366 "Alias and aliasee types should match!");
364367 setIndirectSymbol(Aliasee);
365368 }
369
370 //===----------------------------------------------------------------------===//
371 // GlobalIFunc Implementation
372 //===----------------------------------------------------------------------===//
373
374 GlobalIFunc::GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
375 const Twine &Name, Constant *Resolver,
376 Module *ParentModule)
377 : GlobalIndirectSymbol(Ty, Value::GlobalIFuncVal, AddressSpace, Link, Name,
378 Resolver) {
379 if (ParentModule)
380 ParentModule->getIFuncList().push_back(this);
381 }
382
383 GlobalIFunc *GlobalIFunc::create(Type *Ty, unsigned AddressSpace,
384 LinkageTypes Link, const Twine &Name,
385 Constant *Resolver, Module *ParentModule) {
386 return new GlobalIFunc(Ty, AddressSpace, Link, Name, Resolver, ParentModule);
387 }
388
389 void GlobalIFunc::setParent(Module *parent) {
390 Parent = parent;
391 }
392
393 void GlobalIFunc::removeFromParent() {
394 getParent()->getIFuncList().remove(getIterator());
395 }
396
397 void GlobalIFunc::eraseFromParent() {
398 getParent()->getIFuncList().erase(getIterator());
399 }
4040 template class llvm::SymbolTableListTraits;
4141 template class llvm::SymbolTableListTraits;
4242 template class llvm::SymbolTableListTraits;
43 template class llvm::SymbolTableListTraits;
4344
4445 //===----------------------------------------------------------------------===//
4546 // Primitive Module methods.
5859 GlobalList.clear();
5960 FunctionList.clear();
6061 AliasList.clear();
62 IFuncList.clear();
6163 NamedMDList.clear();
6264 delete ValSymTab;
6365 delete static_cast *>(NamedMDSymTab);
249251 return dyn_cast_or_null(getNamedValue(Name));
250252 }
251253
254 GlobalIFunc *Module::getNamedIFunc(StringRef Name) const {
255 return dyn_cast_or_null(getNamedValue(Name));
256 }
257
252258 /// getNamedMetadata - Return the first NamedMDNode in the module with the
253259 /// specified name. This method returns null if a NamedMDNode with the
254260 /// specified name is not found.
437443
438444 for (GlobalAlias &GA : aliases())
439445 GA.dropAllReferences();
446
447 for (GlobalIFunc &GIF : ifuncs())
448 GIF.dropAllReferences();
440449 }
441450
442451 unsigned Module::getDwarfVersion() const {
0 ; RUN: llvm-as < %s | llvm-dis | FileCheck %s --check-prefix=CHECK-LLVM
1 ; RUN: llvm-as < %s -o - | llc -filetype=asm | FileCheck %s --check-prefix=CHECK-ASM
2
3 target triple = "x86_64-unknown-linux-gnu"
4
5 @foo = ifunc i32 (i32), i64 ()* @foo_ifunc
6 ; CHECK-LLVM: @foo = ifunc i32 (i32), i64 ()* @foo_ifunc
7 ; CHECK-ASM: .type foo,@gnu_indirect_function
8
9 define internal i64 @foo_ifunc() {
10 entry:
11 ret i64 0
12 }
13 ; CHECK-LLVM: define internal i64 @foo_ifunc()
0 ; RUN: verify-uselistorder < %s
1
2 ; Global referencing ifunc.
3 @ptr_foo = global void ()* @foo_ifunc
4
5 ; Alias for ifunc.
6 @alias_foo = alias void (), void ()* @foo_ifunc
7
8 @foo_ifunc = ifunc void (), i8* ()* @foo_resolver
9
10 define i8* @foo_resolver() {
11 entry:
12 ret i8* null
13 }
14
15 ; Function referencing ifunc.
16 define void @bar() {
17 entry:
18 call void @foo_ifunc()
19 ret void
20 }
21
22 ; Global referencing function.
23 @ptr_bar = global void ()* @bar
24
25 ; Alias for function.
26 @alias_bar = alias void (), void ()* @bar
27
28 @bar_ifunc = ifunc void (), i8* ()* @bar2_ifunc
29 @bar2_ifunc = ifunc i8* (), i8* ()* @bar_resolver
30
31 define i8* @bar_resolver() {
32 entry:
33 ret i8* null
34 }
35
36 ; Function referencing bar.
37 define void @bar2() {
38 entry:
39 call void @bar()
40 ret void
41 }
247247 ; Aliases -- unnamed_addr
248248 @a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
249249 ; CHECK: @a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
250
251 ;; IFunc
252 ; Format @ = [Linkage] [Visibility] ifunc ,
253 ; * @
254
255 ; IFunc -- Linkage
256 @ifunc.external = external ifunc void (), i8* ()* @ifunc_resolver
257 ; CHECK: @ifunc.external = ifunc void (), i8* ()* @ifunc_resolver
258 @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver
259 ; CHECK: @ifunc.private = private ifunc void (), i8* ()* @ifunc_resolver
260 @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver
261 ; CHECK: @ifunc.internal = internal ifunc void (), i8* ()* @ifunc_resolver
262
263 ; IFunc -- Visibility
264 @ifunc.default = default ifunc void (), i8* ()* @ifunc_resolver
265 ; CHECK: @ifunc.default = ifunc void (), i8* ()* @ifunc_resolver
266 @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver
267 ; CHECK: @ifunc.hidden = hidden ifunc void (), i8* ()* @ifunc_resolver
268 @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver
269 ; CHECK: @ifunc.protected = protected ifunc void (), i8* ()* @ifunc_resolver
270
271 define i8* @ifunc_resolver() {
272 entry:
273 ret i8* null
274 }
250275
251276 ;; Functions
252277 ; Format: define [linkage] [visibility] [DLLStorageClass]