2021SC@SDUSC
这篇博客承接上面几篇,这几篇博客要研究分析编译器代码中me体系的me_ir部分,这一部分是me体系中最重要的一部分,因为这部分直接决定了me和ir两个体系的结合,这部分代码将对整个方舟编译器的运行产生至关重要的作用。同时,这部分的代码量极为庞大,分析起来难度也很大,故我可能需要6-9周(按每周一篇的速度)才能将之分析完。
今天的重点是MeExpr及其相关内容。
MeExpr定义及实现在src/maple_me/include/me_ir.h和src/maple_me/src/me_ir.cpp中。
Me的MeExprOp(Me表达式操作符)可以分为以下几种(src/maple_me/include/me_ir.h):
enum MeExprOp : std::uint8_t {
kMeOpUnknown,
kMeOpVar,
kMeOpIvar,
kMeOpAddrof,
kMeOpAddroffunc,
kMeOpGcmalloc,
kMeOpReg,
kMeOpConst,
kMeOpConststr,
kMeOpConststr16,
kMeOpSizeoftype,
kMeOpFieldsDist,
kMeOpOp,
kMeOpNary,
}; // cache the op to avoid dynamic cast
这部分内容,和MAPLE IR DESIGN文档中的Leaf Opcodes部分内容有部分相关性。Leaf Opcodes有addrof、addroffunc、constval、conststr、conststr16和sizeoftype。
MeExprOp之中的每个类别(除了kMeOpUnknown之外),都有一个对应的类,这些类都是MeExpr类的子类。具体代码为(src/maple_me/src/me_ir.cpp):
class MeExpr {
public:
MeExpr(int32 exprid, MeExprOp o)
: op(kOpUndef), primType(kPtyInvalid), numOpnds(0), meOp(o), exprID(exprid), depth(0),
treeID(0), next(nullptr) {}
virtual ~MeExpr() = default;
...
// represant dread
class VarMeExpr : public MeExpr {
...
class RegMeExpr : public MeExpr {
...
class ConstMeExpr : public MeExpr {
...
class ConststrMeExpr : public MeExpr {
...
class Conststr16MeExpr : public MeExpr {
...
class SizeoftypeMeExpr : public MeExpr {
...
class FieldsDistMeExpr : public MeExpr {
...
class AddrofMeExpr : public MeExpr {
...
class AddroffuncMeExpr : public MeExpr {
...
class GcmallocMeExpr : public MeExpr {
...
class OpMeExpr : public MeExpr {
...
class IvarMeExpr : public MeExpr {
...
// for array, intrinsicop and intrinsicopwithtype
class NaryMeExpr : public MeExpr {
根据其中的注释,VarMeExpr 是为了表达dread,dread也是Leaf Opcode。NaryMeExpr是为了表达array、intrinsicop和intrinsicopwithtype,它们是N-ary Expression Opcodes。
节点类和Me表达式类的对应:之前方舟编译器学习笔记31 介绍的表达式对应的节点,主要是针对Expression nodes,并没有覆盖针对Leaf nodes的内容,所以并没有和操作符对应的节点类来和Me的表达式类进相对应的内容。但是,这里面NaryMeExpr是个例外,它是为了表达array、intrinsicop和intrinsicopwithtype;array、intrinsicop和intrinsicopwithtype属于N-ary Expression Opcodes,它们有对应的节点类。其中,array对应节点类ArrayNode,intrinsicop和intrinsicopwithtype对应节点类IntrinsicopNode,它们都是NaryNode的子类。这里只是一个对应关系,具体执行过程之中的流程和细节,还要进一步分析。
MeExpr及其子类的成员函数相对都较为简单,除了相关的内容的set/get之外,主要是一些判定、dump,还有一些极个别的其他操作。
总结:
经过我们陆续几天的分析,我们可以看到在IR之中,Me是有一套自己的体系的。我们几天涉及到的MeFunction、BB、MeStmt、MeExpr都是这个体系的一部分。而我们之前分析过的MIRModule、MIRFunction、Node体系,这是一个体系,这个体系的声明周期要比Me的体系要靠前一些。