MIRBuilder的定义和实现代码主要在src/maple_ir/include/mir_builder.h和src/maple_ir/src/mir_builder.cpp。
MIRBuilder是构建很多IR节点所需要的类,它可以构建常量类型节点:
// for creating Expression
ConstvalNode *CreateFloatConst(float val);
ConstvalNode *CreateDoubleConst(double val);
ConstvalNode *CreateFloat128Const(const uint64 *val);
ConstvalNode *GetConstInt(MemPool &memPool, int i);
ConstvalNode *GetConstInt(int i) {
return CreateIntConst(i, PTY_i32);
}
ConstvalNode *GetConstUInt1(bool i) {
return CreateIntConst(i, PTY_u1);
}
ConstvalNode *GetConstUInt8(uint8 i) {
return CreateIntConst(i, PTY_u8);
}
ConstvalNode *GetConstUInt16(uint16 i) {
return CreateIntConst(i, PTY_u16);
}
ConstvalNode *GetConstUInt32(uint32 i) {
return CreateIntConst(i, PTY_u32);
}
ConstvalNode *GetConstUInt64(uint64 i) {
return CreateIntConst(i, PTY_u64);
}
ConstvalNode *GetConstArray(MIRType*, BaseNode*, uint32 length);
ConstvalNode *CreateAddrofConst(BaseNode&);
ConstvalNode *CreateAddroffuncConst(const BaseNode&);
ConstvalNode *CreateStrConst(const BaseNode&);
ConstvalNode *CreateStr16Const(const BaseNode&);
也可以构建表达式节点,另外MIRBuilder还可以构建各种语句节点。
IfStmtNode *CreateStmtIf(BaseNode *cond);
IfStmtNode *CreateStmtIfThenElse(BaseNode *cond);
DoloopNode *CreateStmtDoloop(StIdx, bool, BaseNode*, BaseNode*, BaseNode*);
SwitchNode *CreateStmtSwitch(BaseNode *opnd, LabelIdx defaultLabel, const CaseVector &switchTable);
GotoNode *CreateStmtGoto(Opcode o, LabelIdx labIdx);
JsTryNode *CreateStmtJsTry(Opcode o, LabelIdx cLabIdx, LabelIdx fLabIdx);
TryNode *CreateStmtTry(const MapleVector<LabelIdx> &cLabIdxs);
CatchNode *CreateStmtCatch(const MapleVector<TyIdx> &tyIdxVec);
LabelIdx GetOrCreateMIRLabel(const std::string &name);
LabelIdx CreateLabIdx(MIRFunction &mirfunc);
LabelNode *CreateStmtLabel(LabelIdx labIdx);
StmtNode *CreateStmtComment(const std::string &cmnt);
CondGotoNode *CreateStmtCondGoto(BaseNode *cond, Opcode op, LabelIdx labIdx);
void AddStmtInCurrentFunctionBody(StmtNode &stmt);
MIRSymbol *GetSymbol(TyIdx, const std::string&, MIRSymKind, MIRStorageClass, uint8, bool);
MIRSymbol *GetSymbol(TyIdx, GStrIdx, MIRSymKind, MIRStorageClass, uint8, bool);
MIRSymbol *GetOrCreateSymbol(TyIdx, const std::string&, MIRSymKind, MIRStorageClass, MIRFunction*, uint8, bool);
MIRSymbol *GetOrCreateSymbol(TyIdx, GStrIdx, MIRSymKind, MIRStorageClass, MIRFunction*, uint8, bool);
MIRSymbol *CreatePregFormalSymbol(TyIdx, PregIdx, MIRFunction&);
MIRBuilder还可以构建声明(符号),在此之外,还能构建MIRFcuntion等。也就是说,MAPLE IR中的主要节点,基本上都可以通过MIRBuilder来构建。
MIRBuilder构建一些节点的接口,其实之后还转到了MIRModule去做进一步操作。
LabelNode *MIRBuilder::CreateStmtLabel(LabelIdx labIdx) {
return GetCurrentFuncCodeMp()->New<LabelNode>(labIdx);
}
上面的语句创建了label 语句。其中,GetCurrentFuncCodeMp的实现代码为
MemPool *MIRBuilder::GetCurrentFuncCodeMp() {
return mirModule->CurFuncCodeMemPool();
}
这里已经将操作转到了MIRModule之中。
rc/maple_ir/include/mir_module.h中也有关于CurFunction的实现。
mirModule.CurFuncCodeMemPool(),它获取的是方法在(src/maple_ir/src/mir_module.cpp);
curFunction的定义在(src/maple_ir/include/mir_module.h);
MIRFunction 的GetCodeMempool在(src/maple_ir/include/mir_function.h);
codeMemPool的定义在(src/maple_ir/include/mir_function.h);
所以创建label语句的最终落脚点是MemPool 的New操作(src/mempool/include/mempool.h)。
MIRBuilder和MIRModuler有一个互相对应的关系。MIRBuilder的成员变量有一个,它在构造函数的时候就进行了初始化。
MIRBuilder的一些创建节点的接口,最后都转到了MIRModule之中,通过MIRFunction ,然后最后调用的是MemPool 的New。所以,MIRBuilder的大多数方法,通过MIRModule或者是通过MIRFunction 都可以实现。需要注意的是,这里创建节点,都只是通过MemPool 创建了节点对应的空间,节点的内部内容还需要进一步实现。