[PATCH] Speed-up creation of live ranges for physical registers by using a segment set

Gasiunas, Vaidas vaidas.gasiunas at sap.com
Mon Oct 27 01:51:33 PDT 2014


Hi guys,

Thanks for showing interest in the performance regression in the LiveIntervals pass that I reported to llvm-dev two weeks ago. Here is again the summary of the post:
------------

Some time ago we reported a compile-time performance regression in the LiveIntervals analysis pass (see http://llvm.org/bugs/show_bug.cgi?id=18580). We detected it at first after migrating from LLVM 3.1 to 3.3, but the problem persists also in 3.5. This regression is especially critical when compiling long functions. In one of our benchmarks compile time goes from 200s (in 3.1) up to 1500s (in 3.3). Our analysis had shown that the most of time is taken for generation of live intervals for physical registers. In the biggest example, the live interval of one of the physical registers consists of about 500.000 live ranges. Insertions in the middle of the array of live ranges cause quadratic algorithmic complexity, which is apparently the main reason for the slow-down. I changed the implementation of computeRegUnitInterval() so that it uses a set instead of the array, and in this way managed to reduce the execution time of the computeRegUnitInterval from 1200s down to about 1s. The fix is a bit ugly, however, because I cannot completely switch to the set, since further analyses are more efficient on the array. For that reason, I flush the contents of the set into the array at the end of computeRegUnitInterval. I also had to rewrite various operations on the live interval so that they use the set structure if it is available and the array otherwise.

-------------

Last week I took some time to port the patch to llvm-trunk (see the attachment):
- The patch introduces an additional std::set<Segment>* member in LiveRange for storing segments in the phase of initial creation. The set is used if this member is not NULL, otherwise everything works the old way.
- The set of operations on LiveRange used during initial creation (i.e. used by createDeadDefs and extendToUses) have been reimplemented to use the segment set if it is available.
- After a live range is created the contents of the set are flushed to the segment vector, because my experiments had shown that the set is not as efficient as the vector for the later uses of the live range. After the flushing, the set is deleted and cannot be used again.
- I activated the set only for live ranges computed in LiveIntervalAnalysis::computeLiveInRegUnits() and getRegUnit() but not in computeVirtRegs(), because in the examples that I tested, I could not measure any speed-up in computeVirtRegs(), and in some cases it got even slower.

I would appreciate if you could take a look at the patch and say what you think about it.

Best regards,
Vaidas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141027/40d6025e/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: live-ranges-segment-set.patch
Type: application/octet-stream
Size: 14298 bytes
Desc: live-ranges-segment-set.patch
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141027/40d6025e/attachment.obj>


More information about the llvm-commits mailing list