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

2021SC@SDUSC

还是老规矩,先贴源码:

开源代码托管平台https://code.opensource.huaweicloud.com/HarmonyOS/OpenArkCompiler/file?ref=master&path=doc%252FDevelopment_Preparation.md

(接上期博客)今天继续研究该编译器代码的bb部分,此前我说这部分有些困难,我现在发觉我错了,这部分简直难得要死,头文件研究的差不多了,这次研究cpp文件。具体链接如下所示:

src/mapleall/maple_me/src/bb.cpp · 方舟编译器/OpenArkCompiler - Gitee.com

该代码引用的头文件有

#include "bb.h"
#include "mempool_allocator.h"
#include "ver_symbol.h"
#include "me_ssa.h"
#include "me_ir.h"

 其中"bb.h"上期博客中已经提到,其他头文件以后再说。

以下在maple中选择种类并进行赋值:

namespace maple {

std::string BB::StrAttribute() const {

switch (kind) {

case kBBUnknown:

return "unknown";

case kBBCondGoto:

return "condgoto";

case kBBGoto:

return "goto";

case kBBFallthru:

return "fallthru";

case kBBReturn:

return "return";

case kBBAfterGosub:

return "aftergosub";

case kBBSwitch:

return "switch";

case kBBIgoto:

return "igoto";

case kBBInvalid:

return "invalid";

default:

CHECK_FATAL(false, "not yet implemented");

}

return "NYI";

}

 确定bb的属性:

void BB::DumpBBAttribute(const MIRModule *mod) const {

if (GetAttributes(kBBAttrIsEntry)) {

mod->GetOut() << " Entry ";

}

if (GetAttributes(kBBAttrIsExit)) {

mod->GetOut() << " Exit ";

}

if (GetAttributes(kBBAttrWontExit)) {

mod->GetOut() << " WontExit ";

}

if (GetAttributes(kBBAttrIsTry)) {

mod->GetOut() << " Try ";

}

if (GetAttributes(kBBAttrIsTryEnd)) {

mod->GetOut() << " Tryend ";

}

if (GetAttributes(kBBAttrIsJSCatch)) {

mod->GetOut() << " JSCatch ";

}

if (GetAttributes(kBBAttrIsJSFinally)) {

mod->GetOut() << " JSFinally ";

}

if (GetAttributes(kBBAttrIsJavaFinally)) {

mod->GetOut() << " Catch::Finally ";

} else if (GetAttributes(kBBAttrIsCatch)) {

mod->GetOut() << " Catch ";

}

if (GetAttributes(kBBAttrIsInLoop)) {

mod->GetOut() << " InLoop ";

}

}

dump的一些操作:

void BB::DumpHeader(const MIRModule *mod) const {

mod->GetOut() << "============BB id:" << GetBBId() << " " << StrAttribute() << " [";

DumpBBAttribute(mod);

mod->GetOut() << "]===============\n";

mod->GetOut() << "preds: ";

for (const auto &predElement : pred) {

mod->GetOut() << predElement->GetBBId() << " ";

}

mod->GetOut() << "\nsuccs: ";

for (const auto &succElement : succ) {

mod->GetOut() << succElement->GetBBId() << " ";

}

mod->GetOut() << '\n';

if (bbLabel != 0) {

LabelNode lblNode;

lblNode.SetLabelIdx(bbLabel);

lblNode.Dump(0);

mod->GetOut() << '\n';

}

}

void BB::Dump(const MIRModule *mod) {

DumpHeader(mod);

DumpPhi();

for (auto &stmt : stmtNodeList) {

stmt.Dump(1);

}

}

void BB::DumpPhi() {

for (auto &phi : phiList) {

phi.second.Dump();

}

}

 在bb中插入phi:

void BB::InsertPhi(MapleAllocator *alloc, VersionSt *versionSt) {

PhiNode phiNode(*alloc, *versionSt);

for (auto prevIt = pred.begin(); prevIt != pred.end(); ++prevIt) {

phiNode.GetPhiOpnds().push_back(versionSt);

}

(void)phiList.insert(std::make_pair(versionSt->GetOst()->GetIndex(), phiNode));

}

 查看bb是否在list列表中:

bool BB::IsInList(const MapleVector<BB*> &bbList) const {

for (const auto &bb : bbList) {

if (bb == this) {

return true;

}

}

return false;

}

将bb从vector数组中删除:

// remove the given bb from the BB vector bbVec; nothing done if not found

int BB::RemoveBBFromVector(MapleVector<BB*> &bbVec) const {

size_t i = 0;

while (i < bbVec.size()) {

if (bbVec[i] == this) {

break;

}

++i;

}

if (i == bbVec.size()) {

// bb not in the vector

return -1;

}

bbVec.erase(bbVec.cbegin() + i);

return i;

}

 删除指定位置上的phi:

void BB::RemovePhiOpnd(int index) {

for (auto &phi : phiList) {

ASSERT(phi.second.GetPhiOpnds().size() > index, "index out of range in BB::RemovePhiOpnd");

phi.second.GetPhiOpnds().erase(phi.second.GetPhiOpnds().cbegin() + index);

}

for (auto &phi : mePhiList) {

ASSERT(phi.second->GetOpnds().size() > index, "index out of range in BB::RemovePhiOpnd");

phi.second->GetOpnds().erase(phi.second->GetOpnds().cbegin() + index);

}

}

以下两个方法可将bb从pred或succ中删除:

void BB::RemoveBBFromPred(const BB &bb, bool updatePhi) {

int index = bb.RemoveBBFromVector(pred);

ASSERT(index != -1, "-1 is a very large number in BB::RemoveBBFromPred");

if (updatePhi) {

RemovePhiOpnd(index);

}

}

void BB::RemoveBBFromSucc(const BB &bb) {

int ret = bb.RemoveBBFromVector(succ);

if (ret != -1 && frequency != 0 && !succFreq.empty()) {

succFreq.erase(succFreq.cbegin() + ret);

}

}

 这部分的代码量大得很,今天先研究这些,剩下的一半下次再研究。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值