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_SIMPLIFY_H 17 #define MPL2MPL_INCLUDE_SIMPLIFY_H 18 #include "phase_impl.h" 19 #include "factory.h" 20 #include "maple_phase_manager.h" 21 namespace maple { 22 23 const std::map<std::string, std::string> asmMap = { 24 #include "asm_map.def" 25 }; 26 27 enum ErrorNumber { 28 ERRNO_OK = EOK, 29 ERRNO_INVAL = EINVAL, 30 ERRNO_RANGE = ERANGE, 31 ERRNO_INVAL_AND_RESET = EINVAL_AND_RESET, 32 ERRNO_RANGE_AND_RESET = ERANGE_AND_RESET, 33 ERRNO_OVERLAP_AND_RESET = EOVERLAP_AND_RESET 34 }; 35 36 enum MemOpKind { MEM_OP_unknown, MEM_OP_memset, MEM_OP_memcpy, MEM_OP_memset_s, MEM_OP_memcpy_s }; 37 38 // MemEntry models a memory entry with high level type information. 39 struct MemEntry { 40 enum MemEntryKind { kMemEntryUnknown, kMemEntryPrimitive, kMemEntryStruct, kMemEntryArray }; 41 42 static bool ComputeMemEntry(BaseNode &expr, MIRFunction &func, MemEntry &memEntry, bool isLowLevel); 43 MemEntry() = default; MemEntryMemEntry44 MemEntry(BaseNode *addrExpr, MIRType *memType) : addrExpr(addrExpr), memType(memType) {} 45 GetKindMemEntry46 MemEntryKind GetKind() const 47 { 48 if (memType == nullptr) { 49 return kMemEntryUnknown; 50 } 51 auto typeKind = memType->GetKind(); 52 if (typeKind == kTypeScalar || typeKind == kTypePointer) { 53 return kMemEntryPrimitive; 54 } else if (typeKind == kTypeArray) { 55 return kMemEntryArray; 56 } else if (memType->IsStructType()) { 57 return kMemEntryStruct; 58 } 59 return kMemEntryUnknown; 60 } 61 62 BaseNode *BuildAsRhsExpr(MIRFunction &func) const; 63 bool ExpandMemset(int64 byte, uint64 size, MIRFunction &func, StmtNode &stmt, BlockNode &block, bool isLowLevel, 64 bool debug, ErrorNumber errorNumber) const; 65 void ExpandMemsetLowLevel(int64 byte, uint64 size, MIRFunction &func, StmtNode &stmt, BlockNode &block, 66 MemOpKind memOpKind, bool debug, ErrorNumber errorNumber) const; 67 bool ExpandMemcpy(const MemEntry &srcMem, uint64 copySize, MIRFunction &func, StmtNode &stmt, BlockNode &block, 68 bool isLowLevel, bool debug, ErrorNumber errorNumber) const; 69 void ExpandMemcpyLowLevel(const MemEntry &srcMem, uint64 copySize, MIRFunction &func, StmtNode &stmt, 70 BlockNode &block, MemOpKind memOpKind, bool debug, ErrorNumber errorNumber) const; 71 static StmtNode *GenMemopRetAssign(StmtNode &stmt, MIRFunction &func, bool isLowLevel, MemOpKind memOpKind, 72 ErrorNumber errorNumber = ERRNO_OK); 73 74 BaseNode *addrExpr = nullptr; // memory address 75 MIRType *memType = nullptr; // memory type, this may be nullptr for low level memory entry 76 }; 77 78 // For simplifying memory operation, either memset or memcpy/memmove. 79 class SimplifyMemOp { 80 public: 81 static MemOpKind ComputeMemOpKind(StmtNode &stmt); 82 SimplifyMemOp() = default; 83 virtual ~SimplifyMemOp() = default; func(func)84 explicit SimplifyMemOp(MIRFunction *func, bool debug = false) : func(func), debug(debug) {} SetFunction(MIRFunction * f)85 void SetFunction(MIRFunction *f) 86 { 87 func = f; 88 } SetDebug(bool dbg)89 void SetDebug(bool dbg) 90 { 91 debug = dbg; 92 } 93 94 bool AutoSimplify(StmtNode &stmt, BlockNode &block, bool isLowLevel); 95 bool SimplifyMemset(StmtNode &stmt, BlockNode &block, bool isLowLevel); 96 bool SimplifyMemcpy(StmtNode &stmt, BlockNode &block, bool isLowLevel); 97 98 private: 99 StmtNode *PartiallyExpandMemsetS(StmtNode &stmt, BlockNode &block); 100 101 static const uint32 thresholdMemsetExpand; 102 static const uint32 thresholdMemsetSExpand; 103 static const uint32 thresholdMemcpyExpand; 104 static const uint32 thresholdMemcpySExpand; 105 MIRFunction *func = nullptr; 106 bool debug = false; 107 }; 108 109 class Simplify : public FuncOptimizeImpl { 110 public: Simplify(MIRModule & mod,KlassHierarchy * kh,bool dump)111 Simplify(MIRModule &mod, KlassHierarchy *kh, bool dump) : FuncOptimizeImpl(mod, kh, dump), mirMod(mod) {} 112 Simplify(const Simplify &other) = delete; 113 Simplify &operator=(const Simplify &other) = delete; 114 ~Simplify() = default; Clone()115 FuncOptimizeImpl *Clone() override 116 { 117 CHECK_FATAL(false, "Simplify has pointer, should not be Cloned"); 118 } 119 120 void ProcessStmt(StmtNode &stmt) override; 121 void Finish() override; 122 123 private: 124 MIRModule &mirMod; 125 SimplifyMemOp simplifyMemOp; 126 bool IsMathSqrt(const std::string funcName); 127 bool IsMathAbs(const std::string funcName); 128 bool IsMathMin(const std::string funcName); 129 bool IsMathMax(const std::string funcName); 130 bool IsSymbolReplaceableWithConst(const MIRSymbol &symbol) const; 131 bool IsConstRepalceable(const MIRConst &mirConst) const; 132 bool SimplifyMathMethod(const StmtNode &stmt, BlockNode &block); 133 void SimplifyCallAssigned(StmtNode &stmt, BlockNode &block); 134 StmtNode *SimplifyToSelect(MIRFunction *func, IfStmtNode *ifNode, BlockNode *block); 135 BaseNode *SimplifyExpr(BaseNode &expr); 136 BaseNode *ReplaceExprWithConst(DreadNode &dread); 137 MIRConst *GetElementConstFromFieldId(FieldID fieldId, MIRConst *mirConst); 138 }; 139 140 } // namespace maple 141 #endif // MPL2MPL_INCLUDE_SIMPLIFY_H 142