[midend]重构中端,建立遍管理器,注册器等,初步构建支配树分析遍,增加基本块方法

This commit is contained in:
rain2133
2025-07-21 15:19:38 +08:00
parent 88604c1f94
commit 550f4017be
5 changed files with 538 additions and 1 deletions

181
src/Dom.cpp Normal file
View File

@ -0,0 +1,181 @@
#include "Dom.h"
#include <limits> // for std::numeric_limits
#include <queue>
namespace sysy {
// 初始化 支配树静态 ID
char DominatorTreeAnalysisPass::ID = 0;
// ==============================================================
// DominatorTree 结果类的实现
// ==============================================================
DominatorTree::DominatorTree(Function *F) : AssociatedFunction(F) {
// 构造时可以不计算,在分析遍运行里计算并填充
}
const std::set<BasicBlock *> *DominatorTree::getDominators(BasicBlock *BB) const {
auto it = Dominators.find(BB);
if (it != Dominators.end()) {
return &(it->second);
}
return nullptr;
}
BasicBlock *DominatorTree::getImmediateDominator(BasicBlock *BB) const {
auto it = IDoms.find(BB);
if (it != IDoms.end()) {
return it->second;
}
return nullptr;
}
const std::set<BasicBlock *> *DominatorTree::getDominanceFrontier(BasicBlock *BB) const {
auto it = DominanceFrontiers.find(BB);
if (it != DominanceFrontiers.end()) {
return &(it->second);
}
return nullptr;
}
void DominatorTree::computeDominators(Function *F) {
// 经典的迭代算法计算支配者集合
// TODO: 可以替换为更高效的算法,如 Lengauer-Tarjan 算法
BasicBlock *entryBlock = F->getEntryBlock();
for (const auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
if (bb == entryBlock) {
Dominators[bb].insert(bb);
} else {
for (const auto &all_bb_ptr : F->getBasicBlocks()) {
Dominators[bb].insert(all_bb_ptr.get());
}
}
}
bool changed = true;
while (changed) {
changed = false;
for (const auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
if (bb == entryBlock)
continue;
std::set<BasicBlock *> newDom;
bool firstPred = true;
for (BasicBlock *pred : bb->getPredecessors()) {
if (Dominators.count(pred)) {
if (firstPred) {
newDom = Dominators[pred];
firstPred = false;
} else {
std::set<BasicBlock *> intersection;
std::set_intersection(newDom.begin(), newDom.end(), Dominators[pred].begin(), Dominators[pred].end(),
std::inserter(intersection, intersection.begin()));
newDom = intersection;
}
}
}
newDom.insert(bb);
if (newDom != Dominators[bb]) {
Dominators[bb] = newDom;
changed = true;
}
}
}
}
void DominatorTree::computeIDoms(Function *F) {
// 采用与之前类似的简化实现。TODO:Lengauer-Tarjan等算法。
BasicBlock *entryBlock = F->getEntryBlock();
IDoms[entryBlock] = nullptr;
for (const auto &bb_ptr : F->getBasicBlocks()) {
BasicBlock *bb = bb_ptr.get();
if (bb == entryBlock)
continue;
BasicBlock *currentIDom = nullptr;
const std::set<BasicBlock *> *domsOfBB = getDominators(bb);
if (!domsOfBB)
continue;
for (BasicBlock *D : *domsOfBB) {
if (D == bb)
continue;
bool isCandidateIDom = true;
for (BasicBlock *candidate : *domsOfBB) {
if (candidate == bb || candidate == D)
continue;
const std::set<BasicBlock *> *domsOfCandidate = getDominators(candidate);
if (domsOfCandidate && domsOfCandidate->count(D) == 0 && domsOfBB->count(candidate)) {
isCandidateIDom = false;
break;
}
}
if (isCandidateIDom) {
currentIDom = D;
break;
}
}
IDoms[bb] = currentIDom;
}
}
void DominatorTree::computeDominanceFrontiers(Function *F) {
// 经典的支配边界计算算法
for (const auto &bb_ptr_X : F->getBasicBlocks()) {
BasicBlock *X = bb_ptr_X.get();
DominanceFrontiers[X].clear();
for (BasicBlock *Y : X->getSuccessors()) {
const std::set<BasicBlock *> *domsOfY = getDominators(Y);
if (domsOfY && domsOfY->find(X) == domsOfY->end()) {
DominanceFrontiers[X].insert(Y);
}
}
const std::set<BasicBlock *> *domsOfX = getDominators(X);
if (!domsOfX)
continue;
for (const auto &bb_ptr_Z : F->getBasicBlocks()) {
BasicBlock *Z = bb_ptr_Z.get();
if (Z == X)
continue;
const std::set<BasicBlock *> *domsOfZ = getDominators(Z);
if (domsOfZ && domsOfZ->count(X) && Z != X) {
for (BasicBlock *Y : Z->getSuccessors()) {
const std::set<BasicBlock *> *domsOfY = getDominators(Y);
if (domsOfY && domsOfY->find(X) == domsOfY->end()) {
DominanceFrontiers[X].insert(Y);
}
}
}
}
}
}
// ==============================================================
// DominatorTreeAnalysisPass 的实现
// ==============================================================
bool DominatorTreeAnalysisPass::runOnFunction(Function* F) {
CurrentDominatorTree = std::make_unique<DominatorTree>(F);
CurrentDominatorTree->computeDominators(F);
CurrentDominatorTree->computeIDoms(F);
CurrentDominatorTree->computeDominanceFrontiers(F);
return false;
}
std::unique_ptr<AnalysisResultBase> DominatorTreeAnalysisPass::getResult() {
// 返回计算好的 DominatorTree 实例,所有权转移给 AnalysisManager
return std::move(CurrentDominatorTree);
}
} // namespace sysy

52
src/include/Dom.h Normal file
View File

@ -0,0 +1,52 @@
#pragma once
#include "Pass.h" // 包含 Pass 框架
#include "IR.h" // 包含 IR 定义
#include <map>
#include <set>
#include <vector>
#include <algorithm>
namespace sysy {
// 支配树分析结果类 (保持不变)
class DominatorTree : public AnalysisResultBase {
public:
DominatorTree(Function* F);
const std::set<BasicBlock*>* getDominators(BasicBlock* BB) const;
BasicBlock* getImmediateDominator(BasicBlock* BB) const;
const std::set<BasicBlock*>* getDominanceFrontier(BasicBlock* BB) const;
const std::map<BasicBlock*, std::set<BasicBlock*>>& getDominatorsMap() const { return Dominators; }
const std::map<BasicBlock*, BasicBlock*>& getIDomsMap() const { return IDoms; }
const std::map<BasicBlock*, std::set<BasicBlock*>>& getDominanceFrontiersMap() const { return DominanceFrontiers; }
void computeDominators(Function* F);
void computeIDoms(Function* F);
void computeDominanceFrontiers(Function* F);
private:
Function* AssociatedFunction;
std::map<BasicBlock*, std::set<BasicBlock*>> Dominators;
std::map<BasicBlock*, BasicBlock*> IDoms;
std::map<BasicBlock*, std::set<BasicBlock*>> DominanceFrontiers;
};
// 支配树分析遍
class DominatorTreeAnalysisPass : public AnalysisPass {
public:
// 唯一的 Pass ID
static char ID; // LLVM 风格的唯一 ID
DominatorTreeAnalysisPass() : AnalysisPass("DominatorTreeAnalysis", Pass::Granularity::Function) {}
// 实现 getPassID
void* getPassID() const override { return &ID; }
bool runOnFunction(Function* F) override;
std::unique_ptr<AnalysisResultBase> getResult() override;
private:
std::unique_ptr<DominatorTree> CurrentDominatorTree;
};
} // namespace sysy

View File

@ -522,12 +522,20 @@ public:
void setParent(Function *func) { parent = func; }
inst_list& getInstructions() { return instructions; }
arg_list& getArguments() { return arguments; }
const block_list& getPredecessors() const { return predecessors; }
block_list& getPredecessors() { return predecessors; }
void clearPredecessors() { predecessors.clear(); }
block_list& getSuccessors() { return successors; }
void clearSuccessors() { successors.clear(); }
iterator begin() { return instructions.begin(); }
iterator end() { return instructions.end(); }
iterator terminator() { return std::prev(end()); }
void insertArgument(AllocaInst *inst) { arguments.push_back(inst); }
bool hasSuccessor(BasicBlock *block) const {
return std::find(successors.begin(), successors.end(), block) != successors.end();
} ///< 判断是否有后继块
bool hasPredecessor(BasicBlock *block) const {
return std::find(predecessors.begin(), predecessors.end(), block) != predecessors.end();
} ///< 判断是否有前驱块
void addPredecessor(BasicBlock *block) {
if (std::find(predecessors.begin(), predecessors.end(), block) == predecessors.end()) {
predecessors.push_back(block);
@ -580,6 +588,15 @@ public:
next->addPredecessor(prev);
}
void removeInst(iterator pos) { instructions.erase(pos); }
void removeInst(Instruction *inst) {
auto pos = std::find_if(instructions.begin(), instructions.end(),
[inst](const std::unique_ptr<Instruction> &i) { return i.get() == inst; });
if (pos != instructions.end()) {
instructions.erase(pos);
} else {
assert(false && "Instruction not found in BasicBlock");
}
} ///< 移除指定位置的指令
iterator moveInst(iterator sourcePos, iterator targetPos, BasicBlock *block);
};

284
src/include/Pass.h Normal file
View File

@ -0,0 +1,284 @@
#pragma once
#include <functional> // For std::function
#include <map>
#include <memory>
#include <set>
#include <string>
#include <typeindex> // For std::type_index (although void* ID is more common in LLVM)
#include <vector>
namespace sysy {
// 抽象基类:分析结果
class AnalysisResultBase {
public:
virtual ~AnalysisResultBase() = default;
};
// 抽象基类Pass
class Pass {
public:
enum class Granularity { Module, Function, BasicBlock };
enum class PassKind { Analysis, Optimization };
Pass(const std::string &name, Granularity g, PassKind k) : Name(name), G(g), K(k) {}
virtual ~Pass() = default;
const std::string &getName() const { return Name; }
Granularity getGranularity() const { return G; }
PassKind getPassKind() const { return K; }
virtual bool runOnModule(Module *M, AnalysisManager& AM) { return false; }
virtual bool runOnFunction(Function *F, AnalysisManager& AM) { return false; }
virtual bool runOnBasicBlock(BasicBlock *BB, AnalysisManager& AM) { return false; }
// 所有 Pass 都必须提供一个唯一的 ID
// 这通常是一个静态成员,并在 Pass 类外部定义
virtual void *getPassID() const = 0;
protected:
std::string Name;
Granularity G;
PassKind K;
};
// 抽象基类:分析遍
class AnalysisPass : public Pass {
public:
AnalysisPass(const std::string &name, Granularity g) : Pass(name, g, PassKind::Analysis) {}
virtual std::unique_ptr<AnalysisResultBase> getResult() = 0;
};
// 抽象基类:优化遍
class OptimizationPass : public Pass {
public:
OptimizationPass(const std::string &name, Granularity g) : Pass(name, g, PassKind::Optimization) {}
virtual void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const {
// 默认不依赖也不修改任何分析
}
};
// ======================================================================
// PassRegistry: 全局 Pass 注册表 (单例)
// ======================================================================
class PassRegistry {
public:
// Pass 工厂函数类型:返回 Pass 的唯一指针
using PassFactory = std::function<std::unique_ptr<Pass>()>;
// 获取 PassRegistry 实例 (单例模式)
static PassRegistry &getPassRegistry() {
static PassRegistry instance;
return instance;
}
// 注册一个 Pass
// passID 是 Pass 类的唯一静态 ID (例如 MyPass::ID 的地址)
// factory 是一个 lambda 或函数指针,用于创建该 Pass 的实例
void registerPass(void *passID, PassFactory factory) {
if (factories.count(passID)) {
// Error: Pass with this ID already registered
// You might want to throw an exception or log an error
return;
}
factories[passID] = std::move(factory);
}
// 通过 Pass ID 创建一个 Pass 实例
std::unique_ptr<Pass> createPass(void *passID) {
auto it = factories.find(passID);
if (it == factories.end()) {
// Error: Pass with this ID not registered
return nullptr;
}
return it->second(); // 调用工厂函数创建实例
}
private:
PassRegistry() = default; // 私有构造函数,实现单例
~PassRegistry() = default;
PassRegistry(const PassRegistry &) = delete; // 禁用拷贝构造
PassRegistry &operator=(const PassRegistry &) = delete; // 禁用赋值操作
std::map<void *, PassFactory> factories;
};
// ======================================================================
// AnalysisManager: 负责管理和提供分析结果
// ======================================================================
class AnalysisManager {
public:
AnalysisManager() = default;
~AnalysisManager() = default;
// 获取分析结果
// T 是 AnalysisResult 的具体类型E 是 AnalysisPass 的具体类型
// PassManager 应该在运行 Pass 之前调用 registerAnalysisPass
template <typename T, typename E> T *getAnalysisResult(Function *F) { // 针对函数级别的分析,需要传入 Function*
void *analysisID = E::ID; // 获取分析遍的唯一 ID
// 检查是否已存在有效结果
auto it = cachedResults.find({F, analysisID});
if (it != cachedResults.end()) {
return static_cast<T *>(it->second.get()); // 返回缓存结果
}
// 如果没有缓存结果,通过 PassRegistry 创建分析遍并运行它
// 注意:这里需要 PassRegistry 实例。如果 AnalysisManager 独立于 PassManager
// 则需要传入 PassRegistry 引用或指针。
// 为了简化,假设 AnalysisManager 能够访问到 PassRegistry
std::unique_ptr<Pass> basePass = PassRegistry::getPassRegistry().createPass(analysisID);
if (!basePass) {
// Error: Analysis pass not registered
return nullptr;
}
AnalysisPass *analysisPass = static_cast<AnalysisPass *>(basePass.get());
// 确保分析遍的粒度与请求的上下文匹配
if (analysisPass->getGranularity() == Pass::Granularity::Function) {
analysisPass->runOnFunction(F); // 运行分析遍
// 获取结果并缓存
std::unique_ptr<AnalysisResultBase> result = analysisPass->getResult();
T *specificResult = static_cast<T *>(result.get());
cachedResults[{F, analysisID}] = std::move(result); // 缓存结果
return specificResult;
}
// TODO: 处理 Module 或 BasicBlock 粒度的分析
return nullptr;
}
// 使所有或特定分析结果失效 (当 IR 被修改时调用)
void invalidateAllAnalyses() { cachedResults.clear(); }
// 使特定分析结果失效
void invalidateAnalysis(void *analysisID, Function *F = nullptr) {
if (F) {
// 使特定函数的特定分析结果失效
cachedResults.erase({F, analysisID});
} else {
// 使所有函数的特定分析结果失效
std::map<std::pair<Function *, void *>, std::unique_ptr<AnalysisResultBase>> newCachedResults;
for (auto &pair : cachedResults) {
if (pair.first.second != analysisID) {
newCachedResults.insert(std::move(pair));
}
}
cachedResults = std::move(newCachedResults);
}
}
private:
std::map<std::pair<Function *, void *>, std::unique_ptr<AnalysisResultBase>> cachedResults;
};
// ======================================================================
// PassManager遍管理器
// ======================================================================
class PassManager {
Module *pmodule;
AnalysisManager &AM; // 引用 AnalysisManager用于获取分析结果
public:
PassManager() = default;
~PassManager() = default;
// 添加遍:现在接受 Pass 的 ID而不是直接的 unique_ptr
void addPass(void *passID) {
PassRegistry &registry = PassRegistry::getPassRegistry();
std::unique_ptr<Pass> P = registry.createPass(passID);
if (!P) {
// Error: Pass not found or failed to create
return;
}
passes.push_back(std::move(P));
}
// 运行所有注册的遍
bool run(Module *M) {
bool changed = false;
for (const auto &p : passes) {
bool passChanged = false; // 记录当前遍是否修改了 IR
// 处理优化遍的分析依赖和失效
if (p->getPassKind() == Pass::PassKind::Optimization) {
OptimizationPass *optPass = static_cast<OptimizationPass *>(p.get());
std::set<void *> analysisDependencies;
std::set<void *> analysisInvalidations;
optPass->getAnalysisUsage(analysisDependencies, analysisInvalidations);
// PassManager 不显式运行分析依赖。
// 而是优化遍在 runOnFunction 内部通过 AnalysisManager.getAnalysisResult 按需请求。
}
if (p->getGranularity() == Pass::Granularity::Module) {
passChanged = p->runOnModule(M, AM);
} else if (p->getGranularity() == Pass::Granularity::Function) {
for (auto &funcPair : M->getFunctions()) {
Function *F = funcPair.second.get();
passChanged = p->runOnFunction(F, AM) || passChanged;
if (passChanged && p->getPassKind() == Pass::PassKind::Optimization) {
OptimizationPass *optPass = static_cast<OptimizationPass *>(p.get());
std::set<void *> analysisDependencies;
std::set<void *> analysisInvalidations;
optPass->getAnalysisUsage(analysisDependencies, analysisInvalidations);
for (void *invalidationID : analysisInvalidations) {
analysisManager.invalidateAnalysis(invalidationID, F);
}
}
}
} else if (p->getGranularity() == Pass::Granularity::BasicBlock) {
for (auto &funcPair : M->getFunctions()) {
Function *F = funcPair.second.get();
for (auto &bbPtr : funcPair.second->getBasicBlocks()) {
passChanged = p->runOnBasicBlock(bbPtr.get(), AM) || passChanged;
if (passChanged && p->getPassKind() == Pass::PassKind::Optimization) {
OptimizationPass *optPass = static_cast<OptimizationPass *>(p.get());
std::set<void *> analysisDependencies;
std::set<void *> analysisInvalidations;
optPass->getAnalysisUsage(analysisDependencies, analysisInvalidations);
for (void *invalidationID : analysisInvalidations) {
analysisManager.invalidateAnalysis(invalidationID, F);
}
}
}
}
}
changed = changed || passChanged;
}
return changed;
}
AnalysisManager &getAnalysisManager() { return analysisManager; }
private:
std::vector<std::unique_ptr<Pass>> passes;
AnalysisManager analysisManager;
};
// ======================================================================
// 辅助宏或函数,用于简化 Pass 的注册
// ======================================================================
// 用于分析遍的注册
template <typename AnalysisPassType> void registerAnalysisPass() {
PassRegistry::getPassRegistry().registerPass(&AnalysisPassType::ID,
[]() { return std::make_unique<AnalysisPassType>(); });
}
// 用于优化遍的注册
template <typename OptimizationPassType> void registerOptimizationPass() {
PassRegistry::getPassRegistry().registerPass(&OptimizationPassType::ID,
[]() { return std::make_unique<OptimizationPassType>(); });
}
} // namespace sysy

View File

@ -11,11 +11,14 @@ class SysYIROptUtils{
public:
// 删除use关系
// 根据指令的使用情况删除其所有的use关系
// 找到指令的所有使用者,并从它们的使用列表中删除该指令
static void usedelete(Instruction *instr) {
for (auto &use : instr->getOperands()) {
Value* val = use->getValue();
val->removeUse(use);
}
instr->getParent()->removeInst(instr); // 从基本块中删除指令
}
// 判断是否是全局变量