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_TYPE_H
17 #define MAPLE_IR_INCLUDE_MIR_TYPE_H
18 #include <algorithm>
19 #include <array>
20 #include "prim_types.h"
21 #include "mir_pragma.h"
22 #include "mpl_logging.h"
23 #if MIR_FEATURE_FULL
24 #include "mempool.h"
25 #include "mempool_allocator.h"
26 #endif // MIR_FEATURE_FULL
27
28 namespace maple {
29 constexpr uint32 kTypeHashLength = 12289; // hash length for mirtype, ref: planetmath.org/goodhashtableprimes
30 const std::string kRenameKeyWord = "_MNO"; // A static symbol name will be renamed as oriname_MNOxxx.
31 const uint8 kAlignBase = 0; // alignment base
32 using MIRTypePtr = MIRType *;
33
34 constexpr size_t kMaxArrayDim = 20;
35 constexpr uint32 kInvalidFieldNum = UINT32_MAX;
36 constexpr size_t kInvalidSize = static_cast<size_t>(UINT64_MAX);
37 #if MIR_FEATURE_FULL
38 extern bool VerifyPrimType(PrimType primType1, PrimType primType2); // verify if primType1 and primType2 match
39 extern PrimType GetExactPtrPrimType(); // return either PTY_a64 or PTY_a32
40 extern uint32 GetPrimTypeSize(PrimType primType); // answer in bytes; 0 if unknown
41 extern uint32 GetPrimTypeP2Size(PrimType primType); // answer in bytes in power-of-two.
42 extern PrimType GetUnsignedPrimType(PrimType pty); // return unsigned version
43 #ifdef ARK_LITECG_DEBUG
44 extern const char *GetPrimTypeName(PrimType primType);
45 #endif
46 extern int64 MinValOfSignedInteger(PrimType primType);
47 extern PrimType GetVecElemPrimType(PrimType primType);
48 constexpr uint32 k0BitSize = 0;
49 constexpr uint32 k1BitSize = 1;
50 constexpr uint32 k2BitSize = 2;
51 constexpr uint32 k3BitSize = 3;
52 constexpr uint32 k4BitSize = 4;
53 constexpr uint32 k5BitSize = 5;
54 constexpr uint32 k7BitSize = 7;
55 constexpr uint32 k8BitSize = 8;
56 constexpr uint32 k9BitSize = 9;
57 constexpr uint32 k10BitSize = 10;
58 constexpr uint32 k16BitSize = 16;
59 constexpr uint32 k32BitSize = 32;
60 constexpr uint32 k64BitSize = 64;
61 constexpr uint32 k4BitShift = 2; /* 4 is 1 << 2; */
62 constexpr uint32 k8BitShift = 3; /* 8 is 1 << 3; */
63 constexpr uint32 k16BitShift = 4; /* 8 is 1 << 3; */
64 constexpr uint32 k2ByteSize = 2;
65 constexpr uint32 k3ByteSize = 3;
66 constexpr uint32 k4ByteSize = 4;
67 constexpr uint32 k7ByteSize = 7;
68 constexpr uint32 k8ByteSize = 8;
69
GetPrimTypeBitSize(PrimType primType)70 inline uint32 GetPrimTypeBitSize(PrimType primType)
71 {
72 // 1 byte = 8 bits = 2^3 bits
73 return GetPrimTypeSize(primType) << k8BitShift;
74 }
75
GetAlignedPrimTypeBitSize(PrimType primType)76 inline uint32 GetAlignedPrimTypeBitSize(PrimType primType)
77 {
78 auto size = GetPrimTypeBitSize(primType);
79 return size <= k32BitSize ? k32BitSize : k64BitSize;
80 }
81
GetPrimTypeActualBitSize(PrimType primType)82 inline uint32 GetPrimTypeActualBitSize(PrimType primType)
83 {
84 // GetPrimTypeSize(PTY_u1) will return 1, so we take it as a special case
85 if (primType == PTY_u1) {
86 return 1;
87 }
88 // 1 byte = 8 bits = 2^3 bits
89 return GetPrimTypeSize(primType) << k8BitShift;
90 }
91
92 #endif // MIR_FEATURE_FULL
93 // return the same type with size increased to register size
94 PrimType GetRegPrimType(PrimType primType);
95 PrimType GetIntegerPrimTypeBySizeAndSign(size_t sizeBit, bool isSign);
96
IsAddress(PrimitiveType primitiveType)97 inline bool IsAddress(PrimitiveType primitiveType)
98 {
99 return primitiveType.IsAddress();
100 }
101
IsPossible64BitAddress(PrimType tp)102 inline bool IsPossible64BitAddress(PrimType tp)
103 {
104 return (tp == PTY_ptr || tp == PTY_ref || tp == PTY_u64 || tp == PTY_a64);
105 }
106
IsPossible32BitAddress(PrimType tp)107 inline bool IsPossible32BitAddress(PrimType tp)
108 {
109 return (tp == PTY_ptr || tp == PTY_ref || tp == PTY_u32);
110 }
111
112
IsPrimitivePureScalar(PrimitiveType primitiveType)113 inline bool IsPrimitivePureScalar(PrimitiveType primitiveType)
114 {
115 return primitiveType.IsInteger() && !primitiveType.IsAddress();
116 }
117
IsPrimitiveUnsigned(PrimitiveType primitiveType)118 inline bool IsPrimitiveUnsigned(PrimitiveType primitiveType)
119 {
120 return primitiveType.IsUnsigned();
121 }
122
IsUnsignedInteger(PrimitiveType primitiveType)123 inline bool IsUnsignedInteger(PrimitiveType primitiveType)
124 {
125 return IsPrimitiveUnsigned(primitiveType) && primitiveType.IsInteger();
126 }
127
IsSignedInteger(PrimitiveType primitiveType)128 inline bool IsSignedInteger(PrimitiveType primitiveType)
129 {
130 return !IsPrimitiveUnsigned(primitiveType) && primitiveType.IsInteger();
131 }
132
IsPrimitiveInteger(PrimitiveType primitiveType)133 inline bool IsPrimitiveInteger(PrimitiveType primitiveType)
134 {
135 return primitiveType.IsInteger();
136 }
137
IsPrimitiveFloat(PrimitiveType primitiveType)138 inline bool IsPrimitiveFloat(PrimitiveType primitiveType)
139 {
140 return primitiveType.IsFloat();
141 }
142
IsPrimitiveScalar(PrimitiveType primitiveType)143 inline bool IsPrimitiveScalar(PrimitiveType primitiveType)
144 {
145 return primitiveType.IsInteger() || primitiveType.IsFloat() || primitiveType.IsSimple();
146 }
147
IsPrimitivePoint(PrimitiveType primitiveType)148 inline bool IsPrimitivePoint(PrimitiveType primitiveType)
149 {
150 return primitiveType.IsPointer();
151 }
152
153 bool IsNoCvtNeeded(PrimType toType, PrimType fromType);
154
155 uint8 GetPointerSize();
156 PrimType GetLoweredPtrType();
157
IsRefOrPtrAssign(PrimType toType,PrimType fromType)158 inline bool IsRefOrPtrAssign(PrimType toType, PrimType fromType)
159 {
160 return (toType == PTY_ref && fromType == PTY_ptr) || (toType == PTY_ptr && fromType == PTY_ref);
161 }
162
163 enum MIRTypeKind : std::uint8_t {
164 kTypeScalar,
165 kTypeArray,
166 kTypePointer,
167 kTypeFunction,
168 kTypeVoid,
169 kTypeByName, // type definition not yet seen
170 };
171
172 enum AttrKind : unsigned {
173 #define TYPE_ATTR
174 #define ATTR(STR) ATTR_##STR,
175 #include "all_attributes.def"
176 #undef ATTR
177 #undef TYPE_ATTR
178 };
179
180 class AttrBoundary {
181 public:
182 AttrBoundary() = default;
183 ~AttrBoundary() = default;
184
185 bool operator==(const AttrBoundary &tA) const
186 {
187 return lenExprHash == tA.lenExprHash && lenParamIdx == tA.lenParamIdx && isBytedLen == tA.isBytedLen;
188 }
189
190 bool operator!=(const AttrBoundary &tA) const
191 {
192 return !(*this == tA);
193 }
194
195 bool operator<(const AttrBoundary &tA) const
196 {
197 return lenExprHash < tA.lenExprHash && lenParamIdx < tA.lenParamIdx &&
198 static_cast<int>(isBytedLen) < static_cast<int>(tA.isBytedLen);
199 }
200
SetLenExprHash(uint32 val)201 void SetLenExprHash(uint32 val)
202 {
203 lenExprHash = val;
204 }
205
GetLenExprHash()206 uint32 GetLenExprHash() const
207 {
208 return lenExprHash;
209 }
210
SetLenParamIdx(int8 idx)211 void SetLenParamIdx(int8 idx)
212 {
213 lenParamIdx = idx;
214 }
215
GetLenParamIdx()216 int8 GetLenParamIdx() const
217 {
218 return lenParamIdx;
219 }
220
SetIsBytedLen(bool flag)221 void SetIsBytedLen(bool flag)
222 {
223 isBytedLen = flag;
224 }
225
IsBytedLen()226 bool IsBytedLen() const
227 {
228 return isBytedLen;
229 }
230
Clear()231 void Clear()
232 {
233 lenExprHash = 0;
234 lenParamIdx = -1;
235 isBytedLen = false;
236 }
237
238 private:
239 bool isBytedLen = false;
240 int8 lenParamIdx = -1;
241 uint32 lenExprHash = 0;
242 };
243
244 class TypeAttrs {
245 public:
246 TypeAttrs() = default;
247 TypeAttrs(const TypeAttrs &ta) = default;
248 TypeAttrs &operator=(const TypeAttrs &t) = default;
249 ~TypeAttrs() = default;
250
GetAlignValue()251 uint8 GetAlignValue() const
252 {
253 return attrAlign;
254 }
255
SetAttrFlag(uint64 flag)256 void SetAttrFlag(uint64 flag)
257 {
258 attrFlag = flag;
259 }
260
GetTypeAlignValue()261 uint8 GetTypeAlignValue() const
262 {
263 return attrTypeAlign;
264 }
265
GetAttrFlag()266 uint64 GetAttrFlag() const
267 {
268 return attrFlag;
269 }
270
SetAttr(AttrKind x)271 void SetAttr(AttrKind x)
272 {
273 attrFlag |= (1ULL << static_cast<unsigned int>(x));
274 }
275
ResetAttr(AttrKind x)276 void ResetAttr(AttrKind x)
277 {
278 attrFlag &= ~(1ULL << static_cast<unsigned int>(x));
279 }
280
GetAttr(AttrKind x)281 bool GetAttr(AttrKind x) const
282 {
283 return (attrFlag & (1ULL << static_cast<unsigned int>(x))) != 0;
284 }
285
SetAlign(uint32 x)286 void SetAlign(uint32 x)
287 {
288 DEBUG_ASSERT((~(x - 1) & x) == x, "SetAlign called with non-power-of-2");
289 attrAlign = 0;
290 while (x != 1) {
291 x >>= 1;
292 ++attrAlign;
293 }
294 }
295
GetAlign()296 uint32 GetAlign() const
297 {
298 if (attrAlign == 0) {
299 return 1;
300 }
301 uint32 res = 1;
302 uint32 exp = attrAlign;
303 do {
304 --exp;
305 res <<= 1;
306 } while (exp != 0);
307 return res;
308 }
309
SetTypeAlign(uint32 x)310 void SetTypeAlign(uint32 x)
311 {
312 DEBUG_ASSERT((~(x - 1) & x) == x, "SetTypeAlign called with non-power-of-2");
313 attrTypeAlign = 0;
314 while (x != kAlignBase) {
315 x >>= 1;
316 ++attrTypeAlign;
317 }
318 }
319
GetTypeAlign()320 uint32 GetTypeAlign() const
321 {
322 if (attrTypeAlign == 1) { // align(1)
323 return 1;
324 }
325 constexpr uint32 square = 2;
326 uint32 res = 1;
327 uint32 exp = attrTypeAlign;
328 while (exp > 1) { // calculate align(x)
329 --exp;
330 res *= square;
331 }
332 return res;
333 }
334
335 bool operator==(const TypeAttrs &tA) const
336 {
337 return attrFlag == tA.attrFlag && attrAlign == tA.attrAlign && attrBoundary == tA.attrBoundary;
338 }
339
340 bool operator!=(const TypeAttrs &tA) const
341 {
342 return !(*this == tA);
343 }
344
345 #ifdef ARK_LITECG_DEBUG
346 void DumpAttributes() const;
347 #endif
348
GetAttrBoundary()349 const AttrBoundary &GetAttrBoundary() const
350 {
351 return attrBoundary;
352 }
353
GetAttrBoundary()354 AttrBoundary &GetAttrBoundary()
355 {
356 return attrBoundary;
357 }
358
AddAttrBoundary(const AttrBoundary & attr)359 void AddAttrBoundary(const AttrBoundary &attr)
360 {
361 if (attr.GetLenExprHash() != 0) {
362 attrBoundary.SetLenExprHash(attr.GetLenExprHash());
363 }
364 if (attr.GetLenParamIdx() != -1) {
365 attrBoundary.SetLenParamIdx(attr.GetLenParamIdx());
366 }
367 if (attr.IsBytedLen()) {
368 attrBoundary.SetIsBytedLen(attr.IsBytedLen());
369 }
370 }
371
SetPack(uint32 pack)372 void SetPack(uint32 pack)
373 {
374 attrPack = pack;
375 }
376
GetPack()377 uint32 GetPack() const
378 {
379 return attrPack;
380 }
381
IsPacked()382 bool IsPacked() const
383 {
384 return GetAttr(ATTR_pack);
385 }
386
HasPack()387 bool HasPack() const
388 {
389 return GetAttr(ATTR_pack);
390 }
391
IsTypedef()392 bool IsTypedef() const
393 {
394 return GetAttr(ATTR_typedef);
395 }
396
GetOriginType()397 MIRType *GetOriginType() const
398 {
399 return originType;
400 }
401
402 private:
403 uint64 attrFlag = 0;
404 uint8 attrAlign = 0; // alignment in bytes is 2 to the power of attrAlign
405 uint8 attrTypeAlign = 0; // alignment in bytes is 2 to the power of attrTypeAlign
406 uint32 attrPack = -1; // -1 means inactive
407 AttrBoundary attrBoundary; // boundary attr for EnhanceC
408 MIRType *originType = nullptr;
409 };
410
411 enum FieldAttrKind {
412 #define FIELD_ATTR
413 #define ATTR(STR) FLDATTR_##STR,
414 #include "all_attributes.def"
415 #undef ATTR
416 #undef FIELD_ATTR
417 };
418
419 enum StmtAttrKind : unsigned {
420 #define STMT_ATTR
421 #define ATTR(STR) STMTATTR_##STR,
422 #include "all_attributes.def"
423 #undef ATTR
424 #undef STMT_ATTR
425 };
426
427 class StmtAttrs {
428 public:
429 StmtAttrs() = default;
430 StmtAttrs(const StmtAttrs &ta) = default;
431 StmtAttrs &operator=(const StmtAttrs &p) = default;
432 ~StmtAttrs() = default;
433
434 void SetAttr(StmtAttrKind x, bool flag = true)
435 {
436 if (flag) {
437 attrFlag |= (1u << static_cast<unsigned int>(x));
438 } else {
439 attrFlag &= ~(1u << static_cast<unsigned int>(x));
440 }
441 }
442
GetAttr(StmtAttrKind x)443 bool GetAttr(StmtAttrKind x) const
444 {
445 return (attrFlag & (1u << static_cast<unsigned int>(x))) != 0;
446 }
447
GetTargetAttrFlag(StmtAttrKind x)448 uint32 GetTargetAttrFlag(StmtAttrKind x) const
449 {
450 return attrFlag & (1u << static_cast<unsigned int>(x));
451 }
452
GetAttrFlag()453 uint32 GetAttrFlag() const
454 {
455 return attrFlag;
456 }
457
AppendAttr(uint32 flag)458 void AppendAttr(uint32 flag)
459 {
460 attrFlag |= flag;
461 }
462
Clear()463 void Clear()
464 {
465 attrFlag = 0;
466 }
467
468 #ifdef ARK_LITECG_DEBUG
469 void DumpAttributes() const;
470 #endif
471
472 private:
473 uint32 attrFlag = 0;
474 };
475
476 enum FuncAttrKind : unsigned {
477 #define FUNC_ATTR
478 #define ATTR(STR) FUNCATTR_##STR,
479 #include "all_attributes.def"
480 #undef ATTR
481 #undef FUNC_ATTR
482 };
483
484 class FuncAttrs {
485 public:
486 FuncAttrs() = default;
487 FuncAttrs(const FuncAttrs &ta) = default;
488 FuncAttrs &operator=(const FuncAttrs &p) = default;
489 ~FuncAttrs() = default;
490
491 void SetAttr(FuncAttrKind x, bool unSet = false)
492 {
493 if (!unSet) {
494 attrFlag |= (1ULL << x);
495 } else {
496 attrFlag &= ~(1ULL << x);
497 }
498 }
499
SetAliasFuncName(const std::string & name)500 void SetAliasFuncName(const std::string &name)
501 {
502 aliasFuncName = name;
503 }
504
GetAliasFuncName()505 const std::string &GetAliasFuncName() const
506 {
507 return aliasFuncName;
508 }
509
SetPrefixSectionName(const std::string & name)510 void SetPrefixSectionName(const std::string &name)
511 {
512 prefixSectionName = name;
513 }
514
GetPrefixSectionName()515 const std::string &GetPrefixSectionName() const
516 {
517 return prefixSectionName;
518 }
519
SetAttrFlag(uint64 flag)520 void SetAttrFlag(uint64 flag)
521 {
522 attrFlag = flag;
523 }
524
GetAttrFlag()525 uint64 GetAttrFlag() const
526 {
527 return attrFlag;
528 }
529
GetAttr(FuncAttrKind x)530 bool GetAttr(FuncAttrKind x) const
531 {
532 return (attrFlag & (1ULL << x)) != 0;
533 }
534
535 bool operator==(const FuncAttrs &tA) const
536 {
537 return attrFlag == tA.attrFlag;
538 }
539
540 bool operator!=(const FuncAttrs &tA) const
541 {
542 return !(*this == tA);
543 }
544
545 #ifdef ARK_LITECG_DEBUG
546 void DumpAttributes() const;
547 #endif
548
GetAttrBoundary()549 const AttrBoundary &GetAttrBoundary() const
550 {
551 return attrBoundary;
552 }
553
GetAttrBoundary()554 AttrBoundary &GetAttrBoundary()
555 {
556 return attrBoundary;
557 }
558
SetConstructorPriority(int priority)559 void SetConstructorPriority(int priority)
560 {
561 constructorPriority = priority;
562 }
563
GetConstructorPriority()564 int GetConstructorPriority() const
565 {
566 return constructorPriority;
567 }
568
SetDestructorPriority(int priority)569 void SetDestructorPriority(int priority)
570 {
571 destructorPriority = priority;
572 }
573
GetDestructorPriority()574 int GetDestructorPriority() const
575 {
576 return destructorPriority;
577 }
578
GetFrameResverdSlot()579 int GetFrameResverdSlot() const
580 {
581 return frameResverdSlot;
582 }
583
SetFrameResverdSlot(int slot)584 void SetFrameResverdSlot(int slot)
585 {
586 SetAttr(FUNCATTR_frame_pointer);
587 frameResverdSlot = slot;
588 }
589
SetFramePointer(std::string framePointer_)590 void SetFramePointer(std::string framePointer_)
591 {
592 SetAttr(FUNCATTR_frame_reserved_slots);
593 framePointer = framePointer_;
594 }
595
596 private:
597 uint64 attrFlag = 0;
598 std::string aliasFuncName;
599 std::string prefixSectionName;
600 std::string framePointer;
601 AttrBoundary attrBoundary; // ret boundary for EnhanceC
602 int constructorPriority = -1; // 0~65535, -1 means inactive
603 int destructorPriority = -1; // 0~65535, -1 means inactive
604 int frameResverdSlot = 0;
605 };
606
607 #if MIR_FEATURE_FULL
608 constexpr size_t kShiftNumOfTypeKind = 8;
609 constexpr size_t kShiftNumOfNameStrIdx = 6;
610 constexpr int32 kOffsetUnknown = INT_MAX;
611 constexpr int32 kOffsetMax = (INT_MAX - 1);
612 constexpr int32 kOffsetMin = INT_MIN;
613 struct OffsetType {
OffsetTypeOffsetType614 explicit OffsetType(int64 offset)
615 {
616 Set(offset);
617 }
618
OffsetTypeOffsetType619 OffsetType(const OffsetType &other) : val(other.val) {}
620
621 ~OffsetType() = default;
622
SetOffsetType623 void Set(int64 offsetVal)
624 {
625 val = (offsetVal >= kOffsetMin && offsetVal <= kOffsetMax) ? static_cast<int32>(offsetVal) : kOffsetUnknown;
626 }
627
IsInvalidOffsetType628 bool IsInvalid() const
629 {
630 return val == kOffsetUnknown;
631 }
632
633 OffsetType &operator=(const OffsetType &other)
634 {
635 val = other.val;
636 return *this;
637 }
638
639 OffsetType operator+(int64 offset) const
640 {
641 if (this->IsInvalid() || OffsetType(offset).IsInvalid()) {
642 return InvalidOffset();
643 }
644 return OffsetType(val + offset);
645 }
646
647 OffsetType operator+(OffsetType other) const
648 {
649 return other + val;
650 }
651
652 void operator+=(int64 offset)
653 {
654 if (this->IsInvalid() || OffsetType(offset).IsInvalid()) {
655 val = kOffsetUnknown;
656 return;
657 }
658 Set(offset + val);
659 }
660
661 void operator+=(OffsetType other)
662 {
663 this->operator+=(other.val);
664 }
665
666 OffsetType operator-() const
667 {
668 if (this->IsInvalid()) {
669 return *this;
670 }
671 return OffsetType(-val);
672 }
673
674 bool operator<(OffsetType other) const
675 {
676 return val < other.val;
677 }
678
679 bool operator==(OffsetType other) const
680 {
681 return val == other.val;
682 }
683
684 bool operator!=(OffsetType other) const
685 {
686 return val != other.val;
687 }
688
InvalidOffsetOffsetType689 static OffsetType InvalidOffset()
690 {
691 return OffsetType(kOffsetUnknown);
692 }
693
694 int32 val = kOffsetUnknown;
695 };
696 class MIRFuncType;
697
698 class MIRType {
699 public:
MIRType(MIRTypeKind kind)700 MIRType(MIRTypeKind kind) : typeKind(kind) {}
701
MIRType(MIRTypeKind kind,PrimType pType)702 MIRType(MIRTypeKind kind, PrimType pType) : typeKind(kind), primType(pType) {}
703
MIRType(MIRTypeKind kind,GStrIdx strIdx)704 MIRType(MIRTypeKind kind, GStrIdx strIdx) : typeKind(kind), nameStrIdx(strIdx) {}
705
MIRType(MIRTypeKind kind,PrimType pType,GStrIdx strIdx)706 MIRType(MIRTypeKind kind, PrimType pType, GStrIdx strIdx) : typeKind(kind), primType(pType), nameStrIdx(strIdx) {}
707
708 virtual ~MIRType() = default;
709 #ifdef ARK_LITECG_DEBUG
710 virtual void Dump(int indent, bool dontUseName = false) const;
711 virtual void DumpAsCxx(int indent) const;
712 #endif
713 virtual bool EqualTo(const MIRType &mirType) const;
714
CopyMIRTypeNode()715 virtual MIRType *CopyMIRTypeNode() const
716 {
717 return new MIRType(*this);
718 }
719
GetPrimType()720 PrimType GetPrimType() const
721 {
722 return primType;
723 }
SetPrimType(const PrimType pt)724 void SetPrimType(const PrimType pt)
725 {
726 primType = pt;
727 }
728
GetTypeIndex()729 TyIdx GetTypeIndex() const
730 {
731 return tyIdx;
732 }
SetTypeIndex(TyIdx idx)733 void SetTypeIndex(TyIdx idx)
734 {
735 tyIdx = idx;
736 }
737
GetKind()738 MIRTypeKind GetKind() const
739 {
740 return typeKind;
741 }
SetMIRTypeKind(MIRTypeKind kind)742 void SetMIRTypeKind(MIRTypeKind kind)
743 {
744 typeKind = kind;
745 }
746
IsNameIsLocal()747 bool IsNameIsLocal() const
748 {
749 return nameIsLocal;
750 }
SetNameIsLocal(bool flag)751 void SetNameIsLocal(bool flag)
752 {
753 nameIsLocal = flag;
754 }
755
GetNameStrIdx()756 GStrIdx GetNameStrIdx() const
757 {
758 return nameStrIdx;
759 }
SetNameStrIdx(GStrIdx strIdx)760 void SetNameStrIdx(GStrIdx strIdx)
761 {
762 nameStrIdx = strIdx;
763 }
SetNameStrIdxItem(uint32 idx)764 void SetNameStrIdxItem(uint32 idx)
765 {
766 nameStrIdx.reset(idx);
767 }
768
GetSize()769 virtual size_t GetSize() const
770 {
771 return GetPrimTypeSize(primType);
772 }
773
GetAlign()774 virtual uint32 GetAlign() const
775 {
776 return GetPrimTypeSize(primType);
777 }
778
GetUnadjustedAlign()779 virtual uint32 GetUnadjustedAlign() const
780 {
781 return GetPrimTypeSize(primType);
782 }
783
HasVolatileField()784 virtual bool HasVolatileField() const
785 {
786 return false;
787 }
788
HasTypeParam()789 virtual bool HasTypeParam() const
790 {
791 return false;
792 }
793
794 bool IsVolatile(int fieldID) const;
795
IsMIRPtrType()796 bool IsMIRPtrType() const
797 {
798 return typeKind == kTypePointer;
799 }
800
IsMIRArrayType()801 bool IsMIRArrayType() const
802 {
803 return typeKind == kTypeArray;
804 }
805
IsMIRFuncType()806 bool IsMIRFuncType() const
807 {
808 return typeKind == kTypeFunction;
809 }
810
IsScalarType()811 bool IsScalarType() const
812 {
813 return typeKind == kTypeScalar;
814 }
815
IsMIRTypeByName()816 bool IsMIRTypeByName() const
817 {
818 return typeKind == kTypeByName;
819 }
820
GetHashIndex()821 virtual size_t GetHashIndex() const
822 {
823 constexpr uint8 idxShift = 2;
824 return ((static_cast<uint32>(primType) << idxShift) + (typeKind << kShiftNumOfTypeKind)) % kTypeHashLength;
825 }
826
827 protected:
828 MIRTypeKind typeKind;
829 PrimType primType;
830 bool nameIsLocal = false; // needed when printing the type name
831 TyIdx tyIdx {0};
832 GStrIdx nameStrIdx {0}; // name in global string table
833 };
834
835 class MIRPtrType : public MIRType {
836 public:
MIRPtrType(TyIdx pTyIdx)837 explicit MIRPtrType(TyIdx pTyIdx) : MIRType(kTypePointer, PTY_ptr), pointedTyIdx(pTyIdx) {}
838
MIRPtrType(TyIdx pTyIdx,PrimType pty)839 MIRPtrType(TyIdx pTyIdx, PrimType pty) : MIRType(kTypePointer, pty), pointedTyIdx(pTyIdx) {}
840
MIRPtrType(PrimType primType,GStrIdx strIdx)841 MIRPtrType(PrimType primType, GStrIdx strIdx) : MIRType(kTypePointer, primType, strIdx), pointedTyIdx(0) {}
842
843 ~MIRPtrType() override = default;
844
CopyMIRTypeNode()845 MIRType *CopyMIRTypeNode() const override
846 {
847 return new MIRPtrType(*this);
848 }
849
850 MIRType *GetPointedType() const;
851
GetPointedTyIdx()852 TyIdx GetPointedTyIdx() const
853 {
854 return pointedTyIdx;
855 }
SetPointedTyIdx(TyIdx idx)856 void SetPointedTyIdx(TyIdx idx)
857 {
858 pointedTyIdx = idx;
859 }
860
GetTypeAttrs()861 TypeAttrs &GetTypeAttrs()
862 {
863 return typeAttrs;
864 }
865
GetTypeAttrs()866 const TypeAttrs &GetTypeAttrs() const
867 {
868 return typeAttrs;
869 }
870
SetTypeAttrs(const TypeAttrs & attrs)871 void SetTypeAttrs(const TypeAttrs &attrs)
872 {
873 typeAttrs = attrs;
874 }
875
876 bool EqualTo(const MIRType &type) const override;
877 bool HasTypeParam() const override;
878 bool IsPointedTypeVolatile(int fieldID) const;
879 #ifdef ARK_LITECG_DEBUG
880 void Dump(int indent, bool dontUseName = false) const override;
881 #endif
882 size_t GetSize() const override;
883 uint32 GetAlign() const override;
GetHashIndex()884 size_t GetHashIndex() const override
885 {
886 constexpr uint8 idxShift = 4;
887 constexpr uint8 attrShift = 3;
888 size_t hIdx = (static_cast<size_t>(pointedTyIdx) << idxShift) + (typeKind << kShiftNumOfTypeKind);
889 hIdx += (typeAttrs.GetAttrFlag() << attrShift) + typeAttrs.GetAlignValue();
890 return hIdx % kTypeHashLength;
891 }
IsFunctionPtr()892 bool IsFunctionPtr() const
893 {
894 MIRType *pointedType = GetPointedType();
895 if (pointedType->GetKind() == kTypeFunction) {
896 return true;
897 }
898 if (pointedType->GetKind() == kTypePointer) {
899 MIRPtrType *pointedPtrType = static_cast<MIRPtrType *>(pointedType);
900 return pointedPtrType->GetPointedType()->GetKind() == kTypeFunction;
901 }
902 return false;
903 }
904
905 MIRFuncType *GetPointedFuncType() const;
906
907 #ifdef ARK_LITECG_DEBUG
908 bool PointsToConstString() const;
909 #endif
910
911 private:
912 TyIdx pointedTyIdx;
913 TypeAttrs typeAttrs;
914 };
915
916 class MIRArrayType : public MIRType {
917 public:
MIRArrayType()918 MIRArrayType() : MIRType(kTypeArray) {}
MIRArrayType(GStrIdx strIdx)919 explicit MIRArrayType(GStrIdx strIdx) : MIRType(kTypeArray, strIdx) {}
920
MIRArrayType(TyIdx eTyIdx,const std::vector<uint64> & sizeArray)921 MIRArrayType(TyIdx eTyIdx, const std::vector<uint64> &sizeArray)
922 : MIRType(kTypeArray), eTyIdx(eTyIdx), dim(sizeArray.size())
923 {
924 for (size_t i = 0; i < kMaxArrayDim; ++i) {
925 this->sizeArray[i] = (i < dim) ? sizeArray[i] : 0;
926 }
927 }
928
929 MIRArrayType(const MIRArrayType &pat) = default;
930 MIRArrayType &operator=(const MIRArrayType &p) = default;
931 ~MIRArrayType() override = default;
932
GetElemTyIdx()933 TyIdx GetElemTyIdx() const
934 {
935 return eTyIdx;
936 }
SetElemTyIdx(TyIdx idx)937 void SetElemTyIdx(TyIdx idx)
938 {
939 eTyIdx = idx;
940 }
941
GetSizeArrayItem(uint32 n)942 uint64 GetSizeArrayItem(uint32 n) const
943 {
944 CHECK_FATAL((n >= 0 && n < kMaxArrayDim), "out of bound of array!");
945 return sizeArray[n];
946 }
SetSizeArrayItem(uint32 idx,uint64 value)947 void SetSizeArrayItem(uint32 idx, uint64 value)
948 {
949 CHECK_FATAL((idx >= 0 && idx < kMaxArrayDim), "out of bound of array!");
950 sizeArray[idx] = value;
951 }
952
IsIncompleteArray()953 bool IsIncompleteArray() const
954 {
955 return typeAttrs.GetAttr(ATTR_incomplete_array);
956 }
957
958 bool EqualTo(const MIRType &type) const override;
959
GetDim()960 uint16 GetDim() const
961 {
962 return dim;
963 }
SetDim(uint16 newDim)964 void SetDim(uint16 newDim)
965 {
966 this->dim = newDim;
967 }
968
GetTypeAttrs()969 const TypeAttrs &GetTypeAttrs() const
970 {
971 return typeAttrs;
972 }
973
GetTypeAttrs()974 TypeAttrs &GetTypeAttrs()
975 {
976 return typeAttrs;
977 }
978
SetTypeAttrs(const TypeAttrs & attrs)979 void SetTypeAttrs(const TypeAttrs &attrs)
980 {
981 typeAttrs = attrs;
982 }
983
984 MIRType *GetElemType() const;
985
CopyMIRTypeNode()986 MIRType *CopyMIRTypeNode() const override
987 {
988 return new MIRArrayType(*this);
989 }
990
HasTypeParam()991 bool HasTypeParam() const override
992 {
993 return GetElemType()->HasTypeParam();
994 }
995 #ifdef ARK_LITECG_DEBUG
996 void Dump(int indent, bool dontUseName) const override;
997 #endif
998 size_t GetSize() const override;
999 uint32 GetAlign() const override;
1000
GetHashIndex()1001 size_t GetHashIndex() const override
1002 {
1003 constexpr uint8 idxShift = 2;
1004 size_t hIdx = (static_cast<size_t>(eTyIdx) << idxShift) + (typeKind << kShiftNumOfTypeKind);
1005 for (size_t i = 0; i < dim; ++i) {
1006 CHECK_FATAL(i < kMaxArrayDim, "array index out of range");
1007 hIdx += (sizeArray[i] << i);
1008 }
1009 constexpr uint8 attrShift = 3;
1010 hIdx += (typeAttrs.GetAttrFlag() << attrShift) + typeAttrs.GetAlignValue();
1011 return hIdx % kTypeHashLength;
1012 }
1013
1014 #ifdef ARK_LITECG_DEBUG
1015 size_t ElemNumber() const;
1016 #endif
1017
1018 private:
1019 TyIdx eTyIdx {0};
1020 uint16 dim = 0;
1021 std::array<uint64, kMaxArrayDim> sizeArray {{0}};
1022 TypeAttrs typeAttrs;
1023 mutable size_t size = kInvalidSize;
1024 };
1025
1026 using TyidxFuncAttrPair = std::pair<TyIdx, FuncAttrs>;
1027 using MethodPair = std::pair<StIdx, TyidxFuncAttrPair>;
1028 using MethodVector = std::vector<MethodPair>;
1029 using MethodPtrVector = std::vector<MethodPair *>;
1030 using MIREncodedArray = std::vector<EncodedValue>;
1031 class GenericDeclare;
1032 class AnnotationType;
1033 class GenericType;
1034
1035 class MIRFuncType : public MIRType {
1036 public:
MIRFuncType()1037 MIRFuncType() : MIRType(kTypeFunction, PTY_ptr) {}
1038
MIRFuncType(const GStrIdx & strIdx)1039 explicit MIRFuncType(const GStrIdx &strIdx) : MIRType(kTypeFunction, PTY_ptr, strIdx) {}
1040
MIRFuncType(const TyIdx & retTyIdx,const std::vector<TyIdx> & vecTy,const std::vector<TypeAttrs> & vecAt,const TypeAttrs & retAttrsIn)1041 MIRFuncType(const TyIdx &retTyIdx, const std::vector<TyIdx> &vecTy, const std::vector<TypeAttrs> &vecAt,
1042 const TypeAttrs &retAttrsIn)
1043 : MIRType(kTypeFunction, PTY_ptr),
1044 retTyIdx(retTyIdx),
1045 paramTypeList(vecTy),
1046 paramAttrsList(vecAt),
1047 retAttrs(retAttrsIn)
1048 {
1049 }
1050
1051 ~MIRFuncType() override = default;
1052
1053 bool EqualTo(const MIRType &type) const override;
CopyMIRTypeNode()1054 MIRType *CopyMIRTypeNode() const override
1055 {
1056 return new MIRFuncType(*this);
1057 }
1058 #ifdef ARK_LITECG_DEBUG
1059 void Dump(int indent, bool dontUseName = false) const override;
1060 #endif
GetSize()1061 size_t GetSize() const override
1062 {
1063 return 0;
1064 } // size unknown
1065
GetRetTyIdx()1066 TyIdx GetRetTyIdx() const
1067 {
1068 return retTyIdx;
1069 }
1070
SetRetTyIdx(TyIdx idx)1071 void SetRetTyIdx(TyIdx idx)
1072 {
1073 retTyIdx = idx;
1074 }
1075
GetParamTypeList()1076 const std::vector<TyIdx> &GetParamTypeList() const
1077 {
1078 return paramTypeList;
1079 }
1080
GetParamTypeList()1081 std::vector<TyIdx> &GetParamTypeList()
1082 {
1083 return paramTypeList;
1084 }
1085
GetNthParamType(size_t i)1086 TyIdx GetNthParamType(size_t i) const
1087 {
1088 DEBUG_ASSERT(i < paramTypeList.size(), "array index out of range");
1089 return paramTypeList[i];
1090 }
1091
SetParamTypeList(const std::vector<TyIdx> & list)1092 void SetParamTypeList(const std::vector<TyIdx> &list)
1093 {
1094 paramTypeList.clear();
1095 (void)paramTypeList.insert(paramTypeList.begin(), list.begin(), list.end());
1096 }
1097
GetParamAttrsList()1098 const std::vector<TypeAttrs> &GetParamAttrsList() const
1099 {
1100 return paramAttrsList;
1101 }
1102
GetParamAttrsList()1103 std::vector<TypeAttrs> &GetParamAttrsList()
1104 {
1105 return paramAttrsList;
1106 }
1107
GetNthParamAttrs(size_t i)1108 const TypeAttrs &GetNthParamAttrs(size_t i) const
1109 {
1110 DEBUG_ASSERT(i < paramAttrsList.size(), "array index out of range");
1111 return paramAttrsList[i];
1112 }
1113
GetNthParamAttrs(size_t i)1114 TypeAttrs &GetNthParamAttrs(size_t i)
1115 {
1116 DEBUG_ASSERT(i < paramAttrsList.size(), "array index out of range");
1117 return paramAttrsList[i];
1118 }
1119
SetParamAttrsList(const std::vector<TypeAttrs> & list)1120 void SetParamAttrsList(const std::vector<TypeAttrs> &list)
1121 {
1122 paramAttrsList.clear();
1123 (void)paramAttrsList.insert(paramAttrsList.begin(), list.begin(), list.end());
1124 }
1125
SetNthParamAttrs(size_t i,const TypeAttrs & attrs)1126 void SetNthParamAttrs(size_t i, const TypeAttrs &attrs)
1127 {
1128 DEBUG_ASSERT(i < paramAttrsList.size(), "array index out of range");
1129 paramAttrsList[i] = attrs;
1130 }
1131
IsVarargs()1132 bool IsVarargs() const
1133 {
1134 return funcAttrs.GetAttr(FUNCATTR_varargs);
1135 }
1136
SetVarArgs()1137 void SetVarArgs()
1138 {
1139 funcAttrs.SetAttr(FUNCATTR_varargs);
1140 }
1141
FirstArgReturn()1142 bool FirstArgReturn() const
1143 {
1144 return funcAttrs.GetAttr(FUNCATTR_firstarg_return);
1145 }
1146
SetFirstArgReturn()1147 void SetFirstArgReturn()
1148 {
1149 funcAttrs.SetAttr(FUNCATTR_firstarg_return);
1150 }
1151
GetRetAttrs()1152 const TypeAttrs &GetRetAttrs() const
1153 {
1154 return retAttrs;
1155 }
1156
GetRetAttrs()1157 TypeAttrs &GetRetAttrs()
1158 {
1159 return retAttrs;
1160 }
1161
SetRetAttrs(const TypeAttrs & attrs)1162 void SetRetAttrs(const TypeAttrs &attrs)
1163 {
1164 retAttrs = attrs;
1165 }
1166
GetHashIndex()1167 size_t GetHashIndex() const override
1168 {
1169 constexpr uint8 idxShift = 6;
1170 size_t hIdx = (static_cast<size_t>(retTyIdx) << idxShift) + (typeKind << kShiftNumOfTypeKind);
1171 size_t size = paramTypeList.size();
1172 hIdx += (size ? (static_cast<size_t>(paramTypeList[0]) + size) : 0) << 4; // shift bit is 4
1173 return hIdx % kTypeHashLength;
1174 }
1175
1176 public:
1177 FuncAttrs funcAttrs;
1178
1179 private:
1180 TyIdx retTyIdx {0};
1181 std::vector<TyIdx> paramTypeList;
1182 std::vector<TypeAttrs> paramAttrsList;
1183 TypeAttrs retAttrs;
1184 };
1185
1186 class MIRTypeByName : public MIRType {
1187 // use nameStrIdx to store the name for both local and global
1188 public:
MIRTypeByName(GStrIdx gStrIdx)1189 explicit MIRTypeByName(GStrIdx gStrIdx) : MIRType(kTypeByName, PTY_void)
1190 {
1191 nameStrIdx = gStrIdx;
1192 }
1193
1194 ~MIRTypeByName() override = default;
1195
CopyMIRTypeNode()1196 MIRType *CopyMIRTypeNode() const override
1197 {
1198 return new MIRTypeByName(*this);
1199 }
1200
1201 bool EqualTo(const MIRType &type) const override;
1202 #ifdef ARK_LITECG_DEBUG
1203 void Dump(int indent, bool dontUseName = false) const override;
1204 #endif
GetSize()1205 size_t GetSize() const override
1206 {
1207 return 0;
1208 } // size unknown
1209
GetHashIndex()1210 size_t GetHashIndex() const override
1211 {
1212 constexpr uint8 idxShift = 2;
1213 return ((static_cast<size_t>(nameStrIdx) << idxShift) + nameIsLocal + (typeKind << kShiftNumOfTypeKind)) %
1214 kTypeHashLength;
1215 }
1216 };
1217 // aarch64 specific
1218 bool IsHomogeneousAggregates(const MIRType &ty, PrimType &primType, size_t &elemNum, bool firstDepth = true);
1219 bool IsParamStructCopyToMemory(const MIRType &ty);
1220 #endif // MIR_FEATURE_FULL
1221 } // namespace maple
1222
1223 #define LOAD_SAFE_CAST_FOR_MIR_TYPE
1224 #include "ir_safe_cast_traits.def"
1225
1226 #endif // MAPLE_IR_INCLUDE_MIR_TYPE_H
1227