2003-09-30 20:37:50 +02:00
|
|
|
//===-- llvm/GlobalValue.h - Class to represent a global value --*- C++ -*-===//
|
2005-04-21 22:19:05 +02:00
|
|
|
//
|
2003-10-20 22:19:47 +02:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 20:59:42 +01:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-21 22:19:05 +02:00
|
|
|
//
|
2003-10-20 22:19:47 +02:00
|
|
|
//===----------------------------------------------------------------------===//
|
2001-10-03 16:53:21 +02:00
|
|
|
//
|
|
|
|
// This file is a common base class of all globally definable objects. As such,
|
2007-04-30 21:14:56 +02:00
|
|
|
// it is subclassed by GlobalVariable, GlobalAlias and by Function. This is
|
|
|
|
// used because you can do certain things with these global objects that you
|
|
|
|
// can't do to anything else. For example, use the address of one as a
|
|
|
|
// constant.
|
2001-10-03 16:53:21 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-01-10 01:45:19 +01:00
|
|
|
#ifndef LLVM_IR_GLOBALVALUE_H
|
|
|
|
#define LLVM_IR_GLOBALVALUE_H
|
2001-10-03 16:53:21 +02:00
|
|
|
|
2013-01-02 12:36:10 +01:00
|
|
|
#include "llvm/IR/Constant.h"
|
2013-05-01 17:04:18 +02:00
|
|
|
#include "llvm/IR/DerivedTypes.h"
|
2016-03-15 03:13:19 +01:00
|
|
|
#include "llvm/Support/MD5.h"
|
2014-10-25 00:50:48 +02:00
|
|
|
#include <system_error>
|
|
|
|
|
2003-11-11 23:41:34 +01:00
|
|
|
namespace llvm {
|
|
|
|
|
2014-06-27 20:19:56 +02:00
|
|
|
class Comdat;
|
2001-10-03 16:53:21 +02:00
|
|
|
class PointerType;
|
2002-04-28 06:45:05 +02:00
|
|
|
class Module;
|
2001-10-03 16:53:21 +02:00
|
|
|
|
2015-05-19 02:24:26 +02:00
|
|
|
namespace Intrinsic {
|
|
|
|
enum ID : unsigned;
|
2015-05-19 08:25:19 +02:00
|
|
|
}
|
2015-05-19 02:24:26 +02:00
|
|
|
|
2004-07-18 01:28:28 +02:00
|
|
|
class GlobalValue : public Constant {
|
2015-02-15 23:54:22 +01:00
|
|
|
GlobalValue(const GlobalValue &) = delete;
|
2003-04-16 22:28:45 +02:00
|
|
|
public:
|
2007-01-27 05:42:50 +01:00
|
|
|
/// @brief An enumeration for the kinds of linkage for global values.
|
2016-04-24 16:13:17 +02:00
|
|
|
enum LinkageTypes {
|
2007-04-17 06:31:29 +02:00
|
|
|
ExternalLinkage = 0,///< Externally visible function
|
2009-04-13 07:44:34 +02:00
|
|
|
AvailableExternallyLinkage, ///< Available for inspection, not emission.
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
llvm-svn: 66339
2009-03-07 16:45:40 +01:00
|
|
|
LinkOnceAnyLinkage, ///< Keep one copy of function when linking (inline)
|
|
|
|
LinkOnceODRLinkage, ///< Same, but only replaced by something equivalent.
|
|
|
|
WeakAnyLinkage, ///< Keep one copy of named function when linking (weak)
|
|
|
|
WeakODRLinkage, ///< Same, but only replaced by something equivalent.
|
2007-01-27 05:42:50 +01:00
|
|
|
AppendingLinkage, ///< Special purpose, only applies to global arrays
|
2009-07-20 03:03:30 +02:00
|
|
|
InternalLinkage, ///< Rename collisions when linking (static functions).
|
|
|
|
PrivateLinkage, ///< Like Internal, but omit from symbol table.
|
|
|
|
ExternalWeakLinkage,///< ExternalWeak linkage description.
|
|
|
|
CommonLinkage ///< Tentative definitions.
|
2003-04-16 22:28:45 +02:00
|
|
|
};
|
2007-01-27 05:42:50 +01:00
|
|
|
|
|
|
|
/// @brief An enumeration for the kinds of visibility of global values.
|
2007-01-12 20:20:47 +01:00
|
|
|
enum VisibilityTypes {
|
2007-04-17 06:31:29 +02:00
|
|
|
DefaultVisibility = 0, ///< The GV is visible
|
2007-04-29 20:35:00 +02:00
|
|
|
HiddenVisibility, ///< The GV is hidden
|
|
|
|
ProtectedVisibility ///< The GV is protected
|
2007-01-12 20:20:47 +01:00
|
|
|
};
|
2007-01-27 05:42:50 +01:00
|
|
|
|
2014-01-14 16:22:47 +01:00
|
|
|
/// @brief Storage classes of global values for PE targets.
|
|
|
|
enum DLLStorageClassTypes {
|
|
|
|
DefaultStorageClass = 0,
|
|
|
|
DLLImportStorageClass = 1, ///< Function to be imported from DLL
|
|
|
|
DLLExportStorageClass = 2 ///< Function to be accessible from DLL.
|
|
|
|
};
|
|
|
|
|
2001-10-03 16:53:21 +02:00
|
|
|
protected:
|
2015-09-14 23:47:27 +02:00
|
|
|
GlobalValue(Type *Ty, ValueTy VTy, Use *Ops, unsigned NumOps,
|
|
|
|
LinkageTypes Linkage, const Twine &Name, unsigned AddressSpace)
|
|
|
|
: Constant(PointerType::get(Ty, AddressSpace), VTy, Ops, NumOps),
|
|
|
|
ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility),
|
2016-06-14 23:01:22 +02:00
|
|
|
UnnamedAddrVal(unsigned(UnnamedAddr::None)),
|
|
|
|
DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal),
|
|
|
|
IntID((Intrinsic::ID)0U), Parent(nullptr) {
|
2009-07-25 06:41:11 +02:00
|
|
|
setName(Name);
|
2007-02-12 06:18:08 +01:00
|
|
|
}
|
2001-10-03 21:28:15 +02:00
|
|
|
|
2015-09-14 23:47:27 +02:00
|
|
|
Type *ValueType;
|
2016-02-26 19:08:59 +01:00
|
|
|
// All bitfields use unsigned as the underlying type so that MSVC will pack
|
|
|
|
// them.
|
|
|
|
unsigned Linkage : 4; // The linkage of this global
|
2007-04-29 20:35:00 +02:00
|
|
|
unsigned Visibility : 2; // The visibility style of this global
|
2016-06-14 23:01:22 +02:00
|
|
|
unsigned UnnamedAddrVal : 2; // This value's address is not significant
|
2014-01-14 16:22:47 +01:00
|
|
|
unsigned DllStorageClass : 2; // DLL storage class
|
2014-05-13 20:45:48 +02:00
|
|
|
|
2014-05-28 20:15:43 +02:00
|
|
|
unsigned ThreadLocal : 3; // Is this symbol "Thread Local", if so, what is
|
|
|
|
// the desired model?
|
2015-06-10 08:00:59 +02:00
|
|
|
static const unsigned GlobalValueSubClassDataBits = 19;
|
2014-05-28 20:15:43 +02:00
|
|
|
|
2014-05-13 20:45:48 +02:00
|
|
|
private:
|
|
|
|
// Give subclasses access to what otherwise would be wasted padding.
|
2016-06-14 23:01:22 +02:00
|
|
|
// (19 + 4 + 2 + 2 + 2 + 3) == 32.
|
2015-06-10 08:00:59 +02:00
|
|
|
unsigned SubClassData : GlobalValueSubClassDataBits;
|
2015-05-19 02:24:26 +02:00
|
|
|
|
2015-06-23 23:55:11 +02:00
|
|
|
friend class Constant;
|
|
|
|
void destroyConstantImpl();
|
2016-02-10 23:47:15 +01:00
|
|
|
Value *handleOperandChangeImpl(Value *From, Value *To);
|
2015-06-23 23:55:11 +02:00
|
|
|
|
Don't IPO over functions that can be de-refined
Summary:
Fixes PR26774.
If you're aware of the issue, feel free to skip the "Motivation"
section and jump directly to "This patch".
Motivation:
I define "refinement" as discarding behaviors from a program that the
optimizer has license to discard. So transforming:
```
void f(unsigned x) {
unsigned t = 5 / x;
(void)t;
}
```
to
```
void f(unsigned x) { }
```
is refinement, since the behavior went from "if x == 0 then undefined
else nothing" to "nothing" (the optimizer has license to discard
undefined behavior).
Refinement is a fundamental aspect of many mid-level optimizations done
by LLVM. For instance, transforming `x == (x + 1)` to `false` also
involves refinement since the expression's value went from "if x is
`undef` then { `true` or `false` } else { `false` }" to "`false`" (by
definition, the optimizer has license to fold `undef` to any non-`undef`
value).
Unfortunately, refinement implies that the optimizer cannot assume
that the implementation of a function it can see has all of the
behavior an unoptimized or a differently optimized version of the same
function can have. This is a problem for functions with comdat
linkage, where a function can be replaced by an unoptimized or a
differently optimized version of the same source level function.
For instance, FunctionAttrs cannot assume a comdat function is
actually `readnone` even if it does not have any loads or stores in
it; since there may have been loads and stores in the "original
function" that were refined out in the currently visible variant, and
at the link step the linker may in fact choose an implementation with
a load or a store. As an example, consider a function that does two
atomic loads from the same memory location, and writes to memory only
if the two values are not equal. The optimizer is allowed to refine
this function by first CSE'ing the two loads, and the folding the
comparision to always report that the two values are equal. Such a
refined variant will look like it is `readonly`. However, the
unoptimized version of the function can still write to memory (since
the two loads //can// result in different values), and selecting the
unoptimized version at link time will retroactively invalidate
transforms we may have done under the assumption that the function
does not write to memory.
Note: this is not just a problem with atomics or with linking
differently optimized object files. See PR26774 for more realistic
examples that involved neither.
This patch:
This change introduces a new set of linkage types, predicated as
`GlobalValue::mayBeDerefined` that returns true if the linkage type
allows a function to be replaced by a differently optimized variant at
link time. It then changes a set of IPO passes to bail out if they see
such a function.
Reviewers: chandlerc, hfinkel, dexonsmith, joker.eph, rnk
Subscribers: mcrosier, llvm-commits
Differential Revision: http://reviews.llvm.org/D18634
llvm-svn: 265762
2016-04-08 02:48:30 +02:00
|
|
|
/// Returns true if the definition of this global may be replaced by a
|
|
|
|
/// differently optimized variant of the same source level function at link
|
|
|
|
/// time.
|
|
|
|
bool mayBeDerefined() const {
|
|
|
|
switch (getLinkage()) {
|
|
|
|
case WeakODRLinkage:
|
|
|
|
case LinkOnceODRLinkage:
|
|
|
|
case AvailableExternallyLinkage:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case WeakAnyLinkage:
|
|
|
|
case LinkOnceAnyLinkage:
|
|
|
|
case CommonLinkage:
|
|
|
|
case ExternalWeakLinkage:
|
|
|
|
case ExternalLinkage:
|
|
|
|
case AppendingLinkage:
|
|
|
|
case InternalLinkage:
|
|
|
|
case PrivateLinkage:
|
2016-05-11 03:26:06 +02:00
|
|
|
return isInterposable();
|
Don't IPO over functions that can be de-refined
Summary:
Fixes PR26774.
If you're aware of the issue, feel free to skip the "Motivation"
section and jump directly to "This patch".
Motivation:
I define "refinement" as discarding behaviors from a program that the
optimizer has license to discard. So transforming:
```
void f(unsigned x) {
unsigned t = 5 / x;
(void)t;
}
```
to
```
void f(unsigned x) { }
```
is refinement, since the behavior went from "if x == 0 then undefined
else nothing" to "nothing" (the optimizer has license to discard
undefined behavior).
Refinement is a fundamental aspect of many mid-level optimizations done
by LLVM. For instance, transforming `x == (x + 1)` to `false` also
involves refinement since the expression's value went from "if x is
`undef` then { `true` or `false` } else { `false` }" to "`false`" (by
definition, the optimizer has license to fold `undef` to any non-`undef`
value).
Unfortunately, refinement implies that the optimizer cannot assume
that the implementation of a function it can see has all of the
behavior an unoptimized or a differently optimized version of the same
function can have. This is a problem for functions with comdat
linkage, where a function can be replaced by an unoptimized or a
differently optimized version of the same source level function.
For instance, FunctionAttrs cannot assume a comdat function is
actually `readnone` even if it does not have any loads or stores in
it; since there may have been loads and stores in the "original
function" that were refined out in the currently visible variant, and
at the link step the linker may in fact choose an implementation with
a load or a store. As an example, consider a function that does two
atomic loads from the same memory location, and writes to memory only
if the two values are not equal. The optimizer is allowed to refine
this function by first CSE'ing the two loads, and the folding the
comparision to always report that the two values are equal. Such a
refined variant will look like it is `readonly`. However, the
unoptimized version of the function can still write to memory (since
the two loads //can// result in different values), and selecting the
unoptimized version at link time will retroactively invalidate
transforms we may have done under the assumption that the function
does not write to memory.
Note: this is not just a problem with atomics or with linking
differently optimized object files. See PR26774 for more realistic
examples that involved neither.
This patch:
This change introduces a new set of linkage types, predicated as
`GlobalValue::mayBeDerefined` that returns true if the linkage type
allows a function to be replaced by a differently optimized variant at
link time. It then changes a set of IPO passes to bail out if they see
such a function.
Reviewers: chandlerc, hfinkel, dexonsmith, joker.eph, rnk
Subscribers: mcrosier, llvm-commits
Differential Revision: http://reviews.llvm.org/D18634
llvm-svn: 265762
2016-04-08 02:48:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Fully covered switch above!");
|
|
|
|
}
|
|
|
|
|
2014-05-13 20:45:48 +02:00
|
|
|
protected:
|
2015-05-19 02:24:26 +02:00
|
|
|
/// \brief The intrinsic ID for this subclass (which must be a Function).
|
|
|
|
///
|
|
|
|
/// This member is defined by this class, but not used for anything.
|
|
|
|
/// Subclasses can use it to store their intrinsic ID, if they have one.
|
|
|
|
///
|
|
|
|
/// This is stored here to save space in Function on 64-bit hosts.
|
|
|
|
Intrinsic::ID IntID;
|
|
|
|
|
2014-05-13 20:45:48 +02:00
|
|
|
unsigned getGlobalValueSubClassData() const {
|
|
|
|
return SubClassData;
|
|
|
|
}
|
|
|
|
void setGlobalValueSubClassData(unsigned V) {
|
2015-06-10 08:00:59 +02:00
|
|
|
assert(V < (1 << GlobalValueSubClassDataBits) && "It will not fit");
|
2014-05-13 20:45:48 +02:00
|
|
|
SubClassData = V;
|
|
|
|
}
|
|
|
|
|
2012-01-07 22:17:16 +01:00
|
|
|
Module *Parent; // The containing module.
|
2007-12-09 23:46:10 +01:00
|
|
|
public:
|
2014-05-28 20:15:43 +02:00
|
|
|
enum ThreadLocalMode {
|
|
|
|
NotThreadLocal = 0,
|
|
|
|
GeneralDynamicTLSModel,
|
|
|
|
LocalDynamicTLSModel,
|
|
|
|
InitialExecTLSModel,
|
|
|
|
LocalExecTLSModel
|
|
|
|
};
|
|
|
|
|
2015-04-11 04:11:45 +02:00
|
|
|
~GlobalValue() override {
|
2007-12-10 03:14:30 +01:00
|
|
|
removeDeadConstantUsers(); // remove any dead constants using this.
|
|
|
|
}
|
|
|
|
|
2014-05-06 18:48:58 +02:00
|
|
|
unsigned getAlignment() const;
|
2007-01-12 20:20:47 +01:00
|
|
|
|
2016-06-14 23:01:22 +02:00
|
|
|
enum class UnnamedAddr {
|
|
|
|
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;
|
|
|
|
}
|
2011-01-08 17:42:36 +01:00
|
|
|
|
2014-06-27 20:19:56 +02:00
|
|
|
bool hasComdat() const { return getComdat() != nullptr; }
|
|
|
|
Comdat *getComdat();
|
|
|
|
const Comdat *getComdat() const {
|
|
|
|
return const_cast<GlobalValue *>(this)->getComdat();
|
|
|
|
}
|
|
|
|
|
2007-08-12 10:12:35 +02:00
|
|
|
VisibilityTypes getVisibility() const { return VisibilityTypes(Visibility); }
|
2009-07-09 06:56:23 +02:00
|
|
|
bool hasDefaultVisibility() const { return Visibility == DefaultVisibility; }
|
2007-01-12 20:20:47 +01:00
|
|
|
bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
|
2007-04-29 20:35:00 +02:00
|
|
|
bool hasProtectedVisibility() const {
|
|
|
|
return Visibility == ProtectedVisibility;
|
|
|
|
}
|
2014-05-08 01:00:22 +02:00
|
|
|
void setVisibility(VisibilityTypes V) {
|
|
|
|
assert((!hasLocalLinkage() || V == DefaultVisibility) &&
|
|
|
|
"local linkage requires default visibility");
|
|
|
|
Visibility = V;
|
|
|
|
}
|
2014-01-14 16:22:47 +01:00
|
|
|
|
2014-05-28 20:15:43 +02:00
|
|
|
/// If the value is "Thread Local", its value isn't shared by the threads.
|
|
|
|
bool isThreadLocal() const { return getThreadLocalMode() != NotThreadLocal; }
|
|
|
|
void setThreadLocal(bool Val) {
|
|
|
|
setThreadLocalMode(Val ? GeneralDynamicTLSModel : NotThreadLocal);
|
|
|
|
}
|
|
|
|
void setThreadLocalMode(ThreadLocalMode Val) {
|
|
|
|
assert(Val == NotThreadLocal || getValueID() != Value::FunctionVal);
|
|
|
|
ThreadLocal = Val;
|
|
|
|
}
|
|
|
|
ThreadLocalMode getThreadLocalMode() const {
|
|
|
|
return static_cast<ThreadLocalMode>(ThreadLocal);
|
|
|
|
}
|
|
|
|
|
2014-01-14 16:22:47 +01:00
|
|
|
DLLStorageClassTypes getDLLStorageClass() const {
|
|
|
|
return DLLStorageClassTypes(DllStorageClass);
|
|
|
|
}
|
|
|
|
bool hasDLLImportStorageClass() const {
|
|
|
|
return DllStorageClass == DLLImportStorageClass;
|
|
|
|
}
|
|
|
|
bool hasDLLExportStorageClass() const {
|
|
|
|
return DllStorageClass == DLLExportStorageClass;
|
|
|
|
}
|
|
|
|
void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; }
|
|
|
|
|
2016-05-11 20:21:59 +02:00
|
|
|
bool hasSection() const { return !getSection().empty(); }
|
|
|
|
StringRef getSection() const;
|
2014-02-13 19:26:41 +01:00
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// Global values are always pointers.
|
2015-04-02 20:55:32 +02:00
|
|
|
PointerType *getType() const { return cast<PointerType>(User::getType()); }
|
|
|
|
|
2015-09-14 23:47:27 +02:00
|
|
|
Type *getValueType() const { return ValueType; }
|
2001-10-03 16:53:21 +02:00
|
|
|
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
llvm-svn: 66339
2009-03-07 16:45:40 +01:00
|
|
|
static LinkageTypes getLinkOnceLinkage(bool ODR) {
|
|
|
|
return ODR ? LinkOnceODRLinkage : LinkOnceAnyLinkage;
|
|
|
|
}
|
|
|
|
static LinkageTypes getWeakLinkage(bool ODR) {
|
|
|
|
return ODR ? WeakODRLinkage : WeakAnyLinkage;
|
|
|
|
}
|
|
|
|
|
2010-03-06 08:22:39 +01:00
|
|
|
static bool isExternalLinkage(LinkageTypes Linkage) {
|
|
|
|
return Linkage == ExternalLinkage;
|
|
|
|
}
|
|
|
|
static bool isAvailableExternallyLinkage(LinkageTypes Linkage) {
|
2009-04-13 07:44:34 +02:00
|
|
|
return Linkage == AvailableExternallyLinkage;
|
|
|
|
}
|
2014-07-01 02:30:52 +02:00
|
|
|
static bool isLinkOnceODRLinkage(LinkageTypes Linkage) {
|
|
|
|
return Linkage == LinkOnceODRLinkage;
|
|
|
|
}
|
2010-03-06 08:22:39 +01:00
|
|
|
static bool isLinkOnceLinkage(LinkageTypes Linkage) {
|
2013-11-01 18:09:14 +01:00
|
|
|
return Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage;
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
llvm-svn: 66339
2009-03-07 16:45:40 +01:00
|
|
|
}
|
2014-05-09 02:36:18 +02:00
|
|
|
static bool isWeakAnyLinkage(LinkageTypes Linkage) {
|
|
|
|
return Linkage == WeakAnyLinkage;
|
|
|
|
}
|
|
|
|
static bool isWeakODRLinkage(LinkageTypes Linkage) {
|
|
|
|
return Linkage == WeakODRLinkage;
|
|
|
|
}
|
2010-03-06 08:22:39 +01:00
|
|
|
static bool isWeakLinkage(LinkageTypes Linkage) {
|
2014-05-09 02:36:18 +02:00
|
|
|
return isWeakAnyLinkage(Linkage) || isWeakODRLinkage(Linkage);
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
llvm-svn: 66339
2009-03-07 16:45:40 +01:00
|
|
|
}
|
2010-03-06 08:22:39 +01:00
|
|
|
static bool isAppendingLinkage(LinkageTypes Linkage) {
|
|
|
|
return Linkage == AppendingLinkage;
|
|
|
|
}
|
|
|
|
static bool isInternalLinkage(LinkageTypes Linkage) {
|
|
|
|
return Linkage == InternalLinkage;
|
|
|
|
}
|
|
|
|
static bool isPrivateLinkage(LinkageTypes Linkage) {
|
|
|
|
return Linkage == PrivateLinkage;
|
|
|
|
}
|
|
|
|
static bool isLocalLinkage(LinkageTypes Linkage) {
|
Remove the linker_private and linker_private_weak linkages.
These linkages were introduced some time ago, but it was never very
clear what exactly their semantics were or what they should be used
for. Some investigation found these uses:
* utf-16 strings in clang.
* non-unnamed_addr strings produced by the sanitizers.
It turns out they were just working around a more fundamental problem.
For some sections a MachO linker needs a symbol in order to split the
section into atoms, and llvm had no idea that was the case. I fixed
that in r201700 and it is now safe to use the private linkage. When
the object ends up in a section that requires symbols, llvm will use a
'l' prefix instead of a 'L' prefix and things just work.
With that, these linkages were already dead, but there was a potential
future user in the objc metadata information. I am still looking at
CGObjcMac.cpp, but at this point I am convinced that linker_private
and linker_private_weak are not what they need.
The objc uses are currently split in
* Regular symbols (no '\01' prefix). LLVM already directly provides
whatever semantics they need.
* Uses of a private name (start with "\01L" or "\01l") and private
linkage. We can drop the "\01L" and "\01l" prefixes as soon as llvm
agrees with clang on L being ok or not for a given section. I have two
patches in code review for this.
* Uses of private name and weak linkage.
The last case is the one that one could think would fit one of these
linkages. That is not the case. The semantics are
* the linker will merge these symbol by *name*.
* the linker will hide them in the final DSO.
Given that the merging is done by name, any of the private (or
internal) linkages would be a bad match. They allow llvm to rename the
symbols, and that is really not what we want. From the llvm point of
view, these objects should really be (linkonce|weak)(_odr)?.
For now, just keeping the "\01l" prefix is probably the best for these
symbols. If we one day want to have a more direct support in llvm,
IMHO what we should add is not a linkage, it is just a hidden_symbol
attribute. It would be applicable to multiple linkages. For example,
on weak it would produce the current behavior we have for objc
metadata. On internal, it would be equivalent to private (and we
should then remove private).
llvm-svn: 203866
2014-03-14 00:18:37 +01:00
|
|
|
return isInternalLinkage(Linkage) || isPrivateLinkage(Linkage);
|
2010-03-06 08:22:39 +01:00
|
|
|
}
|
|
|
|
static bool isExternalWeakLinkage(LinkageTypes Linkage) {
|
|
|
|
return Linkage == ExternalWeakLinkage;
|
|
|
|
}
|
|
|
|
static bool isCommonLinkage(LinkageTypes Linkage) {
|
|
|
|
return Linkage == CommonLinkage;
|
2009-01-15 21:18:42 +01:00
|
|
|
}
|
2016-05-11 15:51:39 +02:00
|
|
|
static bool isValidDeclarationLinkage(LinkageTypes Linkage) {
|
|
|
|
return isExternalWeakLinkage(Linkage) || isExternalLinkage(Linkage);
|
|
|
|
}
|
2001-11-26 19:46:40 +01:00
|
|
|
|
2016-05-03 02:27:28 +02:00
|
|
|
/// Whether the definition of this global may be replaced by something
|
|
|
|
/// non-equivalent at link time. For example, if a function has weak linkage
|
|
|
|
/// then the code defining it may be replaced by different code.
|
2016-05-11 03:26:06 +02:00
|
|
|
static bool isInterposableLinkage(LinkageTypes Linkage) {
|
2016-05-03 02:27:28 +02:00
|
|
|
switch (Linkage) {
|
|
|
|
case WeakAnyLinkage:
|
|
|
|
case LinkOnceAnyLinkage:
|
|
|
|
case CommonLinkage:
|
|
|
|
case ExternalWeakLinkage:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case AvailableExternallyLinkage:
|
|
|
|
case LinkOnceODRLinkage:
|
|
|
|
case WeakODRLinkage:
|
|
|
|
// The above three cannot be overridden but can be de-refined.
|
|
|
|
|
|
|
|
case ExternalLinkage:
|
|
|
|
case AppendingLinkage:
|
|
|
|
case InternalLinkage:
|
|
|
|
case PrivateLinkage:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
llvm_unreachable("Fully covered switch above!");
|
|
|
|
}
|
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// Whether the definition of this global may be discarded if it is not used
|
|
|
|
/// in its compilation unit.
|
2012-06-15 00:48:13 +02:00
|
|
|
static bool isDiscardableIfUnused(LinkageTypes Linkage) {
|
2015-09-08 20:25:20 +02:00
|
|
|
return isLinkOnceLinkage(Linkage) || isLocalLinkage(Linkage) ||
|
|
|
|
isAvailableExternallyLinkage(Linkage);
|
2012-06-15 00:48:13 +02:00
|
|
|
}
|
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// Whether the definition of this global may be replaced at link time. NB:
|
|
|
|
/// Using this method outside of the code generators is almost always a
|
2016-05-11 03:26:06 +02:00
|
|
|
/// mistake: when working at the IR level use isInterposable instead as it
|
2014-05-07 19:04:45 +02:00
|
|
|
/// knows about ODR semantics.
|
2010-03-06 08:22:39 +01:00
|
|
|
static bool isWeakForLinker(LinkageTypes Linkage) {
|
2015-07-05 22:52:35 +02:00
|
|
|
return Linkage == WeakAnyLinkage || Linkage == WeakODRLinkage ||
|
|
|
|
Linkage == LinkOnceAnyLinkage || Linkage == LinkOnceODRLinkage ||
|
2015-12-08 20:13:31 +01:00
|
|
|
Linkage == CommonLinkage || Linkage == ExternalWeakLinkage;
|
2008-07-06 01:48:30 +02:00
|
|
|
}
|
|
|
|
|
Don't IPO over functions that can be de-refined
Summary:
Fixes PR26774.
If you're aware of the issue, feel free to skip the "Motivation"
section and jump directly to "This patch".
Motivation:
I define "refinement" as discarding behaviors from a program that the
optimizer has license to discard. So transforming:
```
void f(unsigned x) {
unsigned t = 5 / x;
(void)t;
}
```
to
```
void f(unsigned x) { }
```
is refinement, since the behavior went from "if x == 0 then undefined
else nothing" to "nothing" (the optimizer has license to discard
undefined behavior).
Refinement is a fundamental aspect of many mid-level optimizations done
by LLVM. For instance, transforming `x == (x + 1)` to `false` also
involves refinement since the expression's value went from "if x is
`undef` then { `true` or `false` } else { `false` }" to "`false`" (by
definition, the optimizer has license to fold `undef` to any non-`undef`
value).
Unfortunately, refinement implies that the optimizer cannot assume
that the implementation of a function it can see has all of the
behavior an unoptimized or a differently optimized version of the same
function can have. This is a problem for functions with comdat
linkage, where a function can be replaced by an unoptimized or a
differently optimized version of the same source level function.
For instance, FunctionAttrs cannot assume a comdat function is
actually `readnone` even if it does not have any loads or stores in
it; since there may have been loads and stores in the "original
function" that were refined out in the currently visible variant, and
at the link step the linker may in fact choose an implementation with
a load or a store. As an example, consider a function that does two
atomic loads from the same memory location, and writes to memory only
if the two values are not equal. The optimizer is allowed to refine
this function by first CSE'ing the two loads, and the folding the
comparision to always report that the two values are equal. Such a
refined variant will look like it is `readonly`. However, the
unoptimized version of the function can still write to memory (since
the two loads //can// result in different values), and selecting the
unoptimized version at link time will retroactively invalidate
transforms we may have done under the assumption that the function
does not write to memory.
Note: this is not just a problem with atomics or with linking
differently optimized object files. See PR26774 for more realistic
examples that involved neither.
This patch:
This change introduces a new set of linkage types, predicated as
`GlobalValue::mayBeDerefined` that returns true if the linkage type
allows a function to be replaced by a differently optimized variant at
link time. It then changes a set of IPO passes to bail out if they see
such a function.
Reviewers: chandlerc, hfinkel, dexonsmith, joker.eph, rnk
Subscribers: mcrosier, llvm-commits
Differential Revision: http://reviews.llvm.org/D18634
llvm-svn: 265762
2016-04-08 02:48:30 +02:00
|
|
|
/// Return true if the currently visible definition of this global (if any) is
|
|
|
|
/// exactly the definition we will see at runtime.
|
|
|
|
///
|
|
|
|
/// Non-exact linkage types inhibits most non-inlining IPO, since a
|
|
|
|
/// differently optimized variant of the same function can have different
|
|
|
|
/// observable or undefined behavior than in the variant currently visible.
|
|
|
|
/// For instance, we could have started with
|
|
|
|
///
|
|
|
|
/// void foo(int *v) {
|
|
|
|
/// int t = 5 / v[0];
|
|
|
|
/// (void) t;
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// and "refined" it to
|
|
|
|
///
|
|
|
|
/// void foo(int *v) { }
|
|
|
|
///
|
|
|
|
/// However, we cannot infer readnone for `foo`, since that would justify
|
|
|
|
/// DSE'ing a store to `v[0]` across a call to `foo`, which can cause
|
|
|
|
/// undefined behavior if the linker replaces the actual call destination with
|
|
|
|
/// the unoptimized `foo`.
|
|
|
|
///
|
|
|
|
/// Inlining is okay across non-exact linkage types as long as they're not
|
|
|
|
/// interposable (see \c isInterposable), since in such cases the currently
|
|
|
|
/// visible variant is *a* correct implementation of the original source
|
|
|
|
/// function; it just isn't the *only* correct implementation.
|
|
|
|
bool isDefinitionExact() const {
|
|
|
|
return !mayBeDerefined();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return true if this global has an exact defintion.
|
|
|
|
bool hasExactDefinition() const {
|
|
|
|
// While this computes exactly the same thing as
|
|
|
|
// isStrongDefinitionForLinker, the intended uses are different. This
|
|
|
|
// function is intended to help decide if specific inter-procedural
|
|
|
|
// transforms are correct, while isStrongDefinitionForLinker's intended use
|
|
|
|
// is in low level code generation.
|
|
|
|
return !isDeclaration() && isDefinitionExact();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Return true if this global's definition can be substituted with an
|
|
|
|
/// *arbitrary* definition at link time. We cannot do any IPO or inlinining
|
|
|
|
/// across interposable call edges, since the callee can be replaced with
|
|
|
|
/// something arbitrary at link time.
|
2016-05-11 03:26:06 +02:00
|
|
|
bool isInterposable() const { return isInterposableLinkage(getLinkage()); }
|
Don't IPO over functions that can be de-refined
Summary:
Fixes PR26774.
If you're aware of the issue, feel free to skip the "Motivation"
section and jump directly to "This patch".
Motivation:
I define "refinement" as discarding behaviors from a program that the
optimizer has license to discard. So transforming:
```
void f(unsigned x) {
unsigned t = 5 / x;
(void)t;
}
```
to
```
void f(unsigned x) { }
```
is refinement, since the behavior went from "if x == 0 then undefined
else nothing" to "nothing" (the optimizer has license to discard
undefined behavior).
Refinement is a fundamental aspect of many mid-level optimizations done
by LLVM. For instance, transforming `x == (x + 1)` to `false` also
involves refinement since the expression's value went from "if x is
`undef` then { `true` or `false` } else { `false` }" to "`false`" (by
definition, the optimizer has license to fold `undef` to any non-`undef`
value).
Unfortunately, refinement implies that the optimizer cannot assume
that the implementation of a function it can see has all of the
behavior an unoptimized or a differently optimized version of the same
function can have. This is a problem for functions with comdat
linkage, where a function can be replaced by an unoptimized or a
differently optimized version of the same source level function.
For instance, FunctionAttrs cannot assume a comdat function is
actually `readnone` even if it does not have any loads or stores in
it; since there may have been loads and stores in the "original
function" that were refined out in the currently visible variant, and
at the link step the linker may in fact choose an implementation with
a load or a store. As an example, consider a function that does two
atomic loads from the same memory location, and writes to memory only
if the two values are not equal. The optimizer is allowed to refine
this function by first CSE'ing the two loads, and the folding the
comparision to always report that the two values are equal. Such a
refined variant will look like it is `readonly`. However, the
unoptimized version of the function can still write to memory (since
the two loads //can// result in different values), and selecting the
unoptimized version at link time will retroactively invalidate
transforms we may have done under the assumption that the function
does not write to memory.
Note: this is not just a problem with atomics or with linking
differently optimized object files. See PR26774 for more realistic
examples that involved neither.
This patch:
This change introduces a new set of linkage types, predicated as
`GlobalValue::mayBeDerefined` that returns true if the linkage type
allows a function to be replaced by a differently optimized variant at
link time. It then changes a set of IPO passes to bail out if they see
such a function.
Reviewers: chandlerc, hfinkel, dexonsmith, joker.eph, rnk
Subscribers: mcrosier, llvm-commits
Differential Revision: http://reviews.llvm.org/D18634
llvm-svn: 265762
2016-04-08 02:48:30 +02:00
|
|
|
|
2016-02-26 19:08:59 +01:00
|
|
|
bool hasExternalLinkage() const { return isExternalLinkage(getLinkage()); }
|
2010-03-06 08:22:39 +01:00
|
|
|
bool hasAvailableExternallyLinkage() const {
|
2016-02-26 19:08:59 +01:00
|
|
|
return isAvailableExternallyLinkage(getLinkage());
|
2010-03-06 08:22:39 +01:00
|
|
|
}
|
2016-02-26 19:08:59 +01:00
|
|
|
bool hasLinkOnceLinkage() const { return isLinkOnceLinkage(getLinkage()); }
|
|
|
|
bool hasLinkOnceODRLinkage() const {
|
|
|
|
return isLinkOnceODRLinkage(getLinkage());
|
2010-03-06 08:22:39 +01:00
|
|
|
}
|
2016-02-26 19:08:59 +01:00
|
|
|
bool hasWeakLinkage() const { return isWeakLinkage(getLinkage()); }
|
|
|
|
bool hasWeakAnyLinkage() const { return isWeakAnyLinkage(getLinkage()); }
|
|
|
|
bool hasWeakODRLinkage() const { return isWeakODRLinkage(getLinkage()); }
|
|
|
|
bool hasAppendingLinkage() const { return isAppendingLinkage(getLinkage()); }
|
|
|
|
bool hasInternalLinkage() const { return isInternalLinkage(getLinkage()); }
|
|
|
|
bool hasPrivateLinkage() const { return isPrivateLinkage(getLinkage()); }
|
|
|
|
bool hasLocalLinkage() const { return isLocalLinkage(getLinkage()); }
|
|
|
|
bool hasExternalWeakLinkage() const {
|
|
|
|
return isExternalWeakLinkage(getLinkage());
|
2010-03-06 08:22:39 +01:00
|
|
|
}
|
2016-02-26 19:08:59 +01:00
|
|
|
bool hasCommonLinkage() const { return isCommonLinkage(getLinkage()); }
|
2016-05-11 15:51:39 +02:00
|
|
|
bool hasValidDeclarationLinkage() const {
|
|
|
|
return isValidDeclarationLinkage(getLinkage());
|
|
|
|
}
|
2010-03-06 08:22:39 +01:00
|
|
|
|
2014-05-08 01:00:22 +02:00
|
|
|
void setLinkage(LinkageTypes LT) {
|
2014-05-20 21:00:58 +02:00
|
|
|
if (isLocalLinkage(LT))
|
|
|
|
Visibility = DefaultVisibility;
|
2014-05-08 01:00:22 +02:00
|
|
|
Linkage = LT;
|
|
|
|
}
|
2016-02-26 19:08:59 +01:00
|
|
|
LinkageTypes getLinkage() const { return LinkageTypes(Linkage); }
|
2010-03-06 08:22:39 +01:00
|
|
|
|
2012-06-15 00:48:13 +02:00
|
|
|
bool isDiscardableIfUnused() const {
|
2016-02-26 19:08:59 +01:00
|
|
|
return isDiscardableIfUnused(getLinkage());
|
2012-06-15 00:48:13 +02:00
|
|
|
}
|
|
|
|
|
2016-02-26 19:08:59 +01:00
|
|
|
bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); }
|
2010-03-06 08:22:39 +01:00
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// Copy all additional attributes (those not needed to create a GlobalValue)
|
|
|
|
/// from the GlobalValue Src to this one.
|
2008-05-26 21:58:59 +02:00
|
|
|
virtual void copyAttributesFrom(const GlobalValue *Src);
|
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// If special LLVM prefix that is used to inform the asm printer to not emit
|
|
|
|
/// usual symbol prefix before the symbol name is used then return linkage
|
|
|
|
/// name after skipping this special LLVM prefix.
|
2013-06-01 19:51:14 +02:00
|
|
|
static StringRef getRealLinkageName(StringRef Name) {
|
|
|
|
if (!Name.empty() && Name[0] == '\1')
|
|
|
|
return Name.substr(1);
|
|
|
|
return Name;
|
|
|
|
}
|
|
|
|
|
2016-03-15 03:13:19 +01:00
|
|
|
/// Return the modified name for a global value suitable to be
|
|
|
|
/// used as the key for a global lookup (e.g. profile or ThinLTO).
|
|
|
|
/// The value's original name is \c Name and has linkage of type
|
|
|
|
/// \c Linkage. The value is defined in module \c FileName.
|
|
|
|
static std::string getGlobalIdentifier(StringRef Name,
|
|
|
|
GlobalValue::LinkageTypes Linkage,
|
|
|
|
StringRef FileName);
|
|
|
|
|
2016-03-25 06:57:41 +01:00
|
|
|
/// Return the modified name for this global value suitable to be
|
|
|
|
/// used as the key for a global lookup (e.g. profile or ThinLTO).
|
2016-04-02 07:25:27 +02:00
|
|
|
std::string getGlobalIdentifier() const;
|
2016-03-25 06:57:41 +01:00
|
|
|
|
2016-04-02 07:07:53 +02:00
|
|
|
/// Declare a type to represent a global unique identifier for a global value.
|
|
|
|
/// This is a 64 bits hash that is used by PGO and ThinLTO to have a compact
|
|
|
|
/// unique way to identify a symbol.
|
|
|
|
using GUID = uint64_t;
|
|
|
|
|
2016-03-15 03:13:19 +01:00
|
|
|
/// Return a 64-bit global unique ID constructed from global value name
|
2016-03-25 06:57:41 +01:00
|
|
|
/// (i.e. returned by getGlobalIdentifier()).
|
2016-04-02 07:07:53 +02:00
|
|
|
static GUID getGUID(StringRef GlobalName) { return MD5Hash(GlobalName); }
|
2016-03-15 03:13:19 +01:00
|
|
|
|
2016-03-25 06:57:41 +01:00
|
|
|
/// Return a 64-bit global unique ID constructed from global value name
|
|
|
|
/// (i.e. returned by getGlobalIdentifier()).
|
2016-04-02 07:25:27 +02:00
|
|
|
GUID getGUID() const { return getGUID(getGlobalIdentifier()); }
|
2016-03-25 06:57:41 +01:00
|
|
|
|
2016-03-15 03:13:19 +01:00
|
|
|
/// @name Materialization
|
|
|
|
/// Materialization is used to construct functions only as they're needed.
|
|
|
|
/// This
|
|
|
|
/// is useful to reduce memory usage in LLVM or parsing work done by the
|
|
|
|
/// BitcodeReader to load the Module.
|
|
|
|
/// @{
|
2010-01-27 21:34:15 +01:00
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// If this function's Module is being lazily streamed in functions from disk
|
|
|
|
/// or some other source, this method can be used to check to see if the
|
|
|
|
/// function has been read in yet or not.
|
2010-01-27 21:34:15 +01:00
|
|
|
bool isMaterializable() const;
|
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// Make sure this GlobalValue is fully read. If the module is corrupt, this
|
|
|
|
/// returns true and fills in the optional string with information about the
|
|
|
|
/// problem. If successful, this returns false.
|
2014-10-25 00:50:48 +02:00
|
|
|
std::error_code materialize();
|
2010-01-27 21:34:15 +01:00
|
|
|
|
|
|
|
/// @}
|
2004-11-16 00:20:19 +01:00
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// Return true if the primary definition of this global value is outside of
|
|
|
|
/// the current translation unit.
|
2011-07-14 20:10:41 +02:00
|
|
|
bool isDeclaration() const;
|
2002-10-10 01:11:33 +02:00
|
|
|
|
2014-10-24 20:13:04 +02:00
|
|
|
bool isDeclarationForLinker() const {
|
|
|
|
if (hasAvailableExternallyLinkage())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return isDeclaration();
|
|
|
|
}
|
|
|
|
|
2015-07-05 22:52:35 +02:00
|
|
|
/// Returns true if this global's definition will be the one chosen by the
|
|
|
|
/// linker.
|
Don't IPO over functions that can be de-refined
Summary:
Fixes PR26774.
If you're aware of the issue, feel free to skip the "Motivation"
section and jump directly to "This patch".
Motivation:
I define "refinement" as discarding behaviors from a program that the
optimizer has license to discard. So transforming:
```
void f(unsigned x) {
unsigned t = 5 / x;
(void)t;
}
```
to
```
void f(unsigned x) { }
```
is refinement, since the behavior went from "if x == 0 then undefined
else nothing" to "nothing" (the optimizer has license to discard
undefined behavior).
Refinement is a fundamental aspect of many mid-level optimizations done
by LLVM. For instance, transforming `x == (x + 1)` to `false` also
involves refinement since the expression's value went from "if x is
`undef` then { `true` or `false` } else { `false` }" to "`false`" (by
definition, the optimizer has license to fold `undef` to any non-`undef`
value).
Unfortunately, refinement implies that the optimizer cannot assume
that the implementation of a function it can see has all of the
behavior an unoptimized or a differently optimized version of the same
function can have. This is a problem for functions with comdat
linkage, where a function can be replaced by an unoptimized or a
differently optimized version of the same source level function.
For instance, FunctionAttrs cannot assume a comdat function is
actually `readnone` even if it does not have any loads or stores in
it; since there may have been loads and stores in the "original
function" that were refined out in the currently visible variant, and
at the link step the linker may in fact choose an implementation with
a load or a store. As an example, consider a function that does two
atomic loads from the same memory location, and writes to memory only
if the two values are not equal. The optimizer is allowed to refine
this function by first CSE'ing the two loads, and the folding the
comparision to always report that the two values are equal. Such a
refined variant will look like it is `readonly`. However, the
unoptimized version of the function can still write to memory (since
the two loads //can// result in different values), and selecting the
unoptimized version at link time will retroactively invalidate
transforms we may have done under the assumption that the function
does not write to memory.
Note: this is not just a problem with atomics or with linking
differently optimized object files. See PR26774 for more realistic
examples that involved neither.
This patch:
This change introduces a new set of linkage types, predicated as
`GlobalValue::mayBeDerefined` that returns true if the linkage type
allows a function to be replaced by a differently optimized variant at
link time. It then changes a set of IPO passes to bail out if they see
such a function.
Reviewers: chandlerc, hfinkel, dexonsmith, joker.eph, rnk
Subscribers: mcrosier, llvm-commits
Differential Revision: http://reviews.llvm.org/D18634
llvm-svn: 265762
2016-04-08 02:48:30 +02:00
|
|
|
///
|
|
|
|
/// NB! Ideally this should not be used at the IR level at all. If you're
|
|
|
|
/// interested in optimization constraints implied by the linker's ability to
|
|
|
|
/// choose an implementation, prefer using \c hasExactDefinition.
|
2015-07-05 22:52:35 +02:00
|
|
|
bool isStrongDefinitionForLinker() const {
|
|
|
|
return !(isDeclarationForLinker() || isWeakForLinker());
|
|
|
|
}
|
|
|
|
|
2016-01-15 17:33:06 +01:00
|
|
|
// Returns true if the alignment of the value can be unilaterally
|
|
|
|
// increased.
|
|
|
|
bool canIncreaseAlignment() const;
|
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// This method unlinks 'this' from the containing module, but does not delete
|
|
|
|
/// it.
|
2008-08-29 09:30:15 +02:00
|
|
|
virtual void removeFromParent() = 0;
|
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// This method unlinks 'this' from the containing module and deletes it.
|
2008-08-29 09:30:15 +02:00
|
|
|
virtual void eraseFromParent() = 0;
|
|
|
|
|
2014-05-07 19:04:45 +02:00
|
|
|
/// Get the module that this global value is contained inside of...
|
2015-04-02 20:55:32 +02:00
|
|
|
Module *getParent() { return Parent; }
|
|
|
|
const Module *getParent() const { return Parent; }
|
2001-10-03 21:28:15 +02:00
|
|
|
|
2001-10-03 16:53:21 +02:00
|
|
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
2015-04-02 20:55:32 +02:00
|
|
|
static bool classof(const Value *V) {
|
2007-04-13 20:12:09 +02:00
|
|
|
return V->getValueID() == Value::FunctionVal ||
|
2007-04-25 16:27:10 +02:00
|
|
|
V->getValueID() == Value::GlobalVariableVal ||
|
2016-04-07 14:32:19 +02:00
|
|
|
V->getValueID() == Value::GlobalAliasVal ||
|
|
|
|
V->getValueID() == Value::GlobalIFuncVal;
|
2001-10-03 16:53:21 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-06-23 11:49:53 +02:00
|
|
|
} // End llvm namespace
|
2003-11-11 23:41:34 +01:00
|
|
|
|
2001-10-03 16:53:21 +02:00
|
|
|
#endif
|