llvmir some opt
This commit is contained in:
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user