| #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(); |
| } |