[Transforms] Merge function attributes within InlineFunction (NFC)

In the past, we've had a bug resulting in a compiler crash after
forgetting to merge function attributes (D105729).

This patch teaches InlineFunction to merge function attributes.  This
way, we minimize the "time" when the IR is valid, but the function
attributes are not.

Differential Revision: https://reviews.llvm.org/D134117
This commit is contained in:
Kazu Hirata 2022-09-17 23:10:23 -07:00
parent cf355bf36e
commit 284f0397e2
6 changed files with 33 additions and 22 deletions

View File

@ -260,10 +260,14 @@ public:
/// 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.

View File

@ -71,7 +71,9 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
&FAM.getResult<BlockFrequencyAnalysis>(F));
InlineResult Res = InlineFunction(
*CB, IFI, &FAM.getResult<AAManager>(F), InsertLifetime);
*CB, IFI, &FAM.getResult<AAManager>(F), InsertLifetime,
/*ForwardVarArgsTo=*/nullptr,
/*MergeAttributes=*/true);
if (!Res.isSuccess()) {
ORE.emit([&]() {
return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc,
@ -88,9 +90,6 @@ PreservedAnalyses AlwaysInlinerPass::run(Module &M,
InlineCost::getAlways("always inline attribute"),
/*ForProfileContext=*/false, DEBUG_TYPE);
// Merge the attributes based on the inlining.
AttributeFuncs::mergeAttributesForInlining(*Caller, F);
Changed = true;
}

View File

@ -315,15 +315,15 @@ static InlineResult inlineCallIfPossible(
// 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 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
&FAM.getResult<BlockFrequencyAnalysis>(Callee));
InlineResult IR =
InlineFunction(*CB, IFI, &FAM.getResult<AAManager>(*CB->getCaller()));
InlineFunction(*CB, IFI, &FAM.getResult<AAManager>(*CB->getCaller()),
/*InsertLifetime=*/true,
/*ForwardVarArgsTo=*/nullptr,
/*MergeAttributes=*/true);
if (!IR.isSuccess()) {
Advice->recordUnsuccessfulInlining(IR);
continue;
@ -970,9 +973,6 @@ PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
}
}
// 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

View File

@ -218,7 +218,10 @@ PreservedAnalyses ModuleInlinerPass::run(Module &M,
&FAM.getResult<BlockFrequencyAnalysis>(Callee));
InlineResult IR =
InlineFunction(*CB, IFI, &FAM.getResult<AAManager>(*CB->getCaller()));
InlineFunction(*CB, IFI, &FAM.getResult<AAManager>(*CB->getCaller()),
/*InsertLifetime=*/true,
/*ForwardVarArgsTo=*/nullptr,
/*MergeAttributes=*/true);
if (!IR.isSuccess()) {
Advice->recordUnsuccessfulInlining(IR);
continue;
@ -251,9 +254,6 @@ PreservedAnalyses ModuleInlinerPass::run(Module &M,
}
}
// 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,

View File

@ -1221,13 +1221,14 @@ bool SampleProfileLoader::tryInlineCandidate(
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());

View File

@ -1786,7 +1786,8 @@ inlineRetainOrClaimRVCalls(CallBase &CB, objcarc::ARCInstKind RVCallKind,
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 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
// 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 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
}
}
if (MergeAttributes)
AttributeFuncs::mergeAttributesForInlining(*Caller, *CalledFunc);
return InlineResult::success();
}