llvmir some opt
This commit is contained in:
143
midend/llvm/IrBuilder.java
Normal file
143
midend/llvm/IrBuilder.java
Normal file
@@ -0,0 +1,143 @@
|
||||
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<IrFuncValue, Integer> funcIdMap = new HashMap<>(); // func, localId
|
||||
private static Stack<IrLoop> 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();
|
||||
}
|
||||
}
|
||||
100
midend/llvm/IrModule.java
Normal file
100
midend/llvm/IrModule.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package midend.llvm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import midend.llvm.constant.IrConstantStr;
|
||||
import midend.llvm.value.IrFuncValue;
|
||||
import midend.llvm.value.IrGlobalValue;
|
||||
import midend.llvm.instr.GetIntInstr;
|
||||
import midend.llvm.instr.PutChInstr;
|
||||
import midend.llvm.instr.PutIntInstr;
|
||||
import midend.llvm.instr.PutStrInstr;
|
||||
|
||||
public class IrModule {
|
||||
private ArrayList<String> decls;
|
||||
private HashMap<String, IrConstantStr> strs;
|
||||
private ArrayList<IrGlobalValue> globalVars;
|
||||
private ArrayList<IrFuncValue> funcs;
|
||||
|
||||
public IrModule() {
|
||||
decls = new ArrayList<>();
|
||||
strs = new HashMap<>();
|
||||
globalVars = new ArrayList<>();
|
||||
funcs = new ArrayList<>();
|
||||
decls.add(GetIntInstr.getIntDecl());
|
||||
decls.add(PutChInstr.putChDecl());
|
||||
decls.add(PutIntInstr.putIntDecl());
|
||||
decls.add(PutStrInstr.putStrDecl());
|
||||
}
|
||||
|
||||
public ArrayList<String> getDecls() {
|
||||
return decls;
|
||||
}
|
||||
|
||||
public HashMap<String, IrConstantStr> getStrs() {
|
||||
return strs;
|
||||
}
|
||||
|
||||
public ArrayList<IrGlobalValue> getGlobalVars() {
|
||||
return globalVars;
|
||||
}
|
||||
|
||||
public ArrayList<IrFuncValue> getFuncs() {
|
||||
return funcs;
|
||||
}
|
||||
|
||||
public void addFunc(IrFuncValue func) {
|
||||
funcs.add(func);
|
||||
}
|
||||
|
||||
public void addStr(IrConstantStr str) {
|
||||
if (strs.containsKey(str.getValue())) {
|
||||
return;
|
||||
}
|
||||
strs.put(str.getValue(), str);
|
||||
}
|
||||
|
||||
public boolean containStr(String str) {
|
||||
return strs.containsKey(str);
|
||||
}
|
||||
|
||||
public IrConstantStr getStr(String str) {
|
||||
if (containStr(str)) {
|
||||
return strs.get(str);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addGlobalVar(IrGlobalValue globalVar) {
|
||||
globalVars.add(globalVar);
|
||||
}
|
||||
|
||||
public IrFuncValue getMainFunc() {
|
||||
for (IrFuncValue func : funcs) {
|
||||
if (func.isMain()) {
|
||||
return func;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//TODO: toString()方法编写
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String decl : decls) {
|
||||
sb.append(decl).append("\n");
|
||||
}
|
||||
for (IrConstantStr str : strs.values()) {
|
||||
sb.append(str.toString()).append("\n");
|
||||
}
|
||||
for (IrGlobalValue globalVar : globalVars) {
|
||||
sb.append(globalVar.toString()).append("\n");
|
||||
}
|
||||
for (IrFuncValue func : funcs) {
|
||||
sb.append(func.toString()).append("\n");
|
||||
}
|
||||
// System.out.println(funcs.size());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
14
midend/llvm/constant/IrConstant.java
Normal file
14
midend/llvm/constant/IrConstant.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package midend.llvm.constant;
|
||||
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.llvm.type.IrType;
|
||||
|
||||
public class IrConstant extends IrValue {
|
||||
public IrConstant(IrType type, String name) {
|
||||
super(type, name);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
47
midend/llvm/constant/IrConstantArray.java
Normal file
47
midend/llvm/constant/IrConstantArray.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package midend.llvm.constant;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.type.IrArrayType;
|
||||
|
||||
public class IrConstantArray extends IrConstant {
|
||||
private ArrayList<IrConstant> elements;
|
||||
private int size;
|
||||
|
||||
public IrConstantArray(String name, ArrayList<IrConstant> elements, int size) {
|
||||
super(new IrArrayType(IrInterType.INT32, size), name);
|
||||
this.elements = elements == null ? new ArrayList<>() : new ArrayList<>(elements);
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public ArrayList<IrConstant> getElements() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getType().toString() + " ");
|
||||
if (elements.size() == 0) {
|
||||
sb.append("zeroinitializer");
|
||||
} else {
|
||||
sb.append("[");
|
||||
for (IrConstant element : elements) {
|
||||
sb.append(element.toString());
|
||||
if (element != elements.get(elements.size() - 1)) {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
int left = size - elements.size();
|
||||
for (int i = 0; i < left; i++) {
|
||||
sb.append(", i32 0");
|
||||
}
|
||||
sb.append("]");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
20
midend/llvm/constant/IrConstantInt.java
Normal file
20
midend/llvm/constant/IrConstantInt.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package midend.llvm.constant;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class IrConstantInt extends IrConstant {
|
||||
private int value;
|
||||
|
||||
public IrConstantInt(int value) {
|
||||
super(IrInterType.INT32, value + "");
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "i32 " + value;
|
||||
}
|
||||
}
|
||||
53
midend/llvm/constant/IrConstantStr.java
Normal file
53
midend/llvm/constant/IrConstantStr.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package midend.llvm.constant;
|
||||
|
||||
import midend.llvm.type.IrArrayType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class IrConstantStr extends IrConstant {
|
||||
private String value;
|
||||
|
||||
public IrConstantStr(String value, String name) {
|
||||
super(new IrPointerType(
|
||||
new IrArrayType(IrInterType.INT8, getLen(value) + 1)), name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int getLen(String value) {
|
||||
int len = 0;
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
if (value.charAt(i) == '\\') {
|
||||
i++;
|
||||
} else if (value.charAt(i) == '"') {
|
||||
continue;
|
||||
}
|
||||
len++;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
public static String getRealStr(String str) {
|
||||
boolean start = str.charAt(0) == '"';
|
||||
boolean end = str.charAt(str.length() - 1) == '"';
|
||||
if (start && end) {
|
||||
return str.substring(1, str.length() - 1);
|
||||
} else if (start) {
|
||||
return str.substring(1);
|
||||
} else if (end) {
|
||||
return str.substring(0, str.length() - 1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getName() + " = constant " + ((IrPointerType) getType()).getPointeeType());
|
||||
sb.append(" c\"" + getRealStr(value).replace("\\n", "\\0A"));
|
||||
sb.append("\\00\"");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
21
midend/llvm/instr/AllocateInstr.java
Normal file
21
midend/llvm/instr/AllocateInstr.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.type.IrType;
|
||||
|
||||
public class AllocateInstr extends IrInstr {
|
||||
private IrType pointeeType;
|
||||
|
||||
public AllocateInstr(IrType pointeeType, String name) { // name即为局部变量的name,因为要声明一个局部变量
|
||||
super(new IrPointerType(pointeeType), name, IrInstrType.ALLOCA);
|
||||
this.pointeeType = pointeeType;
|
||||
}
|
||||
|
||||
public IrType getPointeeType() {
|
||||
return pointeeType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + " = alloca " + this.pointeeType;
|
||||
}
|
||||
}
|
||||
24
midend/llvm/instr/AluInstr.java
Normal file
24
midend/llvm/instr/AluInstr.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class AluInstr extends IrInstr {
|
||||
private AluType alutype;
|
||||
|
||||
public AluInstr(String name, String op, IrValue left, IrValue right) {
|
||||
super(IrInterType.INT32, name, IrInstrType.ALU);
|
||||
this.alutype = AluType.getAluType(op);
|
||||
addUse(left);
|
||||
addUse(right);
|
||||
}
|
||||
|
||||
public AluType getAluType() {
|
||||
return alutype;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + " = " + alutype.toString() + " " + getType()
|
||||
+ " " + getUse(0).getName() + ", " + getUse(1).getName();
|
||||
}
|
||||
}
|
||||
53
midend/llvm/instr/AluType.java
Normal file
53
midend/llvm/instr/AluType.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
public enum AluType {
|
||||
ADD,
|
||||
SUB,
|
||||
MUL,
|
||||
SDIV,
|
||||
SREM,
|
||||
AND,
|
||||
OR;
|
||||
|
||||
public static AluType getAluType(String op) {
|
||||
switch (op) {
|
||||
case "+":
|
||||
return ADD;
|
||||
case "-":
|
||||
return SUB;
|
||||
case "*":
|
||||
return MUL;
|
||||
case "/":
|
||||
return SDIV;
|
||||
case "%":
|
||||
return SREM;
|
||||
case "&":
|
||||
return AND;
|
||||
case "|":
|
||||
return OR;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case ADD:
|
||||
return "add";
|
||||
case SUB:
|
||||
return "sub";
|
||||
case MUL:
|
||||
return "mul";
|
||||
case SDIV:
|
||||
return "sdiv";
|
||||
case SREM:
|
||||
return "srem";
|
||||
case AND:
|
||||
return "and";
|
||||
case OR:
|
||||
return "or";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
midend/llvm/instr/BranchInstr.java
Normal file
33
midend/llvm/instr/BranchInstr.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.value.IrBasicBlock;
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class BranchInstr extends IrInstr {
|
||||
public BranchInstr(String name, IrValue cond, IrBasicBlock trueBB, IrBasicBlock falseBB) {
|
||||
super(IrInterType.VOID, name, IrInstrType.BR);
|
||||
addUse(cond);
|
||||
addUse(trueBB);
|
||||
addUse(falseBB);
|
||||
}
|
||||
|
||||
public IrValue getCond() {
|
||||
return getUse(0);
|
||||
}
|
||||
|
||||
public IrBasicBlock getTrueBB() {
|
||||
return (IrBasicBlock) getUse(1);
|
||||
}
|
||||
|
||||
public IrBasicBlock getFalseBB() {
|
||||
return (IrBasicBlock) getUse(2);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "br i1 " + getCond().getName() +
|
||||
", label %" + getTrueBB().getName() +
|
||||
", label %" + getFalseBB().getName();
|
||||
}
|
||||
|
||||
}
|
||||
48
midend/llvm/instr/CallInstr.java
Normal file
48
midend/llvm/instr/CallInstr.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import midend.llvm.value.IrFuncValue;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class CallInstr extends IrInstr {
|
||||
public CallInstr(String name, IrFuncValue func, ArrayList<IrValue> args) {
|
||||
super(func.getRetType(), name, IrInstrType.CALL);
|
||||
addUse(func);
|
||||
for (IrValue arg : args) {
|
||||
addUse(arg);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean callVoid() {
|
||||
return getType().isVoid();
|
||||
}
|
||||
|
||||
public IrFuncValue getCalledFunc() {
|
||||
return (IrFuncValue) getUse(0);
|
||||
}
|
||||
|
||||
public ArrayList<IrValue> getArgs() {
|
||||
ArrayList<IrValue> args = new ArrayList<>();
|
||||
for (int i = 1; i < getNumUses(); i++) {
|
||||
args.add(getUse(i));
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (!callVoid()) {
|
||||
sb.append(getName() + " = ");
|
||||
}
|
||||
sb.append("call " + getType() + " " + getCalledFunc().getName() + "(");
|
||||
for (int i = 1; i < getNumUses(); i++) {
|
||||
sb.append(getUse(i).getType() + " " + getUse(i).getName());
|
||||
if (i < getNumUses() - 1) {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
32
midend/llvm/instr/CmpInstr.java
Normal file
32
midend/llvm/instr/CmpInstr.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class CmpInstr extends IrInstr {
|
||||
private CmpType cmpType;
|
||||
|
||||
public CmpInstr(String name, String op, IrValue lhs, IrValue rhs) {
|
||||
super(IrInterType.BOOL, name, IrInstrType.CMP);
|
||||
cmpType = CmpType.getCmpType(op);
|
||||
addUse(lhs);
|
||||
addUse(rhs);
|
||||
}
|
||||
|
||||
public CmpType getCmpType() {
|
||||
return cmpType;
|
||||
}
|
||||
|
||||
public IrValue getLhs() {
|
||||
return getUse(0);
|
||||
}
|
||||
|
||||
public IrValue getRhs() {
|
||||
return getUse(1);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + " = " + "icmp " + cmpType.toString()
|
||||
+ " i32 " + getLhs().getName() + ", " + getRhs().getName();
|
||||
}
|
||||
}
|
||||
48
midend/llvm/instr/CmpType.java
Normal file
48
midend/llvm/instr/CmpType.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
public enum CmpType {
|
||||
EQ,
|
||||
NE,
|
||||
SGT,
|
||||
SGE,
|
||||
SLT,
|
||||
SLE;
|
||||
|
||||
public static CmpType getCmpType(String op) {
|
||||
switch (op) {
|
||||
case "==":
|
||||
return EQ;
|
||||
case "!=":
|
||||
return NE;
|
||||
case ">":
|
||||
return SGT;
|
||||
case ">=":
|
||||
return SGE;
|
||||
case "<":
|
||||
return SLT;
|
||||
case "<=":
|
||||
return SLE;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
switch (this) {
|
||||
case EQ:
|
||||
return "eq";
|
||||
case NE:
|
||||
return "ne";
|
||||
case SGT:
|
||||
return "sgt";
|
||||
case SGE:
|
||||
return "sge";
|
||||
case SLT:
|
||||
return "slt";
|
||||
case SLE:
|
||||
return "sle";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
midend/llvm/instr/ExtendInstr.java
Normal file
31
midend/llvm/instr/ExtendInstr.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class ExtendInstr extends IrInstr {
|
||||
private IrType targetType;
|
||||
|
||||
public ExtendInstr(String name, IrType targetType, IrValue src) {
|
||||
super(targetType, name, IrInstrType.EXTEND);
|
||||
this.targetType = targetType;
|
||||
addUse(src);
|
||||
}
|
||||
|
||||
public IrValue getSrc() {
|
||||
return getUse(0);
|
||||
}
|
||||
|
||||
public IrType getTargetType() {
|
||||
return this.targetType;
|
||||
}
|
||||
|
||||
public IrType getSrcType() {
|
||||
return getSrc().getType();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + " = zext " + getSrc().getType()
|
||||
+ " " + getSrc().getName() + " to " + getTargetType();
|
||||
}
|
||||
}
|
||||
57
midend/llvm/instr/GepInstr.java
Normal file
57
midend/llvm/instr/GepInstr.java
Normal file
@@ -0,0 +1,57 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrArrayType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class GepInstr extends IrInstr {
|
||||
public GepInstr(IrValue pointer, IrValue offset, String name) {
|
||||
super(new IrPointerType(getTargetType(pointer)), name, IrInstrType.GEP);
|
||||
addUse(pointer);
|
||||
addUse(offset);
|
||||
}
|
||||
|
||||
public IrValue getPointer() {
|
||||
return getUse(0);
|
||||
}
|
||||
|
||||
public IrValue getOffset() {
|
||||
return getUse(1);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
IrValue pointer = this.getPointer();
|
||||
IrValue offset = this.getOffset();
|
||||
|
||||
IrPointerType pointerType = (IrPointerType) pointer.getType();
|
||||
IrType targetType = pointerType.getPointeeType();
|
||||
|
||||
if (targetType instanceof IrArrayType arrayType) {
|
||||
return getName() + " = getelementptr inbounds " +
|
||||
arrayType + ", " +
|
||||
pointerType + " " +
|
||||
pointer.getName() + ", i32 0, " +
|
||||
offset.getType() + " " +
|
||||
offset.getName();
|
||||
} else {
|
||||
return getName() + " = getelementptr inbounds " +
|
||||
targetType + ", " +
|
||||
pointerType + " " +
|
||||
pointer.getName() + ", " +
|
||||
offset.getType() + " " +
|
||||
offset.getName();
|
||||
}
|
||||
}
|
||||
|
||||
public static IrType getTargetType(IrValue pointer) {
|
||||
IrType targetType = ((IrPointerType) pointer.getType()).getPointeeType();
|
||||
if (targetType instanceof IrArrayType arrayType) {
|
||||
return arrayType.getElementType();
|
||||
} else if (targetType instanceof IrPointerType pointerType) {
|
||||
return pointerType.getPointeeType();
|
||||
} else {
|
||||
return targetType;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
midend/llvm/instr/GetIntInstr.java
Normal file
17
midend/llvm/instr/GetIntInstr.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class GetIntInstr extends IrInstr {
|
||||
public GetIntInstr(String name) {
|
||||
super(IrInterType.INT32, name, IrInstrType.IO);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + " = call i32 @getint()";
|
||||
}
|
||||
|
||||
public static String getIntDecl() {
|
||||
return "declare i32 @getint()";
|
||||
}
|
||||
}
|
||||
28
midend/llvm/instr/IrInstr.java
Normal file
28
midend/llvm/instr/IrInstr.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.use.IrUser;
|
||||
import midend.llvm.value.IrBasicBlock;
|
||||
import midend.llvm.type.IrType;
|
||||
|
||||
public class IrInstr extends IrUser {
|
||||
private IrInstrType type;
|
||||
private IrBasicBlock block;
|
||||
|
||||
public IrInstr(IrType type, String name, IrInstrType instrType) {
|
||||
super(type, name);
|
||||
this.type = instrType;
|
||||
this.block = null;
|
||||
}
|
||||
|
||||
public IrInstrType getInstrType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public IrBasicBlock getBBlock() {
|
||||
return block;
|
||||
}
|
||||
|
||||
public void setBBlock(IrBasicBlock block) {
|
||||
this.block = block;
|
||||
}
|
||||
}
|
||||
18
midend/llvm/instr/IrInstrType.java
Normal file
18
midend/llvm/instr/IrInstrType.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
public enum IrInstrType {
|
||||
ALU,
|
||||
CMP,
|
||||
CALL,
|
||||
ALLOCA,
|
||||
LOAD,
|
||||
STORE,
|
||||
GEP,
|
||||
PHI,
|
||||
EXTEND,
|
||||
TRUNC,
|
||||
BR,
|
||||
RET,
|
||||
JUMP,
|
||||
IO
|
||||
}
|
||||
20
midend/llvm/instr/JumpInstr.java
Normal file
20
midend/llvm/instr/JumpInstr.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.value.IrBasicBlock;
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class JumpInstr extends IrInstr {
|
||||
public JumpInstr(IrBasicBlock targetBlock) {
|
||||
super(IrInterType.VOID, "jump", IrInstrType.JUMP);
|
||||
addUse(targetBlock);
|
||||
}
|
||||
|
||||
public IrBasicBlock getTargetBlock() {
|
||||
return (IrBasicBlock) getUse(0);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "br label " + "%" + getTargetBlock().getName();
|
||||
}
|
||||
}
|
||||
// TODO:所有的指令的基本块设置还需完善
|
||||
20
midend/llvm/instr/LoadInstr.java
Normal file
20
midend/llvm/instr/LoadInstr.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class LoadInstr extends IrInstr {
|
||||
public LoadInstr(IrValue pointer, String name) {
|
||||
super(((IrPointerType) pointer.getType()).getPointeeType(), name, IrInstrType.LOAD);
|
||||
addUse(pointer);
|
||||
}
|
||||
|
||||
public IrValue getPointer() {
|
||||
return getUse(0);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + " = load " + getType() + ", "
|
||||
+ getPointer().getType() + " " + getPointer().getName();
|
||||
}
|
||||
}
|
||||
19
midend/llvm/instr/PutChInstr.java
Normal file
19
midend/llvm/instr/PutChInstr.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class PutChInstr extends IrInstr {
|
||||
public PutChInstr(String name, IrValue putValue) {
|
||||
super(IrInterType.VOID, name, IrInstrType.IO);
|
||||
addUse(putValue);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "call void @putch(i32 " + getUses().get(0).getName() + ")";
|
||||
}
|
||||
|
||||
public static String putChDecl() {
|
||||
return "declare void @putch(i32)";
|
||||
}
|
||||
}
|
||||
19
midend/llvm/instr/PutIntInstr.java
Normal file
19
midend/llvm/instr/PutIntInstr.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class PutIntInstr extends IrInstr {
|
||||
public PutIntInstr(String name, IrValue putValue) {
|
||||
super(IrInterType.VOID, name, IrInstrType.IO);
|
||||
addUse(putValue);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "call void @putint(i32 " + getUses().get(0).getName() + ")";
|
||||
}
|
||||
|
||||
public static String putIntDecl() {
|
||||
return "declare void @putint(i32)";
|
||||
}
|
||||
}
|
||||
26
midend/llvm/instr/PutStrInstr.java
Normal file
26
midend/llvm/instr/PutStrInstr.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.constant.IrConstantStr;
|
||||
|
||||
public class PutStrInstr extends IrInstr {
|
||||
private IrConstantStr strVal;
|
||||
|
||||
public PutStrInstr(String name, IrConstantStr putValue) {
|
||||
super(IrInterType.VOID, name, IrInstrType.IO);
|
||||
addUse(putValue);
|
||||
strVal = putValue;
|
||||
}
|
||||
|
||||
public static String putStrDecl() {
|
||||
return "declare void @putstr(i8*)";
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
IrPointerType ptrType = (IrPointerType) strVal.getType();
|
||||
return "call void @putstr(i8* getelementptr inbounds ("
|
||||
+ ptrType.getPointeeType() + ", " + ptrType +
|
||||
" " + strVal.getName() + ", i32 0, i32 0))";
|
||||
}
|
||||
}
|
||||
20
midend/llvm/instr/ReturnInstr.java
Normal file
20
midend/llvm/instr/ReturnInstr.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class ReturnInstr extends IrInstr {
|
||||
public ReturnInstr(IrValue retValue) {
|
||||
super(IrInterType.VOID, "ret", IrInstrType.RET);
|
||||
addUse(retValue);
|
||||
}
|
||||
|
||||
public IrValue getRetValue() {
|
||||
return getUse(0);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + (getRetValue() == null ? " void" :
|
||||
" " + getRetValue().getType() + " " + getRetValue().getName());
|
||||
}
|
||||
}
|
||||
25
midend/llvm/instr/StoreInstr.java
Normal file
25
midend/llvm/instr/StoreInstr.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.llvm.type.IrInterType;
|
||||
|
||||
public class StoreInstr extends IrInstr {
|
||||
public StoreInstr(IrValue value, IrValue pointer) {
|
||||
super(IrInterType.VOID, "store", IrInstrType.STORE);
|
||||
addUse(value);
|
||||
addUse(pointer);
|
||||
}
|
||||
|
||||
public IrValue getValue() {
|
||||
return getUse(0);
|
||||
}
|
||||
|
||||
public IrValue getPointer() {
|
||||
return getUse(1);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + " " + getValue().getType() + " " + getValue().getName()
|
||||
+ ", " + getPointer().getType() + " " + getPointer().getName();
|
||||
}
|
||||
}
|
||||
31
midend/llvm/instr/TruncInstr.java
Normal file
31
midend/llvm/instr/TruncInstr.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package midend.llvm.instr;
|
||||
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class TruncInstr extends IrInstr {
|
||||
private IrType targetType;
|
||||
|
||||
public TruncInstr(IrType targetType, IrValue value, String name) {
|
||||
super(targetType, name, IrInstrType.TRUNC);
|
||||
addUse(value);
|
||||
this.targetType = targetType;
|
||||
}
|
||||
|
||||
public IrValue getSrc() {
|
||||
return getUse(0);
|
||||
}
|
||||
|
||||
public IrType getTargetType() {
|
||||
return targetType;
|
||||
}
|
||||
|
||||
public IrType getSrcType() {
|
||||
return getSrc().getType();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getName() + " = trunc " + getSrcType()
|
||||
+ " " + getSrc().getName() + " to " + getTargetType();
|
||||
}
|
||||
}
|
||||
23
midend/llvm/type/IrArrayType.java
Normal file
23
midend/llvm/type/IrArrayType.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package midend.llvm.type;
|
||||
|
||||
public class IrArrayType extends IrType {
|
||||
private IrType elementType;
|
||||
private int size;
|
||||
|
||||
public IrArrayType(IrType elementType, int size) {
|
||||
this.elementType = elementType;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public IrType getElementType() {
|
||||
return elementType;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "[" + size + " x " + elementType.toString() + "]";
|
||||
}
|
||||
}
|
||||
10
midend/llvm/type/IrBasicBlockType.java
Normal file
10
midend/llvm/type/IrBasicBlockType.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package midend.llvm.type;
|
||||
|
||||
public class IrBasicBlockType extends IrType {
|
||||
public IrBasicBlockType() {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
17
midend/llvm/type/IrFuncType.java
Normal file
17
midend/llvm/type/IrFuncType.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package midend.llvm.type;
|
||||
|
||||
public class IrFuncType extends IrType {
|
||||
private IrType returnType;
|
||||
|
||||
public IrFuncType(IrType returnType) {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
public IrType getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return returnType.toString();
|
||||
}
|
||||
}
|
||||
18
midend/llvm/type/IrInterType.java
Normal file
18
midend/llvm/type/IrInterType.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package midend.llvm.type;
|
||||
|
||||
public class IrInterType extends IrType {
|
||||
private int size;
|
||||
|
||||
public IrInterType(int size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public static final IrInterType INT32 = new IrInterType(32);
|
||||
public static final IrInterType INT8 = new IrInterType(8);
|
||||
public static final IrInterType BOOL = new IrInterType(1);
|
||||
public static final IrInterType VOID = new IrInterType(0);
|
||||
|
||||
public String toString() {
|
||||
return size != 0 ? "i" + size : "void";
|
||||
}
|
||||
}
|
||||
17
midend/llvm/type/IrPointerType.java
Normal file
17
midend/llvm/type/IrPointerType.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package midend.llvm.type;
|
||||
|
||||
public class IrPointerType extends IrType {
|
||||
private IrType pointeeType;
|
||||
|
||||
public IrPointerType(IrType pointeeType) {
|
||||
this.pointeeType = pointeeType;
|
||||
}
|
||||
|
||||
public IrType getPointeeType() {
|
||||
return pointeeType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return pointeeType.toString() + "*";
|
||||
}
|
||||
}
|
||||
74
midend/llvm/type/IrType.java
Normal file
74
midend/llvm/type/IrType.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package midend.llvm.type;
|
||||
|
||||
import midend.llvm.IrBuilder;
|
||||
import midend.llvm.constant.IrConstantInt;
|
||||
import midend.llvm.instr.CmpInstr;
|
||||
import midend.llvm.instr.ExtendInstr;
|
||||
import midend.llvm.instr.TruncInstr;
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.llvm.instr.ExtendInstr;
|
||||
|
||||
public class IrType {
|
||||
public boolean isInt32() {
|
||||
return this == IrInterType.INT32;
|
||||
}
|
||||
|
||||
public boolean isInt8() {
|
||||
return this == IrInterType.INT8;
|
||||
}
|
||||
|
||||
public boolean isBool() {
|
||||
return this == IrInterType.BOOL;
|
||||
}
|
||||
|
||||
public boolean isVoid() {
|
||||
return this == IrInterType.VOID;
|
||||
}
|
||||
|
||||
public boolean isPointer() {
|
||||
return this instanceof IrPointerType;
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return this instanceof IrArrayType;
|
||||
}
|
||||
|
||||
public boolean isFunc() {
|
||||
return this instanceof IrFuncType;
|
||||
}
|
||||
|
||||
public boolean isBasicBlock() {
|
||||
return this instanceof IrBasicBlockType;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public static IrValue convertType(IrValue originValue, IrType targetType) {
|
||||
IrType originType = originValue.getType();
|
||||
if (targetType.isInt32()) {
|
||||
if (originType.isInt32()) {
|
||||
return originValue;
|
||||
} else {
|
||||
ExtendInstr ei = new ExtendInstr(
|
||||
IrBuilder.getLocalName(), targetType, originValue);
|
||||
IrBuilder.addInstr(ei);
|
||||
return ei;
|
||||
}
|
||||
} else if (targetType.isBool()) {
|
||||
if (originType.isBool()) {
|
||||
return originValue;
|
||||
} else {
|
||||
CmpInstr nezero = new CmpInstr(IrBuilder.getLocalName(), "!=",
|
||||
originValue, new IrConstantInt(0));
|
||||
IrBuilder.addInstr(nezero);
|
||||
return nezero;
|
||||
}
|
||||
} else if (targetType.isArray()) {
|
||||
IrArrayType arrayType = (IrArrayType) targetType;
|
||||
return convertType(originValue, arrayType.getElementType());
|
||||
}
|
||||
return originValue;
|
||||
}
|
||||
}
|
||||
21
midend/llvm/use/IrUse.java
Normal file
21
midend/llvm/use/IrUse.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package midend.llvm.use;
|
||||
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
public class IrUse {
|
||||
private IrValue value;
|
||||
private IrUser user;
|
||||
|
||||
public IrUse(IrValue value, IrUser user) {
|
||||
this.value = value;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public IrValue getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public IrUser getUser() {
|
||||
return user;
|
||||
}
|
||||
}
|
||||
38
midend/llvm/use/IrUser.java
Normal file
38
midend/llvm/use/IrUser.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package midend.llvm.use;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.llvm.type.IrType;
|
||||
|
||||
public class IrUser extends IrValue {
|
||||
private ArrayList<IrValue> uses;
|
||||
|
||||
public IrUser(IrType type, String name) {
|
||||
super(type, name);
|
||||
this.uses = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ArrayList<IrValue> getUses() {
|
||||
return uses;
|
||||
}
|
||||
|
||||
public void addUse(IrValue value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
uses.add(value);
|
||||
value.addUser(this);
|
||||
}
|
||||
|
||||
public IrValue getUse(int index) {
|
||||
if (index >= uses.size()) {
|
||||
return null;
|
||||
}
|
||||
return uses.get(index);
|
||||
}
|
||||
|
||||
public int getNumUses() {
|
||||
return uses.size();
|
||||
}
|
||||
}
|
||||
120
midend/llvm/value/IrBasicBlock.java
Normal file
120
midend/llvm/value/IrBasicBlock.java
Normal file
@@ -0,0 +1,120 @@
|
||||
package midend.llvm.value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import midend.llvm.instr.IrInstr;
|
||||
import midend.llvm.instr.ReturnInstr;
|
||||
import midend.llvm.type.IrBasicBlockType;
|
||||
|
||||
public class IrBasicBlock extends IrValue {
|
||||
private ArrayList<IrInstr> instrs;
|
||||
private IrFuncValue func;
|
||||
private ArrayList<IrBasicBlock> preds; //前驱
|
||||
private ArrayList<IrBasicBlock> succs; //后继
|
||||
private HashSet<IrBasicBlock> domied; //支配该节点
|
||||
private IrBasicBlock directDomi;
|
||||
private HashSet<IrBasicBlock> directDomies; //该节点直接支配
|
||||
private HashSet<IrBasicBlock> domiFrontier;
|
||||
|
||||
public IrBasicBlock(String name, IrFuncValue func) {
|
||||
super(new IrBasicBlockType(), name);
|
||||
this.func = func;
|
||||
instrs = new ArrayList<>();
|
||||
preds = new ArrayList<>();
|
||||
succs = new ArrayList<>();
|
||||
domied = new HashSet<>();
|
||||
directDomi = null;
|
||||
directDomies = new HashSet<>();
|
||||
domiFrontier = new HashSet<>();
|
||||
}
|
||||
|
||||
public void addInstr(IrInstr instr) {
|
||||
instrs.add(instr);
|
||||
instr.setBBlock(this);
|
||||
}
|
||||
|
||||
public IrFuncValue getFunc() {
|
||||
return func;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return instrs.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isEntry() {
|
||||
return this.func.getBBlock(0) == this;
|
||||
}
|
||||
|
||||
public ArrayList<IrBasicBlock> getPreds() {
|
||||
return preds;
|
||||
}
|
||||
|
||||
public ArrayList<IrBasicBlock> getSuccs() {
|
||||
return succs;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getName() + ":\n\t");
|
||||
for (IrInstr instr : instrs) {
|
||||
sb.append(instr.toString());
|
||||
if (instr != instrs.get(instrs.size() - 1)) {
|
||||
sb.append("\n\t");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public boolean lastIsReturn() {
|
||||
if (instrs.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return instrs.get(instrs.size() - 1) instanceof ReturnInstr;
|
||||
}
|
||||
|
||||
public void clearCfg() {
|
||||
this.preds.clear();
|
||||
this.succs.clear();
|
||||
domied.clear();
|
||||
directDomi = null;
|
||||
directDomies.clear();
|
||||
domiFrontier.clear();
|
||||
}
|
||||
|
||||
public ArrayList<IrInstr> getInstrs() {
|
||||
return instrs;
|
||||
}
|
||||
|
||||
public void addPred(IrBasicBlock bb) {
|
||||
this.preds.add(bb);
|
||||
}
|
||||
|
||||
public void addSucc(IrBasicBlock bb) {
|
||||
this.succs.add(bb);
|
||||
}
|
||||
|
||||
public void addDomied(IrBasicBlock bb) {
|
||||
this.domied.add(bb);
|
||||
}
|
||||
|
||||
public void addDirectDomies(IrBasicBlock bb) {
|
||||
this.directDomies.add(bb);
|
||||
}
|
||||
|
||||
public void addDomiFrontier(IrBasicBlock bb) {
|
||||
this.domiFrontier.add(bb);
|
||||
}
|
||||
|
||||
public void setDirectDomi(IrBasicBlock bb) {
|
||||
this.directDomi = bb;
|
||||
}
|
||||
|
||||
public HashSet<IrBasicBlock> getDomied() {
|
||||
return domied;
|
||||
}
|
||||
|
||||
public IrBasicBlock getDirectDomi() {
|
||||
return this.directDomi;
|
||||
}
|
||||
}
|
||||
71
midend/llvm/value/IrFuncValue.java
Normal file
71
midend/llvm/value/IrFuncValue.java
Normal file
@@ -0,0 +1,71 @@
|
||||
package midend.llvm.value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.IrBuilder;
|
||||
import midend.llvm.instr.ReturnInstr;
|
||||
import midend.llvm.type.IrFuncType;
|
||||
|
||||
public class IrFuncValue extends IrValue {
|
||||
private ArrayList<IrValue> params;
|
||||
private ArrayList<IrBasicBlock> bblocks;
|
||||
|
||||
public IrFuncValue(String name, IrType retType) {
|
||||
super(new IrFuncType(retType), name);
|
||||
params = new ArrayList<>();
|
||||
bblocks = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ArrayList<IrValue> getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public ArrayList<IrBasicBlock> getBBlocks() {
|
||||
return bblocks;
|
||||
}
|
||||
|
||||
public IrBasicBlock getBBlock(int index) {
|
||||
return bblocks.get(index);
|
||||
}
|
||||
|
||||
public void addParam(IrValue param) {
|
||||
params.add(param);
|
||||
}
|
||||
|
||||
public void addBBlock(IrBasicBlock bblock) {
|
||||
bblocks.add(bblock);
|
||||
}
|
||||
|
||||
public boolean isMain() {
|
||||
return getName().equals("@main");
|
||||
}
|
||||
|
||||
public IrType getRetType() {
|
||||
return ((IrFuncType) getType()).getReturnType();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("define dso_local " + this.getRetType() + " " + this.getName() + "(");
|
||||
for (int i = 0; i < params.size(); i++) {
|
||||
sb.append(params.get(i).getType() + " " + params.get(i).getName());
|
||||
if (i < params.size() - 1) {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
sb.append(") {\n");
|
||||
for (IrBasicBlock bblock : bblocks) {
|
||||
sb.append(bblock.toString() + "\n");
|
||||
}
|
||||
sb.append("}\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void checkReturn() {
|
||||
IrBasicBlock currentBB = IrBuilder.getCurrentBB();
|
||||
if (!currentBB.lastIsReturn()) {
|
||||
ReturnInstr returnInstr = new ReturnInstr(null); // 确保没有return的情况只有void
|
||||
IrBuilder.addInstr(returnInstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
28
midend/llvm/value/IrGlobalValue.java
Normal file
28
midend/llvm/value/IrGlobalValue.java
Normal file
@@ -0,0 +1,28 @@
|
||||
package midend.llvm.value;
|
||||
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.constant.IrConstant;
|
||||
|
||||
public class IrGlobalValue extends IrValue {
|
||||
private boolean isConstant;
|
||||
private IrConstant initVal;
|
||||
|
||||
public IrGlobalValue(IrType type, String name, boolean isConstant, IrConstant initVal) {
|
||||
super(type, name);
|
||||
this.isConstant = isConstant;
|
||||
this.initVal = initVal;
|
||||
}
|
||||
|
||||
public boolean isConstant() {
|
||||
return isConstant;
|
||||
}
|
||||
|
||||
public IrConstant getInitVal() {
|
||||
return initVal;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return isConstant ? getName() + " = dso_local constant " + initVal.toString() :
|
||||
getName() + " = dso_local global " + initVal.toString();
|
||||
}
|
||||
}
|
||||
32
midend/llvm/value/IrLoop.java
Normal file
32
midend/llvm/value/IrLoop.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package midend.llvm.value;
|
||||
|
||||
public class IrLoop {
|
||||
private IrBasicBlock condBB;
|
||||
private IrBasicBlock bodyBB;
|
||||
private IrBasicBlock stepBB;
|
||||
private IrBasicBlock followBB;
|
||||
|
||||
public IrLoop(IrBasicBlock condBB, IrBasicBlock bodyBB,
|
||||
IrBasicBlock stepBB, IrBasicBlock followBB) {
|
||||
this.condBB = condBB;
|
||||
this.bodyBB = bodyBB;
|
||||
this.stepBB = stepBB;
|
||||
this.followBB = followBB;
|
||||
}
|
||||
|
||||
public IrBasicBlock getCondBB() {
|
||||
return condBB;
|
||||
}
|
||||
|
||||
public IrBasicBlock getBodyBB() {
|
||||
return bodyBB;
|
||||
}
|
||||
|
||||
public IrBasicBlock getStepBB() {
|
||||
return stepBB;
|
||||
}
|
||||
|
||||
public IrBasicBlock getFollowBB() {
|
||||
return followBB;
|
||||
}
|
||||
}
|
||||
38
midend/llvm/value/IrValue.java
Normal file
38
midend/llvm/value/IrValue.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package midend.llvm.value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.use.IrUser;
|
||||
|
||||
public class IrValue {
|
||||
private IrType type;
|
||||
private String name;
|
||||
private ArrayList<IrUser> users;
|
||||
|
||||
public IrValue(IrType type, String name) {
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.users = new ArrayList<>();
|
||||
}
|
||||
|
||||
public IrType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public ArrayList<IrUser> getUsers() {
|
||||
return users;
|
||||
}
|
||||
|
||||
public void addUser(IrUser user) {
|
||||
users.add(user);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return type.toString() + " " + name;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user