diff --git a/src/IR.cpp b/src/IR.cpp index 540f974..5d2765d 100644 --- a/src/IR.cpp +++ b/src/IR.cpp @@ -545,6 +545,83 @@ void User::replaceOperand(unsigned index, Value *value) { value->addUse(use); } +/** + * phi相关函数 + */ + + Value* PhiInst::getvalfromBlk(BasicBlock* blk){ + refreshB2VMap(); + if( blk2val.find(blk) != blk2val.end()) { + return blk2val.at(blk); + } + return nullptr; +} + +BasicBlock* PhiInst::getBlkfromVal(Value* val){ + // 返回第一个值对应的基本块 + for(unsigned i = 0; i < vsize; i++) { + if(getValue(i) == val) { + return getBlock(i); + } + } + return nullptr; +} + +void PhiInst::delValue(Value* val){ + //根据value删除对应的基本块和值 + unsigned i = 0; + BasicBlock* blk = getBlkfromVal(val); + for(i = 0; i < vsize; i++) { + if(getValue(i) == val) { + break; + } + } + removeOperand(2 * i + 1); // 删除blk + removeOperand(2 * i); // 删除val + vsize--; + blk2val.erase(blk); // 删除blk2val映射 +} + +void PhiInst::delBlk(BasicBlock* blk){ + //根据Blk删除对应的基本块和值 + unsigned i = 0; + Value* val = getvalfromBlk(blk); + for(i = 0; i < vsize; i++) { + if(getBlock(i) == blk) { + break; + } + } + removeOperand(2 * i + 1); // 删除blk + removeOperand(2 * i); // 删除val + vsize--; + blk2val.erase(blk); // 删除blk2val映射 +} + +void PhiInst::replaceBlk(BasicBlock* newBlk, unsigned k){ + refreshB2VMap(); + Value* val = blk2val.at(getBlock(k)); + // 替换基本块 + setOperand(2 * k + 1, newBlk); + // 替换blk2val映射 + blk2val.erase(getBlock(k)); + blk2val.emplace(newBlk, val); +} + +void PhiInst::replaceold2new(BasicBlock* oldBlk, BasicBlock* newBlk){ + refreshB2VMap(); + Value* val = blk2val.at(oldBlk); + // 替换基本块 + delBlk(oldBlk); + addIncoming(val, newBlk); +} + +void PhiInst::refreshB2VMap(){ + blk2val.clear(); + for(unsigned i = 0; i < vsize; i++) { + blk2val.emplace(getBlock(i), getValue(i)); + } +} + CallInst::CallInst(Function *callee, const std::vector &args, BasicBlock *parent, const std::string &name) : Instruction(kCall, callee->getReturnType(), parent, name) { addOperand(callee); diff --git a/src/include/IR.h b/src/include/IR.h index 1b4c702..1154d4e 100644 --- a/src/include/IR.h +++ b/src/include/IR.h @@ -755,22 +755,50 @@ class LaInst : public Instruction { class PhiInst : public Instruction { friend class IRBuilder; friend class Function; - friend class SysySSA; protected: - Value *map_val; // Phi的旧值 - PhiInst(Type *type, Value *lhs, const std::vector &rhs, Value *mval, BasicBlock *parent, + std::unordered_map blk2val; ///< 存储每个基本块对应的值 + unsigned vsize; ///< 存储值的数量 + + PhiInst(Type *type, + const std::vector &rhs = {}, + const std::vector &Blocks = {}, + BasicBlock *parent, const std::string &name = "") - : Instruction(Kind::kPhi, type, parent, name) { - map_val = mval; - addOperand(lhs); - addOperands(rhs); + : Instruction(Kind::kPhi, type, parent, name), vsize(rhs.size()) { + assert(rhs.size() == Blocks.size() && "PhiInst: rhs and Blocks must have the same size"); + for(size_t i = 0; i < rhs.size(); ++i) { + addOperand(rhs[i]); + blk2val[Blocks[i]] = rhs[i]; + } } public: - Value* getMapVal() { return map_val; } - Value* getPointer() const { return getOperand(0); } + Value* getValue(unsigned k) const {return getOperand(2 * k);} ///< 获取位置为k的值 + BasicBlock* getBlock(unsigned k) const {return dynamic_cast(getOperand(2 * k + 1));} + + auto& getincomings() const {return blk2val;} ///< 获取所有的基本块和对应的值 + + Value* getvalfromBlk(BasicBlock* blk); + BasicBlock* getBlkfromVal(Value* val); + + unsigned getNumIncomingValues() const { return vsize; } ///< 获取传入值的数量 + void addIncoming(Value *value, BasicBlock *block) { + assert(value && block && "PhiInst: value and block must not be null"); + addOperand(value); + addOperand(block); + blk2val[block] = value; + vsize++; + } ///< 添加传入值和对应的基本块 + + void delValue(Value* val); + void delBlk(BasicBlock* blk); + + void replaceBlk(BasicBlock* newBlk, unsigned k); + void replaceold2new(BasicBlock* oldBlk, BasicBlock* newBlk); + void refreshB2VMap(); + auto getValues() { return make_range(std::next(operand_begin()), operand_end()); } Value* getValue(unsigned index) const { return getOperand(index + 1); } }; @@ -884,7 +912,7 @@ public: } } ///< 根据指令类型进行二元计算,eval template模板实现 static BinaryInst* create(Kind kind, Type *type, Value *lhs, Value *rhs, BasicBlock *parent, const std::string &name = "") { - // 后端处理数组访存操作时需要创建计算地址的指令,需要在外部构造 BinaryInst 对象,所以写了个public的方法。 + // 后端处理数组访存操作时需要创建计算地址的指令,需要在外部构造 BinaryInst 对象 return new BinaryInst(kind, type, lhs, rhs, parent, name); } }; // class BinaryInst