• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "instrument.h"
17 #include "cgbb.h"
18 #include "mir_builder.h"
19 #include "mpl_logging.h"
20 
21 namespace maple {
GetProfCntSymbolName(const std::string & funcName)22 std::string GetProfCntSymbolName(const std::string &funcName)
23 {
24     return funcName + "_counter";
25 }
26 
RegisterInFuncInfo(MIRFunction & func,const MIRSymbol & counter,uint64 elemCnt,uint32 cfgHash)27 static inline void RegisterInFuncInfo(MIRFunction &func, const MIRSymbol &counter, uint64 elemCnt, uint32 cfgHash)
28 {
29     if (elemCnt == 0) {
30         return;
31     }
32     auto funcStrIdx = GlobalTables::GetStrTable().GetStrIdxFromName(namemangler::kprefixProfFuncDesc + func.GetName());
33     MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(funcStrIdx);
34     CHECK_FATAL(sym, "function have not generated, please check in CreateFuncInfo");
35     auto *funcInfoMirConst = static_cast<MIRAggConst *>(sym->GetKonst());
36     MIRType *u32Ty = GlobalTables::GetTypeTable().GetUInt32();
37     MIRIntConst *cfgHashConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(cfgHash, *u32Ty);
38     MIRIntConst *eleCntMirConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(elemCnt, *u32Ty);
39     auto *counterConst = func.GetModule()->GetMemPool()->New<MIRAddrofConst>(counter.GetStIdx(), 0,
40                                                                              *GlobalTables::GetTypeTable().GetPtr());
41     int num1 = 1;
42     int num2 = 2;
43     int num3 = 3;
44     int num4 = 4;
45     funcInfoMirConst->SetItem(num1, cfgHashConst, num2);
46     funcInfoMirConst->SetItem(num2, eleCntMirConst, num3);
47     funcInfoMirConst->SetItem(num3, counterConst, num4);
48 }
49 
GetOrCreateFuncCounter(MIRFunction & func,uint32 elemCnt,uint32 cfgHash)50 MIRSymbol *GetOrCreateFuncCounter(MIRFunction &func, uint32 elemCnt, uint32 cfgHash)
51 {
52     auto *mirModule = func.GetModule();
53     std::string name = GetProfCntSymbolName(func.GetName());
54     auto nameStrIdx = GlobalTables::GetStrTable().GetStrIdxFromName(name);
55     MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(nameStrIdx);
56     if (sym != nullptr) {
57         return sym;
58     }
59     auto *elemType = GlobalTables::GetTypeTable().GetUInt64();
60     MIRArrayType &arrayType = *GlobalTables::GetTypeTable().GetOrCreateArrayType(*elemType, elemCnt);
61     sym = mirModule->GetMIRBuilder()->CreateGlobalDecl(name.c_str(), arrayType, kScFstatic);
62     auto *profTab = mirModule->GetMemPool()->New<MIRAggConst>(*mirModule, arrayType);
63     MIRIntConst *indexConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(0, *elemType);
64     for (uint32 i = 0; i < elemCnt; ++i) {
65         profTab->AddItem(indexConst, i);
66     }
67     sym->SetKonst(profTab);
68     sym->SetStorageClass(kScFstatic);
69     sym->sectionAttr = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName("mpl_counter");
70     RegisterInFuncInfo(func, *sym, elemCnt, cfgHash);
71     return sym;
72 }
73 
74 template <class IRBB, class Edge>
GetInstrumentBBs(std::vector<IRBB * > & bbs,IRBB * commonEntry) const75 void PGOInstrumentTemplate<IRBB, Edge>::GetInstrumentBBs(std::vector<IRBB *> &bbs, IRBB *commonEntry) const
76 {
77     std::vector<Edge *> iEdges;
78     mst.GetInstrumentEdges(iEdges);
79     std::unordered_set<IRBB *> visitedBBs;
80     for (auto &edge : iEdges) {
81         IRBB *src = edge->GetSrcBB();
82         IRBB *dest = edge->GetDestBB();
83         if (src->GetSuccs().size() <= 1) {
84             if (src == commonEntry) {
85                 bbs.push_back(dest);
86             } else {
87                 bbs.push_back(src);
88             }
89         } else if (!edge->IsCritical()) {
90             bbs.push_back(dest);
91         } else {
92             if (src->GetKind() == IRBB::kBBIgoto) {
93                 if (visitedBBs.find(dest) == visitedBBs.end()) {
94                     // In this case, we have to instrument it anyway
95                     bbs.push_back(dest);
96                     (void)visitedBBs.insert(dest);
97                 }
98             } else {
99                 CHECK_FATAL(false, "Unexpected case %d -> %d", src->GetId(), dest->GetId());
100             }
101         }
102     }
103 }
104 
105 template <typename BB>
GetOnlyUnknownOutEdges()106 BBUseEdge<BB> *BBUseInfo<BB>::GetOnlyUnknownOutEdges()
107 {
108     BBUseEdge<BB> *ouEdge = nullptr;
109     for (auto *e : outEdges) {
110         if (!e->GetStatus()) {
111             CHECK_FATAL(!ouEdge, "have multiple unknown out edges");
112             ouEdge = e;
113         }
114     }
115     return ouEdge;
116 }
117 
118 template <typename BB>
GetOnlyUnknownInEdges()119 BBUseEdge<BB> *BBUseInfo<BB>::GetOnlyUnknownInEdges()
120 {
121     BBUseEdge<BB> *ouEdge = nullptr;
122     for (auto *e : inEdges) {
123         if (!e->GetStatus()) {
124             CHECK_FATAL(!ouEdge, "have multiple unknown in edges");
125             ouEdge = e;
126         }
127     }
128     return ouEdge;
129 }
130 
131 template <typename BB>
Dump()132 void BBUseInfo<BB>::Dump()
133 {
134     for (const auto &inE : inEdges) {
135         if (inE->GetStatus()) {
136             LogInfo::MapleLogger() << inE->GetSrcBB()->GetId() << "->" << inE->GetDestBB()->GetId()
137                                    << " c : " << inE->GetCount() << "\n";
138         }
139     }
140     for (const auto &outE : outEdges) {
141         if (outE->GetStatus()) {
142             LogInfo::MapleLogger() << outE->GetSrcBB()->GetId() << "->" << outE->GetDestBB()->GetId()
143                                    << " c : " << outE->GetCount() << "\n";
144         }
145     }
146 }
147 
148 template class PGOInstrumentTemplate<maplebe::BB, maple::BBEdge<maplebe::BB>>;
149 template class PGOInstrumentTemplate<maplebe::BB, maple::BBUseEdge<maplebe::BB>>;
150 template class BBUseInfo<maplebe::BB>;
151 } /* namespace maple */
152