[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