mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
IR: Introduce local_unnamed_addr attribute.
If a local_unnamed_addr attribute is attached to a global, the address is known to be insignificant within the module. It is distinct from the existing unnamed_addr attribute in that it only describes a local property of the module rather than a global property of the symbol. This attribute is intended to be used by the code generator and LTO to allow the linker to decide whether the global needs to be in the symbol table. It is possible to exclude a global from the symbol table if three things are true: - This attribute is present on every instance of the global (which means that the normal rule that the global must have a unique address can be broken without being observable by the program by performing comparisons against the global's address) - The global has linkonce_odr linkage (which means that each linkage unit must have its own copy of the global if it requires one, and the copy in each linkage unit must be the same) - It is a constant or a function (which means that the program cannot observe that the unique-address rule has been broken by writing to the global) Although this attribute could in principle be computed from the module contents, LTO clients (i.e. linkers) will normally need to be able to compute this property as part of symbol resolution, and it would be inefficient to materialize every module just to compute it. See: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160509/356401.html http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20160516/356738.html for earlier discussion. Part of the fix for PR27553. Differential Revision: http://reviews.llvm.org/D20348 llvm-svn: 272709
This commit is contained in:
parent
ebef1e3fab
commit
5dcb77e9fb
@ -731,8 +731,14 @@ global variable. The operand fields are:
|
|||||||
* ``initialexec``: code 3
|
* ``initialexec``: code 3
|
||||||
* ``localexec``: code 4
|
* ``localexec``: code 4
|
||||||
|
|
||||||
* *unnamed_addr*: If present and non-zero, indicates that the variable has
|
.. _bcunnamedaddr:
|
||||||
``unnamed_addr``
|
|
||||||
|
* *unnamed_addr*: If present, an encoding of the ``unnamed_addr`` attribute of this
|
||||||
|
variable:
|
||||||
|
|
||||||
|
* not ``unnamed_addr``: code 0
|
||||||
|
* ``unnamed_addr``: code 1
|
||||||
|
* ``local_unnamed_addr``: code 2
|
||||||
|
|
||||||
.. _bcdllstorageclass:
|
.. _bcdllstorageclass:
|
||||||
|
|
||||||
@ -791,8 +797,8 @@ function. The operand fields are:
|
|||||||
* *gc*: If present and nonzero, the 1-based garbage collector index in the table
|
* *gc*: If present and nonzero, the 1-based garbage collector index in the table
|
||||||
of `MODULE_CODE_GCNAME`_ entries.
|
of `MODULE_CODE_GCNAME`_ entries.
|
||||||
|
|
||||||
* *unnamed_addr*: If present and non-zero, indicates that the function has
|
* *unnamed_addr*: If present, an encoding of the
|
||||||
``unnamed_addr``
|
:ref:`unnamed_addr<bcunnamedaddr>` attribute of this function
|
||||||
|
|
||||||
* *prologuedata*: If non-zero, the value index of the prologue data for this function,
|
* *prologuedata*: If non-zero, the value index of the prologue data for this function,
|
||||||
plus 1.
|
plus 1.
|
||||||
@ -830,8 +836,8 @@ fields are
|
|||||||
* *threadlocal*: If present, an encoding of the
|
* *threadlocal*: If present, an encoding of the
|
||||||
:ref:`thread local property<bcthreadlocal>` of the alias
|
:ref:`thread local property<bcthreadlocal>` of the alias
|
||||||
|
|
||||||
* *unnamed_addr*: If present and non-zero, indicates that the alias has
|
* *unnamed_addr*: If present, an encoding of the
|
||||||
``unnamed_addr``
|
:ref:`unnamed_addr<bcunnamedaddr>` attribute of this alias
|
||||||
|
|
||||||
MODULE_CODE_PURGEVALS Record
|
MODULE_CODE_PURGEVALS Record
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -589,6 +589,9 @@ initializer. Note that a constant with significant address *can* be
|
|||||||
merged with a ``unnamed_addr`` constant, the result being a constant
|
merged with a ``unnamed_addr`` constant, the result being a constant
|
||||||
whose address is significant.
|
whose address is significant.
|
||||||
|
|
||||||
|
If the ``local_unnamed_addr`` attribute is given, the address is known to
|
||||||
|
not be significant within the module.
|
||||||
|
|
||||||
A global variable may be declared to reside in a target-specific
|
A global variable may be declared to reside in a target-specific
|
||||||
numbered address space. For targets that support them, address spaces
|
numbered address space. For targets that support them, address spaces
|
||||||
may affect how optimizations are performed and/or what target
|
may affect how optimizations are performed and/or what target
|
||||||
@ -628,7 +631,8 @@ Variables and aliases can have a
|
|||||||
Syntax::
|
Syntax::
|
||||||
|
|
||||||
@<GlobalVarName> = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
|
@<GlobalVarName> = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal]
|
||||||
[unnamed_addr] [AddrSpace] [ExternallyInitialized]
|
[(unnamed_addr|local_unnamed_addr)] [AddrSpace]
|
||||||
|
[ExternallyInitialized]
|
||||||
<global | constant> <Type> [<InitializerConstant>]
|
<global | constant> <Type> [<InitializerConstant>]
|
||||||
[, section "name"] [, comdat [($name)]]
|
[, section "name"] [, comdat [($name)]]
|
||||||
[, align <Alignment>] (, !name !N)*
|
[, align <Alignment>] (, !name !N)*
|
||||||
@ -675,14 +679,14 @@ an optional list of attached :ref:`metadata <metadata>`,
|
|||||||
an opening curly brace, a list of basic blocks, and a closing curly brace.
|
an opening curly brace, a list of basic blocks, and a closing curly brace.
|
||||||
|
|
||||||
LLVM function declarations consist of the "``declare``" keyword, an
|
LLVM function declarations consist of the "``declare``" keyword, an
|
||||||
optional :ref:`linkage type <linkage>`, an optional :ref:`visibility
|
optional :ref:`linkage type <linkage>`, an optional :ref:`visibility style
|
||||||
style <visibility>`, an optional :ref:`DLL storage class <dllstorageclass>`,
|
<visibility>`, an optional :ref:`DLL storage class <dllstorageclass>`, an
|
||||||
an optional :ref:`calling convention <callingconv>`,
|
optional :ref:`calling convention <callingconv>`, an optional ``unnamed_addr``
|
||||||
an optional ``unnamed_addr`` attribute, a return type, an optional
|
or ``local_unnamed_addr`` attribute, a return type, an optional :ref:`parameter
|
||||||
:ref:`parameter attribute <paramattrs>` for the return type, a function
|
attribute <paramattrs>` for the return type, a function name, a possibly
|
||||||
name, a possibly empty list of arguments, an optional alignment, an optional
|
empty list of arguments, an optional alignment, an optional :ref:`garbage
|
||||||
:ref:`garbage collector name <gc>`, an optional :ref:`prefix <prefixdata>`,
|
collector name <gc>`, an optional :ref:`prefix <prefixdata>`, and an optional
|
||||||
and an optional :ref:`prologue <prologuedata>`.
|
:ref:`prologue <prologuedata>`.
|
||||||
|
|
||||||
A function definition contains a list of basic blocks, forming the CFG (Control
|
A function definition contains a list of basic blocks, forming the CFG (Control
|
||||||
Flow Graph) for the function. Each basic block may optionally start with a label
|
Flow Graph) for the function. Each basic block may optionally start with a label
|
||||||
@ -713,14 +717,17 @@ alignment. All alignments must be a power of 2.
|
|||||||
If the ``unnamed_addr`` attribute is given, the address is known to not
|
If the ``unnamed_addr`` attribute is given, the address is known to not
|
||||||
be significant and two identical functions can be merged.
|
be significant and two identical functions can be merged.
|
||||||
|
|
||||||
|
If the ``local_unnamed_addr`` attribute is given, the address is known to
|
||||||
|
not be significant within the module.
|
||||||
|
|
||||||
Syntax::
|
Syntax::
|
||||||
|
|
||||||
define [linkage] [visibility] [DLLStorageClass]
|
define [linkage] [visibility] [DLLStorageClass]
|
||||||
[cconv] [ret attrs]
|
[cconv] [ret attrs]
|
||||||
<ResultType> @<FunctionName> ([argument list])
|
<ResultType> @<FunctionName> ([argument list])
|
||||||
[unnamed_addr] [fn Attrs] [section "name"] [comdat [($name)]]
|
[(unnamed_addr|local_unnamed_addr)] [fn Attrs] [section "name"]
|
||||||
[align N] [gc] [prefix Constant] [prologue Constant]
|
[comdat [($name)]] [align N] [gc] [prefix Constant]
|
||||||
[personality Constant] (!name !N)* { ... }
|
[prologue Constant] [personality Constant] (!name !N)* { ... }
|
||||||
|
|
||||||
The argument list is a comma separated sequence of arguments where each
|
The argument list is a comma separated sequence of arguments where each
|
||||||
argument is of the following form:
|
argument is of the following form:
|
||||||
@ -747,7 +754,7 @@ Aliases may have an optional :ref:`linkage type <linkage>`, an optional
|
|||||||
|
|
||||||
Syntax::
|
Syntax::
|
||||||
|
|
||||||
@<Name> = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal] [unnamed_addr] alias <AliaseeTy>, <AliaseeTy>* @<Aliasee>
|
@<Name> = [Linkage] [Visibility] [DLLStorageClass] [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] alias <AliaseeTy>, <AliaseeTy>* @<Aliasee>
|
||||||
|
|
||||||
The linkage must be one of ``private``, ``internal``, ``linkonce``, ``weak``,
|
The linkage must be one of ``private``, ``internal``, ``linkonce``, ``weak``,
|
||||||
``linkonce_odr``, ``weak_odr``, ``external``. Note that some system linkers
|
``linkonce_odr``, ``weak_odr``, ``external``. Note that some system linkers
|
||||||
@ -757,6 +764,9 @@ Aliases that are not ``unnamed_addr`` are guaranteed to have the same address as
|
|||||||
the aliasee expression. ``unnamed_addr`` ones are only guaranteed to point
|
the aliasee expression. ``unnamed_addr`` ones are only guaranteed to point
|
||||||
to the same content.
|
to the same content.
|
||||||
|
|
||||||
|
If the ``local_unnamed_addr`` attribute is given, the address is known to
|
||||||
|
not be significant within the module.
|
||||||
|
|
||||||
Since aliases are only a second name, some restrictions apply, of which
|
Since aliases are only a second name, some restrictions apply, of which
|
||||||
some can only be checked when producing an object file:
|
some can only be checked when producing an object file:
|
||||||
|
|
||||||
|
@ -70,8 +70,9 @@ protected:
|
|||||||
LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace)
|
LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace)
|
||||||
: Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps),
|
: Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps),
|
||||||
ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility),
|
ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility),
|
||||||
UnnamedAddr(0), DllStorageClass(DefaultStorageClass),
|
UnnamedAddrVal(unsigned(UnnamedAddr::None)),
|
||||||
ThreadLocal(NotThreadLocal), IntID((Intrinsic::ID)0U), Parent(nullptr) {
|
DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal),
|
||||||
|
IntID((Intrinsic::ID)0U), Parent(nullptr) {
|
||||||
setName(Name);
|
setName(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ protected:
|
|||||||
// them.
|
// them.
|
||||||
unsigned Linkage : 4; // The linkage of this global
|
unsigned Linkage : 4; // The linkage of this global
|
||||||
unsigned Visibility : 2; // The visibility style of this global
|
unsigned Visibility : 2; // The visibility style of this global
|
||||||
unsigned UnnamedAddr : 1; // This value's address is not significant
|
unsigned UnnamedAddrVal : 2; // This value's address is not significant
|
||||||
unsigned DllStorageClass : 2; // DLL storage class
|
unsigned DllStorageClass : 2; // DLL storage class
|
||||||
|
|
||||||
unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is
|
unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is
|
||||||
@ -89,7 +90,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Give subclasses access to what otherwise would be wasted padding.
|
// Give subclasses access to what otherwise would be wasted padding.
|
||||||
// (19 + 3 + 2 + 1 + 2 + 5) == 32.
|
// (19 + 4 + 2 + 2 + 2 + 3) == 32.
|
||||||
unsigned SubClassData : GlobalValueSubClassDataBits;
|
unsigned SubClassData : GlobalValueSubClassDataBits;
|
||||||
|
|
||||||
friend class Constant;
|
friend class Constant;
|
||||||
@ -153,8 +154,37 @@ public:
|
|||||||
|
|
||||||
unsigned getAlignment() const;
|
unsigned getAlignment() const;
|
||||||
|
|
||||||
bool hasUnnamedAddr() const { return UnnamedAddr; }
|
enum class UnnamedAddr {
|
||||||
void setUnnamedAddr(bool Val) { UnnamedAddr = Val; }
|
None,
|
||||||
|
Local,
|
||||||
|
Global,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool hasGlobalUnnamedAddr() const {
|
||||||
|
return getUnnamedAddr() == UnnamedAddr::Global;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if this value's address is not significant in this module.
|
||||||
|
/// This attribute is intended to be used only by the code generator and LTO
|
||||||
|
/// to allow the linker to decide whether the global needs to be in the symbol
|
||||||
|
/// table. It should probably not be used in optimizations, as the value may
|
||||||
|
/// have uses outside the module; use hasGlobalUnnamedAddr() instead.
|
||||||
|
bool hasAtLeastLocalUnnamedAddr() const {
|
||||||
|
return getUnnamedAddr() != UnnamedAddr::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnnamedAddr getUnnamedAddr() const {
|
||||||
|
return UnnamedAddr(UnnamedAddrVal);
|
||||||
|
}
|
||||||
|
void setUnnamedAddr(UnnamedAddr Val) { UnnamedAddrVal = unsigned(Val); }
|
||||||
|
|
||||||
|
static UnnamedAddr getMinUnnamedAddr(UnnamedAddr A, UnnamedAddr B) {
|
||||||
|
if (A == UnnamedAddr::None || B == UnnamedAddr::None)
|
||||||
|
return UnnamedAddr::None;
|
||||||
|
if (A == UnnamedAddr::Local || B == UnnamedAddr::Local)
|
||||||
|
return UnnamedAddr::Local;
|
||||||
|
return UnnamedAddr::Global;
|
||||||
|
}
|
||||||
|
|
||||||
bool hasComdat() const { return getComdat() != nullptr; }
|
bool hasComdat() const { return getComdat() != nullptr; }
|
||||||
Comdat *getComdat();
|
Comdat *getComdat();
|
||||||
|
@ -2086,7 +2086,7 @@ computePointerICmp(const DataLayout &DL, const TargetLibraryInfo *TLI,
|
|||||||
return AI->getParent() && AI->getFunction() && AI->isStaticAlloca();
|
return AI->getParent() && AI->getFunction() && AI->isStaticAlloca();
|
||||||
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
|
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
|
||||||
return (GV->hasLocalLinkage() || GV->hasHiddenVisibility() ||
|
return (GV->hasLocalLinkage() || GV->hasHiddenVisibility() ||
|
||||||
GV->hasProtectedVisibility() || GV->hasUnnamedAddr()) &&
|
GV->hasProtectedVisibility() || GV->hasGlobalUnnamedAddr()) &&
|
||||||
!GV->isThreadLocal();
|
!GV->isThreadLocal();
|
||||||
if (const Argument *A = dyn_cast<Argument>(V))
|
if (const Argument *A = dyn_cast<Argument>(V))
|
||||||
return A->hasByValAttr();
|
return A->hasByValAttr();
|
||||||
|
@ -513,6 +513,7 @@ lltok::Kind LLLexer::LexIdentifier() {
|
|||||||
KEYWORD(hidden);
|
KEYWORD(hidden);
|
||||||
KEYWORD(protected);
|
KEYWORD(protected);
|
||||||
KEYWORD(unnamed_addr);
|
KEYWORD(unnamed_addr);
|
||||||
|
KEYWORD(local_unnamed_addr);
|
||||||
KEYWORD(externally_initialized);
|
KEYWORD(externally_initialized);
|
||||||
KEYWORD(extern_weak);
|
KEYWORD(extern_weak);
|
||||||
KEYWORD(external);
|
KEYWORD(external);
|
||||||
|
@ -429,6 +429,17 @@ bool LLParser::ParseGlobalType(bool &IsConstant) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LLParser::ParseOptionalUnnamedAddr(
|
||||||
|
GlobalVariable::UnnamedAddr &UnnamedAddr) {
|
||||||
|
if (EatIfPresent(lltok::kw_unnamed_addr))
|
||||||
|
UnnamedAddr = GlobalValue::UnnamedAddr::Global;
|
||||||
|
else if (EatIfPresent(lltok::kw_local_unnamed_addr))
|
||||||
|
UnnamedAddr = GlobalValue::UnnamedAddr::Local;
|
||||||
|
else
|
||||||
|
UnnamedAddr = GlobalValue::UnnamedAddr::None;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// ParseUnnamedGlobal:
|
/// ParseUnnamedGlobal:
|
||||||
/// OptionalVisibility (ALIAS | IFUNC) ...
|
/// OptionalVisibility (ALIAS | IFUNC) ...
|
||||||
/// OptionalLinkage OptionalVisibility OptionalDLLStorageClass
|
/// OptionalLinkage OptionalVisibility OptionalDLLStorageClass
|
||||||
@ -455,9 +466,9 @@ bool LLParser::ParseUnnamedGlobal() {
|
|||||||
bool HasLinkage;
|
bool HasLinkage;
|
||||||
unsigned Linkage, Visibility, DLLStorageClass;
|
unsigned Linkage, Visibility, DLLStorageClass;
|
||||||
GlobalVariable::ThreadLocalMode TLM;
|
GlobalVariable::ThreadLocalMode TLM;
|
||||||
bool UnnamedAddr;
|
GlobalVariable::UnnamedAddr UnnamedAddr;
|
||||||
if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) ||
|
if (ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) ||
|
||||||
ParseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
|
ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
|
if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
|
||||||
@ -481,10 +492,10 @@ bool LLParser::ParseNamedGlobal() {
|
|||||||
bool HasLinkage;
|
bool HasLinkage;
|
||||||
unsigned Linkage, Visibility, DLLStorageClass;
|
unsigned Linkage, Visibility, DLLStorageClass;
|
||||||
GlobalVariable::ThreadLocalMode TLM;
|
GlobalVariable::ThreadLocalMode TLM;
|
||||||
bool UnnamedAddr;
|
GlobalVariable::UnnamedAddr UnnamedAddr;
|
||||||
if (ParseToken(lltok::equal, "expected '=' in global variable") ||
|
if (ParseToken(lltok::equal, "expected '=' in global variable") ||
|
||||||
ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) ||
|
ParseOptionalLinkage(Linkage, HasLinkage, Visibility, DLLStorageClass) ||
|
||||||
ParseOptionalThreadLocal(TLM) || parseOptionalUnnamedAddr(UnnamedAddr))
|
ParseOptionalThreadLocal(TLM) || ParseOptionalUnnamedAddr(UnnamedAddr))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
|
if (Lex.getKind() != lltok::kw_alias && Lex.getKind() != lltok::kw_ifunc)
|
||||||
@ -659,11 +670,10 @@ static bool isValidVisibilityForLinkage(unsigned V, unsigned L) {
|
|||||||
///
|
///
|
||||||
/// Everything through OptionalUnnamedAddr has already been parsed.
|
/// Everything through OptionalUnnamedAddr has already been parsed.
|
||||||
///
|
///
|
||||||
bool LLParser::parseIndirectSymbol(const std::string &Name, LocTy NameLoc,
|
bool LLParser::parseIndirectSymbol(
|
||||||
unsigned L, unsigned Visibility,
|
const std::string &Name, LocTy NameLoc, unsigned L, unsigned Visibility,
|
||||||
unsigned DLLStorageClass,
|
unsigned DLLStorageClass, GlobalVariable::ThreadLocalMode TLM,
|
||||||
GlobalVariable::ThreadLocalMode TLM,
|
GlobalVariable::UnnamedAddr UnnamedAddr) {
|
||||||
bool UnnamedAddr) {
|
|
||||||
bool IsAlias;
|
bool IsAlias;
|
||||||
if (Lex.getKind() == lltok::kw_alias)
|
if (Lex.getKind() == lltok::kw_alias)
|
||||||
IsAlias = true;
|
IsAlias = true;
|
||||||
@ -799,7 +809,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
|
|||||||
unsigned Linkage, bool HasLinkage,
|
unsigned Linkage, bool HasLinkage,
|
||||||
unsigned Visibility, unsigned DLLStorageClass,
|
unsigned Visibility, unsigned DLLStorageClass,
|
||||||
GlobalVariable::ThreadLocalMode TLM,
|
GlobalVariable::ThreadLocalMode TLM,
|
||||||
bool UnnamedAddr) {
|
GlobalVariable::UnnamedAddr UnnamedAddr) {
|
||||||
if (!isValidVisibilityForLinkage(Visibility, Linkage))
|
if (!isValidVisibilityForLinkage(Visibility, Linkage))
|
||||||
return Error(NameLoc,
|
return Error(NameLoc,
|
||||||
"symbol with local linkage must have default visibility");
|
"symbol with local linkage must have default visibility");
|
||||||
@ -4580,7 +4590,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
|||||||
std::string Section;
|
std::string Section;
|
||||||
unsigned Alignment;
|
unsigned Alignment;
|
||||||
std::string GC;
|
std::string GC;
|
||||||
bool UnnamedAddr;
|
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
|
||||||
LocTy UnnamedAddrLoc;
|
LocTy UnnamedAddrLoc;
|
||||||
Constant *Prefix = nullptr;
|
Constant *Prefix = nullptr;
|
||||||
Constant *Prologue = nullptr;
|
Constant *Prologue = nullptr;
|
||||||
@ -4588,8 +4598,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
|||||||
Comdat *C;
|
Comdat *C;
|
||||||
|
|
||||||
if (ParseArgumentList(ArgList, isVarArg) ||
|
if (ParseArgumentList(ArgList, isVarArg) ||
|
||||||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
|
ParseOptionalUnnamedAddr(UnnamedAddr) ||
|
||||||
&UnnamedAddrLoc) ||
|
|
||||||
ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,
|
ParseFnAttributeValuePairs(FuncAttrs, FwdRefAttrGrps, false,
|
||||||
BuiltinLoc) ||
|
BuiltinLoc) ||
|
||||||
(EatIfPresent(lltok::kw_section) &&
|
(EatIfPresent(lltok::kw_section) &&
|
||||||
|
@ -226,9 +226,7 @@ namespace llvm {
|
|||||||
|
|
||||||
bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
|
bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM);
|
||||||
bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
|
bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM);
|
||||||
bool parseOptionalUnnamedAddr(bool &UnnamedAddr) {
|
bool ParseOptionalUnnamedAddr(GlobalVariable::UnnamedAddr &UnnamedAddr);
|
||||||
return ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr);
|
|
||||||
}
|
|
||||||
bool ParseOptionalAddrSpace(unsigned &AddrSpace);
|
bool ParseOptionalAddrSpace(unsigned &AddrSpace);
|
||||||
bool ParseOptionalParamAttrs(AttrBuilder &B);
|
bool ParseOptionalParamAttrs(AttrBuilder &B);
|
||||||
bool ParseOptionalReturnAttrs(AttrBuilder &B);
|
bool ParseOptionalReturnAttrs(AttrBuilder &B);
|
||||||
@ -275,12 +273,13 @@ namespace llvm {
|
|||||||
bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
|
bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
|
||||||
bool HasLinkage, unsigned Visibility,
|
bool HasLinkage, unsigned Visibility,
|
||||||
unsigned DLLStorageClass,
|
unsigned DLLStorageClass,
|
||||||
GlobalVariable::ThreadLocalMode TLM, bool UnnamedAddr);
|
GlobalVariable::ThreadLocalMode TLM,
|
||||||
|
GlobalVariable::UnnamedAddr UnnamedAddr);
|
||||||
bool parseIndirectSymbol(const std::string &Name, LocTy Loc,
|
bool parseIndirectSymbol(const std::string &Name, LocTy Loc,
|
||||||
unsigned Linkage, unsigned Visibility,
|
unsigned Linkage, unsigned Visibility,
|
||||||
unsigned DLLStorageClass,
|
unsigned DLLStorageClass,
|
||||||
GlobalVariable::ThreadLocalMode TLM,
|
GlobalVariable::ThreadLocalMode TLM,
|
||||||
bool UnnamedAddr);
|
GlobalVariable::UnnamedAddr UnnamedAddr);
|
||||||
bool parseComdat();
|
bool parseComdat();
|
||||||
bool ParseStandaloneMetadata();
|
bool ParseStandaloneMetadata();
|
||||||
bool ParseNamedMetadata();
|
bool ParseNamedMetadata();
|
||||||
|
@ -60,6 +60,7 @@ enum Kind {
|
|||||||
kw_hidden,
|
kw_hidden,
|
||||||
kw_protected,
|
kw_protected,
|
||||||
kw_unnamed_addr,
|
kw_unnamed_addr,
|
||||||
|
kw_local_unnamed_addr,
|
||||||
kw_externally_initialized,
|
kw_externally_initialized,
|
||||||
kw_extern_weak,
|
kw_extern_weak,
|
||||||
kw_external,
|
kw_external,
|
||||||
|
@ -773,6 +773,15 @@ static GlobalVariable::ThreadLocalMode getDecodedThreadLocalMode(unsigned Val) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GlobalVariable::UnnamedAddr getDecodedUnnamedAddrType(unsigned Val) {
|
||||||
|
switch (Val) {
|
||||||
|
default: // Map unknown to UnnamedAddr::None.
|
||||||
|
case 0: return GlobalVariable::UnnamedAddr::None;
|
||||||
|
case 1: return GlobalVariable::UnnamedAddr::Global;
|
||||||
|
case 2: return GlobalVariable::UnnamedAddr::Local;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int getDecodedCastOpcode(unsigned Val) {
|
static int getDecodedCastOpcode(unsigned Val) {
|
||||||
switch (Val) {
|
switch (Val) {
|
||||||
default: return -1;
|
default: return -1;
|
||||||
@ -3791,9 +3800,9 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
|||||||
if (Record.size() > 7)
|
if (Record.size() > 7)
|
||||||
TLM = getDecodedThreadLocalMode(Record[7]);
|
TLM = getDecodedThreadLocalMode(Record[7]);
|
||||||
|
|
||||||
bool UnnamedAddr = false;
|
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
|
||||||
if (Record.size() > 8)
|
if (Record.size() > 8)
|
||||||
UnnamedAddr = Record[8];
|
UnnamedAddr = getDecodedUnnamedAddrType(Record[8]);
|
||||||
|
|
||||||
bool ExternallyInitialized = false;
|
bool ExternallyInitialized = false;
|
||||||
if (Record.size() > 9)
|
if (Record.size() > 9)
|
||||||
@ -3828,6 +3837,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
|||||||
} else if (hasImplicitComdat(RawLinkage)) {
|
} else if (hasImplicitComdat(RawLinkage)) {
|
||||||
NewGV->setComdat(reinterpret_cast<Comdat *>(1));
|
NewGV->setComdat(reinterpret_cast<Comdat *>(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT: {
|
case bitc::MODULE_CODE_GLOBALVAR_ATTACHMENT: {
|
||||||
@ -3885,9 +3895,9 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
|||||||
return error("Invalid ID");
|
return error("Invalid ID");
|
||||||
Func->setGC(GCTable[Record[8] - 1]);
|
Func->setGC(GCTable[Record[8] - 1]);
|
||||||
}
|
}
|
||||||
bool UnnamedAddr = false;
|
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::None;
|
||||||
if (Record.size() > 9)
|
if (Record.size() > 9)
|
||||||
UnnamedAddr = Record[9];
|
UnnamedAddr = getDecodedUnnamedAddrType(Record[9]);
|
||||||
Func->setUnnamedAddr(UnnamedAddr);
|
Func->setUnnamedAddr(UnnamedAddr);
|
||||||
if (Record.size() > 10 && Record[10] != 0)
|
if (Record.size() > 10 && Record[10] != 0)
|
||||||
FunctionPrologues.push_back(std::make_pair(Func, Record[10]-1));
|
FunctionPrologues.push_back(std::make_pair(Func, Record[10]-1));
|
||||||
@ -3974,7 +3984,7 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit,
|
|||||||
if (OpNum != Record.size())
|
if (OpNum != Record.size())
|
||||||
NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++]));
|
NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[OpNum++]));
|
||||||
if (OpNum != Record.size())
|
if (OpNum != Record.size())
|
||||||
NewGA->setUnnamedAddr(Record[OpNum++]);
|
NewGA->setUnnamedAddr(getDecodedUnnamedAddrType(Record[OpNum++]));
|
||||||
ValueList.push_back(NewGA);
|
ValueList.push_back(NewGA);
|
||||||
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
|
IndirectSymbolInits.push_back(std::make_pair(NewGA, Val));
|
||||||
break;
|
break;
|
||||||
|
@ -996,6 +996,15 @@ static unsigned getEncodedComdatSelectionKind(const Comdat &C) {
|
|||||||
llvm_unreachable("Invalid selection kind");
|
llvm_unreachable("Invalid selection kind");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned getEncodedUnnamedAddr(const GlobalValue &GV) {
|
||||||
|
switch (GV.getUnnamedAddr()) {
|
||||||
|
case GlobalValue::UnnamedAddr::None: return 0;
|
||||||
|
case GlobalValue::UnnamedAddr::Local: return 2;
|
||||||
|
case GlobalValue::UnnamedAddr::Global: return 1;
|
||||||
|
}
|
||||||
|
llvm_unreachable("Invalid unnamed_addr");
|
||||||
|
}
|
||||||
|
|
||||||
void ModuleBitcodeWriter::writeComdats() {
|
void ModuleBitcodeWriter::writeComdats() {
|
||||||
SmallVector<unsigned, 64> Vals;
|
SmallVector<unsigned, 64> Vals;
|
||||||
for (const Comdat *C : VE.getComdats()) {
|
for (const Comdat *C : VE.getComdats()) {
|
||||||
@ -1157,12 +1166,13 @@ void ModuleBitcodeWriter::writeModuleInfo() {
|
|||||||
Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
|
Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0);
|
||||||
if (GV.isThreadLocal() ||
|
if (GV.isThreadLocal() ||
|
||||||
GV.getVisibility() != GlobalValue::DefaultVisibility ||
|
GV.getVisibility() != GlobalValue::DefaultVisibility ||
|
||||||
GV.hasUnnamedAddr() || GV.isExternallyInitialized() ||
|
GV.getUnnamedAddr() != GlobalValue::UnnamedAddr::None ||
|
||||||
|
GV.isExternallyInitialized() ||
|
||||||
GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
|
GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass ||
|
||||||
GV.hasComdat()) {
|
GV.hasComdat()) {
|
||||||
Vals.push_back(getEncodedVisibility(GV));
|
Vals.push_back(getEncodedVisibility(GV));
|
||||||
Vals.push_back(getEncodedThreadLocalMode(GV));
|
Vals.push_back(getEncodedThreadLocalMode(GV));
|
||||||
Vals.push_back(GV.hasUnnamedAddr());
|
Vals.push_back(getEncodedUnnamedAddr(GV));
|
||||||
Vals.push_back(GV.isExternallyInitialized());
|
Vals.push_back(GV.isExternallyInitialized());
|
||||||
Vals.push_back(getEncodedDLLStorageClass(GV));
|
Vals.push_back(getEncodedDLLStorageClass(GV));
|
||||||
Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0);
|
Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0);
|
||||||
@ -1188,7 +1198,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
|
|||||||
Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
|
Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0);
|
||||||
Vals.push_back(getEncodedVisibility(F));
|
Vals.push_back(getEncodedVisibility(F));
|
||||||
Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
|
Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0);
|
||||||
Vals.push_back(F.hasUnnamedAddr());
|
Vals.push_back(getEncodedUnnamedAddr(F));
|
||||||
Vals.push_back(F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1)
|
Vals.push_back(F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1)
|
||||||
: 0);
|
: 0);
|
||||||
Vals.push_back(getEncodedDLLStorageClass(F));
|
Vals.push_back(getEncodedDLLStorageClass(F));
|
||||||
@ -1205,7 +1215,8 @@ void ModuleBitcodeWriter::writeModuleInfo() {
|
|||||||
|
|
||||||
// Emit the alias information.
|
// Emit the alias information.
|
||||||
for (const GlobalAlias &A : M.aliases()) {
|
for (const GlobalAlias &A : M.aliases()) {
|
||||||
// ALIAS: [alias type, aliasee val#, linkage, visibility]
|
// ALIAS: [alias type, aliasee val#, linkage, visibility, dllstorageclass,
|
||||||
|
// threadlocal, unnamed_addr]
|
||||||
Vals.push_back(VE.getTypeID(A.getValueType()));
|
Vals.push_back(VE.getTypeID(A.getValueType()));
|
||||||
Vals.push_back(A.getType()->getAddressSpace());
|
Vals.push_back(A.getType()->getAddressSpace());
|
||||||
Vals.push_back(VE.getValueID(A.getAliasee()));
|
Vals.push_back(VE.getValueID(A.getAliasee()));
|
||||||
@ -1213,7 +1224,7 @@ void ModuleBitcodeWriter::writeModuleInfo() {
|
|||||||
Vals.push_back(getEncodedVisibility(A));
|
Vals.push_back(getEncodedVisibility(A));
|
||||||
Vals.push_back(getEncodedDLLStorageClass(A));
|
Vals.push_back(getEncodedDLLStorageClass(A));
|
||||||
Vals.push_back(getEncodedThreadLocalMode(A));
|
Vals.push_back(getEncodedThreadLocalMode(A));
|
||||||
Vals.push_back(A.hasUnnamedAddr());
|
Vals.push_back(getEncodedUnnamedAddr(A));
|
||||||
unsigned AbbrevToUse = 0;
|
unsigned AbbrevToUse = 0;
|
||||||
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
|
Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse);
|
||||||
Vals.clear();
|
Vals.clear();
|
||||||
|
@ -623,7 +623,9 @@ bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) {
|
|||||||
if (!GV->hasLinkOnceODRLinkage())
|
if (!GV->hasLinkOnceODRLinkage())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (GV->hasUnnamedAddr())
|
// We assume that anyone who sets global unnamed_addr on a non-constant knows
|
||||||
|
// what they're doing.
|
||||||
|
if (GV->hasGlobalUnnamedAddr())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If it is a non constant variable, it needs to be uniqued across shared
|
// If it is a non constant variable, it needs to be uniqued across shared
|
||||||
@ -633,21 +635,7 @@ bool llvm::canBeOmittedFromSymbolTable(const GlobalValue *GV) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// An alias can point to a variable. We could try to resolve the alias to
|
return GV->hasAtLeastLocalUnnamedAddr();
|
||||||
// decide, but for now just don't hide them.
|
|
||||||
if (isa<GlobalAlias>(GV))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// If we don't see every use, we have to be conservative and assume the value
|
|
||||||
// address is significant.
|
|
||||||
if (GV->getParent()->getMaterializer())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
GlobalStatus GS;
|
|
||||||
if (GlobalStatus::analyzeGlobal(GV, GS))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return !GS.IsCompared;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: make this a proper option
|
// FIXME: make this a proper option
|
||||||
|
@ -1001,7 +1001,7 @@ static bool isGOTEquivalentCandidate(const GlobalVariable *GV,
|
|||||||
// Global GOT equivalents are unnamed private globals with a constant
|
// Global GOT equivalents are unnamed private globals with a constant
|
||||||
// pointer initializer to another global symbol. They must point to a
|
// pointer initializer to another global symbol. They must point to a
|
||||||
// GlobalVariable or Function, i.e., as GlobalValue.
|
// GlobalVariable or Function, i.e., as GlobalValue.
|
||||||
if (!GV->hasUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() ||
|
if (!GV->hasGlobalUnnamedAddr() || !GV->hasInitializer() || !GV->isConstant() ||
|
||||||
!GV->isDiscardableIfUnused() || !dyn_cast<GlobalValue>(GV->getOperand(0)))
|
!GV->isDiscardableIfUnused() || !dyn_cast<GlobalValue>(GV->getOperand(0)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ const MCExpr *TargetLoweringObjectFileELF::lowerRelativeReference(
|
|||||||
const TargetMachine &TM) const {
|
const TargetMachine &TM) const {
|
||||||
// We may only use a PLT-relative relocation to refer to unnamed_addr
|
// We may only use a PLT-relative relocation to refer to unnamed_addr
|
||||||
// functions.
|
// functions.
|
||||||
if (!LHS->hasUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
|
if (!LHS->hasGlobalUnnamedAddr() || !LHS->getValueType()->isFunctionTy())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Basic sanity checks.
|
// Basic sanity checks.
|
||||||
|
@ -144,7 +144,7 @@ static void raiseVisibilityOnValue(GlobalValue &V, GlobalRenamer &R) {
|
|||||||
V.setLinkage(GlobalValue::ExternalLinkage);
|
V.setLinkage(GlobalValue::ExternalLinkage);
|
||||||
V.setVisibility(GlobalValue::HiddenVisibility);
|
V.setVisibility(GlobalValue::HiddenVisibility);
|
||||||
}
|
}
|
||||||
V.setUnnamedAddr(false);
|
V.setUnnamedAddr(GlobalValue::UnnamedAddr::None);
|
||||||
assert(!R.needsRenaming(V) && "Invalid global name.");
|
assert(!R.needsRenaming(V) && "Invalid global name.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2426,6 +2426,17 @@ static void PrintThreadLocalModel(GlobalVariable::ThreadLocalMode TLM,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static StringRef getUnnamedAddrEncoding(GlobalVariable::UnnamedAddr UA) {
|
||||||
|
switch (UA) {
|
||||||
|
case GlobalVariable::UnnamedAddr::None:
|
||||||
|
return "";
|
||||||
|
case GlobalVariable::UnnamedAddr::Local:
|
||||||
|
return "local_unnamed_addr";
|
||||||
|
case GlobalVariable::UnnamedAddr::Global:
|
||||||
|
return "unnamed_addr";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void maybePrintComdat(formatted_raw_ostream &Out,
|
static void maybePrintComdat(formatted_raw_ostream &Out,
|
||||||
const GlobalObject &GO) {
|
const GlobalObject &GO) {
|
||||||
const Comdat *C = GO.getComdat();
|
const Comdat *C = GO.getComdat();
|
||||||
@ -2458,8 +2469,9 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
|
|||||||
PrintVisibility(GV->getVisibility(), Out);
|
PrintVisibility(GV->getVisibility(), Out);
|
||||||
PrintDLLStorageClass(GV->getDLLStorageClass(), Out);
|
PrintDLLStorageClass(GV->getDLLStorageClass(), Out);
|
||||||
PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
|
PrintThreadLocalModel(GV->getThreadLocalMode(), Out);
|
||||||
if (GV->hasUnnamedAddr())
|
StringRef UA = getUnnamedAddrEncoding(GV->getUnnamedAddr());
|
||||||
Out << "unnamed_addr ";
|
if (!UA.empty())
|
||||||
|
Out << UA << ' ';
|
||||||
|
|
||||||
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
|
if (unsigned AddressSpace = GV->getType()->getAddressSpace())
|
||||||
Out << "addrspace(" << AddressSpace << ") ";
|
Out << "addrspace(" << AddressSpace << ") ";
|
||||||
@ -2499,8 +2511,9 @@ void AssemblyWriter::printIndirectSymbol(const GlobalIndirectSymbol *GIS) {
|
|||||||
PrintVisibility(GIS->getVisibility(), Out);
|
PrintVisibility(GIS->getVisibility(), Out);
|
||||||
PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
|
PrintDLLStorageClass(GIS->getDLLStorageClass(), Out);
|
||||||
PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
|
PrintThreadLocalModel(GIS->getThreadLocalMode(), Out);
|
||||||
if (GIS->hasUnnamedAddr())
|
StringRef UA = getUnnamedAddrEncoding(GIS->getUnnamedAddr());
|
||||||
Out << "unnamed_addr ";
|
if (!UA.empty())
|
||||||
|
Out << UA << ' ';
|
||||||
|
|
||||||
if (isa<GlobalAlias>(GIS))
|
if (isa<GlobalAlias>(GIS))
|
||||||
Out << "alias ";
|
Out << "alias ";
|
||||||
@ -2656,8 +2669,9 @@ void AssemblyWriter::printFunction(const Function *F) {
|
|||||||
Out << "..."; // Output varargs portion of signature!
|
Out << "..."; // Output varargs portion of signature!
|
||||||
}
|
}
|
||||||
Out << ')';
|
Out << ')';
|
||||||
if (F->hasUnnamedAddr())
|
StringRef UA = getUnnamedAddrEncoding(F->getUnnamedAddr());
|
||||||
Out << " unnamed_addr";
|
if (!UA.empty())
|
||||||
|
Out << ' ' << UA;
|
||||||
if (Attrs.hasAttributes(AttributeSet::FunctionIndex))
|
if (Attrs.hasAttributes(AttributeSet::FunctionIndex))
|
||||||
Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes());
|
Out << " #" << Machine.getAttributeGroupSlot(Attrs.getFnAttributes());
|
||||||
if (F->hasSection()) {
|
if (F->hasSection()) {
|
||||||
|
@ -1560,11 +1560,13 @@ void LLVMSetDLLStorageClass(LLVMValueRef Global, LLVMDLLStorageClass Class) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) {
|
LLVMBool LLVMHasUnnamedAddr(LLVMValueRef Global) {
|
||||||
return unwrap<GlobalValue>(Global)->hasUnnamedAddr();
|
return unwrap<GlobalValue>(Global)->hasGlobalUnnamedAddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr) {
|
void LLVMSetUnnamedAddr(LLVMValueRef Global, LLVMBool HasUnnamedAddr) {
|
||||||
unwrap<GlobalValue>(Global)->setUnnamedAddr(HasUnnamedAddr);
|
unwrap<GlobalValue>(Global)->setUnnamedAddr(
|
||||||
|
HasUnnamedAddr ? GlobalValue::UnnamedAddr::Global
|
||||||
|
: GlobalValue::UnnamedAddr::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--.. Operations on global variables, load and store instructions .........--*/
|
/*--.. Operations on global variables, load and store instructions .........--*/
|
||||||
|
@ -51,7 +51,7 @@ Value *GlobalValue::handleOperandChangeImpl(Value *From, Value *To) {
|
|||||||
/// create a GlobalValue) from the GlobalValue Src to this one.
|
/// create a GlobalValue) from the GlobalValue Src to this one.
|
||||||
void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
|
void GlobalValue::copyAttributesFrom(const GlobalValue *Src) {
|
||||||
setVisibility(Src->getVisibility());
|
setVisibility(Src->getVisibility());
|
||||||
setUnnamedAddr(Src->hasUnnamedAddr());
|
setUnnamedAddr(Src->getUnnamedAddr());
|
||||||
setDLLStorageClass(Src->getDLLStorageClass());
|
setDLLStorageClass(Src->getDLLStorageClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ GlobalVariable *IRBuilderBase::CreateGlobalString(StringRef Str,
|
|||||||
StrConstant, Name, nullptr,
|
StrConstant, Name, nullptr,
|
||||||
GlobalVariable::NotThreadLocal,
|
GlobalVariable::NotThreadLocal,
|
||||||
AddressSpace);
|
AddressSpace);
|
||||||
GV->setUnnamedAddr(true);
|
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1535,7 +1535,7 @@ void Verifier::verifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
|
|||||||
if (Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
if (Attrs.hasAttribute(AttributeSet::FunctionIndex,
|
||||||
Attribute::JumpTable)) {
|
Attribute::JumpTable)) {
|
||||||
const GlobalValue *GV = cast<GlobalValue>(V);
|
const GlobalValue *GV = cast<GlobalValue>(V);
|
||||||
Assert(GV->hasUnnamedAddr(),
|
Assert(GV->hasGlobalUnnamedAddr(),
|
||||||
"Attribute 'jumptable' requires 'unnamed_addr'", V);
|
"Attribute 'jumptable' requires 'unnamed_addr'", V);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,7 +791,7 @@ IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
|
|||||||
return stringErr(
|
return stringErr(
|
||||||
"Appending variables with different visibility need to be linked!");
|
"Appending variables with different visibility need to be linked!");
|
||||||
|
|
||||||
if (DstGV->hasUnnamedAddr() != SrcGV->hasUnnamedAddr())
|
if (DstGV->hasGlobalUnnamedAddr() != SrcGV->hasGlobalUnnamedAddr())
|
||||||
return stringErr(
|
return stringErr(
|
||||||
"Appending variables with different unnamed_addr need to be linked!");
|
"Appending variables with different unnamed_addr need to be linked!");
|
||||||
|
|
||||||
|
@ -377,9 +377,10 @@ bool ModuleLinker::linkIfNeeded(GlobalValue &GV) {
|
|||||||
DGV->setVisibility(Visibility);
|
DGV->setVisibility(Visibility);
|
||||||
GV.setVisibility(Visibility);
|
GV.setVisibility(Visibility);
|
||||||
|
|
||||||
bool HasUnnamedAddr = GV.hasUnnamedAddr() && DGV->hasUnnamedAddr();
|
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr(
|
||||||
DGV->setUnnamedAddr(HasUnnamedAddr);
|
DGV->getUnnamedAddr(), GV.getUnnamedAddr());
|
||||||
GV.setUnnamedAddr(HasUnnamedAddr);
|
DGV->setUnnamedAddr(UnnamedAddr);
|
||||||
|
GV.setUnnamedAddr(UnnamedAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't want to append to global_ctors list, for example, when we
|
// Don't want to append to global_ctors list, for example, when we
|
||||||
|
@ -694,7 +694,7 @@ void AMDGPUPromoteAlloca::handleAlloca(AllocaInst &I) {
|
|||||||
nullptr,
|
nullptr,
|
||||||
GlobalVariable::NotThreadLocal,
|
GlobalVariable::NotThreadLocal,
|
||||||
AMDGPUAS::LOCAL_ADDRESS);
|
AMDGPUAS::LOCAL_ADDRESS);
|
||||||
GV->setUnnamedAddr(true);
|
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
GV->setAlignment(I.getAlignment());
|
GV->setAlignment(I.getAlignment());
|
||||||
|
|
||||||
Value *TCntY, *TCntZ;
|
Value *TCntY, *TCntZ;
|
||||||
|
@ -174,7 +174,7 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalValue *GV,
|
|||||||
// If the global is required to have a unique address, it can't be put
|
// If the global is required to have a unique address, it can't be put
|
||||||
// into a mergable section: just drop it into the general read-only
|
// into a mergable section: just drop it into the general read-only
|
||||||
// section instead.
|
// section instead.
|
||||||
if (!GVar->hasUnnamedAddr())
|
if (!GVar->hasGlobalUnnamedAddr())
|
||||||
return SectionKind::getReadOnly();
|
return SectionKind::getReadOnly();
|
||||||
|
|
||||||
// If initializer is a null-terminated string, put it in a "cstring"
|
// If initializer is a null-terminated string, put it in a "cstring"
|
||||||
|
@ -57,7 +57,7 @@ static bool IsBetterCanonical(const GlobalVariable &A,
|
|||||||
if (A.hasLocalLinkage() && !B.hasLocalLinkage())
|
if (A.hasLocalLinkage() && !B.hasLocalLinkage())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return A.hasUnnamedAddr();
|
return A.hasGlobalUnnamedAddr();
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned getAlignment(GlobalVariable *GV) {
|
static unsigned getAlignment(GlobalVariable *GV) {
|
||||||
@ -152,11 +152,11 @@ static bool mergeConstants(Module &M) {
|
|||||||
if (!Slot || Slot == GV)
|
if (!Slot || Slot == GV)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!Slot->hasUnnamedAddr() && !GV->hasUnnamedAddr())
|
if (!Slot->hasGlobalUnnamedAddr() && !GV->hasGlobalUnnamedAddr())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!GV->hasUnnamedAddr())
|
if (!GV->hasGlobalUnnamedAddr())
|
||||||
Slot->setUnnamedAddr(false);
|
Slot->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
|
||||||
|
|
||||||
// Make all uses of the duplicate constant use the canonical version.
|
// Make all uses of the duplicate constant use the canonical version.
|
||||||
Replacements.push_back(std::make_pair(GV, Slot));
|
Replacements.push_back(std::make_pair(GV, Slot));
|
||||||
|
@ -1942,8 +1942,7 @@ static bool processInternalGlobal(
|
|||||||
static bool
|
static bool
|
||||||
processGlobal(GlobalValue &GV, TargetLibraryInfo *TLI,
|
processGlobal(GlobalValue &GV, TargetLibraryInfo *TLI,
|
||||||
function_ref<DominatorTree &(Function &)> LookupDomTree) {
|
function_ref<DominatorTree &(Function &)> LookupDomTree) {
|
||||||
// Do more involved optimizations if the global is internal.
|
if (GV.getName().startswith("llvm."))
|
||||||
if (!GV.hasLocalLinkage())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
GlobalStatus GS;
|
GlobalStatus GS;
|
||||||
@ -1952,12 +1951,20 @@ processGlobal(GlobalValue &GV, TargetLibraryInfo *TLI,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
if (!GS.IsCompared && !GV.hasUnnamedAddr()) {
|
if (!GS.IsCompared && !GV.hasGlobalUnnamedAddr()) {
|
||||||
GV.setUnnamedAddr(true);
|
auto NewUnnamedAddr = GV.hasLocalLinkage() ? GlobalValue::UnnamedAddr::Global
|
||||||
NumUnnamed++;
|
: GlobalValue::UnnamedAddr::Local;
|
||||||
Changed = true;
|
if (NewUnnamedAddr != GV.getUnnamedAddr()) {
|
||||||
|
GV.setUnnamedAddr(NewUnnamedAddr);
|
||||||
|
NumUnnamed++;
|
||||||
|
Changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do more involved optimizations if the global is internal.
|
||||||
|
if (!GV.hasLocalLinkage())
|
||||||
|
return Changed;
|
||||||
|
|
||||||
auto *GVar = dyn_cast<GlobalVariable>(&GV);
|
auto *GVar = dyn_cast<GlobalVariable>(&GV);
|
||||||
if (!GVar)
|
if (!GVar)
|
||||||
return Changed;
|
return Changed;
|
||||||
|
@ -1637,7 +1637,7 @@ void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) {
|
|||||||
|
|
||||||
// Replace G with an alias to F if possible, or else a thunk to F. Deletes G.
|
// Replace G with an alias to F if possible, or else a thunk to F. Deletes G.
|
||||||
void MergeFunctions::writeThunkOrAlias(Function *F, Function *G) {
|
void MergeFunctions::writeThunkOrAlias(Function *F, Function *G) {
|
||||||
if (HasGlobalAliases && G->hasUnnamedAddr()) {
|
if (HasGlobalAliases && G->hasGlobalUnnamedAddr()) {
|
||||||
if (G->hasExternalLinkage() || G->hasLocalLinkage() ||
|
if (G->hasExternalLinkage() || G->hasLocalLinkage() ||
|
||||||
G->hasWeakLinkage()) {
|
G->hasWeakLinkage()) {
|
||||||
writeAlias(F, G);
|
writeAlias(F, G);
|
||||||
|
@ -832,7 +832,7 @@ static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
|
|||||||
GlobalVariable *GV =
|
GlobalVariable *GV =
|
||||||
new GlobalVariable(M, StrConst->getType(), true,
|
new GlobalVariable(M, StrConst->getType(), true,
|
||||||
GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix);
|
GlobalValue::PrivateLinkage, StrConst, kAsanGenPrefix);
|
||||||
if (AllowMerging) GV->setUnnamedAddr(true);
|
if (AllowMerging) GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
GV->setAlignment(1); // Strings may not be merged w/o setting align 1.
|
GV->setAlignment(1); // Strings may not be merged w/o setting align 1.
|
||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
@ -849,7 +849,7 @@ static GlobalVariable *createPrivateGlobalForSourceLoc(Module &M,
|
|||||||
auto GV = new GlobalVariable(M, LocStruct->getType(), true,
|
auto GV = new GlobalVariable(M, LocStruct->getType(), true,
|
||||||
GlobalValue::PrivateLinkage, LocStruct,
|
GlobalValue::PrivateLinkage, LocStruct,
|
||||||
kAsanGenPrefix);
|
kAsanGenPrefix);
|
||||||
GV->setUnnamedAddr(true);
|
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str,
|
|||||||
new GlobalVariable(M, StrConst->getType(), true,
|
new GlobalVariable(M, StrConst->getType(), true,
|
||||||
GlobalValue::PrivateLinkage, StrConst, "");
|
GlobalValue::PrivateLinkage, StrConst, "");
|
||||||
if (AllowMerging)
|
if (AllowMerging)
|
||||||
GV->setUnnamedAddr(true);
|
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
GV->setAlignment(1); // Strings may not be merged w/o setting align 1.
|
GV->setAlignment(1); // Strings may not be merged w/o setting align 1.
|
||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
|
@ -691,7 +691,7 @@ bool GCOVProfiler::emitProfileArcs() {
|
|||||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
||||||
Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
|
Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
|
||||||
"__llvm_gcov_init", M);
|
"__llvm_gcov_init", M);
|
||||||
F->setUnnamedAddr(true);
|
F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
F->setLinkage(GlobalValue::InternalLinkage);
|
F->setLinkage(GlobalValue::InternalLinkage);
|
||||||
F->addFnAttr(Attribute::NoInline);
|
F->addFnAttr(Attribute::NoInline);
|
||||||
if (Options.NoRedZone)
|
if (Options.NoRedZone)
|
||||||
@ -766,7 +766,7 @@ GlobalVariable *GCOVProfiler::buildEdgeLookupTable(
|
|||||||
ConstantArray::get(EdgeTableTy,
|
ConstantArray::get(EdgeTableTy,
|
||||||
makeArrayRef(&EdgeTable[0],TableSize)),
|
makeArrayRef(&EdgeTable[0],TableSize)),
|
||||||
"__llvm_gcda_edge_table");
|
"__llvm_gcda_edge_table");
|
||||||
EdgeTableGV->setUnnamedAddr(true);
|
EdgeTableGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
return EdgeTableGV;
|
return EdgeTableGV;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -840,7 +840,7 @@ GlobalVariable *GCOVProfiler::getEdgeStateValue() {
|
|||||||
ConstantInt::get(Type::getInt32Ty(*Ctx),
|
ConstantInt::get(Type::getInt32Ty(*Ctx),
|
||||||
0xffffffff),
|
0xffffffff),
|
||||||
"__llvm_gcov_global_state_pred");
|
"__llvm_gcov_global_state_pred");
|
||||||
GV->setUnnamedAddr(true);
|
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
}
|
}
|
||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
@ -852,7 +852,7 @@ Function *GCOVProfiler::insertCounterWriteout(
|
|||||||
if (!WriteoutF)
|
if (!WriteoutF)
|
||||||
WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
|
WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
|
||||||
"__llvm_gcov_writeout", M);
|
"__llvm_gcov_writeout", M);
|
||||||
WriteoutF->setUnnamedAddr(true);
|
WriteoutF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
WriteoutF->addFnAttr(Attribute::NoInline);
|
WriteoutF->addFnAttr(Attribute::NoInline);
|
||||||
if (Options.NoRedZone)
|
if (Options.NoRedZone)
|
||||||
WriteoutF->addFnAttr(Attribute::NoRedZone);
|
WriteoutF->addFnAttr(Attribute::NoRedZone);
|
||||||
@ -912,7 +912,7 @@ Function *GCOVProfiler::insertCounterWriteout(
|
|||||||
void GCOVProfiler::insertIndirectCounterIncrement() {
|
void GCOVProfiler::insertIndirectCounterIncrement() {
|
||||||
Function *Fn =
|
Function *Fn =
|
||||||
cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
|
cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
|
||||||
Fn->setUnnamedAddr(true);
|
Fn->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
Fn->setLinkage(GlobalValue::InternalLinkage);
|
Fn->setLinkage(GlobalValue::InternalLinkage);
|
||||||
Fn->addFnAttr(Attribute::NoInline);
|
Fn->addFnAttr(Attribute::NoInline);
|
||||||
if (Options.NoRedZone)
|
if (Options.NoRedZone)
|
||||||
@ -969,7 +969,7 @@ insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
|
|||||||
"__llvm_gcov_flush", M);
|
"__llvm_gcov_flush", M);
|
||||||
else
|
else
|
||||||
FlushF->setLinkage(GlobalValue::InternalLinkage);
|
FlushF->setLinkage(GlobalValue::InternalLinkage);
|
||||||
FlushF->setUnnamedAddr(true);
|
FlushF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
FlushF->addFnAttr(Attribute::NoInline);
|
FlushF->addFnAttr(Attribute::NoInline);
|
||||||
if (Options.NoRedZone)
|
if (Options.NoRedZone)
|
||||||
FlushF->addFnAttr(Attribute::NoRedZone);
|
FlushF->addFnAttr(Attribute::NoRedZone);
|
||||||
|
@ -506,7 +506,7 @@ void InstrProfiling::emitRegistration() {
|
|||||||
auto *RegisterFTy = FunctionType::get(VoidTy, false);
|
auto *RegisterFTy = FunctionType::get(VoidTy, false);
|
||||||
auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage,
|
auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage,
|
||||||
getInstrProfRegFuncsName(), M);
|
getInstrProfRegFuncsName(), M);
|
||||||
RegisterF->setUnnamedAddr(true);
|
RegisterF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
if (Options.NoRedZone) RegisterF->addFnAttr(Attribute::NoRedZone);
|
if (Options.NoRedZone) RegisterF->addFnAttr(Attribute::NoRedZone);
|
||||||
|
|
||||||
auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false);
|
auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false);
|
||||||
@ -606,7 +606,7 @@ void InstrProfiling::emitInitialization() {
|
|||||||
auto *F = Function::Create(FunctionType::get(VoidTy, false),
|
auto *F = Function::Create(FunctionType::get(VoidTy, false),
|
||||||
GlobalValue::InternalLinkage,
|
GlobalValue::InternalLinkage,
|
||||||
getInstrProfInitFuncName(), M);
|
getInstrProfInitFuncName(), M);
|
||||||
F->setUnnamedAddr(true);
|
F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
F->addFnAttr(Attribute::NoInline);
|
F->addFnAttr(Attribute::NoInline);
|
||||||
if (Options.NoRedZone) F->addFnAttr(Attribute::NoRedZone);
|
if (Options.NoRedZone) F->addFnAttr(Attribute::NoRedZone);
|
||||||
|
|
||||||
|
@ -777,7 +777,7 @@ bool LoopIdiomRecognize::processLoopStridedStore(
|
|||||||
GlobalVariable *GV = new GlobalVariable(*M, PatternValue->getType(), true,
|
GlobalVariable *GV = new GlobalVariable(*M, PatternValue->getType(), true,
|
||||||
GlobalValue::PrivateLinkage,
|
GlobalValue::PrivateLinkage,
|
||||||
PatternValue, ".memset_pattern");
|
PatternValue, ".memset_pattern");
|
||||||
GV->setUnnamedAddr(true); // Ok to merge these.
|
GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); // Ok to merge these.
|
||||||
GV->setAlignment(16);
|
GV->setAlignment(16);
|
||||||
Value *PatternPtr = ConstantExpr::getBitCast(GV, Int8PtrTy);
|
Value *PatternPtr = ConstantExpr::getBitCast(GV, Int8PtrTy);
|
||||||
NewCall = Builder.CreateCall(MSP, {BasePtr, PatternPtr, NumBytes});
|
NewCall = Builder.CreateCall(MSP, {BasePtr, PatternPtr, NumBytes});
|
||||||
|
@ -64,7 +64,7 @@ bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal(
|
|||||||
// of the module and recorded in the summary index for use when importing
|
// of the module and recorded in the summary index for use when importing
|
||||||
// from that module.
|
// from that module.
|
||||||
auto *GVar = dyn_cast<GlobalVariable>(SGV);
|
auto *GVar = dyn_cast<GlobalVariable>(SGV);
|
||||||
if (GVar && GVar->isConstant() && GVar->hasUnnamedAddr())
|
if (GVar && GVar->isConstant() && GVar->hasGlobalUnnamedAddr())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (GVar && GVar->hasSection())
|
if (GVar && GVar->hasSection())
|
||||||
|
@ -105,7 +105,7 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StoredVal == GV->getInitializer()) {
|
if (GV->hasInitializer() && StoredVal == GV->getInitializer()) {
|
||||||
if (GS.StoredType < GlobalStatus::InitializerStored)
|
if (GS.StoredType < GlobalStatus::InitializerStored)
|
||||||
GS.StoredType = GlobalStatus::InitializerStored;
|
GS.StoredType = GlobalStatus::InitializerStored;
|
||||||
} else if (isa<LoadInst>(StoredVal) &&
|
} else if (isa<LoadInst>(StoredVal) &&
|
||||||
|
@ -4540,7 +4540,7 @@ SwitchLookupTable::SwitchLookupTable(
|
|||||||
Array = new GlobalVariable(M, ArrayTy, /*constant=*/true,
|
Array = new GlobalVariable(M, ArrayTy, /*constant=*/true,
|
||||||
GlobalVariable::PrivateLinkage, Initializer,
|
GlobalVariable::PrivateLinkage, Initializer,
|
||||||
"switch.table");
|
"switch.table");
|
||||||
Array->setUnnamedAddr(true);
|
Array->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
|
||||||
Kind = ArrayKind;
|
Kind = ArrayKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
test/Assembler/local-unnamed-addr.ll
Normal file
13
test/Assembler/local-unnamed-addr.ll
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
||||||
|
; RUN: verify-uselistorder %s
|
||||||
|
|
||||||
|
; CHECK: @c = local_unnamed_addr constant i32 0
|
||||||
|
@c = local_unnamed_addr constant i32 0
|
||||||
|
|
||||||
|
; CHECK: @a = local_unnamed_addr alias i32, i32* @c
|
||||||
|
@a = local_unnamed_addr alias i32, i32* @c
|
||||||
|
|
||||||
|
; CHECK: define void @f() local_unnamed_addr {
|
||||||
|
define void @f() local_unnamed_addr {
|
||||||
|
ret void
|
||||||
|
}
|
@ -80,7 +80,7 @@ $comdat.samesize = comdat samesize
|
|||||||
|
|
||||||
;; Global Variables
|
;; Global Variables
|
||||||
; Format: [@<GlobalVarName> =] [Linkage] [Visibility] [DLLStorageClass]
|
; Format: [@<GlobalVarName> =] [Linkage] [Visibility] [DLLStorageClass]
|
||||||
; [ThreadLocal] [unnamed_addr] [AddrSpace] [ExternallyInitialized]
|
; [ThreadLocal] [(unnamed_addr|local_unnamed_addr)] [AddrSpace] [ExternallyInitialized]
|
||||||
; <global | constant> <Type> [<InitializerConstant>]
|
; <global | constant> <Type> [<InitializerConstant>]
|
||||||
; [, section "name"] [, comdat [($name)]] [, align <Alignment>]
|
; [, section "name"] [, comdat [($name)]] [, align <Alignment>]
|
||||||
|
|
||||||
@ -142,9 +142,11 @@ $comdat.samesize = comdat samesize
|
|||||||
@g.localexec = thread_local(localexec) global i32 0
|
@g.localexec = thread_local(localexec) global i32 0
|
||||||
; CHECK: @g.localexec = thread_local(localexec) global i32 0
|
; CHECK: @g.localexec = thread_local(localexec) global i32 0
|
||||||
|
|
||||||
; Global Variables -- unnamed_addr
|
; Global Variables -- unnamed_addr and local_unnamed_addr
|
||||||
@g.unnamed_addr = unnamed_addr global i32 0
|
@g.unnamed_addr = unnamed_addr global i32 0
|
||||||
; CHECK: @g.unnamed_addr = unnamed_addr global i32 0
|
; CHECK: @g.unnamed_addr = unnamed_addr global i32 0
|
||||||
|
@g.local_unnamed_addr = local_unnamed_addr global i32 0
|
||||||
|
; CHECK: @g.local_unnamed_addr = local_unnamed_addr global i32 0
|
||||||
|
|
||||||
; Global Variables -- AddrSpace
|
; Global Variables -- AddrSpace
|
||||||
@g.addrspace = addrspace(1) global i32 0
|
@g.addrspace = addrspace(1) global i32 0
|
||||||
@ -245,9 +247,11 @@ declare void @g.f1()
|
|||||||
@a.localexec = thread_local(localexec) alias i32, i32* @g.localexec
|
@a.localexec = thread_local(localexec) alias i32, i32* @g.localexec
|
||||||
; CHECK: @a.localexec = thread_local(localexec) alias i32, i32* @g.localexec
|
; CHECK: @a.localexec = thread_local(localexec) alias i32, i32* @g.localexec
|
||||||
|
|
||||||
; Aliases -- unnamed_addr
|
; Aliases -- unnamed_addr and local_unnamed_addr
|
||||||
@a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
|
@a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
|
||||||
; CHECK: @a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
|
; CHECK: @a.unnamed_addr = unnamed_addr alias i32, i32* @g.unnamed_addr
|
||||||
|
@a.local_unnamed_addr = local_unnamed_addr alias i32, i32* @g.local_unnamed_addr
|
||||||
|
; CHECK: @a.local_unnamed_addr = local_unnamed_addr alias i32, i32* @g.local_unnamed_addr
|
||||||
|
|
||||||
;; IFunc
|
;; IFunc
|
||||||
; Format @<Name> = [Linkage] [Visibility] ifunc <IFuncTy>,
|
; Format @<Name> = [Linkage] [Visibility] ifunc <IFuncTy>,
|
||||||
@ -278,7 +282,7 @@ entry:
|
|||||||
; Format: define [linkage] [visibility] [DLLStorageClass]
|
; Format: define [linkage] [visibility] [DLLStorageClass]
|
||||||
; [cconv] [ret attrs]
|
; [cconv] [ret attrs]
|
||||||
; <ResultType> @<FunctionName> ([argument list])
|
; <ResultType> @<FunctionName> ([argument list])
|
||||||
; [unnamed_addr] [fn Attrs] [section "name"] [comdat [($name)]]
|
; [(unnamed_addr|local_unnamed_addr)] [fn Attrs] [section "name"] [comdat [($name)]]
|
||||||
; [align N] [gc] [prefix Constant] [prologue Constant]
|
; [align N] [gc] [prefix Constant] [prologue Constant]
|
||||||
; [personality Constant] { ... }
|
; [personality Constant] { ... }
|
||||||
|
|
||||||
@ -523,9 +527,11 @@ declare void @f.param.dereferenceable(i8* dereferenceable(4))
|
|||||||
declare void @f.param.dereferenceable_or_null(i8* dereferenceable_or_null(4))
|
declare void @f.param.dereferenceable_or_null(i8* dereferenceable_or_null(4))
|
||||||
; CHECK: declare void @f.param.dereferenceable_or_null(i8* dereferenceable_or_null(4))
|
; CHECK: declare void @f.param.dereferenceable_or_null(i8* dereferenceable_or_null(4))
|
||||||
|
|
||||||
; Functions -- unnamed_addr
|
; Functions -- unnamed_addr and local_unnamed_addr
|
||||||
declare void @f.unnamed_addr() unnamed_addr
|
declare void @f.unnamed_addr() unnamed_addr
|
||||||
; CHECK: declare void @f.unnamed_addr() unnamed_addr
|
; CHECK: declare void @f.unnamed_addr() unnamed_addr
|
||||||
|
declare void @f.local_unnamed_addr() local_unnamed_addr
|
||||||
|
; CHECK: declare void @f.local_unnamed_addr() local_unnamed_addr
|
||||||
|
|
||||||
; Functions -- fn Attrs (Function attributes)
|
; Functions -- fn Attrs (Function attributes)
|
||||||
declare void @f.alignstack4() alignstack(4)
|
declare void @f.alignstack4() alignstack(4)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
; RUN: llc -mtriple=powerpc-apple-darwin9 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
|
; RUN: llc -mtriple=powerpc-apple-darwin9 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
|
||||||
; RUN: llc -mtriple=powerpc-apple-darwin8 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
|
; RUN: llc -mtriple=powerpc-apple-darwin8 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
|
||||||
|
|
||||||
@v1 = linkonce_odr constant i32 32
|
@v1 = linkonce_odr local_unnamed_addr constant i32 32
|
||||||
; CHECK: .globl _v1
|
; CHECK: .globl _v1
|
||||||
; CHECK: .weak_def_can_be_hidden _v1
|
; CHECK: .weak_def_can_be_hidden _v1
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ define i32* @f2() {
|
|||||||
ret i32* @v2
|
ret i32* @v2
|
||||||
}
|
}
|
||||||
|
|
||||||
@v3 = linkonce_odr unnamed_addr global i32 32
|
@v3 = linkonce_odr unnamed_addr constant i32 32
|
||||||
; CHECK: .globl _v3
|
; CHECK: .globl _v3
|
||||||
; CHECK: .weak_def_can_be_hidden _v3
|
; CHECK: .weak_def_can_be_hidden _v3
|
||||||
|
|
||||||
@ -37,9 +37,9 @@ define i32* @f3() {
|
|||||||
ret i32* @v3
|
ret i32* @v3
|
||||||
}
|
}
|
||||||
|
|
||||||
@v4 = linkonce_odr global i32 32
|
@v4 = linkonce_odr unnamed_addr global i32 32
|
||||||
; CHECK: .globl _v4
|
; CHECK: .globl _v4
|
||||||
; CHECK: .weak_definition _v4
|
; CHECK: .weak_def_can_be_hidden _v4
|
||||||
|
|
||||||
; CHECK-D89: .globl _v4
|
; CHECK-D89: .globl _v4
|
||||||
; CHECK-D89: .weak_definition _v4
|
; CHECK-D89: .weak_definition _v4
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
; RUN: llc -mtriple=i686-apple-darwin9 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
|
; RUN: llc -mtriple=i686-apple-darwin9 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
|
||||||
; RUN: llc -mtriple=i686-apple-darwin8 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
|
; RUN: llc -mtriple=i686-apple-darwin8 -O0 < %s | FileCheck --check-prefix=CHECK-D89 %s
|
||||||
|
|
||||||
@v1 = linkonce_odr constant i32 32
|
@v1 = linkonce_odr local_unnamed_addr constant i32 32
|
||||||
; CHECK: .globl _v1
|
; CHECK: .globl _v1
|
||||||
; CHECK: .weak_def_can_be_hidden _v1
|
; CHECK: .weak_def_can_be_hidden _v1
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ define i32* @f2() {
|
|||||||
ret i32* @v2
|
ret i32* @v2
|
||||||
}
|
}
|
||||||
|
|
||||||
@v3 = linkonce_odr unnamed_addr global i32 32
|
@v3 = linkonce_odr unnamed_addr constant i32 32
|
||||||
; CHECK: .globl _v3
|
; CHECK: .globl _v3
|
||||||
; CHECK: .weak_def_can_be_hidden _v3
|
; CHECK: .weak_def_can_be_hidden _v3
|
||||||
|
|
||||||
@ -38,9 +38,9 @@ define i32* @f3() {
|
|||||||
ret i32* @v3
|
ret i32* @v3
|
||||||
}
|
}
|
||||||
|
|
||||||
@v4 = linkonce_odr global i32 32
|
@v4 = linkonce_odr unnamed_addr global i32 32
|
||||||
; CHECK: .globl _v4
|
; CHECK: .globl _v4
|
||||||
; CHECK: .weak_definition _v4
|
; CHECK: .weak_def_can_be_hidden _v4
|
||||||
|
|
||||||
; CHECK-D89: .globl _v4
|
; CHECK-D89: .globl _v4
|
||||||
; CHECK-D89: .weak_definition _v4
|
; CHECK-D89: .weak_definition _v4
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
declare void @foo() readnone
|
declare void @foo() readnone
|
||||||
|
|
||||||
; CHECK-LABEL: define i8* @test(i8* %p) {
|
; CHECK-LABEL: define i8* @test(i8* %p)
|
||||||
; CHECK: %a = alloca i8*, align 8
|
; CHECK: %a = alloca i8*, align 8
|
||||||
; CHECK: store i8* %p, i8** %a, align 8
|
; CHECK: store i8* %p, i8** %a, align 8
|
||||||
; CHECK: call void @foo() [ "abc"(i8** %a) ]
|
; CHECK: call void @foo() [ "abc"(i8** %a) ]
|
||||||
|
@ -33,8 +33,8 @@ define i32* @get_zed1() {
|
|||||||
ret i32* @zed1
|
ret i32* @zed1
|
||||||
}
|
}
|
||||||
|
|
||||||
; ZED1_AND_ZED2: d zed2
|
; ZED1_AND_ZED2: r zed2
|
||||||
@zed2 = linkonce_odr unnamed_addr global i32 42
|
@zed2 = linkonce_odr unnamed_addr constant i32 42
|
||||||
|
|
||||||
define i32 @useZed2() {
|
define i32 @useZed2() {
|
||||||
%x = load i32, i32* @zed2
|
%x = load i32, i32* @zed2
|
||||||
|
@ -1,61 +1,54 @@
|
|||||||
; RUN: llvm-as < %s >%t1
|
; RUN: llvm-as < %s >%t1
|
||||||
; RUN: llvm-lto -o %t2 -dso-symbol=foo1 -dso-symbol=foo2 -dso-symbol=foo3 \
|
; RUN: llvm-lto -o %t2 -dso-symbol=foo1 -dso-symbol=foo2 -dso-symbol=foo3 \
|
||||||
; RUN: -dso-symbol=foo4 -dso-symbol=v1 -dso-symbol=v2 %t1 -O0
|
; RUN: -dso-symbol=v1 -dso-symbol=v2 -dso-symbol=v3 \
|
||||||
|
; RUN: -dso-symbol=v4 -dso-symbol=v5 -dso-symbol=v6 %t1 -O0
|
||||||
; RUN: llvm-nm %t2 | FileCheck %s
|
; RUN: llvm-nm %t2 | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
; CHECK: t foo1
|
; CHECK: W foo1
|
||||||
define linkonce_odr void @foo1() noinline {
|
define linkonce_odr void @foo1() noinline {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: W foo2
|
; CHECK: t foo2
|
||||||
define linkonce_odr void @foo2() noinline {
|
define linkonce_odr void @foo2() local_unnamed_addr noinline {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: t foo3
|
; CHECK: t foo3
|
||||||
define linkonce_odr void @foo3() noinline {
|
define linkonce_odr void @foo3() unnamed_addr noinline {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: W foo4
|
; CHECK: V v1
|
||||||
define linkonce_odr void @foo4() noinline {
|
|
||||||
ret void
|
|
||||||
}
|
|
||||||
|
|
||||||
; CHECK: r v1
|
|
||||||
@v1 = linkonce_odr constant i32 32
|
@v1 = linkonce_odr constant i32 32
|
||||||
|
|
||||||
define i32 @useV1() {
|
; CHECK: r v2
|
||||||
%x = load i32, i32* @v1
|
@v2 = linkonce_odr local_unnamed_addr constant i32 32
|
||||||
ret i32 %x
|
|
||||||
}
|
|
||||||
|
|
||||||
; CHECK: V v2
|
; CHECK: r v3
|
||||||
@v2 = linkonce_odr global i32 32
|
@v3 = linkonce_odr unnamed_addr constant i32 32
|
||||||
|
|
||||||
define i32 @useV2() {
|
; CHECK: V v4
|
||||||
%x = load i32, i32* @v2
|
@v4 = linkonce_odr global i32 32
|
||||||
ret i32 %x
|
|
||||||
}
|
|
||||||
|
|
||||||
declare void @f(void()*)
|
; CHECK: V v5
|
||||||
|
@v5 = linkonce_odr local_unnamed_addr global i32 32
|
||||||
|
|
||||||
declare void @p()
|
; CHECK: d v6
|
||||||
|
@v6 = linkonce_odr unnamed_addr global i32 32
|
||||||
|
|
||||||
define void @bar() personality void()* @p {
|
define void @use() {
|
||||||
bb0:
|
|
||||||
call void @foo1()
|
call void @foo1()
|
||||||
call void @f(void()* @foo2)
|
call void @foo2()
|
||||||
invoke void @foo3() to label %bb1 unwind label %clean
|
call void @foo3()
|
||||||
bb1:
|
%x1 = load i32, i32* @v1
|
||||||
invoke void @f(void()* @foo4) to label %bb2 unwind label %clean
|
%x2 = load i32, i32* @v2
|
||||||
bb2:
|
%x3 = load i32, i32* @v3
|
||||||
ret void
|
%x4 = load i32, i32* @v4
|
||||||
clean:
|
%x5 = load i32, i32* @v5
|
||||||
landingpad {i32, i32} cleanup
|
%x6 = load i32, i32* @v6
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -24,18 +24,18 @@
|
|||||||
; PLAIN: @F1 = global i1* getelementptr (i1, i1* inttoptr (i32 1 to i1*), i32 -2)
|
; PLAIN: @F1 = global i1* getelementptr (i1, i1* inttoptr (i32 1 to i1*), i32 -2)
|
||||||
; PLAIN: @H8 = global i8* getelementptr (i8, i8* null, i32 -1)
|
; PLAIN: @H8 = global i8* getelementptr (i8, i8* null, i32 -1)
|
||||||
; PLAIN: @H1 = global i1* getelementptr (i1, i1* null, i32 -1)
|
; PLAIN: @H1 = global i1* getelementptr (i1, i1* null, i32 -1)
|
||||||
; OPT: @G8 = global i8* null
|
; OPT: @G8 = local_unnamed_addr global i8* null
|
||||||
; OPT: @G1 = global i1* null
|
; OPT: @G1 = local_unnamed_addr global i1* null
|
||||||
; OPT: @F8 = global i8* inttoptr (i64 -1 to i8*)
|
; OPT: @F8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
|
||||||
; OPT: @F1 = global i1* inttoptr (i64 -1 to i1*)
|
; OPT: @F1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
|
||||||
; OPT: @H8 = global i8* inttoptr (i64 -1 to i8*)
|
; OPT: @H8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
|
||||||
; OPT: @H1 = global i1* inttoptr (i64 -1 to i1*)
|
; OPT: @H1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
|
||||||
; TO: @G8 = global i8* null
|
; TO: @G8 = local_unnamed_addr global i8* null
|
||||||
; TO: @G1 = global i1* null
|
; TO: @G1 = local_unnamed_addr global i1* null
|
||||||
; TO: @F8 = global i8* inttoptr (i64 -1 to i8*)
|
; TO: @F8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
|
||||||
; TO: @F1 = global i1* inttoptr (i64 -1 to i1*)
|
; TO: @F1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
|
||||||
; TO: @H8 = global i8* inttoptr (i64 -1 to i8*)
|
; TO: @H8 = local_unnamed_addr global i8* inttoptr (i64 -1 to i8*)
|
||||||
; TO: @H1 = global i1* inttoptr (i64 -1 to i1*)
|
; TO: @H1 = local_unnamed_addr global i1* inttoptr (i64 -1 to i1*)
|
||||||
|
|
||||||
@G8 = global i8* getelementptr (i8, i8* inttoptr (i32 1 to i8*), i32 -1)
|
@G8 = global i8* getelementptr (i8, i8* inttoptr (i32 1 to i8*), i32 -1)
|
||||||
@G1 = global i1* getelementptr (i1, i1* inttoptr (i32 1 to i1*), i32 -1)
|
@G1 = global i1* getelementptr (i1, i1* inttoptr (i32 1 to i1*), i32 -1)
|
||||||
@ -57,24 +57,24 @@
|
|||||||
; PLAIN: @g = constant i64 ptrtoint (double* getelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i64)
|
; PLAIN: @g = constant i64 ptrtoint (double* getelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i64)
|
||||||
; PLAIN: @h = constant i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)
|
; PLAIN: @h = constant i64 ptrtoint (i1** getelementptr (i1*, i1** null, i32 1) to i64)
|
||||||
; PLAIN: @i = constant i64 ptrtoint (i1** getelementptr ({ i1, i1* }, { i1, i1* }* null, i64 0, i32 1) to i64)
|
; PLAIN: @i = constant i64 ptrtoint (i1** getelementptr ({ i1, i1* }, { i1, i1* }* null, i64 0, i32 1) to i64)
|
||||||
; OPT: @a = constant i64 18480
|
; OPT: @a = local_unnamed_addr constant i64 18480
|
||||||
; OPT: @b = constant i64 8
|
; OPT: @b = local_unnamed_addr constant i64 8
|
||||||
; OPT: @c = constant i64 16
|
; OPT: @c = local_unnamed_addr constant i64 16
|
||||||
; OPT: @d = constant i64 88
|
; OPT: @d = local_unnamed_addr constant i64 88
|
||||||
; OPT: @e = constant i64 16
|
; OPT: @e = local_unnamed_addr constant i64 16
|
||||||
; OPT: @f = constant i64 1
|
; OPT: @f = local_unnamed_addr constant i64 1
|
||||||
; OPT: @g = constant i64 8
|
; OPT: @g = local_unnamed_addr constant i64 8
|
||||||
; OPT: @h = constant i64 8
|
; OPT: @h = local_unnamed_addr constant i64 8
|
||||||
; OPT: @i = constant i64 8
|
; OPT: @i = local_unnamed_addr constant i64 8
|
||||||
; TO: @a = constant i64 18480
|
; TO: @a = local_unnamed_addr constant i64 18480
|
||||||
; TO: @b = constant i64 8
|
; TO: @b = local_unnamed_addr constant i64 8
|
||||||
; TO: @c = constant i64 16
|
; TO: @c = local_unnamed_addr constant i64 16
|
||||||
; TO: @d = constant i64 88
|
; TO: @d = local_unnamed_addr constant i64 88
|
||||||
; TO: @e = constant i64 16
|
; TO: @e = local_unnamed_addr constant i64 16
|
||||||
; TO: @f = constant i64 1
|
; TO: @f = local_unnamed_addr constant i64 1
|
||||||
; TO: @g = constant i64 8
|
; TO: @g = local_unnamed_addr constant i64 8
|
||||||
; TO: @h = constant i64 8
|
; TO: @h = local_unnamed_addr constant i64 8
|
||||||
; TO: @i = constant i64 8
|
; TO: @i = local_unnamed_addr constant i64 8
|
||||||
|
|
||||||
@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}, {[7 x double], [7 x double]}* null, i64 11) to i64), i64 5))
|
@a = constant i64 mul (i64 3, i64 mul (i64 ptrtoint ({[7 x double], [7 x double]}* getelementptr ({[7 x double], [7 x double]}, {[7 x double], [7 x double]}* null, i64 11) to i64), i64 5))
|
||||||
@b = constant i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}, {i1, [13 x double]}* null, i64 0, i32 1) to i64)
|
@b = constant i64 ptrtoint ([13 x double]* getelementptr ({i1, [13 x double]}, {i1, [13 x double]}* null, i64 0, i32 1) to i64)
|
||||||
@ -91,12 +91,12 @@
|
|||||||
; PLAIN: @M = constant i64* getelementptr (i64, i64* null, i32 1)
|
; PLAIN: @M = constant i64* getelementptr (i64, i64* null, i32 1)
|
||||||
; PLAIN: @N = constant i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1)
|
; PLAIN: @N = constant i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1)
|
||||||
; PLAIN: @O = constant i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1)
|
; PLAIN: @O = constant i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1)
|
||||||
; OPT: @M = constant i64* inttoptr (i64 8 to i64*)
|
; OPT: @M = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
|
||||||
; OPT: @N = constant i64* inttoptr (i64 8 to i64*)
|
; OPT: @N = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
|
||||||
; OPT: @O = constant i64* inttoptr (i64 8 to i64*)
|
; OPT: @O = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
|
||||||
; TO: @M = constant i64* inttoptr (i64 8 to i64*)
|
; TO: @M = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
|
||||||
; TO: @N = constant i64* inttoptr (i64 8 to i64*)
|
; TO: @N = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
|
||||||
; TO: @O = constant i64* inttoptr (i64 8 to i64*)
|
; TO: @O = local_unnamed_addr constant i64* inttoptr (i64 8 to i64*)
|
||||||
|
|
||||||
@M = constant i64* getelementptr (i64, i64* null, i32 1)
|
@M = constant i64* getelementptr (i64, i64* null, i32 1)
|
||||||
@N = constant i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1)
|
@N = constant i64* getelementptr ({ i64, i64 }, { i64, i64 }* null, i32 0, i32 1)
|
||||||
@ -106,10 +106,10 @@
|
|||||||
|
|
||||||
; PLAIN: @Y = global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
|
; PLAIN: @Y = global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
|
||||||
; PLAIN: @Z = global i32* getelementptr inbounds (i32, i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1)
|
; PLAIN: @Z = global i32* getelementptr inbounds (i32, i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1)
|
||||||
; OPT: @Y = global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
|
; OPT: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
|
||||||
; OPT: @Z = global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
|
; OPT: @Z = local_unnamed_addr global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
|
||||||
; TO: @Y = global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
|
; TO: @Y = local_unnamed_addr global [3 x { i32, i32 }]* getelementptr ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 2)
|
||||||
; TO: @Z = global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
|
; TO: @Z = local_unnamed_addr global i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
|
||||||
|
|
||||||
@ext = external global [3 x { i32, i32 }]
|
@ext = external global [3 x { i32, i32 }]
|
||||||
@Y = global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 1), i64 1)
|
@Y = global [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 1), i64 1)
|
||||||
@ -142,40 +142,40 @@
|
|||||||
; PLAIN: %t = bitcast i1* getelementptr (i1, i1* null, i32 -1) to i1*
|
; PLAIN: %t = bitcast i1* getelementptr (i1, i1* null, i32 -1) to i1*
|
||||||
; PLAIN: ret i1* %t
|
; PLAIN: ret i1* %t
|
||||||
; PLAIN: }
|
; PLAIN: }
|
||||||
; OPT: define i8* @goo8() #0 {
|
; OPT: define i8* @goo8() local_unnamed_addr #0 {
|
||||||
; OPT: ret i8* null
|
; OPT: ret i8* null
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i1* @goo1() #0 {
|
; OPT: define i1* @goo1() local_unnamed_addr #0 {
|
||||||
; OPT: ret i1* null
|
; OPT: ret i1* null
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i8* @foo8() #0 {
|
; OPT: define i8* @foo8() local_unnamed_addr #0 {
|
||||||
; OPT: ret i8* inttoptr (i64 -1 to i8*)
|
; OPT: ret i8* inttoptr (i64 -1 to i8*)
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i1* @foo1() #0 {
|
; OPT: define i1* @foo1() local_unnamed_addr #0 {
|
||||||
; OPT: ret i1* inttoptr (i64 -1 to i1*)
|
; OPT: ret i1* inttoptr (i64 -1 to i1*)
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i8* @hoo8() #0 {
|
; OPT: define i8* @hoo8() local_unnamed_addr #0 {
|
||||||
; OPT: ret i8* inttoptr (i64 -1 to i8*)
|
; OPT: ret i8* inttoptr (i64 -1 to i8*)
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i1* @hoo1() #0 {
|
; OPT: define i1* @hoo1() local_unnamed_addr #0 {
|
||||||
; OPT: ret i1* inttoptr (i64 -1 to i1*)
|
; OPT: ret i1* inttoptr (i64 -1 to i1*)
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; TO: define i8* @goo8() #0 {
|
; TO: define i8* @goo8() local_unnamed_addr #0 {
|
||||||
; TO: ret i8* null
|
; TO: ret i8* null
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i1* @goo1() #0 {
|
; TO: define i1* @goo1() local_unnamed_addr #0 {
|
||||||
; TO: ret i1* null
|
; TO: ret i1* null
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i8* @foo8() #0 {
|
; TO: define i8* @foo8() local_unnamed_addr #0 {
|
||||||
; TO: ret i8* inttoptr (i64 -1 to i8*)
|
; TO: ret i8* inttoptr (i64 -1 to i8*)
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i1* @foo1() #0 {
|
; TO: define i1* @foo1() local_unnamed_addr #0 {
|
||||||
; TO: ret i1* inttoptr (i64 -1 to i1*)
|
; TO: ret i1* inttoptr (i64 -1 to i1*)
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i8* @hoo8() #0 {
|
; TO: define i8* @hoo8() local_unnamed_addr #0 {
|
||||||
; TO: ret i8* inttoptr (i64 -1 to i8*)
|
; TO: ret i8* inttoptr (i64 -1 to i8*)
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i1* @hoo1() #0 {
|
; TO: define i1* @hoo1() local_unnamed_addr #0 {
|
||||||
; TO: ret i1* inttoptr (i64 -1 to i1*)
|
; TO: ret i1* inttoptr (i64 -1 to i1*)
|
||||||
; TO: }
|
; TO: }
|
||||||
; SCEV: Classifying expressions for: @goo8
|
; SCEV: Classifying expressions for: @goo8
|
||||||
@ -256,58 +256,58 @@ define i1* @hoo1() nounwind {
|
|||||||
; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr ({ i1, i1* }, { i1, i1* }* null, i64 0, i32 1) to i64) to i64
|
; PLAIN: %t = bitcast i64 ptrtoint (i1** getelementptr ({ i1, i1* }, { i1, i1* }* null, i64 0, i32 1) to i64) to i64
|
||||||
; PLAIN: ret i64 %t
|
; PLAIN: ret i64 %t
|
||||||
; PLAIN: }
|
; PLAIN: }
|
||||||
; OPT: define i64 @fa() #0 {
|
; OPT: define i64 @fa() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64 18480
|
; OPT: ret i64 18480
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64 @fb() #0 {
|
; OPT: define i64 @fb() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64 8
|
; OPT: ret i64 8
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64 @fc() #0 {
|
; OPT: define i64 @fc() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64 16
|
; OPT: ret i64 16
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64 @fd() #0 {
|
; OPT: define i64 @fd() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64 88
|
; OPT: ret i64 88
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64 @fe() #0 {
|
; OPT: define i64 @fe() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64 16
|
; OPT: ret i64 16
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64 @ff() #0 {
|
; OPT: define i64 @ff() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64 1
|
; OPT: ret i64 1
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64 @fg() #0 {
|
; OPT: define i64 @fg() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64 8
|
; OPT: ret i64 8
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64 @fh() #0 {
|
; OPT: define i64 @fh() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64 8
|
; OPT: ret i64 8
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64 @fi() #0 {
|
; OPT: define i64 @fi() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64 8
|
; OPT: ret i64 8
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; TO: define i64 @fa() #0 {
|
; TO: define i64 @fa() local_unnamed_addr #0 {
|
||||||
; TO: ret i64 18480
|
; TO: ret i64 18480
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64 @fb() #0 {
|
; TO: define i64 @fb() local_unnamed_addr #0 {
|
||||||
; TO: ret i64 8
|
; TO: ret i64 8
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64 @fc() #0 {
|
; TO: define i64 @fc() local_unnamed_addr #0 {
|
||||||
; TO: ret i64 16
|
; TO: ret i64 16
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64 @fd() #0 {
|
; TO: define i64 @fd() local_unnamed_addr #0 {
|
||||||
; TO: ret i64 88
|
; TO: ret i64 88
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64 @fe() #0 {
|
; TO: define i64 @fe() local_unnamed_addr #0 {
|
||||||
; TO: ret i64 16
|
; TO: ret i64 16
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64 @ff() #0 {
|
; TO: define i64 @ff() local_unnamed_addr #0 {
|
||||||
; TO: ret i64 1
|
; TO: ret i64 1
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64 @fg() #0 {
|
; TO: define i64 @fg() local_unnamed_addr #0 {
|
||||||
; TO: ret i64 8
|
; TO: ret i64 8
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64 @fh() #0 {
|
; TO: define i64 @fh() local_unnamed_addr #0 {
|
||||||
; TO: ret i64 8
|
; TO: ret i64 8
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64 @fi() #0 {
|
; TO: define i64 @fi() local_unnamed_addr #0 {
|
||||||
; TO: ret i64 8
|
; TO: ret i64 8
|
||||||
; TO: }
|
; TO: }
|
||||||
; SCEV: Classifying expressions for: @fa
|
; SCEV: Classifying expressions for: @fa
|
||||||
@ -387,22 +387,22 @@ define i64 @fi() nounwind {
|
|||||||
; PLAIN: %t = bitcast i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1) to i64*
|
; PLAIN: %t = bitcast i64* getelementptr ([2 x i64], [2 x i64]* null, i32 0, i32 1) to i64*
|
||||||
; PLAIN: ret i64* %t
|
; PLAIN: ret i64* %t
|
||||||
; PLAIN: }
|
; PLAIN: }
|
||||||
; OPT: define i64* @fM() #0 {
|
; OPT: define i64* @fM() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64* inttoptr (i64 8 to i64*)
|
; OPT: ret i64* inttoptr (i64 8 to i64*)
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64* @fN() #0 {
|
; OPT: define i64* @fN() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64* inttoptr (i64 8 to i64*)
|
; OPT: ret i64* inttoptr (i64 8 to i64*)
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; OPT: define i64* @fO() #0 {
|
; OPT: define i64* @fO() local_unnamed_addr #0 {
|
||||||
; OPT: ret i64* inttoptr (i64 8 to i64*)
|
; OPT: ret i64* inttoptr (i64 8 to i64*)
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; TO: define i64* @fM() #0 {
|
; TO: define i64* @fM() local_unnamed_addr #0 {
|
||||||
; TO: ret i64* inttoptr (i64 8 to i64*)
|
; TO: ret i64* inttoptr (i64 8 to i64*)
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64* @fN() #0 {
|
; TO: define i64* @fN() local_unnamed_addr #0 {
|
||||||
; TO: ret i64* inttoptr (i64 8 to i64*)
|
; TO: ret i64* inttoptr (i64 8 to i64*)
|
||||||
; TO: }
|
; TO: }
|
||||||
; TO: define i64* @fO() #0 {
|
; TO: define i64* @fO() local_unnamed_addr #0 {
|
||||||
; TO: ret i64* inttoptr (i64 8 to i64*)
|
; TO: ret i64* inttoptr (i64 8 to i64*)
|
||||||
; TO: }
|
; TO: }
|
||||||
; SCEV: Classifying expressions for: @fM
|
; SCEV: Classifying expressions for: @fM
|
||||||
@ -432,10 +432,10 @@ define i64* @fO() nounwind {
|
|||||||
; PLAIN: %t = bitcast i32* getelementptr inbounds (i32, i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1) to i32*
|
; PLAIN: %t = bitcast i32* getelementptr inbounds (i32, i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 0), i64 1) to i32*
|
||||||
; PLAIN: ret i32* %t
|
; PLAIN: ret i32* %t
|
||||||
; PLAIN: }
|
; PLAIN: }
|
||||||
; OPT: define i32* @fZ() #0 {
|
; OPT: define i32* @fZ() local_unnamed_addr #0 {
|
||||||
; OPT: ret i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
|
; OPT: ret i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
|
||||||
; OPT: }
|
; OPT: }
|
||||||
; TO: define i32* @fZ() #0 {
|
; TO: define i32* @fZ() local_unnamed_addr #0 {
|
||||||
; TO: ret i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
|
; TO: ret i32* getelementptr inbounds ([3 x { i32, i32 }], [3 x { i32, i32 }]* @ext, i64 0, i64 1, i32 1)
|
||||||
; TO: }
|
; TO: }
|
||||||
; SCEV: Classifying expressions for: @fZ
|
; SCEV: Classifying expressions for: @fZ
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
; PR8389: Globals with weak_odr linkage type must not be modified
|
; PR8389: Globals with weak_odr linkage type must not be modified
|
||||||
|
|
||||||
; CHECK: weak_odr global i32 0
|
; CHECK: weak_odr local_unnamed_addr global i32 0
|
||||||
|
|
||||||
@SomeVar = weak_odr global i32 0
|
@SomeVar = weak_odr global i32 0
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ target datalayout = "p:32:32:32-p1:16:16:16"
|
|||||||
; CHECK-DAG: @llvm.compiler.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @ia to i8*)], section "llvm.metadata"
|
; CHECK-DAG: @llvm.compiler.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @ia to i8*)], section "llvm.metadata"
|
||||||
|
|
||||||
@sameAsUsed = global [1 x i8*] [i8* addrspacecast(i8 addrspace(1)* @ca to i8*)]
|
@sameAsUsed = global [1 x i8*] [i8* addrspacecast(i8 addrspace(1)* @ca to i8*)]
|
||||||
; CHECK-DAG: @sameAsUsed = global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @c to i8*)]
|
; CHECK-DAG: @sameAsUsed = local_unnamed_addr global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* @c to i8*)]
|
||||||
|
|
||||||
@ca = internal alias i8, i8 addrspace(1)* @c
|
@ca = internal alias i8, i8 addrspace(1)* @c
|
||||||
; CHECK: @ca = internal alias i8, i8 addrspace(1)* @c
|
; CHECK: @ca = internal alias i8, i8 addrspace(1)* @c
|
||||||
|
@ -13,10 +13,10 @@
|
|||||||
; CHECK-DAG: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void ()* @fa3 to i8*), i8* @ia], section "llvm.metadata"
|
; CHECK-DAG: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void ()* @fa3 to i8*), i8* @ia], section "llvm.metadata"
|
||||||
|
|
||||||
@sameAsUsed = global [3 x i8*] [i8* bitcast (void ()* @fa to i8*), i8* bitcast (void ()* @f to i8*), i8* @ca]
|
@sameAsUsed = global [3 x i8*] [i8* bitcast (void ()* @fa to i8*), i8* bitcast (void ()* @f to i8*), i8* @ca]
|
||||||
; CHECK-DAG: @sameAsUsed = global [3 x i8*] [i8* bitcast (void ()* @f to i8*), i8* bitcast (void ()* @f to i8*), i8* @c]
|
; CHECK-DAG: @sameAsUsed = local_unnamed_addr global [3 x i8*] [i8* bitcast (void ()* @f to i8*), i8* bitcast (void ()* @f to i8*), i8* @c]
|
||||||
|
|
||||||
@other = global i32* bitcast (void ()* @fa to i32*)
|
@other = global i32* bitcast (void ()* @fa to i32*)
|
||||||
; CHECK-DAG: @other = global i32* bitcast (void ()* @f to i32*)
|
; CHECK-DAG: @other = local_unnamed_addr global i32* bitcast (void ()* @f to i32*)
|
||||||
|
|
||||||
@fa = internal alias void (), void ()* @f
|
@fa = internal alias void (), void ()* @f
|
||||||
; CHECK: @fa = internal alias void (), void ()* @f
|
; CHECK: @fa = internal alias void (), void ()* @f
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; RUN: opt -S -globalopt < %s | FileCheck %s
|
; RUN: opt -S -globalopt < %s | FileCheck %s
|
||||||
|
|
||||||
; CHECK: @tmp = global i32 42
|
; CHECK: @tmp = local_unnamed_addr global i32 42
|
||||||
|
|
||||||
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
|
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
|
||||||
@tmp = global i32 0
|
@tmp = global i32 0
|
||||||
|
@ -4,13 +4,13 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
|
|||||||
|
|
||||||
@.str91250 = global [3 x i8] zeroinitializer
|
@.str91250 = global [3 x i8] zeroinitializer
|
||||||
|
|
||||||
; CHECK: @A = global i1 false
|
; CHECK: @A = local_unnamed_addr global i1 false
|
||||||
@A = global i1 icmp ne (i64 sub nsw (i64 ptrtoint (i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str91250, i64 0, i64 1) to i64), i64 ptrtoint ([3 x i8]* @.str91250 to i64)), i64 1)
|
@A = global i1 icmp ne (i64 sub nsw (i64 ptrtoint (i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str91250, i64 0, i64 1) to i64), i64 ptrtoint ([3 x i8]* @.str91250 to i64)), i64 1)
|
||||||
|
|
||||||
; PR11352
|
; PR11352
|
||||||
|
|
||||||
@xs = global [2 x i32] zeroinitializer, align 4
|
@xs = global [2 x i32] zeroinitializer, align 4
|
||||||
; CHECK: @xs = global [2 x i32] [i32 1, i32 1]
|
; CHECK: @xs = local_unnamed_addr global [2 x i32] [i32 1, i32 1]
|
||||||
|
|
||||||
; PR12642
|
; PR12642
|
||||||
%PR12642.struct = type { i8 }
|
%PR12642.struct = type { i8 }
|
||||||
@ -32,7 +32,7 @@ entry:
|
|||||||
@f = internal global %closure zeroinitializer, align 4
|
@f = internal global %closure zeroinitializer, align 4
|
||||||
@m = global i32 0, align 4
|
@m = global i32 0, align 4
|
||||||
; CHECK-NOT: @f
|
; CHECK-NOT: @f
|
||||||
; CHECK: @m = global i32 13
|
; CHECK: @m = local_unnamed_addr global i32 13
|
||||||
|
|
||||||
define internal i32 @test2_helper(%closure* %this, i32 %b) {
|
define internal i32 @test2_helper(%closure* %this, i32 %b) {
|
||||||
entry:
|
entry:
|
||||||
@ -53,7 +53,7 @@ entry:
|
|||||||
; PR19955
|
; PR19955
|
||||||
|
|
||||||
@dllimportptr = global i32* null, align 4
|
@dllimportptr = global i32* null, align 4
|
||||||
; CHECK: @dllimportptr = global i32* null, align 4
|
; CHECK: @dllimportptr = local_unnamed_addr global i32* null, align 4
|
||||||
@dllimportvar = external dllimport global i32
|
@dllimportvar = external dllimport global i32
|
||||||
define internal void @test3() {
|
define internal void @test3() {
|
||||||
entry:
|
entry:
|
||||||
@ -62,7 +62,7 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
@dllexportptr = global i32* null, align 4
|
@dllexportptr = global i32* null, align 4
|
||||||
; CHECK: @dllexportptr = global i32* @dllexportvar, align 4
|
; CHECK: @dllexportptr = local_unnamed_addr global i32* @dllexportvar, align 4
|
||||||
@dllexportvar = dllexport global i32 0, align 4
|
@dllexportvar = dllexport global i32 0, align 4
|
||||||
; CHECK: @dllexportvar = dllexport global i32 20, align 4
|
; CHECK: @dllexportvar = dllexport global i32 20, align 4
|
||||||
define internal void @test4() {
|
define internal void @test4() {
|
||||||
@ -83,7 +83,7 @@ entry:
|
|||||||
|
|
||||||
@test6_v1 = internal global { i32, i32 } { i32 42, i32 0 }, align 8
|
@test6_v1 = internal global { i32, i32 } { i32 42, i32 0 }, align 8
|
||||||
@test6_v2 = global i32 0, align 4
|
@test6_v2 = global i32 0, align 4
|
||||||
; CHECK: @test6_v2 = global i32 42, align 4
|
; CHECK: @test6_v2 = local_unnamed_addr global i32 42, align 4
|
||||||
define internal void @test6() {
|
define internal void @test6() {
|
||||||
%load = load { i32, i32 }, { i32, i32 }* @test6_v1, align 8
|
%load = load { i32, i32 }, { i32, i32 }* @test6_v1, align 8
|
||||||
%xv0 = extractvalue { i32, i32 } %load, 0
|
%xv0 = extractvalue { i32, i32 } %load, 0
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
; Don't get fooled by the inbounds keyword; it doesn't change
|
; Don't get fooled by the inbounds keyword; it doesn't change
|
||||||
; the computed address.
|
; the computed address.
|
||||||
|
|
||||||
; CHECK: @H = global i32 2
|
; CHECK: @H = local_unnamed_addr global i32 2
|
||||||
; CHECK: @I = global i32 2
|
; CHECK: @I = local_unnamed_addr global i32 2
|
||||||
|
|
||||||
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @CTOR } ]
|
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @CTOR } ]
|
||||||
@addr = external global i32
|
@addr = external global i32
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
; This test is hint, what could globalOpt optimize and what it can't
|
; This test is hint, what could globalOpt optimize and what it can't
|
||||||
; FIXME: @tmp and @tmp2 can be safely set to 42
|
; FIXME: @tmp and @tmp2 can be safely set to 42
|
||||||
; CHECK: @tmp = global i32 0
|
; CHECK: @tmp = local_unnamed_addr global i32 0
|
||||||
; CHECK: @tmp2 = global i32 0
|
; CHECK: @tmp2 = local_unnamed_addr global i32 0
|
||||||
; CHECK: @tmp3 = global i32 0
|
; CHECK: @tmp3 = global i32 0
|
||||||
|
|
||||||
@tmp = global i32 0
|
@tmp = global i32 0
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
; rdar://11022897
|
; rdar://11022897
|
||||||
|
|
||||||
; Globalopt should be able to evaluate an invoke.
|
; Globalopt should be able to evaluate an invoke.
|
||||||
; CHECK: @tmp = global i32 1
|
; CHECK: @tmp = local_unnamed_addr global i32 1
|
||||||
|
|
||||||
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
|
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [{ i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
|
||||||
@tmp = global i32 0
|
@tmp = global i32 0
|
||||||
|
@ -6,12 +6,12 @@ $c = comdat any
|
|||||||
define linkonce_odr void @foo() comdat($c) {
|
define linkonce_odr void @foo() comdat($c) {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK: define linkonce_odr void @foo() comdat($c)
|
; CHECK: define linkonce_odr void @foo() local_unnamed_addr comdat($c)
|
||||||
|
|
||||||
define linkonce_odr void @bar() comdat($c) {
|
define linkonce_odr void @bar() comdat($c) {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
; CHECK: define linkonce_odr void @bar() comdat($c)
|
; CHECK: define linkonce_odr void @bar() local_unnamed_addr comdat($c)
|
||||||
|
|
||||||
define void @zed() {
|
define void @zed() {
|
||||||
call void @foo()
|
call void @foo()
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
; CHECK: @b = internal global i32 0, align 4
|
; CHECK: @b = internal global i32 0, align 4
|
||||||
; CHECK: @c = internal unnamed_addr global i32 0, align 4
|
; CHECK: @c = internal unnamed_addr global i32 0, align 4
|
||||||
; CHECK: @d = internal unnamed_addr constant [4 x i8] c"foo\00", align 1
|
; CHECK: @d = internal unnamed_addr constant [4 x i8] c"foo\00", align 1
|
||||||
; CHECK: @e = linkonce_odr global i32 0
|
; CHECK: @e = linkonce_odr local_unnamed_addr global i32 0
|
||||||
|
|
||||||
; CHECK: define internal fastcc void @used_internal() unnamed_addr {
|
; CHECK: define internal fastcc void @used_internal() unnamed_addr {
|
||||||
define internal void @used_internal() {
|
define internal void @used_internal() {
|
||||||
|
@ -16,7 +16,7 @@ define hidden void @g() {
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: define internal void @h() {
|
; CHECK: define internal void @h() local_unnamed_addr {
|
||||||
define linkonce_odr void @h() {
|
define linkonce_odr void @h() local_unnamed_addr {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,24 @@
|
|||||||
|
|
||||||
target triple = "x86_64-unknown-linux-gnu"
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
|
; CHECK-DAG: @g1 = linkonce_odr constant i32 32
|
||||||
|
@g1 = linkonce_odr constant i32 32
|
||||||
|
|
||||||
|
; CHECK-DAG: @g2 = internal local_unnamed_addr constant i32 32
|
||||||
|
@g2 = linkonce_odr local_unnamed_addr constant i32 32
|
||||||
|
|
||||||
|
; CHECK-DAG: @g3 = internal unnamed_addr constant i32 32
|
||||||
|
@g3 = linkonce_odr unnamed_addr constant i32 32
|
||||||
|
|
||||||
|
; CHECK-DAG: @g4 = linkonce_odr global i32 32
|
||||||
|
@g4 = linkonce_odr global i32 32
|
||||||
|
|
||||||
|
; CHECK-DAG: @g5 = linkonce_odr local_unnamed_addr global i32 32
|
||||||
|
@g5 = linkonce_odr local_unnamed_addr global i32 32
|
||||||
|
|
||||||
|
; CHECK-DAG: @g6 = internal unnamed_addr global i32 32
|
||||||
|
@g6 = linkonce_odr unnamed_addr global i32 32
|
||||||
|
|
||||||
@g7 = extern_weak global i32
|
@g7 = extern_weak global i32
|
||||||
; CHECK-DAG: @g7 = extern_weak global i32
|
; CHECK-DAG: @g7 = extern_weak global i32
|
||||||
|
|
||||||
@ -53,7 +71,7 @@ define void @f3() {
|
|||||||
|
|
||||||
; CHECK-DAG: define internal void @f4()
|
; CHECK-DAG: define internal void @f4()
|
||||||
; OPT2-NOT: @f4
|
; OPT2-NOT: @f4
|
||||||
define linkonce_odr void @f4() {
|
define linkonce_odr void @f4() local_unnamed_addr {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,14 +80,14 @@ define linkonce_odr void @f4() {
|
|||||||
define linkonce_odr void @f5() {
|
define linkonce_odr void @f5() {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
@g5 = global void()* @f5
|
@g9 = global void()* @f5
|
||||||
|
|
||||||
; CHECK-DAG: define internal void @f6() unnamed_addr
|
; CHECK-DAG: define internal void @f6() unnamed_addr
|
||||||
; OPT-DAG: define internal void @f6() unnamed_addr
|
; OPT-DAG: define internal void @f6() unnamed_addr
|
||||||
define linkonce_odr void @f6() unnamed_addr {
|
define linkonce_odr void @f6() unnamed_addr {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
@g6 = global void()* @f6
|
@g10 = global void()* @f6
|
||||||
|
|
||||||
define i32* @f7() {
|
define i32* @f7() {
|
||||||
ret i32* @g7
|
ret i32* @g7
|
||||||
@ -89,5 +107,5 @@ define i32* @f8() {
|
|||||||
; API: f8 PREVAILING_DEF_IRONLY_EXP
|
; API: f8 PREVAILING_DEF_IRONLY_EXP
|
||||||
; API: g7 UNDEF
|
; API: g7 UNDEF
|
||||||
; API: g8 UNDEF
|
; API: g8 UNDEF
|
||||||
; API: g5 PREVAILING_DEF_IRONLY_EXP
|
; API: g9 PREVAILING_DEF_IRONLY_EXP
|
||||||
; API: g6 PREVAILING_DEF_IRONLY_EXP
|
; API: g10 PREVAILING_DEF_IRONLY_EXP
|
||||||
|
@ -109,7 +109,7 @@ struct ResolutionInfo {
|
|||||||
uint64_t CommonSize = 0;
|
uint64_t CommonSize = 0;
|
||||||
unsigned CommonAlign = 0;
|
unsigned CommonAlign = 0;
|
||||||
bool IsLinkonceOdr = true;
|
bool IsLinkonceOdr = true;
|
||||||
bool UnnamedAddr = true;
|
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::UnnamedAddr::Global;
|
||||||
GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
|
GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility;
|
||||||
bool CommonInternal = false;
|
bool CommonInternal = false;
|
||||||
bool UseCommon = false;
|
bool UseCommon = false;
|
||||||
@ -551,7 +551,8 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
|
|||||||
|
|
||||||
sym.visibility = LDPV_DEFAULT;
|
sym.visibility = LDPV_DEFAULT;
|
||||||
if (GV) {
|
if (GV) {
|
||||||
Res.UnnamedAddr &= GV->hasUnnamedAddr();
|
Res.UnnamedAddr =
|
||||||
|
GlobalValue::getMinUnnamedAddr(Res.UnnamedAddr, GV->getUnnamedAddr());
|
||||||
Res.IsLinkonceOdr &= GV->hasLinkOnceLinkage();
|
Res.IsLinkonceOdr &= GV->hasLinkOnceLinkage();
|
||||||
Res.Visibility = getMinVisibility(Res.Visibility, GV->getVisibility());
|
Res.Visibility = getMinVisibility(Res.Visibility, GV->getVisibility());
|
||||||
switch (GV->getVisibility()) {
|
switch (GV->getVisibility()) {
|
||||||
@ -690,10 +691,11 @@ getModuleSummaryIndexForFile(claimed_file &F) {
|
|||||||
return Obj.takeIndex();
|
return Obj.takeIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<Module> getModuleForFile(
|
static std::unique_ptr<Module>
|
||||||
LLVMContext &Context, claimed_file &F, const void *View, StringRef Name,
|
getModuleForFile(LLVMContext &Context, claimed_file &F, const void *View,
|
||||||
raw_fd_ostream *ApiFile, StringSet<> &Internalize, StringSet<> &Maybe,
|
StringRef Name, raw_fd_ostream *ApiFile,
|
||||||
std::vector<GlobalValue *> &Keep, StringMap<unsigned> &Realign) {
|
StringSet<> &Internalize, std::vector<GlobalValue *> &Keep,
|
||||||
|
StringMap<unsigned> &Realign) {
|
||||||
MemoryBufferRef BufferRef(StringRef((const char *)View, F.filesize), Name);
|
MemoryBufferRef BufferRef(StringRef((const char *)View, F.filesize), Name);
|
||||||
ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
|
ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
|
||||||
object::IRObjectFile::create(BufferRef, Context);
|
object::IRObjectFile::create(BufferRef, Context);
|
||||||
@ -827,12 +829,9 @@ static std::unique_ptr<Module> getModuleForFile(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LDPR_PREVAILING_DEF_IRONLY_EXP: {
|
case LDPR_PREVAILING_DEF_IRONLY_EXP: {
|
||||||
// We can only check for address uses after we merge the modules. The
|
|
||||||
// reason is that this GV might have a copy in another module
|
|
||||||
// and in that module the address might be significant, but that
|
|
||||||
// copy will be LDPR_PREEMPTED_IR.
|
|
||||||
Maybe.insert(GV->getName());
|
|
||||||
Keep.push_back(GV);
|
Keep.push_back(GV);
|
||||||
|
if (canBeOmittedFromSymbolTable(GV))
|
||||||
|
Internalize.insert(GV->getName());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1149,11 +1148,11 @@ void CodeGen::runAll() {
|
|||||||
static void linkInModule(LLVMContext &Context, IRMover &L, claimed_file &F,
|
static void linkInModule(LLVMContext &Context, IRMover &L, claimed_file &F,
|
||||||
const void *View, StringRef Name,
|
const void *View, StringRef Name,
|
||||||
raw_fd_ostream *ApiFile, StringSet<> &Internalize,
|
raw_fd_ostream *ApiFile, StringSet<> &Internalize,
|
||||||
StringSet<> &Maybe, bool SetName = false) {
|
bool SetName = false) {
|
||||||
std::vector<GlobalValue *> Keep;
|
std::vector<GlobalValue *> Keep;
|
||||||
StringMap<unsigned> Realign;
|
StringMap<unsigned> Realign;
|
||||||
std::unique_ptr<Module> M = getModuleForFile(
|
std::unique_ptr<Module> M = getModuleForFile(Context, F, View, Name, ApiFile,
|
||||||
Context, F, View, Name, ApiFile, Internalize, Maybe, Keep, Realign);
|
Internalize, Keep, Realign);
|
||||||
if (!M.get())
|
if (!M.get())
|
||||||
return;
|
return;
|
||||||
if (!options::triple.empty())
|
if (!options::triple.empty())
|
||||||
@ -1204,7 +1203,7 @@ static void thinLTOBackendTask(claimed_file &F, const void *View,
|
|||||||
IRMover L(*NewModule.get());
|
IRMover L(*NewModule.get());
|
||||||
|
|
||||||
StringSet<> Dummy;
|
StringSet<> Dummy;
|
||||||
linkInModule(Context, L, F, View, Name, ApiFile, Dummy, Dummy, true);
|
linkInModule(Context, L, F, View, Name, ApiFile, Dummy, true);
|
||||||
if (renameModuleForThinLTO(*NewModule, CombinedIndex))
|
if (renameModuleForThinLTO(*NewModule, CombinedIndex))
|
||||||
message(LDPL_FATAL, "Failed to rename module for ThinLTO");
|
message(LDPL_FATAL, "Failed to rename module for ThinLTO");
|
||||||
|
|
||||||
@ -1474,7 +1473,6 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
|
|||||||
IRMover L(*Combined);
|
IRMover L(*Combined);
|
||||||
|
|
||||||
StringSet<> Internalize;
|
StringSet<> Internalize;
|
||||||
StringSet<> Maybe;
|
|
||||||
for (claimed_file &F : Modules) {
|
for (claimed_file &F : Modules) {
|
||||||
// RAII object to manage the file opening and releasing interfaces with
|
// RAII object to manage the file opening and releasing interfaces with
|
||||||
// gold.
|
// gold.
|
||||||
@ -1482,7 +1480,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
|
|||||||
const void *View = getSymbolsAndView(F);
|
const void *View = getSymbolsAndView(F);
|
||||||
if (!View)
|
if (!View)
|
||||||
continue;
|
continue;
|
||||||
linkInModule(Context, L, F, View, F.name, ApiFile, Internalize, Maybe);
|
linkInModule(Context, L, F, View, F.name, ApiFile, Internalize);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &Name : Internalize) {
|
for (const auto &Name : Internalize) {
|
||||||
@ -1491,15 +1489,6 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
|
|||||||
internalize(*GV);
|
internalize(*GV);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &Name : Maybe) {
|
|
||||||
GlobalValue *GV = Combined->getNamedValue(Name.first());
|
|
||||||
if (!GV)
|
|
||||||
continue;
|
|
||||||
GV->setLinkage(GlobalValue::LinkOnceODRLinkage);
|
|
||||||
if (canBeOmittedFromSymbolTable(GV))
|
|
||||||
internalize(*GV);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options::TheOutputType == options::OT_DISABLE)
|
if (options::TheOutputType == options::OT_DISABLE)
|
||||||
return LDPS_OK;
|
return LDPS_OK;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user