[midend]修改use关系相关的函数,使其能自动的正确维护,修改了phi指令的各种接口
This commit is contained in:
@@ -202,6 +202,7 @@ class Use {
|
||||
|
||||
public:
|
||||
unsigned getIndex() const { return index; } ///< 返回value在User操作数中的位置
|
||||
void setIndex(int newIndex) { index = newIndex; } ///< 设置value在User操作数中的位置
|
||||
User* getUser() const { return user; } ///< 返回使用者
|
||||
Value* getValue() const { return value; } ///< 返回被使用的值
|
||||
void setValue(Value *newValue) { value = newValue; } ///< 将被使用的值设置为newValue
|
||||
@@ -229,7 +230,14 @@ class Value {
|
||||
std::list<std::shared_ptr<Use>>& getUses() { return uses; } ///< 获取使用关系列表
|
||||
void addUse(const std::shared_ptr<Use> &use) { uses.push_back(use); } ///< 添加使用关系
|
||||
void replaceAllUsesWith(Value *value); ///< 将原来使用该value的使用者全变为使用给定参数value并修改相应use关系
|
||||
void removeUse(const std::shared_ptr<Use> &use) { uses.remove(use); } ///< 删除使用关系use
|
||||
void removeUse(const std::shared_ptr<Use> &use) {
|
||||
assert(use != nullptr && "Use cannot be null");
|
||||
assert(use->getValue() != this && "Use does not belong to this Value");
|
||||
auto it = std::find(uses.begin(), uses.end(), use);
|
||||
assert(it != uses.end() && "Use not found in Value's uses");
|
||||
uses.remove(use);
|
||||
} ///< 删除使用关系use
|
||||
void removeAllUses();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -633,21 +641,6 @@ class User : public Value {
|
||||
explicit User(Type *type, const std::string &name = "") : Value(type, name) {}
|
||||
|
||||
public:
|
||||
// ~User() override {
|
||||
// // 当 User 对象被销毁时(例如,LoadInst 或 StoreInst 被删除时),
|
||||
// // 它必须通知它所使用的所有 Value,将对应的 Use 关系从它们的 uses 列表中移除。
|
||||
// // 这样可以防止 Value 的 uses 列表中出现悬空的 Use 对象。
|
||||
// for (const auto &use_ptr : operands) {
|
||||
// // 确保 use_ptr 非空,并且其内部指向的 Value* 也非空
|
||||
// // (虽然通常情况下不会为空,但为了健壮性考虑)
|
||||
// if (use_ptr && use_ptr->getValue()) {
|
||||
// use_ptr->getValue()->removeUse(use_ptr);
|
||||
// }
|
||||
// }
|
||||
// // operands 向量本身是 std::vector<std::shared_ptr<Use>>,
|
||||
// // 在此析构函数结束后,operands 向量会被销毁,其内部的 shared_ptr 也会被释放,
|
||||
// // 如果 shared_ptr 引用计数降为0,Use 对象本身也会被销毁。
|
||||
// }
|
||||
unsigned getNumOperands() const { return operands.size(); } ///< 获取操作数数量
|
||||
auto operand_begin() const { return operands.begin(); } ///< 返回操作数列表的开头迭代器
|
||||
auto operand_end() const { return operands.end(); } ///< 返回操作数列表的结尾迭代器
|
||||
@@ -657,11 +650,7 @@ class User : public Value {
|
||||
operands.emplace_back(std::make_shared<Use>(operands.size(), this, value));
|
||||
value->addUse(operands.back());
|
||||
} ///< 增加操作数
|
||||
void removeOperand(unsigned index) {
|
||||
auto value = getOperand(index);
|
||||
value->removeUse(operands[index]);
|
||||
operands.erase(operands.begin() + index);
|
||||
} ///< 移除操作数
|
||||
void removeOperand(unsigned index);
|
||||
template <typename ContainerT>
|
||||
void addOperands(const ContainerT &newoperands) {
|
||||
for (auto value : newoperands) {
|
||||
@@ -919,57 +908,48 @@ class PhiInst : public Instruction {
|
||||
const std::string &name = "")
|
||||
: 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) {
|
||||
for(size_t i = 0; i < vsize; ++i) {
|
||||
addOperand(rhs[i]);
|
||||
addOperand(Blocks[i]);
|
||||
blk2val[Blocks[i]] = rhs[i];
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Value* getValue(unsigned k) const {return getOperand(2 * k);} ///< 获取位置为k的值
|
||||
BasicBlock* getBlock(unsigned k) const {return dynamic_cast<BasicBlock*>(getOperand(2 * k + 1));}
|
||||
//增加llvm同名方法实现获取value和block
|
||||
Value* getIncomingValue(unsigned k) const {return getOperand(2 * k);} ///< 获取位置为k的值
|
||||
BasicBlock* getIncomingBlock(unsigned k) const {return dynamic_cast<BasicBlock*>(getOperand(2 * k + 1));}
|
||||
|
||||
Value* getIncomingValue(BasicBlock* blk) const {
|
||||
return getvalfromBlk(blk);
|
||||
} ///< 获取指定基本块的传入值
|
||||
|
||||
BasicBlock* getIncomingBlock(Value* val) const {
|
||||
return getBlkfromVal(val);
|
||||
} ///< 获取指定值的传入基本块
|
||||
|
||||
void replaceIncoming(BasicBlock *oldBlock, BasicBlock *newBlock, Value *newValue){
|
||||
delBlk(oldBlock);
|
||||
addIncoming(newValue, newBlock);
|
||||
}
|
||||
|
||||
auto& getincomings() const {return blk2val;} ///< 获取所有的基本块和对应的值
|
||||
|
||||
Value* getvalfromBlk(BasicBlock* blk) const ;
|
||||
BasicBlock* getBlkfromVal(Value* val) const ;
|
||||
|
||||
unsigned getNumIncomingValues() const { return vsize; } ///< 获取传入值的数量
|
||||
Value *getIncomingValue(unsigned Idx) const { return getOperand(Idx * 2); } ///< 获取指定位置的传入值
|
||||
BasicBlock *getIncomingBlock(unsigned Idx) const {return dynamic_cast<BasicBlock *>(getOperand(Idx * 2 + 1)); } ///< 获取指定位置的传入基本块
|
||||
|
||||
Value* getvalfromBlk(BasicBlock* block);
|
||||
BasicBlock* getBlkfromVal(Value* value);
|
||||
|
||||
void addIncoming(Value *value, BasicBlock *block) {
|
||||
assert(value && block && "PhiInst: value and block must not be null");
|
||||
assert(value && block && "PhiInst: value and block cannot be null");
|
||||
addOperand(value);
|
||||
addOperand(block);
|
||||
blk2val[block] = value;
|
||||
vsize++;
|
||||
} ///< 添加传入值和对应的基本块
|
||||
|
||||
void removeIncoming(BasicBlock *block){
|
||||
delBlk(block);
|
||||
}
|
||||
|
||||
void delValue(Value* val);
|
||||
void delBlk(BasicBlock* blk);
|
||||
|
||||
void replaceBlk(BasicBlock* newBlk, unsigned k);
|
||||
void replaceold2new(BasicBlock* oldBlk, BasicBlock* newBlk);
|
||||
void refreshB2VMap();
|
||||
|
||||
void removeIncoming(unsigned Idx) {
|
||||
assert(Idx < vsize && "PhiInst: Index out of bounds");
|
||||
auto blk = getIncomingBlock(Idx);
|
||||
removeOperand(Idx * 2); // Remove value
|
||||
removeOperand(Idx * 2 + 1); // Remove block
|
||||
blk2val.erase(blk);
|
||||
vsize--;
|
||||
} ///< 移除指定位置的传入值和对应的基本块
|
||||
void removeIncomingValue(Value *value);
|
||||
void removeIncomingBlock(BasicBlock *block);
|
||||
void setIncomingValue(unsigned Idx, Value *value);
|
||||
void setIncomingBlock(unsigned Idx, BasicBlock *block);
|
||||
void replaceIncomingValue(Value *oldValue, Value *newValue);
|
||||
void replaceIncomingBlock(BasicBlock *oldBlock, BasicBlock *newBlock);
|
||||
void refreshMap() {
|
||||
blk2val.clear();
|
||||
for (unsigned i = 0; i < vsize; ++i) {
|
||||
blk2val[getIncomingBlock(i)] = getIncomingValue(i);
|
||||
}
|
||||
} ///< 刷新块到值的映射关系
|
||||
auto getValues() { return make_range(std::next(operand_begin()), operand_end()); }
|
||||
};
|
||||
|
||||
|
||||
@@ -48,13 +48,6 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
// 清空 User 的 operands 向量。这会递减 User 持有的 shared_ptr<Use> 的引用计数。
|
||||
// 当引用计数降为 0 时,Use 对象本身将被销毁。
|
||||
// User::operands.clear(); // 这个步骤会在 Instruction 的析构函数中自动完成,因为它是 vector 成员
|
||||
// 或者我们可以在 User::removeOperand 方法中确保 Use 对象从 operands 中移除。
|
||||
// 实际上,只要 Value::removeUse(use_ptr) 被调用了,
|
||||
// 当 Instruction 所在的 unique_ptr 销毁时,它的 operands vector 也会被销毁。
|
||||
// 所以这里不需要显式 clear()
|
||||
}
|
||||
static void usedelete(Instruction *inst) {
|
||||
assert(inst && "Instruction to delete cannot be null.");
|
||||
@@ -75,7 +68,7 @@ public:
|
||||
// 步骤3: 物理删除指令
|
||||
// 这会导致 Instruction 对象的 unique_ptr 销毁,从而调用其析构函数链。
|
||||
parentBlock->removeInst(inst);
|
||||
}
|
||||
}
|
||||
|
||||
static BasicBlock::iterator usedelete(BasicBlock::iterator inst_it) {
|
||||
Instruction *inst_to_delete = inst_it->get();
|
||||
@@ -92,7 +85,7 @@ public:
|
||||
|
||||
// 步骤3: 物理删除指令并返回下一个迭代器
|
||||
return parentBlock->removeInst(inst_it);
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否是全局变量
|
||||
static bool isGlobal(Value *val) {
|
||||
|
||||
Reference in New Issue
Block a user