#include #include #include #include #include // for getopt #include // for std::stoi and exceptions using namespace std; #include "SysYLexer.h" #include "SysYParser.h" using namespace antlr4; #include "SysYIRGenerator.h" #include "SysYIRPrinter.h" #include "SysYIROptPre.h" #include "RISCv64Backend.h" #include "SysYIRAnalyser.h" // #include "DeadCodeElimination.h" #include "AddressCalculationExpansion.h" // #include "Mem2Reg.h" // #include "Reg2Mem.h" using namespace sysy; int DEBUG = 0; int DEEPDEBUG = 0; static string argStopAfter; static string argInputFile; static bool argFormat = false; // 目前未使用,但保留 static string argOutputFilename; static int optLevel = 0; // 优化级别,默认为0 (不加-O参数时) void usage(int code) { const char *msg = "Usage: sysyc [options] inputfile\n\n" "Supported options:\n" " -h \tprint help message and exit\n" " -f \tpretty-format the input file\n" " -s {ast,ir,asm,llvmir,asmd,ird}\tstop after generating AST/IR/Assembly\n" " -S \tcompile to assembly (.s file)\n" " -o \tplace the output into \n" " -O\tenable optimization at (e.g., -O0, -O1)\n"; cerr << msg; exit(code); } void parseArgs(int argc, char **argv) { const char *optstr = "hfs:So:O:"; int opt = 0; while ((opt = getopt(argc, argv, optstr)) != -1) { switch (opt) { case 'h': usage(EXIT_SUCCESS); break; case 'f': argFormat = true; break; case 's': argStopAfter = optarg; 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: /* '?' */ usage(EXIT_FAILURE); } } if (optind >= argc) { usage(EXIT_FAILURE); } argInputFile = argv[optind]; } int main(int argc, char **argv) { parseArgs(argc, argv); // 1. 打开输入文件 ifstream fin(argInputFile); if (not fin.is_open()) { cerr << "Failed to open input file: " << argInputFile << endl; return EXIT_FAILURE; } // 2. 解析 SysY 源代码到 AST (前端) ANTLRInputStream input(fin); SysYLexer lexer(&input); CommonTokenStream tokens(&lexer); SysYParser parser(&tokens); auto moduleAST = parser.compUnit(); // 如果指定停止在 AST 阶段,则打印并退出 if (argStopAfter == "ast") { cout << moduleAST->toStringTree(true) << '\n'; return EXIT_SUCCESS; } // 3. 遍历 AST 生成 IR (中端开始) SysYIRGenerator generator; generator.visitCompUnit(moduleAST); auto moduleIR = generator.get(); auto builder = generator.getBuilder(); // 获取 IRBuilder 实例 // 4. 执行 IR 优化 pass // 无论最终输出是 IR 还是 ASM,只要不是停止在 AST 阶段,都会进入此优化流程。 // optLevel = 0 时,执行默认优化。 // optLevel >= 1 时,执行默认优化 + 额外的 -O1 优化。 if (DEBUG) cout << "Applying middle-end optimizations (level -O" << optLevel << ")...\n"; // 设置 DEBUG 模式(如果指定了 'ird') if (argStopAfter == "ird") { DEBUG = 1; // 这里可能需要更精细地控制 DEBUG 的开启时机和范围 } // 默认优化 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(); // 临时打印器用于调试 } AddressCalculationExpansion ace(moduleIR, builder); if (ace.run()) { if (DEBUG) cout << "AddressCalculationExpansion made changes.\n"; // 如果 ACE 改变了IR,并且 DEBUG 模式开启,可以考虑打印IR if (DEBUG) { cout << "=== After AddressCalculationExpansion ===\n"; SysYPrinter(moduleIR).printIR(); } } else { if (DEBUG) cout << "AddressCalculationExpansion made no changes.\n"; } // 根据优化级别,执行额外的优化 pass if (optLevel >= 1) { if (DEBUG) 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 特有的优化 // 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(); // } } else { if (DEBUG) cout << "No additional middle-end optimizations applied for -O" << optLevel << ".\n"; } // 5. 根据 argStopAfter 决定后续操作 // a) 如果指定停止在 IR 阶段,则打印最终 IR 并退出 if (argStopAfter == "ir" || argStopAfter == "ird") { // 打印最终 IR cout << "=== Final IR ===\n"; SysYPrinter printer(moduleIR); // 在这里创建打印器,因为可能之前调试时用过临时打印器 printer.printIR(); return EXIT_SUCCESS; } // b) 如果未停止在 IR 阶段,则继续生成汇编 (后端) // 设置 DEBUG 模式(如果指定了 'asmd') if (argStopAfter == "asmd") { DEBUG = 1; DEEPDEBUG = 1; } sysy::RISCv64CodeGen codegen(moduleIR); // 传入优化后的 moduleIR string asmCode = codegen.code_gen(); // 如果指定停止在 ASM 阶段,则打印/保存汇编并退出 if (argStopAfter == "asm" || argStopAfter == "asmd") { 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; } // 如果没有匹配到任何 -s 或 -S 选项,即意味着需要生成完整可执行文件(未来的功能) // 目前,可以简单退出,或者打印一条提示 cout << "Compilation completed. No output specified (neither -s nor -S). Exiting.\n"; // return EXIT_SUCCESS; // 或者这里调用一个链接器生成可执行文件 return EXIT_SUCCESS; }