diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -1350,34 +1350,27 @@ // endless loop // FIXME: Any cycle is regarded as endless loop for now. // We have to allow some patterns. -static bool containsPossiblyEndlessLoop(Function &F) { - return containsCycle(F); +static bool containsPossiblyEndlessLoop(Function *F) { + return !F || !F->hasExactDefinition() || containsCycle(*F); } struct AAWillReturnImpl : public AAWillReturn { AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {} - /// See AbstractAttribute::getAsStr() - const std::string getAsStr() const override { - return getAssumed() ? "willreturn" : "may-noreturn"; - } -}; - -struct AAWillReturnFunction final : AAWillReturnImpl { - AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {} - /// See AbstractAttribute::initialize(...). void initialize(Attributor &A) override { - Function &F = *getAnchorScope(); + if (hasAttr({Attribute::WillReturn})) { + indicateOptimisticFixpoint(); + return; + } + Function *F = getAssociatedFunction(); if (containsPossiblyEndlessLoop(F)) indicatePessimisticFixpoint(); } /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { - // The map from instruction opcodes to those instructions in the function. - auto CheckForWillReturn = [&](Instruction &I) { ImmutableCallSite ICS(&I); if (ICS.hasFnAttr(Attribute::WillReturn)) @@ -1402,12 +1395,25 @@ return ChangeStatus::UNCHANGED; } + /// See AbstractAttribute::getAsStr() + const std::string getAsStr() const override { + return getAssumed() ? "willreturn" : "may-noreturn"; + } +}; + +struct AAWillReturnFunction final : AAWillReturnImpl { + AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {} + /// See AbstractAttribute::trackStatistics() - void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) } + void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) } }; -/// WillReturn attribute deduction for a call sites. -using AAWillReturnCallSite = AAWillReturnFunction; +struct AAWillReturnCallSite final : AAWillReturnImpl { + AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {} + + /// See AbstractAttribute::trackStatistics() + void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn) } +}; /// ------------------------ NoAlias Argument Attribute ------------------------