[PATCH] D22949: Speed up Function::isIntrinsic() by adding a bit to GlobalValue. NFC
Justin Bogner via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 2 11:23:50 PDT 2016
Justin Lebar <jlebar at google.com> writes:
> jlebar created this revision.
> jlebar added reviewers: bogner, arsenm, joker-eph.
> jlebar added subscribers: llvm-commits, sanjoy.
>
> Previously isIntrinsic() called getName(). This involves a hashtable
> lookup, so is nontrivially expensive. And isIntrinsic() is called
> frequently, particularly by dyn_cast<IntrinsicInstr>.
>
> This patch steals a bit of IntID and uses that to store whether or not
> getName() starts with "llvm."
I'm a bit less comfortable with this change than I was with the other
one - it's more of a straight performance hack this way, whereas the
other way fit better in a future where target-specific intrinsics are
more of a first class idea.
I'll let others comment on whether or not this is worth it as a
hopefully temporary thing for the performance gain in the short term.
> https://reviews.llvm.org/D22949
>
> Files:
> include/llvm/IR/Function.h
> include/llvm/IR/GlobalValue.h
> lib/IR/Function.cpp
>
> Index: lib/IR/Function.cpp
> ===================================================================
> --- lib/IR/Function.cpp
> +++ lib/IR/Function.cpp
> @@ -271,6 +271,7 @@
> if (ParentModule)
> ParentModule->getFunctionList().push_back(this);
>
> + HasLLVMReservedName = getName().startswith("llvm.");
> // Ensure intrinsics have the right parameter attributes.
> // Note, the IntID field will have been set in Value::setName if this function
> // name is a valid intrinsic ID.
> @@ -488,9 +489,7 @@
>
> /// \brief This does the actual lookup of an intrinsic ID which
> /// matches the given function name.
> -static Intrinsic::ID lookupIntrinsicID(const ValueName *ValName) {
> - StringRef Name = ValName->getKey();
> -
> +static Intrinsic::ID lookupIntrinsicID(StringRef Name) {
> ArrayRef<const char *> NameTable = findTargetSubtable(Name);
> int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name);
> if (Idx == -1)
> @@ -508,12 +507,14 @@
> }
>
> void Function::recalculateIntrinsicID() {
> - const ValueName *ValName = this->getValueName();
> - if (!ValName || !isIntrinsic()) {
> + StringRef Name = getName();
> + if (!Name.startswith("llvm.")) {
> + HasLLVMReservedName = false;
> IntID = Intrinsic::not_intrinsic;
> return;
> }
> - IntID = lookupIntrinsicID(ValName);
> + HasLLVMReservedName = true;
> + IntID = lookupIntrinsicID(Name);
> }
>
> /// Returns a stable mangling for the type specified for use in the name
> Index: include/llvm/IR/GlobalValue.h
> ===================================================================
> --- include/llvm/IR/GlobalValue.h
> +++ include/llvm/IR/GlobalValue.h
> @@ -72,7 +72,7 @@
> ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility),
> UnnamedAddrVal(unsigned(UnnamedAddr::None)),
> DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal),
> - IntID((Intrinsic::ID)0U), Parent(nullptr) {
> + IntID((Intrinsic::ID)0U), HasLLVMReservedName(false), Parent(nullptr) {
> setName(Name);
> }
>
> @@ -128,7 +128,12 @@
> /// 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;
> + Intrinsic::ID IntID : 31;
> +
> + /// True if the function's name starts with "llvm.". This corresponds to the
> + /// value of Function::isIntrinsic(), which may be true even if
> + /// Function::intrinsicID() returns Intrinsic::not_intrinsic.
> + bool HasLLVMReservedName : 1;
>
> unsigned getGlobalValueSubClassData() const {
> return SubClassData;
> Index: include/llvm/IR/Function.h
> ===================================================================
> --- include/llvm/IR/Function.h
> +++ include/llvm/IR/Function.h
> @@ -137,7 +137,11 @@
> /// The particular intrinsic functions which correspond to this value are
> /// defined in llvm/Intrinsics.h.
> Intrinsic::ID getIntrinsicID() const LLVM_READONLY { return IntID; }
> - bool isIntrinsic() const { return getName().startswith("llvm."); }
> +
> + /// isIntrinsic - Returns true if the function's name starts with "llvm.".
> + /// It's possible for this function to return true while getIntrinsicID()
> + /// returns Intrinsic::not_intrinsic!
> + bool isIntrinsic() const { return HasLLVMReservedName; }
>
> /// \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
>
>
> Index: lib/IR/Function.cpp
> ===================================================================
> --- lib/IR/Function.cpp
> +++ lib/IR/Function.cpp
> @@ -271,6 +271,7 @@
> if (ParentModule)
> ParentModule->getFunctionList().push_back(this);
>
> + HasLLVMReservedName = getName().startswith("llvm.");
> // Ensure intrinsics have the right parameter attributes.
> // Note, the IntID field will have been set in Value::setName if this function
> // name is a valid intrinsic ID.
> @@ -488,9 +489,7 @@
>
> /// \brief This does the actual lookup of an intrinsic ID which
> /// matches the given function name.
> -static Intrinsic::ID lookupIntrinsicID(const ValueName *ValName) {
> - StringRef Name = ValName->getKey();
> -
> +static Intrinsic::ID lookupIntrinsicID(StringRef Name) {
> ArrayRef<const char *> NameTable = findTargetSubtable(Name);
> int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name);
> if (Idx == -1)
> @@ -508,12 +507,14 @@
> }
>
> void Function::recalculateIntrinsicID() {
> - const ValueName *ValName = this->getValueName();
> - if (!ValName || !isIntrinsic()) {
> + StringRef Name = getName();
> + if (!Name.startswith("llvm.")) {
> + HasLLVMReservedName = false;
> IntID = Intrinsic::not_intrinsic;
> return;
> }
> - IntID = lookupIntrinsicID(ValName);
> + HasLLVMReservedName = true;
> + IntID = lookupIntrinsicID(Name);
> }
>
> /// Returns a stable mangling for the type specified for use in the name
> Index: include/llvm/IR/GlobalValue.h
> ===================================================================
> --- include/llvm/IR/GlobalValue.h
> +++ include/llvm/IR/GlobalValue.h
> @@ -72,7 +72,7 @@
> ValueType(Ty), Linkage(Linkage), Visibility(DefaultVisibility),
> UnnamedAddrVal(unsigned(UnnamedAddr::None)),
> DllStorageClass(DefaultStorageClass), ThreadLocal(NotThreadLocal),
> - IntID((Intrinsic::ID)0U), Parent(nullptr) {
> + IntID((Intrinsic::ID)0U), HasLLVMReservedName(false), Parent(nullptr) {
> setName(Name);
> }
>
> @@ -128,7 +128,12 @@
> /// 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;
> + Intrinsic::ID IntID : 31;
> +
> + /// True if the function's name starts with "llvm.". This corresponds to the
> + /// value of Function::isIntrinsic(), which may be true even if
> + /// Function::intrinsicID() returns Intrinsic::not_intrinsic.
> + bool HasLLVMReservedName : 1;
>
> unsigned getGlobalValueSubClassData() const {
> return SubClassData;
> Index: include/llvm/IR/Function.h
> ===================================================================
> --- include/llvm/IR/Function.h
> +++ include/llvm/IR/Function.h
> @@ -137,7 +137,11 @@
> /// The particular intrinsic functions which correspond to this value are
> /// defined in llvm/Intrinsics.h.
> Intrinsic::ID getIntrinsicID() const LLVM_READONLY { return IntID; }
> - bool isIntrinsic() const { return getName().startswith("llvm."); }
> +
> + /// isIntrinsic - Returns true if the function's name starts with "llvm.".
> + /// It's possible for this function to return true while getIntrinsicID()
> + /// returns Intrinsic::not_intrinsic!
> + bool isIntrinsic() const { return HasLLVMReservedName; }
>
> /// \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
More information about the llvm-commits
mailing list