Merge branch 'midend' into backend
This commit is contained in:
@@ -202,6 +202,7 @@ class Use {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned getIndex() const { return index; } ///< 返回value在User操作数中的位置
|
unsigned getIndex() const { return index; } ///< 返回value在User操作数中的位置
|
||||||
|
void setIndex(int newIndex) { index = newIndex; } ///< 设置value在User操作数中的位置
|
||||||
User* getUser() const { return user; } ///< 返回使用者
|
User* getUser() const { return user; } ///< 返回使用者
|
||||||
Value* getValue() const { return value; } ///< 返回被使用的值
|
Value* getValue() const { return value; } ///< 返回被使用的值
|
||||||
void setValue(Value *newValue) { value = newValue; } ///< 将被使用的值设置为newValue
|
void setValue(Value *newValue) { value = newValue; } ///< 将被使用的值设置为newValue
|
||||||
@@ -229,7 +230,14 @@ class Value {
|
|||||||
std::list<std::shared_ptr<Use>>& getUses() { return uses; } ///< 获取使用关系列表
|
std::list<std::shared_ptr<Use>>& getUses() { return uses; } ///< 获取使用关系列表
|
||||||
void addUse(const std::shared_ptr<Use> &use) { uses.push_back(use); } ///< 添加使用关系
|
void addUse(const std::shared_ptr<Use> &use) { uses.push_back(use); } ///< 添加使用关系
|
||||||
void replaceAllUsesWith(Value *value); ///< 将原来使用该value的使用者全变为使用给定参数value并修改相应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 being removed does NOT point 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) {}
|
explicit User(Type *type, const std::string &name = "") : Value(type, name) {}
|
||||||
|
|
||||||
public:
|
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(); } ///< 获取操作数数量
|
unsigned getNumOperands() const { return operands.size(); } ///< 获取操作数数量
|
||||||
auto operand_begin() const { return operands.begin(); } ///< 返回操作数列表的开头迭代器
|
auto operand_begin() const { return operands.begin(); } ///< 返回操作数列表的开头迭代器
|
||||||
auto operand_end() const { return operands.end(); } ///< 返回操作数列表的结尾迭代器
|
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));
|
operands.emplace_back(std::make_shared<Use>(operands.size(), this, value));
|
||||||
value->addUse(operands.back());
|
value->addUse(operands.back());
|
||||||
} ///< 增加操作数
|
} ///< 增加操作数
|
||||||
void removeOperand(unsigned index) {
|
void removeOperand(unsigned index);
|
||||||
auto value = getOperand(index);
|
|
||||||
value->removeUse(operands[index]);
|
|
||||||
operands.erase(operands.begin() + index);
|
|
||||||
} ///< 移除操作数
|
|
||||||
template <typename ContainerT>
|
template <typename ContainerT>
|
||||||
void addOperands(const ContainerT &newoperands) {
|
void addOperands(const ContainerT &newoperands) {
|
||||||
for (auto value : newoperands) {
|
for (auto value : newoperands) {
|
||||||
@@ -919,57 +908,54 @@ class PhiInst : public Instruction {
|
|||||||
const std::string &name = "")
|
const std::string &name = "")
|
||||||
: Instruction(Kind::kPhi, type, parent, name), vsize(rhs.size()) {
|
: Instruction(Kind::kPhi, type, parent, name), vsize(rhs.size()) {
|
||||||
assert(rhs.size() == Blocks.size() && "PhiInst: rhs and Blocks must have the same 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(rhs[i]);
|
||||||
|
addOperand(Blocks[i]);
|
||||||
blk2val[Blocks[i]] = rhs[i];
|
blk2val[Blocks[i]] = rhs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
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; } ///< 获取传入值的数量
|
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) {
|
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(value);
|
||||||
addOperand(block);
|
addOperand(block);
|
||||||
blk2val[block] = value;
|
blk2val[block] = value;
|
||||||
vsize++;
|
vsize++;
|
||||||
} ///< 添加传入值和对应的基本块
|
} ///< 添加传入值和对应的基本块
|
||||||
|
void removeIncoming(unsigned Idx) {
|
||||||
void removeIncoming(BasicBlock *block){
|
assert(Idx < vsize && "PhiInst: Index out of bounds");
|
||||||
delBlk(block);
|
auto blk = getIncomingBlock(Idx);
|
||||||
}
|
removeOperand(Idx * 2 + 1); // Remove block
|
||||||
|
removeOperand(Idx * 2); // Remove value
|
||||||
void delValue(Value* val);
|
blk2val.erase(blk);
|
||||||
void delBlk(BasicBlock* blk);
|
vsize--;
|
||||||
|
} ///< 移除指定位置的传入值和对应的基本块
|
||||||
void replaceBlk(BasicBlock* newBlk, unsigned k);
|
// 移除指定的传入值或基本块
|
||||||
void replaceold2new(BasicBlock* oldBlk, BasicBlock* newBlk);
|
void removeIncomingValue(Value *value);
|
||||||
void refreshB2VMap();
|
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 replaceIncomingValue(Value *oldValue, Value *newValue, BasicBlock *newBlock);
|
||||||
|
void replaceIncomingBlock(BasicBlock *oldBlock, BasicBlock *newBlock, Value *newValue);
|
||||||
|
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()); }
|
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) {
|
static void usedelete(Instruction *inst) {
|
||||||
assert(inst && "Instruction to delete cannot be null.");
|
assert(inst && "Instruction to delete cannot be null.");
|
||||||
@@ -75,7 +68,7 @@ public:
|
|||||||
// 步骤3: 物理删除指令
|
// 步骤3: 物理删除指令
|
||||||
// 这会导致 Instruction 对象的 unique_ptr 销毁,从而调用其析构函数链。
|
// 这会导致 Instruction 对象的 unique_ptr 销毁,从而调用其析构函数链。
|
||||||
parentBlock->removeInst(inst);
|
parentBlock->removeInst(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BasicBlock::iterator usedelete(BasicBlock::iterator inst_it) {
|
static BasicBlock::iterator usedelete(BasicBlock::iterator inst_it) {
|
||||||
Instruction *inst_to_delete = inst_it->get();
|
Instruction *inst_to_delete = inst_it->get();
|
||||||
@@ -92,7 +85,7 @@ public:
|
|||||||
|
|
||||||
// 步骤3: 物理删除指令并返回下一个迭代器
|
// 步骤3: 物理删除指令并返回下一个迭代器
|
||||||
return parentBlock->removeInst(inst_it);
|
return parentBlock->removeInst(inst_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断是否是全局变量
|
// 判断是否是全局变量
|
||||||
static bool isGlobal(Value *val) {
|
static bool isGlobal(Value *val) {
|
||||||
|
|||||||
@@ -118,13 +118,45 @@ ArrayType *ArrayType::get(Type *elementType, unsigned numElements) {
|
|||||||
return result.first->get();
|
return result.first->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// void Value::replaceAllUsesWith(Value *value) {
|
||||||
|
// for (auto &use : uses) {
|
||||||
|
// auto user = use->getUser();
|
||||||
|
// assert(user && "Use's user cannot be null");
|
||||||
|
// user->setOperand(use->getIndex(), value);
|
||||||
|
// }
|
||||||
|
// uses.clear();
|
||||||
|
// }
|
||||||
void Value::replaceAllUsesWith(Value *value) {
|
void Value::replaceAllUsesWith(Value *value) {
|
||||||
for (auto &use : uses) {
|
// 1. 创建 uses 列表的副本进行迭代。
|
||||||
use->getUser()->setOperand(use->getIndex(), value);
|
// 这样做是为了避免在迭代过程中,由于 setOperand 间接调用 removeUse 或 addUse
|
||||||
}
|
// 导致原列表被修改,从而引发迭代器失效问题。
|
||||||
uses.clear();
|
std::list<std::shared_ptr<Use>> uses_copy = uses;
|
||||||
}
|
|
||||||
|
|
||||||
|
for (auto &use_ptr : uses_copy) { // 遍历副本
|
||||||
|
// 2. 检查 shared_ptr<Use> 本身是否为空。这是最常见的崩溃原因之一。
|
||||||
|
if (use_ptr == nullptr) {
|
||||||
|
std::cerr << "Warning: Encountered a null std::shared_ptr<Use> in Value::uses list. Skipping this entry." << std::endl;
|
||||||
|
// 在一个健康的 IR 中,这种情况不应该发生。如果经常出现,说明你的 Use 创建或管理有问题。
|
||||||
|
continue; // 跳过空的智能指针
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查 Use 对象内部的 User* 是否为空。
|
||||||
|
User* user_val = use_ptr->getUser();
|
||||||
|
if (user_val == nullptr) {
|
||||||
|
std::cerr << "Warning: Use object (" << use_ptr.get() << ") has a null User* in replaceAllUsesWith. Skipping this entry. This indicates IR corruption." << std::endl;
|
||||||
|
// 同样,在一个健康的 IR 中,Use 对象的 User* 不应该为空。
|
||||||
|
continue; // 跳过用户指针为空的 Use 对象
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果走到这里,use_ptr 和 user_val 都是有效的,可以安全调用 setOperand
|
||||||
|
user_val->setOperand(use_ptr->getIndex(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 处理完所有 use 之后,清空原始的 uses 列表。
|
||||||
|
// replaceAllUsesWith 的目的就是将所有使用关系从当前 Value 转移走,
|
||||||
|
// 所以最后清空列表是正确的。
|
||||||
|
uses.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Implementations for static members
|
// Implementations for static members
|
||||||
|
|
||||||
@@ -182,377 +214,45 @@ auto Function::getCalleesWithNoExternalAndSelf() -> std::set<Function *> {
|
|||||||
}
|
}
|
||||||
return result;
|
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) {
|
void Value::removeAllUses() {
|
||||||
auto oldBlock = oldNewBlockItem.first;
|
while (!uses.empty()) {
|
||||||
auto newBlock = oldNewBlockItem.second;
|
auto use = uses.back();
|
||||||
for (const auto &oldPred : oldBlock->getPredecessors()) {
|
uses.pop_back();
|
||||||
newBlock->addPredecessor(oldNewBlockMap.at(oldPred));
|
if (use && use->getUser()) {
|
||||||
}
|
auto user = use->getUser();
|
||||||
for (const auto &oldSucc : oldBlock->getSuccessors()) {
|
int index = use->getIndex();
|
||||||
newBlock->addSuccessor(oldNewBlockMap.at(oldSucc));
|
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uses.clear();
|
||||||
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 ¶m : 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置操作数
|
* 设置操作数
|
||||||
*/
|
*/
|
||||||
void User::setOperand(unsigned index, Value *value) {
|
void User::setOperand(unsigned index, Value *newvalue) {
|
||||||
assert(index < getNumOperands());
|
if (index >= operands.size()) {
|
||||||
operands[index]->setValue(value);
|
std::cerr << "index=" << index << ", but mOperands max size=" << operands.size() << std::endl;
|
||||||
value->addUse(operands[index]);
|
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 +265,50 @@ void User::replaceOperand(unsigned index, Value *value) {
|
|||||||
value->addUse(use);
|
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相关函数
|
* phi相关函数
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Value* PhiInst::getvalfromBlk(BasicBlock* blk) const {
|
Value* PhiInst::getValfromBlk(BasicBlock* blk) {
|
||||||
// refreshB2VMap();
|
refreshMap();
|
||||||
if( blk2val.find(blk) != blk2val.end()) {
|
if( blk2val.find(blk) != blk2val.end()) {
|
||||||
return blk2val.at(blk);
|
return blk2val.at(blk);
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicBlock* PhiInst::getBlkfromVal(Value* val) const {
|
BasicBlock* PhiInst::getBlkfromVal(Value* val) {
|
||||||
// 返回第一个值对应的基本块
|
// 返回第一个值对应的基本块
|
||||||
for(unsigned i = 0; i < vsize; i++) {
|
for(unsigned i = 0; i < vsize; i++) {
|
||||||
if(getValue(i) == val) {
|
if(getIncomingValue(i) == val) {
|
||||||
return getBlock(i);
|
return getIncomingBlock(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhiInst::delValue(Value* val){
|
void PhiInst::removeIncomingValue(Value* val){
|
||||||
//根据value删除对应的基本块和值
|
//根据value删除对应的基本块和值
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
BasicBlock* blk = getBlkfromVal(val);
|
BasicBlock* blk = getBlkfromVal(val);
|
||||||
@@ -595,62 +316,77 @@ void PhiInst::delValue(Value* val){
|
|||||||
return; // 如果val没有对应的基本块,直接返回
|
return; // 如果val没有对应的基本块,直接返回
|
||||||
}
|
}
|
||||||
for(i = 0; i < vsize; i++) {
|
for(i = 0; i < vsize; i++) {
|
||||||
if(getValue(i) == val) {
|
if(getIncomingValue(i) == val) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removeOperand(2 * i + 1); // 删除blk
|
removeIncoming(i);
|
||||||
removeOperand(2 * i); // 删除val
|
|
||||||
vsize--;
|
|
||||||
blk2val.erase(blk); // 删除blk2val映射
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhiInst::delBlk(BasicBlock* blk){
|
void PhiInst::removeIncomingBlock(BasicBlock* blk){
|
||||||
//根据Blk删除对应的基本块和值
|
//根据Blk删除对应的基本块和值
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
Value* val = getvalfromBlk(blk);
|
Value* val = getValfromBlk(blk);
|
||||||
if(val == nullptr) {
|
if(val == nullptr) {
|
||||||
return; // 如果blk没有对应的值,直接返回
|
return; // 如果blk没有对应的值,直接返回
|
||||||
}
|
}
|
||||||
for(i = 0; i < vsize; i++) {
|
for(i = 0; i < vsize; i++) {
|
||||||
if(getBlock(i) == blk) {
|
if(getIncomingBlock(i) == blk) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removeOperand(2 * i + 1); // 删除blk
|
removeIncoming(i);
|
||||||
removeOperand(2 * i); // 删除val
|
|
||||||
vsize--;
|
|
||||||
blk2val.erase(blk); // 删除blk2val映射
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhiInst::replaceBlk(BasicBlock* newBlk, unsigned k){
|
void PhiInst::setIncomingValue(unsigned k, Value* val) {
|
||||||
// refreshB2VMap();
|
assert(k < vsize && "PhiInst: index out of range");
|
||||||
BasicBlock* oldBlk = getBlock(k);
|
assert(val != nullptr && "PhiInst: value cannot be null");
|
||||||
Value* val = blk2val.at(oldBlk);
|
refreshMap();
|
||||||
if(newBlk == oldBlk || oldBlk == nullptr) {
|
blk2val.erase(getIncomingBlock(k));
|
||||||
return; // 如果新旧基本块相同,直接返回
|
setOperand(2 * k, val);
|
||||||
}
|
blk2val[getIncomingBlock(k)] = val;
|
||||||
// Value* val = blk2val.at(getBlock(k));
|
|
||||||
// 替换基本块
|
|
||||||
setOperand(2 * k + 1, newBlk);
|
|
||||||
// 替换blk2val映射
|
|
||||||
blk2val.erase(oldBlk);
|
|
||||||
blk2val.emplace(newBlk, val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhiInst::replaceold2new(BasicBlock* oldBlk, BasicBlock* newBlk){
|
void PhiInst::setIncomingBlock(unsigned k, BasicBlock* blk) {
|
||||||
// refreshB2VMap();
|
assert(k < vsize && "PhiInst: index out of range");
|
||||||
Value* val = blk2val.at(oldBlk);
|
assert(blk != nullptr && "PhiInst: block cannot be null");
|
||||||
// 替换基本块
|
refreshMap();
|
||||||
delBlk(oldBlk);
|
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);
|
addIncoming(val, newBlk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhiInst::refreshB2VMap(){
|
void PhiInst::replaceIncomingValue(Value *oldValue, Value *newValue, BasicBlock *newBlock) {
|
||||||
blk2val.clear();
|
refreshMap();
|
||||||
for(unsigned i = 0; i < vsize; i++) {
|
assert(blk2val.find(getBlkfromVal(oldValue)) != blk2val.end() && "PhiInst: oldValue not found in blk2val");
|
||||||
blk2val.emplace(getBlock(i), getValue(i));
|
auto oldBlock = getBlkfromVal(oldValue);
|
||||||
}
|
removeIncomingValue(oldValue);
|
||||||
|
addIncoming(newValue, newBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PhiInst::replaceIncomingBlock(BasicBlock *oldBlock, BasicBlock *newBlock, Value *newValue) {
|
||||||
|
refreshMap();
|
||||||
|
assert(blk2val.find(oldBlock) != blk2val.end() && "PhiInst: oldBlock not found in blk2val");
|
||||||
|
auto oldValue = blk2val[oldBlock];
|
||||||
|
removeIncomingBlock(oldBlock);
|
||||||
|
addIncoming(newValue, newBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallInst::CallInst(Function *callee, const std::vector<Value *> &args, BasicBlock *parent, const std::string &name)
|
CallInst::CallInst(Function *callee, const std::vector<Value *> &args, BasicBlock *parent, const std::string &name)
|
||||||
|
|||||||
@@ -148,8 +148,8 @@ void Reg2MemContext::rewritePhis(Function *func) {
|
|||||||
// 1. 为 Phi 指令的每个入边,在前驱块的末尾插入 Store 指令
|
// 1. 为 Phi 指令的每个入边,在前驱块的末尾插入 Store 指令
|
||||||
// PhiInst 假设有 getIncomingValues() 和 getIncomingBlocks()
|
// PhiInst 假设有 getIncomingValues() 和 getIncomingBlocks()
|
||||||
for (unsigned i = 0; i < phiInst->getNumIncomingValues(); ++i) { // 假设 PhiInst 是通过操作数来管理入边的
|
for (unsigned i = 0; i < phiInst->getNumIncomingValues(); ++i) { // 假设 PhiInst 是通过操作数来管理入边的
|
||||||
Value *incomingValue = phiInst->getValue(i); // 获取入值
|
Value *incomingValue = phiInst->getIncomingValue(i); // 获取入值
|
||||||
BasicBlock *incomingBlock = phiInst->getBlock(i); // 获取对应的入块
|
BasicBlock *incomingBlock = phiInst->getIncomingBlock(i); // 获取对应的入块
|
||||||
|
|
||||||
// 在入块的跳转指令之前插入 StoreInst
|
// 在入块的跳转指令之前插入 StoreInst
|
||||||
// 需要找到 incomingBlock 的终结指令 (Terminator Instruction)
|
// 需要找到 incomingBlock 的终结指令 (Terminator Instruction)
|
||||||
|
|||||||
@@ -845,7 +845,7 @@ void SCCPContext::RemovePhiIncoming(BasicBlock *phiParentBB, BasicBlock *removed
|
|||||||
|
|
||||||
for (Instruction *inst : insts_to_check) {
|
for (Instruction *inst : insts_to_check) {
|
||||||
if (auto phi = dynamic_cast<PhiInst *>(inst)) {
|
if (auto phi = dynamic_cast<PhiInst *>(inst)) {
|
||||||
phi->delBlk(removedPred);
|
phi->removeIncomingBlock(removedPred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ bool SysYCFGOptUtils::SysYDelNoPreBLock(Function *func) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 将这个 Phi 节点中来自不可达前驱(unreachableBlock)的输入参数删除
|
// 将这个 Phi 节点中来自不可达前驱(unreachableBlock)的输入参数删除
|
||||||
dynamic_cast<PhiInst *>(phiInstPtr.get())->delBlk(unreachableBlock);
|
dynamic_cast<PhiInst *>(phiInstPtr.get())->removeIncomingBlock(unreachableBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -311,7 +311,7 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
|||||||
// 找到在空块链中导致 currentDefBlock 的那个前驱块
|
// 找到在空块链中导致 currentDefBlock 的那个前驱块
|
||||||
if (emptyBlockRedirectMap.count(incomingBlock) || incomingBlock == currentBlock) {
|
if (emptyBlockRedirectMap.count(incomingBlock) || incomingBlock == currentBlock) {
|
||||||
// 递归追溯该传入值
|
// 递归追溯该传入值
|
||||||
return getUltimateSourceValue(phi->getIncomingValue(incomingBlock), incomingBlock);
|
return getUltimateSourceValue(phi->getValfromBlk(incomingBlock), incomingBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,7 +354,7 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
|||||||
|
|
||||||
if (actualEmptyPredecessorOfS) {
|
if (actualEmptyPredecessorOfS) {
|
||||||
// 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值
|
// 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值
|
||||||
Value *valueFromEmptyPredecessor = phiInst->getIncomingValue(actualEmptyPredecessorOfS);
|
Value *valueFromEmptyPredecessor = phiInst->getValfromBlk(actualEmptyPredecessorOfS);
|
||||||
|
|
||||||
// 追溯这个值,找到它在非空块中的最终来源
|
// 追溯这个值,找到它在非空块中的最终来源
|
||||||
// currentBlock 是 P
|
// currentBlock 是 P
|
||||||
@@ -364,12 +364,13 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
|||||||
|
|
||||||
// 替换 Phi 节点的传入块和传入值
|
// 替换 Phi 节点的传入块和传入值
|
||||||
if (ultimateSourceValue) { // 确保成功追溯到有效来源
|
if (ultimateSourceValue) { // 确保成功追溯到有效来源
|
||||||
phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
// phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||||
|
phiInst->replaceIncomingBlock(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||||
} else {
|
} else {
|
||||||
assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction");
|
assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction");
|
||||||
// 无法追溯到有效来源,这可能是个错误或特殊情况
|
// 无法追溯到有效来源,这可能是个错误或特殊情况
|
||||||
// 此时可能需要移除该 Phi 项,或者插入一个 undef 值
|
// 此时可能需要移除该 Phi 项,或者插入一个 undef 值
|
||||||
phiInst->removeIncoming(actualEmptyPredecessorOfS);
|
phiInst->getValfromBlk(actualEmptyPredecessorOfS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -421,7 +422,7 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
|||||||
|
|
||||||
if (actualEmptyPredecessorOfS) {
|
if (actualEmptyPredecessorOfS) {
|
||||||
// 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值
|
// 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值
|
||||||
Value *valueFromEmptyPredecessor = phiInst->getIncomingValue(actualEmptyPredecessorOfS);
|
Value *valueFromEmptyPredecessor = phiInst->getValfromBlk(actualEmptyPredecessorOfS);
|
||||||
|
|
||||||
// 追溯这个值,找到它在非空块中的最终来源
|
// 追溯这个值,找到它在非空块中的最终来源
|
||||||
// currentBlock 是 P
|
// currentBlock 是 P
|
||||||
@@ -431,12 +432,13 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
|||||||
|
|
||||||
// 替换 Phi 节点的传入块和传入值
|
// 替换 Phi 节点的传入块和传入值
|
||||||
if (ultimateSourceValue) { // 确保成功追溯到有效来源
|
if (ultimateSourceValue) { // 确保成功追溯到有效来源
|
||||||
phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
// phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||||
|
phiInst->replaceIncomingBlock(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||||
} else {
|
} else {
|
||||||
assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction");
|
assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction");
|
||||||
// 无法追溯到有效来源,这可能是个错误或特殊情况
|
// 无法追溯到有效来源,这可能是个错误或特殊情况
|
||||||
// 此时可能需要移除该 Phi 项,或者插入一个 undef 值
|
// 此时可能需要移除该 Phi 项,或者插入一个 undef 值
|
||||||
phiInst->removeIncoming(actualEmptyPredecessorOfS);
|
phiInst->removeIncomingBlock(actualEmptyPredecessorOfS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -481,7 +483,7 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
|||||||
|
|
||||||
if (actualEmptyPredecessorOfS) {
|
if (actualEmptyPredecessorOfS) {
|
||||||
// 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值
|
// 获取 Phi 节点原本从 actualEmptyPredecessorOfS 接收的值
|
||||||
Value *valueFromEmptyPredecessor = phiInst->getIncomingValue(actualEmptyPredecessorOfS);
|
Value *valueFromEmptyPredecessor = phiInst->getValfromBlk(actualEmptyPredecessorOfS);
|
||||||
|
|
||||||
// 追溯这个值,找到它在非空块中的最终来源
|
// 追溯这个值,找到它在非空块中的最终来源
|
||||||
// currentBlock 是 P
|
// currentBlock 是 P
|
||||||
@@ -491,12 +493,13 @@ bool SysYCFGOptUtils::SysYDelEmptyBlock(Function *func, IRBuilder *pBuilder) {
|
|||||||
|
|
||||||
// 替换 Phi 节点的传入块和传入值
|
// 替换 Phi 节点的传入块和传入值
|
||||||
if (ultimateSourceValue) { // 确保成功追溯到有效来源
|
if (ultimateSourceValue) { // 确保成功追溯到有效来源
|
||||||
phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
// phiInst->replaceIncoming(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||||
|
phiInst->replaceIncomingBlock(actualEmptyPredecessorOfS, currentBlock, ultimateSourceValue);
|
||||||
} else {
|
} else {
|
||||||
assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction");
|
assert(false && "[DelEmptyBlock] Unable to trace a valid source for Phi instruction");
|
||||||
// 无法追溯到有效来源,这可能是个错误或特殊情况
|
// 无法追溯到有效来源,这可能是个错误或特殊情况
|
||||||
// 此时可能需要移除该 Phi 项,或者插入一个 undef 值
|
// 此时可能需要移除该 Phi 项,或者插入一个 undef 值
|
||||||
phiInst->removeIncoming(actualEmptyPredecessorOfS);
|
phiInst->removeIncomingBlock(actualEmptyPredecessorOfS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -647,7 +650,7 @@ bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder *pBuilder) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 使用 delBlk 方法删除 basicblock.get() 对应的传入值
|
// 使用 delBlk 方法删除 basicblock.get() 对应的传入值
|
||||||
dynamic_cast<PhiInst *>(phiinst.get())->removeIncoming(basicblock.get());
|
dynamic_cast<PhiInst *>(phiinst.get())->removeIncomingBlock(basicblock.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // cond为false或0
|
} else { // cond为false或0
|
||||||
@@ -665,7 +668,7 @@ bool SysYCFGOptUtils::SysYCondBr2Br(Function *func, IRBuilder *pBuilder) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 使用 delBlk 方法删除 basicblock.get() 对应的传入值
|
// 使用 delBlk 方法删除 basicblock.get() 对应的传入值
|
||||||
dynamic_cast<PhiInst *>(phiinst.get())->removeIncoming(basicblock.get());
|
dynamic_cast<PhiInst *>(phiinst.get())->removeIncomingBlock(basicblock.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,10 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
|
|||||||
this->addPass(&SysYAddReturnPass::ID);
|
this->addPass(&SysYAddReturnPass::ID);
|
||||||
this->run();
|
this->run();
|
||||||
|
|
||||||
|
this->clearPasses();
|
||||||
|
this->addPass(&BuildCFG::ID);
|
||||||
|
this->run();
|
||||||
|
|
||||||
if(DEBUG) {
|
if(DEBUG) {
|
||||||
std::cout << "=== IR After CFGOpt Optimizations ===\n";
|
std::cout << "=== IR After CFGOpt Optimizations ===\n";
|
||||||
printPasses();
|
printPasses();
|
||||||
@@ -119,7 +123,9 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
|
|||||||
std::cout << "=== IR After Reg2Mem Optimizations ===\n";
|
std::cout << "=== IR After Reg2Mem Optimizations ===\n";
|
||||||
printPasses();
|
printPasses();
|
||||||
}
|
}
|
||||||
|
this->clearPasses();
|
||||||
|
this->addPass(&BuildCFG::ID);
|
||||||
|
this->run();
|
||||||
if (DEBUG) std::cout << "--- Custom optimization sequence finished ---\n";
|
if (DEBUG) std::cout << "--- Custom optimization sequence finished ---\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,6 +140,7 @@ void PassManager::runOptimizationPipeline(Module* moduleIR, IRBuilder* builderIR
|
|||||||
SysYPrinter printer(moduleIR);
|
SysYPrinter printer(moduleIR);
|
||||||
printer.printIR();
|
printer.printIR();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PassManager::clearPasses() {
|
void PassManager::clearPasses() {
|
||||||
|
|||||||
@@ -517,9 +517,9 @@ void SysYPrinter::printInst(Instruction *pInst) {
|
|||||||
if (!firstPair) std::cout << ", ";
|
if (!firstPair) std::cout << ", ";
|
||||||
firstPair = false;
|
firstPair = false;
|
||||||
std::cout << "[ ";
|
std::cout << "[ ";
|
||||||
printValue(phiInst->getValue(i));
|
printValue(phiInst->getIncomingValue(i));
|
||||||
std::cout << ", %";
|
std::cout << ", %";
|
||||||
printBlock(phiInst->getBlock(i));
|
printBlock(phiInst->getIncomingBlock(i));
|
||||||
std::cout << " ]";
|
std::cout << " ]";
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user