|
14 | 14 |
|
15 | 15 | #include "xls/passes/range_query_engine.h"
|
16 | 16 |
|
| 17 | +#include <algorithm> |
17 | 18 | #include <cstddef>
|
18 | 19 | #include <cstdint>
|
19 | 20 | #include <functional>
|
@@ -674,6 +675,27 @@ absl::Status RangeQueryVisitor::HandleArrayIndex(ArrayIndex* array_index) {
|
674 | 675 |
|
675 | 676 | IntervalSetTree result = EmptyIntervalSetTree(array_index->GetType());
|
676 | 677 |
|
| 678 | + // Fast path: if all of the index intervals are precise, we can just perform |
| 679 | + // a lookup. |
| 680 | + if (absl::c_all_of(index_intervals, |
| 681 | + [](const IntervalSet& is) { return is.IsPrecise(); }) && |
| 682 | + array_index->GetType()->IsBits()) { |
| 683 | + std::vector<int64_t> indexes; |
| 684 | + indexes.reserve(index_intervals.size()); |
| 685 | + for (int64_t i = 0; i < index_intervals.size(); ++i) { |
| 686 | + const IntervalSet& intervals = index_intervals[i]; |
| 687 | + XLS_ASSIGN_OR_RETURN(uint64_t index, |
| 688 | + intervals.GetPreciseValue()->ToUint64()); |
| 689 | + int64_t bound = dimension[i] - 1; |
| 690 | + // Clamp to boundary if out of bounds. |
| 691 | + indexes.push_back(std::clamp<uint64_t>(index, 0, bound)); |
| 692 | + } |
| 693 | + result.Set({}, array_interval_set_tree->Get(indexes)); |
| 694 | + |
| 695 | + SetIntervalSetTree(array_index, std::move(result)); |
| 696 | + return absl::OkStatus(); |
| 697 | + } |
| 698 | + |
677 | 699 | // Returns true if the given interval set covers the given index value for an
|
678 | 700 | // array of dimension `dim`. Includes handling of OOB conditions.
|
679 | 701 | auto intervals_cover_index = [&](const IntervalSet& intervals, int64_t index,
|
|
0 commit comments