• 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 MAPLE_IR_INCLUDE_MIR_CONST_H
17 #define MAPLE_IR_INCLUDE_MIR_CONST_H
18 #include <math.h>
19 #include "mir_type.h"
20 #include "mpl_int_val.h"
21 
22 namespace maple {
23 class MIRConst;  // circular dependency exists, no other choice
24 using MIRConstPtr = MIRConst *;
25 #if MIR_FEATURE_FULL
26 class MIRSymbol;  // circular dependency exists, no other choice
27 enum MIRConstKind {
28     kConstInvalid,
29     kConstInt,
30     kConstAddrof,
31     kConstAddrofFunc,
32     kConstLblConst,
33     kConstStrConst,
34     kConstStr16Const,
35     kConstFloatConst,
36     kConstDoubleConst,
37     kConstFloat128Const,
38     kConstAggConst,
39     kConstStConst
40 };
41 
42 class MIRConst {
43 public:
44     explicit MIRConst(MIRType &type, MIRConstKind constKind = kConstInvalid) : type(&type), kind(constKind) {}
45 
46     virtual ~MIRConst() = default;
47 #ifdef ARK_LITECG_DEBUG
48     virtual void Dump(const MIRSymbolTable *localSymTab = nullptr) const
49     {
50         (void)localSymTab;
51     }
52 #endif
53 
GetFieldId()54     uint32 GetFieldId() const
55     {
56         return fieldID;
57     }
58 
SetFieldId(uint32 fieldIdx)59     void SetFieldId(uint32 fieldIdx)
60     {
61         DoSetFieldId(fieldIdx);
62     }
63 
IsZero()64     virtual bool IsZero() const
65     {
66         return false;
67     }
68 
IsOne()69     virtual bool IsOne() const
70     {
71         return false;
72     }
73 
IsMagicNum()74     virtual bool IsMagicNum() const
75     {
76         return false;
77     }
78 
79     // NO OP
Neg()80     virtual void Neg() {}
81 
82     virtual bool operator==(const MIRConst &rhs) const
83     {
84         return &rhs == this;
85     }
86 
87     virtual MIRConst *Clone(MemPool &memPool) const = 0;
88 
GetKind()89     MIRConstKind GetKind() const
90     {
91         return kind;
92     }
93 
GetType()94     MIRType &GetType()
95     {
96         return *type;
97     }
98 
GetType()99     const MIRType &GetType() const
100     {
101         return *type;
102     }
103 
SetType(MIRType & t)104     void SetType(MIRType &t)
105     {
106         type = &t;
107     }
108 
109 protected:
110     uint32 fieldID = 0;
111 
112 private:
113     MIRType *type;
114     MIRConstKind kind;
DoSetFieldId(uint32 fieldIdx)115     virtual void DoSetFieldId(uint32 fieldIdx)
116     {
117         DEBUG_ASSERT(kind != kConstInt, "must be");
118         fieldID = fieldIdx;
119     }
120 };
121 
122 class MIRIntConst : public MIRConst {
123 public:
MIRIntConst(uint64 val,MIRType & type)124     MIRIntConst(uint64 val, MIRType &type) : MIRConst(type, kConstInt), value(val, type.GetPrimType()) {}
125 
MIRIntConst(const IntVal & val,MIRType & type)126     MIRIntConst(const IntVal &val, MIRType &type) : MIRConst(type, kConstInt), value(val)
127     {
128         [[maybe_unused]] PrimType pType = type.GetPrimType();
129         DEBUG_ASSERT(
130             IsPrimitiveInteger(pType) && GetPrimTypeActualBitSize(pType) <= value.GetBitWidth(),
131             "Constant is tried to be constructed with non-integral type or bit-width is not appropriate for it");
132     }
133 
134 #ifdef ARK_LITECG_DEBUG
135     /// @return number of used bits in the value
136     uint8 GetActualBitWidth() const;
137 #endif
138 
Trunc(uint8 width)139     void Trunc(uint8 width)
140     {
141         value.TruncInPlace(width);
142     }
143 #ifdef ARK_LITECG_DEBUG
144     void Dump(const MIRSymbolTable *localSymTab) const override;
145 #endif
IsNegative()146     bool IsNegative() const
147     {
148         return value.IsSigned() && value.GetSignBit();
149     }
150 
IsPositive()151     bool IsPositive() const
152     {
153         return !IsNegative() && value != 0;
154     }
155 
IsZero()156     bool IsZero() const override
157     {
158         return value == 0;
159     }
160 
IsOne()161     bool IsOne() const override
162     {
163         return value == 1;
164     }
165 
Neg()166     void Neg() override
167     {
168         value = -value;
169     }
170 
GetValue()171     const IntVal &GetValue() const
172     {
173         return value;
174     }
175 
176     int64 GetExtValue(uint8 size = 0) const
177     {
178         return value.GetExtValue(size);
179     }
180 
181     int64 GetSXTValue(uint8 size = 0) const
182     {
183         return value.GetSXTValue(size);
184     }
185 
186     uint64 GetZXTValue(uint8 size = 0) const
187     {
188         return value.GetZXTValue(size);
189     }
190 
SetValue(int64 val)191     void SetValue(int64 val) const
192     {
193         (void)val;
194         CHECK_FATAL(false, "Can't Use This Interface in This Object");
195     }
196 
197     bool operator==(const MIRConst &rhs) const override;
198 
Clone(MemPool & memPool)199     MIRIntConst *Clone([[maybe_unused]] MemPool &memPool) const override
200     {
201         CHECK_FATAL(false, "Can't Use This Interface in This Object");
202     }
203 
204 private:
205     IntVal value;
206 
DoSetFieldId(uint32 fieldIdx)207     void DoSetFieldId(uint32 fieldIdx) override
208     {
209         DEBUG_ASSERT(false, "Can't Use This Interface in This Object");
210         (void)fieldIdx;
211     }
212 };
213 
214 class MIRAddrofConst : public MIRConst {
215 public:
MIRAddrofConst(StIdx sy,FieldID fi,MIRType & ty)216     MIRAddrofConst(StIdx sy, FieldID fi, MIRType &ty) : MIRConst(ty, kConstAddrof), stIdx(sy), fldID(fi), offset(0) {}
217 
MIRAddrofConst(StIdx sy,FieldID fi,MIRType & ty,int32 ofst)218     MIRAddrofConst(StIdx sy, FieldID fi, MIRType &ty, int32 ofst)
219         : MIRConst(ty, kConstAddrof), stIdx(sy), fldID(fi), offset(ofst)
220     {
221     }
222 
223     ~MIRAddrofConst() = default;
224 
GetSymbolIndex()225     StIdx GetSymbolIndex() const
226     {
227         return stIdx;
228     }
229 
SetSymbolIndex(StIdx idx)230     void SetSymbolIndex(StIdx idx)
231     {
232         stIdx = idx;
233     }
234 
GetFieldID()235     FieldID GetFieldID() const
236     {
237         return fldID;
238     }
239 
GetOffset()240     int32 GetOffset() const
241     {
242         return offset;
243     }
244 #ifdef ARK_LITECG_DEBUG
245     void Dump(const MIRSymbolTable *localSymTab) const override;
246 #endif
247     bool operator==(const MIRConst &rhs) const override;
248 
Clone(MemPool & memPool)249     MIRAddrofConst *Clone(MemPool &memPool) const override
250     {
251         return memPool.New<MIRAddrofConst>(*this);
252     }
253 
254 private:
255     StIdx stIdx;
256     FieldID fldID;
257     int32 offset;
258 };
259 
260 class MIRAddroffuncConst : public MIRConst {
261 public:
MIRAddroffuncConst(PUIdx idx,MIRType & ty)262     MIRAddroffuncConst(PUIdx idx, MIRType &ty) : MIRConst(ty, kConstAddrofFunc), puIdx(idx) {}
263 
264     ~MIRAddroffuncConst() = default;
265 
GetValue()266     PUIdx GetValue() const
267     {
268         return puIdx;
269     }
270 #ifdef ARK_LITECG_DEBUG
271     void Dump(const MIRSymbolTable *localSymTab) const override;
272 #endif
273     bool operator==(const MIRConst &rhs) const override;
274 
Clone(MemPool & memPool)275     MIRAddroffuncConst *Clone(MemPool &memPool) const override
276     {
277         return memPool.New<MIRAddroffuncConst>(*this);
278     }
279 
280 private:
281     PUIdx puIdx;
282 };
283 
284 class MIRLblConst : public MIRConst {
285 public:
MIRLblConst(LabelIdx val,PUIdx pidx,MIRType & type)286     MIRLblConst(LabelIdx val, PUIdx pidx, MIRType &type) : MIRConst(type, kConstLblConst), value(val), puIdx(pidx) {}
287 
288     ~MIRLblConst() = default;
289 #ifdef ARK_LITECG_DEBUG
290     void Dump(const MIRSymbolTable *localSymTab) const override;
291 #endif
292     bool operator==(const MIRConst &rhs) const override;
293 
Clone(MemPool & memPool)294     MIRLblConst *Clone(MemPool &memPool) const override
295     {
296         return memPool.New<MIRLblConst>(*this);
297     }
298 
GetValue()299     LabelIdx GetValue() const
300     {
301         return value;
302     }
303 
GetPUIdx()304     PUIdx GetPUIdx() const
305     {
306         return puIdx;
307     }
308 
309 private:
310     LabelIdx value;
311     PUIdx puIdx;
312 };
313 
314 class MIRStrConst : public MIRConst {
315 public:
MIRStrConst(UStrIdx val,MIRType & type)316     MIRStrConst(UStrIdx val, MIRType &type) : MIRConst(type, kConstStrConst), value(val) {}
317 
318     MIRStrConst(const std::string &str, MIRType &type);
319 
320     ~MIRStrConst() = default;
321 #ifdef ARK_LITECG_DEBUG
322     void Dump(const MIRSymbolTable *localSymTab) const override;
323 #endif
324     bool operator==(const MIRConst &rhs) const override;
325 
Clone(MemPool & memPool)326     MIRStrConst *Clone(MemPool &memPool) const override
327     {
328         return memPool.New<MIRStrConst>(*this);
329     }
330 
GetValue()331     UStrIdx GetValue() const
332     {
333         return value;
334     }
335 
GetPrimType()336     static PrimType GetPrimType()
337     {
338         return kPrimType;
339     }
340 
341 private:
342     UStrIdx value;
343     static const PrimType kPrimType = PTY_ptr;
344 };
345 
346 class MIRStr16Const : public MIRConst {
347 public:
MIRStr16Const(const U16StrIdx & val,MIRType & type)348     MIRStr16Const(const U16StrIdx &val, MIRType &type) : MIRConst(type, kConstStr16Const), value(val) {}
349 
350     MIRStr16Const(const std::u16string &str, MIRType &type);
351     ~MIRStr16Const() = default;
352 
GetPrimType()353     static PrimType GetPrimType()
354     {
355         return kPrimType;
356     }
357 #ifdef ARK_LITECG_DEBUG
358     void Dump(const MIRSymbolTable *localSymTab) const override;
359 #endif
360     bool operator==(const MIRConst &rhs) const override;
361 
Clone(MemPool & memPool)362     MIRStr16Const *Clone(MemPool &memPool) const override
363     {
364         return memPool.New<MIRStr16Const>(*this);
365     }
366 
GetValue()367     U16StrIdx GetValue() const
368     {
369         return value;
370     }
371 
372 private:
373     static const PrimType kPrimType = PTY_ptr;
374     U16StrIdx value;
375 };
376 
377 class MIRFloatConst : public MIRConst {
378 public:
379     using value_type = float;
MIRFloatConst(float val,MIRType & type)380     MIRFloatConst(float val, MIRType &type) : MIRConst(type, kConstFloatConst)
381     {
382         value.floatValue = val;
383     }
384 
385     ~MIRFloatConst() = default;
386 
SetFloatValue(float fvalue)387     void SetFloatValue(float fvalue)
388     {
389         value.floatValue = fvalue;
390     }
391 
GetFloatValue()392     value_type GetFloatValue() const
393     {
394         return value.floatValue;
395     }
396 
GetPrimType()397     static PrimType GetPrimType()
398     {
399         return kPrimType;
400     }
401 
GetIntValue()402     int32 GetIntValue() const
403     {
404         return value.intValue;
405     }
406 
GetValue()407     value_type GetValue() const
408     {
409         return GetFloatValue();
410     }
411 #ifdef ARK_LITECG_DEBUG
412     void Dump(const MIRSymbolTable *localSymTab) const override;
413 #endif
IsZero()414     bool IsZero() const override
415     {
416         return fabs(value.floatValue) <= 1e-6;
417     }
418 
IsGeZero()419     bool IsGeZero() const
420     {
421         return value.floatValue >= 0;
422     }
423 
IsNeg()424     bool IsNeg() const
425     {
426         return ((static_cast<uint32>(value.intValue) & 0x80000000) == 0x80000000);
427     }
428 
IsOne()429     bool IsOne() const override
430     {
431         return fabs(value.floatValue - 1) <= 1e-6;
432     };
IsAllBitsOne()433     bool IsAllBitsOne() const
434     {
435         return fabs(value.floatValue + 1) <= 1e-6;
436     };
Neg()437     void Neg() override
438     {
439         value.floatValue = -value.floatValue;
440     }
441 
442     bool operator==(const MIRConst &rhs) const override;
443 
Clone(MemPool & memPool)444     MIRFloatConst *Clone(MemPool &memPool) const override
445     {
446         return memPool.New<MIRFloatConst>(*this);
447     }
448 
449 private:
450     static const PrimType kPrimType = PTY_f32;
451     union {
452         value_type floatValue;
453         int32 intValue;
454     } value;
455 };
456 
457 class MIRDoubleConst : public MIRConst {
458 public:
459     using value_type = double;
MIRDoubleConst(double val,MIRType & type)460     MIRDoubleConst(double val, MIRType &type) : MIRConst(type, kConstDoubleConst)
461     {
462         value.dValue = val;
463     }
464 
465     ~MIRDoubleConst() = default;
466 
GetIntLow32()467     uint32 GetIntLow32() const
468     {
469         auto unsignVal = static_cast<uint64>(value.intValue);
470         return static_cast<uint32>(unsignVal & 0xffffffff);
471     }
472 
GetIntHigh32()473     uint32 GetIntHigh32() const
474     {
475         auto unsignVal = static_cast<uint64>(value.intValue);
476         return static_cast<uint32>((unsignVal & 0xffffffff00000000) >> k32BitSize);
477     }
478 
GetIntValue()479     int64 GetIntValue() const
480     {
481         return value.intValue;
482     }
483 
GetValue()484     value_type GetValue() const
485     {
486         return value.dValue;
487     }
488 
GetPrimType()489     static PrimType GetPrimType()
490     {
491         return kPrimType;
492     }
493 #ifdef ARK_LITECG_DEBUG
494     void Dump(const MIRSymbolTable *localSymTab) const override;
495 #endif
IsZero()496     bool IsZero() const override
497     {
498         return fabs(value.dValue) <= 1e-15;
499     }
500 
IsGeZero()501     bool IsGeZero() const
502     {
503         return value.dValue >= 0;
504     }
505 
IsNeg()506     bool IsNeg() const
507     {
508         return ((static_cast<uint64>(value.intValue) & 0x8000000000000000LL) == 0x8000000000000000LL);
509     }
510 
IsOne()511     bool IsOne() const override
512     {
513         return fabs(value.dValue - 1) <= 1e-15;
514     };
IsAllBitsOne()515     bool IsAllBitsOne() const
516     {
517         return fabs(value.dValue + 1) <= 1e-15;
518     };
Neg()519     void Neg() override
520     {
521         value.dValue = -value.dValue;
522     }
523 
524     bool operator==(const MIRConst &rhs) const override;
525 
Clone(MemPool & memPool)526     MIRDoubleConst *Clone(MemPool &memPool) const override
527     {
528         return memPool.New<MIRDoubleConst>(*this);
529     }
530 
531 private:
532     static const PrimType kPrimType = PTY_f64;
533     union {
534         value_type dValue;
535         int64 intValue;
536     } value;
537 };
538 
539 
540 class MIRAggConst : public MIRConst {
541 public:
MIRAggConst(MIRModule & mod,MIRType & type)542     MIRAggConst(MIRModule &mod, MIRType &type)
543         : MIRConst(type, kConstAggConst),
544           constVec(mod.GetMPAllocator().Adapter()),
545           fieldIdVec(mod.GetMPAllocator().Adapter())
546     {
547     }
548 
549     ~MIRAggConst() = default;
550 
GetAggConstElement(unsigned int fieldId)551     MIRConst *GetAggConstElement(unsigned int fieldId)
552     {
553         for (size_t i = 0; i < fieldIdVec.size(); ++i) {
554             if (fieldId == fieldIdVec[i]) {
555                 return constVec[i];
556             }
557         }
558         return nullptr;
559     }
560 
SetFieldIdOfElement(uint32 index,uint32 fieldId)561     void SetFieldIdOfElement(uint32 index, uint32 fieldId)
562     {
563         DEBUG_ASSERT(index < fieldIdVec.size(), "index out of range");
564         fieldIdVec[index] = fieldId;
565     }
566 
GetConstVec()567     const MapleVector<MIRConst *> &GetConstVec() const
568     {
569         return constVec;
570     }
571 
GetConstVec()572     MapleVector<MIRConst *> &GetConstVec()
573     {
574         return constVec;
575     }
576 
GetConstVecItem(size_t index)577     const MIRConstPtr &GetConstVecItem(size_t index) const
578     {
579         CHECK_FATAL(index < constVec.size(), "index out of range");
580         return constVec[index];
581     }
582 
GetConstVecItem(size_t index)583     MIRConstPtr &GetConstVecItem(size_t index)
584     {
585         CHECK_FATAL(index < constVec.size(), "index out of range");
586         return constVec[index];
587     }
588 
SetConstVecItem(size_t index,MIRConst & st)589     void SetConstVecItem(size_t index, MIRConst &st)
590     {
591         CHECK_FATAL(index < constVec.size(), "index out of range");
592         constVec[index] = &st;
593     }
594 
GetFieldIdItem(size_t index)595     uint32 GetFieldIdItem(size_t index) const
596     {
597         DEBUG_ASSERT(index < fieldIdVec.size(), "index out of range");
598         return fieldIdVec[index];
599     }
600 
SetItem(uint32 index,MIRConst * mirConst,uint32 fieldId)601     void SetItem(uint32 index, MIRConst *mirConst, uint32 fieldId)
602     {
603         CHECK_FATAL(index < constVec.size(), "index out of range");
604         constVec[index] = mirConst;
605         fieldIdVec[index] = fieldId;
606     }
607 
AddItem(MIRConst * mirConst,uint32 fieldId)608     void AddItem(MIRConst *mirConst, uint32 fieldId)
609     {
610         constVec.push_back(mirConst);
611         fieldIdVec.push_back(fieldId);
612     }
613 
PushBack(MIRConst * elem)614     void PushBack(MIRConst *elem)
615     {
616         AddItem(elem, 0);
617     }
618 #ifdef ARK_LITECG_DEBUG
619     void Dump(const MIRSymbolTable *localSymTab) const override;
620 #endif
621     bool operator==(const MIRConst &rhs) const override;
622 
Clone(MemPool & memPool)623     MIRAggConst *Clone(MemPool &memPool) const override
624     {
625         return memPool.New<MIRAggConst>(*this);
626     }
627 
628 private:
629     MapleVector<MIRConst *> constVec;
630     MapleVector<uint32> fieldIdVec;
631 };
632 
633 // the const has one or more symbols
634 class MIRStConst : public MIRConst {
635 public:
MIRStConst(MIRModule & mod,MIRType & type)636     MIRStConst(MIRModule &mod, MIRType &type)
637         : MIRConst(type, kConstStConst),
638           stVec(mod.GetMPAllocator().Adapter()),
639           stOffsetVec(mod.GetMPAllocator().Adapter())
640     {
641     }
642 
GetStVec()643     const MapleVector<MIRSymbol *> &GetStVec() const
644     {
645         return stVec;
646     }
PushbackSymbolToSt(MIRSymbol * sym)647     void PushbackSymbolToSt(MIRSymbol *sym)
648     {
649         stVec.push_back(sym);
650     }
651 
GetStVecItem(size_t index)652     MIRSymbol *GetStVecItem(size_t index)
653     {
654         CHECK_FATAL(index < stVec.size(), "array index out of range");
655         return stVec[index];
656     }
657 
GetStOffsetVec()658     const MapleVector<uint32> &GetStOffsetVec() const
659     {
660         return stOffsetVec;
661     }
PushbackOffsetToSt(uint32 offset)662     void PushbackOffsetToSt(uint32 offset)
663     {
664         stOffsetVec.push_back(offset);
665     }
666 
GetStOffsetVecItem(size_t index)667     uint32 GetStOffsetVecItem(size_t index) const
668     {
669         CHECK_FATAL(index < stOffsetVec.size(), "array index out of range");
670         return stOffsetVec[index];
671     }
672 
Clone(MemPool & memPool)673     MIRStConst *Clone(MemPool &memPool) const override
674     {
675         auto *res = memPool.New<MIRStConst>(*this);
676         return res;
677     }
678 
679     ~MIRStConst() = default;
680 
681 private:
682     MapleVector<MIRSymbol *> stVec;   // symbols that in the st const
683     MapleVector<uint32> stOffsetVec;  // symbols offset
684 };
685 #endif  // MIR_FEATURE_FULL
686 
687 bool IsDivSafe(const MIRIntConst &dividend, const MIRIntConst &divisor, PrimType pType);
688 
689 }  // namespace maple
690 
691 #define LOAD_SAFE_CAST_FOR_MIR_CONST
692 #include "ir_safe_cast_traits.def"
693 
694 #endif  // MAPLE_IR_INCLUDE_MIR_CONST_H
695