<div dir="ltr">Hi David,<div><br></div><div>Do you have any comments on this change? I'm loath to commit it without your say-so.</div><div><br></div><div>Cheers,</div><div>James</div></div><div class="gmail_extra"><br>
<br><div class="gmail_quote">On 11 August 2014 16:29, James Molloy <span dir="ltr"><<a href="mailto:james@jamesmolloy.co.uk" target="_blank">james@jamesmolloy.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Hi David,<div><br></div><div>OK, having taken a second look the unique_ptr idiom doesn't look so bad. Attached is what I've come up with - given I'm new to the idiom, would you mind taking a look before I commit?</div>

<div><br></div><div>Cheers,</div><div><br></div><div>James</div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On 8 August 2014 17:02, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>On Fri, Aug 8, 2014 at 8:39 AM, James Molloy <<a href="mailto:james@jamesmolloy.co.uk" target="_blank">james@jamesmolloy.co.uk</a>> wrote:<br>


> Hi David,<br>
><br>
> Partly this may be to do with my unfamiliarity with the unique_ptr idiom,<br>
> and may be using it incorrectly. We're talking about pointers to "class<br>
> Chain", which reside in two containers:<br>
><br>
> std::set<Chain*> AllChains;<br>
> std::map<unsigned, Chain*> ActiveChains;<br>
><br>
> AllChains obviously contains all the chains, and ActiveChains may contain a<br>
> subset of AllChains (as values); there may be duplicates too.<br>
<br>
</div>There may be duplicates in ActiveChains, that is? (AllChains is a set,<br>
so it's safe/unique)<br>
<br>
So ActiveChains both contains not all chains and duplicate chains - so<br>
it's not directly a candidate for single ownership, at least.<br>
<div><br>
> To make this<br>
> work, I'd need to change AllChains to be a std::set<std::unique_ptr<Chain>>,<br>
> and would have to use "::get()" to get the unmanaged version of the pointer<br>
> before it could be passed into ActiveChains, as I'm effectively duplicating<br>
> the pointer. This seems to hack around the intended semantics (shared_ptr<br>
> might be better here?).<br>
<br>
</div>I don't think this is hacking around the intended semantics,<br>
necessarily. The names (ActiveChains and AllChains) actually give a<br>
pretty good indicator to me, the unknowing reader, that ActiveChains<br>
is a subset of AllChains (I wouldn't've guessed that ActiveChains<br>
might have duplicates, but that's not too important) and seeing<br>
AllChains have unique_ptr and ActiveChains have raw (non-owning)<br>
pointer would help cement that for me. "Oh, I see, AllChains owns the<br>
Chains and ActiveChains has non-owning pointers to those same Chains"<br>
is how I'd read that.<br>
<div><br>
><br>
> Secondly the loops become more clunky. From:<br>
><br>
>   for (auto *I : AllChains)<br>
>     EC.insert(I);<br>
><br>
>   for (auto *I : AllChains) {<br>
>     for (auto *J : AllChains) {<br>
>       if (I != J && I->rangeOverlapsWith(J))<br>
>         EC.unionSets(I, J);<br>
>     }<br>
>   }<br>
><br>
><br>
> to:<br>
><br>
>   for (auto &I : AllChains)<br>
>     EC.insert(I.get());<br>
<br>
</div>This one's just a necessary thing - I don't think it's overly clunky.<br>
(I could think of some other things to do, but they wouldn't really be<br>
better)<br>
<div><br>
>   for (auto &I : AllChains) {<br>
>     for (auto &J : AllChains) {<br>
>       if (&*I != &*J && I->rangeOverlapsWith(&*J))<br>
>         EC.unionSets(&*I, &*J);<br>
<br>
</div>This bit I /think/ is just your lack of familiarity, and perhaps a few<br>
other things. std::unique_ptr has operator== so you can just do "I ==<br>
J" as you would with raw pointers.<br>
<br>
As for rangeOverlapsWith and unionSets - I've been using unique_ptr as<br>
a great excuse to make more functions take references rather than<br>
pointers. If unionSets and rangeOverlapsWith both took Chain& instead<br>
of Chain*, then the call sites with unique_ptr or raw pointer would be<br>
the same:<br>
<br>
rangeOverlapsWith(*J)<br>
unionSets(*I, *J)<br>
<br>
And their contracts are clearer - the functions can't take null/non-values, etc.<br>
<div><div><br>
>     }<br>
>   }<br>
><br>
> (where I've written &* I could have used .get()).<br>
><br>
> Am I misusing the idiom? What would you recommend?<br>
><br>
> Cheers,<br>
><br>
> James<br>
><br>
><br>
><br>
> On 8 August 2014 16:27, David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>> wrote:<br>
>><br>
>> On Fri, Aug 8, 2014 at 5:43 AM, James Molloy <<a href="mailto:james@jamesmolloy.co.uk" target="_blank">james@jamesmolloy.co.uk</a>><br>
>> wrote:<br>
>> > Thanks Tim,<br>
>> ><br>
>> > Using unique_ptr ended up making the code harder to read, so I simply<br>
>> > added<br>
>> > a deletion loop which I think is cleaner.<br>
>><br>
>> I haven't looked at this patch in detail, but is there a reasonable<br>
>> summary of why unique_ptr made the code harder to read?<br>
>><br>
>> I'm really interested in making/encouraging ownership to be more<br>
>> explicit/clear and would sometimes even encourage it when it hurts<br>
>> (superficial (which might not be the case here)) readability. It's<br>
>> sometimes the case that ownership looks awkward when you make it<br>
>> explicit because it's an awkward ownership scheme and making it<br>
>> implicit just hinds that complexity (in the not good way of hiding -<br>
>> making it a trap/difficult for others to correctly modify the code in<br>
>> the future).<br>
>><br>
>> - David<br>
>><br>
>> ><br>
>> > Committed in r215199, thankyou to all reviewers!<br>
>> ><br>
>> > Cheers,<br>
>> ><br>
>> > James<br>
>> ><br>
>> ><br>
>> > On 8 August 2014 10:42, Tim Northover <<a href="mailto:t.p.northover@gmail.com" target="_blank">t.p.northover@gmail.com</a>> wrote:<br>
>> >><br>
>> >> Just added llvm-commits.<br>
>> >><br>
>> >> ================<br>
>> >> Comment at: lib/Target/AArch64/AArch64A57FPLoadBalancing.cpp:318<br>
>> >> @@ +317,3 @@<br>
>> >> +  // "link" register between each inst in the chain.<br>
>> >> +  std::map<unsigned, Chain*> ActiveChains;<br>
>> >> +  std::set<Chain*> AllChains;<br>
>> >> ----------------<br>
>> >> Tim Northover wrote:<br>
>> >> > Aren't these chains leaked? It *looks* like you could make this (or<br>
>> >> > the<br>
>> >> > set) a unique_ptr<Chain>.<br>
>> >> Also, this should definitely be the set. I hadn't noticed things get<br>
>> >> removed from ActiveChains when I wrote this. Should have been obvious,<br>
>> >> in<br>
>> >> retrospect.<br>
>> >><br>
>> >> <a href="http://reviews.llvm.org/D4791" target="_blank">http://reviews.llvm.org/D4791</a><br>
>> >><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>
>> > 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>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>