[midend]修改use关系相关的函数,使其能自动的正确维护,修改了phi指令的各种接口

This commit is contained in:
rain2133
2025-08-03 22:16:40 +08:00
parent cd814de495
commit d8b004e5e5
3 changed files with 135 additions and 473 deletions

View File

@ -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 引用计数降为0Use 对象本身也会被销毁。
// }
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()); }
};

View File

@ -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) {

View File

@ -182,377 +182,45 @@ auto Function::getCalleesWithNoExternalAndSelf() -> std::set<Function *> {
}
return result;
}
// 函数克隆,后续函数级优化(内联等)需要用到
Function * Function::clone(const std::string &suffix) const {
std::stringstream ss;
std::map<BasicBlock *, BasicBlock *> 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<Value *, Value *> oldNewValueMap;
std::map<Value *, bool> isAddedToCreate;
std::map<Value *, bool> isCreated;
std::queue<Value *> 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<AllocaInst *>(value);
if (oldAllocInst != nullptr) {
std::vector<Value *> 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<AllocaInst *>(inst.get());
std::vector<Value *> 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<GlobalValue *>(value);
auto constVariable = dynamic_cast<ConstantVariable *>(value);
auto constantValue = dynamic_cast<ConstantValue *>(value);
auto functionValue = dynamic_cast<Function *>(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<BasicBlock *>(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<Instruction *>(toCreate.front());
toCreate.pop();
bool isReady = true;
for (const auto &valueUse : inst->getOperands()) {
auto value = dynamic_cast<Instruction *>(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<BinaryInst *>(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<UnaryInst *>(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<CallInst *>(inst);
std::vector<Value *> 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<CondBrInst *>(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<UncondBrInst *>(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<ReturnInst *>(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<LoadInst *>(inst);
auto oldPointer = oldLoadInst->getPointer();
Value *newPointer;
newPointer = oldNewValueMap.at(oldPointer);
std::vector<Value *> 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<StoreInst *>(inst);
auto oldPointer = oldStoreInst->getPointer();
auto oldValue = oldStoreInst->getValue();
Value *newPointer;
Value *newValue;
std::vector<Value *> 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<MemsetInst *>(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<Instruction *>(oldNewValueMap.at(inst.get())));
}
}
// for (const auto &param : blocks.front()->getArguments()) {
// newFunction->getEntryBlock()->insertArgument(dynamic_cast<AllocaInst *>(oldNewValueMap.at(param)));
// }
for (const auto &arg : arguments) {
auto newArg = dynamic_cast<Argument *>(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<Use> olduse = operands[index];
Value *oldValue = olduse->getValue();
if (oldValue != newvalue) {
// 如果新值和旧值不同,先移除旧值的使用关系
oldValue->removeUse(olduse);
// 设置新的操作数
operands[index] = std::make_shared<Use>(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<Use> 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<Value *> &args, BasicBlock *parent, const std::string &name)
: Instruction(kCall, callee->getReturnType(), parent, name) {