Files
mysysy/src/sysyc.cpp

248 lines
7.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <unistd.h> // for getopt
#include <stdexcept> // 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 <file>\tplace the output into <file>\n"
" -O<level>\tenable optimization at <level> (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;
}