#include "swift/Basic/ClusteredBitVector.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ADT/Twine.h" #include #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 &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 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(); }