• 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     CHECK_FATAL(sym != nullptr, "null ptr");
66     LogInfo::MapleLogger() << (stIdx.IsGlobal() ? " $" : " %") << sym->GetName();
67     if (fldID > 0) {
68         LogInfo::MapleLogger() << " " << fldID;
69     }
70     if (offset != 0) {
71         LogInfo::MapleLogger() << " (" << offset << ")";
72     }
73 }
74 
operator ==(const MIRConst & rhs) const75 bool MIRAddrofConst::operator==(const MIRConst &rhs) const
76 {
77     if (&rhs == this) {
78         return true;
79     }
80     if (GetKind() != rhs.GetKind()) {
81         return false;
82     }
83     const auto &rhsA = static_cast<const MIRAddrofConst &>(rhs);
84     if (&GetType() != &rhs.GetType()) {
85         return false;
86     }
87     return (stIdx == rhsA.stIdx) && (fldID == rhsA.fldID);
88 }
89 
Dump(const MIRSymbolTable *) const90 void MIRAddroffuncConst::Dump(const MIRSymbolTable *) const
91 {
92     LogInfo::MapleLogger() << "addroffunc " << GetPrimTypeName(PTY_ptr);
93     MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
94     CHECK_FATAL(func != nullptr, "null ptr");
95     CHECK_NULL_FATAL(GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx()));
96     LogInfo::MapleLogger() << " &"
97                            << GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx())->GetName();
98 }
99 
operator ==(const MIRConst & rhs) const100 bool MIRAddroffuncConst::operator==(const MIRConst &rhs) const
101 {
102     if (&rhs == this) {
103         return true;
104     }
105     if (GetKind() != rhs.GetKind()) {
106         return false;
107     }
108     const auto &rhsAf = static_cast<const MIRAddroffuncConst &>(rhs);
109     return (&GetType() == &rhs.GetType()) && (puIdx == rhsAf.puIdx);
110 }
111 
Dump(const MIRSymbolTable *) const112 void MIRLblConst::Dump(const MIRSymbolTable *) const
113 {
114     LogInfo::MapleLogger() << "addroflabel " << GetPrimTypeName(PTY_ptr);
115     MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
116     LogInfo::MapleLogger() << " @" << func->GetLabelName(value);
117 }
118 
operator ==(const MIRConst & rhs) const119 bool MIRLblConst::operator==(const MIRConst &rhs) const
120 {
121     if (&rhs == this) {
122         return true;
123     }
124     if (GetKind() != rhs.GetKind()) {
125         return false;
126     }
127     const auto &lblConst = static_cast<const MIRLblConst &>(rhs);
128     return (lblConst.value == value);
129 }
130 
operator ==(const MIRConst & rhs) const131 bool MIRFloatConst::operator==(const MIRConst &rhs) const
132 {
133     if (&rhs == this) {
134         return true;
135     }
136     if (GetKind() != rhs.GetKind()) {
137         return false;
138     }
139     const auto &floatConst = static_cast<const MIRFloatConst &>(rhs);
140     if (std::isnan(floatConst.value.floatValue)) {
141         return std::isnan(value.floatValue);
142     }
143     if (std::isnan(value.floatValue)) {
144         return std::isnan(floatConst.value.floatValue);
145     }
146     if (floatConst.value.floatValue == 0.0 && value.floatValue == 0.0) {
147         return floatConst.IsNeg() == IsNeg();
148     }
149     // Use bitwise comparison instead of approximate comparison for FP to avoid treating 0.0 and FLT_MIN as equal
150     return (floatConst.value.intValue == value.intValue);
151 }
152 
operator ==(const MIRConst & rhs) const153 bool MIRDoubleConst::operator==(const MIRConst &rhs) const
154 {
155     if (&rhs == this) {
156         return true;
157     }
158     if (GetKind() != rhs.GetKind()) {
159         return false;
160     }
161     const auto &floatConst = static_cast<const MIRDoubleConst &>(rhs);
162     if (std::isnan(floatConst.value.dValue)) {
163         return std::isnan(value.dValue);
164     }
165     if (std::isnan(value.dValue)) {
166         return std::isnan(floatConst.value.dValue);
167     }
168     if (floatConst.value.dValue == 0.0 && value.dValue == 0.0) {
169         return floatConst.IsNeg() == IsNeg();
170     }
171     // Use bitwise comparison instead of approximate comparison for FP to avoid treating 0.0 and DBL_MIN as equal
172     return (floatConst.value.intValue == value.intValue);
173 }
174 
operator ==(const MIRConst & rhs) const175 bool MIRFloat128Const::operator==(const MIRConst &rhs) const
176 {
177     if (&rhs == this) {
178         return true;
179     }
180     if (GetKind() != rhs.GetKind()) {
181         return false;
182     }
183     const auto &floatConst = static_cast<const MIRFloat128Const &>(rhs);
184     if ((value[0] == floatConst.value[0]) && (value[1] == floatConst.value[1])) {
185         return true;
186     }
187     return false;
188 }
189 
operator ==(const MIRConst & rhs) const190 bool MIRAggConst::operator==(const MIRConst &rhs) const
191 {
192     if (&rhs == this) {
193         return true;
194     }
195     if (GetKind() != rhs.GetKind()) {
196         return false;
197     }
198     const auto &aggregateConst = static_cast<const MIRAggConst &>(rhs);
199     if (aggregateConst.constVec.size() != constVec.size()) {
200         return false;
201     }
202     for (size_t i = 0; i < constVec.size(); ++i) {
203         if (!(*aggregateConst.constVec[i] == *constVec[i])) {
204             return false;
205         }
206     }
207     return true;
208 }
209 
Dump(const MIRSymbolTable *) const210 void MIRFloatConst::Dump(const MIRSymbolTable *) const
211 {
212     LogInfo::MapleLogger() << std::setprecision(std::numeric_limits<float>::max_digits10) << value.floatValue << "f";
213 }
214 
Dump(const MIRSymbolTable *) const215 void MIRDoubleConst::Dump(const MIRSymbolTable *) const
216 {
217     LogInfo::MapleLogger() << std::setprecision(std::numeric_limits<double>::max_digits10) << value.dValue;
218 }
219 
Dump(const MIRSymbolTable *) const220 void MIRFloat128Const::Dump(const MIRSymbolTable *) const
221 {
222     constexpr int fieldWidth = 16;
223     std::ios::fmtflags f(LogInfo::MapleLogger().flags());
224     LogInfo::MapleLogger().setf(std::ios::uppercase);
225     LogInfo::MapleLogger() << "0xL" << std::hex << std::setfill('0') << std::setw(fieldWidth) << value[0]
226                            << std::setfill('0') << std::setw(fieldWidth) << value[1];
227     LogInfo::MapleLogger().flags(f);
228 }
229 
Dump(const MIRSymbolTable * localSymTab) const230 void MIRAggConst::Dump(const MIRSymbolTable *localSymTab) const
231 {
232     LogInfo::MapleLogger() << "[";
233     size_t size = constVec.size();
234     for (size_t i = 0; i < size; ++i) {
235         if (fieldIdVec[i] != 0) {
236             LogInfo::MapleLogger() << fieldIdVec[i] << "= ";
237         }
238         constVec[i]->Dump(localSymTab);
239         if (i != size - 1) {
240             LogInfo::MapleLogger() << ", ";
241         }
242     }
243     LogInfo::MapleLogger() << "]";
244 }
245 
MIRStrConst(const std::string & str,MIRType & type)246 MIRStrConst::MIRStrConst(const std::string &str, MIRType &type)
247     : MIRConst(type, kConstStrConst), value(GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(str))
248 {
249 }
250 
Dump(const MIRSymbolTable *) const251 void MIRStrConst::Dump(const MIRSymbolTable *) const
252 {
253     LogInfo::MapleLogger() << "conststr " << GetPrimTypeName(GetType().GetPrimType());
254     const std::string &dumpStr = GlobalTables::GetUStrTable().GetStringFromStrIdx(value);
255     PrintString(dumpStr);
256 }
257 
operator ==(const MIRConst & rhs) const258 bool MIRStrConst::operator==(const MIRConst &rhs) const
259 {
260     if (&rhs == this) {
261         return true;
262     }
263     if (GetKind() != rhs.GetKind()) {
264         return false;
265     }
266     const auto &rhsCs = static_cast<const MIRStrConst &>(rhs);
267     return (&rhs.GetType() == &GetType()) && (value == rhsCs.value);
268 }
269 
MIRStr16Const(const std::u16string & str,MIRType & type)270 MIRStr16Const::MIRStr16Const(const std::u16string &str, MIRType &type)
271     : MIRConst(type, kConstStr16Const), value(GlobalTables::GetU16StrTable().GetOrCreateStrIdxFromName(str))
272 {
273 }
274 
Dump(const MIRSymbolTable *) const275 void MIRStr16Const::Dump(const MIRSymbolTable *) const
276 {
277     LogInfo::MapleLogger() << "conststr16 " << GetPrimTypeName(GetType().GetPrimType());
278     std::u16string str16 = GlobalTables::GetU16StrTable().GetStringFromStrIdx(value);
279     // UTF-16 string are dumped as UTF-8 string in mpl to keep the printable chars in ascii form
280     std::string str;
281     (void)namemangler::UTF16ToUTF8(str, str16);
282     PrintString(str);
283 }
284 
operator ==(const MIRConst & rhs) const285 bool MIRStr16Const::operator==(const MIRConst &rhs) const
286 {
287     if (&rhs == this) {
288         return true;
289     }
290     if (GetKind() != rhs.GetKind()) {
291         return false;
292     }
293     const auto &rhsCs = static_cast<const MIRStr16Const &>(rhs);
294     return (&GetType() == &rhs.GetType()) && (value == rhsCs.value);
295 }
296 
IsDivSafe(const MIRIntConst & dividend,const MIRIntConst & divisor,PrimType pType)297 bool IsDivSafe(const MIRIntConst &dividend, const MIRIntConst &divisor, PrimType pType)
298 {
299     if (IsUnsignedInteger(pType)) {
300         return divisor.GetValue() != 0;
301     }
302 
303     return divisor.GetValue() != 0 && (!dividend.GetValue().IsMinValue() || !divisor.GetValue().AreAllBitsOne());
304 }
305 
306 }  // namespace maple
307 #endif  // MIR_FEATURE_FULL
308