[IR]phi指令重构,将block信息加入并提供新方法,后续需更改phi相关指令构建逻辑

This commit is contained in:
rain2133
2025-07-17 19:01:02 +08:00
parent 77fae4d662
commit 631ef80de2
2 changed files with 115 additions and 10 deletions

View File

@ -545,6 +545,83 @@ void User::replaceOperand(unsigned index, Value *value) {
value->addUse(use);
}
/**
* phi相关函数
*/
Value* PhiInst::getvalfromBlk(BasicBlock* blk){
refreshB2VMap();
if( blk2val.find(blk) != blk2val.end()) {
return blk2val.at(blk);
}
return nullptr;
}
BasicBlock* PhiInst::getBlkfromVal(Value* val){
// 返回第一个值对应的基本块
for(unsigned i = 0; i < vsize; i++) {
if(getValue(i) == val) {
return getBlock(i);
}
}
return nullptr;
}
void PhiInst::delValue(Value* val){
//根据value删除对应的基本块和值
unsigned i = 0;
BasicBlock* blk = getBlkfromVal(val);
for(i = 0; i < vsize; i++) {
if(getValue(i) == val) {
break;
}
}
removeOperand(2 * i + 1); // 删除blk
removeOperand(2 * i); // 删除val
vsize--;
blk2val.erase(blk); // 删除blk2val映射
}
void PhiInst::delBlk(BasicBlock* blk){
//根据Blk删除对应的基本块和值
unsigned i = 0;
Value* val = getvalfromBlk(blk);
for(i = 0; i < vsize; i++) {
if(getBlock(i) == blk) {
break;
}
}
removeOperand(2 * i + 1); // 删除blk
removeOperand(2 * i); // 删除val
vsize--;
blk2val.erase(blk); // 删除blk2val映射
}
void PhiInst::replaceBlk(BasicBlock* newBlk, unsigned k){
refreshB2VMap();
Value* val = blk2val.at(getBlock(k));
// 替换基本块
setOperand(2 * k + 1, newBlk);
// 替换blk2val映射
blk2val.erase(getBlock(k));
blk2val.emplace(newBlk, val);
}
void PhiInst::replaceold2new(BasicBlock* oldBlk, BasicBlock* newBlk){
refreshB2VMap();
Value* val = blk2val.at(oldBlk);
// 替换基本块
delBlk(oldBlk);
addIncoming(val, newBlk);
}
void PhiInst::refreshB2VMap(){
blk2val.clear();
for(unsigned i = 0; i < vsize; i++) {
blk2val.emplace(getBlock(i), getValue(i));
}
}
CallInst::CallInst(Function *callee, const std::vector<Value *> &args, BasicBlock *parent, const std::string &name)
: Instruction(kCall, callee->getReturnType(), parent, name) {
addOperand(callee);

View File

@ -755,22 +755,50 @@ class LaInst : public Instruction {
class PhiInst : public Instruction {
friend class IRBuilder;
friend class Function;
friend class SysySSA;
protected:
Value *map_val; // Phi的旧值
PhiInst(Type *type, Value *lhs, const std::vector<Value *> &rhs, Value *mval, BasicBlock *parent,
std::unordered_map<BasicBlock *, Value *> blk2val; ///< 存储每个基本块对应的值
unsigned vsize; ///< 存储值的数量
PhiInst(Type *type,
const std::vector<Value *> &rhs = {},
const std::vector<BasicBlock*> &Blocks = {},
BasicBlock *parent,
const std::string &name = "")
: Instruction(Kind::kPhi, type, parent, name) {
map_val = mval;
addOperand(lhs);
addOperands(rhs);
: Instruction(Kind::kPhi, type, parent, name), vsize(rhs.size()) {
assert(rhs.size() == Blocks.size() && "PhiInst: rhs and Blocks must have the same size");
for(size_t i = 0; i < rhs.size(); ++i) {
addOperand(rhs[i]);
blk2val[Blocks[i]] = rhs[i];
}
}
public:
Value* getMapVal() { return map_val; }
Value* getPointer() const { return getOperand(0); }
Value* getValue(unsigned k) const {return getOperand(2 * k);} ///< 获取位置为k的值
BasicBlock* getBlock(unsigned k) const {return dynamic_cast<BasicBlock*>(getOperand(2 * k + 1));}
auto& getincomings() const {return blk2val;} ///< 获取所有的基本块和对应的值
Value* getvalfromBlk(BasicBlock* blk);
BasicBlock* getBlkfromVal(Value* val);
unsigned getNumIncomingValues() const { return vsize; } ///< 获取传入值的数量
void addIncoming(Value *value, BasicBlock *block) {
assert(value && block && "PhiInst: value and block must not be null");
addOperand(value);
addOperand(block);
blk2val[block] = value;
vsize++;
} ///< 添加传入值和对应的基本块
void delValue(Value* val);
void delBlk(BasicBlock* blk);
void replaceBlk(BasicBlock* newBlk, unsigned k);
void replaceold2new(BasicBlock* oldBlk, BasicBlock* newBlk);
void refreshB2VMap();
auto getValues() { return make_range(std::next(operand_begin()), operand_end()); }
Value* getValue(unsigned index) const { return getOperand(index + 1); }
};
@ -884,7 +912,7 @@ public:
}
} ///< 根据指令类型进行二元计算eval template模板实现
static BinaryInst* create(Kind kind, Type *type, Value *lhs, Value *rhs, BasicBlock *parent, const std::string &name = "") {
// 后端处理数组访存操作时需要创建计算地址的指令,需要在外部构造 BinaryInst 对象所以写了个public的方法。
// 后端处理数组访存操作时需要创建计算地址的指令,需要在外部构造 BinaryInst 对象
return new BinaryInst(kind, type, lhs, rhs, parent, name);
}
}; // class BinaryInst