Index: lib/Transforms/IPO/MergeFunctions.cpp =================================================================== --- lib/Transforms/IPO/MergeFunctions.cpp +++ lib/Transforms/IPO/MergeFunctions.cpp @@ -647,6 +647,16 @@ return; } + // Don't merge tiny functions using a thunk, since it can just end up + // making the function larger. + if (G->size() == 1) { + if (G->front().size() <= 2) { + DEBUG(dbgs() << "writeThunk: " << G->getName() + << " is too small to bother creating a thunk for\n"); + return; + } + } + BasicBlock *GEntryBlock = nullptr; std::vector PDIUnrelatedWL; BasicBlock *BB = nullptr; @@ -779,18 +789,6 @@ const FunctionNode &OldF = *Result.first; - // Don't merge tiny functions, since it can just end up making the function - // larger. - // FIXME: Should still merge them if they are unnamed_addr and produce an - // alias. - if (NewFunction->size() == 1) { - if (NewFunction->front().size() <= 2) { - DEBUG(dbgs() << NewFunction->getName() - << " is to small to bother merging\n"); - return false; - } - } - // Impose a total order (by name) on the replacement of functions. This is // important when operating on more than one module independently to prevent // cycles of thunks calling each other when the modules are linked together. Index: test/Transforms/MergeFunc/merge-small-unnamed-addr.ll =================================================================== --- /dev/null +++ test/Transforms/MergeFunc/merge-small-unnamed-addr.ll @@ -0,0 +1,14 @@ +; RUN: opt -S -mergefunc < %s | FileCheck %s + +; CHECK-NOT: @b + +@x = constant { void ()*, void ()* } { void ()* @a, void ()* @b } +; CHECK: { void ()* @a, void ()* @a } + +define internal void @a() unnamed_addr { + ret void +} + +define internal void @b() unnamed_addr { + ret void +} Index: test/Transforms/MergeFunc/no-merge-small.ll =================================================================== --- /dev/null +++ test/Transforms/MergeFunc/no-merge-small.ll @@ -0,0 +1,11 @@ +; RUN: opt -S -mergefunc < %s | FileCheck %s + +; CHECK: @a +define void @a() { + ret void +} + +; CHECK: @b +define void @b() { + ret void +}