diff options
author | Johannes Doerfert <jdoerfert@anl.gov> | 2019-08-05 23:22:05 +0000 |
---|---|---|
committer | Johannes Doerfert <jdoerfert@anl.gov> | 2019-08-05 23:22:05 +0000 |
commit | e83f303938a5aa2f43ba1dbe024b16fec06f20cc (patch) | |
tree | e29d54da9aa01be3edf1b9eebd4c2df5d8562369 /llvm/lib/Transforms/IPO/Attributor.cpp | |
parent | a5c25c5d469f0f9999610bb391bd156eb70e7975 (diff) | |
download | bcm5719-llvm-e83f303938a5aa2f43ba1dbe024b16fec06f20cc.tar.gz bcm5719-llvm-e83f303938a5aa2f43ba1dbe024b16fec06f20cc.zip |
[Attributor] Deduce the "no-return" attribute for functions
A function is "no-return" if we never reach a return instruction, either
because there are none or the ones that exist are dead.
Test have been adjusted:
- either noreturn was added, or
- noreturn was avoided by modifying the code.
The new noreturn_{sync,async} test make sure we do handle invoke
instructions with a noreturn (and potentially nowunwind) callee
correctly, even in the presence of potential asynchronous exceptions.
llvm-svn: 367948
Diffstat (limited to 'llvm/lib/Transforms/IPO/Attributor.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/Attributor.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 3ecad8b03eb..dc6bcb59d5d 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -76,6 +76,7 @@ STATISTIC(NumCSArgumentDereferenceable, STATISTIC(NumFnReturnedAlign, "Number of function return values marked align"); STATISTIC(NumFnArgumentAlign, "Number of function arguments marked align"); STATISTIC(NumCSArgumentAlign, "Number of call site arguments marked align"); +STATISTIC(NumFnNoReturn, "Number of functions marked noreturn"); // TODO: Determine a good default value. // @@ -179,6 +180,9 @@ static void bookkeeping(AbstractAttribute::ManifestPosition MP, case Attribute::WillReturn: NumFnWillReturn++; break; + case Attribute::NoReturn: + NumFnNoReturn++; + return; case Attribute::NoAlias: NumFnArgumentNoAlias++; return; @@ -2336,6 +2340,60 @@ ChangeStatus AAAlignCallSiteArgument::updateImpl(Attributor &A) { : ChangeStatus::CHANGED; } +/// ------------------ Function No-Return Attribute ---------------------------- +struct AANoReturnFunction final : public AANoReturn, BooleanState { + + AANoReturnFunction(Function &F, InformationCache &InfoCache) + : AANoReturn(F, InfoCache) {} + + /// See AbstractAttribute::getState() + /// { + AbstractState &getState() override { return *this; } + const AbstractState &getState() const override { return *this; } + /// } + + /// Return true if the underlying object is known to never return. + bool isKnownNoReturn() const override { return getKnown(); } + + /// Return true if the underlying object is assumed to never return. + bool isAssumedNoReturn() const override { return getAssumed(); } + + /// See AbstractAttribute::getManifestPosition(). + ManifestPosition getManifestPosition() const override { return MP_FUNCTION; } + + /// See AbstractAttribute::getAsStr(). + const std::string getAsStr() const override { + return getAssumed() ? "noreturn" : "may-return"; + } + + /// See AbstractAttribute::initialize(...). + void initialize(Attributor &A) override { + Function &F = getAnchorScope(); + if (F.hasFnAttribute(getAttrKind())) + indicateOptimisticFixpoint(); + } + + /// See AbstractAttribute::updateImpl(Attributor &A). + virtual ChangeStatus updateImpl(Attributor &A) override { + Function &F = getAnchorScope(); + + // The map from instruction opcodes to those instructions in the function. + auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F); + + // Look at all return instructions. + auto &ReturnInsts = OpcodeInstMap[Instruction::Ret]; + if (ReturnInsts.empty()) + return indicateOptimisticFixpoint(); + + auto *LivenessAA = A.getAAFor<AAIsDead>(*this, F); + if (!LivenessAA || + LivenessAA->isLiveInstSet(ReturnInsts.begin(), ReturnInsts.end())) + return indicatePessimisticFixpoint(); + + return ChangeStatus::UNCHANGED; + } +}; + /// ---------------------------------------------------------------------------- /// Attributor /// ---------------------------------------------------------------------------- @@ -2539,6 +2597,9 @@ void Attributor::identifyDefaultAbstractAttributes( // Every function might be "no-free". registerAA(*new AANoFreeFunction(F, InfoCache)); + // Every function might be "no-return". + registerAA(*new AANoReturnFunction(F, InfoCache)); + // Return attributes are only appropriate if the return type is non void. Type *ReturnType = F.getReturnType(); if (!ReturnType->isVoidTy()) { |