#pragma once #include "IR.h" #include "IRBuilder.h" namespace sysy { // 优化前对SysY IR的预处理,也可以视作部分CFG优化 // 主要包括删除无用指令、合并基本块、删除空块等 // 这些操作可以在SysY IR生成时就完成,但为了简化IR生成过程, // 这里将其放在SysY IR生成后进行预处理 // 同时兼容phi节点的处理,可以再mem2reg后再次调用优化 //TODO: 可增加的CFG优化和方法 // - 检查基本块跳转关系正确性 // - 简化条件分支(Branch Simplification),如条件恒真/恒假转为直接跳转 // - 合并连续的跳转指令(Jump Threading)在合并不可达块中似乎已经实现了 // - 基本块重排序(Block Reordering),提升局部性 class SysYCFGOpt { private: Module *pModule; IRBuilder *pBuilder; public: SysYCFGOpt(Module *pMoudle, IRBuilder *pBuilder) : pModule(pMoudle), pBuilder(pBuilder) {} void SysYOptimizateAfterIR(){ auto &functions = pModule->getFunctions(); for (auto &function : functions) { bool changed = false; while(changed){ changed = false; changed |= SysYCondBr2Br(function.second.get(), pBuilder); // 删除br后面的无用指令 changed |= SysYDelInstAfterBr(function.second.get()); // 合并空基本块 changed |= SysYBlockMerge(function.second.get()); // 删除无前驱块 changed |= SysYDelNoPreBLock(function.second.get()); // 删除空块 changed |= SysYDelEmptyBlock(function.second.get(), pBuilder); // 添加return指令 changed |= SysYAddReturn(function.second.get(), pBuilder); } } } public: static bool SysYDelInstAfterBr(Function *func); // 删除br后面的指令 static bool SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder); // 空块删除 static bool SysYDelNoPreBLock(Function *func); // 删除无前驱块(不可达块) static bool SysYBlockMerge(Function *func); // 合并基本块(主要针对嵌套if while的exit块, // 也可以修改IR生成实现回填机制 static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令(主要针对Void函数) static bool SysYCondBr2Br(Function *func, IRBuilder* pBuilder); // 条件分支(已知cond的值)转换为无条件分支 }; } // namespace sysy