1
//===- llvm/ADT/SparseBitVector.h - Efficient Sparse BitVector -*- C++ -*- ===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
10
// This file defines the SparseBitVector class. See the doxygen comment for
11
// SparseBitVector for more details on the algorithm used.
13
//===----------------------------------------------------------------------===//
15
#ifndef LLVM_ADT_SPARSEBITVECTOR_H
16
#define LLVM_ADT_SPARSEBITVECTOR_H
18
#include "llvm/ADT/ilist.h"
19
#include "llvm/ADT/ilist_node.h"
20
#include "llvm/System/DataTypes.h"
21
#include "llvm/Support/MathExtras.h"
22
#include "llvm/Support/raw_ostream.h"
29
/// SparseBitVector is an implementation of a bitvector that is sparse by only
30
/// storing the elements that have non-zero bits set. In order to make this
31
/// fast for the most common cases, SparseBitVector is implemented as a linked
32
/// list of SparseBitVectorElements. We maintain a pointer to the last
33
/// SparseBitVectorElement accessed (in the form of a list iterator), in order
34
/// to make multiple in-order test/set constant time after the first one is
35
/// executed. Note that using vectors to store SparseBitVectorElement's does
36
/// not work out very well because it causes insertion in the middle to take
37
/// enormous amounts of time with a large amount of bits. Other structures that
38
/// have better worst cases for insertion in the middle (various balanced trees,
39
/// etc) do not perform as well in practice as a linked list with this iterator
40
/// kept up to date. They are also significantly more memory intensive.
43
template <unsigned ElementSize = 128>
44
struct SparseBitVectorElement
45
: public ilist_node<SparseBitVectorElement<ElementSize> > {
47
typedef unsigned long BitWord;
49
BITWORD_SIZE = sizeof(BitWord) * CHAR_BIT,
50
BITWORDS_PER_ELEMENT = (ElementSize + BITWORD_SIZE - 1) / BITWORD_SIZE,
51
BITS_PER_ELEMENT = ElementSize
55
// Index of Element in terms of where first bit starts.
56
unsigned ElementIndex;
57
BitWord Bits[BITWORDS_PER_ELEMENT];
58
// Needed for sentinels
59
friend struct ilist_sentinel_traits<SparseBitVectorElement>;
60
SparseBitVectorElement() {
62
memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
66
explicit SparseBitVectorElement(unsigned Idx) {
68
memset(&Bits[0], 0, sizeof (BitWord) * BITWORDS_PER_ELEMENT);
72
bool operator==(const SparseBitVectorElement &RHS) const {
73
if (ElementIndex != RHS.ElementIndex)
75
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
76
if (Bits[i] != RHS.Bits[i])
81
bool operator!=(const SparseBitVectorElement &RHS) const {
82
return !(*this == RHS);
85
// Return the bits that make up word Idx in our element.
86
BitWord word(unsigned Idx) const {
87
assert (Idx < BITWORDS_PER_ELEMENT);
91
unsigned index() const {
96
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
102
void set(unsigned Idx) {
103
Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
106
bool test_and_set (unsigned Idx) {
107
bool old = test(Idx);
115
void reset(unsigned Idx) {
116
Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
119
bool test(unsigned Idx) const {
120
return Bits[Idx / BITWORD_SIZE] & (1L << (Idx % BITWORD_SIZE));
123
unsigned count() const {
124
unsigned NumBits = 0;
125
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
126
if (sizeof(BitWord) == 4)
127
NumBits += CountPopulation_32(Bits[i]);
128
else if (sizeof(BitWord) == 8)
129
NumBits += CountPopulation_64(Bits[i]);
131
assert(0 && "Unsupported!");
135
/// find_first - Returns the index of the first set bit.
136
int find_first() const {
137
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i)
139
if (sizeof(BitWord) == 4)
140
return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
141
else if (sizeof(BitWord) == 8)
142
return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
144
assert(0 && "Unsupported!");
146
assert(0 && "Illegal empty element");
147
return 0; // Not reached
150
/// find_next - Returns the index of the next set bit starting from the
151
/// "Curr" bit. Returns -1 if the next set bit is not found.
152
int find_next(unsigned Curr) const {
153
if (Curr >= BITS_PER_ELEMENT)
156
unsigned WordPos = Curr / BITWORD_SIZE;
157
unsigned BitPos = Curr % BITWORD_SIZE;
158
BitWord Copy = Bits[WordPos];
159
assert (WordPos <= BITWORDS_PER_ELEMENT
160
&& "Word Position outside of element");
162
// Mask off previous bits.
163
Copy &= ~0L << BitPos;
166
if (sizeof(BitWord) == 4)
167
return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy);
168
else if (sizeof(BitWord) == 8)
169
return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
171
assert(0 && "Unsupported!");
174
// Check subsequent words.
175
for (unsigned i = WordPos+1; i < BITWORDS_PER_ELEMENT; ++i)
177
if (sizeof(BitWord) == 4)
178
return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
179
else if (sizeof(BitWord) == 8)
180
return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
182
assert(0 && "Unsupported!");
187
// Union this element with RHS and return true if this one changed.
188
bool unionWith(const SparseBitVectorElement &RHS) {
189
bool changed = false;
190
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
191
BitWord old = changed ? 0 : Bits[i];
193
Bits[i] |= RHS.Bits[i];
194
if (!changed && old != Bits[i])
200
// Return true if we have any bits in common with RHS
201
bool intersects(const SparseBitVectorElement &RHS) const {
202
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
203
if (RHS.Bits[i] & Bits[i])
209
// Intersect this Element with RHS and return true if this one changed.
210
// BecameZero is set to true if this element became all-zero bits.
211
bool intersectWith(const SparseBitVectorElement &RHS,
213
bool changed = false;
217
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
218
BitWord old = changed ? 0 : Bits[i];
220
Bits[i] &= RHS.Bits[i];
224
if (!changed && old != Bits[i])
227
BecameZero = allzero;
230
// Intersect this Element with the complement of RHS and return true if this
231
// one changed. BecameZero is set to true if this element became all-zero
233
bool intersectWithComplement(const SparseBitVectorElement &RHS,
235
bool changed = false;
239
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
240
BitWord old = changed ? 0 : Bits[i];
242
Bits[i] &= ~RHS.Bits[i];
246
if (!changed && old != Bits[i])
249
BecameZero = allzero;
252
// Three argument version of intersectWithComplement that intersects
253
// RHS1 & ~RHS2 into this element
254
void intersectWithComplement(const SparseBitVectorElement &RHS1,
255
const SparseBitVectorElement &RHS2,
260
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
261
Bits[i] = RHS1.Bits[i] & ~RHS2.Bits[i];
265
BecameZero = allzero;
268
// Get a hash value for this element;
269
uint64_t getHashValue() const {
270
uint64_t HashVal = 0;
271
for (unsigned i = 0; i < BITWORDS_PER_ELEMENT; ++i) {
278
template <unsigned ElementSize = 128>
279
class SparseBitVector {
280
typedef ilist<SparseBitVectorElement<ElementSize> > ElementList;
281
typedef typename ElementList::iterator ElementListIter;
282
typedef typename ElementList::const_iterator ElementListConstIter;
284
BITWORD_SIZE = SparseBitVectorElement<ElementSize>::BITWORD_SIZE
287
// Pointer to our current Element.
288
ElementListIter CurrElementIter;
289
ElementList Elements;
291
// This is like std::lower_bound, except we do linear searching from the
293
ElementListIter FindLowerBound(unsigned ElementIndex) {
295
if (Elements.empty()) {
296
CurrElementIter = Elements.begin();
297
return Elements.begin();
300
// Make sure our current iterator is valid.
301
if (CurrElementIter == Elements.end())
304
// Search from our current iterator, either backwards or forwards,
305
// depending on what element we are looking for.
306
ElementListIter ElementIter = CurrElementIter;
307
if (CurrElementIter->index() == ElementIndex) {
309
} else if (CurrElementIter->index() > ElementIndex) {
310
while (ElementIter != Elements.begin()
311
&& ElementIter->index() > ElementIndex)
314
while (ElementIter != Elements.end() &&
315
ElementIter->index() < ElementIndex)
318
CurrElementIter = ElementIter;
322
// Iterator to walk set bits in the bitmap. This iterator is a lot uglier
323
// than it would be, in order to be efficient.
324
class SparseBitVectorIterator {
328
const SparseBitVector<ElementSize> *BitVector;
330
// Current element inside of bitmap.
331
ElementListConstIter Iter;
333
// Current bit number inside of our bitmap.
336
// Current word number inside of our element.
339
// Current bits from the element.
340
typename SparseBitVectorElement<ElementSize>::BitWord Bits;
342
// Move our iterator to the first non-zero bit in the bitmap.
343
void AdvanceToFirstNonZero() {
346
if (BitVector->Elements.empty()) {
350
Iter = BitVector->Elements.begin();
351
BitNumber = Iter->index() * ElementSize;
352
unsigned BitPos = Iter->find_first();
354
WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
355
Bits = Iter->word(WordNumber);
356
Bits >>= BitPos % BITWORD_SIZE;
359
// Move our iterator to the next non-zero bit.
360
void AdvanceToNextNonZero() {
364
while (Bits && !(Bits & 1)) {
369
// See if we ran out of Bits in this word.
371
int NextSetBitNumber = Iter->find_next(BitNumber % ElementSize) ;
372
// If we ran out of set bits in this element, move to next element.
373
if (NextSetBitNumber == -1 || (BitNumber % ElementSize == 0)) {
377
// We may run out of elements in the bitmap.
378
if (Iter == BitVector->Elements.end()) {
382
// Set up for next non zero word in bitmap.
383
BitNumber = Iter->index() * ElementSize;
384
NextSetBitNumber = Iter->find_first();
385
BitNumber += NextSetBitNumber;
386
WordNumber = (BitNumber % ElementSize) / BITWORD_SIZE;
387
Bits = Iter->word(WordNumber);
388
Bits >>= NextSetBitNumber % BITWORD_SIZE;
390
WordNumber = (NextSetBitNumber % ElementSize) / BITWORD_SIZE;
391
Bits = Iter->word(WordNumber);
392
Bits >>= NextSetBitNumber % BITWORD_SIZE;
393
BitNumber = Iter->index() * ElementSize;
394
BitNumber += NextSetBitNumber;
400
inline SparseBitVectorIterator& operator++() {
403
AdvanceToNextNonZero();
408
inline SparseBitVectorIterator operator++(int) {
409
SparseBitVectorIterator tmp = *this;
414
// Return the current set bit number.
415
unsigned operator*() const {
419
bool operator==(const SparseBitVectorIterator &RHS) const {
420
// If they are both at the end, ignore the rest of the fields.
421
if (AtEnd && RHS.AtEnd)
423
// Otherwise they are the same if they have the same bit number and
425
return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
427
bool operator!=(const SparseBitVectorIterator &RHS) const {
428
return !(*this == RHS);
430
SparseBitVectorIterator(): BitVector(NULL) {
434
SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
435
bool end = false):BitVector(RHS) {
436
Iter = BitVector->Elements.begin();
441
AdvanceToFirstNonZero();
445
typedef SparseBitVectorIterator iterator;
448
CurrElementIter = Elements.begin ();
454
// SparseBitVector copy ctor.
455
SparseBitVector(const SparseBitVector &RHS) {
456
ElementListConstIter ElementIter = RHS.Elements.begin();
457
while (ElementIter != RHS.Elements.end()) {
458
Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
462
CurrElementIter = Elements.begin ();
471
SparseBitVector& operator=(const SparseBitVector& RHS) {
474
ElementListConstIter ElementIter = RHS.Elements.begin();
475
while (ElementIter != RHS.Elements.end()) {
476
Elements.push_back(SparseBitVectorElement<ElementSize>(*ElementIter));
480
CurrElementIter = Elements.begin ();
485
// Test, Reset, and Set a bit in the bitmap.
486
bool test(unsigned Idx) {
487
if (Elements.empty())
490
unsigned ElementIndex = Idx / ElementSize;
491
ElementListIter ElementIter = FindLowerBound(ElementIndex);
493
// If we can't find an element that is supposed to contain this bit, there
494
// is nothing more to do.
495
if (ElementIter == Elements.end() ||
496
ElementIter->index() != ElementIndex)
498
return ElementIter->test(Idx % ElementSize);
501
void reset(unsigned Idx) {
502
if (Elements.empty())
505
unsigned ElementIndex = Idx / ElementSize;
506
ElementListIter ElementIter = FindLowerBound(ElementIndex);
508
// If we can't find an element that is supposed to contain this bit, there
509
// is nothing more to do.
510
if (ElementIter == Elements.end() ||
511
ElementIter->index() != ElementIndex)
513
ElementIter->reset(Idx % ElementSize);
515
// When the element is zeroed out, delete it.
516
if (ElementIter->empty()) {
518
Elements.erase(ElementIter);
522
void set(unsigned Idx) {
523
unsigned ElementIndex = Idx / ElementSize;
524
SparseBitVectorElement<ElementSize> *Element;
525
ElementListIter ElementIter;
526
if (Elements.empty()) {
527
Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
528
ElementIter = Elements.insert(Elements.end(), Element);
531
ElementIter = FindLowerBound(ElementIndex);
533
if (ElementIter == Elements.end() ||
534
ElementIter->index() != ElementIndex) {
535
Element = new SparseBitVectorElement<ElementSize>(ElementIndex);
536
// We may have hit the beginning of our SparseBitVector, in which case,
537
// we may need to insert right after this element, which requires moving
538
// the current iterator forward one, because insert does insert before.
539
if (ElementIter != Elements.end() &&
540
ElementIter->index() < ElementIndex)
541
ElementIter = Elements.insert(++ElementIter, Element);
543
ElementIter = Elements.insert(ElementIter, Element);
546
CurrElementIter = ElementIter;
548
ElementIter->set(Idx % ElementSize);
551
bool test_and_set (unsigned Idx) {
552
bool old = test(Idx);
560
bool operator!=(const SparseBitVector &RHS) const {
561
return !(*this == RHS);
564
bool operator==(const SparseBitVector &RHS) const {
565
ElementListConstIter Iter1 = Elements.begin();
566
ElementListConstIter Iter2 = RHS.Elements.begin();
568
for (; Iter1 != Elements.end() && Iter2 != RHS.Elements.end();
570
if (*Iter1 != *Iter2)
573
return Iter1 == Elements.end() && Iter2 == RHS.Elements.end();
576
// Union our bitmap with the RHS and return true if we changed.
577
bool operator|=(const SparseBitVector &RHS) {
578
bool changed = false;
579
ElementListIter Iter1 = Elements.begin();
580
ElementListConstIter Iter2 = RHS.Elements.begin();
582
// If RHS is empty, we are done
583
if (RHS.Elements.empty())
586
while (Iter2 != RHS.Elements.end()) {
587
if (Iter1 == Elements.end() || Iter1->index() > Iter2->index()) {
588
Elements.insert(Iter1,
589
new SparseBitVectorElement<ElementSize>(*Iter2));
592
} else if (Iter1->index() == Iter2->index()) {
593
changed |= Iter1->unionWith(*Iter2);
600
CurrElementIter = Elements.begin();
604
// Intersect our bitmap with the RHS and return true if ours changed.
605
bool operator&=(const SparseBitVector &RHS) {
606
bool changed = false;
607
ElementListIter Iter1 = Elements.begin();
608
ElementListConstIter Iter2 = RHS.Elements.begin();
610
// Check if both bitmaps are empty.
611
if (Elements.empty() && RHS.Elements.empty())
614
// Loop through, intersecting as we go, erasing elements when necessary.
615
while (Iter2 != RHS.Elements.end()) {
616
if (Iter1 == Elements.end()) {
617
CurrElementIter = Elements.begin();
621
if (Iter1->index() > Iter2->index()) {
623
} else if (Iter1->index() == Iter2->index()) {
625
changed |= Iter1->intersectWith(*Iter2, BecameZero);
627
ElementListIter IterTmp = Iter1;
629
Elements.erase(IterTmp);
635
ElementListIter IterTmp = Iter1;
637
Elements.erase(IterTmp);
640
Elements.erase(Iter1, Elements.end());
641
CurrElementIter = Elements.begin();
645
// Intersect our bitmap with the complement of the RHS and return true
647
bool intersectWithComplement(const SparseBitVector &RHS) {
648
bool changed = false;
649
ElementListIter Iter1 = Elements.begin();
650
ElementListConstIter Iter2 = RHS.Elements.begin();
652
// If either our bitmap or RHS is empty, we are done
653
if (Elements.empty() || RHS.Elements.empty())
656
// Loop through, intersecting as we go, erasing elements when necessary.
657
while (Iter2 != RHS.Elements.end()) {
658
if (Iter1 == Elements.end()) {
659
CurrElementIter = Elements.begin();
663
if (Iter1->index() > Iter2->index()) {
665
} else if (Iter1->index() == Iter2->index()) {
667
changed |= Iter1->intersectWithComplement(*Iter2, BecameZero);
669
ElementListIter IterTmp = Iter1;
671
Elements.erase(IterTmp);
680
CurrElementIter = Elements.begin();
684
bool intersectWithComplement(const SparseBitVector<ElementSize> *RHS) const {
685
return intersectWithComplement(*RHS);
689
// Three argument version of intersectWithComplement.
690
// Result of RHS1 & ~RHS2 is stored into this bitmap.
691
void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
692
const SparseBitVector<ElementSize> &RHS2)
695
CurrElementIter = Elements.begin();
696
ElementListConstIter Iter1 = RHS1.Elements.begin();
697
ElementListConstIter Iter2 = RHS2.Elements.begin();
699
// If RHS1 is empty, we are done
700
// If RHS2 is empty, we still have to copy RHS1
701
if (RHS1.Elements.empty())
704
// Loop through, intersecting as we go, erasing elements when necessary.
705
while (Iter2 != RHS2.Elements.end()) {
706
if (Iter1 == RHS1.Elements.end())
709
if (Iter1->index() > Iter2->index()) {
711
} else if (Iter1->index() == Iter2->index()) {
712
bool BecameZero = false;
713
SparseBitVectorElement<ElementSize> *NewElement =
714
new SparseBitVectorElement<ElementSize>(Iter1->index());
715
NewElement->intersectWithComplement(*Iter1, *Iter2, BecameZero);
717
Elements.push_back(NewElement);
724
SparseBitVectorElement<ElementSize> *NewElement =
725
new SparseBitVectorElement<ElementSize>(*Iter1);
726
Elements.push_back(NewElement);
731
// copy the remaining elements
732
while (Iter1 != RHS1.Elements.end()) {
733
SparseBitVectorElement<ElementSize> *NewElement =
734
new SparseBitVectorElement<ElementSize>(*Iter1);
735
Elements.push_back(NewElement);
742
void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
743
const SparseBitVector<ElementSize> *RHS2) {
744
intersectWithComplement(*RHS1, *RHS2);
747
bool intersects(const SparseBitVector<ElementSize> *RHS) const {
748
return intersects(*RHS);
751
// Return true if we share any bits in common with RHS
752
bool intersects(const SparseBitVector<ElementSize> &RHS) const {
753
ElementListConstIter Iter1 = Elements.begin();
754
ElementListConstIter Iter2 = RHS.Elements.begin();
756
// Check if both bitmaps are empty.
757
if (Elements.empty() && RHS.Elements.empty())
760
// Loop through, intersecting stopping when we hit bits in common.
761
while (Iter2 != RHS.Elements.end()) {
762
if (Iter1 == Elements.end())
765
if (Iter1->index() > Iter2->index()) {
767
} else if (Iter1->index() == Iter2->index()) {
768
if (Iter1->intersects(*Iter2))
779
// Return true iff all bits set in this SparseBitVector are
781
bool contains(const SparseBitVector<ElementSize> &RHS) const {
782
SparseBitVector<ElementSize> Result(*this);
784
return (Result == RHS);
787
// Return the first set bit in the bitmap. Return -1 if no bits are set.
788
int find_first() const {
789
if (Elements.empty())
791
const SparseBitVectorElement<ElementSize> &First = *(Elements.begin());
792
return (First.index() * ElementSize) + First.find_first();
795
// Return true if the SparseBitVector is empty
797
return Elements.empty();
800
unsigned count() const {
801
unsigned BitCount = 0;
802
for (ElementListConstIter Iter = Elements.begin();
803
Iter != Elements.end();
805
BitCount += Iter->count();
809
iterator begin() const {
810
return iterator(this);
813
iterator end() const {
814
return iterator(this, true);
817
// Get a hash value for this bitmap.
818
uint64_t getHashValue() const {
819
uint64_t HashVal = 0;
820
for (ElementListConstIter Iter = Elements.begin();
821
Iter != Elements.end();
823
HashVal ^= Iter->index();
824
HashVal ^= Iter->getHashValue();
830
// Convenience functions to allow Or and And without dereferencing in the user
833
template <unsigned ElementSize>
834
inline bool operator |=(SparseBitVector<ElementSize> &LHS,
835
const SparseBitVector<ElementSize> *RHS) {
839
template <unsigned ElementSize>
840
inline bool operator |=(SparseBitVector<ElementSize> *LHS,
841
const SparseBitVector<ElementSize> &RHS) {
842
return LHS->operator|=(RHS);
845
template <unsigned ElementSize>
846
inline bool operator &=(SparseBitVector<ElementSize> *LHS,
847
const SparseBitVector<ElementSize> &RHS) {
848
return LHS->operator&=(RHS);
851
template <unsigned ElementSize>
852
inline bool operator &=(SparseBitVector<ElementSize> &LHS,
853
const SparseBitVector<ElementSize> *RHS) {
857
// Convenience functions for infix union, intersection, difference operators.
859
template <unsigned ElementSize>
860
inline SparseBitVector<ElementSize>
861
operator|(const SparseBitVector<ElementSize> &LHS,
862
const SparseBitVector<ElementSize> &RHS) {
863
SparseBitVector<ElementSize> Result(LHS);
868
template <unsigned ElementSize>
869
inline SparseBitVector<ElementSize>
870
operator&(const SparseBitVector<ElementSize> &LHS,
871
const SparseBitVector<ElementSize> &RHS) {
872
SparseBitVector<ElementSize> Result(LHS);
877
template <unsigned ElementSize>
878
inline SparseBitVector<ElementSize>
879
operator-(const SparseBitVector<ElementSize> &LHS,
880
const SparseBitVector<ElementSize> &RHS) {
881
SparseBitVector<ElementSize> Result;
882
Result.intersectWithComplement(LHS, RHS);
889
// Dump a SparseBitVector to a stream
890
template <unsigned ElementSize>
891
void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
894
typename SparseBitVector<ElementSize>::iterator bi;
895
for (bi = LHS.begin(); bi != LHS.end(); ++bi) {
900
} // end namespace llvm