Give SmallPtrSet move semantics when we have R-value references.

Somehow, this ADT got missed which is moderately terrifying considering
the efficiency of move for it.

The code to implement move semantics for it is pretty horrible
currently but was written to reasonably closely match the rest of the
code. Unittests that cover both copying and moving (at a basic level)
added.

llvm-svn: 195239
This commit is contained in:
Chandler Carruth
2013-11-20 11:14:33 +00:00
parent 3dedf827f8
commit 55758e9691
3 changed files with 115 additions and 5 deletions

View File

@@ -186,6 +186,29 @@ SmallPtrSetImpl::SmallPtrSetImpl(const void **SmallStorage,
NumTombstones = that.NumTombstones;
}
#if LLVM_HAS_RVALUE_REFERENCES
SmallPtrSetImpl::SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize,
SmallPtrSetImpl &&that) {
SmallArray = SmallStorage;
// Copy over the basic members.
CurArraySize = that.CurArraySize;
NumElements = that.NumElements;
NumTombstones = that.NumTombstones;
// When small, just copy into our small buffer.
if (that.isSmall()) {
CurArray = SmallArray;
memcpy(CurArray, that.CurArray, sizeof(void *) * CurArraySize);
return;
}
// Otherwise, we steal the large memory allocation and no copy is needed.
CurArray = that.CurArray;
that.CurArray = that.SmallArray;
}
#endif
/// CopyFrom - implement operator= from a smallptrset that has the same pointer
/// type, but may have a different small size.
void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) {
@@ -222,6 +245,27 @@ void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) {
NumTombstones = RHS.NumTombstones;
}
#if LLVM_HAS_RVALUE_REFERENCES
void SmallPtrSetImpl::MoveFrom(SmallPtrSetImpl &&RHS) {
if (!isSmall())
free(CurArray);
if (RHS.isSmall()) {
// Copy a small RHS rather than moving.
CurArray = SmallArray;
memcpy(CurArray, RHS.CurArray, sizeof(void*)*RHS.CurArraySize);
} else {
CurArray = RHS.CurArray;
RHS.CurArray = RHS.SmallArray;
}
// Copy the rest of the trivial members.
CurArraySize = RHS.CurArraySize;
NumElements = RHS.NumElements;
NumTombstones = RHS.NumTombstones;
}
#endif
void SmallPtrSetImpl::swap(SmallPtrSetImpl &RHS) {
if (this == &RHS) return;