• 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 #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