[llvm-dev] code to sort otherwise-unsortable "ilist"s, e.g. symbol tables

Duncan Exon Smith via llvm-dev llvm-dev at lists.llvm.org
Thu Aug 18 06:42:30 PDT 2016


Thanks for submitting!  I'll likely fix the sort code eventually, so I may use this as a reference.  Another option is to privately split out lower-level versions of some of the functions that avoid triggering the problematic callbacks (my current plan). 

-- dpnes

> On Aug 17, 2016, at 14:03, Justin Bogner <mail at justinbogner.com> wrote:
> 
> +dexonsmith, since he completely changed the implementation of ilist to
> a far more normal one about 15 minutes ago (in r278974)...
> 
> Abe Skolnik via llvm-dev <llvm-dev at lists.llvm.org> writes:
>> Dear all,
>> 
>> The below has been tested quite thoroughly by now, including
>> performance-testing by the way of using a modified compiler that
>> triggers the below while compiling at least an old part of LLVM
>> ["Function.cpp"] and sorting a symbol table with >7000 global
>> variables.
>> 
>> Unfortunately, the optimization I have been working on for which I
>> _thought_ I needed the ability to sort a symbol table is showing poor
>> performance numbers [from the compiled code, not the compiler itself],
>> so I think I probably won`t submit that, at least not in its present
>> form -- maybe in a much-more-limited form that doesn`t need the
>> sorting.  However, I thought this sorting code might be useful to
>> somebody else, so here it is for feedback.
>> 
>> Maybe somebody wants to add the needed glue code so
>> e.g. "my_ilist.sort()" will call the below rather than invoking the
>> relevant ancestor-class "sort()" and crashing?  If so, then ditto for
>> e.g. "my_ilist.sort(my_comparator)", please.
>> 
>> Regards,
>> 
>> Abe
>> 
>> 
>> 
>> 
>> 
>> 
>> ===== snippet from altered "llvm/include/llvm/ADT/ilist.h" =====
>> 
>> ===== context within "ilist.h": the 2nd "public:" section of
>> "template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
>> class iplist : public Traits" =====
>> 
>> 
>> 
>>  template <class Compare>
>>  void sort_without_temporary_list(Compare comp) {
>>    // The list is empty, vacuously sorted.
>>    if (empty())
>>      return;
>>    // The list has a single element, vacuously sorted.
>>    if (std::next(begin()) == end())
>>      return;
>> 
>>    iterator            last_sorted{begin()};
>>    iterator just_after_last_sorted{std::next(last_sorted)};
>>    while (end() != just_after_last_sorted) {
>> 
>>      while ( (end() != just_after_last_sorted) && !
>> comp(*just_after_last_sorted, *last_sorted) ) {
>>        // advance the frontier by one element
>>        ++just_after_last_sorted;
>>        ++           last_sorted;
>>      } // this loop _must_ come _before_ the code to figure out how
>> many elem.s to splice and where to splice them to [place-marker: NOTE
>> 668]
>> 
>>      if (end() != just_after_last_sorted) { // check again in case
>> advancing the frontier finished the job
>> 
>>        // first, find the insertion point for the first-past-the-frontier elem.
>>        iterator insertion_point{begin()};
>>        while ( ! comp(*just_after_last_sorted, *insertion_point) )  ++insertion_point;
>> 
>>        // set up some needed iterators
>>        const iterator just_after_insertion_point{std::next(insertion_point)};
>>        iterator prev_elem_checked_for_order_in_sublist_to_splice{
>> just_after_last_sorted};
>>        iterator
>> just_after_last_elem_in_sublist_to_splice{std::next(just_after_last_sorted)};
>> 
>>        // try to make {the sublist to be spliced} as long as it can be while still being correct
>>        while ( (end() != just_after_last_elem_in_sublist_to_splice) && // ...
>>        /*...*/ ( ! comp(*just_after_insertion_point,
>> *just_after_last_elem_in_sublist_to_splice) ) &&
>>        /*...*/ ! comp(*just_after_last_elem_in_sublist_to_splice,
>> *prev_elem_checked_for_order_in_sublist_to_splice) ) {
>>          // extend the to-splice sublist by one element "to the right"
>>          ++prev_elem_checked_for_order_in_sublist_to_splice;
>>          ++just_after_last_elem_in_sublist_to_splice;
>>        }
>> 
>>        splice(insertion_point, *this, just_after_last_sorted,
>> just_after_last_elem_in_sublist_to_splice);
>> 
>>        just_after_last_sorted = std::next(last_sorted); // refresh
>> the iterator so it points to whatever is now just past the frontier
>>        // We don`t need to refresh the iterator "last_sorted" b/c this is a linked list...
>>        //   and we definitely did not insert at the frontier [see NOTE 668].
>> 
>>      } // end if
>>    } // end while
>>  } // end of "sort_without_temporary_list(Compare comp)"
>>  void         sort_without_temporary_list() { sort_without_temporary_list(op_less); }
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160818/ae81ea4a/attachment.html>


More information about the llvm-dev mailing list