clang plugin: skip function pairs that are syntactically equal
MODIFY
tv/tv.cpp
tv/tv.cpp
#include <fstream>
#include <iostream>
#include <random>
+#include <sstream>
#include <unordered_map>
#include <utility>
@@ -124,13 +125,19 @@ llvm::cl::opt<bool> opt_io_nobuiltin(
llvm::cl::desc("Encode standard I/O functions as an unknown function"),
llvm::cl::init(false));
+struct FnInfo {
+ Function fn;
+ unsigned order;
+ std::string fn_tostr;
+};
+
ostream *out;
ofstream out_file;
string report_filename;
optional<smt::smt_initializer> smt_init;
optional<llvm_util::initializer> llvm_util_init;
TransformPrintOpts print_opts;
-unordered_map<string, pair<Function, unsigned>> fns;
+unordered_map<string, FnInfo> fns;
set<string> fnsToVerify;
unsigned initialized = 0;
bool showed_stats = false;
@@ -167,21 +174,33 @@ struct TVPass final : public llvm::FunctionPass {
auto [I, first] = fns.try_emplace(F.getName().str());
auto fn = llvm2alive(F, *TLI, first ? vector<string_view>()
- : I->second.first.getGlobalVarNames());
+ : I->second.fn.getGlobalVarNames());
if (!fn) {
fns.erase(I);
return false;
}
- auto old_fn = move(I->second.first);
- I->second.first = move(*fn);
+ if (is_clangtv) {
+ // Compare Alive2 IR and skip if syntactically equal
+ stringstream ss;
+ fn->print(ss);
+
+ string str2 = ss.str();
+ if (I->second.fn_tostr == str2)
+ return false;
+
+ I->second.fn_tostr = move(str2);
+ }
+
+ auto old_fn = move(I->second.fn);
+ I->second.fn = move(*fn);
if (opt_print_dot) {
- auto &f = I->second.first;
- ofstream file(f.getName() + '.' + to_string(I->second.second) + ".dot");
+ auto &f = I->second.fn;
+ ofstream file(f.getName() + '.' + to_string(I->second.order) + ".dot");
CFG cfg(f);
cfg.printDot(file);
- ofstream fileDom(f.getName() + '.' + to_string(I->second.second++) +
+ ofstream fileDom(f.getName() + '.' + to_string(I->second.order++) +
".dom.dot");
DomTree(f, cfg).printDot(fileDom);
}
@@ -192,7 +211,7 @@ struct TVPass final : public llvm::FunctionPass {
smt_init->reset();
Transform t;
t.src = move(old_fn);
- t.tgt = move(I->second.first);
+ t.tgt = move(I->second.fn);
t.preprocess();
TransformVerify verifier(t, false);
t.print(*out, print_opts);
@@ -216,7 +235,7 @@ struct TVPass final : public llvm::FunctionPass {
*out << "Transformation seems to be correct!\n\n";
}
- I->second.first = move(t.tgt);
+ I->second.fn = move(t.tgt);
return false;
}

clang plugin: skip function pairs that are syntactically equal (#515)