[midend]重构了src目录

This commit is contained in:
Lixuanwang
2025-07-29 21:30:30 +08:00
parent f5922d0178
commit 09ae47924e
84 changed files with 85 additions and 1715 deletions

1554
src/include/midend/IR.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,404 @@
#pragma once
#include <cassert>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include "IR.h"
/**
* @file IRBuilder.h
*
* @brief 定义IR构建器的头文件
*/
namespace sysy {
/**
* @brief 中间IR的构建器
*
*/
class IRBuilder {
private:
unsigned labelIndex; ///< 基本块标签编号
unsigned tmpIndex; ///< 临时变量编号
BasicBlock *block; ///< 当前基本块
BasicBlock::iterator position; ///< 当前基本块指令列表位置的迭代器
std::vector<BasicBlock *> trueBlocks; ///< true分支基本块列表
std::vector<BasicBlock *> falseBlocks; ///< false分支基本块列表
std::vector<BasicBlock *> breakBlocks; ///< break目标块列表
std::vector<BasicBlock *> continueBlocks; ///< continue目标块列表
public:
IRBuilder() : labelIndex(0), tmpIndex(0), block(nullptr) {}
explicit IRBuilder(BasicBlock *block) : labelIndex(0), tmpIndex(0), block(block), position(block->end()) {}
IRBuilder(BasicBlock *block, BasicBlock::iterator position)
: labelIndex(0), tmpIndex(0), block(block), position(position) {}
public:
unsigned getLabelIndex() {
labelIndex += 1;
return labelIndex - 1;
} ///< 获取基本块标签编号
unsigned getTmpIndex() {
tmpIndex += 1;
return tmpIndex - 1;
} ///< 获取临时变量编号
BasicBlock * getBasicBlock() const { return block; } ///< 获取当前基本块
BasicBlock * getBreakBlock() const { return breakBlocks.back(); } ///< 获取break目标块
BasicBlock * popBreakBlock() {
auto result = breakBlocks.back();
breakBlocks.pop_back();
return result;
} ///< 弹出break目标块
BasicBlock * getContinueBlock() const { return continueBlocks.back(); } ///< 获取continue目标块
BasicBlock * popContinueBlock() {
auto result = continueBlocks.back();
continueBlocks.pop_back();
return result;
} ///< 弹出continue目标块
BasicBlock * getTrueBlock() const { return trueBlocks.back(); } ///< 获取true分支基本块
BasicBlock * getFalseBlock() const { return falseBlocks.back(); } ///< 获取false分支基本块
BasicBlock * popTrueBlock() {
auto result = trueBlocks.back();
trueBlocks.pop_back();
return result;
} ///< 弹出true分支基本块
BasicBlock * popFalseBlock() {
auto result = falseBlocks.back();
falseBlocks.pop_back();
return result;
} ///< 弹出false分支基本块
BasicBlock::iterator getPosition() const { return position; } ///< 获取当前基本块指令列表位置的迭代器
void setPosition(BasicBlock *block, BasicBlock::iterator position) {
this->block = block;
this->position = position;
} ///< 设置基本块和基本块指令列表位置的迭代器
void setPosition(BasicBlock::iterator position) {
this->position = position;
} ///< 设置当前基本块指令列表位置的迭代器
void pushBreakBlock(BasicBlock *block) { breakBlocks.push_back(block); } ///< 压入break目标基本块
void pushContinueBlock(BasicBlock *block) { continueBlocks.push_back(block); } ///< 压入continue目标基本块
void pushTrueBlock(BasicBlock *block) { trueBlocks.push_back(block); } ///< 压入true分支基本块
void pushFalseBlock(BasicBlock *block) { falseBlocks.push_back(block); } ///< 压入false分支基本块
public:
Instruction * insertInst(Instruction *inst) {
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 插入指令
UnaryInst * createUnaryInst(Instruction::Kind kind, Type *type, Value *operand, const std::string &name = "") {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new UnaryInst(kind, type, operand, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建一元指令
UnaryInst * createNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNeg, Type::getIntType(), operand, name);
} ///< 创建取反指令
UnaryInst * createNotInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kNot, Type::getIntType(), operand, name);
} ///< 创建取非指令
UnaryInst * createFtoIInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFtoI, Type::getIntType(), operand, name);
} ///< 创建浮点转整型指令
UnaryInst * createBitFtoIInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kBitFtoI, Type::getIntType(), operand, name);
} ///< 创建按位浮点转整型指令
UnaryInst * createFNegInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNeg, Type::getFloatType(), operand, name);
} ///< 创建浮点取反指令
UnaryInst * createFNotInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kFNot, Type::getIntType(), operand, name);
} ///< 创建浮点取非指令
UnaryInst * createIToFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kItoF, Type::getFloatType(), operand, name);
} ///< 创建整型转浮点指令
UnaryInst * createBitItoFInst(Value *operand, const std::string &name = "") {
return createUnaryInst(Instruction::kBitItoF, Type::getFloatType(), operand, name);
} ///< 创建按位整型转浮点指令
BinaryInst * createBinaryInst(Instruction::Kind kind, Type *type, Value *lhs, Value *rhs, const std::string &name = "") {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new BinaryInst(kind, type, lhs, rhs, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建二元指令
BinaryInst * createAddInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kAdd, Type::getIntType(), lhs, rhs, name);
} ///< 创建加法指令
BinaryInst * createSubInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kSub, Type::getIntType(), lhs, rhs, name);
} ///< 创建减法指令
BinaryInst * createMulInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kMul, Type::getIntType(), lhs, rhs, name);
} ///< 创建乘法指令
BinaryInst * createDivInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kDiv, Type::getIntType(), lhs, rhs, name);
} ///< 创建除法指令
BinaryInst * createRemInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kRem, Type::getIntType(), lhs, rhs, name);
} ///< 创建取余指令
BinaryInst * createICmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpEQ, Type::getIntType(), lhs, rhs, name);
} ///< 创建相等设置指令
BinaryInst * createICmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpNE, Type::getIntType(), lhs, rhs, name);
} ///< 创建不相等设置指令
BinaryInst * createICmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLT, Type::getIntType(), lhs, rhs, name);
} ///< 创建小于设置指令
BinaryInst * createICmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpLE, Type::getIntType(), lhs, rhs, name);
} ///< 创建小于等于设置指令
BinaryInst * createICmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGT, Type::getIntType(), lhs, rhs, name);
} ///< 创建大于设置指令
BinaryInst * createICmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kICmpGE, Type::getIntType(), lhs, rhs, name);
} ///< 创建大于等于设置指令
BinaryInst * createFAddInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFAdd, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点加法指令
BinaryInst * createFSubInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFSub, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点减法指令
BinaryInst * createFMulInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFMul, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点乘法指令
BinaryInst * createFDivInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFDiv, Type::getFloatType(), lhs, rhs, name);
} ///< 创建浮点除法指令
BinaryInst * createFCmpEQInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpEQ, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点相等设置指令
BinaryInst * createFCmpNEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpNE, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点不相等设置指令
BinaryInst * createFCmpLTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLT, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点小于设置指令
BinaryInst * createFCmpLEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpLE, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点小于等于设置指令
BinaryInst * createFCmpGTInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGT, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点大于设置指令
BinaryInst * createFCmpGEInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kFCmpGE, Type::getIntType(), lhs, rhs, name);
} ///< 创建浮点相大于等于设置指令
BinaryInst * createAndInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kAnd, Type::getIntType(), lhs, rhs, name);
} ///< 创建按位且指令
BinaryInst * createOrInst(Value *lhs, Value *rhs, const std::string &name = "") {
return createBinaryInst(Instruction::kOr, Type::getIntType(), lhs, rhs, name);
} ///< 创建按位或指令
CallInst * createCallInst(Function *callee, const std::vector<Value *> &args, const std::string &name = "") {
std::string newName;
if (name.empty() && callee->getReturnType() != Type::getVoidType()) {
std::stringstream ss;
ss << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new CallInst(callee, args, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建Call指令
ReturnInst * createReturnInst(Value *value = nullptr, const std::string &name = "") {
auto inst = new ReturnInst(value, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建return指令
UncondBrInst * createUncondBrInst(BasicBlock *thenBlock, const std::vector<Value *> &args) {
auto inst = new UncondBrInst(thenBlock, args, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建无条件指令
CondBrInst * createCondBrInst(Value *condition, BasicBlock *thenBlock, BasicBlock *elseBlock,
const std::vector<Value *> &thenArgs, const std::vector<Value *> &elseArgs) {
auto inst = new CondBrInst(condition, thenBlock, elseBlock, thenArgs, elseArgs, block);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建条件跳转指令
AllocaInst * createAllocaInst(Type *type, const std::vector<Value *> &dims = {}, const std::string &name = "") {
auto inst = new AllocaInst(type, dims, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建分配指令
AllocaInst * createAllocaInstWithoutInsert(Type *type, const std::vector<Value *> &dims = {}, BasicBlock *parent = nullptr,
const std::string &name = "") {
auto inst = new AllocaInst(type, dims, parent, name);
assert(inst);
return inst;
} ///< 创建不插入指令列表的分配指令[仅用于phi指令]
LoadInst * createLoadInst(Value *pointer, const std::vector<Value *> &indices = {}, const std::string &name = "") {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new LoadInst(pointer, indices, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建load指令
MemsetInst * createMemsetInst(Value *pointer, Value *begin, Value *size, Value *value, const std::string &name = "") {
auto inst = new MemsetInst(pointer, begin, size, value, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建memset指令
StoreInst * createStoreInst(Value *value, Value *pointer, const std::vector<Value *> &indices = {},
const std::string &name = "") {
auto inst = new StoreInst(value, pointer, indices, block, name);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
} ///< 创建store指令
PhiInst * createPhiInst(Type *type, const std::vector<Value*> &vals = {}, const std::vector<BasicBlock*> &blks = {}, const std::string &name = "") {
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new PhiInst(type, vals, blks, block, newName);
assert(inst);
block->getInstructions().emplace(block->begin(), inst);
return inst;
} ///< 创建Phi指令
// GetElementPtrInst* createGetElementPtrInst(Value *basePointer,
// const std::vector<Value *> &indices = {},
// const std::string &name = "") {
// std::string newName;
// if (name.empty()) {
// std::stringstream ss;
// ss << tmpIndex;
// newName = ss.str();
// tmpIndex++;
// } else {
// newName = name;
// }
// auto inst = new GetElementPtrInst(basePointer, indices, block, newName);
// assert(inst);
// block->getInstructions().emplace(position, inst);
// return inst;
// }
/**
* @brief 根据 LLVM 设计模式创建 GEP 指令。
* 它会自动推断返回类型,无需手动指定。
*/
GetElementPtrInst *createGetElementPtrInst(Value *basePointer, const std::vector<Value *> &indices,
const std::string &name = "") {
Type *ResultElementType = getIndexedType(basePointer->getType(), indices);
if (!ResultElementType) {
assert(false && "Invalid GEP indexing!");
return nullptr;
}
Type *ResultType = PointerType::get(ResultElementType);
std::string newName;
if (name.empty()) {
std::stringstream ss;
ss << tmpIndex;
newName = ss.str();
tmpIndex++;
} else {
newName = name;
}
auto inst = new GetElementPtrInst(ResultType, basePointer, indices, block, newName);
assert(inst);
block->getInstructions().emplace(position, inst);
return inst;
}
static Type *getIndexedType(Type *pointerType, const std::vector<Value *> &indices) {
assert(pointerType->isPointer() && "base must be a pointer type!");
// GEP 的类型推断从基指针所指向的类型开始。
// 例如:
// - 如果 pointerType 是 `[20 x [10 x i32]]*``currentWalkType` 初始为 `[20 x [10 x i32]]`。
// - 如果 pointerType 是 `i32*``currentWalkType` 初始为 `i32`。
// - 如果 pointerType 是 `i32**``currentWalkType` 初始为 `i32*`。
Type *currentWalkType = pointerType->as<PointerType>()->getBaseType();
// 遍历所有索引来深入类型层次结构。
// `indices` 向量包含了所有 GEP 索引,包括由 `visitLValue` 等函数添加的初始 `0` 索引。
for (int i = 0; i < indices.size(); ++i) {
if (currentWalkType->isArray()) {
// 情况一:当前遍历类型是 `ArrayType`。
// 索引用于选择数组元素,`currentWalkType` 更新为数组的元素类型。
currentWalkType = currentWalkType->as<ArrayType>()->getElementType();
} else if (currentWalkType->isPointer()) {
// 情况二:当前遍历类型是 `PointerType`。
// 这意味着我们正在通过一个指针来访问其指向的内存。
// 索引用于选择该指针所指向的“数组”的元素。
// `currentWalkType` 更新为该指针所指向的基础类型。
// 例如:如果 `currentWalkType` 是 `i32*`,它将变为 `i32`。
// 如果 `currentWalkType` 是 `[10 x i32]*`,它将变为 `[10 x i32]`。
currentWalkType = currentWalkType->as<PointerType>()->getBaseType();
} else {
// 情况三:当前遍历类型是标量类型 (例如 `i32`, `float` 等非聚合、非指针类型)。
//
// 如果 `currentWalkType` 是标量,并且当前索引 `i` **不是** `indices` 向量中的最后一个索引,
// 这意味着尝试对一个标量类型进行进一步的结构性索引,这是**无效的**。
// 例如:`int x; x[0];` 对应的 GEP 链中,`x` 的类型是 `i32`,再加 `[0]` 索引就是错误。
//
// 如果 `currentWalkType` 是标量,且这是**最后一个索引** (`i == indices.size() - 1`)
// 那么 GEP 是合法的,它只是计算一个偏移地址,最终的类型就是这个标量类型。
// 此时 `currentWalkType` 保持不变,循环结束。
if (i < indices.size() - 1) {
assert(false && "Invalid GEP indexing: attempting to index into a non-aggregate/non-pointer type with further indices.");
return nullptr; // 返回空指针表示类型推断失败
}
// 如果是最后一个索引,且当前类型是标量,则类型保持不变,这是合法的。
// 循环会自然结束,返回正确的 `currentWalkType`。
}
}
// 所有索引处理完毕后,`currentWalkType` 就是 GEP 指令最终计算出的地址所指向的元素的类型。
return currentWalkType;
}
};
} // namespace sysy

View File

@@ -0,0 +1,55 @@
#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::set<BasicBlock*>* getDominatorTreeChildren(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);
void computeDominatorTreeChildren(Function* F);
private:
Function* AssociatedFunction;
std::map<BasicBlock*, std::set<BasicBlock*>> Dominators;
std::map<BasicBlock*, BasicBlock*> IDoms;
std::map<BasicBlock*, std::set<BasicBlock*>> DominanceFrontiers;
std::map<BasicBlock*, std::set<BasicBlock*>> DominatorTreeChildren;
};
// 支配树分析遍
class DominatorTreeAnalysisPass : public AnalysisPass {
public:
// 唯一的 Pass ID
static void *ID;
DominatorTreeAnalysisPass() : AnalysisPass("DominatorTreeAnalysis", Pass::Granularity::Function) {}
// 实现 getPassID
void* getPassID() const override { return &ID; }
bool runOnFunction(Function* F, AnalysisManager &AM) override;
std::unique_ptr<AnalysisResultBase> getResult() override;
private:
std::unique_ptr<DominatorTree> CurrentDominatorTree;
};
} // namespace sysy

View File

@@ -0,0 +1,72 @@
#pragma once
#include "IR.h" // 包含 IR 定义
#include "Pass.h" // 包含 Pass 框架
#include <algorithm> // for std::set_union, std::set_difference
#include <map>
#include <set>
#include <vector>
namespace sysy {
// 前向声明
class Function;
class BasicBlock;
class Value;
class Instruction;
// 活跃变量分析结果类
// 它将包含 LiveIn 和 LiveOut 集合
class LivenessAnalysisResult : public AnalysisResultBase {
public:
LivenessAnalysisResult(Function *F) : AssociatedFunction(F) {}
// 获取给定基本块的 LiveIn 集合
const std::set<Value *> *getLiveIn(BasicBlock *BB) const;
// 获取给定基本块的 LiveOut 集合
const std::set<Value *> *getLiveOut(BasicBlock *BB) const;
// 暴露内部数据结构,如果需要更直接的访问
const std::map<BasicBlock *, std::set<Value *>> &getLiveInSets() const { return liveInSets; }
const std::map<BasicBlock *, std::set<Value *>> &getLiveOutSets() const { return liveOutSets; }
// 核心计算方法,由 LivenessAnalysisPass 调用
void computeLiveness(Function *F);
private:
Function *AssociatedFunction; // 这个活跃变量分析是为哪个函数计算的
std::map<BasicBlock *, std::set<Value *>> liveInSets;
std::map<BasicBlock *, std::set<Value *>> liveOutSets;
// 辅助函数:计算基本块的 Def 和 Use 集合
// Def: 块内定义,且定义在所有使用之前的值
// Use: 块内使用,且使用在所有定义之前的值
void computeDefUse(BasicBlock *BB, std::set<Value *> &def, std::set<Value *> &use);
};
// 活跃变量分析遍
class LivenessAnalysisPass : public AnalysisPass {
public:
// 唯一的 Pass ID
static void *ID; // LLVM 风格的唯一 ID
LivenessAnalysisPass() : AnalysisPass("LivenessAnalysis", Pass::Granularity::Function) {}
// 实现 getPassID
void *getPassID() const override { return &ID; }
// 运行分析并返回结果。现在接受 AnalysisManager& AM 参数
bool runOnFunction(Function *F, AnalysisManager &AM) override;
// 获取分析结果的指针。
// 注意AnalysisManager 将会调用此方法来获取结果并进行缓存。
std::unique_ptr<AnalysisResultBase> getResult() override;
private:
// 存储当前分析计算出的 LivenessAnalysisResult 实例
// runOnFunction 每次调用都会创建新的 LivenessAnalysisResult 对象
std::unique_ptr<LivenessAnalysisResult> CurrentLivenessResult;
};
} // namespace sysy

View File

@@ -0,0 +1,63 @@
#pragma once
#include "Pass.h"
#include "IR.h"
#include "SysYIROptUtils.h"
#include "Dom.h"
#include <unordered_set>
#include <queue>
namespace sysy {
// 前向声明分析结果类,确保在需要时可以引用
// class DominatorTreeAnalysisResult; // Pass.h 中已包含,这里不再需要
class SideEffectInfoAnalysisResult; // 假设有副作用分析结果类
// DCEContext 类用于封装DCE的内部逻辑和状态
// 这样可以避免静态变量在多线程或多次运行时的冲突,并保持代码的模块化
class DCEContext {
public:
// 运行DCE的主要方法
// func: 当前要优化的函数
// tp: 分析管理器,用于获取其他分析结果(如果需要)
void run(Function* func, AnalysisManager* AM, bool &changed);
private:
// 存储活跃指令的集合
std::unordered_set<Instruction*> alive_insts;
// 判断指令是否是“天然活跃”的(即总是保留的)
// inst: 要检查的指令
// 返回值: 如果指令是天然活跃的则为true否则为false
bool isAlive(Instruction* inst);
// 递归地将活跃指令及其依赖加入到 alive_insts 集合中
// inst: 要标记为活跃的指令
void addAlive(Instruction* inst);
};
// DCE 优化遍类,继承自 OptimizationPass
class DCE : public OptimizationPass {
public:
// 构造函数
DCE() : OptimizationPass("DCE", Granularity::Function) {}
// 静态成员作为该遍的唯一ID
static void *ID;
// 运行在函数上的优化逻辑
// F: 当前要优化的函数
// AM: 分析管理器,用于获取或使分析结果失效
// 返回值: 如果IR被修改则为true否则为false
bool runOnFunction(Function *F, AnalysisManager& AM) override;
// 声明该遍的分析依赖和失效信息
// analysisDependencies: 该遍运行前需要哪些分析结果
// analysisInvalidations: 该遍运行后会使哪些分析结果失效
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override;
// Pass 基类中的纯虚函数,必须实现
void *getPassID() const override { return &ID; }
};
} // namespace sysy

View File

@@ -0,0 +1,118 @@
#pragma once
#include "Pass.h" // 包含Pass的基类定义
#include "IR.h" // 包含IR相关的定义如Instruction, Function, BasicBlock, AllocaInst, LoadInst, StoreInst, PhiInst等
#include "Dom.h" // 假设支配树分析的头文件,提供 DominatorTreeAnalysisResult
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack> // 用于变量重命名阶段的SSA值栈
namespace sysy {
// 前向声明分析结果类,确保在需要时可以引用
class DominatorTree;
// Mem2RegContext 类,封装 mem2reg 遍的核心逻辑和状态
// 这样可以避免静态变量在多线程或多次运行时的冲突,并保持代码的模块化
class Mem2RegContext {
public:
Mem2RegContext(IRBuilder *builder) : builder(builder) {}
// 运行 mem2reg 优化的主要方法
// func: 当前要优化的函数
// tp: 分析管理器,用于获取支配树等分析结果
void run(Function* func, AnalysisManager* tp);
private:
IRBuilder *builder; // IR 构建器,用于插入指令
// 存储所有需要被提升的 AllocaInst
std::vector<AllocaInst*> promotableAllocas;
// 存储每个 AllocaInst 对应的 Phi 指令列表
// 键是 AllocaInst值是该 AllocaInst 在各个基本块中插入的 Phi 指令的列表
// (实际上,一个 AllocaInst 在一个基本块中只会有一个 Phi)
std::unordered_map<AllocaInst*, std::unordered_map<BasicBlock*, PhiInst*>> allocaToPhiMap;
// 存储每个 AllocaInst 对应的当前活跃 SSA 值栈
// 用于在变量重命名阶段追踪每个 AllocaInst 在不同控制流路径上的最新值
std::unordered_map<AllocaInst*, std::stack<Value*>> allocaToValueStackMap;
// 辅助映射,存储每个 AllocaInst 的所有 store 指令
std::unordered_map<AllocaInst*, std::unordered_set<StoreInst*>> allocaToStoresMap;
// 辅助映射,存储每个 AllocaInst 对应的定义基本块(包含 store 指令的块)
std::unordered_map<AllocaInst*, std::unordered_set<BasicBlock*>> allocaToDefBlocksMap;
// 支配树分析结果,用于 Phi 插入和变量重命名
DominatorTree* dt;
// --------------------------------------------------------------------
// 阶段1: 识别可提升的 AllocaInst
// --------------------------------------------------------------------
// 判断一个 AllocaInst 是否可以被提升到寄存器
// alloca: 要检查的 AllocaInst
// 返回值: 如果可以提升,则为 true否则为 false
bool isPromotableAlloca(AllocaInst* alloca);
// 收集所有对给定 AllocaInst 进行存储的 StoreInst
// alloca: 目标 AllocaInst
void collectStores(AllocaInst* alloca);
// --------------------------------------------------------------------
// 阶段2: 插入 Phi 指令 (Phi Insertion)
// --------------------------------------------------------------------
// 为给定的 AllocaInst 插入必要的 Phi 指令
// alloca: 目标 AllocaInst
// defBlocks: 包含对该 AllocaInst 进行 store 操作的基本块集合
void insertPhis(AllocaInst* alloca, const std::unordered_set<BasicBlock*>& defBlocks);
// --------------------------------------------------------------------
// 阶段3: 变量重命名 (Variable Renaming)
// --------------------------------------------------------------------
// 对支配树进行深度优先遍历,重命名变量并替换 load/store 指令
// alloca: 当前正在处理的 AllocaInst
// currentBB: 当前正在遍历的基本块
// dt: 支配树分析结果
// valueStack: 存储当前 AllocaInst 在当前路径上可见的 SSA 值栈
void renameVariables(AllocaInst* alloca, BasicBlock* currentBB);
// --------------------------------------------------------------------
// 阶段4: 清理
// --------------------------------------------------------------------
// 删除所有原始的 AllocaInst、LoadInst 和 StoreInst
void cleanup();
};
// Mem2Reg 优化遍类,继承自 OptimizationPass
// 粒度为 Function表示它在每个函数上独立运行
class Mem2Reg : public OptimizationPass {
private:
IRBuilder *builder;
public:
// 构造函数
Mem2Reg(IRBuilder *builder) : OptimizationPass("Mem2Reg", Granularity::Function), builder(builder) {}
// 静态成员作为该遍的唯一ID
static void *ID;
// 运行在函数上的优化逻辑
// F: 当前要优化的函数
// AM: 分析管理器,用于获取支配树等分析结果,或使分析结果失效
// 返回值: 如果IR被修改则为true否则为false
bool runOnFunction(Function *F, AnalysisManager& AM) override;
// 声明该遍的分析依赖和失效信息
// analysisDependencies: 该遍运行前需要哪些分析结果
// analysisInvalidations: 该遍运行后会使哪些分析结果失效
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override;
void *getPassID() const override { return &ID; }
};
} // namespace sysy

View File

@@ -0,0 +1,59 @@
#pragma once
#include "IR.h"
#include "IRBuilder.h" // 你的 IR Builder
#include "Liveness.h"
#include "Dom.h"
#include "Pass.h" // 你的 Pass 框架基类
#include <iostream> // 调试用
#include <map> // 用于 Value 到 AllocaInst 的映射
#include <set> // 可能用于其他辅助集合
#include <string>
#include <vector>
namespace sysy {
class Reg2MemContext {
public:
Reg2MemContext(IRBuilder *b) : builder(b) {}
// 运行 Reg2Mem 优化
void run(Function *func);
private:
IRBuilder *builder; // IR 构建器
// 存储 SSA Value 到对应的 AllocaInst 的映射
// 只有那些需要被"溢出"到内存的 SSA 值才会被记录在这里
std::map<Value *, AllocaInst *> valueToAllocaMap;
// 辅助函数:
// 1. 识别并为 SSA Value 分配 AllocaInst
void allocateMemoryForSSAValues(Function *func);
// 2. 将 SSA 值的使用替换为 Load/Store
void insertLoadsAndStores(Function *func);
// 3. 处理 Phi 指令,将其转换为 Load/Store
void rewritePhis(Function *func);
// 4. 清理 (例如,可能删除不再需要的 Phi 指令)
void cleanup(Function *func);
// 判断一个 Value 是否是 AllocaInst 可以为其分配内存的目标
// 通常指非指针类型的Instruction结果和Argument
bool isPromotableToMemory(Value *val);
};
class Reg2Mem : public OptimizationPass {
private:
IRBuilder *builder; ///< IR构建器用于插入指令
public:
static void *ID; ///< Pass的唯一标识符
Reg2Mem(IRBuilder* builder) : OptimizationPass("Reg2Mem", Pass::Granularity::Function), builder(builder) {}
bool runOnFunction(Function *F, AnalysisManager &AM) override;
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override;
void *getPassID() const override { return &ID; } ///< 获取 Pass ID
};
} // namespace sysy

View File

@@ -0,0 +1,196 @@
#pragma once
#include "IR.h"
namespace sysy {
// 稀疏条件常量传播类
// Sparse Conditional Constant Propagation
/*
伪代码
function SCCP_Optimization(Module):
for each Function in Module:
changed = true
while changed:
changed = false
// 阶段1: 常量传播与折叠
changed |= PropagateConstants(Function)
// 阶段2: 控制流简化
changed |= SimplifyControlFlow(Function)
end while
end for
function PropagateConstants(Function):
// 初始化
executableBlocks = {entryBlock}
valueState = map<Value, State> // 值->状态映射
instWorkList = Queue()
edgeWorkList = Queue()
// 初始化工作列表
for each inst in entryBlock:
instWorkList.push(inst)
// 迭代处理
while !instWorkList.empty() || !edgeWorkList.empty():
// 处理指令工作列表
while !instWorkList.empty():
inst = instWorkList.pop()
// 如果指令是可执行基本块中的
if executableBlocks.contains(inst.parent):
ProcessInstruction(inst)
// 处理边工作列表
while !edgeWorkList.empty():
edge = edgeWorkList.pop()
ProcessEdge(edge)
// 应用常量替换
for each inst in Function:
if valueState[inst] == CONSTANT:
ReplaceWithConstant(inst, valueState[inst].constant)
changed = true
return changed
function ProcessInstruction(Instruction inst):
switch inst.type:
//二元操作
case BINARY_OP:
lhs = GetValueState(inst.operands[0])
rhs = GetValueState(inst.operands[1])
if lhs == CONSTANT && rhs == CONSTANT:
newState = ComputeConstant(inst.op, lhs.value, rhs.value)
UpdateState(inst, newState)
else if lhs == BOTTOM || rhs == BOTTOM:
UpdateState(inst, BOTTOM)
//phi
case PHI:
mergedState =
for each incoming in inst.incomings:
// 检查每个输入的状态
if executableBlocks.contains(incoming.block):
incomingState = GetValueState(incoming.value)
mergedState = Meet(mergedState, incomingState)
UpdateState(inst, mergedState)
// 条件分支
case COND_BRANCH:
cond = GetValueState(inst.condition)
if cond == CONSTANT:
// 判断条件分支
if cond.value == true:
AddEdgeToWorkList(inst.parent, inst.trueTarget)
else:
AddEdgeToWorkList(inst.parent, inst.falseTarget)
else if cond == BOTTOM:
AddEdgeToWorkList(inst.parent, inst.trueTarget)
AddEdgeToWorkList(inst.parent, inst.falseTarget)
case UNCOND_BRANCH:
AddEdgeToWorkList(inst.parent, inst.target)
// 其他指令处理...
function ProcessEdge(Edge edge):
fromBB, toBB = edge
if !executableBlocks.contains(toBB):
executableBlocks.add(toBB)
for each inst in toBB:
if inst is PHI:
instWorkList.push(inst)
else:
instWorkList.push(inst) // 非PHI指令
// 更新PHI节点的输入
for each phi in toBB.phis:
instWorkList.push(phi)
function SimplifyControlFlow(Function):
changed = false
// 标记可达基本块
ReachableBBs = FindReachableBlocks(Function.entry)
// 删除不可达块
for each bb in Function.blocks:
if !ReachableBBs.contains(bb):
RemoveDeadBlock(bb)
changed = true
// 简化条件分支
for each bb in Function.blocks:
terminator = bb.terminator
if terminator is COND_BRANCH:
cond = GetValueState(terminator.condition)
if cond == CONSTANT:
SimplifyBranch(terminator, cond.value)
changed = true
return changed
function RemoveDeadBlock(BasicBlock bb):
// 1. 更新前驱块的分支指令
for each pred in bb.predecessors:
UpdateTerminator(pred, bb)
// 2. 更新后继块的PHI节点
for each succ in bb.successors:
RemovePhiIncoming(succ, bb)
// 3. 删除块内所有指令
for each inst in bb.instructions:
inst.remove()
// 4. 从函数中移除基本块
Function.removeBlock(bb)
function Meet(State a, State b):
if a == : return b
if b == : return a
if a == ⊥ || b == ⊥: return ⊥
if a.value == b.value: return a
return ⊥
function UpdateState(Value v, State newState):
oldState = valueState.get(v, )
if newState != oldState:
valueState[v] = newState
for each user in v.users:
if user is Instruction:
instWorkList.push(user)
*/
enum class LatticeValue {
Top, // (Unknown)
Constant, // c (Constant)
Bottom // ⊥ (Undefined / Varying)
};
// LatticeValue: 用于表示值的状态Top表示未知Constant表示常量Bottom表示未定义或变化的值。
// 这里的LatticeValue用于跟踪每个SSA值变量、指令结果的状态
// 以便在SCCP过程中进行常量传播和控制流简化。
//TODO: 下列数据结构考虑集成到类中,避免重命名问题
static std::set<Instruction *> Worklist;
static std::unordered_set<BasicBlock*> Executable_Blocks;
static std::queue<std::pair<BasicBlock *, BasicBlock *> > Executable_Edges;
static std::map<Value*, LatticeValue> valueState;
class SCCP {
private:
Module *pModule;
public:
SCCP(Module *pMoudle) : pModule(pMoudle) {}
void run();
bool PropagateConstants(Function *function);
bool SimplifyControlFlow(Function *function);
void ProcessInstruction(Instruction *inst);
void ProcessEdge(const std::pair<BasicBlock *, BasicBlock *> &edge);
void RemoveDeadBlock(BasicBlock *bb);
void UpdateState(Value *v, LatticeValue newState);
LatticeValue Meet(LatticeValue a, LatticeValue b);
LatticeValue GetValueState(Value *v);
};
} // namespace sysy

View File

@@ -0,0 +1,101 @@
#pragma once
#include "IR.h"
#include "IRBuilder.h"
#include "Pass.h"
namespace sysy {
// 优化前对SysY IR的预处理也可以视作部分CFG优化
// 主要包括删除无用指令、合并基本块、删除空块等
// 这些操作可以在SysY IR生成时就完成但为了简化IR生成过程
// 这里将其放在SysY IR生成后进行预处理
// 同时兼容phi节点的处理可以再mem2reg后再次调用优化
//TODO: 可增加的CFG优化和方法
// - 检查基本块跳转关系正确性
// - 简化条件分支Branch Simplification如条件恒真/恒假转为直接跳转
// - 合并连续的跳转指令Jump Threading在合并不可达块中似乎已经实现了
// - 基本块重排序Block Reordering提升局部性
// 辅助工具类包含实际的CFG优化逻辑
// 这些方法可以被独立的Pass调用
class SysYCFGOptUtils {
public:
static bool SysYDelInstAfterBr(Function *func); // 删除br后面的指令
static bool SysYDelEmptyBlock(Function *func, IRBuilder* pBuilder); // 空块删除
static bool SysYDelNoPreBLock(Function *func); // 删除无前驱块(不可达块)
static bool SysYBlockMerge(Function *func); // 合并基本块
static bool SysYAddReturn(Function *func, IRBuilder* pBuilder); // 添加return指令
static bool SysYCondBr2Br(Function *func, IRBuilder* pBuilder); // 条件分支转换为无条件分支
};
// ======================================================================
// 独立的CFG优化遍
// ======================================================================
class SysYDelInstAfterBrPass : public OptimizationPass {
public:
static void *ID; // 唯一ID
SysYDelInstAfterBrPass() : OptimizationPass("SysYDelInstAfterBrPass", Granularity::Function) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override {
// 这个优化可能改变CFG结构使一些CFG相关的分析失效
// 可以在这里指定哪些分析会失效,例如支配树、活跃变量等
// analysisInvalidations.insert(DominatorTreeAnalysisPass::ID); // 示例
}
void *getPassID() const override { return &ID; }
};
class SysYDelEmptyBlockPass : public OptimizationPass {
private:
IRBuilder *pBuilder;
public:
static void *ID;
SysYDelEmptyBlockPass(IRBuilder *builder) : OptimizationPass("SysYDelEmptyBlockPass", Granularity::Function), pBuilder(builder) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override {};
void *getPassID() const override { return &ID; }
};
class SysYDelNoPreBLockPass : public OptimizationPass {
public:
static void *ID;
SysYDelNoPreBLockPass() : OptimizationPass("SysYDelNoPreBLockPass", Granularity::Function) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override {};
void *getPassID() const override { return &ID; }
};
class SysYBlockMergePass : public OptimizationPass {
public:
static void *ID;
SysYBlockMergePass() : OptimizationPass("SysYBlockMergePass", Granularity::Function) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override {};
void *getPassID() const override { return &ID; }
};
class SysYAddReturnPass : public OptimizationPass {
private:
IRBuilder *pBuilder;
public:
static void *ID;
SysYAddReturnPass(IRBuilder *builder) : OptimizationPass("SysYAddReturnPass", Granularity::Function), pBuilder(builder) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override {};
void *getPassID() const override { return &ID; }
};
class SysYCondBr2BrPass : public OptimizationPass {
private:
IRBuilder *pBuilder;
public:
static void *ID;
SysYCondBr2BrPass(IRBuilder *builder) : OptimizationPass("SysYCondBr2BrPass", Granularity::Function), pBuilder(builder) {}
bool runOnFunction(Function *F, AnalysisManager& AM) override;
void getAnalysisUsage(std::set<void *> &analysisDependencies, std::set<void *> &analysisInvalidations) const override {};
void *getPassID() const override { return &ID; }
};
} // namespace sysy

View File

@@ -0,0 +1,33 @@
#pragma once
#include "IR.h"
namespace sysy {
// 优化工具类,包含一些通用的优化方法
// 这些方法可以在不同的优化 pass 中复用
// 例如删除use关系,判断是否是全局变量等
class SysYIROptUtils{
public:
// 仅仅删除use关系
static void usedelete(Instruction *instr) {
for (auto &use : instr->getOperands()) {
Value* val = use->getValue();
val->removeUse(use);
}
}
// 判断是否是全局变量
static bool isGlobal(Value *val) {
auto gval = dynamic_cast<GlobalValue *>(val);
return gval != nullptr;
}
// 判断是否是数组
static bool isArr(Value *val) {
auto aval = dynamic_cast<AllocaInst *>(val);
return aval != nullptr && aval->getNumDims() != 0;
}
};
}// namespace sysy

View File

@@ -0,0 +1,324 @@
#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>
#include <type_traits>
#include "IR.h"
#include "IRBuilder.h"
extern int DEBUG; // 全局调试标志
namespace sysy {
//前向声明
class PassManager;
class AnalysisManager;
// 抽象基类:分析结果
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 {
private:
Module *pModuleRef; // 指向被分析的Module
// 缓存不同粒度的分析结果
std::map<void *, std::unique_ptr<AnalysisResultBase>> moduleCachedResults;
std::map<std::pair<Function *, void *>, std::unique_ptr<AnalysisResultBase>> functionCachedResults;
std::map<std::pair<BasicBlock *, void *>, std::unique_ptr<AnalysisResultBase>> basicBlockCachedResults;
public:
// 构造函数接收 Module 指针
AnalysisManager(Module *M) : pModuleRef(M) {}
AnalysisManager() = delete; // 禁止无参构造
~AnalysisManager() = default;
// 获取分析结果的通用模板函数
// T 是 AnalysisResult 的具体类型E 是 AnalysisPass 的具体类型
// F 和 BB 参数用于提供上下文,根据分析遍的粒度来使用
template <typename T, typename E> T *getAnalysisResult(Function *F = nullptr, BasicBlock *BB = nullptr) {
void *analysisID = E::ID; // 获取分析遍的唯一 ID
// 尝试从注册表创建分析遍实例
std::unique_ptr<Pass> basePass = PassRegistry::getPassRegistry().createPass(analysisID);
if (!basePass) {
// Error: Analysis pass not registered
std::cerr << "Error: Analysis pass with ID " << analysisID << " not registered.\n";
return nullptr;
}
AnalysisPass *analysisPass = static_cast<AnalysisPass *>(basePass.get());
if(DEBUG){
std::cout << "Running Analysis Pass: " << analysisPass->getName() << "\n";
}
// 根据分析遍的粒度处理
switch (analysisPass->getGranularity()) {
case Pass::Granularity::Module: {
// 检查是否已存在有效结果
auto it = moduleCachedResults.find(analysisID);
if (it != moduleCachedResults.end()) {
return static_cast<T *>(it->second.get()); // 返回缓存结果
}
// 运行模块级分析遍
if (!pModuleRef) {
std::cerr << "Error: Module reference not set for AnalysisManager to run Module Pass.\n";
return nullptr;
}
analysisPass->runOnModule(pModuleRef, *this);
// 获取结果并缓存
std::unique_ptr<AnalysisResultBase> result = analysisPass->getResult();
T *specificResult = static_cast<T *>(result.get());
moduleCachedResults[analysisID] = std::move(result); // 缓存结果
return specificResult;
}
case Pass::Granularity::Function: {
// 检查请求的上下文是否正确
if (!F) {
std::cerr << "Error: Function context required for Function-level Analysis Pass.\n";
return nullptr;
}
// 检查是否已存在有效结果
auto it = functionCachedResults.find({F, analysisID});
if (it != functionCachedResults.end()) {
return static_cast<T *>(it->second.get()); // 返回缓存结果
}
// 运行函数级分析遍
analysisPass->runOnFunction(F, *this);
// 获取结果并缓存
std::unique_ptr<AnalysisResultBase> result = analysisPass->getResult();
T *specificResult = static_cast<T *>(result.get());
functionCachedResults[{F, analysisID}] = std::move(result); // 缓存结果
return specificResult;
}
case Pass::Granularity::BasicBlock: {
// 检查请求的上下文是否正确
if (!BB) {
std::cerr << "Error: BasicBlock context required for BasicBlock-level Analysis Pass.\n";
return nullptr;
}
// 检查是否已存在有效结果
auto it = basicBlockCachedResults.find({BB, analysisID});
if (it != basicBlockCachedResults.end()) {
return static_cast<T *>(it->second.get()); // 返回缓存结果
}
// 运行基本块级分析遍
analysisPass->runOnBasicBlock(BB, *this);
// 获取结果并缓存
std::unique_ptr<AnalysisResultBase> result = analysisPass->getResult();
T *specificResult = static_cast<T *>(result.get());
basicBlockCachedResults[{BB, analysisID}] = std::move(result); // 缓存结果
return specificResult;
}
}
return nullptr; // 不会到达这里
}
// 使所有分析结果失效 (当 IR 被修改时调用)
void invalidateAllAnalyses() {
moduleCachedResults.clear();
functionCachedResults.clear();
basicBlockCachedResults.clear();
}
// 使特定分析结果失效
// void *analysisID: 要失效的分析的ID
// Function *F: 如果是函数级分析指定函数如果是模块级或基本块级则为nullptr (取决于调用方式)
// BasicBlock *BB: 如果是基本块级分析指定基本块否则为nullptr
void invalidateAnalysis(void *analysisID, Function *F = nullptr, BasicBlock *BB = nullptr) {
if (BB) {
// 使特定基本块的特定分析结果失效
basicBlockCachedResults.erase({BB, analysisID});
} else if (F) {
// 使特定函数的特定分析结果失效 (也可能包含聚合的BasicBlock结果)
functionCachedResults.erase({F, analysisID});
// 遍历所有属于F的基本块使其BasicBlockCache失效 (如果该分析是BasicBlock粒度的)
// 这需要遍历F的所有基本块效率较低更推荐在BasicBlockPass的invalidateAnalysisUsage中精确指定
// 或者在Function级别的invalidate时清空该Function的所有BasicBlock分析
// 这里的实现简单地清空该Function下所有该ID的BasicBlock缓存
for (auto it = basicBlockCachedResults.begin(); it != basicBlockCachedResults.end(); ) {
// 假设BasicBlock::getParent()方法存在可以获取所属Function
if (it->first.second == analysisID /* && it->first.first->getParent() == F */) { // 需要BasicBlock能获取其父函数
it = basicBlockCachedResults.erase(it);
} else {
++it;
}
}
} else {
// 使所有函数的特定分析结果失效 (Module级和所有Function/BasicBlock级)
moduleCachedResults.erase(analysisID);
for (auto it = functionCachedResults.begin(); it != functionCachedResults.end(); ) {
if (it->first.second == analysisID) {
it = functionCachedResults.erase(it);
} else {
++it;
}
}
for (auto it = basicBlockCachedResults.begin(); it != basicBlockCachedResults.end(); ) {
if (it->first.second == analysisID) {
it = basicBlockCachedResults.erase(it);
} else {
++it;
}
}
}
}
};
// ======================================================================
// PassManager遍管理器
// ======================================================================
class PassManager {
private:
std::vector<std::unique_ptr<Pass>> passes;
AnalysisManager analysisManager;
Module *pmodule;
IRBuilder *pBuilder;
public:
PassManager() = default;
~PassManager() = default;
PassManager(Module *module, IRBuilder *builder) : pmodule(module) ,pBuilder(builder), analysisManager(module) {}
// 运行所有注册的遍
bool run();
// 运行优化管道主要负责注册和运行优化遍
// 这里可以根据 optLevel 和 DEBUG 控制不同的优化遍
void runOptimizationPipeline(Module* moduleIR, IRBuilder* builder, int optLevel);
// 添加遍:现在接受 Pass 的 ID而不是直接的 unique_ptr
void addPass(void *passID);
AnalysisManager &getAnalysisManager() { return analysisManager; }
void clearPasses();
// 输出pass列表并打印IR信息供观察优化遍效果
void printPasses() const;
};
// ======================================================================
// 辅助宏或函数,用于简化 Pass 的注册
// ======================================================================
// 用于分析遍的注册
template <typename AnalysisPassType> void registerAnalysisPass();
// (1) 针对需要 IRBuilder 参数的优化遍的重载
// 这个模板只在 OptimizationPassType 可以通过 IRBuilder* 构造时才有效
template <typename OptimizationPassType, typename std::enable_if<
std::is_constructible<OptimizationPassType, IRBuilder*>::value, int>::type = 0>
void registerOptimizationPass(IRBuilder* builder);
// (2) 针对不需要 IRBuilder 参数的所有其他优化遍的重载
// 这个模板只在 OptimizationPassType 不能通过 IRBuilder* 构造时才有效
template <typename OptimizationPassType, typename std::enable_if<
!std::is_constructible<OptimizationPassType, IRBuilder*>::value, int>::type = 0>
void registerOptimizationPass();
} // namespace sysy

View File

@@ -0,0 +1,146 @@
#pragma once
#include "IR.h"
#include "IRBuilder.h"
#include "SysYBaseVisitor.h"
#include "SysYParser.h"
#include <memory>
#include <unordered_map>
#include <forward_list>
namespace sysy {
// @brief 用于存储数组值的树结构
// 多位数组本质上是一维数组的嵌套可以用树来表示。
class ArrayValueTree {
private:
Value *value = nullptr; /// 该节点存储的value
std::vector<std::unique_ptr<ArrayValueTree>> children; /// 子节点列表
public:
ArrayValueTree() = default;
public:
auto getValue() const -> Value * { return value; }
auto getChildren() const
-> const std::vector<std::unique_ptr<ArrayValueTree>> & {
return children;
}
void setValue(Value *newValue) { value = newValue; }
void addChild(ArrayValueTree *newChild) { children.emplace_back(newChild); }
void addChildren(const std::vector<ArrayValueTree *> &newChildren) {
for (const auto &child : newChildren) {
children.emplace_back(child);
}
}
};
class Utils {
public:
// transform a tree of ArrayValueTree to a ValueCounter
static void tree2Array(Type *type, ArrayValueTree *root,
const std::vector<Value *> &dims, unsigned numDims,
ValueCounter &result, IRBuilder *builder);
static void
createExternalFunction(const std::vector<Type *> &paramTypes,
const std::vector<std::string> &paramNames,
const std::vector<std::vector<Value *>> &paramDims,
Type *returnType, const std::string &funcName,
Module *pModule, IRBuilder *pBuilder);
static void initExternalFunction(Module *pModule, IRBuilder *pBuilder);
};
class SysYIRGenerator : public SysYBaseVisitor {
private:
std::unique_ptr<Module> module;
IRBuilder builder;
public:
SysYIRGenerator() = default;
public:
Module *get() const { return module.get(); }
IRBuilder *getBuilder(){ return &builder; }
public:
std::any visitCompUnit(SysYParser::CompUnitContext *ctx) override;
std::any visitGlobalConstDecl(SysYParser::GlobalConstDeclContext *ctx) override;
std::any visitGlobalVarDecl(SysYParser::GlobalVarDeclContext *ctx) override;
// std::any visitDecl(SysYParser::DeclContext *ctx) override;
std::any visitConstDecl(SysYParser::ConstDeclContext *ctx) override;
std::any visitVarDecl(SysYParser::VarDeclContext *ctx) override;
std::any visitBType(SysYParser::BTypeContext *ctx) override;
// std::any visitConstDef(SysYParser::ConstDefContext *ctx) override;
// std::any visitVarDef(SysYParser::VarDefContext *ctx) override;
std::any visitScalarInitValue(SysYParser::ScalarInitValueContext *ctx) override;
std::any visitArrayInitValue(SysYParser::ArrayInitValueContext *ctx) override;
std::any visitConstScalarInitValue(SysYParser::ConstScalarInitValueContext *ctx) override;
std::any visitConstArrayInitValue(SysYParser::ConstArrayInitValueContext *ctx) override;
// std::any visitConstInitVal(SysYParser::ConstInitValContext *ctx) override;
std::any visitFuncType(SysYParser::FuncTypeContext* ctx) override;
std::any visitFuncDef(SysYParser::FuncDefContext* ctx) override;
// std::any visitInitVal(SysYParser::InitValContext *ctx) override;
// std::any visitFuncFParam(SysYParser::FuncFParamContext *ctx) override;
// std::any visitFuncFParams(SysYParser::FuncFParamsContext *ctx) override;
std::any visitBlockStmt(SysYParser::BlockStmtContext* ctx) override;
// std::any visitStmt(SysYParser::StmtContext *ctx) override;
std::any visitAssignStmt(SysYParser::AssignStmtContext *ctx) override;
// std::any visitExpStmt(SysYParser::ExpStmtContext *ctx) override;
// std::any visitBlkStmt(SysYParser::BlkStmtContext *ctx) override;
std::any visitIfStmt(SysYParser::IfStmtContext *ctx) override;
std::any visitWhileStmt(SysYParser::WhileStmtContext *ctx) override;
std::any visitBreakStmt(SysYParser::BreakStmtContext *ctx) override;
std::any visitContinueStmt(SysYParser::ContinueStmtContext *ctx) override;
std::any visitReturnStmt(SysYParser::ReturnStmtContext *ctx) override;
// std::any visitExp(SysYParser::ExpContext *ctx) override;
// std::any visitCond(SysYParser::CondContext *ctx) override;
std::any visitLValue(SysYParser::LValueContext *ctx) override;
std::any visitPrimaryExp(SysYParser::PrimaryExpContext *ctx) override;
// std::any visitParenExp(SysYParser::ParenExpContext *ctx) override;
std::any visitNumber(SysYParser::NumberContext *ctx) override;
// std::any visitString(SysYParser::StringContext *ctx) override;
std::any visitCall(SysYParser::CallContext *ctx) override;
std::any visitUnaryExp(SysYParser::UnaryExpContext *ctx) override;
// std::any visitUnaryOp(SysYParser::UnaryOpContext *ctx) override;
// std::any visitUnExp(SysYParser::UnExpContext *ctx) override;
std::any visitFuncRParams(SysYParser::FuncRParamsContext *ctx) override;
std::any visitMulExp(SysYParser::MulExpContext *ctx) override;
std::any visitAddExp(SysYParser::AddExpContext *ctx) override;
std::any visitRelExp(SysYParser::RelExpContext *ctx) override;
std::any visitEqExp(SysYParser::EqExpContext *ctx) override;
std::any visitLAndExp(SysYParser::LAndExpContext *ctx) override;
std::any visitLOrExp(SysYParser::LOrExpContext *ctx) override;
// std::any visitConstExp(SysYParser::ConstExpContext *ctx) override;
public:
// 获取GEP指令的地址
Value* getGEPAddressInst(Value* basePointer, const std::vector<Value*>& indices);
// 构建数组类型
Type* buildArrayType(Type* baseType, const std::vector<Value*>& dims);
unsigned countArrayDimensions(Type* type);
}; // class SysYIRGenerator
} // namespace sysy

View File

@@ -0,0 +1,32 @@
#pragma once
#include <string>
#include "IR.h"
namespace sysy {
class SysYPrinter {
private:
Module *pModule;
public:
explicit SysYPrinter(Module *pModule) : pModule(pModule) {}
public:
void printIR();
void printGlobalVariable();
public:
static void printFunction(Function *function);
static void printInst(Instruction *pInst);
static void printType(Type *type);
static void printValue(Value *value);
static void printBlock(BasicBlock *block);
static std::string getBlockName(BasicBlock *block);
static std::string getOperandName(Value *operand);
static std::string getTypeString(Type *type);
static std::string getValueName(Value *value);
};
} // namespace sysy

View File

@@ -0,0 +1,63 @@
#pragma once
#include <iterator>
namespace sysy {
/*!
* \defgroup utility Utilities
* @{
*/
/*!
* \brief `range` is an simple wrapper of an iterator pair [begin, end)
*
* Example usage
*
* ```cpp
* vector<int> v = {1,2,3};
* auto rg = make_range(v);
* for (auto v : rg)
* cout << v << '\n';
* ```
*/
template <typename IterT> struct range {
using iterator = IterT;
using value_type = typename std::iterator_traits<iterator>::value_type;
using reference = typename std::iterator_traits<iterator>::reference;
private:
iterator b;
iterator e;
public:
explicit range(iterator b, iterator e) : b(b), e(e) {}
iterator begin() { return b; }
iterator end() { return e; }
iterator begin() const { return b; }
iterator end() const { return e; }
auto size() const { return std::distance(b, e); }
auto empty() const { return b == e; }
};
//! create `range` object from iterator pair [begin, end)
template <typename IterT> range<IterT> make_range(IterT b, IterT e) {
return range(b, e);
}
//! create `range` object from a container who has `begin()` and `end()` methods
template <typename ContainerT>
range<typename ContainerT::iterator> make_range(ContainerT &c) {
return make_range(c.begin(), c.end());
}
//! create `range` object from a container who has `begin()` and `end()` methods
template <typename ContainerT>
range<typename ContainerT::const_iterator> make_range(const ContainerT &c) {
return make_range(c.begin(), c.end());
}
/*!
* @}
*/
} // namespace sysy