/// as the Attributor is not destroyed (it owns the attributes now).
///
/// \Returns CHANGED if the IR was changed, otherwise UNCHANGED.
- ChangeStatus run();
+ ChangeStatus run(InformationCache &InfoCache);
/// Lookup an abstract attribute of type \p AAType anchored at value \p V and
/// argument number \p ArgNo. If no attribute is found and \p V is a call base
///
/// \param AssociatedVal The value this abstract attribute is associated with.
/// \param AnchoredVal The value this abstract attributes is anchored at.
- /// \param InfoCache Cached information accessible to the abstract attribute.
- AbstractAttribute(Value *AssociatedVal, Value &AnchoredVal,
- InformationCache &InfoCache)
- : AssociatedVal(AssociatedVal), AnchoredVal(AnchoredVal),
- InfoCache(InfoCache) {}
+ AbstractAttribute(Value *AssociatedVal, Value &AnchoredVal)
+ : AssociatedVal(AssociatedVal), AnchoredVal(AnchoredVal) {}
/// An abstract attribute associated with and anchored at \p V.
- AbstractAttribute(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(&V, V, InfoCache) {}
+ AbstractAttribute(Value &V) : AbstractAttribute(&V, V) {}
/// Virtual destructor.
virtual ~AbstractAttribute() {}
/// - perform any work that is not going to change over time, e.g., determine
/// a subset of the IR, or attributes in-flight, that have to be looked at
/// in the `updateImpl` method.
- virtual void initialize(Attributor &A) {}
+ virtual void initialize(Attributor &A, InformationCache &InfoCache) {}
/// Return the internal abstract state for inspection.
virtual const AbstractState &getState() const = 0;
/// otherwise it delegates to `AbstractAttribute::updateImpl`.
///
/// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
- ChangeStatus update(Attributor &A);
+ ChangeStatus update(Attributor &A, InformationCache &InfoCache);
/// Hook for the Attributor to trigger the manifestation of the information
/// represented by the abstract attribute in the LLVM-IR.
/// the current information is still valid or adjust it otherwise.
///
/// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
- virtual ChangeStatus updateImpl(Attributor &A) = 0;
+ virtual ChangeStatus updateImpl(Attributor &A,
+ InformationCache &InfoCache) = 0;
/// The value this abstract attribute is associated with.
Value *AssociatedVal;
/// The value this abstract attribute is anchored at.
Value &AnchoredVal;
-
- /// The information cache accessible to this abstract attribute.
- InformationCache &InfoCache;
};
/// Forward declarations of output streams for debug purposes.
/// An abstract attribute for the returned values of a function.
struct AAReturnedValues : public AbstractAttribute {
/// See AbstractAttribute::AbstractAttribute(...).
- AAReturnedValues(Function &F, InformationCache &InfoCache)
- : AbstractAttribute(F, InfoCache) {}
+ AAReturnedValues(Function &F) : AbstractAttribute(F) {}
/// Check \p Pred on all returned values.
///
struct AANoUnwind : public AbstractAttribute {
/// An abstract interface for all nosync attributes.
- AANoUnwind(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AANoUnwind(Value &V) : AbstractAttribute(V) {}
/// See AbstractAttribute::getAttrKind()/
Attribute::AttrKind getAttrKind() const override { return ID; }
struct AANoSync : public AbstractAttribute {
/// An abstract interface for all nosync attributes.
- AANoSync(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AANoSync(Value &V) : AbstractAttribute(V) {}
/// See AbstractAttribute::getAttrKind().
Attribute::AttrKind getAttrKind() const override { return ID; }
struct AANonNull : public AbstractAttribute {
/// See AbstractAttribute::AbstractAttribute(...).
- AANonNull(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AANonNull(Value &V) : AbstractAttribute(V) {}
/// See AbstractAttribute::AbstractAttribute(...).
- AANonNull(Value *AssociatedVal, Value &AnchoredValue,
- InformationCache &InfoCache)
- : AbstractAttribute(AssociatedVal, AnchoredValue, InfoCache) {}
+ AANonNull(Value *AssociatedVal, Value &AnchoredValue)
+ : AbstractAttribute(AssociatedVal, AnchoredValue) {}
/// Return true if we assume that the underlying value is nonnull.
virtual bool isAssumedNonNull() const = 0;
struct AANoRecurse : public AbstractAttribute {
/// See AbstractAttribute::AbstractAttribute(...).
- AANoRecurse(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AANoRecurse(Value &V) : AbstractAttribute(V) {}
/// See AbstractAttribute::getAttrKind()
virtual Attribute::AttrKind getAttrKind() const override {
struct AAWillReturn : public AbstractAttribute {
/// See AbstractAttribute::AbstractAttribute(...).
- AAWillReturn(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AAWillReturn(Value &V) : AbstractAttribute(V) {}
/// See AbstractAttribute::getAttrKind()
virtual Attribute::AttrKind getAttrKind() const override {
struct AANoAlias : public AbstractAttribute {
/// See AbstractAttribute::AbstractAttribute(...).
- AANoAlias(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AANoAlias(Value &V) : AbstractAttribute(V) {}
/// Return true if we assume that the underlying value is alias.
virtual bool isAssumedNoAlias() const = 0;
struct AANoReturn : public AbstractAttribute {
/// See AbstractAttribute::AbstractAttribute(...).
- AANoReturn(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AANoReturn(Value &V) : AbstractAttribute(V) {}
/// Return true if the underlying object is known to never return.
virtual bool isKnownNoReturn() const = 0;
struct AAIsDead : public AbstractAttribute {
/// See AbstractAttribute::AbstractAttribute(...).
- AAIsDead(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AAIsDead(Value &V) : AbstractAttribute(V) {}
/// See AbstractAttribute::getAttrKind()
Attribute::AttrKind getAttrKind() const override { return ID; }
struct AADereferenceable : public AbstractAttribute {
/// See AbstractAttribute::AbstractAttribute(...).
- AADereferenceable(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AADereferenceable(Value &V) : AbstractAttribute(V) {}
/// See AbstractAttribute::AbstractAttribute(...).
- AADereferenceable(Value *AssociatedVal, Value &AnchoredValue,
- InformationCache &InfoCache)
- : AbstractAttribute(AssociatedVal, AnchoredValue, InfoCache) {}
+ AADereferenceable(Value *AssociatedVal, Value &AnchoredValue)
+ : AbstractAttribute(AssociatedVal, AnchoredValue) {}
/// Return true if we assume that the underlying value is nonnull.
virtual bool isAssumedNonNull() const = 0;
struct AAAlign : public AbstractAttribute {
/// See AbstractAttribute::AbstractAttribute(...).
- AAAlign(Value &V, InformationCache &InfoCache)
- : AbstractAttribute(V, InfoCache) {}
+ AAAlign(Value &V) : AbstractAttribute(V) {}
/// See AbstractAttribute::AbstractAttribute(...).
- AAAlign(Value *AssociatedVal, Value &AnchoredValue,
- InformationCache &InfoCache)
- : AbstractAttribute(AssociatedVal, AnchoredValue, InfoCache) {}
+ AAAlign(Value *AssociatedVal, Value &AnchoredValue)
+ : AbstractAttribute(AssociatedVal, AnchoredValue) {}
/// See AbastractState::getAttrKind().
Attribute::AttrKind getAttrKind() const override { return ID; }
llvm_unreachable("Expected enum or string attribute!");
}
-ChangeStatus AbstractAttribute::update(Attributor &A) {
+ChangeStatus AbstractAttribute::update(Attributor &A,
+ InformationCache &InfoCache) {
ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
if (getState().isAtFixpoint())
return HasChanged;
LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
- HasChanged = updateImpl(A);
+ HasChanged = updateImpl(A, InfoCache);
LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
<< "\n");
struct AANoUnwindFunction : AANoUnwind, BooleanState {
- AANoUnwindFunction(Function &F, InformationCache &InfoCache)
- : AANoUnwind(F, InfoCache) {}
+ AANoUnwindFunction(Function &F) : AANoUnwind(F) {}
/// See AbstractAttribute::getState()
/// {
}
/// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
/// See AANoUnwind::isAssumedNoUnwind().
bool isAssumedNoUnwind() const override { return getAssumed(); }
bool isKnownNoUnwind() const override { return getKnown(); }
};
-ChangeStatus AANoUnwindFunction::updateImpl(Attributor &A) {
+ChangeStatus AANoUnwindFunction::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
// The map from instruction opcodes to those instructions in the function.
public:
/// See AbstractAttribute::AbstractAttribute(...).
- AAReturnedValuesImpl(Function &F, InformationCache &InfoCache)
- : AAReturnedValues(F, InfoCache) {
+ AAReturnedValuesImpl(Function &F) : AAReturnedValues(F) {
// We do not have an associated argument yet.
AssociatedVal = nullptr;
}
/// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
// Reset the state.
AssociatedVal = nullptr;
IsFixed = false;
ManifestPosition getManifestPosition() const override { return MP_ARGUMENT; }
/// See AbstractAttribute::updateImpl(Attributor &A).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
/// Return the number of potential return values, -1 if unknown.
size_t getNumReturnValues() const {
return true;
}
-ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
+ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
// Check if we know of any values returned by the associated function,
// if not, we are done.
struct AANoSyncFunction : AANoSync, BooleanState {
- AANoSyncFunction(Function &F, InformationCache &InfoCache)
- : AANoSync(F, InfoCache) {}
+ AANoSyncFunction(Function &F) : AANoSync(F) {}
/// See AbstractAttribute::getState()
/// {
}
/// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
/// See AANoSync::isAssumedNoSync()
bool isAssumedNoSync() const override { return getAssumed(); }
}
}
-ChangeStatus AANoSyncFunction::updateImpl(Attributor &A) {
+ChangeStatus AANoSyncFunction::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
auto *LivenessAA = A.getAAFor<AAIsDead>(*this, F);
struct AANoFreeFunction : AbstractAttribute, BooleanState {
/// See AbstractAttribute::AbstractAttribute(...).
- AANoFreeFunction(Function &F, InformationCache &InfoCache)
- : AbstractAttribute(F, InfoCache) {}
+ AANoFreeFunction(Function &F) : AbstractAttribute(F) {}
/// See AbstractAttribute::getState()
///{
}
/// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
/// See AbstractAttribute::getAttrKind().
Attribute::AttrKind getAttrKind() const override { return ID; }
static constexpr Attribute::AttrKind ID = Attribute::NoFree;
};
-ChangeStatus AANoFreeFunction::updateImpl(Attributor &A) {
+ChangeStatus AANoFreeFunction::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
auto *LivenessAA = A.getAAFor<AAIsDead>(*this, F);
/// ------------------------ NonNull Argument Attribute ------------------------
struct AANonNullImpl : AANonNull, BooleanState {
- AANonNullImpl(Value &V, InformationCache &InfoCache)
- : AANonNull(V, InfoCache) {}
+ AANonNullImpl(Value &V) : AANonNull(V) {}
- AANonNullImpl(Value *AssociatedVal, Value &AnchoredValue,
- InformationCache &InfoCache)
- : AANonNull(AssociatedVal, AnchoredValue, InfoCache) {}
+ AANonNullImpl(Value *AssociatedVal, Value &AnchoredValue)
+ : AANonNull(AssociatedVal, AnchoredValue) {}
/// See AbstractAttribute::getState()
/// {
/// NonNull attribute for function return value.
struct AANonNullReturned : AANonNullImpl {
- AANonNullReturned(Function &F, InformationCache &InfoCache)
- : AANonNullImpl(F, InfoCache) {}
+ AANonNullReturned(Function &F) : AANonNullImpl(F) {}
/// See AbstractAttribute::getManifestPosition().
ManifestPosition getManifestPosition() const override { return MP_RETURNED; }
/// See AbstractAttriubute::initialize(...).
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
Function &F = getAnchorScope();
// Already nonnull.
}
/// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
};
-ChangeStatus AANonNullReturned::updateImpl(Attributor &A) {
+ChangeStatus AANonNullReturned::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
auto *AARetVal = A.getAAFor<AAReturnedValues>(*this, F);
/// NonNull attribute for function argument.
struct AANonNullArgument : AANonNullImpl {
- AANonNullArgument(Argument &A, InformationCache &InfoCache)
- : AANonNullImpl(A, InfoCache) {}
+ AANonNullArgument(Argument &A) : AANonNullImpl(A) {}
/// See AbstractAttribute::getManifestPosition().
ManifestPosition getManifestPosition() const override { return MP_ARGUMENT; }
/// See AbstractAttriubute::initialize(...).
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
Argument *Arg = cast<Argument>(getAssociatedValue());
if (Arg->hasNonNullAttr())
indicateOptimisticFixpoint();
}
/// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
};
/// NonNull attribute for a call site argument.
struct AANonNullCallSiteArgument : AANonNullImpl {
/// See AANonNullImpl::AANonNullImpl(...).
- AANonNullCallSiteArgument(CallSite CS, unsigned ArgNo,
- InformationCache &InfoCache)
- : AANonNullImpl(CS.getArgOperand(ArgNo), *CS.getInstruction(), InfoCache),
+ AANonNullCallSiteArgument(CallSite CS, unsigned ArgNo)
+ : AANonNullImpl(CS.getArgOperand(ArgNo), *CS.getInstruction()),
ArgNo(ArgNo) {}
/// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
CallSite CS(&getAnchoredValue());
if (CS.paramHasAttr(ArgNo, getAttrKind()) ||
CS.paramHasAttr(ArgNo, Attribute::Dereferenceable) ||
}
/// See AbstractAttribute::updateImpl(Attributor &A).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
/// See AbstractAttribute::getManifestPosition().
ManifestPosition getManifestPosition() const override {
private:
unsigned ArgNo;
};
-ChangeStatus AANonNullArgument::updateImpl(Attributor &A) {
+
+ChangeStatus AANonNullArgument::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
Argument &Arg = cast<Argument>(getAnchoredValue());
return ChangeStatus::UNCHANGED;
}
-ChangeStatus AANonNullCallSiteArgument::updateImpl(Attributor &A) {
+ChangeStatus
+AANonNullCallSiteArgument::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
// NOTE: Never look at the argument of the callee in this method.
// If we do this, "nonnull" is always deduced because of the assumption.
struct AAWillReturnImpl : public AAWillReturn, BooleanState {
/// See AbstractAttribute::AbstractAttribute(...).
- AAWillReturnImpl(Function &F, InformationCache &InfoCache)
- : AAWillReturn(F, InfoCache) {}
+ AAWillReturnImpl(Function &F) : AAWillReturn(F) {}
/// See AAWillReturn::isKnownWillReturn().
bool isKnownWillReturn() const override { return getKnown(); }
struct AAWillReturnFunction final : AAWillReturnImpl {
/// See AbstractAttribute::AbstractAttribute(...).
- AAWillReturnFunction(Function &F, InformationCache &InfoCache)
- : AAWillReturnImpl(F, InfoCache) {}
+ AAWillReturnFunction(Function &F) : AAWillReturnImpl(F) {}
/// See AbstractAttribute::getManifestPosition().
ManifestPosition getManifestPosition() const override { return MP_FUNCTION; }
/// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override;
+ void initialize(Attributor &A, InformationCache &InfoCache) override;
/// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
};
// Helper function that checks whether a function has any cycle.
// We have to allow some patterns.
bool containsPossiblyEndlessLoop(Function &F) { return containsCycle(F); }
-void AAWillReturnFunction::initialize(Attributor &A) {
+void AAWillReturnFunction::initialize(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
if (containsPossiblyEndlessLoop(F))
indicatePessimisticFixpoint();
}
-ChangeStatus AAWillReturnFunction::updateImpl(Attributor &A) {
+ChangeStatus AAWillReturnFunction::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
// The map from instruction opcodes to those instructions in the function.
struct AANoAliasImpl : AANoAlias, BooleanState {
- AANoAliasImpl(Value &V, InformationCache &InfoCache)
- : AANoAlias(V, InfoCache) {}
+ AANoAliasImpl(Value &V) : AANoAlias(V) {}
/// See AbstractAttribute::getState()
/// {
/// NoAlias attribute for function return value.
struct AANoAliasReturned : AANoAliasImpl {
- AANoAliasReturned(Function &F, InformationCache &InfoCache)
- : AANoAliasImpl(F, InfoCache) {}
+ AANoAliasReturned(Function &F) : AANoAliasImpl(F) {}
/// See AbstractAttribute::getManifestPosition().
virtual ManifestPosition getManifestPosition() const override {
}
/// See AbstractAttriubute::initialize(...).
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
Function &F = getAnchorScope();
// Already noalias.
}
/// See AbstractAttribute::updateImpl(...).
- virtual ChangeStatus updateImpl(Attributor &A) override;
+ virtual ChangeStatus updateImpl(Attributor &A,
+ InformationCache &InfoCache) override;
};
-ChangeStatus AANoAliasReturned::updateImpl(Attributor &A) {
+ChangeStatus AANoAliasReturned::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
auto *AARetValImpl = A.getAAFor<AAReturnedValuesImpl>(*this, F);
struct AAIsDeadFunction : AAIsDead, BooleanState {
- AAIsDeadFunction(Function &F, InformationCache &InfoCache)
- : AAIsDead(F, InfoCache) {}
+ AAIsDeadFunction(Function &F) : AAIsDead(F) {}
/// See AbstractAttribute::getState()
/// {
/// See AbstractAttribute::getManifestPosition().
ManifestPosition getManifestPosition() const override { return MP_FUNCTION; }
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
Function &F = getAnchorScope();
ToBeExploredPaths.insert(&(F.getEntryBlock().front()));
}
/// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
/// See AAIsDead::isAssumedDead(BasicBlock *).
bool isAssumedDead(const BasicBlock *BB) const override {
return nullptr;
}
-ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
+ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
// Temporary collection to iterate over existing noreturn instructions. This
// will alow easier modification of NoReturnCalls collection
SmallVector<const Instruction *, 8> NoReturnChanged;
};
struct AADereferenceableImpl : AADereferenceable, DerefState {
- AADereferenceableImpl(Value &V, InformationCache &InfoCache)
- : AADereferenceable(V, InfoCache) {}
+ AADereferenceableImpl(Value &V) : AADereferenceable(V) {}
- AADereferenceableImpl(Value *AssociatedVal, Value &AnchoredValue,
- InformationCache &InfoCache)
- : AADereferenceable(AssociatedVal, AnchoredValue, InfoCache) {}
+ AADereferenceableImpl(Value *AssociatedVal, Value &AnchoredValue)
+ : AADereferenceable(AssociatedVal, AnchoredValue) {}
/// See AbstractAttribute::getState()
/// {
uint64_t computeAssumedDerefenceableBytes(Attributor &A, Value &V,
bool &IsNonNull, bool &IsGlobal);
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
Function &F = getAnchorScope();
unsigned AttrIdx =
getAttrIndex(getManifestPosition(), getArgNo(getAnchoredValue()));
};
struct AADereferenceableReturned : AADereferenceableImpl {
- AADereferenceableReturned(Function &F, InformationCache &InfoCache)
- : AADereferenceableImpl(F, InfoCache) {}
+ AADereferenceableReturned(Function &F) : AADereferenceableImpl(F) {}
/// See AbstractAttribute::getManifestPosition().
ManifestPosition getManifestPosition() const override { return MP_RETURNED; }
/// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
};
// Helper function that returns dereferenceable bytes.
IsNonNull = false;
return 0;
}
-ChangeStatus AADereferenceableReturned::updateImpl(Attributor &A) {
+
+ChangeStatus
+AADereferenceableReturned::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
auto BeforeState = static_cast<DerefState>(*this);
}
struct AADereferenceableArgument : AADereferenceableImpl {
- AADereferenceableArgument(Argument &A, InformationCache &InfoCache)
- : AADereferenceableImpl(A, InfoCache) {}
+ AADereferenceableArgument(Argument &A) : AADereferenceableImpl(A) {}
/// See AbstractAttribute::getManifestPosition().
ManifestPosition getManifestPosition() const override { return MP_ARGUMENT; }
/// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
};
-ChangeStatus AADereferenceableArgument::updateImpl(Attributor &A) {
+ChangeStatus
+AADereferenceableArgument::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
Argument &Arg = cast<Argument>(getAnchoredValue());
struct AADereferenceableCallSiteArgument : AADereferenceableImpl {
/// See AADereferenceableImpl::AADereferenceableImpl(...).
- AADereferenceableCallSiteArgument(CallSite CS, unsigned ArgNo,
- InformationCache &InfoCache)
- : AADereferenceableImpl(CS.getArgOperand(ArgNo), *CS.getInstruction(),
- InfoCache),
+ AADereferenceableCallSiteArgument(CallSite CS, unsigned ArgNo)
+ : AADereferenceableImpl(CS.getArgOperand(ArgNo), *CS.getInstruction()),
ArgNo(ArgNo) {}
/// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
CallSite CS(&getAnchoredValue());
if (CS.paramHasAttr(ArgNo, Attribute::Dereferenceable))
takeKnownDerefBytesMaximum(
}
/// See AbstractAttribute::updateImpl(Attributor &A).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
/// See AbstractAttribute::getManifestPosition().
ManifestPosition getManifestPosition() const override {
unsigned ArgNo;
};
-ChangeStatus AADereferenceableCallSiteArgument::updateImpl(Attributor &A) {
+ChangeStatus
+AADereferenceableCallSiteArgument::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
// NOTE: Never look at the argument of the callee in this method.
// If we do this, "dereferenceable" is always deduced because of the
// assumption.
// Max alignemnt value allowed in IR
static const unsigned MAX_ALIGN = 1U << 29;
- AAAlignImpl(Value *AssociatedVal, Value &AnchoredValue,
- InformationCache &InfoCache)
- : AAAlign(AssociatedVal, AnchoredValue, InfoCache),
- IntegerState(MAX_ALIGN) {}
+ AAAlignImpl(Value *AssociatedVal, Value &AnchoredValue)
+ : AAAlign(AssociatedVal, AnchoredValue), IntegerState(MAX_ALIGN) {}
- AAAlignImpl(Value &V, InformationCache &InfoCache)
- : AAAlignImpl(&V, V, InfoCache) {}
+ AAAlignImpl(Value &V) : AAAlignImpl(&V, V) {}
/// See AbstractAttribute::getState()
/// {
unsigned getKnownAlign() const override { return getKnown(); }
/// See AbstractAttriubute::initialize(...).
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
Function &F = getAnchorScope();
unsigned AttrIdx =
/// Align attribute for function return value.
struct AAAlignReturned : AAAlignImpl {
- AAAlignReturned(Function &F, InformationCache &InfoCache)
- : AAAlignImpl(F, InfoCache) {}
+ AAAlignReturned(Function &F) : AAAlignImpl(F) {}
/// See AbstractAttribute::getManifestPosition().
virtual ManifestPosition getManifestPosition() const override {
}
/// See AbstractAttribute::updateImpl(...).
- virtual ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
};
-ChangeStatus AAAlignReturned::updateImpl(Attributor &A) {
+ChangeStatus AAAlignReturned::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
auto *AARetValImpl = A.getAAFor<AAReturnedValuesImpl>(*this, F);
if (!AARetValImpl)
/// Align attribute for function argument.
struct AAAlignArgument : AAAlignImpl {
- AAAlignArgument(Argument &A, InformationCache &InfoCache)
- : AAAlignImpl(A, InfoCache) {}
+ AAAlignArgument(Argument &A) : AAAlignImpl(A) {}
/// See AbstractAttribute::getManifestPosition().
virtual ManifestPosition getManifestPosition() const override {
}
/// See AbstractAttribute::updateImpl(...).
- virtual ChangeStatus updateImpl(Attributor &A) override;
+ virtual ChangeStatus updateImpl(Attributor &A,
+ InformationCache &InfoCache) override;
};
-ChangeStatus AAAlignArgument::updateImpl(Attributor &A) {
+ChangeStatus AAAlignArgument::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
Function &F = getAnchorScope();
Argument &Arg = cast<Argument>(getAnchoredValue());
struct AAAlignCallSiteArgument : AAAlignImpl {
/// See AANonNullImpl::AANonNullImpl(...).
- AAAlignCallSiteArgument(CallSite CS, unsigned ArgNo,
- InformationCache &InfoCache)
- : AAAlignImpl(CS.getArgOperand(ArgNo), *CS.getInstruction(), InfoCache),
+ AAAlignCallSiteArgument(CallSite CS, unsigned ArgNo)
+ : AAAlignImpl(CS.getArgOperand(ArgNo), *CS.getInstruction()),
ArgNo(ArgNo) {}
/// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
CallSite CS(&getAnchoredValue());
takeKnownMaximum(getAssociatedValue()->getPointerAlignment(
getAnchorScope().getParent()->getDataLayout()));
}
/// See AbstractAttribute::updateImpl(Attributor &A).
- ChangeStatus updateImpl(Attributor &A) override;
+ ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
/// See AbstractAttribute::getManifestPosition().
ManifestPosition getManifestPosition() const override {
unsigned ArgNo;
};
-ChangeStatus AAAlignCallSiteArgument::updateImpl(Attributor &A) {
+ChangeStatus AAAlignCallSiteArgument::updateImpl(Attributor &A,
+ InformationCache &InfoCache) {
// NOTE: Never look at the argument of the callee in this method.
// If we do this, "align" is always deduced because of the assumption.
/// ------------------ Function No-Return Attribute ----------------------------
struct AANoReturnFunction final : public AANoReturn, BooleanState {
- AANoReturnFunction(Function &F, InformationCache &InfoCache)
- : AANoReturn(F, InfoCache) {}
+ AANoReturnFunction(Function &F) : AANoReturn(F) {}
/// See AbstractAttribute::getState()
/// {
}
/// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
+ void initialize(Attributor &A, InformationCache &InfoCache) override {
Function &F = getAnchorScope();
if (F.hasFnAttribute(getAttrKind()))
indicateOptimisticFixpoint();
}
/// See AbstractAttribute::updateImpl(Attributor &A).
- virtual ChangeStatus updateImpl(Attributor &A) override {
+ virtual ChangeStatus updateImpl(Attributor &A,
+ InformationCache &InfoCache) override {
Function &F = getAnchorScope();
// The map from instruction opcodes to those instructions in the function.
return true;
}
-ChangeStatus Attributor::run() {
+ChangeStatus Attributor::run(InformationCache &InfoCache) {
// Initialize all abstract attributes.
for (AbstractAttribute *AA : AllAbstractAttributes)
- AA->initialize(*this);
+ AA->initialize(*this, InfoCache);
LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
<< AllAbstractAttributes.size()
// Update all abstract attribute in the work list and record the ones that
// changed.
for (AbstractAttribute *AA : Worklist)
- if (AA->update(*this) == ChangeStatus::CHANGED)
+ if (AA->update(*this, InfoCache) == ChangeStatus::CHANGED)
ChangedAAs.push_back(AA);
// Reset the work list and repopulate with the changed abstract attributes.
if (VerifyAttributor && FinishedAtFixpoint &&
ManifestChange == ChangeStatus::CHANGED) {
VerifyAttributor = false;
- ChangeStatus VerifyStatus = run();
+ ChangeStatus VerifyStatus = run(InfoCache);
if (VerifyStatus != ChangeStatus::UNCHANGED)
llvm_unreachable(
"Attributor verification failed, re-run did result in an IR change "
DenseSet</* Attribute::AttrKind */ unsigned> *Whitelist) {
// Check for dead BasicBlocks in every function.
- registerAA(*new AAIsDeadFunction(F, InfoCache));
+ registerAA(*new AAIsDeadFunction(F));
// Every function might be "will-return".
- registerAA(*new AAWillReturnFunction(F, InfoCache));
+ registerAA(*new AAWillReturnFunction(F));
// Every function can be nounwind.
- registerAA(*new AANoUnwindFunction(F, InfoCache));
+ registerAA(*new AANoUnwindFunction(F));
// Every function might be marked "nosync"
- registerAA(*new AANoSyncFunction(F, InfoCache));
+ registerAA(*new AANoSyncFunction(F));
// Every function might be "no-free".
- registerAA(*new AANoFreeFunction(F, InfoCache));
+ registerAA(*new AANoFreeFunction(F));
// Every function might be "no-return".
- registerAA(*new AANoReturnFunction(F, InfoCache));
+ registerAA(*new AANoReturnFunction(F));
// Return attributes are only appropriate if the return type is non void.
Type *ReturnType = F.getReturnType();
// Argument attribute "returned" --- Create only one per function even
// though it is an argument attribute.
if (!Whitelist || Whitelist->count(AAReturnedValues::ID))
- registerAA(*new AAReturnedValuesImpl(F, InfoCache));
+ registerAA(*new AAReturnedValuesImpl(F));
if (ReturnType->isPointerTy()) {
// Every function with pointer return type might be marked align.
if (!Whitelist || Whitelist->count(AAAlignReturned::ID))
- registerAA(*new AAAlignReturned(F, InfoCache));
+ registerAA(*new AAAlignReturned(F));
// Every function with pointer return type might be marked nonnull.
if (!Whitelist || Whitelist->count(AANonNullReturned::ID))
- registerAA(*new AANonNullReturned(F, InfoCache));
+ registerAA(*new AANonNullReturned(F));
// Every function with pointer return type might be marked noalias.
if (!Whitelist || Whitelist->count(AANoAliasReturned::ID))
- registerAA(*new AANoAliasReturned(F, InfoCache));
+ registerAA(*new AANoAliasReturned(F));
// Every function with pointer return type might be marked
// dereferenceable.
if (ReturnType->isPointerTy() &&
(!Whitelist || Whitelist->count(AADereferenceableReturned::ID)))
- registerAA(*new AADereferenceableReturned(F, InfoCache));
+ registerAA(*new AADereferenceableReturned(F));
}
}
if (Arg.getType()->isPointerTy()) {
// Every argument with pointer type might be marked nonnull.
if (!Whitelist || Whitelist->count(AANonNullArgument::ID))
- registerAA(*new AANonNullArgument(Arg, InfoCache));
+ registerAA(*new AANonNullArgument(Arg));
// Every argument with pointer type might be marked dereferenceable.
if (!Whitelist || Whitelist->count(AADereferenceableArgument::ID))
- registerAA(*new AADereferenceableArgument(Arg, InfoCache));
+ registerAA(*new AADereferenceableArgument(Arg));
// Every argument with pointer type might be marked align.
if (!Whitelist || Whitelist->count(AAAlignArgument::ID))
- registerAA(*new AAAlignArgument(Arg, InfoCache));
+ registerAA(*new AAAlignArgument(Arg));
}
}
// Call site argument attribute "non-null".
if (!Whitelist || Whitelist->count(AANonNullCallSiteArgument::ID))
- registerAA(*new AANonNullCallSiteArgument(CS, i, InfoCache), i);
+ registerAA(*new AANonNullCallSiteArgument(CS, i), i);
// Call site argument attribute "dereferenceable".
if (!Whitelist ||
Whitelist->count(AADereferenceableCallSiteArgument::ID))
- registerAA(*new AADereferenceableCallSiteArgument(CS, i, InfoCache),
- i);
+ registerAA(*new AADereferenceableCallSiteArgument(CS, i), i);
// Call site argument attribute "align".
if (!Whitelist || Whitelist->count(AAAlignCallSiteArgument::ID))
- registerAA(*new AAAlignCallSiteArgument(CS, i, InfoCache), i);
+ registerAA(*new AAAlignCallSiteArgument(CS, i), i);
}
}
}
A.identifyDefaultAbstractAttributes(F, InfoCache);
}
- return A.run() == ChangeStatus::CHANGED;
+ return A.run(InfoCache) == ChangeStatus::CHANGED;
}
PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {