fix unneeded copy of BBs
MODIFY
ir/function.cpp
ir/function.cpp
@@ -109,6 +109,8 @@ ostream& operator<<(ostream &os, const BasicBlock &bb) {
}
+BasicBlock Function::sink_bb("#sink");
+
expr Function::getTypeConstraints() const {
expr t(true);
for (auto bb : getBBs()) {
@@ -134,6 +136,7 @@ void Function::fixupTypes(const Model &m) {
}
BasicBlock& Function::getBB(string_view name, bool push_front) {
+ assert(name != "#sink");
auto p = BBs.try_emplace(string(name), name);
if (p.second) {
if (push_front)
@@ -145,15 +148,12 @@ BasicBlock& Function::getBB(string_view name, bool push_front) {
}
const BasicBlock& Function::getBB(string_view name) const {
+ assert(name != "#sink");
return BBs.at(string(name));
}
-const BasicBlock* Function::getBBIfExists(string_view name) const {
- auto I = BBs.find(string(name));
- return I != BBs.end() ? &I->second : nullptr;
-}
-
void Function::removeBB(BasicBlock &BB) {
+ assert(BB.getName() != "#sink");
BBs.erase(BB.getName());
for (auto I = BB_order.begin(), E = BB_order.end(); I != E; ++I) {
@@ -469,7 +469,7 @@ void Function::unroll(unsigned k) {
return;
auto &forest = la.getLoopForest();
- BasicBlock &sink = getBB("#sink");
+ auto &sink = getSinkBB();
vector<tuple<BasicBlock*, unsigned, bool>> worklist;
// insert in reverse order because the worklist is iterated in LIFO
@@ -869,10 +869,11 @@ void CFG::printDot(ostream &os) const {
// traverse the cfg in reverse postorder to build dominators.
void DomTree::buildDominators(const CFG &cfg) {
// initialization
- unsigned i = f.getBBs().size();
+ unsigned i = f.getBBs().size() + 1;
for (auto &b : f.getBBs()) {
doms.emplace(b, *b).first->second.order = --i;
}
+ doms.emplace(&f.getSinkBB(), f.getSinkBB()).first->second.order = 0;
// build predecessors relationship
for (auto [src, tgt, instr] : cfg) {

MODIFY
ir/function.h
ir/function.h
@@ -28,7 +28,6 @@ class BasicBlock final {
std::vector<std::unique_ptr<Instr>> m_instrs;
public:
- BasicBlock(std::string &&name) : name(std::move(name)) {}
BasicBlock(std::string_view name) : name(name) {}
const std::string& getName() const { return name; }
@@ -63,6 +62,8 @@ class Function final {
std::unordered_map<std::string, BasicBlock> BBs;
std::vector<BasicBlock*> BB_order;
+ static BasicBlock sink_bb;
+
unsigned bits_pointers = 64;
unsigned bits_ptr_offset = 64;
bool little_endian = true;
@@ -96,15 +97,16 @@ public:
const std::string& getName() const { return name; }
auto& getFnAttrs() { return attrs; }
+ auto& getFnAttrs() const { return attrs; }
smt::expr getTypeConstraints() const;
void fixupTypes(const smt::Model &m);
const BasicBlock& getFirstBB() const { return *BB_order[0]; }
BasicBlock& getFirstBB() { return *BB_order[0]; }
+ const BasicBlock& getSinkBB() const { return sink_bb; }
BasicBlock& getBB(std::string_view name, bool push_front = false);
const BasicBlock& getBB(std::string_view name) const;
- const BasicBlock* getBBIfExists(std::string_view name) const;
void removeBB(BasicBlock &BB);

MODIFY
ir/state.cpp
ir/state.cpp
@@ -119,7 +119,7 @@ State::VarArgsData::mkIf(const expr &cond, const VarArgsData &then,
return ret;
}
-State::State(Function &f, bool source)
+State::State(const Function &f, bool source)
: f(f), source(source), memory(*this),
return_val(f.getType().getDummyValue(false)), return_memory(memory) {}
@@ -567,7 +567,7 @@ void State::addJump(const BasicBlock &dst0, expr &&cond) {
auto dst = &dst0;
if (seen_bbs.count(dst)) {
- dst = &f.getBB("#sink");
+ dst = &f.getSinkBB();
}
cond &= domain.path;
@@ -919,11 +919,7 @@ void State::finishInitializer() {
}
expr State::sinkDomain() const {
- auto bb = f.getBBIfExists("#sink");
- if (!bb)
- return false;
-
- auto I = predecessor_data.find(bb);
+ auto I = predecessor_data.find(&f.getSinkBB());
if (I == predecessor_data.end())
return false;

MODIFY
ir/state.h
ir/state.h
@@ -96,8 +96,7 @@ private:
VarArgsData var_args;
};
- // TODO: make this const again
- Function &f;
+ const Function &f;
bool source;
bool disable_undef_rewrite = false;
bool is_initialization_phase = true;
@@ -174,7 +173,7 @@ private:
VarArgsData var_args_data;
public:
- State(Function &f, bool source);
+ State(const Function &f, bool source);
static void resetGlobals();

MODIFY
util/symexec.cpp
util/symexec.cpp
@@ -43,9 +43,7 @@ void sym_exec(State &s) {
first = false;
}
- // TODO: remove copy
- auto BBs = f.getBBs();
- for (auto &bb : BBs) {
+ for (auto &bb : f.getBBs()) {
if (!s.startBB(*bb))
continue;

fix #267: unneeded copy of BBs