llvmir some opt
This commit is contained in:
36
midend/visit/Visitor.java
Normal file
36
midend/visit/Visitor.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package midend.visit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import frontend.ast.CompUnit;
|
||||
import frontend.ast.decl.Decl;
|
||||
import frontend.ast.func.FuncDef;
|
||||
import frontend.ast.func.MainFuncDef;
|
||||
import midend.symbol.SymbolManager;
|
||||
|
||||
public class Visitor {
|
||||
private CompUnit compUnit;
|
||||
|
||||
public Visitor(CompUnit compUnit) {
|
||||
this.compUnit = compUnit;
|
||||
SymbolManager.reset();
|
||||
SymbolManager.nextTable();
|
||||
}
|
||||
|
||||
public void visit() {
|
||||
ArrayList<Decl> decls = this.compUnit.GetDecls();
|
||||
ArrayList<FuncDef> funcDefs = this.compUnit.GetFuncDefs();
|
||||
MainFuncDef mainFuncDef = this.compUnit.GetMainFuncDef();
|
||||
|
||||
for (Decl decl : decls) {
|
||||
VisitorDecl.visitDecl(decl);
|
||||
}
|
||||
|
||||
for (FuncDef funcDef : funcDefs) {
|
||||
VisitorFuncDef.visitFuncDef(funcDef);
|
||||
}
|
||||
|
||||
VisitorFuncDef.visitMainFuncDef(mainFuncDef);
|
||||
}
|
||||
//:TODO:符号表的变换,什么时候往前进一个符号表,这需要人工手工来操作
|
||||
}
|
||||
35
midend/visit/VisitorBlock.java
Normal file
35
midend/visit/VisitorBlock.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package midend.visit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import frontend.ast.block.Block;
|
||||
import frontend.ast.block.BlockItem;
|
||||
import frontend.ast.block.Stmt;
|
||||
import frontend.ast.decl.Decl;
|
||||
import midend.symbol.SymbolManager;
|
||||
|
||||
public class VisitorBlock {
|
||||
public static void visitBlock(Block block) {
|
||||
if (!block.isFuncBlock()) {
|
||||
SymbolManager.nextTable();
|
||||
}
|
||||
// System.out.println("(block)now table: " + SymbolManager.getCurrentTableId());
|
||||
// System.out.println("bsequence: " + SymbolManager.getCurrentSequence());//TODO:debug
|
||||
ArrayList<BlockItem> blockItems = block.getBlockItems();
|
||||
for (BlockItem blockItem : blockItems) {
|
||||
visitBlockItem(blockItem);
|
||||
}
|
||||
if (!block.isFuncBlock()) {
|
||||
SymbolManager.nextTable();
|
||||
}
|
||||
// System.out.println("(block)now table: " + SymbolManager.getCurrentTableId());//TODO:debug
|
||||
}
|
||||
|
||||
public static void visitBlockItem(BlockItem blockItem) {
|
||||
if (blockItem.getChild(0) instanceof Decl) {
|
||||
VisitorDecl.visitDecl((Decl) blockItem.getChild(0));
|
||||
} else {
|
||||
VisitorStmt.visitStmt((Stmt) blockItem.getChild(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
167
midend/visit/VisitorDecl.java
Normal file
167
midend/visit/VisitorDecl.java
Normal file
@@ -0,0 +1,167 @@
|
||||
package midend.visit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import frontend.ast.decl.ConstDecl;
|
||||
import frontend.ast.decl.ConstDef;
|
||||
import frontend.ast.decl.Decl;
|
||||
import frontend.ast.decl.VarDecl;
|
||||
import frontend.ast.decl.VarDef;
|
||||
import frontend.ast.exp.ConstExp;
|
||||
import frontend.ast.exp.Exp;
|
||||
import frontend.ast.token.TokenNode;
|
||||
import frontend.lexer.Token;
|
||||
import midend.llvm.IrBuilder;
|
||||
import midend.llvm.constant.IrConstant;
|
||||
import midend.llvm.constant.IrConstantArray;
|
||||
import midend.llvm.constant.IrConstantInt;
|
||||
import midend.llvm.instr.AllocateInstr;
|
||||
import midend.llvm.instr.StoreInstr;
|
||||
import midend.llvm.instr.GepInstr;
|
||||
import midend.llvm.type.IrArrayType;
|
||||
import midend.llvm.type.IrFuncType;
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.value.IrGlobalValue;
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.symbol.SymbolType;
|
||||
import midend.symbol.ArraySymbol;
|
||||
import midend.symbol.Symbol;
|
||||
import midend.symbol.SymbolManager;
|
||||
|
||||
public class VisitorDecl {
|
||||
public static void visitDecl(Decl decl) {
|
||||
if (decl.getChild(0) instanceof ConstDecl) {
|
||||
visitConstDecl((ConstDecl) decl.getChild(0));
|
||||
} else {
|
||||
visitVarDecl((VarDecl) decl.getChild(0));
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitConstDecl(ConstDecl constDecl) {
|
||||
ArrayList<ConstDef> constDefs = constDecl.GetConstDefs();
|
||||
for (ConstDef constDef : constDefs) {
|
||||
visitConstDef(constDef);
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitVarDecl(VarDecl varDecl) {
|
||||
ArrayList<VarDef> varDefs = varDecl.GetVarDefs();
|
||||
for (VarDef varDef : varDefs) {
|
||||
visitVarDef(varDef);
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitConstDef(ConstDef constDef) {
|
||||
Symbol symbol = SymbolManager.getSymbol(((TokenNode) constDef.getChild(0)).getValue());
|
||||
if (SymbolManager.IsGlobal()) { // 全局变量下直接声明
|
||||
IrGlobalValue irGlobalValue = new IrGlobalValue(
|
||||
new IrPointerType(getSymbolIrType(symbol)),
|
||||
IrBuilder.getGlobalName(), true, getSymbolIrConst(symbol));
|
||||
IrBuilder.addNewGlobal(irGlobalValue);
|
||||
symbol.setIrValue(irGlobalValue);
|
||||
} else { // 局部变量需要分配地址再存值
|
||||
AllocateInstr allocateInstr = new AllocateInstr(getSymbolIrType(symbol),
|
||||
IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(allocateInstr);
|
||||
symbol.setIrValue(allocateInstr);
|
||||
ArrayList<Integer> valueList = symbol.getValueList();
|
||||
if (!(symbol instanceof ArraySymbol)) {
|
||||
StoreInstr storeInstr = new StoreInstr(getSymbolIrConst(symbol),
|
||||
allocateInstr);
|
||||
IrBuilder.addInstr(storeInstr);
|
||||
} else {
|
||||
for (int i = 0; i < valueList.size(); i++) {
|
||||
GepInstr gepInstr = new GepInstr(allocateInstr,
|
||||
new IrConstantInt(i), IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(gepInstr);
|
||||
IrValue initValue = new IrConstantInt(valueList.get(i));
|
||||
StoreInstr storeInstr = new StoreInstr(initValue, gepInstr);
|
||||
IrBuilder.addInstr(storeInstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void visitVarDef(VarDef varDef) {
|
||||
Symbol symbol = SymbolManager.getSymbol(((TokenNode) varDef.getChild(0)).getValue());
|
||||
if (SymbolManager.IsGlobal()) {
|
||||
IrGlobalValue irGlobalValue = new IrGlobalValue(
|
||||
new IrPointerType(getSymbolIrType(symbol)),
|
||||
IrBuilder.getGlobalName(), false, getSymbolIrConst(symbol));
|
||||
IrBuilder.addNewGlobal(irGlobalValue);
|
||||
symbol.setIrValue(irGlobalValue);
|
||||
} else { // Think:static修饰的变量该如何实现
|
||||
visitLocalVarDef(varDef, symbol);
|
||||
}
|
||||
}
|
||||
|
||||
private static void visitLocalVarDef(VarDef varDef, Symbol symbol) {
|
||||
if (symbol.getType().equals(SymbolType.STATIC_INT) ||
|
||||
symbol.getType().equals(SymbolType.STATIC_INT_ARRAY)) {
|
||||
// 当为局部变量且为static修饰的变量的时候,将其作为全局变量处理
|
||||
IrGlobalValue irGlobalValue = new IrGlobalValue(
|
||||
new IrPointerType(getSymbolIrType(symbol)),
|
||||
IrBuilder.getGlobalName(), false, getSymbolIrConst(symbol));
|
||||
IrBuilder.addNewGlobal(irGlobalValue);
|
||||
symbol.setIrValue(irGlobalValue);
|
||||
return;
|
||||
}
|
||||
AllocateInstr allocateInstr = new AllocateInstr(
|
||||
getSymbolIrType(symbol), IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(allocateInstr);
|
||||
if (!(symbol instanceof ArraySymbol)) { // 非数组变量
|
||||
if (varDef.HaveInitVal()) {
|
||||
Exp exp = varDef.getInitVal().getExpList().get(0);
|
||||
IrValue irExp = VisitorExp.visitExp(exp);
|
||||
StoreInstr storeInstr = new StoreInstr(irExp, allocateInstr);
|
||||
IrBuilder.addInstr(storeInstr);
|
||||
}
|
||||
} else { // 数组变量
|
||||
if (varDef.HaveInitVal()) {
|
||||
ArrayList<Exp> expList = varDef.getInitVal().getExpList();
|
||||
for (int i = 0; i < expList.size(); i++) {
|
||||
IrValue irExp = VisitorExp.visitExp(expList.get(i));
|
||||
irExp = IrType.convertType(irExp, IrInterType.INT32);
|
||||
GepInstr gepInstr = new GepInstr(allocateInstr,
|
||||
new IrConstantInt(i), IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(gepInstr);
|
||||
StoreInstr storeInstr = new StoreInstr(irExp, gepInstr);
|
||||
IrBuilder.addInstr(storeInstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
symbol.setIrValue(allocateInstr);
|
||||
}
|
||||
|
||||
public static IrType getSymbolIrType(Symbol symbol) {
|
||||
SymbolType st = symbol.getType();
|
||||
if (st.equals(SymbolType.INT) || st.equals(SymbolType.CONST_INT)
|
||||
|| st.equals(SymbolType.STATIC_INT)) {
|
||||
return IrInterType.INT32;
|
||||
} else if (st.equals(SymbolType.INT_ARRAY) || st.equals(SymbolType.CONST_INT_ARRAY)
|
||||
|| st.equals(SymbolType.STATIC_INT_ARRAY)) {
|
||||
return new IrArrayType(IrInterType.INT32, ((ArraySymbol) symbol).getDim());
|
||||
} else {
|
||||
if (st.equals(SymbolType.INT_FUNC)) {
|
||||
return new IrFuncType(IrInterType.INT32);
|
||||
} else {
|
||||
return new IrFuncType(IrInterType.VOID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IrConstant getSymbolIrConst(Symbol symbol) {
|
||||
ArrayList<Integer> valueList = symbol.getValueList();
|
||||
if (symbol instanceof ArraySymbol) {
|
||||
ArrayList<IrConstant> elements = new ArrayList<>();
|
||||
for (int i = 0; i < valueList.size(); i++) {
|
||||
elements.add(new IrConstantInt(valueList.get(i)));
|
||||
}
|
||||
return new IrConstantArray(symbol.getName(), elements, ((ArraySymbol) symbol).getDim());
|
||||
} else {
|
||||
return valueList.isEmpty() ? new IrConstantInt(0) : new IrConstantInt(valueList.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
264
midend/visit/VisitorExp.java
Normal file
264
midend/visit/VisitorExp.java
Normal file
@@ -0,0 +1,264 @@
|
||||
package midend.visit;
|
||||
|
||||
import frontend.ast.exp.Exp;
|
||||
import frontend.ast.exp.LAndExp;
|
||||
import frontend.ast.exp.LOrExp;
|
||||
import frontend.ast.exp.LVal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import frontend.ast.exp.AddExp;
|
||||
import frontend.ast.exp.EqExp;
|
||||
import frontend.ast.exp.MulExp;
|
||||
import frontend.ast.exp.NumberExp;
|
||||
import frontend.ast.exp.PrimaryExp;
|
||||
import frontend.ast.exp.RelExp;
|
||||
import frontend.ast.exp.UnaryExp;
|
||||
import frontend.ast.exp.UnaryOp;
|
||||
import frontend.ast.exp.Cond;
|
||||
import frontend.ast.token.TokenNode;
|
||||
import midend.llvm.IrBuilder;
|
||||
import midend.llvm.constant.IrConstantInt;
|
||||
import midend.llvm.instr.AluInstr;
|
||||
import midend.llvm.instr.BranchInstr;
|
||||
import midend.llvm.instr.CallInstr;
|
||||
import midend.llvm.instr.CmpInstr;
|
||||
import midend.llvm.instr.ExtendInstr;
|
||||
import midend.llvm.instr.GepInstr;
|
||||
import midend.llvm.instr.GetIntInstr;
|
||||
import midend.llvm.instr.LoadInstr;
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.value.IrBasicBlock;
|
||||
import midend.llvm.value.IrFuncValue;
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.symbol.*;
|
||||
|
||||
public class VisitorExp {
|
||||
public static IrValue visitExp(Exp exp) {
|
||||
return visitAddExp((AddExp) exp.getChild(0));
|
||||
}
|
||||
|
||||
public static IrValue visitAddExp(AddExp addExp) {
|
||||
if (addExp.getChildren().size() == 1) {
|
||||
return visitMulExp((MulExp) addExp.getChild(0));
|
||||
} else {
|
||||
IrValue left = visitAddExp((AddExp) addExp.getChild(0));
|
||||
TokenNode op = (TokenNode) addExp.getChild(1);
|
||||
IrValue right = visitMulExp((MulExp) addExp.getChild(2));
|
||||
left = IrType.convertType(left, IrInterType.INT32);
|
||||
right = IrType.convertType(right, IrInterType.INT32);
|
||||
AluInstr aluInstr = new AluInstr(IrBuilder.getLocalName(), op.getValue(), left, right);
|
||||
IrBuilder.addInstr(aluInstr);
|
||||
return aluInstr;
|
||||
}
|
||||
}
|
||||
|
||||
public static IrValue visitMulExp(MulExp mulExp) {
|
||||
if (mulExp.getChildren().size() == 1) {
|
||||
return visitUnaryExp((UnaryExp) mulExp.getChild(0));
|
||||
} else {
|
||||
IrValue left = visitMulExp((MulExp) mulExp.getChild(0));
|
||||
TokenNode op = (TokenNode) mulExp.getChild(1);
|
||||
IrValue right = visitUnaryExp((UnaryExp) mulExp.getChild(2));
|
||||
left = IrType.convertType(left, IrInterType.INT32);
|
||||
right = IrType.convertType(right, IrInterType.INT32);
|
||||
AluInstr aluInstr = new AluInstr(IrBuilder.getLocalName(), op.getValue(), left, right);
|
||||
IrBuilder.addInstr(aluInstr);
|
||||
return aluInstr;
|
||||
}
|
||||
}
|
||||
|
||||
public static IrValue visitUnaryExp(UnaryExp unaryExp) {
|
||||
if (unaryExp.getChild(0) instanceof PrimaryExp) {
|
||||
return visitPrimaryExp((PrimaryExp) unaryExp.getChild(0));
|
||||
} else if (unaryExp.getChild(0) instanceof TokenNode) {
|
||||
return visitFuncCall((TokenNode) unaryExp.getChild(0), unaryExp.getParamList());
|
||||
} else {
|
||||
return visitOpUnaryExp((UnaryOp) unaryExp.getChild(0), (UnaryExp) unaryExp.getChild(1));
|
||||
}
|
||||
}
|
||||
|
||||
public static IrValue visitOpUnaryExp(UnaryOp uop, UnaryExp unaryExp) {
|
||||
String op = ((TokenNode) uop.getChild(0)).getValue();
|
||||
IrValue operand = visitUnaryExp(unaryExp);
|
||||
IrConstantInt zero = new IrConstantInt(0);
|
||||
if (op.equals("+")) {
|
||||
return operand;
|
||||
} else if (op.equals("-")) {
|
||||
AluInstr aluInstr = new AluInstr(IrBuilder.getLocalName(), op, zero, operand);
|
||||
IrBuilder.addInstr(aluInstr);
|
||||
return aluInstr;
|
||||
} else {
|
||||
operand = IrType.convertType(operand, IrInterType.INT32);
|
||||
CmpInstr cmpInstr = new CmpInstr(IrBuilder.getLocalName(), "==", zero, operand);
|
||||
IrBuilder.addInstr(cmpInstr);
|
||||
ExtendInstr extendInstr = new ExtendInstr(
|
||||
IrBuilder.getLocalName(), IrInterType.INT32, cmpInstr);
|
||||
IrBuilder.addInstr(extendInstr);
|
||||
return extendInstr;
|
||||
}
|
||||
}
|
||||
|
||||
public static IrValue visitPrimaryExp(PrimaryExp primaryExp) {
|
||||
if (primaryExp.getChild(0) instanceof TokenNode) {
|
||||
return visitExp((Exp) primaryExp.getChild(1));
|
||||
} else if (primaryExp.getChild(0) instanceof LVal) {
|
||||
return visitLVal((LVal) primaryExp.getChild(0), false);
|
||||
} else {
|
||||
return new IrConstantInt(((NumberExp) primaryExp.getChild(0)).getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public static IrValue visitFuncCall(TokenNode funcName, ArrayList<Exp> paramList) {
|
||||
if (funcName.getValue().equals("getint")) {
|
||||
GetIntInstr getIntInstr = new GetIntInstr(IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(getIntInstr);
|
||||
return getIntInstr;
|
||||
}
|
||||
FuncSymbol funcSymbol = (FuncSymbol) SymbolManager.getSymbol(funcName.getName(), true);
|
||||
IrFuncValue irFunction = (IrFuncValue) funcSymbol.getIrValue();
|
||||
ArrayList<IrValue> args = new ArrayList<>();
|
||||
for (Exp param : paramList) {
|
||||
args.add(visitExp(param));
|
||||
}
|
||||
CallInstr callInstr = new CallInstr(IrBuilder.getLocalName(), irFunction, args);
|
||||
IrBuilder.addInstr(callInstr);
|
||||
return callInstr;
|
||||
}
|
||||
|
||||
public static IrValue visitLVal(LVal lval, boolean assign) {
|
||||
if (assign) {
|
||||
Symbol symbol = SymbolManager.getSymbol(((TokenNode) lval.getChild(0)).getName(), true);
|
||||
if (!(symbol instanceof ArraySymbol)) {
|
||||
return symbol.getIrValue();
|
||||
} else {
|
||||
Exp exp = (Exp) lval.getChild(2);
|
||||
IrValue pointer = symbol.getIrValue();
|
||||
GepInstr gepInstr = new GepInstr(
|
||||
pointer, visitExp(exp), IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(gepInstr);
|
||||
return gepInstr;
|
||||
}
|
||||
} else {
|
||||
Symbol symbol = SymbolManager.getSymbol(((TokenNode) lval.getChild(0)).getName(), true);
|
||||
// if (symbol == null) {
|
||||
// System.out.println(((TokenNode)lval.getChild(0)).getLine() + " " +
|
||||
// ((TokenNode)lval.getChild(0)).getValue());
|
||||
// SymbolTable table = SymbolManager.getCurrentTable();
|
||||
// System.out.println(table.toString());
|
||||
// // TODO:报错
|
||||
// }
|
||||
if (!(symbol instanceof ArraySymbol)) {
|
||||
LoadInstr loadInstr = new LoadInstr(symbol.getIrValue(), IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(loadInstr);
|
||||
return loadInstr;
|
||||
} else {
|
||||
if (lval.getChildren().size() == 1) {
|
||||
GepInstr gepInstr = new GepInstr(
|
||||
symbol.getIrValue(), new IrConstantInt(0), IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(gepInstr);
|
||||
return gepInstr;
|
||||
} else {
|
||||
Exp exp = (Exp) lval.getChild(2);
|
||||
GepInstr gepInstr = new GepInstr(
|
||||
symbol.getIrValue(), visitExp(exp), IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(gepInstr);
|
||||
LoadInstr loadInstr = new LoadInstr(gepInstr, IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(loadInstr);
|
||||
return loadInstr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO:条件表达式的实现
|
||||
public static IrValue visitRelExp(RelExp relExp) {
|
||||
if (relExp.getChildren().size() == 1) {
|
||||
return visitAddExp((AddExp) relExp.getChild(0));
|
||||
} else {
|
||||
IrValue left = visitRelExp((RelExp) relExp.getChild(0));
|
||||
IrValue right = visitAddExp((AddExp) relExp.getChild(2));
|
||||
String op = ((TokenNode) relExp.getChild(1)).getValue();
|
||||
left = IrType.convertType(left, IrInterType.INT32);
|
||||
right = IrType.convertType(right, IrInterType.INT32);
|
||||
CmpInstr cmpInstr = new CmpInstr(IrBuilder.getLocalName(), op, left, right);
|
||||
IrBuilder.addInstr(cmpInstr);
|
||||
return cmpInstr;
|
||||
}
|
||||
}
|
||||
|
||||
public static IrValue visitEqExp(EqExp eqExp) {
|
||||
if (eqExp.getChildren().size() == 1) {
|
||||
return visitRelExp((RelExp) eqExp.getChild(0));
|
||||
} else {
|
||||
IrValue left = visitEqExp((EqExp) eqExp.getChild(0));
|
||||
IrValue right = visitRelExp((RelExp) eqExp.getChild(2));
|
||||
String op = ((TokenNode) eqExp.getChild(1)).getValue();
|
||||
left = IrType.convertType(left, IrInterType.INT32);
|
||||
right = IrType.convertType(right, IrInterType.INT32);
|
||||
CmpInstr cmpInstr = new CmpInstr(IrBuilder.getLocalName(), op, left, right);
|
||||
IrBuilder.addInstr(cmpInstr);
|
||||
return cmpInstr;
|
||||
}
|
||||
}
|
||||
|
||||
public static IrValue visitLAndExp(LAndExp landExp,
|
||||
IrBasicBlock trueBlock, IrBasicBlock falseBlock) {
|
||||
if (landExp.getChildren().size() == 1) {
|
||||
IrValue eqIrValue = visitEqExp((EqExp) landExp.getChild(0));
|
||||
eqIrValue = IrType.convertType(eqIrValue, IrInterType.BOOL);
|
||||
BranchInstr branchInstr = new BranchInstr(
|
||||
IrBuilder.getLocalName(), eqIrValue, trueBlock, falseBlock);
|
||||
IrBuilder.addInstr(branchInstr);
|
||||
return eqIrValue;
|
||||
} else {
|
||||
IrBasicBlock nextBB = new IrBasicBlock(
|
||||
IrBuilder.getBlockName(), IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(nextBB);
|
||||
IrValue left = visitLAndExp((LAndExp) landExp.getChild(0), nextBB, falseBlock);
|
||||
IrBuilder.setCurrentBBlock(nextBB);
|
||||
IrValue right = visitEqExp((EqExp) landExp.getChild(2));
|
||||
right = IrType.convertType(right, IrInterType.BOOL);
|
||||
BranchInstr branchInstr2 = new BranchInstr(
|
||||
IrBuilder.getLocalName(), right, trueBlock, falseBlock);
|
||||
IrBuilder.addInstr(branchInstr2);
|
||||
return right;
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitLOrExp(LOrExp lorExp, IrBasicBlock trueBB, IrBasicBlock falseBB) {
|
||||
if (lorExp.getChildren().size() == 1) {
|
||||
IrValue landIrValue = visitLAndExp((LAndExp) lorExp.getChild(0), trueBB, falseBB);
|
||||
} else {
|
||||
IrBasicBlock nextBB = new IrBasicBlock(
|
||||
IrBuilder.getBlockName(), IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(nextBB);
|
||||
visitLOrExp((LOrExp) lorExp.getChild(0), trueBB, nextBB);
|
||||
IrBuilder.setCurrentBBlock(nextBB);
|
||||
IrValue right = visitLAndExp((LAndExp) lorExp.getChild(2), trueBB, falseBB);
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitCond(Cond cond, IrBasicBlock trueBB, IrBasicBlock falseBB) {
|
||||
visitLOrExp((LOrExp) cond.getChild(0), trueBB, falseBB);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
80
midend/visit/VisitorFuncDef.java
Normal file
80
midend/visit/VisitorFuncDef.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package midend.visit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import frontend.ast.block.Block;
|
||||
import frontend.ast.func.FuncDef;
|
||||
import frontend.ast.func.MainFuncDef;
|
||||
import frontend.ast.token.TokenNode;
|
||||
import midend.llvm.IrBuilder;
|
||||
import midend.llvm.instr.AllocateInstr;
|
||||
import midend.llvm.instr.StoreInstr;
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.type.IrPointerType;
|
||||
import midend.llvm.value.IrFuncValue;
|
||||
import midend.llvm.value.IrValue;
|
||||
|
||||
import midend.symbol.Symbol;
|
||||
import midend.symbol.FuncSymbol;
|
||||
import midend.symbol.SymbolManager;
|
||||
|
||||
public class VisitorFuncDef {
|
||||
public static void visitFuncDef(FuncDef funcDef) {
|
||||
FuncSymbol funcSymbol = (FuncSymbol) SymbolManager.getSymbol(
|
||||
((TokenNode) funcDef.getChild(1)).getName());
|
||||
IrInterType returnType = funcSymbol.getReturnType() == 1
|
||||
? IrInterType.INT32
|
||||
: IrInterType.VOID;
|
||||
IrFuncValue funcValue = new IrFuncValue(
|
||||
IrBuilder.geFuncName(funcSymbol.getName()), returnType);
|
||||
IrBuilder.addNewFunc(funcValue);
|
||||
funcSymbol.setIrValue(funcValue);
|
||||
// 进入函数作用域
|
||||
SymbolManager.nextTable();
|
||||
// System.out.println("(func)now table: " + SymbolManager.getCurrentTableId());//TODO:debug
|
||||
ArrayList<Integer> paramList = funcSymbol.getParamList();
|
||||
ArrayList<Symbol> paramSymbolList = funcSymbol.getParamSymbolList();
|
||||
ArrayList<IrValue> irParamList = new ArrayList<>();
|
||||
for (int i = 0; i < paramList.size(); i++) {
|
||||
if (paramList.get(i) == 0) {
|
||||
IrValue param = new IrValue(IrInterType.INT32, IrBuilder.getLocalName());
|
||||
irParamList.add(param);
|
||||
funcValue.addParam(param);
|
||||
} else {
|
||||
IrValue param = new IrValue(
|
||||
new IrPointerType(IrInterType.INT32), IrBuilder.getLocalName());
|
||||
irParamList.add(param);
|
||||
funcValue.addParam(param);
|
||||
paramSymbolList.get(i).setIrValue(param);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < irParamList.size(); i++) {
|
||||
if (paramList.get(i) == 1) {
|
||||
continue; // 数组参数不分配内存
|
||||
}
|
||||
AllocateInstr allocateInstr = new AllocateInstr(
|
||||
irParamList.get(i).getType(), IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(allocateInstr);
|
||||
StoreInstr storeInstr = new StoreInstr(irParamList.get(i), allocateInstr);
|
||||
IrBuilder.addInstr(storeInstr);
|
||||
paramSymbolList.get(i).setIrValue(allocateInstr);
|
||||
} //这里貌似可以不用allocate?函数形参似乎可以直接拿来用?
|
||||
Block block = (Block) funcDef.getChild(funcDef.getChildren().size() - 1);
|
||||
VisitorBlock.visitBlock(block);
|
||||
// TODO:check return?
|
||||
funcValue.checkReturn();
|
||||
SymbolManager.nextTable();
|
||||
// System.out.println("(func)now table: " + SymbolManager.getCurrentTableId());//TODO:debug
|
||||
}
|
||||
|
||||
public static void visitMainFuncDef(MainFuncDef mainFuncDef) {
|
||||
IrFuncValue mainFuncValue = new IrFuncValue(
|
||||
IrBuilder.geFuncName("main"), IrInterType.INT32);
|
||||
IrBuilder.addNewFunc(mainFuncValue);
|
||||
SymbolManager.nextTable();
|
||||
// System.out.println("(mainfunc)now table: " + SymbolManager.getCurrentTableId());//TODO:debug
|
||||
Block block = (Block) mainFuncDef.getChild(mainFuncDef.getChildren().size() - 1);
|
||||
VisitorBlock.visitBlock(block);
|
||||
SymbolManager.nextTable();
|
||||
}
|
||||
}
|
||||
271
midend/visit/VisitorStmt.java
Normal file
271
midend/visit/VisitorStmt.java
Normal file
@@ -0,0 +1,271 @@
|
||||
package midend.visit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import frontend.ast.block.Block;
|
||||
import frontend.ast.block.ForStmt;
|
||||
import frontend.ast.block.Stmt;
|
||||
import frontend.ast.exp.Cond;
|
||||
import frontend.ast.exp.Exp;
|
||||
import frontend.ast.exp.LVal;
|
||||
import frontend.ast.token.TokenNode;
|
||||
import frontend.lexer.Token;
|
||||
import midend.symbol.SymbolManager;
|
||||
import midend.llvm.IrBuilder;
|
||||
import midend.llvm.constant.IrConstantStr;
|
||||
import midend.llvm.instr.GetIntInstr;
|
||||
import midend.llvm.instr.JumpInstr;
|
||||
import midend.llvm.instr.PutIntInstr;
|
||||
import midend.llvm.instr.PutStrInstr;
|
||||
import midend.llvm.instr.ReturnInstr;
|
||||
import midend.llvm.instr.StoreInstr;
|
||||
import midend.llvm.type.IrInterType;
|
||||
import midend.llvm.type.IrType;
|
||||
import midend.llvm.value.IrBasicBlock;
|
||||
import midend.llvm.value.IrValue;
|
||||
import midend.llvm.value.IrLoop;
|
||||
|
||||
public class VisitorStmt {
|
||||
public static void visitStmt(Stmt stmt) {
|
||||
if (stmt.getChild(0) instanceof LVal) {
|
||||
visitAssign(stmt);
|
||||
} else if (stmt.getChild(0) instanceof Exp
|
||||
|| (stmt.getChild(0) instanceof TokenNode
|
||||
&& ((TokenNode) stmt.getChild(0)).getValue().equals(";"))) {
|
||||
visitExp(stmt);
|
||||
} else if (stmt.getChild(0) instanceof Block) {
|
||||
visitBlock(stmt);
|
||||
} else if (((TokenNode) stmt.getChild(0)).getValue().equals("if")) {
|
||||
visitIf(stmt);
|
||||
} else if (((TokenNode) stmt.getChild(0)).getValue().equals("for")) {
|
||||
visitFor(stmt);
|
||||
} else if (((TokenNode) stmt.getChild(0)).getValue().equals("break")) {
|
||||
visitBreak(stmt);
|
||||
} else if (((TokenNode) stmt.getChild(0)).getValue().equals("continue")) {
|
||||
visitContinue(stmt);
|
||||
} else if (((TokenNode) stmt.getChild(0)).getValue().equals("return")) {
|
||||
visitReturn(stmt);
|
||||
} else {
|
||||
visitPrintf(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitBlock(Stmt stmt) {
|
||||
Block block = (Block) stmt.getChild(0);
|
||||
VisitorBlock.visitBlock(block);
|
||||
}
|
||||
|
||||
public static void visitExp(Stmt stmt) {
|
||||
if (stmt.getChild(0) instanceof Exp) {
|
||||
VisitorExp.visitExp((Exp) stmt.getChild(0));
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitAssign(Stmt stmt) {
|
||||
if (!stmt.isGetint()) {
|
||||
LVal lval = (LVal) stmt.getChild(0);
|
||||
Exp exp = (Exp) stmt.getChild(2);
|
||||
IrValue lvalIr = VisitorExp.visitLVal(lval, true);
|
||||
IrValue expIr = VisitorExp.visitExp(exp);
|
||||
expIr = IrType.convertType(expIr, IrInterType.INT32);
|
||||
StoreInstr storeInstr = new StoreInstr(expIr, lvalIr);
|
||||
IrBuilder.addInstr(storeInstr);
|
||||
} else {
|
||||
LVal lval = (LVal) stmt.getChild(0);
|
||||
IrValue lvalIr = VisitorExp.visitLVal(lval, true);
|
||||
GetIntInstr getIntInstr = new GetIntInstr(IrBuilder.getLocalName());
|
||||
IrBuilder.addInstr(getIntInstr);
|
||||
StoreInstr storeInstr = new StoreInstr(getIntInstr, lvalIr);
|
||||
IrBuilder.addInstr(storeInstr);
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitPrintf(Stmt stmt) {
|
||||
// System.out.println(((TokenNode)stmt.getChild(0)).getValue());//TODO:debug
|
||||
String strconst = ((TokenNode) stmt.getChild(2)).getValue();
|
||||
ArrayList<Exp> expList = stmt.getExpList();
|
||||
ArrayList<IrValue> expIrList = new ArrayList<>();
|
||||
for (Exp exp : expList) {
|
||||
expIrList.add(VisitorExp.visitExp(exp));
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int expnum = 0;
|
||||
ArrayList<IrValue> printValue = new ArrayList<>();
|
||||
for (int i = 0; i < strconst.length(); i++) {
|
||||
if (strconst.charAt(i) == '%') {
|
||||
if (!sb.isEmpty() && !sb.toString().equals("\"")) {
|
||||
IrConstantStr str = IrBuilder.getCurrentModule().getStr(sb.toString());
|
||||
// System.out.println(sb.toString());//TODO:debug
|
||||
if (str == null) {
|
||||
str = new IrConstantStr(sb.toString(), IrBuilder.getStrName());
|
||||
IrBuilder.addNewStr(str);
|
||||
}
|
||||
printValue.add(str); // 修改为到最后统一输出,而不是立即输出
|
||||
// PutStrInstr putStrInstr = new PutStrInstr(IrBuilder.getLocalName(), str);
|
||||
// IrBuilder.addInstr(putStrInstr);
|
||||
sb.setLength(0);
|
||||
} else if (sb.toString().equals("\"")) {
|
||||
sb.setLength(0);
|
||||
}
|
||||
IrValue expIr = expIrList.get(expnum++);
|
||||
expIr = IrType.convertType(expIr, IrInterType.INT32);
|
||||
printValue.add(expIr); // 修改为到最后统一输出,而不是立即输出
|
||||
// PutIntInstr putIntInstr = new PutIntInstr(IrBuilder.getLocalName(), expIr);
|
||||
// IrBuilder.addInstr(putIntInstr);
|
||||
i++;
|
||||
} else {
|
||||
sb.append(strconst.charAt(i));
|
||||
}
|
||||
}
|
||||
if (!sb.isEmpty() && !sb.toString().equals("\"")) {
|
||||
IrConstantStr str = IrBuilder.getCurrentModule().getStr(sb.toString());
|
||||
// System.out.println(sb.toString());//TODO:debug
|
||||
if (str == null) {
|
||||
str = new IrConstantStr(sb.toString(), IrBuilder.getStrName());
|
||||
IrBuilder.addNewStr(str);
|
||||
}
|
||||
printValue.add(str); // 修改为到最后统一输出,而不是立即输出
|
||||
// PutStrInstr putStrInstr = new PutStrInstr(IrBuilder.getLocalName(), str);
|
||||
// IrBuilder.addInstr(putStrInstr);
|
||||
sb.setLength(0);
|
||||
}
|
||||
for (IrValue irValue : printValue) {
|
||||
if (irValue instanceof IrConstantStr) {
|
||||
PutStrInstr putStrInstr = new PutStrInstr(
|
||||
IrBuilder.getLocalName(), (IrConstantStr) irValue);
|
||||
IrBuilder.addInstr(putStrInstr);
|
||||
} else {
|
||||
PutIntInstr putIntInstr = new PutIntInstr(IrBuilder.getLocalName(), irValue);
|
||||
IrBuilder.addInstr(putIntInstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitReturn(Stmt stmt) {
|
||||
IrValue retValue = null;
|
||||
if (stmt.getChild(1) instanceof Exp) {
|
||||
retValue = VisitorExp.visitExp((Exp) stmt.getChild(1));
|
||||
retValue = IrType.convertType(retValue, IrInterType.INT32);
|
||||
}
|
||||
ReturnInstr returnInstr = new ReturnInstr(retValue);
|
||||
IrBuilder.addInstr(returnInstr);
|
||||
}
|
||||
|
||||
public static void visitIf(Stmt stmt) {
|
||||
Cond cond = (Cond) stmt.getChild(2);
|
||||
Stmt ifStmt = (Stmt) stmt.getChild(4);
|
||||
if (stmt.getChildren().size() == 7) {
|
||||
IrBasicBlock ifBlock = new IrBasicBlock(
|
||||
IrBuilder.getBlockName(), IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(ifBlock);
|
||||
IrBasicBlock elseBlock = new IrBasicBlock(
|
||||
IrBuilder.getBlockName(), IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(elseBlock);
|
||||
VisitorExp.visitCond(cond, ifBlock, elseBlock);
|
||||
// ifblock解析
|
||||
IrBuilder.setCurrentBBlock(ifBlock);
|
||||
VisitorStmt.visitStmt(ifStmt);
|
||||
IrBasicBlock followBlock = new IrBasicBlock(
|
||||
IrBuilder.getBlockName(), IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(followBlock);
|
||||
JumpInstr jumpInstr = new JumpInstr(followBlock);
|
||||
IrBuilder.addInstr(jumpInstr);
|
||||
//elseblock解析
|
||||
IrBuilder.setCurrentBBlock(elseBlock);
|
||||
Stmt elseStmt = (Stmt) stmt.getChild(6);
|
||||
VisitorStmt.visitStmt(elseStmt);
|
||||
jumpInstr = new JumpInstr(followBlock);
|
||||
IrBuilder.addInstr(jumpInstr);
|
||||
//跳转至followblock
|
||||
IrBuilder.setCurrentBBlock(followBlock);
|
||||
} else {
|
||||
IrBasicBlock ifBlock = new IrBasicBlock(
|
||||
IrBuilder.getBlockName(), IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(ifBlock);
|
||||
IrBasicBlock followBlock = new IrBasicBlock(
|
||||
IrBuilder.getBlockName(), IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(followBlock);
|
||||
VisitorExp.visitCond(cond, ifBlock, followBlock);
|
||||
IrBuilder.setCurrentBBlock(ifBlock);
|
||||
VisitorStmt.visitStmt(ifStmt);
|
||||
JumpInstr jumpInstr = new JumpInstr(followBlock);
|
||||
IrBuilder.addInstr(jumpInstr);
|
||||
//跳转至followblock
|
||||
IrBuilder.setCurrentBBlock(followBlock);
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitFor(Stmt stmt) {
|
||||
IrBasicBlock condBB = new IrBasicBlock(IrBuilder.getBlockName(),
|
||||
IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(condBB);
|
||||
IrBasicBlock bodyBB = new IrBasicBlock(IrBuilder.getBlockName(),
|
||||
IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(bodyBB);
|
||||
IrBasicBlock stepBB = new IrBasicBlock(IrBuilder.getBlockName(),
|
||||
IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(stepBB);
|
||||
IrBasicBlock followBB = new IrBasicBlock(IrBuilder.getBlockName(),
|
||||
IrBuilder.getCurrentFunc());
|
||||
IrBuilder.addNewBB(followBB);
|
||||
IrLoop loop = new IrLoop(condBB, bodyBB, stepBB, followBB);
|
||||
IrBuilder.pushLoop(loop);
|
||||
ForStmt initStmt = stmt.getinitStmt();
|
||||
if (initStmt != null) {
|
||||
VisitorStmt.visitForStmt(initStmt);
|
||||
}
|
||||
JumpInstr jumpInstr = new JumpInstr(condBB);
|
||||
IrBuilder.addInstr(jumpInstr);
|
||||
IrBuilder.setCurrentBBlock(condBB);
|
||||
Cond cond = stmt.getCond();
|
||||
if (cond != null) {
|
||||
VisitorExp.visitCond(cond, bodyBB, followBB);
|
||||
} else {
|
||||
JumpInstr jumpBody = new JumpInstr(bodyBB);
|
||||
IrBuilder.addInstr(jumpBody);
|
||||
}
|
||||
IrBuilder.setCurrentBBlock(bodyBB);
|
||||
Stmt bodyStmt = stmt.getBodyStmt();
|
||||
VisitorStmt.visitStmt(bodyStmt);
|
||||
jumpInstr = new JumpInstr(stepBB);
|
||||
IrBuilder.addInstr(jumpInstr);
|
||||
IrBuilder.setCurrentBBlock(stepBB);
|
||||
ForStmt stepStmt = stmt.getStepStmt();
|
||||
if (stepStmt != null) {
|
||||
VisitorStmt.visitForStmt(stepStmt);
|
||||
}
|
||||
JumpInstr jumpCond = new JumpInstr(condBB);
|
||||
IrBuilder.addInstr(jumpCond);
|
||||
IrBuilder.popLoop();
|
||||
IrBuilder.setCurrentBBlock(followBB);
|
||||
} /*TODO:此处可能还有问题,循环体和条件、步长表达式等可能不在一个符号表,应该修改,应该比较好改,判断一下stmt是否为block再决定是否last
|
||||
细想应该不用,如果body是一个block,那visit的时候符号表next,visit完之后符号表还会next,相当于再解析step的时候还是原来的符号表*/
|
||||
|
||||
public static void visitForStmt(ForStmt stmt) {
|
||||
ArrayList<LVal> lvalList = stmt.getLValList();
|
||||
ArrayList<Exp> expList = stmt.getExpList();
|
||||
for (int i = 0; i < lvalList.size(); i++) {
|
||||
LVal lval = lvalList.get(i);
|
||||
Exp exp = expList.get(i);
|
||||
IrValue lvalIr = VisitorExp.visitLVal(lval, true);
|
||||
IrValue expIr = VisitorExp.visitExp(exp);
|
||||
expIr = IrType.convertType(expIr, IrInterType.INT32);
|
||||
StoreInstr storeInstr = new StoreInstr(expIr, lvalIr);
|
||||
IrBuilder.addInstr(storeInstr);
|
||||
}
|
||||
}
|
||||
|
||||
public static void visitBreak(Stmt stmt) {
|
||||
IrLoop loop = IrBuilder.getCurrentLoop();
|
||||
IrBasicBlock followBB = loop.getFollowBB();
|
||||
JumpInstr jumpInstr = new JumpInstr(followBB);
|
||||
IrBuilder.addInstr(jumpInstr);
|
||||
}
|
||||
|
||||
public static void visitContinue(Stmt stmt) {
|
||||
IrLoop loop = IrBuilder.getCurrentLoop();
|
||||
IrBasicBlock stepBB = loop.getStepBB();
|
||||
JumpInstr jumpInstr = new JumpInstr(stepBB);
|
||||
IrBuilder.addInstr(jumpInstr);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user