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 }