package midend.llvm; import java.util.HashMap; import java.util.Stack; import midend.llvm.value.IrFuncValue; import midend.llvm.value.IrBasicBlock; import midend.llvm.value.IrLoop; import midend.llvm.type.IrType; import midend.llvm.constant.IrConstant; import midend.llvm.value.IrGlobalValue; import midend.llvm.constant.IrConstantStr; import midend.llvm.instr.IrInstr; public class IrBuilder { private static final String prebb = "b_"; private static final String prestr = "@s_"; private static final String prefunc = "@f_"; private static final String preglobal = "@g_"; private static final String prelocal = "%v_"; private static IrModule module = null; private static IrFuncValue currentFunc = null; private static IrBasicBlock currentBB = null; private static int strId = 0; private static int globalId = 0; private static int bblockId = 0; private static HashMap funcIdMap = new HashMap<>(); // func, localId private static Stack loopStack = new Stack<>(); public static void setCurrentModule(IrModule module) { IrBuilder.module = module; } public static void addNewFunc(String name, IrType retType) { IrFuncValue func = new IrFuncValue(geFuncName(name), retType); module.addFunc(func); funcIdMap.put(func, 0); currentFunc = func; IrBasicBlock entryBB = new IrBasicBlock(getBlockName(), func); func.addBBlock(entryBB); currentBB = entryBB; } public static void addNewFunc(IrFuncValue func) { module.addFunc(func); funcIdMap.put(func, 0); currentFunc = func; IrBasicBlock entryBB = new IrBasicBlock(getBlockName(), func); func.addBBlock(entryBB); currentBB = entryBB; } public static void addNewBB() { IrBasicBlock bb = new IrBasicBlock(getBlockName(), currentFunc); currentFunc.addBBlock(bb); } public static void addNewBB(IrBasicBlock bb) { currentFunc.addBBlock(bb); } public static void setCurrentBBlock(IrBasicBlock bb) { currentBB = bb; } public static void addNewGlobal(IrType type, boolean isConstant, IrConstant initVal) { IrGlobalValue global = new IrGlobalValue(type, getGlobalName(), isConstant, initVal); module.addGlobalVar(global); } public static void addNewGlobal(IrGlobalValue global) { module.addGlobalVar(global); } public static void addNewStr(String str) { if (module.containStr(str)) { return; } module.addStr(new IrConstantStr(str, getStrName())); } public static void addNewStr(IrConstantStr str) { module.addStr(str); } public static void addInstr(IrInstr instr) { currentBB.addInstr(instr); instr.setBBlock(currentBB); } public static String geFuncName(String name) { return name.equals("main") ? "@main" : prefunc + name; } public static String getBlockName() { return prebb + bblockId++; } public static String getStrName() { return prestr + strId++; } public static String getGlobalName() { return preglobal + globalId++; } public static String getLocalName() { int id = funcIdMap.get(currentFunc); funcIdMap.put(currentFunc, id + 1); return prelocal + id; } public static String getLocalName(IrFuncValue func) { int id = funcIdMap.get(func); funcIdMap.put(func, id + 1); return prelocal + id; } public static IrModule getCurrentModule() { return module; } public static IrFuncValue getCurrentFunc() { return currentFunc; } public static IrBasicBlock getCurrentBB() { return currentBB; } public static void pushLoop(IrLoop loop) { loopStack.push(loop); } public static IrLoop popLoop() { return loopStack.pop(); } public static IrLoop getCurrentLoop() { return loopStack.peek(); } }