方舟编译器分析七——代码分析(第五篇)

2021SC@SDUSC

仍然是老规矩,官方源码献上:

开源代码托管平台

今天和以后的几篇博客将研究分析编译器代码中me体系的me_ir部分,这一部分是me体系中最重要的一部分,因为这部分直接决定了me和ir两个体系的结合,这部分代码将对整个方舟编译器的运行产生至关重要的作用。鉴于此,这部分的代码量极为庞大,分析起来难度也很大,故我可能需要6-9周(按每周一篇的速度)才能将之分析完。目前计划用3篇博客分析其头文件。

我看代码的平台网址如下:

头文件:

src/mapleall/maple_me/include/me_ir.h · 方舟编译器/OpenArkCompiler - Gitee.com

cpp文件:

开源代码托管平台

开头定义了几个类,注释中明确提到,存在循环依赖,别无选择,也就是说这些类之间的关系非常复杂而且缺一不可。按理来说这样的代码并不太好,耦合度太高,出bug的概率很大。但是程序嘛,总是会有各种各样的问题,有的问题甚至要拖很久才能解决,如直到今年9月份新发布的JDK17,才刚刚解决了浮点数运算的问题。所以说这个不太好的地方肯定也是不得已而为之。

namespace maple {

class PhiNode; // circular dependency exists, no other choice

class MeStmt; // circular dependency exists, no other choice

class IRMap; // circular dependency exists, no other choice

class SSATab; // circular dependency exists, no other choice

class VarMeExpr; // circular dependency exists, no other choice

class Dominance; // circular dependency exists, no other choice

using MeStmtPtr = MeStmt*;

enum MeExprOp : uint8 {

kMeOpUnknown,

kMeOpVar,

kMeOpIvar,

kMeOpAddrof,

kMeOpAddroffunc,

kMeOpAddroflabel,

kMeOpGcmalloc,

kMeOpReg,

kMeOpConst,

kMeOpConststr,

kMeOpConststr16,

kMeOpSizeoftype,

kMeOpFieldsDist,

kMeOpOp,

kMeOpNary

}; // cache the op to avoid dynamic cast

 

 这是VarMeExpr and RegMeExpr的基类,定义了这两个类中共同的基础功能,继承自MeExpr 类:

// base class for VarMeExpr and RegMeExpr

class ScalarMeExpr : public MeExpr {

public:

ScalarMeExpr(int32 exprid, OriginalSt *origSt, uint32 vidx, MeExprOp meop, Opcode o, PrimType ptyp)

: MeExpr(exprid, meop, o, ptyp, 0),

ost(origSt),

vstIdx(vidx),

defBy(kDefByNo) {

def.defStmt = nullptr;

}

~ScalarMeExpr() = default;

bool IsIdentical(MeExpr&) const {

CHECK_FATAL(false, "ScalarMeExpr::IsIdentical() should not be called");

return true;

}

bool IsUseSameSymbol(const MeExpr&) const override;

.......(中间是getter和setter,无需多管)

MeStmt *GetDefByMeStmt() const;

BB *GetDefByBBMeStmt(const Dominance&, MeStmtPtr&) const;

void Dump(const IRMap*, int32 indent = 0) const override;

BaseNode &EmitExpr(SSATab&) override;

bool IsSameVariableValue(const VarMeExpr&) const override;

ScalarMeExpr *FindDefByStmt(std::set<ScalarMeExpr*> &visited);

protected:

OriginalSt *ost;

uint32 vstIdx; // the index in MEOptimizer's VersionStTable, 0 if not in VersionStTable

MeDefBy defBy : 3;

union {

MeStmt *defStmt; // definition stmt of this var

MePhiNode *defPhi;

ChiMeNode *defChi; // definition node by Chi

MustDefMeNode *defMustDef; // definition by callassigned

} def;

};

 继承自ScalarMeExpr的类:

下面的两个私有的bool变量会在其不能通过委托人优化的时候值为true

using RegMeExpr = ScalarMeExpr;

// represant dread

class VarMeExpr final : public ScalarMeExpr {

public:

VarMeExpr(int32 exprid, OriginalSt *ost, size_t vidx, PrimType ptyp)

: ScalarMeExpr(exprid, ost, vidx, kMeOpVar, OP_dread, ptyp) {}

~VarMeExpr() = default;

void Dump(const IRMap*, int32 indent = 0) const override;

BaseNode &EmitExpr(SSATab&) override;

bool IsValidVerIdx(const SSATab &ssaTab) const;

bool IsVolatile() const override;

// indicate if the variable is local variable but not a function formal variable

bool IsPureLocal(const MIRFunction&) const;

bool IsZeroVersion() const;

bool IsSameVariableValue(const VarMeExpr&) const override;

VarMeExpr &ResolveVarMeValue();

bool PointsToStringLiteral();

FieldID GetFieldID() const {

return GetOst()->GetFieldID();

}

TyIdx GetInferredTyIdx() const {

return inferredTyIdx;

}

void SetInferredTyIdx(TyIdx inferredTyIdxVal) {

inferredTyIdx = inferredTyIdxVal;

}

bool GetMaybeNull() const {

return maybeNull;

}

void SetMaybeNull(bool maybeNullVal) {

maybeNull = maybeNullVal;

}

bool GetNoDelegateRC() const {

return noDelegateRC;

}

void SetNoDelegateRC(bool noDelegateRCVal) {

noDelegateRC = noDelegateRCVal;

}

bool GetNoSubsumeRC() const {

return noSubsumeRC;

}

void SetNoSubsumeRC(bool noSubsumeRCVal) {

noSubsumeRC = noSubsumeRCVal;

}

MIRType *GetType() const override {

return GlobalTables::GetTypeTable().GetTypeFromTyIdx(ost->GetTyIdx());

}

bool HasAddressValue() override { return GetType()->GetKind() == kTypePointer; }

private:

bool noDelegateRC = false; // true if this cannot be optimized by delegaterc

bool noSubsumeRC = false; // true if this cannot be optimized by subsumrc

TyIdx inferredTyIdx{ 0 }; /* Non zero if it has a known type (allocation type is seen). */

bool maybeNull = true; // false if definitely not null

};

继承自 MeExpr的另一个类:

class ConstMeExpr : public MeExpr {

public:

ConstMeExpr(int32 exprID, MIRConst *constValParam, PrimType t)

: MeExpr(exprID, kMeOpConst, OP_constval, t, 0), constVal(constValParam) {}

~ConstMeExpr() = default;

void Dump(const IRMap*, int32 indent = 0) const override;

BaseNode &EmitExpr(SSATab &) override;

bool GeZero() const;

bool GtZero() const;

bool IsZero() const override;

bool IsOne() const;

int64 GetIntValue() const;

MIRConst *GetConstVal() {

return constVal;

}

MeExpr *GetIdenticalExpr(MeExpr &expr, bool) const override;

uint32 GetHashIndex() const override {

CHECK_FATAL(constVal != nullptr, "constVal is null");

if (constVal->GetKind() == kConstInt) {

auto *intConst = safe_cast<MIRIntConst>(constVal);

CHECK_NULL_FATAL(intConst);

return intConst->GetValue();

}

if (constVal->GetKind() == kConstFloatConst) {

auto *floatConst = safe_cast<MIRFloatConst>(constVal);

CHECK_NULL_FATAL(floatConst);

return floatConst->GetIntValue();

}

if (constVal->GetKind() == kConstDoubleConst) {

auto *doubleConst = safe_cast<MIRDoubleConst>(constVal);

CHECK_NULL_FATAL(doubleConst);

return doubleConst->GetIntValue();

}

if (constVal->GetKind() == kConstLblConst) {

auto *lblConst = safe_cast<MIRLblConst>(constVal);

CHECK_NULL_FATAL(lblConst);

return lblConst->GetValue();

}

ASSERT(false, "ComputeHash: const type not yet implemented");

return 0;

}

private:

MIRConst *constVal;

};

 

 今天的分析就到这里吧,最近事情有点多,先看这么多,剩下的下次再说

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值