[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.
This commit is contained in:
Johannes Doerfert 2020-01-29 18:02:42 -06:00
parent 91f863be4f
commit 791c9f1145
2 changed files with 33 additions and 31 deletions

View File

@ -332,6 +332,15 @@ struct IRPosition {
return *cast<CallBase>(AnchorVal)->getArgOperand(getArgNo()); return *cast<CallBase>(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 /// Return the argument number of the associated value if it is an argument or
/// call site argument, otherwise a negative value. /// call site argument, otherwise a negative value.
int getArgNo() const { return KindOrArgNo; } int getArgNo() const { return KindOrArgNo; }
@ -2447,8 +2456,7 @@ struct AAValueConstantRange : public IntegerRangeState,
public AbstractAttribute, public AbstractAttribute,
public IRPosition { public IRPosition {
AAValueConstantRange(const IRPosition &IRP) AAValueConstantRange(const IRPosition &IRP)
: IntegerRangeState( : IntegerRangeState(IRP.getAssociatedType()->getIntegerBitWidth()),
IRP.getAssociatedValue().getType()->getIntegerBitWidth()),
IRPosition(IRP) {} IRPosition(IRP) {}
/// Return an IR position, see struct IRPosition. /// Return an IR position, see struct IRPosition.

View File

@ -740,13 +740,13 @@ struct AAComposeTwoGenericDeduction
/// Helper class for generic deduction: return value -> returned position. /// Helper class for generic deduction: return value -> returned position.
template <typename AAType, typename Base, template <typename AAType, typename Base,
typename StateType = typename AAType::StateType> typename StateType = typename Base::StateType>
struct AAReturnedFromReturnedValues : public Base { struct AAReturnedFromReturnedValues : public Base {
AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {} AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
/// See AbstractAttribute::updateImpl(...). /// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override { ChangeStatus updateImpl(Attributor &A) override {
StateType S; StateType S(StateType::getBestState(this->getState()));
clampReturnedValueStates<AAType, StateType>(A, *this, S); clampReturnedValueStates<AAType, StateType>(A, *this, S);
// TODO: If we know we visited all returned values, thus no are assumed // TODO: If we know we visited all returned values, thus no are assumed
// dead, we can take the known information from the state T. // 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. /// Helper class for generic replication: function returned -> cs returned.
template <typename AAType, typename Base, template <typename AAType, typename Base,
typename StateType = typename AAType::StateType> typename StateType = typename Base::StateType>
struct AACallSiteReturnedFromReturned : public Base { struct AACallSiteReturnedFromReturned : public Base {
AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {} AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
@ -837,7 +837,7 @@ struct AACallSiteReturnedFromReturned : public Base {
IRPosition FnPos = IRPosition::returned(*AssociatedFunction); IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
const AAType &AA = A.getAAFor<AAType>(*this, FnPos); const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
return clampStateAndIndicateChange( return clampStateAndIndicateChange(
S, static_cast<const typename AAType::StateType &>(AA.getState())); S, static_cast<const StateType &>(AA.getState()));
} }
}; };
@ -3440,11 +3440,10 @@ struct AADereferenceableFloating
/// Dereferenceable attribute for a return value. /// Dereferenceable attribute for a return value.
struct AADereferenceableReturned final struct AADereferenceableReturned final
: AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl, : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
DerefState> {
AADereferenceableReturned(const IRPosition &IRP) AADereferenceableReturned(const IRPosition &IRP)
: AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl, : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>(
DerefState>(IRP) {} IRP) {}
/// See AbstractAttribute::trackStatistics() /// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { void trackStatistics() const override {
@ -3455,9 +3454,9 @@ struct AADereferenceableReturned final
/// Dereferenceable attribute for an argument /// Dereferenceable attribute for an argument
struct AADereferenceableArgument final struct AADereferenceableArgument final
: AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext< : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
AADereferenceable, AADereferenceableImpl, DerefState> { AADereferenceable, AADereferenceableImpl> {
using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext< using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
AADereferenceable, AADereferenceableImpl, DerefState>; AADereferenceable, AADereferenceableImpl>;
AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {} AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
/// See AbstractAttribute::trackStatistics() /// See AbstractAttribute::trackStatistics()
@ -5463,23 +5462,15 @@ struct AAValueConstantRangeArgument final
} }
}; };
struct AAValueConstantRangeReturned : AAValueConstantRangeImpl { struct AAValueConstantRangeReturned
AAValueConstantRangeReturned(const IRPosition &IRP) : AAReturnedFromReturnedValues<AAValueConstantRange,
: AAValueConstantRangeImpl(IRP) {} AAValueConstantRangeImpl> {
using Base = AAReturnedFromReturnedValues<AAValueConstantRange,
AAValueConstantRangeImpl>;
AAValueConstantRangeReturned(const IRPosition &IRP) : Base(IRP) {}
/// See AbstractAttribute::updateImpl(...). /// See AbstractAttribute::initialize(...).
ChangeStatus updateImpl(Attributor &A) override { void initialize(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<AAValueConstantRange, IntegerRangeState>(A, *this,
S);
return clampStateAndIndicateChange<StateType>(this->getState(), S);
}
/// See AbstractAttribute::trackStatistics() /// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { void trackStatistics() const override {
@ -5668,9 +5659,12 @@ struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) } void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
}; };
struct AAValueConstantRangeCallSiteReturned : AAValueConstantRangeReturned { struct AAValueConstantRangeCallSiteReturned
: AACallSiteReturnedFromReturned<AAValueConstantRange,
AAValueConstantRangeImpl> {
AAValueConstantRangeCallSiteReturned(const IRPosition &IRP) AAValueConstantRangeCallSiteReturned(const IRPosition &IRP)
: AAValueConstantRangeReturned(IRP) {} : AACallSiteReturnedFromReturned<AAValueConstantRange,
AAValueConstantRangeImpl>(IRP) {}
/// See AbstractAttribute::initialize(...). /// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override { void initialize(Attributor &A) override {
@ -5679,7 +5673,7 @@ struct AAValueConstantRangeCallSiteReturned : AAValueConstantRangeReturned {
if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range)) if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range))
intersectKnown(getConstantRangeFromMetadata(*RangeMD)); intersectKnown(getConstantRangeFromMetadata(*RangeMD));
AAValueConstantRangeReturned::initialize(A); AAValueConstantRangeImpl::initialize(A);
} }
/// See AbstractAttribute::trackStatistics() /// See AbstractAttribute::trackStatistics()