[llvm-commits] Twines
Chris Lattner
clattner at apple.com
Thu Jul 23 19:13:27 PDT 2009
Ok, sounds great!
-Chris
On Jul 23, 2009, at 6:26 PM, Daniel Dunbar wrote:
> On Thu, Jul 23, 2009 at 11:41 AM, Chris Lattner<clattner at apple.com>
> wrote:
>> On Jul 23, 2009, at 12:26 AM, Daniel Dunbar wrote:
>>> There are also a number of hacks to make introducing Twines easier,
>>> which should be removed:
>>> 1. Twine shouldn't actually have a conversion operator to
>>> std::string.
>>> 2. The patch hacks in support for writing StringRef's to
>>> std::ostream, we should move clients to raw_ostream instead.
>>> 3. We probably don't want Twine.h in Value.h, clients should
>>> explicitly import it if they want to get implicit string
>>> concatenation.
>>
>>
>> You're planning to do this as a follow-on, right?
>
> Yes to #1 and #2. Chris and I discussed #3 and decided that including
> Twine.h in Value.h was reasonable. I need to do some more prep on #s 1
> and 2 to know exactly how much work is involved -- hopefully it
> doesn't amount to converting everything to raw_ostream. :)
>
>> It would also be nice to remove a bunch of the Value::*Name* methods.
>
> Definitely.
>
>> Please also add a short mention of this in the ProgrammersManual.html
>> file (datastructure section).
>
> Certainly. I have adding both StringRef and Twine docs on my TODO
> list, I'll probably try to have patches for all this stuff before I
> actually bring it in.
>
>> +++ include/llvm/ADT/Twine.h (revision 0)
>>
>> + /// A Twine is a kind of rope, it represents a concatenated string
>> by a
>> + /// binary-tree, where the string is the preorder of the nodes.
>> Since the
>>
>> "by a" -> "with a" or "as a"
>
>
>> + // FIXME: We could normalize "" (in its C string, StringRef, and
>> std::string)
>> + // spellings to Empty. I decided this was not worth the effort,
>> complexity, or
>> + // increased code size; clients rarely concatenate empty strings?
>>
>> I agree, don't worry about empty strings.
>
> Ok. One case Chris and I did decide to handle is to make sure that a
> call to
> --
> void f0(const Twine &Name = "");
> --
> can be optimized so that there isn't a reference to an empty string.
> This is important, since otherwise we would want to write such
> functions using Twine() as a default value, and I much prefer the
> readability of the former.
>
>> + /// LHSKind - The NodeKind of the left hand side, \see
>> getLHSKind().
>> + unsigned LHSKind : 8;
>> + /// RHSKind - The NodeKind of the left hand side, \see
>> getLHSKind().
>> + unsigned RHSKind : 8;
>>
>> Please declare as "NodeKind LHSKind : 8;"
>
> Ok. I get paranoid about using enumerations in bitfields but this
> case is safe.
>
>> +++ lib/Support/Twine.cpp (revision 0)
>> @@ -0,0 +1,83 @@
>> +//===-- Twine.h - Fast Temporary String Concatenation
>> ---------------------===//
>>
>> Please s/.h/.cpp.
>
> Ok.
>
>> +std::string Twine::str() const {
>> + std::string Res;
>> + raw_string_ostream OS(Res);
>> + print(OS);
>> + return Res;
>> +}
>>
>> Do you anticipate the performance of this method to matter? If so,
>> you could do a pre-traversal to get a bound for the length of the
>> resultant string, then do a reserve, then get the contents.
>
> I thought about that, but I think the current method is likely faster.
> raw_ostream has a large buffer, so I think the negative effects of
> chasing the rope twice would be worse on average than the cost of
> occasionally concatenating multiple times to an std::string. Of
> course, it could be rewritten to use a small vector, but if we cared
> we should just do that inside raw_string_ostream. Actually I think I
> just realized that is a nice idea for a different reason...
>
>> + case Twine::CStringKind:
>> + OS << static_cast<const char*>(Ptr); break;
>> + case Twine::StdStringKind:
>> + OS << *static_cast<const std::string*>(Ptr); break;
>> + case Twine::StringRefKind:
>> + OS << *static_cast<const StringRef*>(Ptr); break;
>> + case Twine::TwineKind:
>> + static_cast<const Twine*>(Ptr)->print(OS); break;
>>
>> Please put the breaks on their own line unless the whole statement is
>> on one line with the 'case'.
>
> Ok.
>
>> +++ include/llvm/ADT/StringRef.h (working copy)
>> @@ -171,6 +171,16 @@
>>
>> /// @}
>>
>> + struct StringRefWrapper {
>> + const StringRef &Str;
>> + StringRefWrapper(const StringRef &_Str) : Str(_Str) {}
>> + };
>> +
>> + template<typename T>
>> + T &operator<<(T &OS, const StringRefWrapper &RHS) {
>> + OS.write(RHS.Str.data(), RHS.Str.size());
>> + return OS;
>> + }
>> }
>>
>> Why do you need StringRefWrapper? I assume this is due to ambiguity,
>> please add a comment.
>
> Yes, its a temporary hack just to minimize the changes in any one
> patch. I'll add an explanation and FIXME, but my hope is to bring it
> in then eliminate it.
>
>> +++ tools/bugpoint/ExtractFunction.cpp (working copy)
>> @@ -353,7 +353,8 @@
>> // If the BB doesn't have a name, give it one so we have
>> something to key
>> // off of.
>> if (!BB->hasName()) BB->setName("tmpbb");
>> - BlocksToNotExtractFile << BB->getParent()->getName() << " "
>> + // FIXME: Remove explicit .str() call once ambiguous overload
>> goes away.
>> + BlocksToNotExtractFile << BB->getParent()->getName().str() <<
>> " "
>> << BB->getName() << "\n";
>> }
>> BlocksToNotExtractFile.close();
>> Index: unittests/ADT/StringRefTest.cpp
>> ===================================================================
>> --- unittests/ADT/StringRefTest.cpp (revision 76864)
>> +++ unittests/ADT/StringRefTest.cpp (working copy)
>> @@ -70,7 +70,8 @@
>>
>> std::string Storage;
>> raw_string_ostream OS(Storage);
>> - OS << StringRef("hello");
>> + // FIXME: Remove .str() when overload is fixed.
>> + OS << StringRef("hello").str();
>> EXPECT_EQ("hello", OS.str());
>> }
>>
>> When will the fixme's be resolved?
>
> I hope to resolve them immediately, just in separate patches.
>
> - Daniel
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list