1 module d.semantic.flow; 2 3 import d.semantic.semantic; 4 5 import d.ir.instruction; 6 7 import source.location; 8 9 struct FlowAnalyzer { 10 private: 11 SemanticPass pass; 12 alias pass this; 13 14 Body fbody; 15 16 import d.ir.symbol; 17 uint[Variable] closure; 18 uint nextClosureIndex; 19 20 public: 21 this(SemanticPass pass, Function f) in { 22 assert(f.fbody, "f does not have a body"); 23 } do { 24 this.pass = pass; 25 26 fbody = f.fbody; 27 nextClosureIndex = f.hasContext; 28 foreach (p; f.params) { 29 if (p.storage == Storage.Capture) { 30 assert(p !in closure); 31 closure[p] = nextClosureIndex++; 32 } 33 } 34 } 35 36 uint[Variable] getClosure() { 37 foreach (b; range(fbody)) { 38 visit(b); 39 } 40 41 return closure; 42 } 43 44 void visit(BasicBlockRef b) { 45 auto instructions = range(fbody, b); 46 foreach (i; instructions) { 47 if (i.op != OpCode.Alloca) { 48 continue; 49 } 50 51 auto v = i.var; 52 if (v.storage == Storage.Capture) { 53 assert(v !in closure); 54 closure[v] = nextClosureIndex++; 55 } 56 } 57 } 58 }