[deploy]修正了本地不能通过编译的bug,大幅修改了主函数,使之支持云平台测试参数

This commit is contained in:
LixuanWang
2025-07-16 11:18:43 +08:00
parent bd7f6ea6f6
commit 8c80b732f3
7 changed files with 176 additions and 500 deletions

4
.gitignore vendored
View File

@@ -51,4 +51,6 @@ __init__.py
*.pyc *.pyc
.DS_* .DS_*
antlr/

View File

@@ -1,4 +1,4 @@
# Generate lexer and parser with ANTLR # 移除 ANTLR 代码生成相关配置
# list(APPEND CMAKE_MODULE_PATH "${ANTLR_RUNTIME}/cmake") # list(APPEND CMAKE_MODULE_PATH "${ANTLR_RUNTIME}/cmake")
# include(FindANTLR) # include(FindANTLR)
# antlr_target(SysYGen SysY.g4 # antlr_target(SysYGen SysY.g4
@@ -7,15 +7,17 @@
# VISITOR # VISITOR
# ) # )
add_library(SysYParser SHARED ${ANTLR_SysYGen_CXX_OUTPUTS}) # 移除 SysYParser 库的构建(如果不需要独立库)
target_include_directories(SysYParser PUBLIC ${ANTLR_RUNTIME}/runtime/src) # add_library(SysYParser SHARED ${ANTLR_SysYGen_CXX_OUTPUTS})
target_link_libraries(SysYParser PUBLIC antlr4_shared) # target_include_directories(SysYParser PUBLIC ${ANTLR_RUNTIME}/runtime/src)
# target_link_libraries(SysYParser PUBLIC antlr4_shared)
# 构建 sysyc 可执行文件,使用手动提供的 SysYLexer.cpp、SysYParser.cpp 等文件
add_executable(sysyc add_executable(sysyc
sysyc.cpp sysyc.cpp
SysYLexer.cpp SysYLexer.cpp # 手动提供的文件
SysYParser.cpp SysYParser.cpp # 手动提供的文件
SysYVisitor.cpp SysYVisitor.cpp # 手动提供的文件
IR.cpp IR.cpp
SysYIRGenerator.cpp SysYIRGenerator.cpp
SysYIRPrinter.cpp SysYIRPrinter.cpp
@@ -27,10 +29,19 @@ add_executable(sysyc
RISCv64Backend.cpp RISCv64Backend.cpp
) )
target_include_directories(sysyc PRIVATE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include) # 设置 include 路径,包含 ANTLR 运行时库和项目头文件
target_compile_options(sysyc PRIVATE -frtti) target_include_directories(sysyc PRIVATE
target_link_libraries(sysyc PRIVATE SysYParser) ${CMAKE_CURRENT_SOURCE_DIR}/include # 项目头文件目录
${ANTLR_RUNTIME}/runtime/src # ANTLR 运行时库头文件
)
# 保留 ANTLR 运行时库的链接
target_link_libraries(sysyc PRIVATE antlr4_shared)
# 保留其他编译选项
target_compile_options(sysyc PRIVATE -frtti)
# 可选:线程支持(如果需要,取消注释)
# set(THREADS_PREFER_PTHREAD_FLAG ON) # set(THREADS_PREFER_PTHREAD_FLAG ON)
# find_package(Threads REQUIRED) # find_package(Threads REQUIRED)
# target_link_libraries(sysyc PRIVATE Threads::Threads) # target_link_libraries(sysyc PRIVATE Threads::Threads)

File diff suppressed because one or more lines are too long

View File

@@ -1,73 +0,0 @@
CONST=1
INT=2
FLOAT=3
VOID=4
IF=5
ELSE=6
WHILE=7
BREAK=8
CONTINUE=9
RETURN=10
ADD=11
SUB=12
MUL=13
DIV=14
MOD=15
EQ=16
NE=17
LT=18
LE=19
GT=20
GE=21
AND=22
OR=23
NOT=24
ASSIGN=25
COMMA=26
SEMICOLON=27
LPAREN=28
RPAREN=29
LBRACE=30
RBRACE=31
LBRACK=32
RBRACK=33
Ident=34
ILITERAL=35
FLITERAL=36
STRING=37
WS=38
LINECOMMENT=39
BLOCKCOMMENT=40
'const'=1
'int'=2
'float'=3
'void'=4
'if'=5
'else'=6
'while'=7
'break'=8
'continue'=9
'return'=10
'+'=11
'-'=12
'*'=13
'/'=14
'%'=15
'=='=16
'!='=17
'<'=18
'<='=19
'>'=20
'>='=21
'&&'=22
'||'=23
'!'=24
'='=25
','=26
';'=27
'('=28
')'=29
'{'=30
'}'=31
'['=32
']'=33

File diff suppressed because one or more lines are too long

View File

@@ -1,73 +0,0 @@
CONST=1
INT=2
FLOAT=3
VOID=4
IF=5
ELSE=6
WHILE=7
BREAK=8
CONTINUE=9
RETURN=10
ADD=11
SUB=12
MUL=13
DIV=14
MOD=15
EQ=16
NE=17
LT=18
LE=19
GT=20
GE=21
AND=22
OR=23
NOT=24
ASSIGN=25
COMMA=26
SEMICOLON=27
LPAREN=28
RPAREN=29
LBRACE=30
RBRACE=31
LBRACK=32
RBRACK=33
Ident=34
ILITERAL=35
FLITERAL=36
STRING=37
WS=38
LINECOMMENT=39
BLOCKCOMMENT=40
'const'=1
'int'=2
'float'=3
'void'=4
'if'=5
'else'=6
'while'=7
'break'=8
'continue'=9
'return'=10
'+'=11
'-'=12
'*'=13
'/'=14
'%'=15
'=='=16
'!='=17
'<'=18
'<='=19
'>'=20
'>='=21
'&&'=22
'||'=23
'!'=24
'='=25
','=26
';'=27
'('=28
')'=29
'{'=30
'}'=31
'['=32
']'=33

View File

@@ -1,12 +1,16 @@
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <unistd.h> #include <string>
#include <unistd.h> // for getopt
#include <stdexcept> // for std::stoi and exceptions
using namespace std; using namespace std;
#include "SysYLexer.h" #include "SysYLexer.h"
#include "SysYParser.h" #include "SysYParser.h"
using namespace antlr4; using namespace antlr4;
// #include "Backend.h"
#include "SysYIRGenerator.h" #include "SysYIRGenerator.h"
#include "SysYIRPrinter.h" #include "SysYIRPrinter.h"
#include "SysYIROptPre.h" #include "SysYIROptPre.h"
@@ -15,7 +19,7 @@ using namespace antlr4;
#include "DeadCodeElimination.h" #include "DeadCodeElimination.h"
#include "Mem2Reg.h" #include "Mem2Reg.h"
#include "Reg2Mem.h" #include "Reg2Mem.h"
// #include "LLVMIRGenerator.h"
using namespace sysy; using namespace sysy;
int DEBUG = 0; int DEBUG = 0;
@@ -23,21 +27,27 @@ int DEEPDEBUG = 0;
static string argStopAfter; static string argStopAfter;
static string argInputFile; static string argInputFile;
static bool argFormat = false; static bool argFormat = false; // 目前未使用,但保留
static string argOutputFilename;
static int optLevel = 0; // 优化级别默认为0 (不加-O参数时)
void usage(int code = EXIT_FAILURE) { void usage(int code) {
const char *msg = "Usage: sysyc [options] inputfile\n\n" const char *msg = "Usage: sysyc [options] inputfile\n\n"
"Supported options:\n" "Supported options:\n"
" -h \tprint help message and exit\n"; " -h \tprint help message and exit\n"
" -f \tpretty-format the input file\n"; " -f \tpretty-format the input file\n"
" -s {ast,ir,asm,llvmir,asmd,ird}\tstop after generating AST/IR/Assembly\n"; " -s {ast,ir,asm,llvmir,asmd,ird}\tstop after generating AST/IR/Assembly\n"
" -S \tcompile to assembly (.s file)\n"
" -o <file>\tplace the output into <file>\n"
" -O<level>\tenable optimization at <level> (e.g., -O0, -O1)\n";
cerr << msg; cerr << msg;
exit(code); exit(code);
} }
void parseArgs(int argc, char **argv) { void parseArgs(int argc, char **argv) {
const char *optstr = "hfs:"; const char *optstr = "hfs:So:O:";
int opt = 0; int opt = 0;
while ((opt = getopt(argc, argv, optstr)) != -1) { while ((opt = getopt(argc, argv, optstr)) != -1) {
switch (opt) { switch (opt) {
case 'h': case 'h':
@@ -49,101 +59,179 @@ void parseArgs(int argc, char **argv) {
case 's': case 's':
argStopAfter = optarg; argStopAfter = optarg;
break; break;
case 'S':
argStopAfter = "asm";
break;
case 'o':
argOutputFilename = optarg;
break;
case 'O':
try {
optLevel = std::stoi(optarg);
if (optLevel < 0) {
cerr << "Error: Optimization level must be non-negative." << endl;
usage(EXIT_FAILURE);
}
} catch (const std::invalid_argument& ia) {
cerr << "Error: Invalid argument for -O: " << optarg << endl;
usage(EXIT_FAILURE);
} catch (const std::out_of_range& oor) {
cerr << "Error: Optimization level out of range: " << optarg << endl;
usage(EXIT_FAILURE);
}
break;
default: /* '?' */ default: /* '?' */
usage(); usage(EXIT_FAILURE);
} }
} }
if (optind >= argc)
usage(); if (optind >= argc) {
usage(EXIT_FAILURE);
}
argInputFile = argv[optind]; argInputFile = argv[optind];
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
parseArgs(argc, argv); parseArgs(argc, argv);
// open the input file // 1. 打开输入文件
ifstream fin(argInputFile); ifstream fin(argInputFile);
if (not fin) { if (not fin.is_open()) {
cerr << "Failed to open file " << argv[1]; cerr << "Failed to open input file: " << argInputFile << endl;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// parse sysy source to AST // 2. 解析 SysY 源代码到 AST (前端)
ANTLRInputStream input(fin); ANTLRInputStream input(fin);
SysYLexer lexer(&input); SysYLexer lexer(&input);
CommonTokenStream tokens(&lexer); CommonTokenStream tokens(&lexer);
SysYParser parser(&tokens); SysYParser parser(&tokens);
auto moduleAST = parser.compUnit(); auto moduleAST = parser.compUnit();
// 如果指定停止在 AST 阶段,则打印并退出
if (argStopAfter == "ast") { if (argStopAfter == "ast") {
cout << moduleAST->toStringTree(true) << '\n'; cout << moduleAST->toStringTree(true) << '\n';
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
// 3. 遍历 AST 生成 IR (中端开始)
// visit AST to generate IR
SysYIRGenerator generator; SysYIRGenerator generator;
generator.visitCompUnit(moduleAST); generator.visitCompUnit(moduleAST);
auto moduleIR = generator.get();
auto builder = generator.getBuilder(); // 获取 IRBuilder 实例
// 4. 执行 IR 优化 pass
// 无论最终输出是 IR 还是 ASM只要不是停止在 AST 阶段,都会进入此优化流程。
// optLevel = 0 时,执行默认优化。
// optLevel >= 1 时,执行默认优化 + 额外的 -O1 优化。
cout << "Applying middle-end optimizations (level -O" << optLevel << ")...\n";
// 默认优化 pass (在所有优化级别都会执行)
SysYOptPre optPre(moduleIR, builder);
optPre.SysYOptimizateAfterIR();
ControlFlowAnalysis cfa(moduleIR);
cfa.init();
ActiveVarAnalysis ava;
ava.init(moduleIR);
if (DEBUG) {
cout << "=== After CFA & AVA (Default) ===\n";
SysYPrinter(moduleIR).printIR(); // 临时打印器用于调试
}
DeadCodeElimination dce(moduleIR, &cfa, &ava);
dce.runDCEPipeline();
if (DEBUG) {
cout << "=== After 1st DCE (Default) ===\n";
SysYPrinter(moduleIR).printIR();
}
Mem2Reg mem2reg(moduleIR, builder, &cfa, &ava);
mem2reg.mem2regPipeline();
if (DEBUG) {
cout << "=== After Mem2Reg (Default) ===\n";
SysYPrinter(moduleIR).printIR();
}
Reg2Mem reg2mem(moduleIR, builder);
reg2mem.DeletePhiInst();
if (DEBUG) {
cout << "=== After Reg2Mem (Default) ===\n";
SysYPrinter(moduleIR).printIR();
}
dce.runDCEPipeline(); // 第二次 DCE (默认)
if (DEBUG) {
cout << "=== After 2nd DCE (Default) ===\n";
SysYPrinter(moduleIR).printIR();
}
// 根据优化级别,执行额外的优化 pass
if (optLevel >= 1) {
cout << "Applying additional -O" << optLevel << " optimizations...\n";
// 放置 -O1 及其以上级别要启用的额外优化 pass
// 例如:
// MyNewOptimizationPass newOpt(moduleIR, builder);
// newOpt.run();
// 占位符注释,替换为你的具体优化 pass
// cout << "--- Additional Pass: MyCustomOpt1 ---" << endl;
// MyCustomOpt1 opt1_pass(moduleIR, builder);
// opt1_pass.run();
// cout << "--- Additional Pass: MyCustomOpt2 ---" << endl;
// MyCustomOpt2 opt2_pass(moduleIR, builder, &cfa); // 假设需要CFA
// opt2_pass.run();
// ... 更多 -O1 特有的优化
} else {
cout << "No additional middle-end optimizations applied for -O" << optLevel << ".\n";
}
// 5. 根据 argStopAfter 决定后续操作
// a) 如果指定停止在 IR 阶段,则打印最终 IR 并退出
if (argStopAfter == "ir" || argStopAfter == "ird") { if (argStopAfter == "ir" || argStopAfter == "ird") {
// 设置 DEBUG 模式(如果指定了 'ird'
if (argStopAfter == "ird") { if (argStopAfter == "ird") {
DEBUG = 1; DEBUG = 1; // 这里可能需要更精细地控制 DEBUG 的开启时机和范围
}
auto moduleIR = generator.get();
SysYPrinter printer(moduleIR);
if (DEBUG) {
cout << "=== Original IR ===\n";
printer.printIR();
}
auto builder = generator.getBuilder();
SysYOptPre optPre(moduleIR, builder);
optPre.SysYOptimizateAfterIR();
ControlFlowAnalysis cfa(moduleIR);
cfa.init();
ActiveVarAnalysis ava;
ava.init(moduleIR);
if (DEBUG) {
cout << "=== After CFA & AVA ===\n";
printer.printIR();
}
DeadCodeElimination dce(moduleIR, &cfa, &ava);
dce.runDCEPipeline();
if (DEBUG) {
cout << "=== After 1st DCE ===\n";
printer.printIR();
}
Mem2Reg mem2reg(moduleIR, builder, &cfa, &ava);
mem2reg.mem2regPipeline();
if (DEBUG) {
cout << "=== After Mem2Reg ===\n";
printer.printIR();
}
Reg2Mem reg2mem(moduleIR, builder);
reg2mem.DeletePhiInst();
if (DEBUG) {
cout << "=== After Reg2Mem ===\n";
printer.printIR();
}
dce.runDCEPipeline();
if (DEBUG) {
cout << "=== After 2nd DCE ===\n";
printer.printIR();
} }
// 打印最终 IR
cout << "=== Final IR ===\n"; cout << "=== Final IR ===\n";
SysYPrinter printer(moduleIR); // 在这里创建打印器,因为可能之前调试时用过临时打印器
printer.printIR(); printer.printIR();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
// generate assembly // b) 如果未停止在 IR 阶段,则继续生成汇编 (后端)
auto module = generator.get(); sysy::RISCv64CodeGen codegen(moduleIR); // 传入优化后的 moduleIR
sysy::RISCv64CodeGen codegen(module);
string asmCode = codegen.code_gen(); string asmCode = codegen.code_gen();
// 如果指定停止在 ASM 阶段,则打印/保存汇编并退出
if (argStopAfter == "asm" || argStopAfter == "asmd") { if (argStopAfter == "asm" || argStopAfter == "asmd") {
// 设置 DEBUG 模式(如果指定了 'asmd'
if (argStopAfter == "asmd") { if (argStopAfter == "asmd") {
DEBUG = 1; DEBUG = 1;
DEEPDEBUG = 1; DEEPDEBUG = 1;
} }
cout << asmCode << endl;
if (!argOutputFilename.empty()) {
ofstream fout(argOutputFilename);
if (not fout.is_open()) {
cerr << "Failed to open output file: " << argOutputFilename << endl;
return EXIT_FAILURE;
}
fout << asmCode << endl;
fout.close();
} else {
cout << asmCode << endl;
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
return EXIT_SUCCESS; // 如果没有匹配到任何 -s 或 -S 选项,即意味着需要生成完整可执行文件(未来的功能)
// 目前,可以简单退出,或者打印一条提示
cout << "Compilation completed. No output specified (neither -s nor -S). Exiting.\n";
// return EXIT_SUCCESS; // 或者这里调用一个链接器生成可执行文件
return EXIT_SUCCESS;
} }