<div dir="rtl"><div dir="ltr">With a helper function we can get a global StringRef without a constructor call, try this:</div><div dir="ltr"><br></div><div dir="ltr"><font face="monospace, monospace">class StringRef {</font></div><div dir="ltr"><font face="monospace, monospace">...</font></div><div dir="ltr"><font face="monospace, monospace">    template <unsigned N></font></div><div dir="ltr"><font face="monospace, monospace">    static constexpr StringRef create(char const(&Str)[N]) {</font></div><div dir="ltr"><font face="monospace, monospace">      return StringRef(Str, N - 1);</font></div><div dir="ltr"><font face="monospace, monospace">    }</font></div><div dir="ltr"><font face="monospace, monospace">...</font></div><div dir="ltr"><font face="monospace, monospace">}</font></div><div dir="ltr"><font face="monospace, monospace"><br></font></div><div dir="ltr"><font face="monospace, monospace">...</font></div><div dir="ltr"><div dir="ltr"><font face="monospace, monospace">const char hello[] = "hello";</font></div><div dir="ltr"><font face="monospace, monospace">const llvm::StringRef Hello = llvm::StringRef::create(hello);</font></div><div dir="ltr"><font face="monospace, monospace">bool ggg(llvm::StringRef s) { return s != Hello; }</font></div><div><br></div></div><div dir="ltr"><br></div></div><div class="gmail_extra"><div dir="ltr"><br><div class="gmail_quote">2015-06-08 0:11 GMT+03:00 Yaron Keren <span dir="ltr"><<a href="mailto:yaron.keren@gmail.com" target="_blank">yaron.keren@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 .8ex;border-left:1px #ccc solid;border-right:1px #ccc solid;padding-left:1ex;padding-right:1ex"><div dir="rtl"><div dir="ltr">Yes, I see. I had tried a small example with clang r239218, below. The global StringRef indeed requires a global constructor which is bad. The strlen call in the const char * version is optimized away even in -O2. It would be very nice if StringRef constructor would be optimized the same.</div><div dir="ltr"><br></div><div dir="ltr">The C++ code</div><div dir="ltr"><br></div><div dir="ltr"><div dir="ltr"><font face="monospace, monospace">#include "llvm/ADT/StringRef.h"</font></div><div dir="ltr"><font face="monospace, monospace">const char *const hello = "hello";</font></div><div dir="ltr"><font face="monospace, monospace">bool fff(llvm::StringRef s) { return s != hello; }<br></font></div><div dir="ltr"><font face="monospace, monospace">llvm::StringRef Hello(hello);</font></div><div dir="ltr"><font face="monospace, monospace">bool ggg(llvm::StringRef s) { return s != Hello; }</font></div><div><br></div><div>compiled with</div><div><br></div><div><font face="monospace, monospace">clang -O3 a.cpp -std=c++11 -I c:\llvm\include -S -emit-llvm</font><br></div><div><br></div></div><div><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote"><div dir="ltr">2015-06-07 23:31 GMT+03:00 Benjamin Kramer <span dir="ltr"><<a href="mailto:benny.kra@gmail.com" target="_blank">benny.kra@gmail.com</a>></span>:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span><br>
> On 07.06.2015, at 22:26, Yaron Keren <<a href="mailto:yaron.keren@gmail.com" target="_blank">yaron.keren@gmail.com</a>> wrote:<br>
><br>
> > Which doesn't matter at all because a StringRef is just a pointer + size and the size can be determined statically<br>
> >for GCSafepointPollName. The StringRef construction is folded away completely at clang -O3.<br>
><br>
> A global variable StringRef(const char *) does not get optimized the same way?<br>
<br>
</span>Exactly. This is a deficiency in LLVM's optimizer but one that's very hard to fix. Clang emits a writeable global and a function to initialize it which is called by the linker at startup. The optimizer tries to statically evaluate the function but that often fails.<br>
<br>
- Ben<br>
<div><div><br>
> 2015-06-07 22:44 GMT+03:00 Benjamin Kramer <<a href="mailto:benny.kra@gmail.com" target="_blank">benny.kra@gmail.com</a>>:<br>
><br>
> > On 07.06.2015, at 21:33, Yaron Keren <<a href="mailto:yaron.keren@gmail.com" target="_blank">yaron.keren@gmail.com</a>> wrote:<br>
> ><br>
> > If StringRef (const char *) is optimized away than StringRef GCSafepointPollName is better.<br>
><br>
> This creates the global in .bss and writes to it in a global constructor at clang -O3. This also means that LLVM cannot constant fold accesses to the global variable.<br>
><br>
> > If StringRef (const char *) is not optimized away then<br>
> ><br>
> > static bool isGCSafepointPoll(Function &F) {<br>
> >   return F.getName().equals(GCSafepointPollName);<br>
> > }<br>
> ><br>
> > will construct a StringRef on every call to isGCSafepointPoll instead of once globally.<br>
><br>
> Which doesn't matter at all because a StringRef is just a pointer + size and the size can be determined statically for GCSafepointPollName. The StringRef construction is folded away completely at clang -O3.<br>
><br>
> - Ben<br>
><br>
> ><br>
> ><br>
> > 2015-06-07 22:13 GMT+03:00 Benjamin Kramer <<a href="mailto:benny.kra@gmail.com" target="_blank">benny.kra@gmail.com</a>>:<br>
> ><br>
> > > On 07.06.2015, at 20:24, Yaron Keren <<a href="mailto:yaron.keren@gmail.com" target="_blank">yaron.keren@gmail.com</a>> wrote:<br>
> > ><br>
> > > I don't think any of this would actually matter since all would be optimized away, but if anything, it's probably best to match GCSafepointPollName two code users which expect a StringRef by making this a static StringRef.<br>
> > ><br>
> > > In general, unless a null-terminated C string is actually required (for example, for OS API) StringRefs are always superior  to const char *. Just think about the easy mistake S == "some string".<br>
> ><br>
> > I don't know of a compiler that can optimize away global std::strings, it is very hard and probably not feasible without a domain-specific C++ optimizer. Clang for example emits a global constructor and destructor for this example which is badness.<br>
> ><br>
> > I agree that StringRef is superior but not in a global variable. LLVM's globalopt can optimize them away if you get lucky, but I don't want to rely on that. The only acceptable way for complex types in global constants is constexpr, but making StringRef's ctor constexpr isn't possible because of the strlen call in there.<br>
> ><br>
> > We also have warnings for common char* misuse in clang.<br>
> ><br>
> > - Ben<br>
> ><br>
> > ><br>
> > ><br>
> > > 2015-06-07 19:36 GMT+03:00 Benjamin Kramer <<a href="mailto:benny.kra@googlemail.com" target="_blank">benny.kra@googlemail.com</a>>:<br>
> > > Author: d0k<br>
> > > Date: Sun Jun  7 11:36:28 2015<br>
> > > New Revision: 239254<br>
> > ><br>
> > > URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D239254-26view-3Drev&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=kN1Y_cSz1YI5-f_4fpMWnaeDImulYIXzpypTMME2jIs&s=zFkccdUtNNrWGr5GLx35ZlMsGwB3_2xzyBG5t10lRzU&e=" target="_blank">http://llvm.org/viewvc/llvm-project?rev=239254&view=rev</a><br>
> > > Log:<br>
> > > Remove global std::string. NFC.<br>
> > ><br>
> > > Modified:<br>
> > >     llvm/trunk/lib/Transforms/Scalar/PlaceSafepoints.cpp<br>
> > ><br>
> > > Modified: llvm/trunk/lib/Transforms/Scalar/PlaceSafepoints.cpp<br>
> > > URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_llvm_trunk_lib_Transforms_Scalar_PlaceSafepoints.cpp-3Frev-3D239254-26r1-3D239253-26r2-3D239254-26view-3Ddiff&d=AwMFaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=mQ4LZ2PUj9hpadE3cDHZnIdEwhEBrbAstXeMaFoB9tg&m=kN1Y_cSz1YI5-f_4fpMWnaeDImulYIXzpypTMME2jIs&s=hKHK5XeD-bf2lkt18-jp94LHP1xXV6calUadIeMi_DE&e=" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/PlaceSafepoints.cpp?rev=239254&r1=239253&r2=239254&view=diff</a><br>
> > > ==============================================================================<br>
> > > --- llvm/trunk/lib/Transforms/Scalar/PlaceSafepoints.cpp (original)<br>
> > > +++ llvm/trunk/lib/Transforms/Scalar/PlaceSafepoints.cpp Sun Jun  7 11:36:28 2015<br>
> > > @@ -496,7 +496,7 @@ template <typename T> static void unique<br>
> > >    }<br>
> > >  }<br>
> > ><br>
> > > -static std::string GCSafepointPollName("gc.safepoint_poll");<br>
> > > +static const char *const GCSafepointPollName = "gc.safepoint_poll";<br>
> > ><br>
> > >  static bool isGCSafepointPoll(Function &F) {<br>
> > >    return F.getName().equals(GCSafepointPollName);<br>
> > ><br>
> > ><br>
> > > _______________________________________________<br>
> > > llvm-commits mailing list<br>
> > > <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
> > > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
> > ><br>
> ><br>
> ><br>
><br>
><br>
<br>
</div></div></blockquote></div><br></div></div></div></div>
</blockquote></div></div></div>