• 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 "global_tables.h"
19 #include "printing.h"
20 #if MIR_FEATURE_FULL
21 
22 namespace maple {
Dump(const MIRSymbolTable *) const23 void MIRIntConst::Dump(const MIRSymbolTable *) const
24 {
25     LogInfo::MapleLogger() << value;
26 }
27 
operator ==(const MIRConst & rhs) const28 bool MIRIntConst::operator==(const MIRConst &rhs) const
29 {
30     if (&rhs == this) {
31         return true;
32     }
33     if (GetKind() != rhs.GetKind()) {
34         return false;
35     }
36     const auto &intConst = static_cast<const MIRIntConst &>(rhs);
37     return ((&intConst.GetType() == &GetType()) && (intConst.value == value));
38 }
39 
GetActualBitWidth() const40 uint8 MIRIntConst::GetActualBitWidth() const
41 {
42     if (value == 0) {
43         return 1;
44     }
45 
46     int64 val = GetExtValue();
47     uint64 tmp = val < 0 ? -(val + 1) : val;
48 
49     uint8 width = 0;
50     while (tmp != 0) {
51         ++width;
52         tmp = tmp >> 1u;
53     }
54 
55     return width;
56 }
57 
Dump(const MIRSymbolTable * localSymTab) const58 void MIRAddrofConst::Dump(const MIRSymbolTable *localSymTab) const
59 {
60     LogInfo::MapleLogger() << "addrof " << GetPrimTypeName(PTY_ptr);
61     const MIRSymbol *sym = stIdx.IsGlobal() ? GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx())
62                                             : localSymTab->GetSymbolFromStIdx(stIdx.Idx());
63     DEBUG_ASSERT(stIdx.IsGlobal() || sym->GetStorageClass() == kScPstatic || sym->GetStorageClass() == kScFstatic,
64                  "MIRAddrofConst can only point to a global symbol");
65     LogInfo::MapleLogger() << (stIdx.IsGlobal() ? " $" : " %") << sym->GetName();
66     if (fldID > 0) {
67         LogInfo::MapleLogger() << " " << fldID;
68     }
69     if (offset != 0) {
70         LogInfo::MapleLogger() << " (" << offset << ")";
71     }
72 }
73 
operator ==(const MIRConst & rhs) const74 bool MIRAddrofConst::operator==(const MIRConst &rhs) const
75 {
76     if (&rhs == this) {
77         return true;
78     }
79     if (GetKind() != rhs.GetKind()) {
80         return false;
81     }
82     const auto &rhsA = static_cast<const MIRAddrofConst &>(rhs);
83     if (&GetType() != &rhs.GetType()) {
84         return false;
85     }
86     return (stIdx == rhsA.stIdx) && (fldID == rhsA.fldID);
87 }
88 
Dump(const MIRSymbolTable *) const89 void MIRAddroffuncConst::Dump(const MIRSymbolTable *) const
90 {
91     LogInfo::MapleLogger() << "addroffunc " << GetPrimTypeName(PTY_ptr);
92     MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
93     LogInfo::MapleLogger() << " &"
94                            << GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx())->GetName();
95 }
96 
operator ==(const MIRConst & rhs) const97 bool MIRAddroffuncConst::operator==(const MIRConst &rhs) const
98 {
99     if (&rhs == this) {
100         return true;
101     }
102     if (GetKind() != rhs.GetKind()) {
103         return false;
104     }
105     const auto &rhsAf = static_cast<const MIRAddroffuncConst &>(rhs);
106     return (&GetType() == &rhs.GetType()) && (puIdx == rhsAf.puIdx);
107 }
108 
Dump(const MIRSymbolTable *) const109 void MIRLblConst::Dump(const MIRSymbolTable *) const
110 {
111     LogInfo::MapleLogger() << "addroflabel " << GetPrimTypeName(PTY_ptr);
112     MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
113     LogInfo::MapleLogger() << " @" << func->GetLabelName(value);
114 }
115 
operator ==(const MIRConst & rhs) const116 bool MIRLblConst::operator==(const MIRConst &rhs) const
117 {
118     if (&rhs == this) {
119         return true;
120     }
121     if (GetKind() != rhs.GetKind()) {
122         return false;
123     }
124     const auto &lblConst = static_cast<const MIRLblConst &>(rhs);
125     return (lblConst.value == value);
126 }
127 
operator ==(const MIRConst & rhs) const128 bool MIRFloatConst::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 &floatConst = static_cast<const MIRFloatConst &>(rhs);
137     if (std::isnan(floatConst.value.floatValue)) {
138         return std::isnan(value.floatValue);
139     }
140     if (std::isnan(value.floatValue)) {
141         return std::isnan(floatConst.value.floatValue);
142     }
143     if (floatConst.value.floatValue == 0.0 && value.floatValue == 0.0) {
144         return floatConst.IsNeg() == IsNeg();
145     }
146     // Use bitwise comparison instead of approximate comparison for FP to avoid treating 0.0 and FLT_MIN as equal
147     return (floatConst.value.intValue == value.intValue);
148 }
149 
operator ==(const MIRConst & rhs) const150 bool MIRDoubleConst::operator==(const MIRConst &rhs) const
151 {
152     if (&rhs == this) {
153         return true;
154     }
155     if (GetKind() != rhs.GetKind()) {
156         return false;
157     }
158     const auto &floatConst = static_cast<const MIRDoubleConst &>(rhs);
159     if (std::isnan(floatConst.value.dValue)) {
160         return std::isnan(value.dValue);
161     }
162     if (std::isnan(value.dValue)) {
163         return std::isnan(floatConst.value.dValue);
164     }
165     if (floatConst.value.dValue == 0.0 && value.dValue == 0.0) {
166         return floatConst.IsNeg() == IsNeg();
167     }
168     // Use bitwise comparison instead of approximate comparison for FP to avoid treating 0.0 and DBL_MIN as equal
169     return (floatConst.value.intValue == value.intValue);
170 }
171 
operator ==(const MIRConst & rhs) const172 bool MIRFloat128Const::operator==(const MIRConst &rhs) const
173 {
174     if (&rhs == this) {
175         return true;
176     }
177     if (GetKind() != rhs.GetKind()) {
178         return false;
179     }
180     const auto &floatConst = static_cast<const MIRFloat128Const &>(rhs);
181     if ((value[0] == floatConst.value[0]) && (value[1] == floatConst.value[1])) {
182         return true;
183     }
184     return false;
185 }
186 
operator ==(const MIRConst & rhs) const187 bool MIRAggConst::operator==(const MIRConst &rhs) const
188 {
189     if (&rhs == this) {
190         return true;
191     }
192     if (GetKind() != rhs.GetKind()) {
193         return false;
194     }
195     const auto &aggregateConst = static_cast<const MIRAggConst &>(rhs);
196     if (aggregateConst.constVec.size() != constVec.size()) {
197         return false;
198     }
199     for (size_t i = 0; i < constVec.size(); ++i) {
200         if (!(*aggregateConst.constVec[i] == *constVec[i])) {
201             return false;
202         }
203     }
204     return true;
205 }
206 
Dump(const MIRSymbolTable *) const207 void MIRFloatConst::Dump(const MIRSymbolTable *) const
208 {
209     LogInfo::MapleLogger() << std::setprecision(std::numeric_limits<float>::max_digits10) << value.floatValue << "f";
210 }
211 
Dump(const MIRSymbolTable *) const212 void MIRDoubleConst::Dump(const MIRSymbolTable *) const
213 {
214     LogInfo::MapleLogger() << std::setprecision(std::numeric_limits<double>::max_digits10) << value.dValue;
215 }
216 
Dump(const MIRSymbolTable *) const217 void MIRFloat128Const::Dump(const MIRSymbolTable *) const
218 {
219     constexpr int fieldWidth = 16;
220     std::ios::fmtflags f(LogInfo::MapleLogger().flags());
221     LogInfo::MapleLogger().setf(std::ios::uppercase);
222     LogInfo::MapleLogger() << "0xL" << std::hex << std::setfill('0') << std::setw(fieldWidth) << value[0]
223                            << std::setfill('0') << std::setw(fieldWidth) << value[1];
224     LogInfo::MapleLogger().flags(f);
225 }
226 
Dump(const MIRSymbolTable * localSymTab) const227 void MIRAggConst::Dump(const MIRSymbolTable *localSymTab) const
228 {
229     LogInfo::MapleLogger() << "[";
230     size_t size = constVec.size();
231     for (size_t i = 0; i < size; ++i) {
232         if (fieldIdVec[i] != 0) {
233             LogInfo::MapleLogger() << fieldIdVec[i] << "= ";
234         }
235         constVec[i]->Dump(localSymTab);
236         if (i != size - 1) {
237             LogInfo::MapleLogger() << ", ";
238         }
239     }
240     LogInfo::MapleLogger() << "]";
241 }
242 
MIRStrConst(const std::string & str,MIRType & type)243 MIRStrConst::MIRStrConst(const std::string &str, MIRType &type)
244     : MIRConst(type, kConstStrConst), value(GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(str))
245 {
246 }
247 
Dump(const MIRSymbolTable *) const248 void MIRStrConst::Dump(const MIRSymbolTable *) const
249 {
250     LogInfo::MapleLogger() << "conststr " << GetPrimTypeName(GetType().GetPrimType());
251     const std::string &dumpStr = GlobalTables::GetUStrTable().GetStringFromStrIdx(value);
252     PrintString(dumpStr);
253 }
254 
operator ==(const MIRConst & rhs) const255 bool MIRStrConst::operator==(const MIRConst &rhs) const
256 {
257     if (&rhs == this) {
258         return true;
259     }
260     if (GetKind() != rhs.GetKind()) {
261         return false;
262     }
263     const auto &rhsCs = static_cast<const MIRStrConst &>(rhs);
264     return (&rhs.GetType() == &GetType()) && (value == rhsCs.value);
265 }
266 
MIRStr16Const(const std::u16string & str,MIRType & type)267 MIRStr16Const::MIRStr16Const(const std::u16string &str, MIRType &type)
268     : MIRConst(type, kConstStr16Const), value(GlobalTables::GetU16StrTable().GetOrCreateStrIdxFromName(str))
269 {
270 }
271 
Dump(const MIRSymbolTable *) const272 void MIRStr16Const::Dump(const MIRSymbolTable *) const
273 {
274     LogInfo::MapleLogger() << "conststr16 " << GetPrimTypeName(GetType().GetPrimType());
275     std::u16string str16 = GlobalTables::GetU16StrTable().GetStringFromStrIdx(value);
276     // UTF-16 string are dumped as UTF-8 string in mpl to keep the printable chars in ascii form
277     std::string str;
278     (void)namemangler::UTF16ToUTF8(str, str16);
279     PrintString(str);
280 }
281 
operator ==(const MIRConst & rhs) const282 bool MIRStr16Const::operator==(const MIRConst &rhs) const
283 {
284     if (&rhs == this) {
285         return true;
286     }
287     if (GetKind() != rhs.GetKind()) {
288         return false;
289     }
290     const auto &rhsCs = static_cast<const MIRStr16Const &>(rhs);
291     return (&GetType() == &rhs.GetType()) && (value == rhsCs.value);
292 }
293 
IsDivSafe(const MIRIntConst & dividend,const MIRIntConst & divisor,PrimType pType)294 bool IsDivSafe(const MIRIntConst &dividend, const MIRIntConst &divisor, PrimType pType)
295 {
296     if (IsUnsignedInteger(pType)) {
297         return divisor.GetValue() != 0;
298     }
299 
300     return divisor.GetValue() != 0 && (!dividend.GetValue().IsMinValue() || !divisor.GetValue().AreAllBitsOne());
301 }
302 
303 }  // namespace maple
304 #endif  // MIR_FEATURE_FULL
305