1 /**
2 Copyright: Copyright (c) 2017-2019 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 /// IR Function
7 module vox.ir.ir_mirror;
8 
9 import std.string : format;
10 
11 import vox.all;
12 
13 /// Allows associating a single uint sized item with any object in original IR
14 /// IR must be immutable (no new items must added)
15 /// Mirror is stored in temp memory of context
16 struct IrMirror(T)
17 {
18 	static assert(T.sizeof == uint.sizeof, "T size must be equal to uint.sizeof");
19 
20 	// Mirror of original IR
21 	private T[] virtRegMirror;
22 	private T[] basicBlockMirror;
23 	private T[] phiMirror;
24 	private T[] instrMirror;
25 
26 	void createVirtRegMirror(CompilationContext* context, IrFunction* ir) {
27 		virtRegMirror = makeParallelArray!T(context, ir.numVirtualRegisters);
28 	}
29 
30 	void createBasicBlockMirror(CompilationContext* context, IrFunction* ir) {
31 		basicBlockMirror = makeParallelArray!T(context, ir.numBasicBlocks);
32 	}
33 
34 	void createPhiMirror(CompilationContext* context, IrFunction* ir) {
35 		phiMirror = makeParallelArray!T(context, ir.numPhis);
36 	}
37 
38 	void createInstrMirror(CompilationContext* context, IrFunction* ir) {
39 		instrMirror = makeParallelArray!T(context, ir.numInstructions);
40 	}
41 
42 	void createAll(CompilationContext* context, IrFunction* ir)
43 	{
44 		createVirtRegMirror(context, ir);
45 		createBasicBlockMirror(context, ir);
46 		createPhiMirror(context, ir);
47 		createInstrMirror(context, ir);
48 	}
49 
50 	ref T opIndex(IrIndex index)
51 	{
52 		switch (index.kind) with(IrValueKind) {
53 			case basicBlock: return basicBlockMirror[index.storageUintIndex];
54 			case phi: return phiMirror[index.storageUintIndex];
55 			case virtualRegister: return virtRegMirror[index.storageUintIndex];
56 			case instruction: return instrMirror[index.storageUintIndex];
57 			default: assert(false, format("%s", index));
58 		}
59 	}
60 
61 	ref T instr(IrIndex index) {
62 		assert(index.isInstruction);
63 		return instrMirror[index.storageUintIndex];
64 	}
65 	ref T basicBlock(IrIndex index) {
66 		assert(index.isBasicBlock);
67 		return basicBlockMirror[index.storageUintIndex];
68 	}
69 	ref T phi(IrIndex index) {
70 		assert(index.isPhi);
71 		return phiMirror[index.storageUintIndex];
72 	}
73 	ref T vreg(IrIndex index) {
74 		assert(index.isVirtReg);
75 		return virtRegMirror[index.storageUintIndex];
76 	}
77 }
78 
79 T[] makeParallelArray(T)(CompilationContext* context, uint size)
80 {
81 	static assert(T.sizeof % uint.sizeof == 0, "T.sizeof is not multiple of uint.sizeof");
82 	enum size_t numSlotsPerItem = divCeil(T.sizeof, uint.sizeof);
83 	auto result = cast(T[])context.tempBuffer.voidPut(size * numSlotsPerItem);
84 	result[] = T.init;
85 	return result;
86 }