• 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 "mir_function.h"
17 #include "printing.h"
18 
19 namespace {
20 using namespace maple;
21 enum FuncProp : uint32_t {
22     kFuncPropHasCall = 1U,                    // the function has call
23 #ifdef ARK_LITECG_DEBUG
24     kFuncPropInfoPrinted = 1U << 3,           // to avoid printing frameSize/moduleid/funcSize info more
25                                               // than once per function since they
26                                               // can only be printed at the beginning of a block
27 #endif
28 };
29 }  // namespace
30 
31 namespace maple {
GetFuncSymbol() const32 const MIRSymbol *MIRFunction::GetFuncSymbol() const
33 {
34     return GlobalTables::GetGsymTable().GetSymbolFromStidx(symbolTableIdx.Idx());
35 }
GetFuncSymbol()36 MIRSymbol *MIRFunction::GetFuncSymbol()
37 {
38     const MIRFunction *mirFunc = const_cast<const MIRFunction *>(this);
39     DEBUG_ASSERT(mirFunc != nullptr, "null ptr check");
40     return const_cast<MIRSymbol *>(mirFunc->GetFuncSymbol());
41 }
42 
GetName() const43 const std::string &MIRFunction::GetName() const
44 {
45     MIRSymbol *mirSymbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(symbolTableIdx.Idx());
46     DEBUG_ASSERT(mirSymbol != nullptr, "null ptr check");
47     return mirSymbol->GetName();
48 }
49 
50 #ifdef ARK_LITECG_DEBUG
GetNameStrIdx() const51 GStrIdx MIRFunction::GetNameStrIdx() const
52 {
53     MIRSymbol *mirSymbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(symbolTableIdx.Idx());
54     DEBUG_ASSERT(mirSymbol != nullptr, "null ptr check");
55     return mirSymbol->GetNameStrIdx();
56 }
57 #endif
58 
GetBaseClassName() const59 const std::string &MIRFunction::GetBaseClassName() const
60 {
61     return GlobalTables::GetStrTable().GetStringFromStrIdx(baseClassStrIdx);
62 }
63 
GetBaseFuncName() const64 const std::string &MIRFunction::GetBaseFuncName() const
65 {
66     return GlobalTables::GetStrTable().GetStringFromStrIdx(baseFuncStrIdx);
67 }
68 
GetReturnType() const69 const MIRType *MIRFunction::GetReturnType() const
70 {
71     CHECK_FATAL(funcType != nullptr, "funcType should not be nullptr");
72     return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx());
73 }
GetReturnType()74 MIRType *MIRFunction::GetReturnType()
75 {
76     return const_cast<MIRType *>(const_cast<const MIRFunction *>(this)->GetReturnType());
77 }
78 
GetNthParamType(size_t i) const79 const MIRType *MIRFunction::GetNthParamType(size_t i) const
80 {
81     CHECK_FATAL(funcType != nullptr, "funcType should not be nullptr");
82     DEBUG_ASSERT(i < funcType->GetParamTypeList().size(), "array index out of range");
83     return GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetParamTypeList()[i]);
84 }
GetNthParamType(size_t i)85 MIRType *MIRFunction::GetNthParamType(size_t i)
86 {
87     return const_cast<MIRType *>(const_cast<const MIRFunction *>(this)->GetNthParamType(i));
88 }
89 
90 // reconstruct formals, and return a new MIRFuncType
ReconstructFormals(const std::vector<MIRSymbol * > & symbols,bool clearOldArgs)91 MIRFuncType *MIRFunction::ReconstructFormals(const std::vector<MIRSymbol *> &symbols, bool clearOldArgs)
92 {
93     auto *newFuncType = static_cast<MIRFuncType *>(funcType->CopyMIRTypeNode());
94     if (clearOldArgs) {
95         formalDefVec.clear();
96         newFuncType->GetParamTypeList().clear();
97         newFuncType->GetParamAttrsList().clear();
98     }
99     for (auto *symbol : symbols) {
100         FormalDef formalDef(symbol->GetNameStrIdx(), symbol, symbol->GetTyIdx(), symbol->GetAttrs());
101         formalDefVec.push_back(formalDef);
102         newFuncType->GetParamTypeList().push_back(symbol->GetTyIdx());
103         newFuncType->GetParamAttrsList().push_back(symbol->GetAttrs());
104     }
105     return newFuncType;
106 }
107 
UpdateFuncTypeAndFormalsAndReturnType(const std::vector<MIRSymbol * > & symbols,const TyIdx & retTyIdx,bool clearOldArgs)108 void MIRFunction::UpdateFuncTypeAndFormalsAndReturnType(const std::vector<MIRSymbol *> &symbols, const TyIdx &retTyIdx,
109                                                         bool clearOldArgs)
110 {
111     auto *newFuncType = ReconstructFormals(symbols, clearOldArgs);
112     newFuncType->SetRetTyIdx(retTyIdx);
113     auto newFuncTypeIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(newFuncType);
114     funcType = static_cast<MIRFuncType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(newFuncTypeIdx));
115     delete newFuncType;
116 }
117 
GetOrCreateLableIdxFromName(const std::string & name)118 LabelIdx MIRFunction::GetOrCreateLableIdxFromName(const std::string &name)
119 {
120     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
121     LabelIdx labelIdx = GetLabelTab()->GetLabelIdxFromStrIdx(strIdx);
122     if (labelIdx == 0) {
123         labelIdx = GetLabelTab()->CreateLabel();
124         GetLabelTab()->SetSymbolFromStIdx(labelIdx, strIdx);
125         GetLabelTab()->AddToStringLabelMap(labelIdx);
126     }
127     return labelIdx;
128 }
129 
HasCall() const130 bool MIRFunction::HasCall() const
131 {
132     return flag & kFuncPropHasCall;
133 }
SetHasCall()134 void MIRFunction::SetHasCall()
135 {
136     flag |= kFuncPropHasCall;
137 }
138 
139 #ifdef ARK_LITECG_DEBUG
IsInfoPrinted() const140 bool MIRFunction::IsInfoPrinted() const
141 {
142     return flag & kFuncPropInfoPrinted;
143 }
144 
SetInfoPrinted()145 void MIRFunction::SetInfoPrinted()
146 {
147     flag |= kFuncPropInfoPrinted;
148 }
149 
ResetInfoPrinted()150 void MIRFunction::ResetInfoPrinted()
151 {
152     flag &= ~kFuncPropInfoPrinted;
153 }
154 
DumpAttributes() const155 void FuncAttrs::DumpAttributes() const
156 {
157 // parse no content of attr
158 #define STRING(s) #s
159 #define FUNC_ATTR
160 #define NOCONTENT_ATTR
161 #define ATTR(AT)                                     \
162     if (GetAttr(FUNCATTR_##AT)) {                    \
163         LogInfo::MapleLogger() << " " << STRING(AT); \
164     }
165 #include "all_attributes.def"
166 #undef ATTR
167 #undef NOCONTENT_ATTR
168 #undef FUNC_ATTR
169     // parse content of attr
170     if (GetAttr(FUNCATTR_alias) && !GetAliasFuncName().empty()) {
171         LogInfo::MapleLogger() << " alias ( \"" << GetAliasFuncName() << "\" )";
172     }
173     if (GetAttr(FUNCATTR_constructor_priority) && GetConstructorPriority() != -1) {
174         LogInfo::MapleLogger() << " constructor_priority ( " << GetConstructorPriority() << " )";
175     }
176     if (GetAttr(FUNCATTR_destructor_priority) && GetDestructorPriority() != -1) {
177         LogInfo::MapleLogger() << " destructor_priority ( " << GetDestructorPriority() << " )";
178     }
179     if (GetAttr(FUNCATTR_frame_pointer) && !framePointer.empty()) {
180         LogInfo::MapleLogger() << " frame-pointer ( " << framePointer << " )";
181     }
182     if (GetAttr(FUNCATTR_frame_reserved_slots) && GetFrameResverdSlot() != 0) {
183         LogInfo::MapleLogger() << " frame-reserved-slots ( " << GetFrameResverdSlot() << " )";
184     }
185 }
186 
DumpFlavorLoweredThanMmpl() const187 void MIRFunction::DumpFlavorLoweredThanMmpl() const
188 {
189     LogInfo::MapleLogger() << " (";
190 
191     // Dump arguments
192     bool hasPrintedFormal = false;
193     for (uint32 i = 0; i < formalDefVec.size(); i++) {
194         MIRSymbol *symbol = formalDefVec[i].formalSym;
195         if (symbol == nullptr &&
196             (formalDefVec[i].formalStrIdx.GetIdx() == 0 ||
197              GlobalTables::GetStrTable().GetStringFromStrIdx(formalDefVec[i].formalStrIdx).empty())) {
198             break;
199         }
200         hasPrintedFormal = true;
201         if (symbol == nullptr) {
202             LogInfo::MapleLogger() << "var %"
203                                    << GlobalTables::GetStrTable().GetStringFromStrIdx(formalDefVec[i].formalStrIdx)
204                                    << " ";
205         } else {
206             if (symbol->GetSKind() != kStPreg) {
207                 LogInfo::MapleLogger() << "var %" << symbol->GetName() << " ";
208             } else {
209                 LogInfo::MapleLogger() << "reg %" << symbol->GetPreg()->GetPregNo() << " ";
210             }
211         }
212         MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDefVec[i].formalTyIdx);
213         constexpr uint8 indent = 2;
214         ty->Dump(indent);
215         if (symbol != nullptr) {
216             symbol->GetAttrs().DumpAttributes();
217         } else {
218             formalDefVec[i].formalAttrs.DumpAttributes();
219         }
220         DEBUG_ASSERT(formalDefVec.size() > 0, "must not be zero");
221         if (i != (formalDefVec.size() - 1)) {
222             LogInfo::MapleLogger() << ", ";
223         }
224     }
225     if (IsVarargs()) {
226         if (!hasPrintedFormal) {
227             LogInfo::MapleLogger() << "...";
228         } else {
229             LogInfo::MapleLogger() << ", ...";
230         }
231     }
232 
233     LogInfo::MapleLogger() << ") ";
234     GetReturnType()->Dump(1);
235 }
236 
Dump(bool withoutBody)237 void MIRFunction::Dump(bool withoutBody)
238 {
239     // skip the functions that are added during process methods in
240     // class and interface decls.  these has nothing in formals
241     // they do have paramtypelist_. this can not skip ones without args
242     // but for them at least the func decls are valid
243     if (GetAttr(FUNCATTR_optimized)) {
244         return;
245     }
246 
247     // save the module's curFunction and set it to the one currently Dump()ing
248     MIRFunction *savedFunc = module->CurFunction();
249     module->SetCurFunction(this);
250 
251     MIRSymbol *symbol = GlobalTables::GetGsymTable().GetSymbolFromStidx(symbolTableIdx.Idx());
252     DEBUG_ASSERT(symbol != nullptr, "symbol MIRSymbol is null");
253     if (!withoutBody) {
254         symbol->GetSrcPosition().DumpLoc(MIRSymbol::LastPrintedLineNumRef(), MIRSymbol::LastPrintedColumnNumRef());
255     }
256     LogInfo::MapleLogger() << "func "
257                            << "&" << symbol->GetName();
258     theMIRModule = module;
259     funcAttrs.DumpAttributes();
260 
261     if (symbol->GetWeakrefAttr().first) {
262         LogInfo::MapleLogger() << " weakref";
263         if (symbol->GetWeakrefAttr().second != UStrIdx(0)) {
264             LogInfo::MapleLogger() << " (";
265             PrintString(GlobalTables::GetUStrTable().GetStringFromStrIdx(symbol->GetWeakrefAttr().second));
266             LogInfo::MapleLogger() << " )";
267         }
268     }
269 
270     if (symbol->sectionAttr != UStrIdx(0)) {
271         LogInfo::MapleLogger() << " section (";
272         PrintString(GlobalTables::GetUStrTable().GetStringFromStrIdx(symbol->sectionAttr));
273         LogInfo::MapleLogger() << " )";
274     }
275 
276     if (module->GetFlavor() != kMmpl) {
277         DumpFlavorLoweredThanMmpl();
278     }
279 
280     // codeMemPool is nullptr, means maple_ir has been released for memory's sake
281     if (codeMemPool == nullptr) {
282         LogInfo::MapleLogger() << '\n';
283     } else if (GetBody() != nullptr && !withoutBody && symbol->GetStorageClass() != kScExtern) {
284         ResetInfoPrinted();  // this ensures funcinfo will be printed
285         GetBody()->Dump(0, module->GetFlavor() == kMmpl ? nullptr : GetSymTab(),
286                         module->GetFlavor() < kMmpl ? GetPregTab() : nullptr, false, true,
287                         module->GetFlavor());  // Dump body
288     } else {
289         LogInfo::MapleLogger() << '\n';
290     }
291 
292     // restore the curFunction
293     module->SetCurFunction(savedFunc);
294 }
295 
DumpUpFormal(int32 indent) const296 void MIRFunction::DumpUpFormal(int32 indent) const
297 {
298     PrintIndentation(indent + 1);
299 
300     LogInfo::MapleLogger() << "upformalsize " << GetUpFormalSize() << '\n';
301     if (localWordsTypeTagged != nullptr) {
302         PrintIndentation(indent + 1);
303         LogInfo::MapleLogger() << "formalWordsTypeTagged = [ ";
304         const auto *p = reinterpret_cast<const uint32 *>(localWordsTypeTagged);
305         LogInfo::MapleLogger() << std::hex;
306         while (p <
307                reinterpret_cast<const uint32 *>(localWordsTypeTagged + BlockSize2BitVectorSize(GetUpFormalSize()))) {
308             LogInfo::MapleLogger() << std::hex << "0x" << *p << " ";
309             ++p;
310         }
311         LogInfo::MapleLogger() << std::dec << "]\n";
312     }
313 
314     if (formalWordsRefCounted != nullptr) {
315         PrintIndentation(indent + 1);
316         LogInfo::MapleLogger() << "formalWordsRefCounted = [ ";
317         const uint32 *p = reinterpret_cast<const uint32 *>(formalWordsRefCounted);
318         LogInfo::MapleLogger() << std::hex;
319         while (p <
320                reinterpret_cast<const uint32 *>(formalWordsRefCounted + BlockSize2BitVectorSize(GetUpFormalSize()))) {
321             LogInfo::MapleLogger() << std::hex << "0x" << *p << " ";
322             ++p;
323         }
324         LogInfo::MapleLogger() << std::dec << "]\n";
325     }
326 }
327 
DumpFrame(int32 indent) const328 void MIRFunction::DumpFrame(int32 indent) const
329 {
330     PrintIndentation(indent + 1);
331 
332     LogInfo::MapleLogger() << "framesize " << static_cast<uint32>(GetFrameSize()) << '\n';
333     if (localWordsTypeTagged != nullptr) {
334         PrintIndentation(indent + 1);
335         LogInfo::MapleLogger() << "localWordsTypeTagged = [ ";
336         const uint32 *p = reinterpret_cast<const uint32 *>(localWordsTypeTagged);
337         LogInfo::MapleLogger() << std::hex;
338         while (p < reinterpret_cast<const uint32 *>(localWordsTypeTagged + BlockSize2BitVectorSize(GetFrameSize()))) {
339             LogInfo::MapleLogger() << std::hex << "0x" << *p << " ";
340             ++p;
341         }
342         LogInfo::MapleLogger() << std::dec << "]\n";
343     }
344 
345     if (localWordsRefCounted != nullptr) {
346         PrintIndentation(indent + 1);
347         LogInfo::MapleLogger() << "localWordsRefCounted = [ ";
348         const uint32 *p = reinterpret_cast<const uint32 *>(localWordsRefCounted);
349         LogInfo::MapleLogger() << std::hex;
350         while (p < reinterpret_cast<const uint32 *>(localWordsRefCounted + BlockSize2BitVectorSize(GetFrameSize()))) {
351             LogInfo::MapleLogger() << std::hex << "0x" << *p << " ";
352             ++p;
353         }
354         LogInfo::MapleLogger() << std::dec << "]\n";
355     }
356 }
357 
DumpFuncBody(int32 indent)358 void MIRFunction::DumpFuncBody(int32 indent)
359 {
360     LogInfo::MapleLogger() << "  funcid " << GetPuidxOrigin() << '\n';
361 
362     if (IsInfoPrinted()) {
363         return;
364     }
365 
366     SetInfoPrinted();
367 
368     if (GetUpFormalSize() > 0) {
369         DumpUpFormal(indent);
370     }
371 
372     if (GetFrameSize() > 0) {
373         DumpFrame(indent);
374     }
375 
376     if (GetOutParmSize() > 0) {
377         PrintIndentation(indent + 1);
378         LogInfo::MapleLogger() << "outparmsize " << GetOutParmSize() << '\n';
379     }
380 
381     if (GetModuleId() > 0) {
382         PrintIndentation(indent + 1);
383         LogInfo::MapleLogger() << "moduleID " << static_cast<uint32>(GetModuleId()) << '\n';
384     }
385 
386     if (GetFuncSize() > 0) {
387         PrintIndentation(indent + 1);
388         LogInfo::MapleLogger() << "funcSize " << GetFuncSize() << '\n';
389     }
390 
391     if (GetInfoVector().empty()) {
392         return;
393     }
394 
395     const MIRInfoVector &funcInfo = GetInfoVector();
396     const MapleVector<bool> &funcInfoIsString = InfoIsString();
397     PrintIndentation(indent + 1);
398     LogInfo::MapleLogger() << "funcinfo {\n";
399     size_t size = funcInfo.size();
400     constexpr int kIndentOffset = 2;
401     for (size_t i = 0; i < size; ++i) {
402         PrintIndentation(indent + kIndentOffset);
403         LogInfo::MapleLogger() << "@" << GlobalTables::GetStrTable().GetStringFromStrIdx(funcInfo[i].first) << " ";
404         if (!funcInfoIsString[i]) {
405             LogInfo::MapleLogger() << funcInfo[i].second;
406         } else {
407             LogInfo::MapleLogger() << "\""
408                                    << GlobalTables::GetStrTable().GetStringFromStrIdx(GStrIdx(funcInfo[i].second))
409                                    << "\"";
410         }
411         if (i < size - 1) {
412             LogInfo::MapleLogger() << ",\n";
413         } else {
414             LogInfo::MapleLogger() << "}\n";
415         }
416     }
417     LogInfo::MapleLogger() << '\n';
418 }
419 #endif
420 
GetLocalOrGlobalSymbol(const StIdx & idx,bool checkFirst) const421 const MIRSymbol *MIRFunction::GetLocalOrGlobalSymbol(const StIdx &idx, bool checkFirst) const
422 {
423     return idx.Islocal() ? GetSymbolTabItem(idx.Idx(), checkFirst)
424                          : GlobalTables::GetGsymTable().GetSymbolFromStidx(idx.Idx(), checkFirst);
425 }
GetLocalOrGlobalSymbol(const StIdx & idx,bool checkFirst)426 MIRSymbol *MIRFunction::GetLocalOrGlobalSymbol(const StIdx &idx, bool checkFirst)
427 {
428     DEBUG_ASSERT(const_cast<MIRSymbol *>(const_cast<const MIRFunction *>(this)->
429                  GetLocalOrGlobalSymbol(idx, checkFirst)) != nullptr,
430                  "this->GetLocalOrGlobalSymbol(idx, checkFirst) should not be nullptr");
431     return const_cast<MIRSymbol *>(const_cast<const MIRFunction *>(this)->GetLocalOrGlobalSymbol(idx, checkFirst));
432 }
433 
EnterFormals()434 void MIRFunction::EnterFormals()
435 {
436     for (auto &formalDef : formalDefVec) {
437         formalDef.formalSym = symTab->CreateSymbol(kScopeLocal);
438         formalDef.formalSym->SetStorageClass(kScFormal);
439         formalDef.formalSym->SetNameStrIdx(formalDef.formalStrIdx);
440         formalDef.formalSym->SetTyIdx(formalDef.formalTyIdx);
441         formalDef.formalSym->SetAttrs(formalDef.formalAttrs);
442         const std::string &formalName = GlobalTables::GetStrTable().GetStringFromStrIdx(formalDef.formalStrIdx);
443         if (!isdigit(formalName.front())) {
444             formalDef.formalSym->SetSKind(kStVar);
445             (void)symTab->AddToStringSymbolMap(*formalDef.formalSym);
446         } else {
447             formalDef.formalSym->SetSKind(kStPreg);
448             uint32 thepregno = static_cast<uint32>(std::stoi(formalName));
449             MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx);
450             PrimType pType = mirType->GetPrimType();
451             // if mirType info is not needed, set mirType to nullptr
452             if (pType != PTY_ref && pType != PTY_ptr) {
453                 mirType = nullptr;
454             } else if (pType == PTY_ptr && mirType->IsMIRPtrType()) {
455                 MIRType *pointedType = static_cast<MIRPtrType *>(mirType)->GetPointedType();
456                 if (pointedType == nullptr || pointedType->GetKind() != kTypeFunction) {
457                     mirType = nullptr;
458                 }
459             }
460             PregIdx pregIdx = pregTab->EnterPregNo(thepregno, pType, mirType);
461             MIRPreg *preg = pregTab->PregFromPregIdx(pregIdx);
462             formalDef.formalSym->SetPreg(preg);
463         }
464     }
465 }
466 
NewBody()467 void MIRFunction::NewBody()
468 {
469     codeMemPool = GetCodeMemPool();
470     SetBody(codeMemPool->New<BlockNode>());
471     SetLastPosBody(codeMemPool->New<BlockNode>());
472     // If mir_function.has been seen as a declaration, its symtab has to be moved
473     // from module mempool to function mempool.
474     MIRSymbolTable *oldSymTable = GetSymTab();
475     MIRPregTable *oldPregTable = GetPregTab();
476     MIRTypeNameTable *oldTypeNameTable = typeNameTab;
477     MIRLabelTable *oldLabelTable = GetLabelTab();
478     symTab = module->GetMemPool()->New<MIRSymbolTable>(module->GetMPAllocator());
479     pregTab = module->GetMemPool()->New<MIRPregTable>(&module->GetMPAllocator());
480     typeNameTab = module->GetMemPool()->New<MIRTypeNameTable>(module->GetMPAllocator());
481     labelTab = module->GetMemPool()->New<MIRLabelTable>(module->GetMPAllocator());
482 
483     if (oldSymTable == nullptr) {
484         // formals not yet entered into symTab; enter them now
485         EnterFormals();
486     } else {
487         for (size_t i = 1; i < oldSymTable->GetSymbolTableSize(); ++i) {
488             (void)GetSymTab()->AddStOutside(oldSymTable->GetSymbolFromStIdx(i));
489         }
490     }
491     if (oldPregTable != nullptr) {
492         for (size_t i = 1; i < oldPregTable->Size(); ++i) {
493             (void)GetPregTab()->AddPreg(*oldPregTable->PregFromPregIdx(static_cast<PregIdx>(i)));
494         }
495     }
496     if (oldTypeNameTable != nullptr) {
497         DEBUG_ASSERT(oldTypeNameTable->Size() == typeNameTab->Size(),
498                      "Does not expect to process typeNameTab in MIRFunction::NewBody");
499     }
500     if (oldLabelTable != nullptr) {
501         DEBUG_ASSERT(oldLabelTable->Size() == GetLabelTab()->Size(),
502                      "Does not expect to process labelTab in MIRFunction::NewBody");
503     }
504 }
505 }  // namespace maple
506