summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/IPO/MergeFunctions.cpp
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2019-01-19 02:46:22 +0000
committerVedant Kumar <vsk@apple.com>2019-01-19 02:46:22 +0000
commitb537b946b82f7e2c52ad16cf3fbff93345ee4993 (patch)
tree7e5a7c7b578d85bf1a89453f8b781f19e05ff7c6 /llvm/lib/Transforms/IPO/MergeFunctions.cpp
parentb755a2df5123a2b970733c43c9e65326b73d99c7 (diff)
downloadbcm5719-llvm-b537b946b82f7e2c52ad16cf3fbff93345ee4993.tar.gz
bcm5719-llvm-b537b946b82f7e2c52ad16cf3fbff93345ee4993.zip
[MergeFunc] Allow merging identical vararg functions using aliases
Thanks to Nikita Popov for pointing out this missed case. This is a follow-up to r351411, which disabled function merging for vararg functions outright due to a miscompile (see llvm.org/PR40345). Differential Revision: https://reviews.llvm.org/D56865 llvm-svn: 351624
Diffstat (limited to 'llvm/lib/Transforms/IPO/MergeFunctions.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/MergeFunctions.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
index 26b204f61cb..f143b252b5f 100644
--- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
@@ -281,8 +281,8 @@ 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
- // profitable. Returns false if neither is the case.
+ // 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);
/// Replace function F with function G in the function tree.
@@ -385,8 +385,7 @@ bool MergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) {
/// Check whether \p F is eligible for function merging.
static bool isEligibleForMerging(Function &F) {
- return !F.isDeclaration() && !F.hasAvailableExternallyLinkage() &&
- !F.isVarArg();
+ return !F.isDeclaration() && !F.hasAvailableExternallyLinkage();
}
bool MergeFunctions::runOnModule(Module &M) {
@@ -660,12 +659,16 @@ void MergeFunctions::filterInstsUnrelatedToPDI(
LLVM_DEBUG(dbgs() << " }\n");
}
-// Don't merge tiny functions using a thunk, since it can just end up
-// making the function larger.
-static bool isThunkProfitable(Function * F) {
+/// Whether this function may be replaced by a forwarding thunk.
+static bool canCreateThunkFor(Function *F) {
+ if (F->isVarArg())
+ return false;
+
+ // Don't merge tiny functions using a thunk, since it can just end up
+ // making the function larger.
if (F->size() == 1) {
if (F->front().size() <= 2) {
- LLVM_DEBUG(dbgs() << "isThunkProfitable: " << F->getName()
+ LLVM_DEBUG(dbgs() << "canCreateThunkFor: " << F->getName()
<< " is too small to bother creating a thunk for\n");
return false;
}
@@ -793,7 +796,7 @@ bool MergeFunctions::writeThunkOrAlias(Function *F, Function *G) {
writeAlias(F, G);
return true;
}
- if (isThunkProfitable(F)) {
+ if (canCreateThunkFor(F)) {
writeThunk(F, G);
return true;
}
@@ -808,9 +811,9 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) {
// 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.
- if (!isThunkProfitable(F) && (!canCreateAliasFor(F) || !canCreateAliasFor(G))) {
+ if (!canCreateThunkFor(F) &&
+ (!canCreateAliasFor(F) || !canCreateAliasFor(G)))
return;
- }
// Make them both thunks to the same internal function.
Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(),
OpenPOWER on IntegriCloud