blob: 038f4a74ea6c3c299dea51f3d994106535d57647 [file] [log] [blame]
#include "swift/Basic/ClusteredBitVector.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/Twine.h"
#include <vector>
#include "stdlib.h"
using namespace swift;
const unsigned NV = 16;
/// Random number in [0,n)
unsigned randCount(unsigned n) {
return unsigned(rand()) % n;
}
unsigned randNV() { return randCount(NV); }
static void checkConsistency(const Twine &name, const ClusteredBitVector &cbv,
const std::vector<bool> &vec, unsigned depth) {
auto finish = [=]() {
for (unsigned j = depth; j != 0; --j) {
llvm::outs().indent(2 * (j-1)) << "}\n";
}
abort();
};
auto n = cbv.size();
if (n != vec.size()) {
llvm::outs().indent(2 * depth)
<< "assert(" << name << ".size() == " << vec.size() << ");\n";
finish();
}
for (auto i = 0; i != n; ++i) {
if (cbv[i] != vec[i]) {
llvm::outs().indent(2 * depth)
<< "assert(" << name << "[" << i << "] == "
<< (vec[i] ? "true" : "false") << ");\n";
finish();
}
}
}
static void run() {
llvm::outs() << "#include \"swift/Basic/ClusteredBitVector.h\"\n";
llvm::outs() << "using namespace swift;\n";
llvm::outs() << "int main() {\n";
llvm::outs() << " ClusteredBitVector cbvs[" << NV << "];\n";
ClusteredBitVector cbvs[NV];
std::vector<bool> vecs[NV];
unsigned nextTemp = 0;
while (true) {
switch (randCount(10)) {
case 0: {
auto from = randNV();
auto to = randNV();
if (from == to) continue;
llvm::outs() << " cbvs[" << to << "].append(cbvs[" << from << "]);\n";
cbvs[to].append(cbvs[from]);
vecs[to].insert(vecs[to].end(), vecs[from].begin(), vecs[from].end());
break;
}
case 1: {
auto from = randNV();
auto to = randNV();
if (from == to) continue;
llvm::outs() << " cbvs[" << to << "] = cbvs[" << from << "];\n";
cbvs[to] = cbvs[from];
vecs[to] = vecs[from];
break;
}
case 2: {
auto from = randNV();
auto to = randNV();
if (from == to) continue;
llvm::outs() << " cbvs[" << to << "] = std::move(cbvs[" << from << "]);\n";
cbvs[to] = std::move(cbvs[from]);
vecs[to] = std::move(vecs[from]);
break;
}
case 3: {
auto from = randNV();
auto to = randNV();
auto temp = nextTemp++;
llvm::outs() << " { ClusteredBitVector temp" << temp << " = cbvs[" << from << "];\n";
ClusteredBitVector tempCBV = cbvs[from];
auto tempVec = vecs[from];
checkConsistency("temp" + Twine(temp), tempCBV, tempVec, 2);
llvm::outs() << " cbvs[" << to << "] = temp" << temp << "; }\n";
cbvs[to] = tempCBV;
vecs[to] = tempVec;
break;
}
case 4: {
auto from = randNV();
auto to = randNV();
auto temp = nextTemp++;
llvm::outs() << " { ClusteredBitVector temp" << temp << " = std::move(cbvs[" << from << "]);\n";
ClusteredBitVector tempCBV = std::move(cbvs[from]);
auto tempVec = std::move(vecs[from]);
checkConsistency("temp" + Twine(temp), tempCBV, tempVec, 2);
llvm::outs() << " cbvs[" << to << "] = temp" << temp << "; }\n";
cbvs[to] = tempCBV;
vecs[to] = tempVec;
break;
}
case 5: {
auto from = randNV();
auto to = randNV();
auto temp = nextTemp++;
llvm::outs() << " { ClusteredBitVector temp" << temp << " = cbvs[" << from << "];\n";
ClusteredBitVector tempCBV = cbvs[from];
auto tempVec = vecs[from];
checkConsistency("temp" + Twine(temp), tempCBV, tempVec, 2);
llvm::outs() << " cbvs[" << to << "] = std::move(temp" << temp << "); }\n";
cbvs[to] = std::move(tempCBV);
vecs[to] = std::move(tempVec);
break;
}
case 6: {
auto from = randNV();
auto to = randNV();
auto temp = nextTemp++;
llvm::outs() << " { ClusteredBitVector temp" << temp << " = std::move(cbvs[" << from << "]);\n";
ClusteredBitVector tempCBV = std::move(cbvs[from]);
auto tempVec = std::move(vecs[from]);
checkConsistency("temp" + Twine(temp), tempCBV, tempVec, 2);
llvm::outs() << " cbvs[" << to << "] = std::move(temp" << temp << "); }\n";
cbvs[to] = std::move(tempCBV);
vecs[to] = std::move(tempVec);
break;
}
case 7: {
auto to = randNV();
auto count = randCount(32);
auto bits = randCount(1ULL << count);
llvm::outs() << " cbvs[" << to << "].add(" << count << ", "
<< llvm::format_hex(bits, 18) << ");\n";
cbvs[to].add(count, bits);
while (count--) {
vecs[to].push_back(bits & 1);
bits >>= 1;
}
break;
}
case 8: {
auto to = randNV();
auto count = randCount(128);
llvm::outs() << " cbvs[" << to << "].appendClearBits(" << count << ");\n";
cbvs[to].appendClearBits(count);
while (count--) vecs[to].push_back(false);
break;
}
case 9: {
auto to = randNV();
auto count = randCount(128);
llvm::outs() << " cbvs[" << to << "].appendSetBits(" << count << ");\n";
cbvs[to].appendSetBits(count);
while (count--) vecs[to].push_back(true);
break;
}
}
// Validate that everything's still okay.
for (auto i = 0; i != NV; ++i) {
checkConsistency("cbvs[" + Twine(i) + "]", cbvs[i], vecs[i], 1);
auto enumerator = cbvs[i].enumerateSetBits();
auto nextIndex = enumerator.findNext();
for (unsigned j = 0, je = cbvs[i].size(); j != je; ++j) {
assert((!nextIndex || nextIndex.getValue() >= j) && "going in reverse?");
if (cbvs[i][j]) {
if (!nextIndex || nextIndex.getValue() != j) {
llvm::outs() << " cbvs[" << i << "][" << j
<< "] is set but was not found by enumerator\n";
abort();
}
nextIndex = enumerator.findNext();
} else {
if (nextIndex && nextIndex.getValue() == j) {
llvm::outs() << " cbvs[" << i << "][" << j
<< "] is not set but was found by enumerator\n";
abort();
}
}
}
}
}
}
int main() {
sranddev();
run();
}