From 3dbb394bc2c5456a1d0f5891055aa6b8d72994ab Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Tue, 24 Jun 2025 22:39:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E6=9E=84=E5=BB=BA=E5=88=86?= =?UTF-8?q?=E6=9E=90=E5=99=A8=EF=BC=8C=E5=A2=9E=E5=8A=A0=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E6=B5=81=E5=88=86=E6=9E=90=EF=BC=8C=E5=AE=9E=E7=8E=B0=E6=94=AF?= =?UTF-8?q?=E9=85=8D=E8=8A=82=E7=82=B9=E8=AE=A1=E7=AE=97=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E9=85=8D=E6=A0=91=E6=9E=84=E5=BB=BA=EF=BC=8C=E6=94=AF=E9=85=8D?= =?UTF-8?q?=E8=BE=B9=E7=95=8C=E8=AE=A1=E7=AE=97=EF=BC=8C=E4=B8=BA=E5=90=8E?= =?UTF-8?q?=E7=BB=ADMem2reg=E5=81=9A=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SysYIRAnalyser.cpp | 259 ++++++++++++++++++++++++++++++ src/include/SysYIRAnalyser.h | 299 +++++++++++++++++++++++++++++++++++ 2 files changed, 558 insertions(+) diff --git a/src/SysYIRAnalyser.cpp b/src/SysYIRAnalyser.cpp index e69de29..f7c685d 100644 --- a/src/SysYIRAnalyser.cpp +++ b/src/SysYIRAnalyser.cpp @@ -0,0 +1,259 @@ +#include "SysYIRAnalyser.h" + + +namespace sysy { + + +void ControlFlowAnalysis::init() { + // 初始化分析器 + auto &functions = pModule->getFunctions(); + for (const auto &function : functions) { + auto func = function.second.get(); + auto basicBlocks = func->getBasicBlocks(); + for (auto &basicBlock : basicBlocks) { + blockAnalysisInfo[basicBlock.get()] = new BlockAnalysisInfo(); + blockAnalysisInfo[basicBlock.get()]->clear(); + } + functionAnalysisInfo[func] = new FunctionAnalysisInfo(); + functionAnalysisInfo[func]->clear(); + } +} + +void ControlFlowAnalysis::runControlFlowAnalysis() { + // 运行控制流分析 + clear(); // 清空之前的分析结果 + init(); // 初始化分析器 + computeDomNode(); + computeDomTree(); + computeDomFrontierAllBlk(); +} + +void ControlFlowAnalysis::intersectOP4Dom(std::unordered_set &dom, const std::unordered_set &other) { + // 计算交集 + for (auto it = dom.begin(); it != dom.end();) { + if (other.find(*it) == other.end()) { + // 如果other中没有这个基本块,则从dom中删除 + it = dom.erase(it); + } else { + ++it; + } + } +} + +auto ControlFlowAnalysis::findCommonDominator(BasicBlock *a, BasicBlock *b) -> BasicBlock * { + // 查找两个基本块的共同支配结点 + while (a != b) { + BlockAnalysisInfo* infoA = blockAnalysisInfo[a]; + BlockAnalysisInfo* infoB = blockAnalysisInfo[b]; + // 如果深度不同,则向上移动到直接支配结点 + // TODO:空间换时间倍增优化,优先级较低 + while (infoA->getDomDepth() > infoB->getDomDepth()) a = const_cast(infoA->getIdom()); + while (infoB->getDomDepth() > infoA->getDomDepth()) b = const_cast(infoB->getIdom()); + if (a == b) break; + a = const_cast(infoA->getIdom()); + b = const_cast(infoB->getIdom()); + } + return a; +} + +void ControlFlowAnalysis::computeDomNode(){ + auto &functions = pModule->getFunctions(); + // 分析每个函数内的基本块 + for (const auto &function : functions) { + auto func = function.second.get(); + auto basicBlocks = func->getBasicBlocks(); + std::unordered_set domSetTmp; + // 一开始把domSetTmp置为所有block + auto entry_block = func->getEntryBlock(); + entry_block->setName("Entry"); + blockAnalysisInfo[entry_block]->addDominants(entry_block); + for (auto &basicBlock : basicBlocks) { + domSetTmp.emplace(basicBlock.get()); + } + // 初始化 + for (auto &basicBlock : basicBlocks) { + if (basicBlock.get() != entry_block) { + blockAnalysisInfo[basicBlock.get()]->setDominants(domSetTmp); + // 先把所有block的必经结点都设为N + } + } + + // 支配节点计算公式 + //DOM[B]={B}∪ {⋂P∈pred(B) DOM[P]} + // 其中pred(B)是B的所有前驱结点 + // 迭代计算支配结点,直到不再变化 + // 这里使用迭代法,直到支配结点不再变化 + // TODO:Lengauer-Tarjan 算法可以更高效地计算支配结点 + // 或者按照CFG拓扑序遍历效率更高 + bool changed = true; + while (changed) { + changed = false; + // 循环非start结点 + for (auto &basicBlock : basicBlocks) { + if (basicBlock.get() != entry_block) { + auto olddom = + blockAnalysisInfo[basicBlock.get()]->getDominants(); + + std::unordered_set dom = + blockAnalysisInfo[basicBlock->getPredecessors().front()]->getDominants(); + + // 对于每个基本块,计算其支配结点 + // 取其前驱结点的支配结点的交集和自己 + for (auto pred : basicBlock->getPredecessors()) { + intersectOP4Dom(dom, blockAnalysisInfo[pred]->getDominants()); + } + dom.emplace(basicBlock.get()); + blockAnalysisInfo[basicBlock.get()]->setDominants(dom); + + if (dom != olddom) { + changed = true; + } + } + } + } + } +} + +void ControlFlowAnalysis::computeDomTree() { + // 构造支配树 + auto &functions = pModule->getFunctions(); + for (const auto &function : functions) { + auto func = function.second.get(); + auto basicBlocks = func->getBasicBlocks(); + auto entry_block = func->getEntryBlock(); + + blockAnalysisInfo[entry_block]->setIdom(entry_block); + blockAnalysisInfo[entry_block]->setDomDepth(0); // 入口块深度为0 + + bool changed = true; + while (changed) { + changed = false; + + for (auto &basicBlock : basicBlocks) { + if (basicBlock.get() == entry_block) continue; + + BasicBlock *new_idom = nullptr; + for (auto pred : basicBlock->getPredecessors()) { + // 跳过未处理的前驱 + if (blockAnalysisInfo[pred]->getIdom() == nullptr) continue; + new_idom = (new_idom == nullptr) ? pred : findCommonDominator(new_idom, pred); + // if (new_idom == nullptr) + // new_idom = pred; + // else + // new_idom = findCommonDominator(new_idom, pred); + } + // 更新直接支配节点 + if (new_idom && new_idom != blockAnalysisInfo[basicBlock.get()]->getIdom()) { + // 移除旧的支配关系 + if (blockAnalysisInfo[basicBlock.get()]->getIdom()) { + blockAnalysisInfo[const_cast(blockAnalysisInfo[basicBlock.get()]->getIdom())]->removeSdoms(basicBlock.get()); + } + // 设置新的支配关系 + blockAnalysisInfo[basicBlock.get()]->setIdom(new_idom); + blockAnalysisInfo[new_idom]->addSdoms(basicBlock.get()); + // 更新深度 = 直接支配节点深度 + 1 + blockAnalysisInfo[basicBlock.get()]->setDomDepth( + blockAnalysisInfo[new_idom]->getDomDepth() + 1); + + changed = true; + } + } + } + } + // for (auto &basicBlock : basicBlocks) { + // if (basicBlock.get() != func->getEntryBlock()) { + // auto dominats = + // blockAnalysisInfo[basicBlock.get()]->getDominants(); + // bool found = false; + // // 从前驱结点开始寻找直接支配结点 + // std::queue q; + // for (auto pred : basicBlock->getPredecessors()) { + // q.push(pred); + // } + // // BFS遍历前驱结点,直到找到直接支配结点 + // while (!found && !q.empty()) { + // auto curr = q.front(); + // q.pop(); + // if (curr == basicBlock.get()) + // continue; + // if (dominats.count(curr) != 0U) { + // blockAnalysisInfo[basicBlock.get()]->setIdom(curr); + // blockAnalysisInfo[curr]->addSdoms(basicBlock.get()); + // found = true; + // } else { + // for (auto pred : curr->getPredecessors()) { + // q.push(pred); + // } + // } + // } + // } + // } +} + +// std::unordered_set ControlFlowAnalysis::computeDomFrontier(BasicBlock *block) { +// std::unordered_set ret_list; +// // 计算 localDF +// for (auto local_successor : block->getSuccessors()) { +// if (local_successor->getIdom() != block) { +// ret_list.emplace(local_successor); +// } +// } +// // 计算 upDF +// for (auto up_successor : block->getSdoms()) { +// auto childrenDF = computeDF(up_successor); +// for (auto w : childrenDF) { +// if (block != w->getIdom() || block == w) { +// ret_list.emplace(w); +// } +// } +// } + +// return ret_list; +// } + +void ControlFlowAnalysis::computeDomFrontierAllBlk() { + auto &functions = pModule->getFunctions(); + for (const auto &function : functions) { + auto func = function.second.get(); + auto basicBlocks = func->getBasicBlocks(); + + // 按支配树深度排序(从深到浅) + std::vector orderedBlocks; + for (auto &bb : basicBlocks) { + orderedBlocks.push_back(bb.get()); + } + std::sort(orderedBlocks.begin(), orderedBlocks.end(), + [this](BasicBlock *a, BasicBlock *b) { + return blockAnalysisInfo[a]->getDomDepth() > blockAnalysisInfo[b]->getDomDepth(); + }); + + // 计算支配边界 + for (auto block : orderedBlocks) { + std::unordered_set df; + + // Local DF: 直接后继中不被当前块支配的 + for (auto succ : block->getSuccessors()) { + // 当前块不支配该后继(即不是其直接支配节点) + if (blockAnalysisInfo[succ]->getIdom() != block) { + df.insert(succ); + } + } + + // Up DF: 从支配子树中继承 + for (auto child : blockAnalysisInfo[block]->getSdoms()) { + for (auto w : blockAnalysisInfo[child]->getDomFrontiers()) { + // 如果w不被当前块支配 + if (block != blockAnalysisInfo[w]->getIdom()) { + df.insert(w); + } + } + } + + blockAnalysisInfo[block]->setDomFrontiers(df); + } + } +} + + +} // namespace sysy + diff --git a/src/include/SysYIRAnalyser.h b/src/include/SysYIRAnalyser.h index e69de29..2cb3f1f 100644 --- a/src/include/SysYIRAnalyser.h +++ b/src/include/SysYIRAnalyser.h @@ -0,0 +1,299 @@ +#pragma once + +#include "IR.h" + +namespace sysy { + +// 前向声明 + +class Loop; +// 基本块分析信息类 +class BlockAnalysisInfo { + +public: + using block_list = std::vector; + using block_set = std::unordered_set; + +protected: + // 支配树相关 + int domdepth = 0; ///< 支配节点所在深度 + BasicBlock* idom = nullptr; ///< 直接支配结点 + block_list sdoms; ///< 支配树后继 + block_set dominants; ///< 必经结点集合 + block_set dominant_frontiers; ///< 支配边界 + + // 后续添加循环分析相关 + // Loop* loopbelong = nullptr; ///< 所属循环 + // int loopdepth = 0; ///< 循环深度 + +public: + // getterface + const int getDomDepth() const { return domdepth; } + const BasicBlock* getIdom() const { return idom; } + const block_list& getSdoms() const { return sdoms; } + const block_set& getDominants() const { return dominants; } + const block_set& getDomFrontiers() const { return dominant_frontiers; } + + // 支配树操作 + void setDomDepth(int depth) { domdepth = depth; } + void setIdom(BasicBlock* block) { idom = block; } + void addSdoms(BasicBlock* block) { sdoms.push_back(block); } + void clearSdoms() { sdoms.clear(); } + void removeSdoms(BasicBlock* block) { + sdoms.erase(std::remove(sdoms.begin(), sdoms.end(), block), sdoms.end()); + } + void addDominants(BasicBlock* block) { dominants.emplace(block); } + void addDominants(const block_set& blocks) { dominants.insert(blocks.begin(), blocks.end()); } + void setDominants(BasicBlock* block) { + dominants.clear(); + addDominants(block); + } + void setDominants(const block_set& doms) { + dominants = doms; + } + void setDomFrontiers(const block_set& df) { + dominant_frontiers = df; + } + + + // TODO:循环分析操作方法 + + // 清空所有分析信息 + void clear() { + domdepth = -1; + idom = nullptr; + sdoms.clear(); + dominants.clear(); + dominant_frontiers.clear(); + // loopbelong = nullptr; + // loopdepth = 0; + } +}; + +// 函数分析信息类 +class FunctionAnalysisInfo { + + +public: + // 函数属性 + enum FunctionAttribute : uint64_t { + PlaceHolder = 0x0UL, + Pure = 0x1UL << 0, + SelfRecursive = 0x1UL << 1, + SideEffect = 0x1UL << 2, + NoPureCauseMemRead = 0x1UL << 3 + }; + + // 数据结构 + using Loop_list = std::list>; + using block_loop_map = std::unordered_map; + using value_block_map = std::unordered_map; + using value_block_count_map = std::unordered_map>; + + // 分析数据 + FunctionAttribute attribute = PlaceHolder; ///< 函数属性 + std::set callees; ///< 函数调用集合 + Loop_list loops; ///< 所有循环 + Loop_list topLoops; ///< 顶层循环 + block_loop_map basicblock2Loop; ///< 基本块到循环映射 + std::list> indirectAllocas; ///< 间接分配内存 + + // 值定义/使用信息 + value_block_map value2AllocBlocks; ///< 值分配位置映射 + value_block_count_map value2DefBlocks; ///< 值定义位置映射 + value_block_count_map value2UseBlocks; ///< 值使用位置映射 + + // 函数属性操作 + FunctionAttribute getAttribute() const { return attribute; } + void setAttribute(FunctionAttribute attr) { attribute = static_cast(attribute | attr); } + void clearAttribute() { attribute = PlaceHolder; } + + // 调用关系操作 + void addCallee(Function* callee) { callees.insert(callee); } + void removeCallee(Function* callee) { callees.erase(callee); } + void clearCallees() { callees.clear(); } + + // 循环分析操作 + Loop* getLoopOfBasicBlock(BasicBlock* bb) { + auto it = basicblock2Loop.find(bb); + return it != basicblock2Loop.end() ? it->second : nullptr; + } + + void addBBToLoop(BasicBlock* bb, Loop* loop) { basicblock2Loop[bb] = loop; } + + unsigned getLoopDepthByBlock(BasicBlock* bb) { + Loop* loop = getLoopOfBasicBlock(bb); + return loop ? loop->getLoopDepth() : 0; + } + + // 值-块映射操作 + void addValue2AllocBlocks(Value* value, BasicBlock* block) { value2AllocBlocks[value] = block; } + + BasicBlock* getAllocBlockByValue(Value* value) { + auto it = value2AllocBlocks.find(value); + return it != value2AllocBlocks.end() ? it->second : nullptr; + } + + // 值定义/使用操作 + void addValue2DefBlocks(Value* value, BasicBlock* block) { ++value2DefBlocks[value][block]; } + void addValue2UseBlocks(Value* value, BasicBlock* block) { ++value2UseBlocks[value][block]; } + + // 间接分配操作 + void addIndirectAlloca(AllocaInst* alloca) { indirectAllocas.emplace_back(alloca); } + + // 清空所有分析信息 + void clear() { + attribute = PlaceHolder; + callees.clear(); + loops.clear(); + topLoops.clear(); + basicblock2Loop.clear(); + indirectAllocas.clear(); + value2AllocBlocks.clear(); + value2DefBlocks.clear(); + value2UseBlocks.clear(); + } +}; +// 循环类 - 未实现优化 +class Loop { +public: + using block_list = std::vector; + using block_set = std::unordered_set; + using Loop_list = std::vector; + +protected: + Function *parent; // 所属函数 + block_list blocksInLoop; // 循环内的基本块 + BasicBlock *preheaderBlock = nullptr; // 前驱块 + BasicBlock *headerBlock = nullptr; // 循环头 + block_list latchBlock; // 回边块 + block_set exitingBlocks; // 退出块 + block_set exitBlocks; // 退出目标块 + Loop *parentloop = nullptr; // 父循环 + Loop_list subLoops; // 子循环 + size_t loopID; // 循环ID + unsigned loopDepth; // 循环深度 + + Instruction *indCondVar = nullptr; // 循环条件变量 + Instruction::Kind IcmpKind; // 比较类型 + Value *indEnd = nullptr; // 循环结束值 + AllocaInst *IndPhi = nullptr; // 循环变量 + + ConstantValue *indBegin = nullptr; // 循环起始值 + ConstantValue *indStep = nullptr; // 循环步长 + + std::set GlobalValuechange; // 循环内改变的全局变量 + + int StepType = 0; // 循环步长类型 + bool parallelable = false; // 是否可并行 + +public: + explicit Loop(BasicBlock *header, const std::string &name = "") + : headerBlock(header) { + blocksInLoop.push_back(header); + } + + void setloopID() { + static unsigned loopCount = 0; + loopCount = loopCount + 1; + loopID = loopCount; + } + ConstantValue* getindBegin() { return indBegin; } + ConstantValue* getindStep() { return indStep; } + void setindBegin(ConstantValue *indBegin2set) { indBegin = indBegin2set; } + void setindStep(ConstantValue *indStep2set) { indStep = indStep2set; } + void setStepType(int StepType2Set) { StepType = StepType2Set; } + int getStepType() { return StepType; } + size_t getLoopID() { return loopID; } + + BasicBlock* getHeader() const { return headerBlock; } + BasicBlock* getPreheaderBlock() const { return preheaderBlock; } + block_list& getLatchBlocks() { return latchBlock; } + block_set& getExitingBlocks() { return exitingBlocks; } + block_set& getExitBlocks() { return exitBlocks; } + Loop* getParentLoop() const { return parentloop; } + void setParentLoop(Loop *parent) { parentloop = parent; } + void addBasicBlock(BasicBlock *bb) { blocksInLoop.push_back(bb); } + void addSubLoop(Loop *loop) { subLoops.push_back(loop); } + void setLoopDepth(unsigned depth) { loopDepth = depth; } + block_list& getBasicBlocks() { return blocksInLoop; } + Loop_list& getSubLoops() { return subLoops; } + unsigned getLoopDepth() const { return loopDepth; } + + bool isLoopContainsBasicBlock(BasicBlock *bb) const { + return std::find(blocksInLoop.begin(), blocksInLoop.end(), bb) != blocksInLoop.end(); + } + + void addExitingBlock(BasicBlock *bb) { exitingBlocks.insert(bb); } + void addExitBlock(BasicBlock *bb) { exitBlocks.insert(bb); } + void addLatchBlock(BasicBlock *bb) { latchBlock.push_back(bb); } + void setPreheaderBlock(BasicBlock *bb) { preheaderBlock = bb; } + + void setIndexCondInstr(Instruction *instr) { indCondVar = instr; } + void setIcmpKind(Instruction::Kind kind) { IcmpKind = kind; } + Instruction::Kind getIcmpKind() const { return IcmpKind; } + + bool isSimpleLoopInvariant(Value *value) ; + + void setIndEnd(Value *value) { indEnd = value; } + void setIndPhi(AllocaInst *phi) { IndPhi = phi; } + Value* getIndEnd() const { return indEnd; } + AllocaInst* getIndPhi() const { return IndPhi; } + Instruction* getIndCondVar() const { return indCondVar; } + + void addGlobalValuechange(GlobalValue *globalvaluechange2add) { + GlobalValuechange.insert(globalvaluechange2add); + } + std::set& getGlobalValuechange() { + return GlobalValuechange; + } + + void setParallelable(bool flag) { parallelable = flag; } + bool isParallelable() const { return parallelable; } +}; + +class ControlFlowAnalysis { +private: + Module *pModule; ///< 模块 + std::unordered_map blockAnalysisInfo; // 基本块分析信息 + std::unordered_map functionAnalysisInfo; // 函数分析信息 + +public: + explicit ControlFlowAnalysis(Module *pMoudle) : pModule(pMoudle) {} + + void init(); // 初始化分析器 + void computeDomNode(); // 计算必经结点 + void computeDomTree(); // 构造支配树 + // std::unordered_set computeDomFrontier(BasicBlock *block) ; // 计算单个块的支配边界(弃用) + void computeDomFrontierAllBlk(); // 计算所有块的支配边界 + void runControlFlowAnalysis(); // 运行控制流分析(主要是支配树和支配边界) + void clear(){ + for (auto &pair : blockAnalysisInfo) { + delete pair.second; // 清理基本块分析信息 + } + blockAnalysisInfo.clear(); + + for (auto &pair : functionAnalysisInfo) { + delete pair.second; // 清理函数分析信息 + } + functionAnalysisInfo.clear(); + } // 清空分析结果 + ~ControlFlowAnalysis() { + clear(); // 析构时清理所有分析信息 + } + +private: + void intersectOP4Dom(std::unordered_set &dom, const std::unordered_set &other); // 交集运算, + BasicBlock* findCommonDominator(BasicBlock *a, BasicBlock *b); // 查找两个基本块的共同支配结点 +}; + + +// 分析管理器(整合版) +class AnalysisManager { + +}; + + + + +} // namespace sysy \ No newline at end of file