#include "dominator.h" namespace seq { namespace ir { namespace analyze { namespace dataflow { void DominatorInspector::analyze() { auto changed = true; while (changed) { changed = false; for (auto *blk : *cfg) { auto init = false; std::set old = sets[blk->getId()]; std::set working; for (auto it = blk->predecessors_begin(); it != blk->predecessors_end(); ++it) { auto &predDoms = sets[(*it)->getId()]; if (!init) { init = true; working = std::set(predDoms.begin(), predDoms.end()); } std::set newWorking; std::set_intersection(working.begin(), working.end(), predDoms.begin(), predDoms.end(), std::inserter(newWorking, newWorking.begin())); working = newWorking; } working.insert(blk->getId()); if (working != old) { changed = true; sets[blk->getId()] = working; } } } } bool DominatorInspector::isDominated(const Value *v, const Value *dominator) { auto *vBlock = cfg->getBlock(v); auto *dBlock = cfg->getBlock(dominator); if (vBlock->getId() == dBlock->getId()) { auto vDist = std::distance(vBlock->begin(), std::find(vBlock->begin(), vBlock->end(), v)); auto dDist = std::distance(vBlock->begin(), std::find(vBlock->begin(), vBlock->end(), dominator)); return dDist <= vDist; } return sets[vBlock->getId()].find(dBlock->getId()) != sets[vBlock->getId()].end(); } const std::string DominatorAnalysis::KEY = "core-analyses-dominator"; std::unique_ptr DominatorAnalysis::run(const Module *m) { auto *cfgResult = getAnalysisResult(cfAnalysisKey); auto ret = std::make_unique(cfgResult); for (const auto &graph : cfgResult->graphs) { auto inspector = std::make_unique(graph.second.get()); inspector->analyze(); ret->results[graph.first] = std::move(inspector); } return ret; } } // namespace dataflow } // namespace analyze } // namespace ir } // namespace seq