• 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_const.h"
17 #include "mir_function.h"
18 #include "printing.h"
19 #include <iomanip>
20 
21 #if MIR_FEATURE_FULL
22 
23 namespace maple {
24 #ifdef ARK_LITECG_DEBUG
Dump(const MIRSymbolTable *) const25 void MIRIntConst::Dump(const MIRSymbolTable *) const
26 {
27     LogInfo::MapleLogger() << value;
28 }
29 #endif
30 
operator ==(const MIRConst & rhs) const31 bool MIRIntConst::operator==(const MIRConst &rhs) const
32 {
33     if (&rhs == this) {
34         return true;
35     }
36     if (GetKind() != rhs.GetKind()) {
37         return false;
38     }
39     const auto &intConst = static_cast<const MIRIntConst &>(rhs);
40     return ((&intConst.GetType() == &GetType()) && (intConst.value == value));
41 }
42 
43 #ifdef ARK_LITECG_DEBUG
GetActualBitWidth() const44 uint8 MIRIntConst::GetActualBitWidth() const
45 {
46     if (value == 0) {
47         return 1;
48     }
49 
50     int64 val = GetExtValue();
51     uint64 tmp = val < 0 ? -(val + 1) : val;
52 
53     uint8 width = 0;
54     while (tmp != 0) {
55         ++width;
56         tmp = tmp >> 1u;
57     }
58 
59     return width;
60 }
61 
Dump(const MIRSymbolTable * localSymTab) const62 void MIRAddrofConst::Dump(const MIRSymbolTable *localSymTab) const
63 {
64     LogInfo::MapleLogger() << "addrof " << GetPrimTypeName(PTY_ptr);
65     const MIRSymbol *sym = stIdx.IsGlobal() ? GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx())
66                                             : localSymTab->GetSymbolFromStIdx(stIdx.Idx());
67     DEBUG_ASSERT(stIdx.IsGlobal() || sym->GetStorageClass() == kScPstatic || sym->GetStorageClass() == kScFstatic,
68                  "MIRAddrofConst can only point to a global symbol");
69     CHECK_FATAL(sym != nullptr, "null ptr");
70     LogInfo::MapleLogger() << (stIdx.IsGlobal() ? " $" : " %") << sym->GetName();
71     if (fldID > 0) {
72         LogInfo::MapleLogger() << " " << fldID;
73     }
74     if (offset != 0) {
75         LogInfo::MapleLogger() << " (" << offset << ")";
76     }
77 }
78 #endif
79 
operator ==(const MIRConst & rhs) const80 bool MIRAddrofConst::operator==(const MIRConst &rhs) const
81 {
82     if (&rhs == this) {
83         return true;
84     }
85     if (GetKind() != rhs.GetKind()) {
86         return false;
87     }
88     const auto &rhsA = static_cast<const MIRAddrofConst &>(rhs);
89     if (&GetType() != &rhs.GetType()) {
90         return false;
91     }
92     return (stIdx == rhsA.stIdx) && (fldID == rhsA.fldID);
93 }
94 
95 #ifdef ARK_LITECG_DEBUG
Dump(const MIRSymbolTable *) const96 void MIRAddroffuncConst::Dump(const MIRSymbolTable *) const
97 {
98     LogInfo::MapleLogger() << "addroffunc " << GetPrimTypeName(PTY_ptr);
99     MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
100     CHECK_FATAL(func != nullptr, "null ptr");
101     CHECK_NULL_FATAL(GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()));
102     LogInfo::MapleLogger() << " &"
103                            << GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx())->GetName();
104 }
105 #endif
106 
operator ==(const MIRConst & rhs) const107 bool MIRAddroffuncConst::operator==(const MIRConst &rhs) const
108 {
109     if (&rhs == this) {
110         return true;
111     }
112     if (GetKind() != rhs.GetKind()) {
113         return false;
114     }
115     const auto &rhsAf = static_cast<const MIRAddroffuncConst &>(rhs);
116     return (&GetType() == &rhs.GetType()) && (puIdx == rhsAf.puIdx);
117 }
118 
119 #ifdef ARK_LITECG_DEBUG
Dump(const MIRSymbolTable *) const120 void MIRLblConst::Dump(const MIRSymbolTable *) const
121 {
122     LogInfo::MapleLogger() << "addroflabel " << GetPrimTypeName(PTY_ptr);
123     MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
124     LogInfo::MapleLogger() << " @" << func->GetLabelName(value);
125 }
126 #endif
127 
operator ==(const MIRConst & rhs) const128 bool MIRLblConst::operator==(const MIRConst &rhs) const
129 {
130     if (&rhs == this) {
131         return true;
132     }
133     if (GetKind() != rhs.GetKind()) {
134         return false;
135     }
136     const auto &lblConst = static_cast<const MIRLblConst &>(rhs);
137     return (lblConst.value == value);
138 }
139 
operator ==(const MIRConst & rhs) const140 bool MIRFloatConst::operator==(const MIRConst &rhs) const
141 {
142     if (&rhs == this) {
143         return true;
144     }
145     if (GetKind() != rhs.GetKind()) {
146         return false;
147     }
148     const auto &floatConst = static_cast<const MIRFloatConst &>(rhs);
149     if (std::isnan(floatConst.value.floatValue)) {
150         return std::isnan(value.floatValue);
151     }
152     if (std::isnan(value.floatValue)) {
153         return std::isnan(floatConst.value.floatValue);
154     }
155     if (floatConst.value.floatValue == 0.0 && value.floatValue == 0.0) {
156         return floatConst.IsNeg() == IsNeg();
157     }
158     // Use bitwise comparison instead of approximate comparison for FP to avoid treating 0.0 and FLT_MIN as equal
159     return (floatConst.value.intValue == value.intValue);
160 }
161 
operator ==(const MIRConst & rhs) const162 bool MIRDoubleConst::operator==(const MIRConst &rhs) const
163 {
164     if (&rhs == this) {
165         return true;
166     }
167     if (GetKind() != rhs.GetKind()) {
168         return false;
169     }
170     const auto &floatConst = static_cast<const MIRDoubleConst &>(rhs);
171     if (std::isnan(floatConst.value.dValue)) {
172         return std::isnan(value.dValue);
173     }
174     if (std::isnan(value.dValue)) {
175         return std::isnan(floatConst.value.dValue);
176     }
177     if (floatConst.value.dValue == 0.0 && value.dValue == 0.0) {
178         return floatConst.IsNeg() == IsNeg();
179     }
180     // Use bitwise comparison instead of approximate comparison for FP to avoid treating 0.0 and DBL_MIN as equal
181     return (floatConst.value.intValue == value.intValue);
182 }
183 
operator ==(const MIRConst & rhs) const184 bool MIRAggConst::operator==(const MIRConst &rhs) const
185 {
186     if (&rhs == this) {
187         return true;
188     }
189     if (GetKind() != rhs.GetKind()) {
190         return false;
191     }
192     const auto &aggregateConst = static_cast<const MIRAggConst &>(rhs);
193     if (aggregateConst.constVec.size() != constVec.size()) {
194         return false;
195     }
196     for (size_t i = 0; i < constVec.size(); ++i) {
197         if (!(*aggregateConst.constVec[i] == *constVec[i])) {
198             return false;
199         }
200     }
201     return true;
202 }
203 
204 #ifdef ARK_LITECG_DEBUG
Dump(const MIRSymbolTable *) const205 void MIRFloatConst::Dump(const MIRSymbolTable *) const
206 {
207     LogInfo::MapleLogger() << std::setprecision(std::numeric_limits<float>::max_digits10) << value.floatValue << "f";
208 }
209 
Dump(const MIRSymbolTable *) const210 void MIRDoubleConst::Dump(const MIRSymbolTable *) const
211 {
212     LogInfo::MapleLogger() << std::setprecision(std::numeric_limits<double>::max_digits10) << value.dValue;
213 }
214 
Dump(const MIRSymbolTable * localSymTab) const215 void MIRAggConst::Dump(const MIRSymbolTable *localSymTab) const
216 {
217     LogInfo::MapleLogger() << "[";
218     size_t size = constVec.size();
219     for (size_t i = 0; i < size; ++i) {
220         if (fieldIdVec[i] != 0) {
221             LogInfo::MapleLogger() << fieldIdVec[i] << "= ";
222         }
223         constVec[i]->Dump(localSymTab);
224         if (i != size - 1) {
225             LogInfo::MapleLogger() << ", ";
226         }
227     }
228     LogInfo::MapleLogger() << "]";
229 }
230 #endif
231 
MIRStrConst(const std::string & str,MIRType & type)232 MIRStrConst::MIRStrConst(const std::string &str, MIRType &type)
233     : MIRConst(type, kConstStrConst), value(GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(str))
234 {
235 }
236 
237 #ifdef ARK_LITECG_DEBUG
Dump(const MIRSymbolTable *) const238 void MIRStrConst::Dump(const MIRSymbolTable *) const
239 {
240     LogInfo::MapleLogger() << "conststr " << GetPrimTypeName(GetType().GetPrimType());
241     const std::string &dumpStr = GlobalTables::GetUStrTable().GetStringFromStrIdx(value);
242     PrintString(dumpStr);
243 }
244 #endif
245 
operator ==(const MIRConst & rhs) const246 bool MIRStrConst::operator==(const MIRConst &rhs) const
247 {
248     if (&rhs == this) {
249         return true;
250     }
251     if (GetKind() != rhs.GetKind()) {
252         return false;
253     }
254     const auto &rhsCs = static_cast<const MIRStrConst &>(rhs);
255     return (&rhs.GetType() == &GetType()) && (value == rhsCs.value);
256 }
257 
MIRStr16Const(const std::u16string & str,MIRType & type)258 MIRStr16Const::MIRStr16Const(const std::u16string &str, MIRType &type)
259     : MIRConst(type, kConstStr16Const), value(GlobalTables::GetU16StrTable().GetOrCreateStrIdxFromName(str))
260 {
261 }
262 
263 #ifdef ARK_LITECG_DEBUG
Dump(const MIRSymbolTable *) const264 void MIRStr16Const::Dump(const MIRSymbolTable *) const
265 {
266     LogInfo::MapleLogger() << "conststr16 " << GetPrimTypeName(GetType().GetPrimType());
267     std::u16string str16 = GlobalTables::GetU16StrTable().GetStringFromStrIdx(value);
268     // UTF-16 string are dumped as UTF-8 string in mpl to keep the printable chars in ascii form
269     std::string str;
270     (void)namemangler::UTF16ToUTF8(str, str16);
271     PrintString(str);
272 }
273 #endif
274 
operator ==(const MIRConst & rhs) const275 bool MIRStr16Const::operator==(const MIRConst &rhs) const
276 {
277     if (&rhs == this) {
278         return true;
279     }
280     if (GetKind() != rhs.GetKind()) {
281         return false;
282     }
283     const auto &rhsCs = static_cast<const MIRStr16Const &>(rhs);
284     return (&GetType() == &rhs.GetType()) && (value == rhsCs.value);
285 }
286 
IsDivSafe(const MIRIntConst & dividend,const MIRIntConst & divisor,PrimType pType)287 bool IsDivSafe(const MIRIntConst &dividend, const MIRIntConst &divisor, PrimType pType)
288 {
289     if (IsUnsignedInteger(pType)) {
290         return divisor.GetValue() != 0;
291     }
292 
293     return divisor.GetValue() != 0 && (!dividend.GetValue().IsMinValue() || !divisor.GetValue().AreAllBitsOne());
294 }
295 
296 }  // namespace maple
297 #endif  // MIR_FEATURE_FULL
298