22
33#include " dominator.h"
44
5+ #include " codon/cir/llvm/llvm.h"
6+
57namespace codon {
68namespace ir {
79namespace analyze {
810namespace dataflow {
911
1012void DominatorInspector::analyze () {
11- auto changed = true ;
13+ const auto numBlocks = cfg->size ();
14+ std::unordered_map<id_t , size_t > mapping; // id -> sequential id
15+ std::vector<id_t > mappingInv (numBlocks); // sequential id -> id
16+ std::vector<llvm::BitVector> bitvecs (numBlocks); // sequential id -> bitvector
17+
18+ mapping.reserve (numBlocks);
19+ size_t next = 0 ;
20+ for (auto *blk : *cfg) {
21+ auto id = blk->getId ();
22+ mapping[id] = next;
23+ mappingInv[next] = id;
24+ ++next;
25+ }
26+
27+ // Initialize: all blocks dominate themselves; others start with universal set
28+ for (auto *blk : *cfg) {
29+ auto id = mapping[blk->getId ()];
30+ llvm::BitVector &bv = bitvecs[id];
31+ bv.resize (numBlocks, true );
32+ if (blk == cfg->getEntryBlock ()) { // entry block only dominated by itself
33+ bv.reset ();
34+ bv.set (id);
35+ }
36+ }
37+
38+ // Run simple domination algorithm
39+ bool changed = true ;
1240 while (changed) {
1341 changed = false ;
1442 for (auto *blk : *cfg) {
15- auto init = false ;
16- std::set<id_t > old = sets[blk->getId ()];
17- std::set<id_t > working;
43+ auto id = mapping[blk->getId ()];
44+ llvm::BitVector old = bitvecs[id];
45+ llvm::BitVector newSet;
46+
47+ if (blk->predecessors_begin () == blk->predecessors_end ())
48+ newSet.resize (numBlocks);
1849
50+ bool first = true ;
1951 for (auto it = blk->predecessors_begin (); it != blk->predecessors_end (); ++it) {
20- auto &predDoms = sets[(*it)->getId ()];
21- if (!init) {
22- init = true ;
23- working = std::set<id_t >(predDoms.begin (), predDoms.end ());
52+ auto predId = mapping[(*it)->getId ()];
53+ const auto &predSet = bitvecs[predId];
54+ if (first) {
55+ newSet = predSet;
56+ first = false ;
57+ } else {
58+ newSet &= predSet;
2459 }
25-
26- std::set<id_t > newWorking;
27- std::set_intersection (working.begin (), working.end (), predDoms.begin (),
28- predDoms.end (),
29- std::inserter (newWorking, newWorking.begin ()));
30- working = newWorking;
3160 }
3261
33- working. insert (blk-> getId ());
62+ newSet. set (id); // a block always dominates itself
3463
35- if (working != old) {
64+ if (newSet != old) {
65+ bitvecs[id] = newSet;
3666 changed = true ;
37- sets[blk->getId ()] = working;
3867 }
3968 }
4069 }
70+
71+ // Map back to canonical id
72+ sets.reserve (numBlocks);
73+ for (unsigned id = 0 ; id < numBlocks; id++) {
74+ auto &bv = bitvecs[id];
75+ auto &set = sets[mappingInv[id]];
76+ for (auto n = bv.find_first (); n != -1 ; n = bv.find_next (n)) {
77+ set.insert (mappingInv[n]);
78+ }
79+ }
4180}
4281
4382bool DominatorInspector::isDominated (const Value *v, const Value *dominator) {
@@ -52,7 +91,8 @@ bool DominatorInspector::isDominated(const Value *v, const Value *dominator) {
5291 return dDist <= vDist;
5392 }
5493
55- return sets[vBlock->getId ()].find (dBlock->getId ()) != sets[vBlock->getId ()].end ();
94+ auto &set = sets[vBlock->getId ()];
95+ return set.find (dBlock->getId ()) != set.end ();
5696}
5797
5898const std::string DominatorAnalysis::KEY = " core-analyses-dominator" ;
0 commit comments