diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -260,10 +260,14 @@ /// and all varargs at the callsite will be passed to any calls to /// ForwardVarArgsTo. The caller of InlineFunction has to make sure any varargs /// are only used by ForwardVarArgsTo. +/// +/// The callee's function attributes are merged into the callers' if +/// MergeAttributes is set to true. InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, AAResults *CalleeAAR = nullptr, bool InsertLifetime = true, - Function *ForwardVarArgsTo = nullptr); + Function *ForwardVarArgsTo = nullptr, + bool MergeAttributes = false); /// Clones a loop \p OrigLoop. Returns the loop and the blocks in \p /// Blocks. diff --git a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp --- a/llvm/lib/Transforms/IPO/AlwaysInliner.cpp +++ b/llvm/lib/Transforms/IPO/AlwaysInliner.cpp @@ -71,7 +71,9 @@ &FAM.getResult(F)); InlineResult Res = InlineFunction( - *CB, IFI, &FAM.getResult(F), InsertLifetime); + *CB, IFI, &FAM.getResult(F), InsertLifetime, + /*ForwardVarArgsTo=*/nullptr, + /*MergeAttributes=*/true); if (!Res.isSuccess()) { ORE.emit([&]() { return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, @@ -88,9 +90,6 @@ InlineCost::getAlways("always inline attribute"), /*ForProfileContext=*/false, DEBUG_TYPE); - // Merge the attributes based on the inlining. - AttributeFuncs::mergeAttributesForInlining(*Caller, F); - Changed = true; } diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -315,15 +315,15 @@ // Try to inline the function. Get the list of static allocas that were // inlined. - InlineResult IR = InlineFunction(CB, IFI, &AAR, InsertLifetime); + InlineResult IR = InlineFunction(CB, IFI, &AAR, InsertLifetime, + /*ForwardVarArgsTo=*/nullptr, + /*MergeAttributes=*/true); if (!IR.isSuccess()) return IR; if (InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No) ImportedFunctionsStats.recordInline(*Caller, *Callee); - AttributeFuncs::mergeAttributesForInlining(*Caller, *Callee); - if (!DisableInlinedAllocaMerging) mergeInlinedArrayAllocas(Caller, IFI, InlinedArrayAllocas, InlineHistory); @@ -915,7 +915,10 @@ &FAM.getResult(Callee)); InlineResult IR = - InlineFunction(*CB, IFI, &FAM.getResult(*CB->getCaller())); + InlineFunction(*CB, IFI, &FAM.getResult(*CB->getCaller()), + /*InsertLifetime=*/true, + /*ForwardVarArgsTo=*/nullptr, + /*MergeAttributes=*/true); if (!IR.isSuccess()) { Advice->recordUnsuccessfulInlining(IR); continue; @@ -970,9 +973,6 @@ } } - // Merge the attributes based on the inlining. - AttributeFuncs::mergeAttributesForInlining(F, Callee); - // For local functions or discardable functions without comdats, check // whether this makes the callee trivially dead. In that case, we can drop // the body of the function eagerly which may reduce the number of callers diff --git a/llvm/lib/Transforms/IPO/ModuleInliner.cpp b/llvm/lib/Transforms/IPO/ModuleInliner.cpp --- a/llvm/lib/Transforms/IPO/ModuleInliner.cpp +++ b/llvm/lib/Transforms/IPO/ModuleInliner.cpp @@ -218,7 +218,10 @@ &FAM.getResult(Callee)); InlineResult IR = - InlineFunction(*CB, IFI, &FAM.getResult(*CB->getCaller())); + InlineFunction(*CB, IFI, &FAM.getResult(*CB->getCaller()), + /*InsertLifetime=*/true, + /*ForwardVarArgsTo=*/nullptr, + /*MergeAttributes=*/true); if (!IR.isSuccess()) { Advice->recordUnsuccessfulInlining(IR); continue; @@ -251,9 +254,6 @@ } } - // Merge the attributes based on the inlining. - AttributeFuncs::mergeAttributesForInlining(F, Callee); - // For local functions, check whether this makes the callee trivially // dead. In that case, we can drop the body of the function eagerly // which may reduce the number of callers of other functions to one, diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -1221,13 +1221,14 @@ InlineFunctionInfo IFI(nullptr, GetAC); IFI.UpdateProfile = false; - if (!InlineFunction(CB, IFI).isSuccess()) + InlineResult IR = InlineFunction(CB, IFI, + /*CalleeAAR=*/nullptr, + /*InsertLifetime=*/true, + /*ForwardVarArgsTo=*/nullptr, + /*MergeAttributes=*/true); + if (!IR.isSuccess()) return false; - // Merge the attributes based on the inlining. - AttributeFuncs::mergeAttributesForInlining(*BB->getParent(), - *CalledFunction); - // The call to InlineFunction erases I, so we can't pass it here. emitInlinedIntoBasedOnCost(*ORE, DLoc, BB, *CalledFunction, *BB->getParent(), Cost, true, getAnnotatedRemarkPassName()); diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1786,7 +1786,8 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, AAResults *CalleeAAR, bool InsertLifetime, - Function *ForwardVarArgsTo) { + Function *ForwardVarArgsTo, + bool MergeAttributes) { assert(CB.getParent() && CB.getFunction() && "Instruction not in function!"); // FIXME: we don't inline callbr yet. @@ -2509,6 +2510,9 @@ // Since we are now done with the return instruction, delete it also. Returns[0]->eraseFromParent(); + if (MergeAttributes) + AttributeFuncs::mergeAttributesForInlining(*Caller, *CalledFunc); + // We are now done with the inlining. return InlineResult::success(); } @@ -2672,5 +2676,8 @@ } } + if (MergeAttributes) + AttributeFuncs::mergeAttributesForInlining(*Caller, *CalledFunc); + return InlineResult::success(); }