[llvm-commits] Speeding up RegAllocLinearScan on big test-cases
Evan Cheng
evan.cheng at apple.com
Mon May 5 09:37:51 PDT 2008
Hi Roman,
Thanks for working on this. I think the idea is workable. But I worry
about your fixation on std::set. It can't be healthy?! :-)
+ /// IntrvalEndsComparator - Weak Ordering operator for ordering
+ /// intervals in increasing order according to their endNuber
value.
+ struct IntrvalEndsComparator {
+ bool operator() (const LiveInterval *L, const LiveInterval
*R) const {
+ if (L->endNumber() < R->endNumber())
+ return true;
+ if (L->endNumber() == R->endNumber())
+ return L->beginNumber() < R->beginNumber();
+
+ return false;
+ }
+ };
Please fix the inconsistent indentation.
+ iBeginNumber.addRange(LiveRange(cur->beginNumber()-1, cur-
>beginNumber(), NULL));
Please avoid 80 col. violation.
Have you run through at least MultiSource? Can you tell what impact it
has on compile time of medium sized apps like kimwitu++?
Thanks,
Evan
On May 5, 2008, at 7:52 AM, Roman Levenstein wrote:
> Hi,
>
> I have found out that RegAllocLinearScan is very inefficient on very
> big test-cases, where there are thousands of live intervals.
> Even in the release build (which is optimized), the function
> assignRegOrStackSlotAtInterval may consume up to 60-90% of the total
> compilation time according to the profiler.
>
> The reason for this bad performance is the following snippet of code
> in that function:
>
> for (unsigned i = 0, e = handled_.size(); i != e; ++i) {
> LiveInterval *HI = handled_[i];
> if (!HI->expiredAt(earliestStart) &&
> HI->expiredAt(cur->beginNumber())) {
> DOUT << "\t\t\tundo changes for: " << *HI << '\n';
> active_.push_back(std::make_pair(HI, HI->begin()));
> assert(!TargetRegisterInfo::isPhysicalRegister(HI->reg));
> prt_->addRegUse(vrm_->getPhys(HI->reg));
> }
> }
>
> It looks quite innocent, but imagine that handled_ vector contains
> thousands of elements and that we do backtracking rather often, which
> is
> the case if you have a lot of overlapping live intervals.
>
> Therefore, this loop should be implemented more efficiently.
> Basically, we need to find intervals whose endNumber() is between
> earliestStart and cur->beginNumber().
> The easiest way to do that is to have a dedicated data structure where
> all intervals are sorted in the increasing order if their endNumber().
>
> This is exactly what I do with this patch. Initially, I tried with the
> std::set approach and it worked. But since I know how much you both
> like the std::set :-),
> I decided to implement something similar that does not produce so many
> dynamic memory allocations. So, I used vectors and used std::sort to
> keep them sorted. But that non std::set based approach was
> significantly slower than std::set-based one. Therefore, I decided to
> go with the std::set-based approach.
>
> With this patch, the bottleneck is completely removed and my profiler
> does not even show this function as time-consuming (i.e. it is more
> than an order of magnitude speed-up). On small use-cases the impact is
> virtually invisible, since the number of elements in the handled_ set
> is rather small.
>
> All dejagnu tests pass without problems.
>
> Please review it and tell if it is OK for committing.
>
> -Roman
> <
> RegAllocLinearScan
> .cpp.patch>_______________________________________________
> 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