[llvm] 08ed216 - [IR] Refactor GlobalIFunc to inherit from GlobalObject, Remove GlobalIndirectSymbol
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 20 10:29:59 PDT 2021
Author: Itay Bookstein
Date: 2021-10-20T10:29:47-07:00
New Revision: 08ed216000b6503a4a4be52f18394d008d5fb8f4
URL: https://github.com/llvm/llvm-project/commit/08ed216000b6503a4a4be52f18394d008d5fb8f4
DIFF: https://github.com/llvm/llvm-project/commit/08ed216000b6503a4a4be52f18394d008d5fb8f4.diff
LOG: [IR] Refactor GlobalIFunc to inherit from GlobalObject, Remove GlobalIndirectSymbol
As discussed in:
* https://reviews.llvm.org/D94166
* https://lists.llvm.org/pipermail/llvm-dev/2020-September/145031.html
The GlobalIndirectSymbol class lost most of its meaning in
https://reviews.llvm.org/D109792, which disambiguated getBaseObject
(now getAliaseeObject) between GlobalIFunc and everything else.
In addition, as long as GlobalIFunc is not a GlobalObject and
getAliaseeObject returns GlobalObjects, a GlobalAlias whose aliasee
is a GlobalIFunc cannot currently be modeled properly. Creating
aliases for GlobalIFuncs does happen in the wild (e.g. glibc). In addition,
calling getAliaseeObject on a GlobalIFunc will currently return nullptr,
which is undesirable because it should return the object itself for
non-aliases.
This patch refactors the GlobalIFunc class to inherit directly from
GlobalObject, and removes GlobalIndirectSymbol (while inlining the
relevant parts into GlobalAlias and GlobalIFunc). This allows for
calling getAliaseeObject() on a GlobalIFunc to return the GlobalIFunc
itself, making getAliaseeObject() more consistent and enabling
alias-to-ifunc to be properly modeled in the IR.
I exercised some judgement in the API clients of GlobalIndirectSymbol:
some were 'monomorphized' for GlobalAlias and GlobalIFunc, and
some remained shared (with the type adapted to become GlobalValue).
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D108872
Added:
Modified:
clang/lib/CodeGen/CodeGenModule.cpp
llvm/include/llvm-c/Core.h
llvm/include/llvm/AsmParser/LLParser.h
llvm/include/llvm/CodeGen/AsmPrinter.h
llvm/include/llvm/IR/GlobalAlias.h
llvm/include/llvm/IR/GlobalIFunc.h
llvm/include/llvm/IR/GlobalObject.h
llvm/include/llvm/IR/Value.h
llvm/include/llvm/Transforms/Utils/ValueMapper.h
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/lib/Bitcode/Reader/MetadataLoader.cpp
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/IR/AsmWriter.cpp
llvm/lib/IR/Globals.cpp
llvm/lib/Linker/IRMover.cpp
llvm/lib/Object/ModuleSymbolTable.cpp
llvm/lib/Transforms/IPO/LowerTypeTests.cpp
llvm/lib/Transforms/Utils/SplitModule.cpp
llvm/lib/Transforms/Utils/ValueMapper.cpp
llvm/unittests/IR/ConstantsTest.cpp
Removed:
llvm/include/llvm/IR/GlobalIndirectSymbol.h
################################################################################
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 57454a59563a2..e53a8a36974ae 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -317,21 +317,21 @@ void CodeGenModule::applyGlobalValReplacements() {
// This is only used in aliases that we created and we know they have a
// linear structure.
-static const llvm::GlobalObject *getAliasedGlobal(
- const llvm::GlobalIndirectSymbol &GIS) {
- llvm::SmallPtrSet<const llvm::GlobalIndirectSymbol*, 4> Visited;
- const llvm::Constant *C = &GIS;
+static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) {
+ llvm::SmallPtrSet<const llvm::GlobalValue *, 4> Visited;
for (;;) {
- C = C->stripPointerCasts();
- if (auto *GO = dyn_cast<llvm::GlobalObject>(C))
- return GO;
- // stripPointerCasts will not walk over weak aliases.
- auto *GIS2 = dyn_cast<llvm::GlobalIndirectSymbol>(C);
- if (!GIS2)
+ if (!GV || !Visited.insert(GV).second)
return nullptr;
- if (!Visited.insert(GIS2).second)
- return nullptr;
- C = GIS2->getIndirectSymbol();
+
+ const llvm::Constant *C;
+ if (auto *GA = dyn_cast<llvm::GlobalAlias>(GV))
+ C = GA->getAliasee();
+ else if (auto *GI = dyn_cast<llvm::GlobalIFunc>(GV))
+ C = GI->getResolver();
+ else
+ return GV;
+
+ GV = dyn_cast<llvm::GlobalValue>(C->stripPointerCasts());
}
}
@@ -350,9 +350,8 @@ void CodeGenModule::checkAliases() {
else
llvm_unreachable("Not an alias or ifunc?");
StringRef MangledName = getMangledName(GD);
- llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
- auto *Alias = cast<llvm::GlobalIndirectSymbol>(Entry);
- const llvm::GlobalValue *GV = getAliasedGlobal(*Alias);
+ llvm::GlobalValue *Alias = GetGlobalValue(MangledName);
+ const llvm::GlobalValue *GV = getAliasedGlobal(Alias);
if (!GV) {
Error = true;
Diags.Report(Location, diag::err_cyclic_alias) << IsIFunc;
@@ -369,7 +368,10 @@ void CodeGenModule::checkAliases() {
Diags.Report(Location, diag::err_ifunc_resolver_return);
}
- llvm::Constant *Aliasee = Alias->getIndirectSymbol();
+ llvm::Constant *Aliasee =
+ IsIFunc ? cast<llvm::GlobalIFunc>(Alias)->getResolver()
+ : cast<llvm::GlobalAlias>(Alias)->getAliasee();
+
llvm::GlobalValue *AliaseeGV;
if (auto CE = dyn_cast<llvm::ConstantExpr>(Aliasee))
AliaseeGV = cast<llvm::GlobalValue>(CE->getOperand(0));
@@ -388,13 +390,17 @@ void CodeGenModule::checkAliases() {
// compatibility with gcc we implement it by just pointing the alias
// to its aliasee's aliasee. We also warn, since the user is probably
// expecting the link to be weak.
- if (auto GA = dyn_cast<llvm::GlobalIndirectSymbol>(AliaseeGV)) {
+ if (auto *GA = dyn_cast<llvm::GlobalAlias>(AliaseeGV)) {
if (GA->isInterposable()) {
Diags.Report(Location, diag::warn_alias_to_weak_alias)
<< GV->getName() << GA->getName() << IsIFunc;
Aliasee = llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
- GA->getIndirectSymbol(), Alias->getType());
- Alias->setIndirectSymbol(Aliasee);
+ GA->getAliasee(), Alias->getType());
+
+ if (IsIFunc)
+ cast<llvm::GlobalIFunc>(Alias)->setResolver(Aliasee);
+ else
+ cast<llvm::GlobalAlias>(Alias)->setAliasee(Aliasee);
}
}
}
@@ -403,8 +409,7 @@ void CodeGenModule::checkAliases() {
for (const GlobalDecl &GD : Aliases) {
StringRef MangledName = getMangledName(GD);
- llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
- auto *Alias = cast<llvm::GlobalIndirectSymbol>(Entry);
+ llvm::GlobalValue *Alias = GetGlobalValue(MangledName);
Alias->replaceAllUsesWith(llvm::UndefValue::get(Alias->getType()));
Alias->eraseFromParent();
}
diff --git a/llvm/include/llvm-c/Core.h b/llvm/include/llvm-c/Core.h
index fc8736a110260..7330e247152dc 100644
--- a/llvm/include/llvm-c/Core.h
+++ b/llvm/include/llvm-c/Core.h
@@ -1580,10 +1580,10 @@ LLVMTypeRef LLVMX86AMXType(void);
macro(ConstantVector) \
macro(GlobalValue) \
macro(GlobalAlias) \
- macro(GlobalIFunc) \
macro(GlobalObject) \
macro(Function) \
macro(GlobalVariable) \
+ macro(GlobalIFunc) \
macro(UndefValue) \
macro(PoisonValue) \
macro(Instruction) \
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index f311eaf789ead..d621c232378c3 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -304,11 +304,10 @@ namespace llvm {
unsigned DLLStorageClass, bool DSOLocal,
GlobalVariable::ThreadLocalMode TLM,
GlobalVariable::UnnamedAddr UnnamedAddr);
- bool parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
- unsigned L, unsigned Visibility,
- unsigned DLLStorageClass, bool DSOLocal,
- GlobalVariable::ThreadLocalMode TLM,
- GlobalVariable::UnnamedAddr UnnamedAddr);
+ bool parseAliasOrIFunc(const std::string &Name, LocTy NameLoc, unsigned L,
+ unsigned Visibility, unsigned DLLStorageClass,
+ bool DSOLocal, GlobalVariable::ThreadLocalMode TLM,
+ GlobalVariable::UnnamedAddr UnnamedAddr);
bool parseComdat();
bool parseStandaloneMetadata();
bool parseNamedMetadata();
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 5dea86e67d642..87ecf51d4d49e 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -41,7 +41,6 @@ class DIEAbbrev;
class DwarfDebug;
class GCMetadataPrinter;
class GCStrategy;
-class GlobalIndirectSymbol;
class GlobalObject;
class GlobalValue;
class GlobalVariable;
@@ -795,8 +794,8 @@ class AsmPrinter : public MachineFunctionPass {
void emitModuleCommandLines(Module &M);
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &S);
- /// Emit GlobalAlias or GlobalIFunc.
- void emitGlobalIndirectSymbol(Module &M, const GlobalIndirectSymbol &GIS);
+ void emitGlobalAlias(Module &M, const GlobalAlias &GA);
+ void emitGlobalIFunc(Module &M, const GlobalIFunc &GI);
/// This method decides whether the specified basic block requires a label.
bool shouldEmitLabelForBasicBlock(const MachineBasicBlock &MBB) const;
diff --git a/llvm/include/llvm/IR/GlobalAlias.h b/llvm/include/llvm/IR/GlobalAlias.h
index 1d0d98351cb1a..01134448a8fa7 100644
--- a/llvm/include/llvm/IR/GlobalAlias.h
+++ b/llvm/include/llvm/IR/GlobalAlias.h
@@ -15,7 +15,8 @@
#define LLVM_IR_GLOBALALIAS_H
#include "llvm/ADT/ilist_node.h"
-#include "llvm/IR/GlobalIndirectSymbol.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Value.h"
namespace llvm {
@@ -24,8 +25,7 @@ class Twine;
class Module;
template <typename ValueSubClass> class SymbolTableListTraits;
-class GlobalAlias : public GlobalIndirectSymbol,
- public ilist_node<GlobalAlias> {
+class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
friend class SymbolTableListTraits<GlobalAlias>;
GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage,
@@ -58,6 +58,17 @@ class GlobalAlias : public GlobalIndirectSymbol,
// Linkage, Type, Parent and AddressSpace taken from the Aliasee.
static GlobalAlias *create(const Twine &Name, GlobalValue *Aliasee);
+ // allocate space for exactly one operand
+ void *operator new(size_t S) { return User::operator new(S, 1); }
+ void operator delete(void *Ptr) { User::operator delete(Ptr); }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+ void copyAttributesFrom(const GlobalAlias *Src) {
+ GlobalValue::copyAttributesFrom(Src);
+ }
+
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
///
@@ -71,11 +82,9 @@ class GlobalAlias : public GlobalIndirectSymbol,
/// These methods retrieve and set alias target.
void setAliasee(Constant *Aliasee);
const Constant *getAliasee() const {
- return getIndirectSymbol();
- }
- Constant *getAliasee() {
- return getIndirectSymbol();
+ return static_cast<Constant *>(Op<0>().get());
}
+ Constant *getAliasee() { return static_cast<Constant *>(Op<0>().get()); }
const GlobalObject *getAliaseeObject() const;
GlobalObject *getAliaseeObject() {
@@ -94,6 +103,12 @@ class GlobalAlias : public GlobalIndirectSymbol,
}
};
+template <>
+struct OperandTraits<GlobalAlias>
+ : public FixedNumOperandTraits<GlobalAlias, 1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalAlias, Constant)
+
} // end namespace llvm
#endif // LLVM_IR_GLOBALALIAS_H
diff --git a/llvm/include/llvm/IR/GlobalIFunc.h b/llvm/include/llvm/IR/GlobalIFunc.h
index 39316937ac4cc..4dc184c2336fe 100644
--- a/llvm/include/llvm/IR/GlobalIFunc.h
+++ b/llvm/include/llvm/IR/GlobalIFunc.h
@@ -18,7 +18,9 @@
#define LLVM_IR_GLOBALIFUNC_H
#include "llvm/ADT/ilist_node.h"
-#include "llvm/IR/GlobalIndirectSymbol.h"
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/GlobalObject.h"
+#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/Value.h"
namespace llvm {
@@ -29,8 +31,7 @@ class Module;
// Traits class for using GlobalIFunc in symbol table in Module.
template <typename ValueSubClass> class SymbolTableListTraits;
-class GlobalIFunc final : public GlobalIndirectSymbol,
- public ilist_node<GlobalIFunc> {
+class GlobalIFunc final : public GlobalObject, public ilist_node<GlobalIFunc> {
friend class SymbolTableListTraits<GlobalIFunc>;
GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage,
@@ -46,6 +47,17 @@ class GlobalIFunc final : public GlobalIndirectSymbol,
LinkageTypes Linkage, const Twine &Name,
Constant *Resolver, Module *Parent);
+ // allocate space for exactly one operand
+ void *operator new(size_t S) { return User::operator new(S, 1); }
+ void operator delete(void *Ptr) { User::operator delete(Ptr); }
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
+
+ void copyAttributesFrom(const GlobalIFunc *Src) {
+ GlobalObject::copyAttributesFrom(Src);
+ }
+
/// This method unlinks 'this' from the containing module, but does not
/// delete it.
void removeFromParent();
@@ -54,11 +66,11 @@ class GlobalIFunc final : public GlobalIndirectSymbol,
void eraseFromParent();
/// These methods retrieve and set ifunc resolver function.
- void setResolver(Constant *Resolver) {
- setIndirectSymbol(Resolver);
+ void setResolver(Constant *Resolver) { Op<0>().set(Resolver); }
+ const Constant *getResolver() const {
+ return static_cast<Constant *>(Op<0>().get());
}
- const Constant *getResolver() const { return getIndirectSymbol(); }
- Constant *getResolver() { return getIndirectSymbol(); }
+ Constant *getResolver() { return static_cast<Constant *>(Op<0>().get()); }
// Return the resolver function after peeling off potential ConstantExpr
// indirection.
@@ -74,6 +86,12 @@ class GlobalIFunc final : public GlobalIndirectSymbol,
}
};
+template <>
+struct OperandTraits<GlobalIFunc>
+ : public FixedNumOperandTraits<GlobalIFunc, 1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalIFunc, Constant)
+
} // end namespace llvm
#endif // LLVM_IR_GLOBALIFUNC_H
diff --git a/llvm/include/llvm/IR/GlobalIndirectSymbol.h b/llvm/include/llvm/IR/GlobalIndirectSymbol.h
deleted file mode 100644
index da59a80ed9225..0000000000000
--- a/llvm/include/llvm/IR/GlobalIndirectSymbol.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//===- llvm/GlobalIndirectSymbol.h - GlobalIndirectSymbol class -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the declaration of the GlobalIndirectSymbol class, which
-// is a base class for GlobalAlias and GlobalIFunc. It contains all common code
-// for aliases and ifuncs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_GLOBALINDIRECTSYMBOL_H
-#define LLVM_IR_GLOBALINDIRECTSYMBOL_H
-
-#include "llvm/IR/GlobalObject.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/OperandTraits.h"
-#include "llvm/IR/User.h"
-#include "llvm/IR/Value.h"
-#include "llvm/Support/Casting.h"
-#include <cstddef>
-
-namespace llvm {
-
-class GlobalIndirectSymbol : public GlobalValue {
-protected:
- GlobalIndirectSymbol(Type *Ty, ValueTy VTy, unsigned AddressSpace,
- LinkageTypes Linkage, const Twine &Name, Constant *Symbol);
-
-public:
- GlobalIndirectSymbol(const GlobalIndirectSymbol &) = delete;
- GlobalIndirectSymbol &operator=(const GlobalIndirectSymbol &) = delete;
-
- // allocate space for exactly one operand
- void *operator new(size_t S) { return User::operator new(S, 1); }
- void operator delete(void *Ptr) { User::operator delete(Ptr); }
-
- /// Provide fast operand accessors
- DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
-
- void copyAttributesFrom(const GlobalValue *Src) {
- GlobalValue::copyAttributesFrom(Src);
- }
-
- /// These methods set and retrieve indirect symbol.
- void setIndirectSymbol(Constant *Symbol) {
- setOperand(0, Symbol);
- }
- const Constant *getIndirectSymbol() const {
- return getOperand(0);
- }
- Constant *getIndirectSymbol() {
- return const_cast<Constant *>(
- static_cast<const GlobalIndirectSymbol *>(this)->getIndirectSymbol());
- }
-
- const GlobalObject *getAliaseeObject() const;
- GlobalObject *getAliaseeObject() {
- return const_cast<GlobalObject *>(
- static_cast<const GlobalIndirectSymbol *>(this)->getAliaseeObject());
- }
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const Value *V) {
- return V->getValueID() == Value::GlobalAliasVal ||
- V->getValueID() == Value::GlobalIFuncVal;
- }
-};
-
-template <>
-struct OperandTraits<GlobalIndirectSymbol> :
- public FixedNumOperandTraits<GlobalIndirectSymbol, 1> {
-};
-
-DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalIndirectSymbol, Constant)
-
-} // end namespace llvm
-
-#endif // LLVM_IR_GLOBALINDIRECTSYMBOL_H
diff --git a/llvm/include/llvm/IR/GlobalObject.h b/llvm/include/llvm/IR/GlobalObject.h
index 130196bb6c4a7..e15cf718bb107 100644
--- a/llvm/include/llvm/IR/GlobalObject.h
+++ b/llvm/include/llvm/IR/GlobalObject.h
@@ -153,7 +153,8 @@ class GlobalObject : public GlobalValue {
// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal ||
- V->getValueID() == Value::GlobalVariableVal;
+ V->getValueID() == Value::GlobalVariableVal ||
+ V->getValueID() == Value::GlobalIFuncVal;
}
private:
diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h
index 2cb4d09c295b2..515cfc7c1fa9b 100644
--- a/llvm/include/llvm/IR/Value.h
+++ b/llvm/include/llvm/IR/Value.h
@@ -37,7 +37,6 @@ class DataLayout;
class Function;
class GlobalAlias;
class GlobalIFunc;
-class GlobalIndirectSymbol;
class GlobalObject;
class GlobalValue;
class GlobalVariable;
@@ -1016,21 +1015,16 @@ template <> struct isa_impl<GlobalIFunc, Value> {
}
};
-template <> struct isa_impl<GlobalIndirectSymbol, Value> {
- static inline bool doit(const Value &Val) {
- return isa<GlobalAlias>(Val) || isa<GlobalIFunc>(Val);
- }
-};
-
template <> struct isa_impl<GlobalValue, Value> {
static inline bool doit(const Value &Val) {
- return isa<GlobalObject>(Val) || isa<GlobalIndirectSymbol>(Val);
+ return isa<GlobalObject>(Val) || isa<GlobalAlias>(Val);
}
};
template <> struct isa_impl<GlobalObject, Value> {
static inline bool doit(const Value &Val) {
- return isa<GlobalVariable>(Val) || isa<Function>(Val);
+ return isa<GlobalVariable>(Val) || isa<Function>(Val) ||
+ isa<GlobalIFunc>(Val);
}
};
diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h
index 4245f51cc1e2a..95fd0b14dd511 100644
--- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h
+++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h
@@ -22,7 +22,6 @@ namespace llvm {
class Constant;
class Function;
-class GlobalIndirectSymbol;
class GlobalVariable;
class Instruction;
class MDNode;
@@ -122,7 +121,8 @@ inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
/// instance:
/// - \a scheduleMapGlobalInitializer()
/// - \a scheduleMapAppendingVariable()
-/// - \a scheduleMapGlobalIndirectSymbol()
+/// - \a scheduleMapGlobalAlias()
+/// - \a scheduleMapGlobalIFunc()
/// - \a scheduleRemapFunction()
///
/// Sometimes a callback needs a
diff erent mapping context. Such a context can
@@ -182,9 +182,10 @@ class ValueMapper {
bool IsOldCtorDtor,
ArrayRef<Constant *> NewMembers,
unsigned MappingContextID = 0);
- void scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS,
- Constant &Target,
- unsigned MappingContextID = 0);
+ void scheduleMapGlobalAlias(GlobalAlias &GA, Constant &Aliasee,
+ unsigned MappingContextID = 0);
+ void scheduleMapGlobalIFunc(GlobalIFunc &GI, Constant &Resolver,
+ unsigned MappingContextID = 0);
void scheduleRemapFunction(Function &F, unsigned MappingContextID = 0);
};
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 924c83079e3c5..5bce1eaa59a09 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -601,12 +601,15 @@ bool LLParser::parseUnnamedGlobal() {
parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
return true;
- if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
+ switch (Lex.getKind()) {
+ default:
return parseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
-
- return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
+ case lltok::kw_alias:
+ case lltok::kw_ifunc:
+ return parseAliasOrIFunc(Name, NameLoc, Linkage, Visibility,
DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
+ }
}
/// parseNamedGlobal:
@@ -631,12 +634,15 @@ bool LLParser::parseNamedGlobal() {
parseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
return true;
- if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
+ switch (Lex.getKind()) {
+ default:
return parseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
-
- return parseIndirectSymbol(Name, NameLoc, Linkage, Visibility,
+ case lltok::kw_alias:
+ case lltok::kw_ifunc:
+ return parseAliasOrIFunc(Name, NameLoc, Linkage, Visibility,
DLLStorageClass, DSOLocal, TLM, UnnamedAddr);
+ }
}
bool LLParser::parseComdat() {
@@ -909,25 +915,25 @@ static std::string typeComparisonErrorMessage(StringRef Message, Type *Ty1,
return ErrOS.str();
}
-/// parseIndirectSymbol:
+/// parseAliasOrIFunc:
/// ::= GlobalVar '=' OptionalLinkage OptionalPreemptionSpecifier
/// OptionalVisibility OptionalDLLStorageClass
/// OptionalThreadLocal OptionalUnnamedAddr
-/// 'alias|ifunc' IndirectSymbol IndirectSymbolAttr*
+/// 'alias|ifunc' AliaseeOrResolver SymbolAttrs*
///
-/// IndirectSymbol
+/// AliaseeOrResolver
/// ::= TypeAndValue
///
-/// IndirectSymbolAttr
+/// SymbolAttrs
/// ::= ',' 'partition' StringConstant
///
/// Everything through OptionalUnnamedAddr has already been parsed.
///
-bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
- unsigned L, unsigned Visibility,
- unsigned DLLStorageClass, bool DSOLocal,
- GlobalVariable::ThreadLocalMode TLM,
- GlobalVariable::UnnamedAddr UnnamedAddr) {
+bool LLParser::parseAliasOrIFunc(const std::string &Name, LocTy NameLoc,
+ unsigned L, unsigned Visibility,
+ unsigned DLLStorageClass, bool DSOLocal,
+ GlobalVariable::ThreadLocalMode TLM,
+ GlobalVariable::UnnamedAddr UnnamedAddr) {
bool IsAlias;
if (Lex.getKind() == lltok::kw_alias)
IsAlias = true;
@@ -1009,21 +1015,26 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
}
}
- // Okay, create the alias but do not insert it into the module yet.
- std::unique_ptr<GlobalIndirectSymbol> GA;
- if (IsAlias)
+ // Okay, create the alias/ifunc but do not insert it into the module yet.
+ std::unique_ptr<GlobalAlias> GA;
+ std::unique_ptr<GlobalIFunc> GI;
+ GlobalValue *GV;
+ if (IsAlias) {
GA.reset(GlobalAlias::create(Ty, AddrSpace,
(GlobalValue::LinkageTypes)Linkage, Name,
Aliasee, /*Parent*/ nullptr));
- else
- GA.reset(GlobalIFunc::create(Ty, AddrSpace,
+ GV = GA.get();
+ } else {
+ GI.reset(GlobalIFunc::create(Ty, AddrSpace,
(GlobalValue::LinkageTypes)Linkage, Name,
Aliasee, /*Parent*/ nullptr));
- GA->setThreadLocalMode(TLM);
- GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
- GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
- GA->setUnnamedAddr(UnnamedAddr);
- maybeSetDSOLocal(DSOLocal, *GA);
+ GV = GI.get();
+ }
+ GV->setThreadLocalMode(TLM);
+ GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+ GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
+ GV->setUnnamedAddr(UnnamedAddr);
+ maybeSetDSOLocal(DSOLocal, *GV);
// At this point we've parsed everything except for the IndirectSymbolAttrs.
// Now parse them if there are any.
@@ -1032,7 +1043,7 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
if (Lex.getKind() == lltok::kw_partition) {
Lex.Lex();
- GA->setPartition(Lex.getStrVal());
+ GV->setPartition(Lex.getStrVal());
if (parseToken(lltok::StringConstant, "expected partition string"))
return true;
} else {
@@ -1041,30 +1052,27 @@ bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
}
if (Name.empty())
- NumberedVals.push_back(GA.get());
+ NumberedVals.push_back(GV);
if (GVal) {
// Verify that types agree.
- if (GVal->getType() != GA->getType())
+ if (GVal->getType() != GV->getType())
return error(
ExplicitTypeLoc,
"forward reference and definition of alias have
diff erent types");
// If they agree, just RAUW the old value with the alias and remove the
// forward ref info.
- GVal->replaceAllUsesWith(GA.get());
+ GVal->replaceAllUsesWith(GV);
GVal->eraseFromParent();
}
// Insert into the module, we know its name won't collide now.
if (IsAlias)
- M->getAliasList().push_back(cast<GlobalAlias>(GA.get()));
+ M->getAliasList().push_back(GA.release());
else
- M->getIFuncList().push_back(cast<GlobalIFunc>(GA.get()));
- assert(GA->getName() == Name && "Should not be a name conflict!");
-
- // The module owns this now
- GA.release();
+ M->getIFuncList().push_back(GI.release());
+ assert(GV->getName() == Name && "Should not be a name conflict!");
return false;
}
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index b3df3a759d971..349d40e1a63c1 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -41,7 +41,6 @@
#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
-#include "llvm/IR/GlobalIndirectSymbol.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
@@ -500,7 +499,7 @@ class BitcodeReader : public BitcodeReaderBase, public GVMaterializer {
SmallVector<Instruction *, 64> InstructionList;
std::vector<std::pair<GlobalVariable *, unsigned>> GlobalInits;
- std::vector<std::pair<GlobalIndirectSymbol *, unsigned>> IndirectSymbolInits;
+ std::vector<std::pair<GlobalValue *, unsigned>> IndirectSymbolInits;
struct FunctionOperandInfo {
Function *F;
@@ -2253,8 +2252,7 @@ uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
/// Resolve all of the initializers for global values and aliases that we can.
Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() {
std::vector<std::pair<GlobalVariable *, unsigned>> GlobalInitWorklist;
- std::vector<std::pair<GlobalIndirectSymbol *, unsigned>>
- IndirectSymbolInitWorklist;
+ std::vector<std::pair<GlobalValue *, unsigned>> IndirectSymbolInitWorklist;
std::vector<FunctionOperandInfo> FunctionOperandWorklist;
GlobalInitWorklist.swap(GlobalInits);
@@ -2283,10 +2281,16 @@ Error BitcodeReader::resolveGlobalAndIndirectSymbolInits() {
Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]);
if (!C)
return error("Expected a constant");
- GlobalIndirectSymbol *GIS = IndirectSymbolInitWorklist.back().first;
- if (isa<GlobalAlias>(GIS) && C->getType() != GIS->getType())
- return error("Alias and aliasee types don't match");
- GIS->setIndirectSymbol(C);
+ GlobalValue *GV = IndirectSymbolInitWorklist.back().first;
+ if (auto *GA = dyn_cast<GlobalAlias>(GV)) {
+ if (C->getType() != GV->getType())
+ return error("Alias and aliasee types don't match");
+ GA->setAliasee(C);
+ } else if (auto *GI = dyn_cast<GlobalIFunc>(GV)) {
+ GI->setResolver(C);
+ } else {
+ return error("Expected an alias or an ifunc");
+ }
}
IndirectSymbolInitWorklist.pop_back();
}
@@ -3118,8 +3122,7 @@ Error BitcodeReader::globalCleanup() {
// Force deallocation of memory for these vectors to favor the client that
// want lazy deserialization.
std::vector<std::pair<GlobalVariable *, unsigned>>().swap(GlobalInits);
- std::vector<std::pair<GlobalIndirectSymbol *, unsigned>>().swap(
- IndirectSymbolInits);
+ std::vector<std::pair<GlobalValue *, unsigned>>().swap(IndirectSymbolInits);
return Error::success();
}
@@ -3499,7 +3502,7 @@ Error BitcodeReader::parseGlobalIndirectSymbolRecord(
auto Val = Record[OpNum++];
auto Linkage = Record[OpNum++];
- GlobalIndirectSymbol *NewGA;
+ GlobalValue *NewGA;
if (BitCode == bitc::MODULE_CODE_ALIAS ||
BitCode == bitc::MODULE_CODE_ALIAS_OLD)
NewGA = GlobalAlias::create(Ty, AddrSpace, getDecodedLinkage(Linkage), Name,
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 425b61a066c0f..a2b495e6f7549 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -21,8 +21,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Bitcode/BitcodeReader.h"
-#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
+#include "llvm/Bitstream/BitstreamReader.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/AutoUpgrade.h"
@@ -40,7 +40,6 @@
#include "llvm/IR/GVMaterializer.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
-#include "llvm/IR/GlobalIndirectSymbol.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 0ddef29b0dc56..54aaa335d24be 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -71,7 +71,6 @@
#include "llvm/IR/GCStrategy.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
-#include "llvm/IR/GlobalIndirectSymbol.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
@@ -1604,14 +1603,13 @@ void AsmPrinter::emitGlobalGOTEquivs() {
emitGlobalVariable(GV);
}
-void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
- const GlobalIndirectSymbol& GIS) {
- MCSymbol *Name = getSymbol(&GIS);
- bool IsFunction = GIS.getValueType()->isFunctionTy();
+void AsmPrinter::emitGlobalAlias(Module &M, const GlobalAlias &GA) {
+ MCSymbol *Name = getSymbol(&GA);
+ bool IsFunction = GA.getValueType()->isFunctionTy();
// Treat bitcasts of functions as functions also. This is important at least
// on WebAssembly where object and function addresses can't alias each other.
if (!IsFunction)
- if (auto *CE = dyn_cast<ConstantExpr>(GIS.getIndirectSymbol()))
+ if (auto *CE = dyn_cast<ConstantExpr>(GA.getAliasee()))
if (CE->getOpcode() == Instruction::BitCast)
IsFunction =
CE->getOperand(0)->getType()->getPointerElementType()->isFunctionTy();
@@ -1621,61 +1619,80 @@ void AsmPrinter::emitGlobalIndirectSymbol(Module &M,
// point, all the extra label is emitted, we just have to emit linkage for
// those labels.
if (TM.getTargetTriple().isOSBinFormatXCOFF()) {
- assert(!isa<GlobalIFunc>(GIS) && "IFunc is not supported on AIX.");
assert(MAI->hasVisibilityOnlyWithLinkage() &&
"Visibility should be handled with emitLinkage() on AIX.");
- emitLinkage(&GIS, Name);
+ emitLinkage(&GA, Name);
// If it's a function, also emit linkage for aliases of function entry
// point.
if (IsFunction)
- emitLinkage(&GIS,
- getObjFileLowering().getFunctionEntryPointSymbol(&GIS, TM));
+ emitLinkage(&GA,
+ getObjFileLowering().getFunctionEntryPointSymbol(&GA, TM));
return;
}
- if (GIS.hasExternalLinkage() || !MAI->getWeakRefDirective())
+ if (GA.hasExternalLinkage() || !MAI->getWeakRefDirective())
OutStreamer->emitSymbolAttribute(Name, MCSA_Global);
- else if (GIS.hasWeakLinkage() || GIS.hasLinkOnceLinkage())
+ else if (GA.hasWeakLinkage() || GA.hasLinkOnceLinkage())
OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);
else
- assert(GIS.hasLocalLinkage() && "Invalid alias or ifunc linkage");
+ assert(GA.hasLocalLinkage() && "Invalid alias linkage");
// Set the symbol type to function if the alias has a function type.
// This affects codegen when the aliasee is not a function.
if (IsFunction)
- OutStreamer->emitSymbolAttribute(Name, isa<GlobalIFunc>(GIS)
- ? MCSA_ELF_TypeIndFunction
- : MCSA_ELF_TypeFunction);
+ OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeFunction);
- emitVisibility(Name, GIS.getVisibility());
+ emitVisibility(Name, GA.getVisibility());
- const MCExpr *Expr = lowerConstant(GIS.getIndirectSymbol());
+ const MCExpr *Expr = lowerConstant(GA.getAliasee());
- if (isa<GlobalAlias>(&GIS) && MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr))
+ if (MAI->hasAltEntry() && isa<MCBinaryExpr>(Expr))
OutStreamer->emitSymbolAttribute(Name, MCSA_AltEntry);
// Emit the directives as assignments aka .set:
OutStreamer->emitAssignment(Name, Expr);
- MCSymbol *LocalAlias = getSymbolPreferLocal(GIS);
+ MCSymbol *LocalAlias = getSymbolPreferLocal(GA);
if (LocalAlias != Name)
OutStreamer->emitAssignment(LocalAlias, Expr);
- if (auto *GA = dyn_cast<GlobalAlias>(&GIS)) {
- // If the aliasee does not correspond to a symbol in the output, i.e. the
- // alias is not of an object or the aliased object is private, then set the
- // size of the alias symbol from the type of the alias. We don't do this in
- // other situations as the alias and aliasee having
diff ering types but same
- // size may be intentional.
- const GlobalObject *Aliasee = GA->getAliaseeObject();
- if (MAI->hasDotTypeDotSizeDirective() && GA->getValueType()->isSized() &&
- (!Aliasee || Aliasee->hasPrivateLinkage())) {
- const DataLayout &DL = M.getDataLayout();
- uint64_t Size = DL.getTypeAllocSize(GA->getValueType());
- OutStreamer->emitELFSize(Name, MCConstantExpr::create(Size, OutContext));
- }
+ // If the aliasee does not correspond to a symbol in the output, i.e. the
+ // alias is not of an object or the aliased object is private, then set the
+ // size of the alias symbol from the type of the alias. We don't do this in
+ // other situations as the alias and aliasee having
diff ering types but same
+ // size may be intentional.
+ const GlobalObject *BaseObject = GA.getAliaseeObject();
+ if (MAI->hasDotTypeDotSizeDirective() && GA.getValueType()->isSized() &&
+ (!BaseObject || BaseObject->hasPrivateLinkage())) {
+ const DataLayout &DL = M.getDataLayout();
+ uint64_t Size = DL.getTypeAllocSize(GA.getValueType());
+ OutStreamer->emitELFSize(Name, MCConstantExpr::create(Size, OutContext));
}
}
+void AsmPrinter::emitGlobalIFunc(Module &M, const GlobalIFunc &GI) {
+ assert(!TM.getTargetTriple().isOSBinFormatXCOFF() &&
+ "IFunc is not supported on AIX.");
+
+ MCSymbol *Name = getSymbol(&GI);
+
+ if (GI.hasExternalLinkage() || !MAI->getWeakRefDirective())
+ OutStreamer->emitSymbolAttribute(Name, MCSA_Global);
+ else if (GI.hasWeakLinkage() || GI.hasLinkOnceLinkage())
+ OutStreamer->emitSymbolAttribute(Name, MCSA_WeakReference);
+ else
+ assert(GI.hasLocalLinkage() && "Invalid ifunc linkage");
+
+ OutStreamer->emitSymbolAttribute(Name, MCSA_ELF_TypeIndFunction);
+ emitVisibility(Name, GI.getVisibility());
+
+ // Emit the directives as assignments aka .set:
+ const MCExpr *Expr = lowerConstant(GI.getResolver());
+ OutStreamer->emitAssignment(Name, Expr);
+ MCSymbol *LocalAlias = getSymbolPreferLocal(GI);
+ if (LocalAlias != Name)
+ OutStreamer->emitAssignment(LocalAlias, Expr);
+}
+
void AsmPrinter::emitRemarksSection(remarks::RemarkStreamer &RS) {
if (!RS.needsSection())
return;
@@ -1856,11 +1873,11 @@ bool AsmPrinter::doFinalization(Module &M) {
AliasStack.push_back(Cur);
}
for (const GlobalAlias *AncestorAlias : llvm::reverse(AliasStack))
- emitGlobalIndirectSymbol(M, *AncestorAlias);
+ emitGlobalAlias(M, *AncestorAlias);
AliasStack.clear();
}
for (const auto &IFunc : M.ifuncs())
- emitGlobalIndirectSymbol(M, IFunc);
+ emitGlobalIFunc(M, IFunc);
GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index c668e15dfbe40..c7a46bd5fe253 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -45,7 +45,6 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalIFunc.h"
-#include "llvm/IR/GlobalIndirectSymbol.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
@@ -2594,7 +2593,8 @@ class AssemblyWriter {
void printTypeIdentities();
void printGlobal(const GlobalVariable *GV);
- void printIndirectSymbol(const GlobalIndirectSymbol *GIS);
+ void printAlias(const GlobalAlias *GA);
+ void printIFunc(const GlobalIFunc *GI);
void printComdat(const Comdat *C);
void printFunction(const Function *F);
void printArgument(const Argument *FA, AttributeSet Attrs);
@@ -2832,12 +2832,12 @@ void AssemblyWriter::printModule(const Module *M) {
// Output all aliases.
if (!M->alias_empty()) Out << "\n";
for (const GlobalAlias &GA : M->aliases())
- printIndirectSymbol(&GA);
+ printAlias(&GA);
// Output all ifuncs.
if (!M->ifunc_empty()) Out << "\n";
for (const GlobalIFunc &GI : M->ifuncs())
- printIndirectSymbol(&GI);
+ printIFunc(&GI);
// Output all of the functions.
for (const Function &F : *M) {
@@ -3566,50 +3566,76 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
printInfoComment(*GV);
}
-void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) {
- if (GIS->isMaterializable())
+void AssemblyWriter::printAlias(const GlobalAlias *GA) {
+ if (GA->isMaterializable())
Out << "; Materializable\n";
- AsmWriterContext WriterCtx(&TypePrinter, &Machine, GIS->getParent());
- WriteAsOperandInternal(Out, GIS, WriterCtx);
+ AsmWriterContext WriterCtx(&TypePrinter, &Machine, GA->getParent());
+ WriteAsOperandInternal(Out, GA, WriterCtx);
Out << " = ";
- Out << getLinkageNameWithSpace(GIS->getLinkage());
- PrintDSOLocation(*GIS, Out);
- PrintVisibility(GIS->getVisibility(), Out);
- PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
- PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
- StringRef UA = getUnnamedAddrEncoding(GIS->getUnnamedAddr());
+ Out << getLinkageNameWithSpace(GA->getLinkage());
+ PrintDSOLocation(*GA, Out);
+ PrintVisibility(GA->getVisibility(), Out);
+ PrintDLLStorageClass(GA->getDLLStorageClass(), Out);
+ PrintThreadLocalModel(GA->getThreadLocalMode(), Out);
+ StringRef UA = getUnnamedAddrEncoding(GA->getUnnamedAddr());
if (!UA.empty())
Out << UA << ' ';
- if (isa<GlobalAlias>(GIS))
- Out << "alias ";
- else if (isa<GlobalIFunc>(GIS))
- Out << "ifunc ";
- else
- llvm_unreachable("Not an alias or ifunc!");
-
- TypePrinter.print(GIS->getValueType(), Out);
+ Out << "alias ";
+ TypePrinter.print(GA->getValueType(), Out);
Out << ", ";
- const Constant *IS = GIS->getIndirectSymbol();
-
- if (!IS) {
- TypePrinter.print(GIS->getType(), Out);
+ if (const Constant *Aliasee = GA->getAliasee()) {
+ writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee));
+ } else {
+ TypePrinter.print(GA->getType(), Out);
Out << " <<NULL ALIASEE>>";
+ }
+
+ if (GA->hasPartition()) {
+ Out << ", partition \"";
+ printEscapedString(GA->getPartition(), Out);
+ Out << '"';
+ }
+
+ printInfoComment(*GA);
+ Out << '\n';
+}
+
+void AssemblyWriter::printIFunc(const GlobalIFunc *GI) {
+ if (GI->isMaterializable())
+ Out << "; Materializable\n";
+
+ AsmWriterContext WriterCtx(&TypePrinter, &Machine, GI->getParent());
+ WriteAsOperandInternal(Out, GI, WriterCtx);
+ Out << " = ";
+
+ Out << getLinkageNameWithSpace(GI->getLinkage());
+ PrintDSOLocation(*GI, Out);
+ PrintVisibility(GI->getVisibility(), Out);
+
+ Out << "ifunc ";
+
+ TypePrinter.print(GI->getValueType(), Out);
+ Out << ", ";
+
+ if (const Constant *Resolver = GI->getResolver()) {
+ writeOperand(Resolver, !isa<ConstantExpr>(Resolver));
} else {
- writeOperand(IS, !isa<ConstantExpr>(IS));
+ TypePrinter.print(GI->getType(), Out);
+ Out << " <<NULL RESOLVER>>";
}
- if (GIS->hasPartition()) {
+ if (GI->hasPartition()) {
Out << ", partition \"";
- printEscapedString(GIS->getPartition(), Out);
+ printEscapedString(GI->getPartition(), Out);
Out << '"';
}
- printInfoComment(*GIS);
+ printInfoComment(*GI);
Out << '\n';
}
@@ -4600,8 +4626,12 @@ void Value::print(raw_ostream &ROS, ModuleSlotTracker &MST,
W.printGlobal(V);
else if (const Function *F = dyn_cast<Function>(GV))
W.printFunction(F);
+ else if (const GlobalAlias *A = dyn_cast<GlobalAlias>(GV))
+ W.printAlias(A);
+ else if (const GlobalIFunc *I = dyn_cast<GlobalIFunc>(GV))
+ W.printIFunc(I);
else
- W.printIndirectSymbol(cast<GlobalIndirectSymbol>(GV));
+ llvm_unreachable("Unknown GlobalValue to print out!");
} else if (const MetadataAsValue *V = dyn_cast<MetadataAsValue>(this)) {
V->getMetadata()->print(ROS, MST, getModuleFromVal(V));
} else if (const Constant *C = dyn_cast<Constant>(this)) {
diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp
index 37d079ba5753f..0aff4906bcf15 100644
--- a/llvm/lib/IR/Globals.cpp
+++ b/llvm/lib/IR/Globals.cpp
@@ -235,7 +235,7 @@ bool GlobalValue::isDeclaration() const {
return F->empty() && !F->isMaterializable();
// Aliases and ifuncs are always definitions.
- assert(isa<GlobalIndirectSymbol>(this));
+ assert(isa<GlobalAlias>(this) || isa<GlobalIFunc>(this));
return false;
}
@@ -280,14 +280,44 @@ bool GlobalObject::canIncreaseAlignment() const {
return true;
}
-const GlobalObject *GlobalValue::getAliaseeObject() const {
- if (auto *GO = dyn_cast<GlobalObject>(this))
+static const GlobalObject *
+findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases) {
+ if (auto *GO = dyn_cast<GlobalObject>(C))
return GO;
- if (auto *GA = dyn_cast<GlobalAlias>(this))
- return GA->getAliaseeObject();
+ if (auto *GA = dyn_cast<GlobalAlias>(C))
+ if (Aliases.insert(GA).second)
+ return findBaseObject(GA->getOperand(0), Aliases);
+ if (auto *CE = dyn_cast<ConstantExpr>(C)) {
+ switch (CE->getOpcode()) {
+ case Instruction::Add: {
+ auto *LHS = findBaseObject(CE->getOperand(0), Aliases);
+ auto *RHS = findBaseObject(CE->getOperand(1), Aliases);
+ if (LHS && RHS)
+ return nullptr;
+ return LHS ? LHS : RHS;
+ }
+ case Instruction::Sub: {
+ if (findBaseObject(CE->getOperand(1), Aliases))
+ return nullptr;
+ return findBaseObject(CE->getOperand(0), Aliases);
+ }
+ case Instruction::IntToPtr:
+ case Instruction::PtrToInt:
+ case Instruction::BitCast:
+ case Instruction::GetElementPtr:
+ return findBaseObject(CE->getOperand(0), Aliases);
+ default:
+ break;
+ }
+ }
return nullptr;
}
+const GlobalObject *GlobalValue::getAliaseeObject() const {
+ DenseSet<const GlobalAlias *> Aliases;
+ return findBaseObject(this, Aliases);
+}
+
bool GlobalValue::isAbsoluteSymbolRef() const {
auto *GO = dyn_cast<GlobalObject>(this);
if (!GO)
@@ -420,50 +450,6 @@ void GlobalVariable::dropAllReferences() {
clearMetadata();
}
-//===----------------------------------------------------------------------===//
-// GlobalIndirectSymbol Implementation
-//===----------------------------------------------------------------------===//
-
-GlobalIndirectSymbol::GlobalIndirectSymbol(Type *Ty, ValueTy VTy,
- unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name,
- Constant *Symbol)
- : GlobalValue(Ty, VTy, &Op<0>(), 1, Linkage, Name, AddressSpace) {
- Op<0>() = Symbol;
-}
-
-static const GlobalObject *
-findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases) {
- if (auto *GO = dyn_cast<GlobalObject>(C))
- return GO;
- if (auto *GA = dyn_cast<GlobalAlias>(C))
- if (Aliases.insert(GA).second)
- return findBaseObject(GA->getOperand(0), Aliases);
- if (auto *CE = dyn_cast<ConstantExpr>(C)) {
- switch (CE->getOpcode()) {
- case Instruction::Add: {
- auto *LHS = findBaseObject(CE->getOperand(0), Aliases);
- auto *RHS = findBaseObject(CE->getOperand(1), Aliases);
- if (LHS && RHS)
- return nullptr;
- return LHS ? LHS : RHS;
- }
- case Instruction::Sub: {
- if (findBaseObject(CE->getOperand(1), Aliases))
- return nullptr;
- return findBaseObject(CE->getOperand(0), Aliases);
- }
- case Instruction::IntToPtr:
- case Instruction::PtrToInt:
- case Instruction::BitCast:
- case Instruction::GetElementPtr:
- return findBaseObject(CE->getOperand(0), Aliases);
- default:
- break;
- }
- }
- return nullptr;
-}
-
//===----------------------------------------------------------------------===//
// GlobalAlias Implementation
//===----------------------------------------------------------------------===//
@@ -471,8 +457,9 @@ findBaseObject(const Constant *C, DenseSet<const GlobalAlias *> &Aliases) {
GlobalAlias::GlobalAlias(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
const Twine &Name, Constant *Aliasee,
Module *ParentModule)
- : GlobalIndirectSymbol(Ty, Value::GlobalAliasVal, AddressSpace, Link, Name,
- Aliasee) {
+ : GlobalValue(Ty, Value::GlobalAliasVal, &Op<0>(), 1, Link, Name,
+ AddressSpace) {
+ setAliasee(Aliasee);
if (ParentModule)
ParentModule->getAliasList().push_back(this);
}
@@ -516,7 +503,7 @@ void GlobalAlias::eraseFromParent() {
void GlobalAlias::setAliasee(Constant *Aliasee) {
assert((!Aliasee || Aliasee->getType() == getType()) &&
"Alias and aliasee types should match!");
- setIndirectSymbol(Aliasee);
+ Op<0>().set(Aliasee);
}
const GlobalObject *GlobalAlias::getAliaseeObject() const {
@@ -531,8 +518,9 @@ const GlobalObject *GlobalAlias::getAliaseeObject() const {
GlobalIFunc::GlobalIFunc(Type *Ty, unsigned AddressSpace, LinkageTypes Link,
const Twine &Name, Constant *Resolver,
Module *ParentModule)
- : GlobalIndirectSymbol(Ty, Value::GlobalIFuncVal, AddressSpace, Link, Name,
- Resolver) {
+ : GlobalObject(Ty, Value::GlobalIFuncVal, &Op<0>(), 1, Link, Name,
+ AddressSpace) {
+ setResolver(Resolver);
if (ParentModule)
ParentModule->getIFuncList().push_back(this);
}
@@ -553,5 +541,5 @@ void GlobalIFunc::eraseFromParent() {
const Function *GlobalIFunc::getResolverFunction() const {
DenseSet<const GlobalAlias *> Aliases;
- return cast<Function>(findBaseObject(getIndirectSymbol(), Aliases));
+ return cast<Function>(findBaseObject(getResolver(), Aliases));
}
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index ba8ce5a3ed703..bad483be197df 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -492,8 +492,8 @@ class IRLinker {
void linkGlobalVariable(GlobalVariable &Dst, GlobalVariable &Src);
Error linkFunctionBody(Function &Dst, Function &Src);
- void linkIndirectSymbolBody(GlobalIndirectSymbol &Dst,
- GlobalIndirectSymbol &Src);
+ void linkAliasAliasee(GlobalAlias &Dst, GlobalAlias &Src);
+ void linkIFuncResolver(GlobalIFunc &Dst, GlobalIFunc &Src);
Error linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src);
/// Replace all types in the source AttributeList with the
@@ -504,7 +504,7 @@ class IRLinker {
/// into the destination module.
GlobalVariable *copyGlobalVariableProto(const GlobalVariable *SGVar);
Function *copyFunctionProto(const Function *SF);
- GlobalValue *copyGlobalIndirectSymbolProto(const GlobalIndirectSymbol *SGIS);
+ GlobalValue *copyIndirectSymbolProto(const GlobalValue *SGV);
/// Perform "replace all uses with" operations. These work items need to be
/// performed as part of materialization, but we postpone them to happen after
@@ -606,10 +606,14 @@ Value *IRLinker::materialize(Value *V, bool ForIndirectSymbol) {
} else if (auto *V = dyn_cast<GlobalVariable>(New)) {
if (V->hasInitializer() || V->hasAppendingLinkage())
return New;
- } else {
- auto *IS = cast<GlobalIndirectSymbol>(New);
- if (IS->getIndirectSymbol())
+ } else if (auto *GA = dyn_cast<GlobalAlias>(New)) {
+ if (GA->getAliasee())
+ return New;
+ } else if (auto *GI = dyn_cast<GlobalIFunc>(New)) {
+ if (GI->getResolver())
return New;
+ } else {
+ llvm_unreachable("Invalid GlobalValue type");
}
// If the global is being linked for an indirect symbol, it may have already
@@ -680,22 +684,28 @@ Function *IRLinker::copyFunctionProto(const Function *SF) {
/// Set up prototypes for any indirect symbols that come over from the source
/// module.
-GlobalValue *
-IRLinker::copyGlobalIndirectSymbolProto(const GlobalIndirectSymbol *SGIS) {
+GlobalValue *IRLinker::copyIndirectSymbolProto(const GlobalValue *SGV) {
// If there is no linkage to be performed or we're linking from the source,
// bring over SGA.
- auto *Ty = TypeMap.get(SGIS->getValueType());
- GlobalIndirectSymbol *GIS;
- if (isa<GlobalAlias>(SGIS))
- GIS = GlobalAlias::create(Ty, SGIS->getAddressSpace(),
- GlobalValue::ExternalLinkage, SGIS->getName(),
- &DstM);
- else
- GIS = GlobalIFunc::create(Ty, SGIS->getAddressSpace(),
- GlobalValue::ExternalLinkage, SGIS->getName(),
- nullptr, &DstM);
- GIS->copyAttributesFrom(SGIS);
- return GIS;
+ auto *Ty = TypeMap.get(SGV->getValueType());
+
+ if (auto *GA = dyn_cast<GlobalAlias>(SGV)) {
+ auto *DGA = GlobalAlias::create(Ty, SGV->getAddressSpace(),
+ GlobalValue::ExternalLinkage,
+ SGV->getName(), &DstM);
+ DGA->copyAttributesFrom(GA);
+ return DGA;
+ }
+
+ if (auto *GI = dyn_cast<GlobalIFunc>(SGV)) {
+ auto *DGI = GlobalIFunc::create(Ty, SGV->getAddressSpace(),
+ GlobalValue::ExternalLinkage,
+ SGV->getName(), nullptr, &DstM);
+ DGI->copyAttributesFrom(GI);
+ return DGI;
+ }
+
+ llvm_unreachable("Invalid source global value type");
}
GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
@@ -707,7 +717,7 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
NewGV = copyFunctionProto(SF);
} else {
if (ForDefinition)
- NewGV = copyGlobalIndirectSymbolProto(cast<GlobalIndirectSymbol>(SGV));
+ NewGV = copyIndirectSymbolProto(SGV);
else if (SGV->getValueType()->isFunctionTy())
NewGV =
Function::Create(cast<FunctionType>(TypeMap.get(SGV->getValueType())),
@@ -1111,10 +1121,12 @@ Error IRLinker::linkFunctionBody(Function &Dst, Function &Src) {
return Error::success();
}
-void IRLinker::linkIndirectSymbolBody(GlobalIndirectSymbol &Dst,
- GlobalIndirectSymbol &Src) {
- Mapper.scheduleMapGlobalIndirectSymbol(Dst, *Src.getIndirectSymbol(),
- IndirectSymbolMCID);
+void IRLinker::linkAliasAliasee(GlobalAlias &Dst, GlobalAlias &Src) {
+ Mapper.scheduleMapGlobalAlias(Dst, *Src.getAliasee(), IndirectSymbolMCID);
+}
+
+void IRLinker::linkIFuncResolver(GlobalIFunc &Dst, GlobalIFunc &Src) {
+ Mapper.scheduleMapGlobalIFunc(Dst, *Src.getResolver(), IndirectSymbolMCID);
}
Error IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
@@ -1124,7 +1136,11 @@ Error IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
linkGlobalVariable(cast<GlobalVariable>(Dst), *GVar);
return Error::success();
}
- linkIndirectSymbolBody(cast<GlobalIndirectSymbol>(Dst), cast<GlobalIndirectSymbol>(Src));
+ if (auto *GA = dyn_cast<GlobalAlias>(&Src)) {
+ linkAliasAliasee(cast<GlobalAlias>(Dst), *GA);
+ return Error::success();
+ }
+ linkIFuncResolver(cast<GlobalIFunc>(Dst), cast<GlobalIFunc>(Src));
return Error::success();
}
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp
index cbe9c69c1fcb7..954d1f09f4e97 100644
--- a/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -204,8 +204,9 @@ uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const {
if (GVar->isConstant())
Res |= BasicSymbolRef::SF_Const;
}
- if (isa_and_nonnull<Function>(GV->getAliaseeObject()) || isa<GlobalIFunc>(GV))
- Res |= BasicSymbolRef::SF_Executable;
+ if (const GlobalObject *GO = GV->getAliaseeObject())
+ if (isa<Function>(GO) || isa<GlobalIFunc>(GO))
+ Res |= BasicSymbolRef::SF_Executable;
if (isa<GlobalAlias>(GV))
Res |= BasicSymbolRef::SF_Indirect;
if (GV->hasPrivateLinkage())
diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index 0f7b8593417b3..340baff90904f 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -342,7 +342,8 @@ struct ICallBranchFunnel final
struct ScopedSaveAliaseesAndUsed {
Module &M;
SmallVector<GlobalValue *, 4> Used, CompilerUsed;
- std::vector<std::pair<GlobalIndirectSymbol *, Function *>> FunctionAliases;
+ std::vector<std::pair<GlobalAlias *, Function *>> FunctionAliases;
+ std::vector<std::pair<GlobalIFunc *, Function *>> ResolverIFuncs;
ScopedSaveAliaseesAndUsed(Module &M) : M(M) {
// The users of this class want to replace all function references except
@@ -362,13 +363,16 @@ struct ScopedSaveAliaseesAndUsed {
if (GlobalVariable *GV = collectUsedGlobalVariables(M, CompilerUsed, true))
GV->eraseFromParent();
- for (auto &GIS : concat<GlobalIndirectSymbol>(M.aliases(), M.ifuncs())) {
+ for (auto &GA : M.aliases()) {
// FIXME: This should look past all aliases not just interposable ones,
// see discussion on D65118.
- if (auto *F =
- dyn_cast<Function>(GIS.getIndirectSymbol()->stripPointerCasts()))
- FunctionAliases.push_back({&GIS, F});
+ if (auto *F = dyn_cast<Function>(GA.getAliasee()->stripPointerCasts()))
+ FunctionAliases.push_back({&GA, F});
}
+
+ for (auto &GI : M.ifuncs())
+ if (auto *F = dyn_cast<Function>(GI.getResolver()->stripPointerCasts()))
+ ResolverIFuncs.push_back({&GI, F});
}
~ScopedSaveAliaseesAndUsed() {
@@ -376,8 +380,15 @@ struct ScopedSaveAliaseesAndUsed {
appendToCompilerUsed(M, CompilerUsed);
for (auto P : FunctionAliases)
- P.first->setIndirectSymbol(
+ P.first->setAliasee(
ConstantExpr::getBitCast(P.second, P.first->getType()));
+
+ for (auto P : ResolverIFuncs) {
+ // This does not preserve pointer casts that may have been stripped by the
+ // constructor, but the resolver's type is
diff erent from that of the
+ // ifunc anyway.
+ P.first->setResolver(P.second);
+ }
}
};
diff --git a/llvm/lib/Transforms/Utils/SplitModule.cpp b/llvm/lib/Transforms/Utils/SplitModule.cpp
index 4bc3ba543b1f3..7e12bbd2851cf 100644
--- a/llvm/lib/Transforms/Utils/SplitModule.cpp
+++ b/llvm/lib/Transforms/Utils/SplitModule.cpp
@@ -24,7 +24,6 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalObject.h"
-#include "llvm/IR/GlobalIndirectSymbol.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
@@ -65,9 +64,8 @@ static void addNonConstUser(ClusterMapType &GVtoClusterMap,
if (const Instruction *I = dyn_cast<Instruction>(U)) {
const GlobalValue *F = I->getParent()->getParent();
GVtoClusterMap.unionSets(GV, F);
- } else if (isa<GlobalIndirectSymbol>(U) || isa<Function>(U) ||
- isa<GlobalVariable>(U)) {
- GVtoClusterMap.unionSets(GV, cast<GlobalValue>(U));
+ } else if (const GlobalValue *GVU = dyn_cast<GlobalValue>(U)) {
+ GVtoClusterMap.unionSets(GV, GVU);
} else {
llvm_unreachable("Underimplemented use case");
}
@@ -91,6 +89,13 @@ static void addAllGlobalValueUsers(ClusterMapType &GVtoClusterMap,
}
}
+static const GlobalObject *getGVPartitioningRoot(const GlobalValue *GV) {
+ const GlobalObject *GO = GV->getAliaseeObject();
+ if (const auto *GI = dyn_cast_or_null<GlobalIFunc>(GO))
+ GO = GI->getResolverFunction();
+ return GO;
+}
+
// Find partitions for module in the way that no locals need to be
// globalized.
// Try to balance pack those partitions into N files since this roughly equals
@@ -123,14 +128,11 @@ static void findPartitions(Module &M, ClusterIDMapType &ClusterIDMap,
Member = &GV;
}
- // For aliases we should not separate them from their aliasees regardless
- // of linkage.
- if (auto *GIS = dyn_cast<GlobalAlias>(&GV)) {
- if (const GlobalObject *Aliasee = GIS->getAliaseeObject())
- GVtoClusterMap.unionSets(&GV, Aliasee);
- } else if (auto *GIS = dyn_cast<GlobalIFunc>(&GV)) {
- GVtoClusterMap.unionSets(&GV, GIS->getResolverFunction());
- }
+ // Aliases should not be separated from their aliasees and ifuncs should
+ // not be separated from their resolvers regardless of linkage.
+ if (const GlobalObject *Root = getGVPartitioningRoot(&GV))
+ if (&GV != Root)
+ GVtoClusterMap.unionSets(&GV, Root);
if (const Function *F = dyn_cast<Function>(&GV)) {
for (const BasicBlock &BB : *F) {
@@ -227,12 +229,8 @@ static void externalize(GlobalValue *GV) {
// Returns whether GV should be in partition (0-based) I of N.
static bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N) {
- if (auto *GIS = dyn_cast<GlobalAlias>(GV)) {
- if (const GlobalObject *Base = GIS->getAliaseeObject())
- GV = Base;
- } else if (auto *GIS = dyn_cast<GlobalIFunc>(GV)) {
- GV = GIS->getResolverFunction();
- }
+ if (const GlobalObject *Root = getGVPartitioningRoot(GV))
+ GV = Root;
StringRef Name;
if (const Comdat *C = GV->getComdat())
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 468c0449cc03d..c3eafd6b24922 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -26,7 +26,8 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/GlobalIndirectSymbol.h"
+#include "llvm/IR/GlobalAlias.h"
+#include "llvm/IR/GlobalIFunc.h"
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/InlineAsm.h"
@@ -68,7 +69,7 @@ struct WorklistEntry {
enum EntryKind {
MapGlobalInit,
MapAppendingVar,
- MapGlobalIndirectSymbol,
+ MapAliasOrIFunc,
RemapFunction
};
struct GVInitTy {
@@ -79,8 +80,8 @@ struct WorklistEntry {
GlobalVariable *GV;
Constant *InitPrefix;
};
- struct GlobalIndirectSymbolTy {
- GlobalIndirectSymbol *GIS;
+ struct AliasOrIFuncTy {
+ GlobalValue *GV;
Constant *Target;
};
@@ -91,7 +92,7 @@ struct WorklistEntry {
union {
GVInitTy GVInit;
AppendingGVTy AppendingGV;
- GlobalIndirectSymbolTy GlobalIndirectSymbol;
+ AliasOrIFuncTy AliasOrIFunc;
Function *RemapF;
} Data;
};
@@ -163,8 +164,8 @@ class Mapper {
bool IsOldCtorDtor,
ArrayRef<Constant *> NewMembers,
unsigned MCID);
- void scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS, Constant &Target,
- unsigned MCID);
+ void scheduleMapAliasOrIFunc(GlobalValue &GV, Constant &Target,
+ unsigned MCID);
void scheduleRemapFunction(Function &F, unsigned MCID);
void flush();
@@ -873,10 +874,17 @@ void Mapper::flush() {
E.AppendingGVIsOldCtorDtor, makeArrayRef(NewInits));
break;
}
- case WorklistEntry::MapGlobalIndirectSymbol:
- E.Data.GlobalIndirectSymbol.GIS->setIndirectSymbol(
- mapConstant(E.Data.GlobalIndirectSymbol.Target));
+ case WorklistEntry::MapAliasOrIFunc: {
+ GlobalValue *GV = E.Data.AliasOrIFunc.GV;
+ Constant *Target = mapConstant(E.Data.AliasOrIFunc.Target);
+ if (auto *GA = dyn_cast<GlobalAlias>(GV))
+ GA->setAliasee(Target);
+ else if (auto *GI = dyn_cast<GlobalIFunc>(GV))
+ GI->setResolver(Target);
+ else
+ llvm_unreachable("Not alias or ifunc");
break;
+ }
case WorklistEntry::RemapFunction:
remapFunction(*E.Data.RemapF);
break;
@@ -1069,16 +1077,18 @@ void Mapper::scheduleMapAppendingVariable(GlobalVariable &GV,
AppendingInits.append(NewMembers.begin(), NewMembers.end());
}
-void Mapper::scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS,
- Constant &Target, unsigned MCID) {
- assert(AlreadyScheduled.insert(&GIS).second && "Should not reschedule");
+void Mapper::scheduleMapAliasOrIFunc(GlobalValue &GV, Constant &Target,
+ unsigned MCID) {
+ assert(AlreadyScheduled.insert(&GV).second && "Should not reschedule");
+ assert((isa<GlobalAlias>(GV) || isa<GlobalIFunc>(GV)) &&
+ "Should be alias or ifunc");
assert(MCID < MCs.size() && "Invalid mapping context");
WorklistEntry WE;
- WE.Kind = WorklistEntry::MapGlobalIndirectSymbol;
+ WE.Kind = WorklistEntry::MapAliasOrIFunc;
WE.MCID = MCID;
- WE.Data.GlobalIndirectSymbol.GIS = &GIS;
- WE.Data.GlobalIndirectSymbol.Target = &Target;
+ WE.Data.AliasOrIFunc.GV = &GV;
+ WE.Data.AliasOrIFunc.Target = &Target;
Worklist.push_back(WE);
}
@@ -1175,10 +1185,14 @@ void ValueMapper::scheduleMapAppendingVariable(GlobalVariable &GV,
GV, InitPrefix, IsOldCtorDtor, NewMembers, MCID);
}
-void ValueMapper::scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS,
- Constant &Target,
- unsigned MCID) {
- getAsMapper(pImpl)->scheduleMapGlobalIndirectSymbol(GIS, Target, MCID);
+void ValueMapper::scheduleMapGlobalAlias(GlobalAlias &GA, Constant &Aliasee,
+ unsigned MCID) {
+ getAsMapper(pImpl)->scheduleMapAliasOrIFunc(GA, Aliasee, MCID);
+}
+
+void ValueMapper::scheduleMapGlobalIFunc(GlobalIFunc &GI, Constant &Resolver,
+ unsigned MCID) {
+ getAsMapper(pImpl)->scheduleMapAliasOrIFunc(GI, Resolver, MCID);
}
void ValueMapper::scheduleRemapFunction(Function &F, unsigned MCID) {
diff --git a/llvm/unittests/IR/ConstantsTest.cpp b/llvm/unittests/IR/ConstantsTest.cpp
index 7a2488b175673..41cfb9d5c04f0 100644
--- a/llvm/unittests/IR/ConstantsTest.cpp
+++ b/llvm/unittests/IR/ConstantsTest.cpp
@@ -385,7 +385,7 @@ TEST(ConstantsTest, GEPReplaceWithConstant) {
new GlobalVariable(*M, PtrTy, false, GlobalValue::ExternalLinkage, GEP);
ASSERT_EQ(GEP, Ref->getInitializer());
- auto *Global = new GlobalVariable(*M, PtrTy, false,
+ auto *Global = new GlobalVariable(*M, IntTy, false,
GlobalValue::ExternalLinkage, nullptr);
auto *Alias = GlobalAlias::create(IntTy, 0, GlobalValue::ExternalLinkage,
"alias", Global, M.get());
More information about the llvm-commits
mailing list