forked from OSchip/llvm-project
[Attributor] Use proper ID for attribute lookup
Summary: The new scheme is similar to the pass manager and dyn_cast scheme where we identify classes by the address of a static member. This is better than the old scheme in which we had to "invent" new Attributor enums if there was no corresponding one. Reviewers: sstefan1, uenoku Subscribers: hiraditya, bollu, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65710 llvm-svn: 367951
This commit is contained in:
parent
007153e9d4
commit
2402062557
|
@ -176,8 +176,6 @@ struct Attributor {
|
||||||
static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
|
static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
|
||||||
"Cannot query an attribute with a type not derived from "
|
"Cannot query an attribute with a type not derived from "
|
||||||
"'AbstractAttribute'!");
|
"'AbstractAttribute'!");
|
||||||
assert(AAType::ID != Attribute::None &&
|
|
||||||
"Cannot lookup generic abstract attributes!");
|
|
||||||
|
|
||||||
// Determine the argument number automatically for llvm::Arguments if none
|
// Determine the argument number automatically for llvm::Arguments if none
|
||||||
// is set. Do not override a given one as it could be a use of the argument
|
// is set. Do not override a given one as it could be a use of the argument
|
||||||
|
@ -198,7 +196,7 @@ struct Attributor {
|
||||||
// registering a dependence of QueryingAA on the one returned attribute.
|
// registering a dependence of QueryingAA on the one returned attribute.
|
||||||
const auto &KindToAbstractAttributeMap = AAMap.lookup({&V, ArgNo});
|
const auto &KindToAbstractAttributeMap = AAMap.lookup({&V, ArgNo});
|
||||||
if (AAType *AA = static_cast<AAType *>(
|
if (AAType *AA = static_cast<AAType *>(
|
||||||
KindToAbstractAttributeMap.lookup(AAType::ID))) {
|
KindToAbstractAttributeMap.lookup(&AAType::ID))) {
|
||||||
// Do not return an attribute with an invalid state. This minimizes checks
|
// Do not return an attribute with an invalid state. This minimizes checks
|
||||||
// at the calls sites and allows the fallback below to kick in.
|
// at the calls sites and allows the fallback below to kick in.
|
||||||
if (AA->getState().isValidState()) {
|
if (AA->getState().isValidState()) {
|
||||||
|
@ -225,7 +223,7 @@ struct Attributor {
|
||||||
/// Attributes are identified by
|
/// Attributes are identified by
|
||||||
/// (1) their anchored value (see AA.getAnchoredValue()),
|
/// (1) their anchored value (see AA.getAnchoredValue()),
|
||||||
/// (2) their argument number (\p ArgNo, or Argument::getArgNo()), and
|
/// (2) their argument number (\p ArgNo, or Argument::getArgNo()), and
|
||||||
/// (3) their default attribute kind (see AAType::ID).
|
/// (3) the address of their static member (see AAType::ID).
|
||||||
template <typename AAType> AAType ®isterAA(AAType &AA, int ArgNo = -1) {
|
template <typename AAType> AAType ®isterAA(AAType &AA, int ArgNo = -1) {
|
||||||
static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
|
static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
|
||||||
"Cannot register an attribute with a type not derived from "
|
"Cannot register an attribute with a type not derived from "
|
||||||
|
@ -242,7 +240,7 @@ struct Attributor {
|
||||||
|
|
||||||
// Put the attribute in the lookup map structure and the container we use to
|
// Put the attribute in the lookup map structure and the container we use to
|
||||||
// keep track of all attributes.
|
// keep track of all attributes.
|
||||||
AAMap[{&AnchoredVal, ArgNo}][AAType::ID] = &AA;
|
AAMap[{&AnchoredVal, ArgNo}][&AAType::ID] = &AA;
|
||||||
AllAbstractAttributes.push_back(&AA);
|
AllAbstractAttributes.push_back(&AA);
|
||||||
return AA;
|
return AA;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +259,7 @@ struct Attributor {
|
||||||
/// various places.
|
/// various places.
|
||||||
void identifyDefaultAbstractAttributes(
|
void identifyDefaultAbstractAttributes(
|
||||||
Function &F, InformationCache &InfoCache,
|
Function &F, InformationCache &InfoCache,
|
||||||
DenseSet</* Attribute::AttrKind */ unsigned> *Whitelist = nullptr);
|
DenseSet<const char *> *Whitelist = nullptr);
|
||||||
|
|
||||||
/// Check \p Pred on all function call sites.
|
/// Check \p Pred on all function call sites.
|
||||||
///
|
///
|
||||||
|
@ -279,10 +277,11 @@ private:
|
||||||
///}
|
///}
|
||||||
|
|
||||||
/// A nested map to lookup abstract attributes based on the anchored value and
|
/// A nested map to lookup abstract attributes based on the anchored value and
|
||||||
/// an argument positions (or -1) on the outer level, and attribute kinds
|
/// an argument positions (or -1) on the outer level, and the addresses of the
|
||||||
/// (Attribute::AttrKind) on the inner level.
|
/// static member (AAType::ID) on the inner level.
|
||||||
///{
|
///{
|
||||||
using KindToAbstractAttributeMap = DenseMap<unsigned, AbstractAttribute *>;
|
using KindToAbstractAttributeMap =
|
||||||
|
DenseMap<const char *, AbstractAttribute *>;
|
||||||
DenseMap<std::pair<const Value *, int>, KindToAbstractAttributeMap> AAMap;
|
DenseMap<std::pair<const Value *, int>, KindToAbstractAttributeMap> AAMap;
|
||||||
///}
|
///}
|
||||||
|
|
||||||
|
@ -700,10 +699,12 @@ struct AAReturnedValues : public AbstractAttribute {
|
||||||
const = 0;
|
const = 0;
|
||||||
|
|
||||||
/// See AbstractAttribute::getAttrKind()
|
/// See AbstractAttribute::getAttrKind()
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override {
|
||||||
|
return Attribute::Returned;
|
||||||
|
}
|
||||||
|
|
||||||
/// The identifier used by the Attributor for this class of attributes.
|
/// Unique ID (due to the unique address)
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::Returned;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AANoUnwind : public AbstractAttribute {
|
struct AANoUnwind : public AbstractAttribute {
|
||||||
|
@ -711,15 +712,18 @@ struct AANoUnwind : public AbstractAttribute {
|
||||||
AANoUnwind(Value &V) : AbstractAttribute(V) {}
|
AANoUnwind(Value &V) : AbstractAttribute(V) {}
|
||||||
|
|
||||||
/// See AbstractAttribute::getAttrKind()/
|
/// See AbstractAttribute::getAttrKind()/
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override {
|
||||||
|
return Attribute::NoUnwind;
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::NoUnwind;
|
}
|
||||||
|
|
||||||
/// Returns true if nounwind is assumed.
|
/// Returns true if nounwind is assumed.
|
||||||
virtual bool isAssumedNoUnwind() const = 0;
|
virtual bool isAssumedNoUnwind() const = 0;
|
||||||
|
|
||||||
/// Returns true if nounwind is known.
|
/// Returns true if nounwind is known.
|
||||||
virtual bool isKnownNoUnwind() const = 0;
|
virtual bool isKnownNoUnwind() const = 0;
|
||||||
|
|
||||||
|
/// Unique ID (due to the unique address)
|
||||||
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AANoSync : public AbstractAttribute {
|
struct AANoSync : public AbstractAttribute {
|
||||||
|
@ -727,16 +731,16 @@ struct AANoSync : public AbstractAttribute {
|
||||||
AANoSync(Value &V) : AbstractAttribute(V) {}
|
AANoSync(Value &V) : AbstractAttribute(V) {}
|
||||||
|
|
||||||
/// See AbstractAttribute::getAttrKind().
|
/// See AbstractAttribute::getAttrKind().
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override { return Attribute::NoSync; }
|
||||||
|
|
||||||
static constexpr Attribute::AttrKind ID =
|
|
||||||
Attribute::AttrKind(Attribute::NoSync);
|
|
||||||
|
|
||||||
/// Returns true if "nosync" is assumed.
|
/// Returns true if "nosync" is assumed.
|
||||||
virtual bool isAssumedNoSync() const = 0;
|
virtual bool isAssumedNoSync() const = 0;
|
||||||
|
|
||||||
/// Returns true if "nosync" is known.
|
/// Returns true if "nosync" is known.
|
||||||
virtual bool isKnownNoSync() const = 0;
|
virtual bool isKnownNoSync() const = 0;
|
||||||
|
|
||||||
|
/// Unique ID (due to the unique address)
|
||||||
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An abstract interface for all nonnull attributes.
|
/// An abstract interface for all nonnull attributes.
|
||||||
|
@ -756,10 +760,12 @@ struct AANonNull : public AbstractAttribute {
|
||||||
virtual bool isKnownNonNull() const = 0;
|
virtual bool isKnownNonNull() const = 0;
|
||||||
|
|
||||||
/// See AbastractState::getAttrKind().
|
/// See AbastractState::getAttrKind().
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override {
|
||||||
|
return Attribute::NonNull;
|
||||||
|
}
|
||||||
|
|
||||||
/// The identifier used by the Attributor for this class of attributes.
|
/// Unique ID (due to the unique address)
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::NonNull;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An abstract attribute for norecurse.
|
/// An abstract attribute for norecurse.
|
||||||
|
@ -779,8 +785,8 @@ struct AANoRecurse : public AbstractAttribute {
|
||||||
/// Return true if "norecurse" is assumed.
|
/// Return true if "norecurse" is assumed.
|
||||||
virtual bool isAssumedNoRecurse() const = 0;
|
virtual bool isAssumedNoRecurse() const = 0;
|
||||||
|
|
||||||
/// The identifier used by the Attributor for this class of attributes.
|
/// Unique ID (due to the unique address)
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::NoRecurse;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An abstract attribute for willreturn.
|
/// An abstract attribute for willreturn.
|
||||||
|
@ -800,8 +806,8 @@ struct AAWillReturn : public AbstractAttribute {
|
||||||
/// Return true if "willreturn" is assumed.
|
/// Return true if "willreturn" is assumed.
|
||||||
virtual bool isAssumedWillReturn() const = 0;
|
virtual bool isAssumedWillReturn() const = 0;
|
||||||
|
|
||||||
/// The identifier used by the Attributor for this class of attributes.
|
/// Unique ID (due to the unique address)
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::WillReturn;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An abstract interface for all noalias attributes.
|
/// An abstract interface for all noalias attributes.
|
||||||
|
@ -817,10 +823,12 @@ struct AANoAlias : public AbstractAttribute {
|
||||||
virtual bool isKnownNoAlias() const = 0;
|
virtual bool isKnownNoAlias() const = 0;
|
||||||
|
|
||||||
/// See AbastractState::getAttrKind().
|
/// See AbastractState::getAttrKind().
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override {
|
||||||
|
return Attribute::NoAlias;
|
||||||
|
}
|
||||||
|
|
||||||
/// The identifier used by the Attributor for this class of attributes.
|
/// Unique ID (due to the unique address)
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::NoAlias;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An AbstractAttribute for noreturn.
|
/// An AbstractAttribute for noreturn.
|
||||||
|
@ -836,10 +844,12 @@ struct AANoReturn : public AbstractAttribute {
|
||||||
virtual bool isAssumedNoReturn() const = 0;
|
virtual bool isAssumedNoReturn() const = 0;
|
||||||
|
|
||||||
/// See AbstractAttribute::getAttrKind()
|
/// See AbstractAttribute::getAttrKind()
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override {
|
||||||
|
return Attribute::NoReturn;
|
||||||
|
}
|
||||||
|
|
||||||
/// The identifier used by the Attributor for this class of attributes.
|
/// Unique ID (due to the unique address)
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::NoReturn;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An abstract interface for liveness abstract attribute.
|
/// An abstract interface for liveness abstract attribute.
|
||||||
|
@ -849,10 +859,7 @@ struct AAIsDead : public AbstractAttribute {
|
||||||
AAIsDead(Value &V) : AbstractAttribute(V) {}
|
AAIsDead(Value &V) : AbstractAttribute(V) {}
|
||||||
|
|
||||||
/// See AbstractAttribute::getAttrKind()
|
/// See AbstractAttribute::getAttrKind()
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override { return Attribute::None; }
|
||||||
|
|
||||||
static constexpr Attribute::AttrKind ID =
|
|
||||||
Attribute::AttrKind(Attribute::EndAttrKinds + 1);
|
|
||||||
|
|
||||||
/// Returns true if \p BB is assumed dead.
|
/// Returns true if \p BB is assumed dead.
|
||||||
virtual bool isAssumedDead(const BasicBlock *BB) const = 0;
|
virtual bool isAssumedDead(const BasicBlock *BB) const = 0;
|
||||||
|
@ -879,6 +886,9 @@ struct AAIsDead : public AbstractAttribute {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Unique ID (due to the unique address)
|
||||||
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An abstract interface for all dereferenceable attribute.
|
/// An abstract interface for all dereferenceable attribute.
|
||||||
|
@ -912,10 +922,12 @@ struct AADereferenceable : public AbstractAttribute {
|
||||||
virtual uint32_t getKnownDereferenceableBytes() const = 0;
|
virtual uint32_t getKnownDereferenceableBytes() const = 0;
|
||||||
|
|
||||||
/// See AbastractState::getAttrKind().
|
/// See AbastractState::getAttrKind().
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override {
|
||||||
|
return Attribute::Dereferenceable;
|
||||||
|
}
|
||||||
|
|
||||||
/// The identifier used by the Attributor for this class of attributes.
|
/// Unique ID (due to the unique address)
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::Dereferenceable;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An abstract interface for all align attributes.
|
/// An abstract interface for all align attributes.
|
||||||
|
@ -929,7 +941,9 @@ struct AAAlign : public AbstractAttribute {
|
||||||
: AbstractAttribute(AssociatedVal, AnchoredValue) {}
|
: AbstractAttribute(AssociatedVal, AnchoredValue) {}
|
||||||
|
|
||||||
/// See AbastractState::getAttrKind().
|
/// See AbastractState::getAttrKind().
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override {
|
||||||
|
return Attribute::Alignment;
|
||||||
|
}
|
||||||
|
|
||||||
/// Return assumed alignment.
|
/// Return assumed alignment.
|
||||||
virtual unsigned getAssumedAlign() const = 0;
|
virtual unsigned getAssumedAlign() const = 0;
|
||||||
|
@ -937,8 +951,8 @@ struct AAAlign : public AbstractAttribute {
|
||||||
/// Return known alignemnt.
|
/// Return known alignemnt.
|
||||||
virtual unsigned getKnownAlign() const = 0;
|
virtual unsigned getKnownAlign() const = 0;
|
||||||
|
|
||||||
/// The identifier used by the Attributor for this class of attributes.
|
/// Unique ID (due to the unique address)
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::Alignment;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace llvm
|
} // end namespace llvm
|
||||||
|
|
|
@ -1074,7 +1074,7 @@ struct AANoFreeFunction : AbstractAttribute, BooleanState {
|
||||||
ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
|
ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
|
||||||
|
|
||||||
/// See AbstractAttribute::getAttrKind().
|
/// See AbstractAttribute::getAttrKind().
|
||||||
Attribute::AttrKind getAttrKind() const override { return ID; }
|
Attribute::AttrKind getAttrKind() const override { return Attribute::NoFree; }
|
||||||
|
|
||||||
/// Return true if "nofree" is assumed.
|
/// Return true if "nofree" is assumed.
|
||||||
bool isAssumedNoFree() const { return getAssumed(); }
|
bool isAssumedNoFree() const { return getAssumed(); }
|
||||||
|
@ -1082,8 +1082,8 @@ struct AANoFreeFunction : AbstractAttribute, BooleanState {
|
||||||
/// Return true if "nofree" is known.
|
/// Return true if "nofree" is known.
|
||||||
bool isKnownNoFree() const { return getKnown(); }
|
bool isKnownNoFree() const { return getKnown(); }
|
||||||
|
|
||||||
/// The identifier used by the Attributor for this class of attributes.
|
/// Unique ID (due to the unique address)
|
||||||
static constexpr Attribute::AttrKind ID = Attribute::NoFree;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
ChangeStatus AANoFreeFunction::updateImpl(Attributor &A,
|
ChangeStatus AANoFreeFunction::updateImpl(Attributor &A,
|
||||||
|
@ -2177,8 +2177,9 @@ struct AAAlignImpl : AAAlign, IntegerState {
|
||||||
getAttrIndex(getManifestPosition(), getArgNo(getAnchoredValue()));
|
getAttrIndex(getManifestPosition(), getArgNo(getAnchoredValue()));
|
||||||
|
|
||||||
// Already the function has align attribute on return value or argument.
|
// Already the function has align attribute on return value or argument.
|
||||||
if (F.getAttributes().hasAttribute(AttrIdx, ID))
|
if (F.getAttributes().hasAttribute(AttrIdx, Attribute::Alignment))
|
||||||
addKnownBits(F.getAttribute(AttrIdx, ID).getAlignment());
|
addKnownBits(
|
||||||
|
F.getAttribute(AttrIdx, Attribute::Alignment).getAlignment());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See AbstractAttribute::getDeducedAttributes
|
/// See AbstractAttribute::getDeducedAttributes
|
||||||
|
@ -2580,7 +2581,7 @@ ChangeStatus Attributor::run(InformationCache &InfoCache) {
|
||||||
|
|
||||||
void Attributor::identifyDefaultAbstractAttributes(
|
void Attributor::identifyDefaultAbstractAttributes(
|
||||||
Function &F, InformationCache &InfoCache,
|
Function &F, InformationCache &InfoCache,
|
||||||
DenseSet</* Attribute::AttrKind */ unsigned> *Whitelist) {
|
DenseSet<const char *> *Whitelist) {
|
||||||
|
|
||||||
// Check for dead BasicBlocks in every function.
|
// Check for dead BasicBlocks in every function.
|
||||||
registerAA(*new AAIsDeadFunction(F));
|
registerAA(*new AAIsDeadFunction(F));
|
||||||
|
@ -2605,26 +2606,26 @@ void Attributor::identifyDefaultAbstractAttributes(
|
||||||
if (!ReturnType->isVoidTy()) {
|
if (!ReturnType->isVoidTy()) {
|
||||||
// Argument attribute "returned" --- Create only one per function even
|
// Argument attribute "returned" --- Create only one per function even
|
||||||
// though it is an argument attribute.
|
// though it is an argument attribute.
|
||||||
if (!Whitelist || Whitelist->count(AAReturnedValues::ID))
|
if (!Whitelist || Whitelist->count(&AAReturnedValues::ID))
|
||||||
registerAA(*new AAReturnedValuesImpl(F));
|
registerAA(*new AAReturnedValuesImpl(F));
|
||||||
|
|
||||||
if (ReturnType->isPointerTy()) {
|
if (ReturnType->isPointerTy()) {
|
||||||
// Every function with pointer return type might be marked align.
|
// Every function with pointer return type might be marked align.
|
||||||
if (!Whitelist || Whitelist->count(AAAlignReturned::ID))
|
if (!Whitelist || Whitelist->count(&AAAlignReturned::ID))
|
||||||
registerAA(*new AAAlignReturned(F));
|
registerAA(*new AAAlignReturned(F));
|
||||||
|
|
||||||
// Every function with pointer return type might be marked nonnull.
|
// Every function with pointer return type might be marked nonnull.
|
||||||
if (!Whitelist || Whitelist->count(AANonNullReturned::ID))
|
if (!Whitelist || Whitelist->count(&AANonNullReturned::ID))
|
||||||
registerAA(*new AANonNullReturned(F));
|
registerAA(*new AANonNullReturned(F));
|
||||||
|
|
||||||
// Every function with pointer return type might be marked noalias.
|
// Every function with pointer return type might be marked noalias.
|
||||||
if (!Whitelist || Whitelist->count(AANoAliasReturned::ID))
|
if (!Whitelist || Whitelist->count(&AANoAliasReturned::ID))
|
||||||
registerAA(*new AANoAliasReturned(F));
|
registerAA(*new AANoAliasReturned(F));
|
||||||
|
|
||||||
// Every function with pointer return type might be marked
|
// Every function with pointer return type might be marked
|
||||||
// dereferenceable.
|
// dereferenceable.
|
||||||
if (ReturnType->isPointerTy() &&
|
if (ReturnType->isPointerTy() &&
|
||||||
(!Whitelist || Whitelist->count(AADereferenceableReturned::ID)))
|
(!Whitelist || Whitelist->count(&AADereferenceableReturned::ID)))
|
||||||
registerAA(*new AADereferenceableReturned(F));
|
registerAA(*new AADereferenceableReturned(F));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2632,15 +2633,15 @@ void Attributor::identifyDefaultAbstractAttributes(
|
||||||
for (Argument &Arg : F.args()) {
|
for (Argument &Arg : F.args()) {
|
||||||
if (Arg.getType()->isPointerTy()) {
|
if (Arg.getType()->isPointerTy()) {
|
||||||
// Every argument with pointer type might be marked nonnull.
|
// Every argument with pointer type might be marked nonnull.
|
||||||
if (!Whitelist || Whitelist->count(AANonNullArgument::ID))
|
if (!Whitelist || Whitelist->count(&AANonNullArgument::ID))
|
||||||
registerAA(*new AANonNullArgument(Arg));
|
registerAA(*new AANonNullArgument(Arg));
|
||||||
|
|
||||||
// Every argument with pointer type might be marked dereferenceable.
|
// Every argument with pointer type might be marked dereferenceable.
|
||||||
if (!Whitelist || Whitelist->count(AADereferenceableArgument::ID))
|
if (!Whitelist || Whitelist->count(&AADereferenceableArgument::ID))
|
||||||
registerAA(*new AADereferenceableArgument(Arg));
|
registerAA(*new AADereferenceableArgument(Arg));
|
||||||
|
|
||||||
// Every argument with pointer type might be marked align.
|
// Every argument with pointer type might be marked align.
|
||||||
if (!Whitelist || Whitelist->count(AAAlignArgument::ID))
|
if (!Whitelist || Whitelist->count(&AAAlignArgument::ID))
|
||||||
registerAA(*new AAAlignArgument(Arg));
|
registerAA(*new AAAlignArgument(Arg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2686,16 +2687,16 @@ void Attributor::identifyDefaultAbstractAttributes(
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Call site argument attribute "non-null".
|
// Call site argument attribute "non-null".
|
||||||
if (!Whitelist || Whitelist->count(AANonNullCallSiteArgument::ID))
|
if (!Whitelist || Whitelist->count(&AANonNullCallSiteArgument::ID))
|
||||||
registerAA(*new AANonNullCallSiteArgument(CS, i), i);
|
registerAA(*new AANonNullCallSiteArgument(CS, i), i);
|
||||||
|
|
||||||
// Call site argument attribute "dereferenceable".
|
// Call site argument attribute "dereferenceable".
|
||||||
if (!Whitelist ||
|
if (!Whitelist ||
|
||||||
Whitelist->count(AADereferenceableCallSiteArgument::ID))
|
Whitelist->count(&AADereferenceableCallSiteArgument::ID))
|
||||||
registerAA(*new AADereferenceableCallSiteArgument(CS, i), i);
|
registerAA(*new AADereferenceableCallSiteArgument(CS, i), i);
|
||||||
|
|
||||||
// Call site argument attribute "align".
|
// Call site argument attribute "align".
|
||||||
if (!Whitelist || Whitelist->count(AAAlignCallSiteArgument::ID))
|
if (!Whitelist || Whitelist->count(&AAAlignCallSiteArgument::ID))
|
||||||
registerAA(*new AAAlignCallSiteArgument(CS, i), i);
|
registerAA(*new AAAlignCallSiteArgument(CS, i), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2817,6 +2818,20 @@ struct AttributorLegacyPass : public ModulePass {
|
||||||
Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
|
Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
|
||||||
|
|
||||||
char AttributorLegacyPass::ID = 0;
|
char AttributorLegacyPass::ID = 0;
|
||||||
|
|
||||||
|
const char AAReturnedValues::ID = 0;
|
||||||
|
const char AANoUnwind::ID = 0;
|
||||||
|
const char AANoSync::ID = 0;
|
||||||
|
const char AANoFreeFunction::ID = 0;
|
||||||
|
const char AANonNull::ID = 0;
|
||||||
|
const char AANoRecurse::ID = 0;
|
||||||
|
const char AAWillReturn::ID = 0;
|
||||||
|
const char AANoAlias::ID = 0;
|
||||||
|
const char AANoReturn::ID = 0;
|
||||||
|
const char AAIsDead::ID = 0;
|
||||||
|
const char AADereferenceable::ID = 0;
|
||||||
|
const char AAAlign::ID = 0;
|
||||||
|
|
||||||
INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
|
INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
|
||||||
"Deduce and propagate attributes", false, false)
|
"Deduce and propagate attributes", false, false)
|
||||||
INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
|
INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
|
||||||
|
|
Loading…
Reference in New Issue