diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -1134,10 +1134,8 @@ const function_ref &)> &Pred) const = 0; - using iterator = DenseMap>::iterator; using const_iterator = DenseMap>::const_iterator; - virtual llvm::iterator_range returned_values() = 0; virtual llvm::iterator_range returned_values() const = 0; virtual size_t getNumReturnValues() const = 0; 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 @@ -683,13 +683,18 @@ /// return instructions that might return them. DenseMap> ReturnedValues; + /// Mapping to remember the number of returned values for a AAReturnedValues + /// object such that we can avoid updates if nothing changed. + DenseMap NumReturnedValuesPerKnownAA; + + /// Set of unresolved calls returned by the associated function. SmallPtrSet UnresolvedCalls; /// State flags /// ///{ - bool IsFixed; - bool IsValidState; + bool IsFixed = false; + bool IsValidState = true; ///} public: @@ -736,10 +741,6 @@ /// See AbstractAttribute::updateImpl(Attributor &A). ChangeStatus updateImpl(Attributor &A) override; - llvm::iterator_range returned_values() override { - return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end()); - } - llvm::iterator_range returned_values() const override { return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end()); } @@ -775,7 +776,6 @@ /// See AbstractState::indicateOptimisticFixpoint(...). ChangeStatus indicateOptimisticFixpoint() override { IsFixed = true; - IsValidState &= true; return ChangeStatus::UNCHANGED; } @@ -976,6 +976,15 @@ if (Unresolved) continue; + // Now track transitively returned values. + unsigned &NumRetAA = NumReturnedValuesPerKnownAA[&RetValAA]; + if (NumRetAA == RetValAA.getNumReturnValues()) { + LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip RetValAA as it has not " + "changed since it was seen last\n"); + continue; + } + NumRetAA = RetValAA.getNumReturnValues(); + for (auto &RetValAAIt : RetValAA.returned_values()) { Value *RetVal = RetValAAIt.first; if (Argument *Arg = dyn_cast(RetVal)) { @@ -1617,6 +1626,9 @@ Instruction *I = const_cast(NRC); BasicBlock *BB = I->getParent(); Instruction *SplitPos = I->getNextNode(); + // TODO: mark stuff before unreachable instructions as dead. + if (!I->isTerminator() && isa(SplitPos)) + continue; if (auto *II = dyn_cast(I)) { // If we keep the invoke the split position is at the beginning of the @@ -1634,6 +1646,7 @@ if (AANoUnw.isAssumedNoUnwind()) { LLVM_DEBUG(dbgs() << "[AAIsDead] Replace invoke with call inst\n"); + // We do not need an invoke (II) but instead want a call followed // by an unreachable. However, we do not remove II as other // abstract attributes might have it cached as part of their @@ -2676,6 +2689,37 @@ CallSite CS(&I); if (CS && CS.getCalledFunction()) { + Function *Callee = CS.getCalledFunction(); + Type *ReturnType = Callee->getReturnType(); + if (!ReturnType->isVoidTy()) { + + checkAndRegisterAA( + IRPosition::callsite_function(CS), *this, Whitelist); + + if (ReturnType->isPointerTy()) { + IRPosition RetPos = IRPosition::callsite_returned(CS); + + // Every function with pointer call site return type might be marked + // align. + checkAndRegisterAA(RetPos, *this, Whitelist); + + // Every function with pointer call site return type might be marked + // nonnull. + checkAndRegisterAA(RetPos, *this, + Whitelist); + + // Every function with pointer call site return type might be marked + // noalias. + checkAndRegisterAA(RetPos, *this, + Whitelist); + + // Every function with pointer call site return type might be marked + // dereferenceable. + checkAndRegisterAA(RetPos, *this, + Whitelist); + } + } + for (int i = 0, e = CS.getCalledFunction()->arg_size(); i < e; i++) { if (!CS.getArgument(i)->getType()->isPointerTy()) continue; diff --git a/llvm/test/Transforms/FunctionAttrs/align.ll b/llvm/test/Transforms/FunctionAttrs/align.ll --- a/llvm/test/Transforms/FunctionAttrs/align.ll +++ b/llvm/test/Transforms/FunctionAttrs/align.ll @@ -88,7 +88,7 @@ br i1 %2, label %3, label %5 ;