其他分享
首页 > 其他分享> > 方舟编译器分析六——代码分析(第四篇)

方舟编译器分析六——代码分析(第四篇)

作者:互联网

 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

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

 上期博客分析了bb代码的上半部分,代码量实在有些大,我就在此分析下半部分。

这部分代码可以获得pred的索引位置:

int BB::GetPredIndex(const BB &predBB) {

int i = 0;

while (i < pred.size()) {

if (pred[i] == &predBB) {

break;

}

++i;

}

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

// bb not in the vector

return -1;

}

return i;

}

向StmtNode中添加指定数据:

// add stmtnode to bb and update first_stmt_ and last_stmt_

void BB::AddStmtNode(StmtNode *stmt) {

CHECK_FATAL(stmt != nullptr, "null ptr check");

stmtNodeList.push_back(stmt);

}

如果 bb 只包含评论以外的一个 stmt,则返回该 stmt ,否则返回 nullptr  :

StmtNode *BB::GetTheOnlyStmtNode() {

StmtNode *onlyStmtNode = nullptr;

for (auto &stmtNode : stmtNodeList) {

if (stmtNode.GetOpCode() == OP_comment) {

continue;

}

if (onlyStmtNode != nullptr) {

return nullptr;

}

onlyStmtNode = &stmtNode;

}

return onlyStmtNode;

}

移除指定stmtNode中的数据(如果其不在bb中则会出现错误):

void BB::RemoveStmtNode(StmtNode *stmt) {

CHECK_FATAL(stmt != nullptr, "null ptr check");

stmtNodeList.erase(StmtNodes::iterator(stmt));

}

 插入、替换和移除最后一个节点:

void BB::InsertStmtBefore(StmtNode *stmt, StmtNode *newStmt) {

CHECK_FATAL(newStmt != nullptr, "null ptr check");

CHECK_FATAL(stmt != nullptr, "null ptr check");

stmtNodeList.insert(stmt, newStmt);

}

void BB::ReplaceStmt(StmtNode *stmt, StmtNode *newStmt) {

InsertStmtBefore(stmt, newStmt);

RemoveStmtNode(stmt);

}

// delete last_stmt_ and update

void BB::RemoveLastStmt() {

stmtNodeList.pop_back();

}

 用新的bb替换pred:

void BB::ReplacePred(const BB *old, BB *newPred) {

ASSERT((old != nullptr && newPred != nullptr), "Nullptr check.");

ASSERT((old->IsInList(pred) && IsInList(old->succ)), "Nullptr check.");

for (auto &predElement : pred) {

if (predElement == old) {

predElement->RemoveBBFromSucc(*this);

if (IsInList(newPred->succ)){

RemoveBBFromPred(*predElement, true);

} else {

newPred->succ.push_back(this);

predElement = newPred;

}

break;

}

}

}

移除全部pred:

void BB::MoveAllPredToSucc(BB *newSucc, BB *commonEntry) {

ASSERT_NOT_NULL(newSucc);

if (GetAttributes(kBBAttrIsEntry)) {

ASSERT(IsSuccBB(*commonEntry), "BB is not in commonEntry's successors, but it is set kBBAttrIsEntry");

commonEntry->RemoveEntry(*this);

commonEntry->AddEntry(*newSucc);

newSucc->SetAttributes(kBBAttrIsEntry);

} else {

while (!GetPred().empty()) {

BB *firstPred = GetPred(0);

if (IsSuccBB(*firstPred)) { // avoid replacing twice

firstPred->ReplaceSucc(this, newSucc, true); // firstPred will be removed from this->pred

}

}

}

}

 替换succ:

void BB::ReplaceSucc(const BB *old, BB *newSucc, bool updatePhi) {

ASSERT((old != nullptr && newSucc != nullptr), "Nullptr check.");

ASSERT((old->IsInList(succ) && IsInList(old->pred)), "Nullptr check.");

for (auto &succElement : succ) {

if (succElement == old) {

succElement->RemoveBBFromPred(*this, updatePhi);

if (IsInList(newSucc->pred)) {

RemoveBBFromSucc(*succElement);

} else {

newSucc->pred.push_back(this);

succElement = newSucc;

}

break;

}

}

}

 这次的分析差不多就到这里了,我的水平也不高,难以说的非常透彻,希望有大佬能够指正。

标签:old,BB,pred,newSucc,nullptr,stmt,编译器,方舟,第四篇
来源: https://blog.csdn.net/weixin_46915587/article/details/120978576