2021SC@SDUSC
还是老规矩,先贴源码:
(接上期博客)今天继续研究该编译器代码的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);
}
}
这部分的代码量大得很,今天先研究这些,剩下的一半下次再研究。