// Compute a range A-B and add it to the list. void HexagonBlockRanges::RangeList::addsub(const IndexRange &A, const IndexRange &B) { // Exclusion of non-overlapping ranges makes some checks simpler // later in this function. if (!A.overlaps(B)) { // A - B = A. add(A); return; } IndexType AS = A.start(), AE = A.end(); IndexType BS = B.start(), BE = B.end(); // If AE is None, then A is included in B, since A and B overlap. // The result of subtraction if empty, so just return. if (AE == IndexType::None) return; if (AS < BS) { // A starts before B. // AE cannot be None since A and B overlap. assert(AE != IndexType::None); // Add the part of A that extends on the "less" side of B. add(AS, BS, A.Fixed, false); } if (BE < AE) { // BE cannot be Exit here. if (BE == IndexType::None) add(BS, AE, A.Fixed, false); else add(BE, AE, A.Fixed, false); } }
bool HexagonBlockRanges::IndexRange::contains(const IndexRange &A) const { if (start() <= A.start()) { // Treat "None" in the range end as equal to the range start. IndexType E = (end() != IndexType::None) ? end() : start(); IndexType AE = (A.end() != IndexType::None) ? A.end() : A.start(); if (AE <= E) return true; } return false; }
IndexRange reverse(IndexRange arg) { if (arg.empty()) { return arg; } else { if (arg.start() < arg.end()) { return IndexRange::between(arg.end() - 1, arg.start() - 1); } else { return IndexRange::between(arg.end() + 1, arg.start() + 1); } } }
bool operator < ( const Structure& o) const { if (structname < o.structname) return true; if (structname > o.structname) return false; if (source.end() < o.source.end()) return true; if (source.end() > o.source.end()) return false; if (sink.end() < o.sink.end()) return true; if (sink.end() > o.sink.end()) return false; if (source.start() < o.source.start()) return true; if (source.start() > o.source.start()) return false; return (sink.start() < o.sink.start()); }
void HexagonBlockRanges::IndexRange::merge(const IndexRange &A) { // Allow merging adjacent ranges. assert(end() == A.start() || overlaps(A)); IndexType AS = A.start(), AE = A.end(); if (AS < start() || start() == IndexType::None) setStart(AS); if (end() < AE || end() == IndexType::None) { setEnd(AE); TiedEnd = A.TiedEnd; } else { if (end() == AE) TiedEnd |= A.TiedEnd; } if (A.Fixed) Fixed = true; }
bool HexagonBlockRanges::IndexRange::overlaps(const IndexRange &A) const { // If A contains start(), or "this" contains A.start(), then overlap. IndexType S = start(), E = end(), AS = A.start(), AE = A.end(); if (AS == S) return true; bool SbAE = (S < AE) || (S == AE && A.TiedEnd); // S-before-AE. bool ASbE = (AS < E) || (AS == E && TiedEnd); // AS-before-E. if ((AS < S && SbAE) || (S < AS && ASbE)) return true; // Otherwise no overlap. return false; }
PrimitiveRange::PrimitiveRange(PrimitiveType type, VertexBuffer& vertexBuffer, const IndexRange& indexRange, size_t base): m_type(type), m_vertexBuffer(&vertexBuffer), m_indexBuffer(nullptr), m_start(0), m_count(0), m_base(base) { m_indexBuffer = indexRange.indexBuffer(); m_start = indexRange.start(); m_count = indexRange.count(); }
IndexRange span(IndexRange lhs, IndexRange rhs) { if (lhs.start() <= lhs.end()) { if (rhs.start() <= rhs.end()) { const SINT start = std::min(lhs.start(), rhs.start()); const SINT end = std::max(lhs.end(), rhs.end()); DEBUG_ASSERT(start <= end); return IndexRange::between(start, end); } else { DEBUG_ASSERT(!"Cannot span index ranges with contrary orientations"); } } else { if (rhs.start() >= rhs.end()) { const SINT start = std::max(lhs.start(), rhs.start()); const SINT end = std::min(lhs.end(), rhs.end()); DEBUG_ASSERT(start >= end); return IndexRange::between(start, end); } else { DEBUG_ASSERT(!"Cannot span index ranges with contrary orientations"); } } return IndexRange(); }