[ADT] Apply a large hammer to StringRef functions: attribute always_inline.

The logic of this follows something Howard does in libc++ and something
I discussed with Chris eons ago -- for a lot of functions, there is
really no benefit to preserving "debug information" by leaving the
out-of-line even in debug builds. This is especially true as we now do
a very good job of preserving most debug information even in the face of
inlining. There are a bunch of methods in StringRef that we are paying
a completely unacceptable amount for with every debug build of every
LLVM developer.

Some day, we should fix Clang/LLVM so that developers can reasonable
use a default of something other than '-O0' and not waste their lives
waiting on *completely* unoptimized code to execute. We should have
a default that doesn't impede debugging while providing at least
plausable performance.

But today is not that day.

So today, I'm applying always_inline to the functions that are really
hurting the critical path for stuff like 'check_llvm'. I'm being very
cautious here, but there are a few other APIs that we really should do
this for as a matter of pragmatism. Hopefully we can rip this out some
day.

With this change, TripleTest.Normalization runtime decreases by over
10%, and the total 'check-llvm' time on my 48-core box goes from 38s to
just under 37s.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247253 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2015-09-10 08:29:35 +00:00
parent cfffa6e06a
commit 3dba3be8e5

View File

@ -10,6 +10,7 @@
#ifndef LLVM_ADT_STRINGREF_H
#define LLVM_ADT_STRINGREF_H
#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cstring>
@ -53,6 +54,7 @@ namespace llvm {
// Workaround memcmp issue with null pointers (undefined behavior)
// by providing a specialized version
LLVM_ATTRIBUTE_ALWAYS_INLINE
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
if (Length == 0) { return 0; }
return ::memcmp(Lhs,Rhs,Length);
@ -63,9 +65,11 @@ namespace llvm {
/// @{
/// Construct an empty string ref.
LLVM_ATTRIBUTE_ALWAYS_INLINE
/*implicit*/ StringRef() : Data(nullptr), Length(0) {}
/// Construct a string ref from a cstring.
LLVM_ATTRIBUTE_ALWAYS_INLINE
/*implicit*/ StringRef(const char *Str)
: Data(Str) {
assert(Str && "StringRef cannot be built from a NULL argument");
@ -73,6 +77,7 @@ namespace llvm {
}
/// Construct a string ref from a pointer and length.
LLVM_ATTRIBUTE_ALWAYS_INLINE
/*implicit*/ StringRef(const char *data, size_t length)
: Data(data), Length(length) {
assert((data || length == 0) &&
@ -80,6 +85,7 @@ namespace llvm {
}
/// Construct a string ref from an std::string.
LLVM_ATTRIBUTE_ALWAYS_INLINE
/*implicit*/ StringRef(const std::string &Str)
: Data(Str.data()), Length(Str.length()) {}
@ -104,12 +110,15 @@ namespace llvm {
/// data - Get a pointer to the start of the string (which may not be null
/// terminated).
LLVM_ATTRIBUTE_ALWAYS_INLINE
const char *data() const { return Data; }
/// empty - Check if the string is empty.
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool empty() const { return Length == 0; }
/// size - Get the string size.
LLVM_ATTRIBUTE_ALWAYS_INLINE
size_t size() const { return Length; }
/// front - Get the first character in the string.
@ -133,6 +142,7 @@ namespace llvm {
/// equals - Check for string equality, this is more efficient than
/// compare() when the relative ordering of inequal strings isn't needed.
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool equals(StringRef RHS) const {
return (Length == RHS.Length &&
compareMemory(Data, RHS.Data, RHS.Length) == 0);
@ -145,6 +155,7 @@ namespace llvm {
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
/// is lexicographically less than, equal to, or greater than the \p RHS.
LLVM_ATTRIBUTE_ALWAYS_INLINE
int compare(StringRef RHS) const {
// Check the prefix for a mismatch.
if (int Res = compareMemory(Data, RHS.Data, std::min(Length, RHS.Length)))
@ -212,6 +223,7 @@ namespace llvm {
/// @{
/// Check if this string starts with the given \p Prefix.
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool startswith(StringRef Prefix) const {
return Length >= Prefix.Length &&
compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
@ -221,6 +233,7 @@ namespace llvm {
bool startswith_lower(StringRef Prefix) const;
/// Check if this string ends with the given \p Suffix.
LLVM_ATTRIBUTE_ALWAYS_INLINE
bool endswith(StringRef Suffix) const {
return Length >= Suffix.Length &&
compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
@ -237,6 +250,7 @@ namespace llvm {
///
/// \returns The index of the first occurrence of \p C, or npos if not
/// found.
LLVM_ATTRIBUTE_ALWAYS_INLINE
size_t find(char C, size_t From = 0) const {
size_t FindBegin = std::min(From, Length);
if (FindBegin < Length) { // Avoid calling memchr with nullptr.
@ -402,6 +416,7 @@ namespace llvm {
/// \param N The number of characters to included in the substring. If N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \p Start) will be returned.
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef substr(size_t Start, size_t N = npos) const {
Start = std::min(Start, Length);
return StringRef(Data + Start, std::min(N, Length - Start));
@ -409,6 +424,7 @@ namespace llvm {
/// Return a StringRef equal to 'this' but with the first \p N elements
/// dropped.
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef drop_front(size_t N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(N);
@ -416,6 +432,7 @@ namespace llvm {
/// Return a StringRef equal to 'this' but with the last \p N elements
/// dropped.
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef drop_back(size_t N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(0, size()-N);
@ -431,6 +448,7 @@ namespace llvm {
/// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
/// (starting with \p Start) will be returned.
LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef slice(size_t Start, size_t End) const {
Start = std::min(Start, Length);
End = std::min(std::max(Start, End), Length);
@ -547,10 +565,12 @@ namespace llvm {
/// @name StringRef Comparison Operators
/// @{
LLVM_ATTRIBUTE_ALWAYS_INLINE
inline bool operator==(StringRef LHS, StringRef RHS) {
return LHS.equals(RHS);
}
LLVM_ATTRIBUTE_ALWAYS_INLINE
inline bool operator!=(StringRef LHS, StringRef RHS) {
return !(LHS == RHS);
}