mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-28 19:25:00 +00:00
IR: Do not consider available_externally linkage to be linker-weak.
From the linker's perspective, an available_externally global is equivalent to an external declaration (per isDeclarationForLinker()), so it is incorrect to consider it to be a weak definition. Also clean up some logic in the dead argument elimination pass and clarify its comments to better explain how its behavior depends on linkage, introduce GlobalValue::isStrongDefinitionForLinker() and start using it throughout the optimizers and backend. Differential Revision: http://reviews.llvm.org/D10941 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241413 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -326,7 +326,18 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
|
||||
/// instead.
|
||||
bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn)
|
||||
{
|
||||
if (Fn.isDeclaration() || Fn.mayBeOverridden())
|
||||
// We cannot change the arguments if this TU does not define the function or
|
||||
// if the linker may choose a function body from another TU, even if the
|
||||
// nominal linkage indicates that other copies of the function have the same
|
||||
// semantics. In the below example, the dead load from %p may not have been
|
||||
// eliminated from the linker-chosen copy of f, so replacing %p with undef
|
||||
// in callers may introduce undefined behavior.
|
||||
//
|
||||
// define linkonce_odr void @f(i32* %p) {
|
||||
// %v = load i32 %p
|
||||
// ret void
|
||||
// }
|
||||
if (!Fn.isStrongDefinitionForLinker())
|
||||
return false;
|
||||
|
||||
// Functions with local linkage should already have been handled, except the
|
||||
@@ -334,19 +345,6 @@ bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn)
|
||||
if (Fn.hasLocalLinkage() && !Fn.getFunctionType()->isVarArg())
|
||||
return false;
|
||||
|
||||
// If a function seen at compile time is not necessarily the one linked to
|
||||
// the binary being built, it is illegal to change the actual arguments
|
||||
// passed to it. These functions can be captured by isWeakForLinker().
|
||||
// *NOTE* that mayBeOverridden() is insufficient for this purpose as it
|
||||
// doesn't include linkage types like AvailableExternallyLinkage and
|
||||
// LinkOnceODRLinkage. Take link_odr* as an example, it indicates a set of
|
||||
// *EQUIVALENT* globals that can be merged at link-time. However, the
|
||||
// semantic of *EQUIVALENT*-functions includes parameters. Changing
|
||||
// parameters breaks this assumption.
|
||||
//
|
||||
if (Fn.isWeakForLinker())
|
||||
return false;
|
||||
|
||||
if (Fn.use_empty())
|
||||
return false;
|
||||
|
||||
|
Reference in New Issue
Block a user