Compare commits
1 Commits
midend-SCC
...
deploy-202
| Author | SHA1 | Date | |
|---|---|---|---|
| ed8fc32a23 |
@ -1,529 +0,0 @@
|
|||||||
#include "SysYIRAnalyser.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
|
|
||||||
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<BasicBlock *> &dom, const std::unordered_set<BasicBlock *> &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<BasicBlock*>(infoA->getIdom());
|
|
||||||
infoA = blockAnalysisInfo[a];
|
|
||||||
}
|
|
||||||
while (infoB->getDomDepth() > infoA->getDomDepth()) {
|
|
||||||
b = const_cast<BasicBlock*>(infoB->getIdom());
|
|
||||||
infoB = blockAnalysisInfo[b];
|
|
||||||
}
|
|
||||||
if (a == b) break;
|
|
||||||
a = const_cast<BasicBlock*>(infoA->getIdom());
|
|
||||||
b = const_cast<BasicBlock*>(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<BasicBlock *> 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<BasicBlock *> 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: SEMI-NCA算法改进
|
|
||||||
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<BasicBlock*>(blockAnalysisInfo[basicBlock.get()]->getIdom())]->removeSdoms(basicBlock.get());
|
|
||||||
}
|
|
||||||
// 设置新的支配关系
|
|
||||||
|
|
||||||
// std::cout << "Block: " << basicBlock->getName()
|
|
||||||
// << " New Idom: " << new_idom->getName() << std::endl;
|
|
||||||
|
|
||||||
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<BasicBlock *> 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<BasicBlock *> ControlFlowAnalysis::computeDomFrontier(BasicBlock *block) {
|
|
||||||
// std::unordered_set<BasicBlock *> 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<BasicBlock *> 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<BasicBlock *> 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==========================
|
|
||||||
// dataflow analysis utils
|
|
||||||
// ==========================
|
|
||||||
|
|
||||||
// 先引用学长的代码
|
|
||||||
// TODO: Worklist 增加逆后序遍历机制
|
|
||||||
void DataFlowAnalysisUtils::forwardAnalyze(Module *pModule){
|
|
||||||
std::map<DataFlowAnalysis *, bool> workAnalysis;
|
|
||||||
for (auto &dataflow : forwardAnalysisList) {
|
|
||||||
dataflow->init(pModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &function : pModule->getFunctions()) {
|
|
||||||
for (auto &dataflow : forwardAnalysisList) {
|
|
||||||
workAnalysis.emplace(dataflow, false);
|
|
||||||
}
|
|
||||||
while (!workAnalysis.empty()) {
|
|
||||||
for (const auto &block : function.second->getBasicBlocks()) {
|
|
||||||
for (auto &elem : workAnalysis) {
|
|
||||||
if (elem.first->analyze(pModule, block.get())) {
|
|
||||||
elem.second = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::map<DataFlowAnalysis *, bool> tmp;
|
|
||||||
std::remove_copy_if(workAnalysis.begin(), workAnalysis.end(), std::inserter(tmp, tmp.end()),
|
|
||||||
[](const std::pair<DataFlowAnalysis *, bool> &elem) -> bool { return !elem.second; });
|
|
||||||
workAnalysis.swap(tmp);
|
|
||||||
|
|
||||||
for (auto &elem : workAnalysis) {
|
|
||||||
elem.second = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DataFlowAnalysisUtils::backwardAnalyze(Module *pModule) {
|
|
||||||
std::map<DataFlowAnalysis *, bool> workAnalysis;
|
|
||||||
for (auto &dataflow : backwardAnalysisList) {
|
|
||||||
dataflow->init(pModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &function : pModule->getFunctions()) {
|
|
||||||
for (auto &dataflow : backwardAnalysisList) {
|
|
||||||
workAnalysis.emplace(dataflow, false);
|
|
||||||
}
|
|
||||||
while (!workAnalysis.empty()) {
|
|
||||||
for (const auto &block : function.second->getBasicBlocks()) {
|
|
||||||
for (auto &elem : workAnalysis) {
|
|
||||||
if (elem.first->analyze(pModule, block.get())) {
|
|
||||||
elem.second = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::map<DataFlowAnalysis *, bool> tmp;
|
|
||||||
std::remove_copy_if(workAnalysis.begin(), workAnalysis.end(), std::inserter(tmp, tmp.end()),
|
|
||||||
[](const std::pair<DataFlowAnalysis *, bool> &elem) -> bool { return !elem.second; });
|
|
||||||
workAnalysis.swap(tmp);
|
|
||||||
|
|
||||||
for (auto &elem : workAnalysis) {
|
|
||||||
elem.second = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::set<User *> ActiveVarAnalysis::getUsedSet(Instruction *inst) {
|
|
||||||
using Kind = Instruction::Kind;
|
|
||||||
std::vector<User *> operands;
|
|
||||||
for (const auto &operand : inst->getOperands()) {
|
|
||||||
operands.emplace_back(dynamic_cast<User *>(operand->getValue()));
|
|
||||||
}
|
|
||||||
std::set<User *> result;
|
|
||||||
switch (inst->getKind()) {
|
|
||||||
// phi op
|
|
||||||
case Kind::kPhi:
|
|
||||||
case Kind::kCall:
|
|
||||||
result.insert(std::next(operands.begin()), operands.end());
|
|
||||||
break;
|
|
||||||
case Kind::kCondBr:
|
|
||||||
result.insert(operands[0]);
|
|
||||||
break;
|
|
||||||
case Kind::kBr:
|
|
||||||
case Kind::kAlloca:
|
|
||||||
break;
|
|
||||||
// mem op
|
|
||||||
case Kind::kStore:
|
|
||||||
// StoreInst 的第一个操作数是被存储的值,第二个操作数是存储的变量
|
|
||||||
// 后续的是可能的数组维度
|
|
||||||
result.insert(operands[0]);
|
|
||||||
result.insert(operands.begin() + 2, operands.end());
|
|
||||||
break;
|
|
||||||
case Kind::kLoad:
|
|
||||||
case Kind::kLa: {
|
|
||||||
auto variable = dynamic_cast<AllocaInst *>(operands[0]);
|
|
||||||
auto global = dynamic_cast<GlobalValue *>(operands[0]);
|
|
||||||
auto constArray = dynamic_cast<ConstantVariable *>(operands[0]);
|
|
||||||
if ((variable != nullptr && variable->getNumDims() == 0) || (global != nullptr && global->getNumDims() == 0) ||
|
|
||||||
(constArray != nullptr && constArray->getNumDims() == 0)) {
|
|
||||||
result.insert(operands[0]);
|
|
||||||
}
|
|
||||||
result.insert(std::next(operands.begin()), operands.end());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Kind::kGetSubArray: {
|
|
||||||
for (unsigned i = 2; i < operands.size(); i++) {
|
|
||||||
// 数组的维度信息
|
|
||||||
result.insert(operands[i]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Kind::kMemset: {
|
|
||||||
result.insert(std::next(operands.begin()), operands.end());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Kind::kInvalid:
|
|
||||||
// Binary
|
|
||||||
case Kind::kAdd:
|
|
||||||
case Kind::kSub:
|
|
||||||
case Kind::kMul:
|
|
||||||
case Kind::kDiv:
|
|
||||||
case Kind::kRem:
|
|
||||||
case Kind::kICmpEQ:
|
|
||||||
case Kind::kICmpNE:
|
|
||||||
case Kind::kICmpLT:
|
|
||||||
case Kind::kICmpLE:
|
|
||||||
case Kind::kICmpGT:
|
|
||||||
case Kind::kICmpGE:
|
|
||||||
case Kind::kFAdd:
|
|
||||||
case Kind::kFSub:
|
|
||||||
case Kind::kFMul:
|
|
||||||
case Kind::kFDiv:
|
|
||||||
case Kind::kFCmpEQ:
|
|
||||||
case Kind::kFCmpNE:
|
|
||||||
case Kind::kFCmpLT:
|
|
||||||
case Kind::kFCmpLE:
|
|
||||||
case Kind::kFCmpGT:
|
|
||||||
case Kind::kFCmpGE:
|
|
||||||
case Kind::kAnd:
|
|
||||||
case Kind::kOr:
|
|
||||||
// Unary
|
|
||||||
case Kind::kNeg:
|
|
||||||
case Kind::kNot:
|
|
||||||
case Kind::kFNot:
|
|
||||||
case Kind::kFNeg:
|
|
||||||
case Kind::kFtoI:
|
|
||||||
case Kind::kItoF:
|
|
||||||
// terminator
|
|
||||||
case Kind::kReturn:
|
|
||||||
result.insert(operands.begin(), operands.end());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result.erase(nullptr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
User * ActiveVarAnalysis::getDefine(Instruction *inst) {
|
|
||||||
User *result = nullptr;
|
|
||||||
if (inst->isStore()) {
|
|
||||||
StoreInst* store = dynamic_cast<StoreInst *>(inst);
|
|
||||||
auto operand = store->getPointer();
|
|
||||||
AllocaInst* variable = dynamic_cast<AllocaInst *>(operand);
|
|
||||||
GlobalValue* global = dynamic_cast<GlobalValue *>(operand);
|
|
||||||
if ((variable != nullptr && variable->getNumDims() != 0) || (global != nullptr && global->getNumDims() != 0)) {
|
|
||||||
// 如果是数组变量或者全局变量,则不返回定义
|
|
||||||
// TODO:兼容数组变量
|
|
||||||
result = nullptr;
|
|
||||||
} else {
|
|
||||||
result = dynamic_cast<User *>(operand);
|
|
||||||
}
|
|
||||||
} else if (inst->isPhi()) {
|
|
||||||
result = dynamic_cast<User *>(inst->getOperand(0));
|
|
||||||
} else if (inst->isBinary() || inst->isUnary() || inst->isCall() ||
|
|
||||||
inst->isLoad() || inst->isLa()) {
|
|
||||||
result = dynamic_cast<User *>(inst);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActiveVarAnalysis::init(Module *pModule) {
|
|
||||||
for (const auto &function : pModule->getFunctions()) {
|
|
||||||
for (const auto &block : function.second->getBasicBlocks()) {
|
|
||||||
activeTable.emplace(block.get(), std::vector<std::set<User *>>{});
|
|
||||||
for (unsigned i = 0; i < block->getNumInstructions() + 1; i++)
|
|
||||||
activeTable.at(block.get()).emplace_back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 活跃变量分析公式 每个块内的分析动作供分析器调用
|
|
||||||
bool ActiveVarAnalysis::analyze(Module *pModule, BasicBlock *block) {
|
|
||||||
bool changed = false; // 标记数据流结果是否有变化
|
|
||||||
std::set<User *> activeSet{}; // 当前计算的活跃变量集合
|
|
||||||
|
|
||||||
// 步骤1: 计算基本块出口的活跃变量集 (OUT[B])
|
|
||||||
// 公式: OUT[B] = ∪_{S ∈ succ(B)} IN[S]
|
|
||||||
for (const auto &succ : block->getSuccessors()) {
|
|
||||||
// 获取后继块入口的活跃变量集 (IN[S])
|
|
||||||
auto succActiveSet = activeTable.at(succ).front();
|
|
||||||
// 合并所有后继块的入口活跃变量
|
|
||||||
activeSet.insert(succActiveSet.begin(), succActiveSet.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 步骤2: 处理基本块出口处的活跃变量集
|
|
||||||
const auto &instructions = block->getInstructions();
|
|
||||||
const auto numInstructions = instructions.size();
|
|
||||||
|
|
||||||
// 获取旧的出口活跃变量集 (block出口对应索引numInstructions)
|
|
||||||
const auto &oldEndActiveSet = activeTable.at(block)[numInstructions];
|
|
||||||
|
|
||||||
// 检查出口活跃变量集是否有变化
|
|
||||||
if (!std::equal(activeSet.begin(), activeSet.end(),
|
|
||||||
oldEndActiveSet.begin(), oldEndActiveSet.end()))
|
|
||||||
{
|
|
||||||
changed = true; // 标记变化
|
|
||||||
activeTable.at(block)[numInstructions] = activeSet; // 更新出口活跃变量集
|
|
||||||
}
|
|
||||||
|
|
||||||
// 步骤3: 逆序遍历基本块中的指令
|
|
||||||
// 从最后一条指令开始向前计算每个程序点的活跃变量
|
|
||||||
auto instructionIter = instructions.end();
|
|
||||||
instructionIter--; // 指向最后一条指令
|
|
||||||
|
|
||||||
// 从出口向入口遍历 (索引从numInstructions递减到1)
|
|
||||||
for (unsigned i = numInstructions; i > 0; i--) {
|
|
||||||
auto inst = instructionIter->get(); // 当前指令
|
|
||||||
|
|
||||||
auto used = getUsedSet(inst);
|
|
||||||
User *defined = getDefine(inst);
|
|
||||||
|
|
||||||
// 步骤3.3: 计算指令入口的活跃变量 (IN[i])
|
|
||||||
// 公式: IN[i] = use_i ∪ (OUT[i] - def_i)
|
|
||||||
activeSet.erase(defined); // 移除被定义的变量 (OUT[i] - def_i)
|
|
||||||
activeSet.insert(used.begin(), used.end()); // 添加使用的变量
|
|
||||||
|
|
||||||
// 获取旧的入口活跃变量集 (位置i-1对应当前指令的入口)
|
|
||||||
const auto &oldActiveSet = activeTable.at(block)[i - 1];
|
|
||||||
|
|
||||||
// 检查活跃变量集是否有变化
|
|
||||||
if (!std::equal(activeSet.begin(), activeSet.end(),
|
|
||||||
oldActiveSet.begin(), oldActiveSet.end()))
|
|
||||||
{
|
|
||||||
changed = true; // 标记变化
|
|
||||||
activeTable.at(block)[i - 1] = activeSet; // 更新入口活跃变量集
|
|
||||||
}
|
|
||||||
|
|
||||||
instructionIter--; // 移动到前一条指令
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed; // 返回数据流结果是否变化
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace sysy
|
|
||||||
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
// PassManager.cpp
|
|
||||||
#include "SysYIRPassManager.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace sysy {
|
|
||||||
|
|
||||||
void PassManager::run(Module& M) {
|
|
||||||
// 首先运行Module级别的Pass
|
|
||||||
for (auto& pass : modulePasses) {
|
|
||||||
std::cout << "Running Module Pass: " << pass->getPassName() << std::endl;
|
|
||||||
pass->runOnModule(M);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 然后对每个函数运行Function级别的Pass
|
|
||||||
auto& functions = M.getFunctions();
|
|
||||||
for (auto& pair : functions) {
|
|
||||||
Function& F = *(pair.second); // 获取Function的引用
|
|
||||||
std::cout << " Processing Function: " << F.getName() << std::endl;
|
|
||||||
|
|
||||||
// 在每个函数上运行FunctionPasses
|
|
||||||
bool changedInFunction;
|
|
||||||
do {
|
|
||||||
changedInFunction = false;
|
|
||||||
for (auto& pass : functionPasses) {
|
|
||||||
// 对于FunctionPasses,可以考虑一个迭代执行的循环,直到稳定
|
|
||||||
std::cout << " Running Function Pass: " << pass->getPassName() << std::endl;
|
|
||||||
changedInFunction |= pass->runOnFunction(F);
|
|
||||||
}
|
|
||||||
} while (changedInFunction); // 循环直到函数稳定,这模拟了您SysYCFGOpt的while(changed)逻辑
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分析Pass的运行可以在其他Pass需要时触发,或者在特定的PassManager阶段触发
|
|
||||||
// 对于依赖于分析结果的Pass,可以在其run方法中通过PassManager::getAnalysis()来获取
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace sysy
|
|
||||||
Reference in New Issue
Block a user