bool MergeFunctions::runOnModule(Module &M) { bool Changed = false; std::map<unsigned long, std::vector<Function *> > FnMap; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->isDeclaration() || F->isIntrinsic()) continue; if (!F->hasLocalLinkage() && !F->hasExternalLinkage() && !F->hasWeakLinkage()) continue; if (hasAddressTaken(F)) continue; FnMap[hash(F)].push_back(F); } // TODO: instead of running in a loop, we could also fold functions in callgraph // order. Constructing the CFG probably isn't cheaper than just running in a loop. bool LocalChanged; do { LocalChanged = false; for (std::map<unsigned long, std::vector<Function *> >::iterator I = FnMap.begin(), E = FnMap.end(); I != E; ++I) { DOUT << "size: " << FnMap.size() << "\n"; std::vector<Function *> &FnVec = I->second; DOUT << "hash (" << I->first << "): " << FnVec.size() << "\n"; for (int i = 0, e = FnVec.size(); i != e; ++i) { for (int j = i + 1; j != e; ++j) { bool isEqual = equals(FnVec[i], FnVec[j]); DOUT << " " << FnVec[i]->getName() << (isEqual ? " == " : " != ") << FnVec[j]->getName() << "\n"; if (isEqual) { if (fold(FnVec, i, j)) { LocalChanged = true; FnVec.erase(FnVec.begin() + j); --j, --e; } } } } } Changed |= LocalChanged; } while (LocalChanged); return Changed; }