<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Sep 15, 2015, at 9:36 PM, Chandler Carruth via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Sure, I hadn't realized how much this hurt debugging for you. How can we fix it? </div></div></blockquote>How about adding attribute((used)) to these methods?</div><div><br class=""></div><div>We could change the ALWAYS_INLINE macro to also imply used (via a new name probably) if we decided that always inline is an optimization, but that we are happy to still waste a small amount of code size to keep around the definition. Otherwise I guess just add both macro’s to the defs that matter.</div><div><br class=""></div><div>Pete<br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">We're in violent agreement that this is a total workaround that we should do if there is a low cost way, not something we should jsut do blindly.</div><br class=""><div class="gmail_quote"><div dir="ltr" class="">On Tue, Sep 15, 2015 at 8:16 PM Justin Bogner <<a href="mailto:mail@justinbogner.com" class="">mail@justinbogner.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Chandler Carruth via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a>> writes:<br class="">
> Author: chandlerc<br class="">
> Date: Thu Sep 10 03:29:35 2015<br class="">
> New Revision: 247253<br class="">
><br class="">
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=247253&view=rev" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project?rev=247253&view=rev</a><br class="">
> Log:<br class="">
> [ADT] Apply a large hammer to StringRef functions: attribute always_inline.<br class="">
><br class="">
> The logic of this follows something Howard does in libc++ and something<br class="">
> I discussed with Chris eons ago -- for a lot of functions, there is<br class="">
> really no benefit to preserving "debug information" by leaving the<br class="">
> out-of-line even in debug builds. This is especially true as we now do<br class="">
> a very good job of preserving most debug information even in the face of<br class="">
> inlining. There are a bunch of methods in StringRef that we are paying<br class="">
> a completely unacceptable amount for with every debug build of every<br class="">
> LLVM developer.<br class="">
><br class="">
> Some day, we should fix Clang/LLVM so that developers can reasonable<br class="">
> use a default of something other than '-O0' and not waste their lives<br class="">
> waiting on *completely* unoptimized code to execute. We should have<br class="">
> a default that doesn't impede debugging while providing at least<br class="">
> plausable performance.<br class="">
><br class="">
> But today is not that day.<br class="">
><br class="">
> So today, I'm applying always_inline to the functions that are really<br class="">
> hurting the critical path for stuff like 'check_llvm'. I'm being very<br class="">
> cautious here, but there are a few other APIs that we really should do<br class="">
> this for as a matter of pragmatism. Hopefully we can rip this out some<br class="">
> day.<br class="">
><br class="">
> With this change, TripleTest.Normalization runtime decreases by over<br class="">
> 10%, and the total 'check-llvm' time on my 48-core box goes from 38s to<br class="">
> just under 37s.<br class="">
><br class="">
> Modified:<br class="">
> llvm/trunk/include/llvm/ADT/StringRef.h<br class="">
><br class="">
> Modified: llvm/trunk/include/llvm/ADT/StringRef.h<br class="">
> URL:<br class="">
> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringRef.h?rev=247253&r1=247252&r2=247253&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringRef.h?rev=247253&r1=247252&r2=247253&view=diff</a><br class="">
> ==============================================================================<br class="">
><br class="">
> --- llvm/trunk/include/llvm/ADT/StringRef.h (original)<br class="">
> +++ llvm/trunk/include/llvm/ADT/StringRef.h Thu Sep 10 03:29:35 2015<br class="">
> @@ -10,6 +10,7 @@<br class="">
> #ifndef LLVM_ADT_STRINGREF_H<br class="">
> #define LLVM_ADT_STRINGREF_H<br class="">
><br class="">
> +#include "llvm/Support/Compiler.h"<br class="">
> #include <algorithm><br class="">
> #include <cassert><br class="">
> #include <cstring><br class="">
> @@ -53,6 +54,7 @@ namespace llvm {<br class="">
><br class="">
> // Workaround memcmp issue with null pointers (undefined behavior)<br class="">
> // by providing a specialized version<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {<br class="">
> if (Length == 0) { return 0; }<br class="">
> return ::memcmp(Lhs,Rhs,Length);<br class="">
> @@ -63,9 +65,11 @@ namespace llvm {<br class="">
> /// @{<br class="">
><br class="">
<br class="">
> /// Construct an empty string ref.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> /*implicit*/ StringRef() : Data(nullptr), Length(0) {}<br class="">
><br class="">
> /// Construct a string ref from a cstring.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> /*implicit*/ StringRef(const char *Str)<br class="">
> : Data(Str) {<br class="">
> assert(Str && "StringRef cannot be built from a NULL argument");<br class="">
> @@ -73,6 +77,7 @@ namespace llvm {<br class="">
> }<br class="">
><br class="">
> /// Construct a string ref from a pointer and length.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> /*implicit*/ StringRef(const char *data, size_t length)<br class="">
> : Data(data), Length(length) {<br class="">
> assert((data || length == 0) &&<br class="">
> @@ -80,6 +85,7 @@ namespace llvm {<br class="">
> }<br class="">
><br class="">
> /// Construct a string ref from an std::string.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> /*implicit*/ StringRef(const std::string &Str)<br class="">
> : Data(Str.data()), Length(Str.length()) {}<br class="">
<br class="">
This makes constructing StringRefs in lldb basically impossible, which<br class="">
means that functions in llvm that take a string for an argument are<br class="">
basically uncallable in a debugger. So, basically, this makes my life<br class="">
much worse. I'm fine with making "-O0 -g" builds faster if there isn't<br class="">
really a cost to it, but this kind of thing is just a work around for<br class="">
the fact that nobody's bothering to invest in making optimized debugging<br class="">
in llvm useable. The trade off is wrong.<br class="">
<br class="">
><br class="">
> @@ -104,12 +110,15 @@ namespace llvm {<br class="">
><br class="">
> /// data - Get a pointer to the start of the string (which may not be null<br class="">
> /// terminated).<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> const char *data() const { return Data; }<br class="">
><br class="">
> /// empty - Check if the string is empty.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> bool empty() const { return Length == 0; }<br class="">
><br class="">
> /// size - Get the string size.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> size_t size() const { return Length; }<br class="">
><br class="">
> /// front - Get the first character in the string.<br class="">
> @@ -133,6 +142,7 @@ namespace llvm {<br class="">
><br class="">
> /// equals - Check for string equality, this is more efficient than<br class="">
> /// compare() when the relative ordering of inequal strings isn't needed.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> bool equals(StringRef RHS) const {<br class="">
> return (Length == RHS.Length &&<br class="">
> compareMemory(Data, RHS.Data, RHS.Length) == 0);<br class="">
> @@ -145,6 +155,7 @@ namespace llvm {<br class="">
><br class="">
> /// compare - Compare two strings; the result is -1, 0, or 1 if this string<br class="">
> /// is lexicographically less than, equal to, or greater than the \p RHS.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> int compare(StringRef RHS) const {<br class="">
> // Check the prefix for a mismatch.<br class="">
> if (int Res = compareMemory(Data, RHS.Data, std::min(Length, RHS.Length)))<br class="">
> @@ -212,6 +223,7 @@ namespace llvm {<br class="">
> /// @{<br class="">
><br class="">
> /// Check if this string starts with the given \p Prefix.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> bool startswith(StringRef Prefix) const {<br class="">
> return Length >= Prefix.Length &&<br class="">
> compareMemory(Data, Prefix.Data, Prefix.Length) == 0;<br class="">
> @@ -221,6 +233,7 @@ namespace llvm {<br class="">
> bool startswith_lower(StringRef Prefix) const;<br class="">
><br class="">
> /// Check if this string ends with the given \p Suffix.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> bool endswith(StringRef Suffix) const {<br class="">
> return Length >= Suffix.Length &&<br class="">
> compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;<br class="">
> @@ -237,6 +250,7 @@ namespace llvm {<br class="">
> ///<br class="">
> /// \returns The index of the first occurrence of \p C, or npos if not<br class="">
> /// found.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> size_t find(char C, size_t From = 0) const {<br class="">
> size_t FindBegin = std::min(From, Length);<br class="">
> if (FindBegin < Length) { // Avoid calling memchr with nullptr.<br class="">
> @@ -402,6 +416,7 @@ namespace llvm {<br class="">
> /// \param N The number of characters to included in the substring. If N<br class="">
> /// exceeds the number of characters remaining in the string, the string<br class="">
> /// suffix (starting with \p Start) will be returned.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> StringRef substr(size_t Start, size_t N = npos) const {<br class="">
> Start = std::min(Start, Length);<br class="">
> return StringRef(Data + Start, std::min(N, Length - Start));<br class="">
> @@ -409,6 +424,7 @@ namespace llvm {<br class="">
><br class="">
> /// Return a StringRef equal to 'this' but with the first \p N elements<br class="">
> /// dropped.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> StringRef drop_front(size_t N = 1) const {<br class="">
> assert(size() >= N && "Dropping more elements than exist");<br class="">
> return substr(N);<br class="">
> @@ -416,6 +432,7 @@ namespace llvm {<br class="">
><br class="">
> /// Return a StringRef equal to 'this' but with the last \p N elements<br class="">
> /// dropped.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> StringRef drop_back(size_t N = 1) const {<br class="">
> assert(size() >= N && "Dropping more elements than exist");<br class="">
> return substr(0, size()-N);<br class="">
> @@ -431,6 +448,7 @@ namespace llvm {<br class="">
> /// substring. If this is npos, or less than \p Start, or exceeds the<br class="">
> /// number of characters remaining in the string, the string suffix<br class="">
> /// (starting with \p Start) will be returned.<br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> StringRef slice(size_t Start, size_t End) const {<br class="">
> Start = std::min(Start, Length);<br class="">
> End = std::min(std::max(Start, End), Length);<br class="">
> @@ -547,10 +565,12 @@ namespace llvm {<br class="">
> /// @name StringRef Comparison Operators<br class="">
> /// @{<br class="">
><br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> inline bool operator==(StringRef LHS, StringRef RHS) {<br class="">
> return LHS.equals(RHS);<br class="">
> }<br class="">
><br class="">
> + LLVM_ATTRIBUTE_ALWAYS_INLINE<br class="">
> inline bool operator!=(StringRef LHS, StringRef RHS) {<br class="">
> return !(LHS == RHS);<br class="">
> }<br class="">
><br class="">
><br class="">
> _______________________________________________<br class="">
> llvm-commits mailing list<br class="">
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank" class="">llvm-commits@lists.llvm.org</a><br class="">
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br class="">
</blockquote></div>
_______________________________________________<br class="">llvm-commits mailing list<br class=""><a href="mailto:llvm-commits@lists.llvm.org" class="">llvm-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits<br class=""></div></blockquote></div><br class=""></body></html>