[IR]phi指令重构,将block信息加入并提供新方法,后续需更改phi相关指令构建逻辑
This commit is contained in:
77
src/IR.cpp
77
src/IR.cpp
@ -545,6 +545,83 @@ void User::replaceOperand(unsigned index, Value *value) {
|
|||||||
value->addUse(use);
|
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<Value *> &args, BasicBlock *parent, const std::string &name)
|
CallInst::CallInst(Function *callee, const std::vector<Value *> &args, BasicBlock *parent, const std::string &name)
|
||||||
: Instruction(kCall, callee->getReturnType(), parent, name) {
|
: Instruction(kCall, callee->getReturnType(), parent, name) {
|
||||||
addOperand(callee);
|
addOperand(callee);
|
||||||
|
|||||||
@ -755,22 +755,50 @@ class LaInst : public Instruction {
|
|||||||
class PhiInst : public Instruction {
|
class PhiInst : public Instruction {
|
||||||
friend class IRBuilder;
|
friend class IRBuilder;
|
||||||
friend class Function;
|
friend class Function;
|
||||||
friend class SysySSA;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Value *map_val; // Phi的旧值
|
|
||||||
|
|
||||||
PhiInst(Type *type, Value *lhs, const std::vector<Value *> &rhs, Value *mval, BasicBlock *parent,
|
std::unordered_map<BasicBlock *, Value *> blk2val; ///< 存储每个基本块对应的值
|
||||||
|
unsigned vsize; ///< 存储值的数量
|
||||||
|
|
||||||
|
PhiInst(Type *type,
|
||||||
|
const std::vector<Value *> &rhs = {},
|
||||||
|
const std::vector<BasicBlock*> &Blocks = {},
|
||||||
|
BasicBlock *parent,
|
||||||
const std::string &name = "")
|
const std::string &name = "")
|
||||||
: Instruction(Kind::kPhi, type, parent, name) {
|
: Instruction(Kind::kPhi, type, parent, name), vsize(rhs.size()) {
|
||||||
map_val = mval;
|
assert(rhs.size() == Blocks.size() && "PhiInst: rhs and Blocks must have the same size");
|
||||||
addOperand(lhs);
|
for(size_t i = 0; i < rhs.size(); ++i) {
|
||||||
addOperands(rhs);
|
addOperand(rhs[i]);
|
||||||
|
blk2val[Blocks[i]] = rhs[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Value* getMapVal() { return map_val; }
|
Value* getValue(unsigned k) const {return getOperand(2 * k);} ///< 获取位置为k的值
|
||||||
Value* getPointer() const { return getOperand(0); }
|
BasicBlock* getBlock(unsigned k) const {return dynamic_cast<BasicBlock*>(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()); }
|
auto getValues() { return make_range(std::next(operand_begin()), operand_end()); }
|
||||||
Value* getValue(unsigned index) const { return getOperand(index + 1); }
|
Value* getValue(unsigned index) const { return getOperand(index + 1); }
|
||||||
};
|
};
|
||||||
@ -884,7 +912,7 @@ public:
|
|||||||
}
|
}
|
||||||
} ///< 根据指令类型进行二元计算,eval template模板实现
|
} ///< 根据指令类型进行二元计算,eval template模板实现
|
||||||
static BinaryInst* create(Kind kind, Type *type, Value *lhs, Value *rhs, BasicBlock *parent, const std::string &name = "") {
|
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);
|
return new BinaryInst(kind, type, lhs, rhs, parent, name);
|
||||||
}
|
}
|
||||||
}; // class BinaryInst
|
}; // class BinaryInst
|
||||||
|
|||||||
Reference in New Issue
Block a user