From 791c9f1145f89d0ad8daddcc2207a8cdacbadaa0 Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Wed, 29 Jan 2020 18:02:42 -0600 Subject: [PATCH] [Attributor] Fix TODO to avoid recomputation of results The helpers AAReturnedFromReturnedValues and AACallSiteReturnedFromReturned are useful not only to avoid code duplication but also to avoid recomputation of results. If we have N call sites we should not recompute the function return information N times but once. These are mostly straightforward usages with some minor improvements on the helpers and addition of a new one (IRPosition::getAssociatedType) that knows about function return types. --- llvm/include/llvm/Transforms/IPO/Attributor.h | 12 ++++- llvm/lib/Transforms/IPO/Attributor.cpp | 52 ++++++++----------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index f224d3c7ca9a..a8e83673f196 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -332,6 +332,15 @@ struct IRPosition { return *cast(AnchorVal)->getArgOperand(getArgNo()); } + /// Return the type this abstract attribute is associated with. + Type *getAssociatedType() const { + assert(KindOrArgNo != IRP_INVALID && + "Invalid position does not have an associated type!"); + if (getPositionKind() == IRPosition::IRP_RETURNED) + return getAssociatedFunction()->getReturnType(); + return getAssociatedValue().getType(); + } + /// Return the argument number of the associated value if it is an argument or /// call site argument, otherwise a negative value. int getArgNo() const { return KindOrArgNo; } @@ -2447,8 +2456,7 @@ struct AAValueConstantRange : public IntegerRangeState, public AbstractAttribute, public IRPosition { AAValueConstantRange(const IRPosition &IRP) - : IntegerRangeState( - IRP.getAssociatedValue().getType()->getIntegerBitWidth()), + : IntegerRangeState(IRP.getAssociatedType()->getIntegerBitWidth()), IRPosition(IRP) {} /// Return an IR position, see struct IRPosition. diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 64238ca58771..c055e18902c6 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -740,13 +740,13 @@ struct AAComposeTwoGenericDeduction /// Helper class for generic deduction: return value -> returned position. template + typename StateType = typename Base::StateType> struct AAReturnedFromReturnedValues : public Base { AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {} /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { - StateType S; + StateType S(StateType::getBestState(this->getState())); clampReturnedValueStates(A, *this, S); // TODO: If we know we visited all returned values, thus no are assumed // dead, we can take the known information from the state T. @@ -817,7 +817,7 @@ struct AAArgumentFromCallSiteArguments : public Base { /// Helper class for generic replication: function returned -> cs returned. template + typename StateType = typename Base::StateType> struct AACallSiteReturnedFromReturned : public Base { AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {} @@ -837,7 +837,7 @@ struct AACallSiteReturnedFromReturned : public Base { IRPosition FnPos = IRPosition::returned(*AssociatedFunction); const AAType &AA = A.getAAFor(*this, FnPos); return clampStateAndIndicateChange( - S, static_cast(AA.getState())); + S, static_cast(AA.getState())); } }; @@ -3440,11 +3440,10 @@ struct AADereferenceableFloating /// Dereferenceable attribute for a return value. struct AADereferenceableReturned final - : AAReturnedFromReturnedValues { + : AAReturnedFromReturnedValues { AADereferenceableReturned(const IRPosition &IRP) - : AAReturnedFromReturnedValues(IRP) {} + : AAReturnedFromReturnedValues( + IRP) {} /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -3455,9 +3454,9 @@ struct AADereferenceableReturned final /// Dereferenceable attribute for an argument struct AADereferenceableArgument final : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext< - AADereferenceable, AADereferenceableImpl, DerefState> { + AADereferenceable, AADereferenceableImpl> { using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext< - AADereferenceable, AADereferenceableImpl, DerefState>; + AADereferenceable, AADereferenceableImpl>; AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {} /// See AbstractAttribute::trackStatistics() @@ -5463,23 +5462,15 @@ struct AAValueConstantRangeArgument final } }; -struct AAValueConstantRangeReturned : AAValueConstantRangeImpl { - AAValueConstantRangeReturned(const IRPosition &IRP) - : AAValueConstantRangeImpl(IRP) {} +struct AAValueConstantRangeReturned + : AAReturnedFromReturnedValues { + using Base = AAReturnedFromReturnedValues; + AAValueConstantRangeReturned(const IRPosition &IRP) : Base(IRP) {} - /// See AbstractAttribute::updateImpl(...). - ChangeStatus updateImpl(Attributor &A) override { - // TODO: Use AAReturnedFromReturnedValues - - // TODO: If we know we visited all returned values, thus no are assumed - // dead, we can take the known information from the state T. - - IntegerRangeState S(getBitWidth()); - - clampReturnedValueStates(A, *this, - S); - return clampStateAndIndicateChange(this->getState(), S); - } + /// See AbstractAttribute::initialize(...). + void initialize(Attributor &A) override {} /// See AbstractAttribute::trackStatistics() void trackStatistics() const override { @@ -5668,9 +5659,12 @@ struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction { void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) } }; -struct AAValueConstantRangeCallSiteReturned : AAValueConstantRangeReturned { +struct AAValueConstantRangeCallSiteReturned + : AACallSiteReturnedFromReturned { AAValueConstantRangeCallSiteReturned(const IRPosition &IRP) - : AAValueConstantRangeReturned(IRP) {} + : AACallSiteReturnedFromReturned(IRP) {} /// See AbstractAttribute::initialize(...). void initialize(Attributor &A) override { @@ -5679,7 +5673,7 @@ struct AAValueConstantRangeCallSiteReturned : AAValueConstantRangeReturned { if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range)) intersectKnown(getConstantRangeFromMetadata(*RangeMD)); - AAValueConstantRangeReturned::initialize(A); + AAValueConstantRangeImpl::initialize(A); } /// See AbstractAttribute::trackStatistics()