54 lines
2.2 KiB
C++
54 lines
2.2 KiB
C++
#include "RISCv64Passes.h"
|
||
#include <iostream>
|
||
|
||
namespace sysy {
|
||
|
||
// --- 寄存器分配前优化 ---
|
||
|
||
void PreRA_Scheduler::runOnMachineFunction(MachineFunction* mfunc) {
|
||
// TODO: 在此实现寄存器分配前的指令调度。
|
||
// 遍历mfunc中的每一个MachineBasicBlock。
|
||
// 对每个基本块内的MachineInstr列表进行重排。
|
||
//
|
||
// 实现思路:
|
||
// 1. 分析每个基本块内指令的数据依赖关系,构建依赖图(DAG)。
|
||
// 2. 根据目标处理器的流水线特性(指令延迟等),使用列表调度等算法对指令进行重排。
|
||
// 3. 此时操作的是虚拟寄存器,只存在真依赖,调度自由度最大。
|
||
//
|
||
// std::cout << "Running Pre-RA Instruction Scheduler..." << std::endl;
|
||
}
|
||
|
||
|
||
// --- 寄存器分配后优化 ---
|
||
|
||
void PeepholeOptimizer::runOnMachineFunction(MachineFunction* mfunc) {
|
||
// TODO: 在此实现窥孔优化。
|
||
// 遍历mfunc中的每一个MachineBasicBlock。
|
||
// 对每个基本块内的MachineInstr列表进行扫描和替换。
|
||
//
|
||
// 实现思路:
|
||
// 1. 维护一个大小固定(例如3-5条指令)的滑动窗口。
|
||
// 2. 识别特定的冗余模式,例如:
|
||
// - `mv a0, a1` 后紧跟 `mv a1, a0` (可消除的交换)
|
||
// - `sw t0, 12(s0)` 后紧跟 `lw t1, 12(s0)` (冗余加载)
|
||
// - 强度削减: `mul x, x, 2` -> `slli x, x, 1`
|
||
// 3. 识别后,直接修改MachineInstr列表(删除、替换或插入指令)。
|
||
//
|
||
// std::cout << "Running Post-RA Peephole Optimizer..." << std::endl;
|
||
}
|
||
|
||
void PostRA_Scheduler::runOnMachineFunction(MachineFunction* mfunc) {
|
||
// TODO: 在此实现寄存器分配后的局部指令调度。
|
||
// 遍历mfunc中的每一个MachineBasicBlock。
|
||
// 重点关注由寄存器分配器插入的spill/fill代码。
|
||
//
|
||
// 实现思路:
|
||
// 1. 识别出用于spill/fill的lw/sw指令。
|
||
// 2. 在不违反数据依赖(包括物理寄存器引入的伪依赖)的前提下,
|
||
// 尝试将lw指令向上移动,使其与使用它的指令之间有足够的距离,以隐藏访存延迟。
|
||
// 3. 同样,可以尝试将sw指令向下移动。
|
||
//
|
||
// std::cout << "Running Post-RA Local Scheduler..." << std::endl;
|
||
}
|
||
|
||
} // namespace sysy
|