From d8b004e5e58fdd3ac52b942ff1a46e65169b6449 Mon Sep 17 00:00:00 2001 From: rain2133 <1370973498@qq.com> Date: Sun, 3 Aug 2025 22:16:40 +0800 Subject: [PATCH] =?UTF-8?q?[midend]=E4=BF=AE=E6=94=B9use=E5=85=B3=E7=B3=BB?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E5=87=BD=E6=95=B0=EF=BC=8C=E4=BD=BF?= =?UTF-8?q?=E5=85=B6=E8=83=BD=E8=87=AA=E5=8A=A8=E7=9A=84=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E7=BB=B4=E6=8A=A4=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=BA=86phi?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=E7=9A=84=E5=90=84=E7=A7=8D=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/include/midend/IR.h | 98 ++-- .../midend/Pass/Optimize/SysYIROptUtils.h | 11 +- src/midend/IR.cpp | 499 ++++-------------- 3 files changed, 135 insertions(+), 473 deletions(-) diff --git a/src/include/midend/IR.h b/src/include/midend/IR.h index 14433e4..2920ccd 100644 --- a/src/include/midend/IR.h +++ b/src/include/midend/IR.h @@ -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>& getUses() { return uses; } ///< 获取使用关系列表 void addUse(const std::shared_ptr &use) { uses.push_back(use); } ///< 添加使用关系 void replaceAllUsesWith(Value *value); ///< 将原来使用该value的使用者全变为使用给定参数value并修改相应use关系 - void removeUse(const std::shared_ptr &use) { uses.remove(use); } ///< 删除使用关系use + void removeUse(const std::shared_ptr &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>, - // // 在此析构函数结束后,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(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 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(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(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(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()); } }; diff --git a/src/include/midend/Pass/Optimize/SysYIROptUtils.h b/src/include/midend/Pass/Optimize/SysYIROptUtils.h index 1265059..00a4db5 100644 --- a/src/include/midend/Pass/Optimize/SysYIROptUtils.h +++ b/src/include/midend/Pass/Optimize/SysYIROptUtils.h @@ -48,13 +48,6 @@ public: } } } - // 清空 User 的 operands 向量。这会递减 User 持有的 shared_ptr 的引用计数。 - // 当引用计数降为 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) { diff --git a/src/midend/IR.cpp b/src/midend/IR.cpp index b61a766..636f38f 100644 --- a/src/midend/IR.cpp +++ b/src/midend/IR.cpp @@ -182,377 +182,45 @@ auto Function::getCalleesWithNoExternalAndSelf() -> std::set { } return result; } -// 函数克隆,后续函数级优化(内联等)需要用到 -Function * Function::clone(const std::string &suffix) const { - std::stringstream ss; - std::map oldNewBlockMap; - IRBuilder builder; - auto newFunction = new Function(parent, type, name); - newFunction->getEntryBlock()->setName(blocks.front()->getName()); - oldNewBlockMap.emplace(blocks.front().get(), newFunction->getEntryBlock()); - auto oldBlockListIter = std::next(blocks.begin()); - while (oldBlockListIter != blocks.end()) { - auto newBlock = newFunction->addBasicBlock(oldBlockListIter->get()->getName()); - oldNewBlockMap.emplace(oldBlockListIter->get(), newBlock); - oldBlockListIter++; - } - for (const auto &oldNewBlockItem : oldNewBlockMap) { - auto oldBlock = oldNewBlockItem.first; - auto newBlock = oldNewBlockItem.second; - for (const auto &oldPred : oldBlock->getPredecessors()) { - newBlock->addPredecessor(oldNewBlockMap.at(oldPred)); - } - for (const auto &oldSucc : oldBlock->getSuccessors()) { - newBlock->addSuccessor(oldNewBlockMap.at(oldSucc)); +void Value::removeAllUses() { + while (!uses.empty()) { + auto use = uses.back(); + uses.pop_back(); + if (use && use->getUser()) { + auto user = use->getUser(); + int index = use->getIndex(); + user->removeOperand(index); ///< 从User中移除该操作数 + } else { + // 如果use或user为null,输出警告信息 + assert(use != nullptr && "Use cannot be null"); + assert(use->getUser() != nullptr && "Use's user cannot be null"); } } - - std::map oldNewValueMap; - std::map isAddedToCreate; - std::map isCreated; - std::queue toCreate; - - for (const auto &oldBlock : blocks) { - for (const auto &inst : oldBlock->getInstructions()) { - isAddedToCreate.emplace(inst.get(), false); - isCreated.emplace(inst.get(), false); - } - } - for (const auto &oldBlock : blocks) { - for (const auto &inst : oldBlock->getInstructions()) { - for (const auto &valueUse : inst->getOperands()) { - auto value = valueUse->getValue(); - if (oldNewValueMap.find(value) == oldNewValueMap.end()) { - auto oldAllocInst = dynamic_cast(value); - if (oldAllocInst != nullptr) { - std::vector dims; - // TODO: 这里的dims用type推断 - // for (const auto &dim : oldAllocInst->getDims()) { - // dims.emplace_back(dim->getValue()); - // } - ss << oldAllocInst->getName() << suffix; - auto newAllocInst = - new AllocaInst(oldAllocInst->getType(), oldNewBlockMap.at(oldAllocInst->getParent()), ss.str()); - ss.str(""); - oldNewValueMap.emplace(oldAllocInst, newAllocInst); - if (isAddedToCreate.find(oldAllocInst) == isAddedToCreate.end()) { - isAddedToCreate.emplace(oldAllocInst, true); - } else { - isAddedToCreate.at(oldAllocInst) = true; - } - if (isCreated.find(oldAllocInst) == isCreated.end()) { - isCreated.emplace(oldAllocInst, true); - } else { - isCreated.at(oldAllocInst) = true; - } - } - } - } - if (inst->getKind() == Instruction::kAlloca) { - if (oldNewValueMap.find(inst.get()) == oldNewValueMap.end()) { - auto oldAllocInst = dynamic_cast(inst.get()); - std::vector dims; - // TODO: 这里的dims用type推断 - // for (const auto &dim : oldAllocInst->getDims()) { - // dims.emplace_back(dim->getValue()); - // } - ss << oldAllocInst->getName() << suffix; - auto newAllocInst = - new AllocaInst(oldAllocInst->getType(), oldNewBlockMap.at(oldAllocInst->getParent()), ss.str()); - ss.str(""); - oldNewValueMap.emplace(oldAllocInst, newAllocInst); - if (isAddedToCreate.find(oldAllocInst) == isAddedToCreate.end()) { - isAddedToCreate.emplace(oldAllocInst, true); - } else { - isAddedToCreate.at(oldAllocInst) = true; - } - if (isCreated.find(oldAllocInst) == isCreated.end()) { - isCreated.emplace(oldAllocInst, true); - } else { - isCreated.at(oldAllocInst) = true; - } - } - } - } - } - for (const auto &oldBlock : blocks) { - for (const auto &inst : oldBlock->getInstructions()) { - for (const auto &valueUse : inst->getOperands()) { - auto value = valueUse->getValue(); - if (oldNewValueMap.find(value) == oldNewValueMap.end()) { - auto globalValue = dynamic_cast(value); - auto constVariable = dynamic_cast(value); - auto constantValue = dynamic_cast(value); - auto functionValue = dynamic_cast(value); - if (globalValue != nullptr || constantValue != nullptr || constVariable != nullptr || - functionValue != nullptr) { - if (functionValue == this) { - oldNewValueMap.emplace(value, newFunction); - } else { - oldNewValueMap.emplace(value, value); - } - isCreated.emplace(value, true); - isAddedToCreate.emplace(value, true); - } - } - } - } - } - for (const auto &oldBlock : blocks) { - for (const auto &inst : oldBlock->getInstructions()) { - if (inst->getKind() != Instruction::kAlloca) { - bool isReady = true; - for (const auto &use : inst->getOperands()) { - auto value = use->getValue(); - if (dynamic_cast(value) == nullptr && !isCreated.at(value)) { - isReady = false; - break; - } - } - if (isReady) { - toCreate.push(inst.get()); - isAddedToCreate.at(inst.get()) = true; - } - } - } - } - - while (!toCreate.empty()) { - auto inst = dynamic_cast(toCreate.front()); - toCreate.pop(); - - bool isReady = true; - for (const auto &valueUse : inst->getOperands()) { - auto value = dynamic_cast(valueUse->getValue()); - if (value != nullptr && !isCreated.at(value)) { - isReady = false; - break; - } - } - - if (!isReady) { - toCreate.push(inst); - continue; - } - isCreated.at(inst) = true; - switch (inst->getKind()) { - case Instruction::kAdd: - case Instruction::kSub: - case Instruction::kMul: - case Instruction::kDiv: - case Instruction::kRem: - case Instruction::kICmpEQ: - case Instruction::kICmpNE: - case Instruction::kICmpLT: - case Instruction::kICmpGT: - case Instruction::kICmpLE: - case Instruction::kICmpGE: - case Instruction::kAnd: - case Instruction::kOr: - case Instruction::kFAdd: - case Instruction::kFSub: - case Instruction::kFMul: - case Instruction::kFDiv: - case Instruction::kFCmpEQ: - case Instruction::kFCmpNE: - case Instruction::kFCmpLT: - case Instruction::kFCmpGT: - case Instruction::kFCmpLE: - case Instruction::kFCmpGE: { - auto oldBinaryInst = dynamic_cast(inst); - auto lhs = oldBinaryInst->getLhs(); - auto rhs = oldBinaryInst->getRhs(); - Value *newLhs; - Value *newRhs; - newLhs = oldNewValueMap[lhs]; - newRhs = oldNewValueMap[rhs]; - ss << oldBinaryInst->getName() << suffix; - auto newBinaryInst = new BinaryInst(oldBinaryInst->getKind(), oldBinaryInst->getType(), newLhs, newRhs, - oldNewBlockMap.at(oldBinaryInst->getParent()), ss.str()); - ss.str(""); - oldNewValueMap.emplace(oldBinaryInst, newBinaryInst); - break; - } - - case Instruction::kNeg: - case Instruction::kNot: - case Instruction::kFNeg: - case Instruction::kFNot: - case Instruction::kItoF: - case Instruction::kFtoI: { - auto oldUnaryInst = dynamic_cast(inst); - auto hs = oldUnaryInst->getOperand(); - Value *newHs; - newHs = oldNewValueMap.at(hs); - ss << oldUnaryInst->getName() << suffix; - auto newUnaryInst = new UnaryInst(oldUnaryInst->getKind(), oldUnaryInst->getType(), newHs, - oldNewBlockMap.at(oldUnaryInst->getParent()), ss.str()); - ss.str(""); - oldNewValueMap.emplace(oldUnaryInst, newUnaryInst); - break; - } - - case Instruction::kCall: { - auto oldCallInst = dynamic_cast(inst); - std::vector newArgumnts; - for (const auto &arg : oldCallInst->getArguments()) { - newArgumnts.emplace_back(oldNewValueMap.at(arg->getValue())); - } - - ss << oldCallInst->getName() << suffix; - CallInst *newCallInst; - newCallInst = - new CallInst(oldCallInst->getCallee(), newArgumnts, oldNewBlockMap.at(oldCallInst->getParent()), ss.str()); - ss.str(""); - // if (oldCallInst->getCallee() != this) { - // newCallInst = new CallInst(oldCallInst->getCallee(), newArgumnts, - // oldNewBlockMap.at(oldCallInst->getParent()), - // oldCallInst->getName()); - // } else { - // newCallInst = new CallInst(newFunction, newArgumnts, oldNewBlockMap.at(oldCallInst->getParent()), - // oldCallInst->getName()); - // } - - oldNewValueMap.emplace(oldCallInst, newCallInst); - break; - } - - case Instruction::kCondBr: { - auto oldCondBrInst = dynamic_cast(inst); - auto oldCond = oldCondBrInst->getCondition(); - Value *newCond; - newCond = oldNewValueMap.at(oldCond); - auto newCondBrInst = new CondBrInst(newCond, oldNewBlockMap.at(oldCondBrInst->getThenBlock()), - oldNewBlockMap.at(oldCondBrInst->getElseBlock()), - oldNewBlockMap.at(oldCondBrInst->getParent())); - oldNewValueMap.emplace(oldCondBrInst, newCondBrInst); - break; - } - - case Instruction::kBr: { - auto oldBrInst = dynamic_cast(inst); - auto newBrInst = - new UncondBrInst(oldNewBlockMap.at(oldBrInst->getBlock()), oldNewBlockMap.at(oldBrInst->getParent())); - oldNewValueMap.emplace(oldBrInst, newBrInst); - break; - } - - case Instruction::kReturn: { - auto oldReturnInst = dynamic_cast(inst); - auto oldRval = oldReturnInst->getReturnValue(); - Value *newRval = nullptr; - if (oldRval != nullptr) { - newRval = oldNewValueMap.at(oldRval); - } - auto newReturnInst = - new ReturnInst(newRval, oldNewBlockMap.at(oldReturnInst->getParent()), oldReturnInst->getName()); - oldNewValueMap.emplace(oldReturnInst, newReturnInst); - break; - } - - case Instruction::kAlloca: { - assert(false); - } - - case Instruction::kLoad: { - auto oldLoadInst = dynamic_cast(inst); - auto oldPointer = oldLoadInst->getPointer(); - Value *newPointer; - newPointer = oldNewValueMap.at(oldPointer); - - std::vector newIndices; - // for (const auto &index : oldLoadInst->getIndices()) { - // newIndices.emplace_back(oldNewValueMap.at(index->getValue())); - // } - ss << oldLoadInst->getName() << suffix; - // TODO : 这里的newLoadInst的类型需要根据oldLoadInst的类型来推断 - auto newLoadInst = new LoadInst(newPointer, oldNewBlockMap.at(oldLoadInst->getParent()), ss.str()); - ss.str(""); - oldNewValueMap.emplace(oldLoadInst, newLoadInst); - break; - } - - case Instruction::kStore: { - auto oldStoreInst = dynamic_cast(inst); - auto oldPointer = oldStoreInst->getPointer(); - auto oldValue = oldStoreInst->getValue(); - Value *newPointer; - Value *newValue; - std::vector newIndices; - newPointer = oldNewValueMap.at(oldPointer); - newValue = oldNewValueMap.at(oldValue); - // TODO: 这里的newIndices需要根据oldStoreInst的类型来推断 - // for (const auto &index : oldStoreInst->getIndices()) { - // newIndices.emplace_back(oldNewValueMap.at(index->getValue())); - // } - auto newStoreInst = new StoreInst(newValue, newPointer, - oldNewBlockMap.at(oldStoreInst->getParent()), oldStoreInst->getName()); - oldNewValueMap.emplace(oldStoreInst, newStoreInst); - break; - } - - // TODO:复制GEP指令 - - case Instruction::kMemset: { - auto oldMemsetInst = dynamic_cast(inst); - auto oldPointer = oldMemsetInst->getPointer(); - auto oldValue = oldMemsetInst->getValue(); - Value *newPointer; - Value *newValue; - newPointer = oldNewValueMap.at(oldPointer); - newValue = oldNewValueMap.at(oldValue); - - auto newMemsetInst = new MemsetInst(newPointer, oldMemsetInst->getBegin(), oldMemsetInst->getSize(), newValue, - oldNewBlockMap.at(oldMemsetInst->getParent()), oldMemsetInst->getName()); - oldNewValueMap.emplace(oldMemsetInst, newMemsetInst); - break; - } - - case Instruction::kInvalid: - case Instruction::kPhi: { - break; - } - - default: - assert(false); - } - for (const auto &userUse : inst->getUses()) { - auto user = userUse->getUser(); - if (!isAddedToCreate.at(user)) { - toCreate.push(user); - isAddedToCreate.at(user) = true; - } - } - } - - for (const auto &oldBlock : blocks) { - auto newBlock = oldNewBlockMap.at(oldBlock.get()); - builder.setPosition(newBlock, newBlock->end()); - for (const auto &inst : oldBlock->getInstructions()) { - builder.insertInst(dynamic_cast(oldNewValueMap.at(inst.get()))); - } - } - - // for (const auto ¶m : blocks.front()->getArguments()) { - // newFunction->getEntryBlock()->insertArgument(dynamic_cast(oldNewValueMap.at(param))); - // } - for (const auto &arg : arguments) { - auto newArg = dynamic_cast(oldNewValueMap.at(arg)); - if (newArg != nullptr) { - newFunction->insertArgument(newArg); - } - } - - return newFunction; + uses.clear(); } + /** * 设置操作数 */ -void User::setOperand(unsigned index, Value *value) { - assert(index < getNumOperands()); - operands[index]->setValue(value); - value->addUse(operands[index]); +void User::setOperand(unsigned index, Value *newvalue) { + if (index >= operands.size()) { + std::cerr << "index=" << index << ", but mOperands max size=" << operands.size() << std::endl; + assert(index < operands.size()); + } + std::shared_ptr olduse = operands[index]; + Value *oldValue = olduse->getValue(); + if (oldValue != newvalue) { + // 如果新值和旧值不同,先移除旧值的使用关系 + oldValue->removeUse(olduse); + // 设置新的操作数 + operands[index] = std::make_shared(index, this, newvalue); + newvalue->addUse(operands[index]); + } + else { + // 如果新值和旧值相同,直接更新use的索引 + operands[index]->setValue(newvalue); + } } /** * 替换操作数 @@ -565,29 +233,50 @@ void User::replaceOperand(unsigned index, Value *value) { value->addUse(use); } +/** + * 移除操作数 + */ +void User::removeOperand(unsigned index) { + assert(index < getNumOperands() && "Index out of range in removeOperand"); + std::shared_ptr useToRemove = operands.at(index); + Value *valueToRemove = useToRemove->getValue(); + if(valueToRemove) { + if(valueToRemove == this) { + std::cerr << "Cannot remove operand that is the same as the User itself." << std::endl; + } + valueToRemove->removeUse(useToRemove); + } + operands.erase(operands.begin() + index); + unsigned newIndex = 0; + for(auto it = operands.begin(); it != operands.end(); ++it, ++newIndex) { + (*it)->setIndex(newIndex); // 更新剩余操作数的索引 + } +} + + /** * phi相关函数 */ -Value* PhiInst::getvalfromBlk(BasicBlock* blk) const { - // refreshB2VMap(); +Value* PhiInst::getvalfromBlk(BasicBlock* blk) { + refreshMap(); if( blk2val.find(blk) != blk2val.end()) { return blk2val.at(blk); } return nullptr; } -BasicBlock* PhiInst::getBlkfromVal(Value* val) const { +BasicBlock* PhiInst::getBlkfromVal(Value* val) { // 返回第一个值对应的基本块 for(unsigned i = 0; i < vsize; i++) { - if(getValue(i) == val) { - return getBlock(i); + if(getIncomingValue(i) == val) { + return getIncomingBlock(i); } } return nullptr; } -void PhiInst::delValue(Value* val){ +void PhiInst::removeIncomingValue(Value* val){ //根据value删除对应的基本块和值 unsigned i = 0; BasicBlock* blk = getBlkfromVal(val); @@ -595,17 +284,14 @@ void PhiInst::delValue(Value* val){ return; // 如果val没有对应的基本块,直接返回 } for(i = 0; i < vsize; i++) { - if(getValue(i) == val) { + if(getIncomingValue(i) == val) { break; } } - removeOperand(2 * i + 1); // 删除blk - removeOperand(2 * i); // 删除val - vsize--; - blk2val.erase(blk); // 删除blk2val映射 + removeIncoming(i); } -void PhiInst::delBlk(BasicBlock* blk){ +void PhiInst::removeIncomingBlock(BasicBlock* blk){ //根据Blk删除对应的基本块和值 unsigned i = 0; Value* val = getvalfromBlk(blk); @@ -613,45 +299,48 @@ void PhiInst::delBlk(BasicBlock* blk){ return; // 如果blk没有对应的值,直接返回 } for(i = 0; i < vsize; i++) { - if(getBlock(i) == blk) { + if(getIncomingBlock(i) == blk) { break; } } - removeOperand(2 * i + 1); // 删除blk - removeOperand(2 * i); // 删除val - vsize--; - blk2val.erase(blk); // 删除blk2val映射 + removeIncoming(i); } -void PhiInst::replaceBlk(BasicBlock* newBlk, unsigned k){ - // refreshB2VMap(); - BasicBlock* oldBlk = getBlock(k); - Value* val = blk2val.at(oldBlk); - if(newBlk == oldBlk || oldBlk == nullptr) { - return; // 如果新旧基本块相同,直接返回 - } - // Value* val = blk2val.at(getBlock(k)); - // 替换基本块 - setOperand(2 * k + 1, newBlk); - // 替换blk2val映射 - blk2val.erase(oldBlk); - blk2val.emplace(newBlk, val); +void PhiInst::setIncomingValue(unsigned k, Value* val) { + assert(k < vsize && "PhiInst: index out of range"); + assert(val != nullptr && "PhiInst: value cannot be null"); + refreshMap(); + blk2val.erase(getIncomingBlock(k)); + setOperand(2 * k, val); + blk2val[getIncomingBlock(k)] = val; } -void PhiInst::replaceold2new(BasicBlock* oldBlk, BasicBlock* newBlk){ - // refreshB2VMap(); - Value* val = blk2val.at(oldBlk); - // 替换基本块 - delBlk(oldBlk); +void PhiInst::setIncomingBlock(unsigned k, BasicBlock* blk) { + assert(k < vsize && "PhiInst: index out of range"); + assert(blk != nullptr && "PhiInst: block cannot be null"); + refreshMap(); + auto oldVal = getIncomingValue(k); + blk2val.erase(getIncomingBlock(k)); + setOperand(2 * k + 1, blk); + blk2val[blk] = oldVal; +} + +void PhiInst::replaceIncomingValue(Value* newVal, Value* oldVal) { + refreshMap(); + assert(blk2val.find(getBlkfromVal(oldVal)) != blk2val.end() && "PhiInst: oldVal not found in blk2val"); + auto blk = getBlkfromVal(oldVal); + removeIncomingValue(oldVal); + addIncoming(newVal, blk); +} + +void PhiInst::replaceIncomingBlock(BasicBlock* newBlk, BasicBlock* oldBlk) { + refreshMap(); + assert(blk2val.find(oldBlk) != blk2val.end() && "PhiInst: oldBlk not found in blk2val"); + auto val = blk2val[oldBlk]; + removeIncomingBlock(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 &args, BasicBlock *parent, const std::string &name) : Instruction(kCall, callee->getReturnType(), parent, name) {