/// intrinsic, or if the pointer is null. This value is always defined to be
/// zero to allow easy checking for whether a function is intrinsic or not.
/// The particular intrinsic functions which correspond to this value are
- /// defined in llvm/Intrinsics.h. Results are cached in the LLVM context,
- /// subsequent requests for the same ID return results much faster from the
- /// cache.
- ///
- unsigned getIntrinsicID() const LLVM_READONLY;
+ /// defined in llvm/Intrinsics.h.
+ unsigned getIntrinsicID() const LLVM_READONLY { return IntID; }
bool isIntrinsic() const { return getName().startswith("llvm."); }
+ /// \brief Recalculate the ID for this function if it is an Intrinsic defined
+ /// in llvm/Intrinsics.h. Sets the intrinsic ID to Intrinsic::not_intrinsic
+ /// if the name of this function does not match an intrinsic in that header.
+ /// Note, this method does not need to be called directly, as it is called
+ /// from Value::setName() whenever the name of this function changes.
+ void recalculateIntrinsicID();
+
/// getCallingConv()/setCallingConv(CC) - These method get and set the
/// calling convention of this function. The enum values for the known
/// calling conventions are defined in CallingConv.h.
class PointerType;
class Module;
+namespace Intrinsic {
+ enum ID : unsigned;
+};
+
class GlobalValue : public Constant {
GlobalValue(const GlobalValue &) = delete;
public:
: Constant(Ty, VTy, Ops, NumOps), Linkage(Linkage),
Visibility(DefaultVisibility), UnnamedAddr(0),
DllStorageClass(DefaultStorageClass),
- ThreadLocal(NotThreadLocal), Parent(nullptr) {
+ ThreadLocal(NotThreadLocal), IntID((Intrinsic::ID)0U), Parent(nullptr) {
setName(Name);
}
// Give subclasses access to what otherwise would be wasted padding.
// (19 + 3 + 2 + 1 + 2 + 5) == 32.
unsigned SubClassData : 19;
+
protected:
+ /// \brief The intrinsic ID for this subclass (which must be a Function).
+ ///
+ /// This member is defined by this class, but not used for anything.
+ /// Subclasses can use it to store their intrinsic ID, if they have one.
+ ///
+ /// This is stored here to save space in Function on 64-bit hosts.
+ Intrinsic::ID IntID;
+
static const unsigned GlobalValueSubClassDataBits = 19;
unsigned getGlobalValueSubClassData() const {
return SubClassData;
/// function known by LLVM. The enum values are returned by
/// Function::getIntrinsicID().
namespace Intrinsic {
- enum ID {
+ enum ID : unsigned {
not_intrinsic = 0, // Must be zero
// Get the intrinsic enums generated from Intrinsics.td
private:
void destroyValueName();
+ void setNameImpl(const Twine &Name);
public:
/// \brief Return a constant reference to the value's name.
ParentModule->getFunctionList().push_back(this);
// Ensure intrinsics have the right parameter attributes.
- if (unsigned IID = getIntrinsicID())
- setAttributes(Intrinsic::getAttributes(getContext(), Intrinsic::ID(IID)));
-
+ // Note, the IntID field will have been set in Value::setName if this function
+ // name is a valid intrinsic ID.
+ if (IntID)
+ setAttributes(Intrinsic::getAttributes(getContext(), IntID));
}
Function::~Function() {
// Remove the function from the on-the-side GC table.
clearGC();
-
- // Remove the intrinsicID from the Cache.
- if (getValueName() && isIntrinsic())
- getContext().pImpl->IntrinsicIDCache.erase(this);
}
void Function::BuildLazyArguments() const {
return Intrinsic::not_intrinsic;
}
-/// getIntrinsicID - This method returns the ID number of the specified
-/// function, or Intrinsic::not_intrinsic if the function is not an
-/// intrinsic, or if the pointer is null. This value is always defined to be
-/// zero to allow easy checking for whether a function is intrinsic or not. The
-/// particular intrinsic functions which correspond to this value are defined in
-/// llvm/Intrinsics.h. Results are cached in the LLVM context, subsequent
-/// requests for the same ID return results much faster from the cache.
-///
-unsigned Function::getIntrinsicID() const {
+void Function::recalculateIntrinsicID() {
const ValueName *ValName = this->getValueName();
- if (!ValName || !isIntrinsic())
- return 0;
-
- LLVMContextImpl::IntrinsicIDCacheTy &IntrinsicIDCache =
- getContext().pImpl->IntrinsicIDCache;
- if (!IntrinsicIDCache.count(this)) {
- unsigned Id = lookupIntrinsicID(ValName);
- IntrinsicIDCache[this]=Id;
- return Id;
+ if (!ValName || !isIntrinsic()) {
+ IntID = Intrinsic::not_intrinsic;
+ return;
}
- return IntrinsicIDCache[this];
+ IntID = lookupIntrinsicID(ValName);
}
/// Returns a stable mangling for the type specified for use in the name
/// instructions in different blocks at the same location.
DenseMap<std::pair<const char *, unsigned>, unsigned> DiscriminatorTable;
- /// IntrinsicIDCache - Cache of intrinsic name (string) to numeric ID mappings
- /// requested in this context
- typedef DenseMap<const Function*, unsigned> IntrinsicIDCacheTy;
- IntrinsicIDCacheTy IntrinsicIDCache;
-
/// \brief Mapping from a function to its prefix data, which is stored as the
/// operand of an unparented ReturnInst so that the prefix data has a Use.
typedef DenseMap<const Function *, ReturnInst *> PrefixDataMapTy;
return getValueName()->getKey();
}
-void Value::setName(const Twine &NewName) {
+void Value::setNameImpl(const Twine &NewName) {
// Fast path for common IRBuilder case of setName("") when there is no name.
if (NewName.isTriviallyEmpty() && !hasName())
return;
if (getSymTab(this, ST))
return; // Cannot set a name on this value (e.g. constant).
- if (Function *F = dyn_cast<Function>(this))
- getContext().pImpl->IntrinsicIDCache.erase(F);
-
if (!ST) { // No symbol table to update? Just do the change.
if (NameRef.empty()) {
// Free the name for this value.
setValueName(ST->createValueName(NameRef, this));
}
+void Value::setName(const Twine &NewName) {
+ setNameImpl(NewName);
+ if (Function *F = dyn_cast<Function>(this))
+ F->recalculateIntrinsicID();
+}
+
void Value::takeName(Value *V) {
ValueSymbolTable *ST = nullptr;
// If this value has a name, drop it.