bool _removeUnusedFromModule() { using namespace llvm; // do not slice away these functions no matter what // FIXME do it a vector and fill it dynamically according // to what is the setup (like for sv-comp or general..) const char *keep[] = {options.dgOptions.entryFunction.c_str(), "klee_assume", nullptr}; // when erasing while iterating the slicer crashes // so set the to be erased values into container // and then erase them std::set<Function *> funs; std::set<GlobalVariable *> globals; std::set<GlobalAlias *> aliases; for (auto I = M->begin(), E = M->end(); I != E; ++I) { Function *func = &*I; if (array_match(func->getName(), keep)) continue; // if the function is unused or we haven't constructed it // at all in dependence graph, we can remove it // (it may have some uses though - like when one // unused func calls the other unused func if (func->hasNUses(0)) funs.insert(func); } for (auto I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *gv = &*I; if (gv->hasNUses(0)) globals.insert(gv); } for (GlobalAlias& ga : M->getAliasList()) { if (ga.hasNUses(0)) aliases.insert(&ga); } for (Function *f : funs) f->eraseFromParent(); for (GlobalVariable *gv : globals) gv->eraseFromParent(); for (GlobalAlias *ga : aliases) ga->eraseFromParent(); return (!funs.empty() || !globals.empty() || !aliases.empty()); }