diff options
Diffstat (limited to 'llvm/lib/Transforms/IPO/MergeFunctions.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/MergeFunctions.cpp | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp index 9cc1598..d2443a8 100644 --- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp +++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp @@ -283,9 +283,10 @@ private: // Replace G with an alias to F (deleting function G) void writeAlias(Function *F, Function *G); - // Replace G with an alias to F if possible, or a thunk to F if possible. - // Returns false if neither is the case. - bool writeThunkOrAlias(Function *F, Function *G); + // If needed, replace G with an alias to F if possible, or a thunk to F if + // profitable. Returns false if neither is the case. If \p G is not needed + // (i.e. it is discardable and not used), \p G is removed directly. + bool writeThunkOrAliasIfNeeded(Function *F, Function *G); /// Replace function F with function G in the function tree. void replaceFunctionInTree(const FunctionNode &FN, Function *G); @@ -875,9 +876,14 @@ void MergeFunctions::writeAlias(Function *F, Function *G) { ++NumAliasesWritten; } -// Replace G with an alias to F if possible, or a thunk to F if -// profitable. Returns false if neither is the case. -bool MergeFunctions::writeThunkOrAlias(Function *F, Function *G) { +// If needed, replace G with an alias to F if possible, or a thunk to F if +// profitable. Returns false if neither is the case. If \p G is not needed (i.e. +// it is discardable and unused), \p G is removed directly. +bool MergeFunctions::writeThunkOrAliasIfNeeded(Function *F, Function *G) { + if (G->isDiscardableIfUnused() && G->use_empty() && !MergeFunctionsPDI) { + G->eraseFromParent(); + return true; + } if (canCreateAliasFor(G)) { writeAlias(F, G); return true; @@ -904,9 +910,10 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) { assert((!isODR(G) || isODR(F)) && "if G is ODR, F must also be ODR due to ordering"); - // Both writeThunkOrAlias() calls below must succeed, either because we can - // create aliases for G and NewF, or because a thunk for F is profitable. - // F here has the same signature as NewF below, so that's what we check. + // Both writeThunkOrAliasIfNeeded() calls below must succeed, either because + // we can create aliases for G and NewF, or because a thunk for F is + // profitable. F here has the same signature as NewF below, so that's what + // we check. if (!canCreateThunkFor(F) && (!canCreateAliasFor(F) || !canCreateAliasFor(G))) return; @@ -930,13 +937,13 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) { if (isODR(F)) replaceDirectCallers(NewF, F); - // We collect alignment before writeThunkOrAlias that overwrites NewF and - // G's content. + // We collect alignment before writeThunkOrAliasIfNeeded that overwrites + // NewF and G's content. const MaybeAlign NewFAlign = NewF->getAlign(); const MaybeAlign GAlign = G->getAlign(); - writeThunkOrAlias(F, G); - writeThunkOrAlias(F, NewF); + writeThunkOrAliasIfNeeded(F, G); + writeThunkOrAliasIfNeeded(F, NewF); if (NewFAlign || GAlign) F->setAlignment(std::max(NewFAlign.valueOrOne(), GAlign.valueOrOne())); @@ -975,7 +982,7 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) { return; } - if (writeThunkOrAlias(F, G)) { + if (writeThunkOrAliasIfNeeded(F, G)) { ++NumFunctionsMerged; } } |