[llvm-commits] PATCH: Fix quadratic behavior in PR12652
Benjamin Kramer
benny.kra at gmail.com
Fri Jul 6 01:57:34 PDT 2012
On 06.07.2012, at 10:28, Chandler Carruth wrote:
> diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp
> index 3d34c08..54d120a 100644
> --- a/lib/CodeGen/LiveInterval.cpp
> +++ b/lib/CodeGen/LiveInterval.cpp
> @@ -458,44 +458,94 @@ void LiveInterval::join(LiveInterval &Other,
> }
> }
>
> +/// \brief Helper function for merging in another LiveInterval's ranges.
> +///
> +/// This is a helper routine implementing an efficient merge of another
> +/// LiveIntervals ranges into the current interval. It accepts an optional
> +/// value number constraint for the RHS, and a new value number to assign to
> +/// each range merged into the interval.
> +void LiveInterval::mergeIntervalRanges(const LiveInterval &RHS,
> + VNInfo *LHSValNo,
> + const VNInfo *RHSValNo) {
> + if (RHS.begin() == RHS.end())
> + return;
> +
> + SmallVector<LiveRange, 4> NewRanges;
> + const_iterator LI = begin(), LE = end(), RI = RHS.begin(), RE = RHS.end();
> + while (true) {
> + if (LI == LE) {
> + for (; RI != RE; ++RI)
> + if (!RHSValNo || RI->valno == RHSValNo) {
> + NewRanges.push_back(*RI);
> + NewRanges.back().valno = LHSValNo;
> + }
> + break;
> + }
> + if (RI == RE) {
> + std::copy(LI, LE, std::back_inserter(NewRanges));
NewRanges.append(LI, LE) would be cleaner.
- Ben
> + break;
> + }
> + assert(LI != LE && RI != RE);
> +
> + // Skip incoming ranges with the wrong value.
> + if (RHSValNo && RI->valno != RHSValNo) {
> + ++RI;
> + continue;
> + }
> +
> + // Select the first range. We pick the earliest start point, and then the
> + // largest range.
> + bool MergeRight = *RI < *LI;
> + LiveRange R = MergeRight ? *RI : *LI;
> + if (MergeRight)
> + R.valno = LHSValNo;
> + ++(MergeRight ? RI : LI);
> +
> + // Check if we have any ranges that this one might merge with.
> + if (!NewRanges.empty()) {
> + LiveRange &LastR = NewRanges.back();
> + if (R.valno == LastR.valno) {
> + // Try to merge this range into the last one.
> + if (R.start <= LastR.end) {
> + LastR.end = std::max(LastR.end, R.end);
> + continue;
> + }
> + } else {
> + // We can't merge ranges across a value number.
> + assert(R.start >= LastR.end &&
> + "Cannot overlap two LiveRanges with differing ValID's"
> + " (did you def the same reg twice in a MachineInstr?)");
> + }
> + }
> +
> + // If all else fails, just append the range.
> + NewRanges.push_back(R);
> + }
> +
> + // Swap the new ranges with our current ranges.
> + NewRanges.swap(ranges);
> +}
> +
More information about the llvm-commits
mailing list