[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