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 }