[midend-mem2reg]dom增加访问支配树子节点求解和访问方法,修复block打印,phi指令命名,TODO:reg2membug待修复
This commit is contained in:
22
src/Dom.cpp
22
src/Dom.cpp
@ -38,6 +38,14 @@ const std::set<BasicBlock *> *DominatorTree::getDominanceFrontier(BasicBlock *BB
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::set<BasicBlock*>* DominatorTree::getDominatorTreeChildren(BasicBlock* BB) const {
|
||||
auto it = DominatorTreeChildren.find(BB);
|
||||
if (it != DominatorTreeChildren.end()) {
|
||||
return &(it->second);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void DominatorTree::computeDominators(Function *F) {
|
||||
// 经典的迭代算法计算支配者集合
|
||||
// TODO: 可以替换为更高效的算法,如 Lengauer-Tarjan 算法
|
||||
@ -159,6 +167,19 @@ void DominatorTree::computeDominanceFrontiers(Function *F) {
|
||||
}
|
||||
}
|
||||
|
||||
void DominatorTree::computeDominatorTreeChildren(Function *F) {
|
||||
for (auto &bb_ptr : F->getBasicBlocks()) {
|
||||
BasicBlock *B = bb_ptr.get();
|
||||
auto it = getImmediateDominator(B);
|
||||
if (it != nullptr) {
|
||||
BasicBlock *A = it;
|
||||
if (A) {
|
||||
DominatorTreeChildren[A].insert(B);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==============================================================
|
||||
// DominatorTreeAnalysisPass 的实现
|
||||
// ==============================================================
|
||||
@ -169,6 +190,7 @@ bool DominatorTreeAnalysisPass::runOnFunction(Function* F, AnalysisManager &AM)
|
||||
CurrentDominatorTree->computeDominators(F);
|
||||
CurrentDominatorTree->computeIDoms(F);
|
||||
CurrentDominatorTree->computeDominanceFrontiers(F);
|
||||
CurrentDominatorTree->computeDominatorTreeChildren(F);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -193,7 +193,7 @@ void Mem2RegContext::insertPhis(AllocaInst *alloca, const std::unordered_set<Bas
|
||||
// Phi 指令的类型与 alloca 的类型指向的类型相同
|
||||
|
||||
builder->setPosition(frontierBlock, frontierBlock->begin()); // 设置插入位置为基本块开头
|
||||
auto phiInst = builder->createPhiInst(alloca->getAllocatedType(), {}, {frontierBlock}, "");
|
||||
PhiInst *phiInst = builder->createPhiInst(alloca->getAllocatedType(), {}, {}, "");
|
||||
|
||||
allocaToPhiMap[alloca][frontierBlock] = phiInst; // 记录 Phi 指令
|
||||
|
||||
@ -294,12 +294,16 @@ void Mem2RegContext::renameVariables(AllocaInst *currentAlloca, BasicBlock *curr
|
||||
// --------------------------------------------------------------------
|
||||
// 递归访问支配树的子节点
|
||||
// --------------------------------------------------------------------
|
||||
const std::set<BasicBlock *> *dominatedBlocks = dt->getDominators(currentBB);
|
||||
for (auto dominatedBB : *dominatedBlocks) {
|
||||
if (dominatedBB) {
|
||||
renameVariables(currentAlloca, dominatedBB);
|
||||
const std::set<BasicBlock *> *dominatedBlocks = dt->getDominatorTreeChildren(currentBB);
|
||||
if(dominatedBlocks){
|
||||
for (auto dominatedBB : *dominatedBlocks) {
|
||||
if (dominatedBB) {
|
||||
std::cout << "Mem2Reg: Recursively renaming variables in dominated block: " << dominatedBB->getName() << std::endl;
|
||||
renameVariables(currentAlloca, dominatedBB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// 退出基本块时,弹出在此块中压入值栈的 SSA 值
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#include "Reg2Mem.h"
|
||||
#include "SysYIROptUtils.h" // 如果有的话
|
||||
|
||||
extern int DEBUG; // 全局调试标志
|
||||
|
||||
namespace sysy {
|
||||
|
||||
void *Reg2Mem::ID = (void *)&Reg2Mem::ID;
|
||||
@ -30,6 +32,12 @@ void Reg2MemContext::run(Function *func) {
|
||||
|
||||
bool Reg2MemContext::isPromotableToMemory(Value *val) {
|
||||
// 参数和指令结果是 SSA 值
|
||||
if(DEBUG){
|
||||
if(val->getName() == ""){
|
||||
assert(false && "Value name should not be empty in Reg2MemContext::isPromotableToMemory");
|
||||
}
|
||||
std::cout << "Checking if value is promotable to memory: " << val->getName() << std::endl;
|
||||
}
|
||||
if (dynamic_cast<Argument *>(val) || dynamic_cast<Instruction *>(val)) {
|
||||
// 如果值已经是指针类型,则通常不为其分配额外的内存,因为它已经是一个地址。
|
||||
// (除非我们想将其值也存储起来,这通常不用于 Reg2Mem)
|
||||
@ -54,7 +62,7 @@ void Reg2MemContext::allocateMemoryForSSAValues(Function *func) {
|
||||
for (auto arg : func->getArguments()) {
|
||||
if (isPromotableToMemory(arg)) {
|
||||
// 参数的类型就是 AllocaInst 需要分配的类型
|
||||
AllocaInst *alloca = builder->createAllocaInst(arg->getType(), {}, arg->getName() + ".reg2mem");
|
||||
AllocaInst *alloca = builder->createAllocaInst(arg->getType(), {});
|
||||
// 将参数值 store 到 alloca 中 (这是 Mem2Reg 逆转的关键一步)
|
||||
builder->createStoreInst(arg, alloca);
|
||||
valueToAllocaMap[arg] = alloca;
|
||||
@ -82,7 +90,7 @@ void Reg2MemContext::allocateMemoryForSSAValues(Function *func) {
|
||||
// AllocaInst 应该在入口块,而不是当前指令所在块
|
||||
// 这里我们只是创建,并稍后调整其位置
|
||||
// 通常的做法是在循环结束后统一将 alloca 放到 entryBlock 的顶部
|
||||
AllocaInst *alloca = builder->createAllocaInst(inst.get()->getType(), {}, inst->getName() + ".reg2mem");
|
||||
AllocaInst *alloca = builder->createAllocaInst(inst.get()->getType(), {});
|
||||
valueToAllocaMap[inst.get()] = alloca;
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,6 +79,15 @@ std::string SysYPrinter::getValueName(Value *value) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string SysYPrinter::getBlockName(BasicBlock *block) {
|
||||
static int blockId = 0; // 用于生成唯一的基本块ID
|
||||
if (block->getName().empty()) {
|
||||
return "bb" + std::to_string(blockId++); // 如果没有名字,生成一个唯一的基本块ID
|
||||
} else {
|
||||
return block->getName();
|
||||
}
|
||||
}
|
||||
|
||||
void SysYPrinter::printType(Type *type) {
|
||||
std::cout << getTypeString(type);
|
||||
}
|
||||
@ -128,6 +137,10 @@ void SysYPrinter::printGlobalVariable() {
|
||||
}
|
||||
}
|
||||
|
||||
void SysYPrinter::printBlock(BasicBlock *block) {
|
||||
std::cout << getBlockName(block);
|
||||
}
|
||||
|
||||
void SysYPrinter::printFunction(Function *function) {
|
||||
// Function signature
|
||||
std::cout << "define ";
|
||||
@ -466,13 +479,13 @@ void SysYPrinter::printInst(Instruction *pInst) {
|
||||
// 如果你的 PhiInst 存储方式是 getIncomingValues() 和 getIncomingBlocks(),请相应调整
|
||||
// LLVM IR 格式: phi type [value1, block1], [value2, block2]
|
||||
bool firstPair = true;
|
||||
for (unsigned i = 0; i < phiInst->getNumOperands() / 2; ++i) { // 遍历成对的操作数
|
||||
for (unsigned i = 0; i < phiInst->getNumIncomingValues(); ++i) { // 遍历成对的操作数
|
||||
if (!firstPair) std::cout << ", ";
|
||||
firstPair = false;
|
||||
std::cout << "[ ";
|
||||
printValue(phiInst->getOperand(i * 2)); // value
|
||||
printValue(phiInst->getValue(i));
|
||||
std::cout << ", %";
|
||||
printValue(phiInst->getOperand(i * 2 + 1)); // block
|
||||
printBlock(phiInst->getBlock(i));
|
||||
std::cout << " ]";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
@ -16,17 +16,20 @@ public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -294,7 +294,16 @@ class IRBuilder {
|
||||
return inst;
|
||||
} ///< 创建store指令
|
||||
PhiInst * createPhiInst(Type *type, const std::vector<Value*> &vals = {}, const std::vector<BasicBlock*> &blks = {}, const std::string &name = "") {
|
||||
auto inst = new PhiInst(type, vals, blks, block, 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;
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
#include "IR.h"
|
||||
#include "IRBuilder.h"
|
||||
|
||||
extern int DEBUG; // 全局调试标志
|
||||
|
||||
namespace sysy {
|
||||
|
||||
//前向声明
|
||||
@ -149,6 +151,9 @@ public:
|
||||
}
|
||||
AnalysisPass *analysisPass = static_cast<AnalysisPass *>(basePass.get());
|
||||
|
||||
if(DEBUG){
|
||||
std::cout << "Running Analysis Pass: " << analysisPass->getName() << "\n";
|
||||
}
|
||||
// 根据分析遍的粒度处理
|
||||
switch (analysisPass->getGranularity()) {
|
||||
case Pass::Granularity::Module: {
|
||||
|
||||
@ -22,6 +22,8 @@ public:
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user