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 #ifndef MPL2MPL_INCLUDE_CLONE_H 17 #define MPL2MPL_INCLUDE_CLONE_H 18 #include "mir_module.h" 19 #include "mir_function.h" 20 #include "mir_builder.h" 21 #include "mempool.h" 22 #include "mempool_allocator.h" 23 #include "class_hierarchy_phase.h" 24 #include "me_ir.h" 25 #include "maple_phase_manager.h" 26 27 static constexpr char kFullNameStr[] = "INFO_fullname"; 28 static constexpr char kClassNameStr[] = "INFO_classname"; 29 static constexpr char kFuncNameStr[] = "INFO_funcname"; 30 static constexpr char kVoidRetSuffix[] = "CLONEDignoreret"; 31 namespace maple { 32 class ReplaceRetIgnored { 33 public: 34 explicit ReplaceRetIgnored(MemPool *memPool); 35 ~ReplaceRetIgnored() = default; 36 37 bool ShouldReplaceWithVoidFunc(const CallMeStmt &stmt, const MIRFunction &calleeFunc) const; 38 std::string GenerateNewBaseName(const MIRFunction &originalFunc) const; 39 std::string GenerateNewFullName(const MIRFunction &originalFunc) const; GetTobeClonedFuncNames()40 const MapleSet<MapleString> *GetTobeClonedFuncNames() const 41 { 42 return &toBeClonedFuncNames; 43 } 44 IsInCloneList(const std::string & funcName)45 bool IsInCloneList(const std::string &funcName) const 46 { 47 return toBeClonedFuncNames.find(MapleString(funcName, memPool)) != toBeClonedFuncNames.end(); 48 } 49 IsClonedFunc(const std::string & funcName)50 static bool IsClonedFunc(const std::string &funcName) 51 { 52 return funcName.find(kVoidRetSuffix) != std::string::npos; 53 } 54 55 private: 56 MemPool *memPool; 57 maple::MapleAllocator allocator; 58 MapleSet<MapleString> toBeClonedFuncNames; 59 bool RealShouldReplaceWithVoidFunc(Opcode op, size_t nRetSize, const MIRFunction &calleeFunc) const; 60 }; 61 62 class Clone : public AnalysisResult { 63 public: Clone(MIRModule * mod,MemPool * memPool,MIRBuilder & builder,KlassHierarchy * kh)64 Clone(MIRModule *mod, MemPool *memPool, MIRBuilder &builder, KlassHierarchy *kh) 65 : AnalysisResult(memPool), 66 allocator(memPool), 67 mirBuilder(builder), 68 kh(kh), 69 replaceRetIgnored(memPool->New<ReplaceRetIgnored>(memPool)) 70 { 71 } 72 73 ~Clone() = default; 74 75 static MIRSymbol *CloneLocalSymbol(const MIRSymbol &oldSym, const MIRFunction &newFunc); 76 static void CloneSymbols(MIRFunction &newFunc, const MIRFunction &oldFunc); 77 static void CloneLabels(MIRFunction &newFunc, const MIRFunction &oldFunc); 78 MIRFunction *CloneFunction(MIRFunction &originalFunction, const std::string &newBaseFuncName, 79 MIRType *returnType = nullptr) const; 80 MIRFunction *CloneFunctionNoReturn(MIRFunction &originalFunction); 81 void CopyFuncInfo(MIRFunction &originalFunction, MIRFunction &newFunc) const; 82 void UpdateFuncInfo(MIRFunction &newFunc); 83 void CloneArgument(MIRFunction &originalFunction, ArgVector &argument) const; GetReplaceRetIgnored()84 const ReplaceRetIgnored *GetReplaceRetIgnored() const 85 { 86 return replaceRetIgnored; 87 } 88 89 void UpdateReturnVoidIfPossible(CallMeStmt *callMeStmt, const MIRFunction &targetFunc); 90 91 private: 92 MapleAllocator allocator; 93 MIRBuilder &mirBuilder; 94 KlassHierarchy *kh; 95 ReplaceRetIgnored *replaceRetIgnored; 96 }; 97 98 } // namespace maple 99 #endif // MPL2MPL_INCLUDE_CLONE_H 100