• 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 MAPLEBE_INCLUDE_CG_INSN_H
17 #define MAPLEBE_INCLUDE_CG_INSN_H
18 /* C++ headers */
19 #include <cstddef> /* for nullptr */
20 #include <string>
21 #include <vector>
22 #include <list>
23 #include "operand.h"
24 #include "stackmap.h"
25 #include "mpl_logging.h"
26 #include "sparse_datainfo.h"
27 
28 /* Maple IR header */
29 #include "types_def.h" /* for uint32 */
30 #include "common_utils.h"
31 
32 namespace maplebe {
33 /* forward declaration */
34 class BB;
35 class CG;
36 class Emitter;
37 class DepNode;
38 struct InsnDesc;
39 class Insn {
40 public:
41     enum RetType : uint8 {
42         kRegNull,  /* no return type */
43         kRegFloat, /* return register is V0 */
44         kRegInt    /* return register is R0 */
45     };
46     /* MCC_DecRefResetPair clear 2 stack position, MCC_ClearLocalStackRef clear 1 stack position */
47     static constexpr uint8 kMaxStackOffsetSize = 2;
48 
Insn(MemPool & memPool,MOperator opc)49     Insn(MemPool &memPool, MOperator opc)
50         : mOp(opc),
51           localAlloc(&memPool),
52           opnds(localAlloc.Adapter()),
53           registerBinding(localAlloc.Adapter()),
54           comment(&memPool)
55     {
56     }
Insn(MemPool & memPool,MOperator opc,Operand & opnd0)57     Insn(MemPool &memPool, MOperator opc, Operand &opnd0) : Insn(memPool, opc)
58     {
59         opnds.emplace_back(&opnd0);
60     }
Insn(MemPool & memPool,MOperator opc,Operand & opnd0,Operand & opnd1)61     Insn(MemPool &memPool, MOperator opc, Operand &opnd0, Operand &opnd1) : Insn(memPool, opc)
62     {
63         opnds.emplace_back(&opnd0);
64         opnds.emplace_back(&opnd1);
65     }
Insn(MemPool & memPool,MOperator opc,Operand & opnd0,Operand & opnd1,Operand & opnd2)66     Insn(MemPool &memPool, MOperator opc, Operand &opnd0, Operand &opnd1, Operand &opnd2) : Insn(memPool, opc)
67     {
68         opnds.emplace_back(&opnd0);
69         opnds.emplace_back(&opnd1);
70         opnds.emplace_back(&opnd2);
71     }
Insn(MemPool & memPool,MOperator opc,Operand & opnd0,Operand & opnd1,Operand & opnd2,Operand & opnd3)72     Insn(MemPool &memPool, MOperator opc, Operand &opnd0, Operand &opnd1, Operand &opnd2, Operand &opnd3)
73         : Insn(memPool, opc)
74     {
75         opnds.emplace_back(&opnd0);
76         opnds.emplace_back(&opnd1);
77         opnds.emplace_back(&opnd2);
78         opnds.emplace_back(&opnd3);
79     }
Insn(MemPool & memPool,MOperator opc,Operand & opnd0,Operand & opnd1,Operand & opnd2,Operand & opnd3,Operand & opnd4)80     Insn(MemPool &memPool, MOperator opc, Operand &opnd0, Operand &opnd1, Operand &opnd2, Operand &opnd3,
81          Operand &opnd4)
82         : Insn(memPool, opc)
83     {
84         opnds.emplace_back(&opnd0);
85         opnds.emplace_back(&opnd1);
86         opnds.emplace_back(&opnd2);
87         opnds.emplace_back(&opnd3);
88         opnds.emplace_back(&opnd4);
89     }
90     virtual ~Insn() = default;
91 
GetMachineOpcode()92     MOperator GetMachineOpcode() const
93     {
94         return mOp;
95     }
96 
97     void SetMOP(const InsnDesc &idesc);
98 
AddOperand(Operand & opnd)99     void AddOperand(Operand &opnd)
100     {
101         opnds.emplace_back(&opnd);
102     }
103 
AddOpndChain(Operand & opnd)104     Insn &AddOpndChain(Operand &opnd)
105     {
106         AddOperand(opnd);
107         return *this;
108     }
109     /* use carefully which might cause insn to illegal */
110     void CommuteOperands(uint32 dIndex, uint32 sIndex);
CleanAllOperand()111     void CleanAllOperand()
112     {
113         opnds.clear();
114     }
115 
PopBackOperand()116     void PopBackOperand()
117     {
118         opnds.pop_back();
119     }
120 
GetOperand(uint32 index)121     Operand &GetOperand(uint32 index) const
122     {
123         DEBUG_ASSERT(index < opnds.size(), "index out of range");
124         return *opnds[index];
125     }
126 
ResizeOpnds(uint32 newSize)127     void ResizeOpnds(uint32 newSize)
128     {
129         opnds.resize(static_cast<std::size_t>(newSize));
130     }
131 
GetOperandSize()132     uint32 GetOperandSize() const
133     {
134         return static_cast<uint32>(opnds.size());
135     }
136 
SetOperand(uint32 index,Operand & opnd)137     void SetOperand(uint32 index, Operand &opnd)
138     {
139         DEBUG_ASSERT(index <= opnds.size(), "index out of range");
140         opnds[index] = &opnd;
141     }
142 
SetRetSize(uint32 size)143     void SetRetSize(uint32 size)
144     {
145         DEBUG_ASSERT(IsCall(), "Insn should be a call.");
146         retSize = size;
147     }
148 
GetRetSize()149     uint32 GetRetSize() const
150     {
151         DEBUG_ASSERT(IsCall(), "Insn should be a call.");
152         return retSize;
153     }
154 
155     virtual bool IsMachineInstruction() const;
156 
IsIntrinsic()157     virtual bool IsIntrinsic() const
158     {
159         return false;
160     }
161 
162     bool OpndIsDef(uint32 id) const;
163 
164     bool OpndIsUse(uint32 id) const;
165 
IsPCLoad()166     virtual bool IsPCLoad() const
167     {
168         return false;
169     }
170 
171     Operand *GetMemOpnd() const;
172 
173     void SetMemOpnd(MemOperand *memOpnd);
174 
175     bool IsCall() const;
176     bool IsTailCall() const;
177     bool IsAsmInsn() const;
178     bool IsClinit() const;
179     bool CanThrow() const;
180     bool MayThrow() const;
181     bool IsBranch() const;
182     bool IsCondBranch() const;
183     bool IsUnCondBranch() const;
184     bool IsMove() const;
185     bool IsBasicOp() const;
186     bool IsUnaryOp() const;
187     bool IsShift() const;
188     bool IsPhi() const;
189     bool IsLoad() const;
190     bool IsStore() const;
191     bool IsConversion() const;
192     bool IsAtomic() const;
193 
194     bool IsLoadPair() const;
195     bool IsStorePair() const;
196     bool IsLoadStorePair() const;
197     bool IsLoadLabel() const;
198 
NoAlias()199     virtual bool NoAlias() const
200     {
201         return false;
202     }
203 
204     bool IsVolatile() const;
205 
206     bool IsMemAccessBar() const;
207 
208     bool IsMemAccess() const;
209 
HasSideEffects()210     virtual bool HasSideEffects() const
211     {
212         return false;
213     }
214 
215     bool HasLoop() const;
216 
217     virtual bool IsSpecialIntrinsic() const;
218 
219     bool IsComment() const;
220     bool IsImmaterialInsn() const;
221 
222     bool IsPseudo() const;
223 
IsTargetInsn()224     virtual bool IsTargetInsn() const
225     {
226         return true;
227     }
228 
IsCfiInsn()229     virtual bool IsCfiInsn() const
230     {
231         return false;
232     }
233 
IsDbgInsn()234     virtual bool IsDbgInsn() const
235     {
236         return false;
237     }
238 
239     bool IsDMBInsn() const;
240 
241     bool IsVectorOp() const;
242 
243     virtual Operand *GetCallTargetOperand() const;
244 
245     uint32 GetAtomicNum() const;
246     /*
247      * returns a ListOperand
248      * Note that we don't really need this for Emit
249      * Rather, we need it for register allocation, to
250      * correctly state the live ranges for operands
251      * use for passing call arguments
252      */
253     virtual ListOperand *GetCallArgumentOperand();
IsAtomicStore()254     bool IsAtomicStore() const
255     {
256         return IsStore() && IsAtomic();
257     }
258 
SetCondDef()259     void SetCondDef()
260     {
261         flags |= kOpCondDef;
262     }
263 
IsCondDef()264     bool IsCondDef() const
265     {
266         return flags & kOpCondDef;
267     }
268 
AccessMem()269     bool AccessMem() const
270     {
271         return IsLoad() || IsStore();
272     }
273 
IsFrameDef()274     bool IsFrameDef() const
275     {
276         return isFrameDef;
277     }
278 
SetFrameDef(bool b)279     void SetFrameDef(bool b)
280     {
281         isFrameDef = b;
282     }
283 
IsAsmDefCondCode()284     bool IsAsmDefCondCode() const
285     {
286         return asmDefCondCode;
287     }
288 
SetAsmDefCondCode()289     void SetAsmDefCondCode()
290     {
291         asmDefCondCode = true;
292     }
293 
IsAsmModMem()294     bool IsAsmModMem() const
295     {
296         return asmModMem;
297     }
298 
SetAsmModMem()299     void SetAsmModMem()
300     {
301         asmModMem = true;
302     }
303 
GetUnitType()304     virtual uint32 GetUnitType()
305     {
306         return 0;
307     }
308 
309     virtual void Dump() const;
310 
311 #if DEBUG
312     virtual void Check() const;
313 #endif
314 
SetComment(const std::string & str)315     void SetComment(const std::string &str)
316     {
317         comment = str;
318     }
319 
SetComment(const MapleString & str)320     void SetComment(const MapleString &str)
321     {
322         comment = str;
323     }
324 
GetComment()325     const MapleString &GetComment() const
326     {
327         return comment;
328     }
329 
AppendComment(const std::string & str)330     void AppendComment(const std::string &str)
331     {
332         comment += str;
333     }
334 
MarkAsSaveRetValToLocal()335     void MarkAsSaveRetValToLocal()
336     {
337         flags |= kOpDassignToSaveRetValToLocal;
338     }
339 
IsSaveRetValToLocal()340     bool IsSaveRetValToLocal() const
341     {
342         return ((flags & kOpDassignToSaveRetValToLocal) != 0);
343     }
344 
MarkAsAccessRefField(bool cond)345     void MarkAsAccessRefField(bool cond)
346     {
347         if (cond) {
348             flags |= kOpAccessRefField;
349         }
350     }
351 
IsAccessRefField()352     bool IsAccessRefField() const
353     {
354         return ((flags & kOpAccessRefField) != 0);
355     }
356 
GetPreviousMachineInsn()357     Insn *GetPreviousMachineInsn() const
358     {
359         for (Insn *returnInsn = prev; returnInsn != nullptr; returnInsn = returnInsn->prev) {
360             DEBUG_ASSERT(returnInsn->bb == bb, "insn and it's prev insn must have same bb");
361             if (returnInsn->IsMachineInstruction()) {
362                 return returnInsn;
363             }
364         }
365         return nullptr;
366     }
367 
GetNextMachineInsn()368     Insn *GetNextMachineInsn() const
369     {
370         for (Insn *returnInsn = next; returnInsn != nullptr; returnInsn = returnInsn->next) {
371             CHECK_FATAL(returnInsn->bb == bb, "insn and it's next insn must have same bb");
372             if (returnInsn->IsMachineInstruction()) {
373                 return returnInsn;
374             }
375         }
376         return nullptr;
377     }
378 
379     uint32 GetLatencyType() const;
380 
SetPrev(Insn * prev)381     void SetPrev(Insn *prev)
382     {
383         this->prev = prev;
384     }
385 
GetPrev()386     Insn *GetPrev()
387     {
388         return prev;
389     }
390 
GetPrev()391     const Insn *GetPrev() const
392     {
393         return prev;
394     }
395 
SetNext(Insn * next)396     void SetNext(Insn *next)
397     {
398         this->next = next;
399     }
400 
GetNext()401     Insn *GetNext() const
402     {
403         return next;
404     }
405 
SetBB(BB * bb)406     void SetBB(BB *bb)
407     {
408         this->bb = bb;
409     }
410 
GetBB()411     BB *GetBB()
412     {
413         return bb;
414     }
415 
GetBB()416     const BB *GetBB() const
417     {
418         return bb;
419     }
420 
SetId(uint32 id)421     void SetId(uint32 id)
422     {
423         this->id = id;
424     }
425 
GetId()426     uint32 GetId() const
427     {
428         return id;
429     }
430 
SetAddress(uint32 addr)431     void SetAddress(uint32 addr)
432     {
433         address = addr;
434     }
435 
GetAddress()436     uint32 GetAddress() const
437     {
438         return address;
439     }
440 
SetNopNum(uint32 num)441     void SetNopNum(uint32 num)
442     {
443         nopNum = num;
444     }
445 
GetNopNum()446     uint32 GetNopNum() const
447     {
448         return nopNum;
449     }
450 
SetNeedSplit(bool flag)451     void SetNeedSplit(bool flag)
452     {
453         needSplit = flag;
454     }
455 
IsNeedSplit()456     bool IsNeedSplit() const
457     {
458         return needSplit;
459     }
460 
SetIsThrow(bool isThrow)461     void SetIsThrow(bool isThrow)
462     {
463         this->isThrow = isThrow;
464     }
465 
GetIsThrow()466     bool GetIsThrow() const
467     {
468         return isThrow;
469     }
470 
SetDoNotRemove(bool doNotRemove)471     void SetDoNotRemove(bool doNotRemove)
472     {
473         this->doNotRemove = doNotRemove;
474     }
475 
GetDoNotRemove()476     bool GetDoNotRemove() const
477     {
478         return doNotRemove;
479     }
480 
SetIsSpill()481     void SetIsSpill()
482     {
483         this->isSpill = true;
484     }
485 
GetIsSpill()486     bool GetIsSpill() const
487     {
488         return isSpill;
489     }
490 
SetIsReload()491     void SetIsReload()
492     {
493         this->isReload = true;
494     }
495 
GetIsReload()496     bool GetIsReload() const
497     {
498         return isReload;
499     }
500 
IsSpillInsn()501     bool IsSpillInsn() const
502     {
503         return (isSpill || isReload);
504     }
505 
SetIsCallReturnUnsigned(bool unSigned)506     void SetIsCallReturnUnsigned(bool unSigned)
507     {
508         DEBUG_ASSERT(IsCall(), "Insn should be a call.");
509         this->isCallReturnUnsigned = unSigned;
510     }
511 
GetIsCallReturnUnsigned()512     bool GetIsCallReturnUnsigned() const
513     {
514         DEBUG_ASSERT(IsCall(), "Insn should be a call.");
515         return isCallReturnUnsigned;
516     }
517 
GetIsCallReturnSigned()518     bool GetIsCallReturnSigned() const
519     {
520         DEBUG_ASSERT(IsCall(), "Insn should be a call.");
521         return !isCallReturnUnsigned;
522     }
523 
SetRetType(RetType retType)524     void SetRetType(RetType retType)
525     {
526         this->retType = retType;
527     }
528 
GetRetType()529     RetType GetRetType() const
530     {
531         return retType;
532     }
533 
SetClearStackOffset(short index,int64 offset)534     void SetClearStackOffset(short index, int64 offset)
535     {
536         CHECK_FATAL(index < kMaxStackOffsetSize, "out of clearStackOffset's range");
537         clearStackOffset[index] = offset;
538     }
539 
GetClearStackOffset(short index)540     int64 GetClearStackOffset(short index) const
541     {
542         CHECK_FATAL(index < kMaxStackOffsetSize, "out of clearStackOffset's range");
543         return clearStackOffset[index];
544     }
545 
546     /* if function name is MCC_ClearLocalStackRef or MCC_DecRefResetPair, will clear designate stack slot */
IsClearDesignateStackCall()547     bool IsClearDesignateStackCall() const
548     {
549         return clearStackOffset[0] != -1 || clearStackOffset[1] != -1;
550     }
551 
SetDepNode(DepNode & depNode)552     void SetDepNode(DepNode &depNode)
553     {
554         this->depNode = &depNode;
555     }
556 
GetDepNode()557     DepNode *GetDepNode()
558     {
559         return depNode;
560     }
561 
GetDepNode()562     const DepNode *GetDepNode() const
563     {
564         return depNode;
565     }
566 
SetIsPhiMovInsn(bool val)567     void SetIsPhiMovInsn(bool val)
568     {
569         isPhiMovInsn = val;
570     }
571 
IsPhiMovInsn()572     bool IsPhiMovInsn() const
573     {
574         return isPhiMovInsn;
575     }
576 
577     Insn *Clone(MemPool &memPool) const;
578 
SetInsnDescrption(const InsnDesc & newMD)579     void SetInsnDescrption(const InsnDesc &newMD)
580     {
581         md = &newMD;
582     }
583 
GetDesc()584     const InsnDesc *GetDesc() const
585     {
586         return md;
587     }
588 
AddRegBinding(uint32 regA,uint32 regB)589     void AddRegBinding(uint32 regA, uint32 regB)
590     {
591         (void)registerBinding.emplace(regA, regB);
592     }
593 
GetRegBinding()594     const MapleMap<uint32, uint32> &GetRegBinding() const
595     {
596         return registerBinding;
597     }
598 
AddDeoptBundleInfo(int32 deoptVreg,Operand & opnd)599     void AddDeoptBundleInfo(int32 deoptVreg, Operand &opnd)
600     {
601         if (stackMap == nullptr) {
602             stackMap = localAlloc.New<StackMap>(localAlloc);
603         }
604         stackMap->GetDeoptInfo().AddDeoptBundleInfo(deoptVreg, opnd);
605     }
606 
GetStackMap()607     StackMap *GetStackMap()
608     {
609         return stackMap;
610     }
611 
GetStackMap()612     const StackMap *GetStackMap() const
613     {
614         return stackMap;
615     }
616 
InitStackMapInfo()617     void InitStackMapInfo()
618     {
619         if (stackMap != nullptr) {
620             return;
621         }
622         stackMap = localAlloc.New<StackMap>(localAlloc);
623     }
624 
SetRefSkipIdx(int32 index)625     void SetRefSkipIdx(int32 index)
626     {
627         refSkipIdx = index;
628     }
629 
630     /* Get Size of memory write/read by insn */
631     uint32 GetMemoryByteSize() const;
632 
633     /* return ture if register appears */
634     virtual bool ScanReg(regno_t regNO) const;
635 
636     virtual bool IsRegDefined(regno_t regNO) const;
637 
638     virtual std::set<uint32> GetDefRegs() const;
639 
640     virtual uint32 GetBothDefUseOpnd() const;
641 
SetStackMapDef(SparseDataInfo & def)642     void SetStackMapDef(SparseDataInfo &def)
643     {
644         stackMapDef = &def;
645     }
646 
GetStackMapDef()647     SparseDataInfo *GetStackMapDef()
648     {
649         return stackMapDef;
650     }
651 
SetStackMapUse(SparseDataInfo & use)652     void SetStackMapUse(SparseDataInfo &use)
653     {
654         stackMapUse = &use;
655     }
656 
GetStackMapUse()657     SparseDataInfo *GetStackMapUse()
658     {
659         return stackMapUse;
660     }
661 
SetStackMapLiveIn(SparseDataInfo & liveIn)662     void SetStackMapLiveIn(SparseDataInfo &liveIn)
663     {
664         stackMapLiveIn = &liveIn;
665     }
666 
GetStackMapLiveIn()667     SparseDataInfo *GetStackMapLiveIn()
668     {
669         return stackMapLiveIn;
670     }
671 
ClearStackMapDefUse()672     void ClearStackMapDefUse()
673     {
674         stackMapDef = nullptr;
675         stackMapUse = nullptr;
676     }
677 
678 protected:
679     MOperator mOp;
680     MapleAllocator localAlloc;
681     MapleVector<Operand *> opnds;
682     Insn *prev = nullptr;
683     Insn *next = nullptr;
684     BB *bb = nullptr; /* BB to which this insn belongs */
685     uint32 flags = 0;
686     bool isPhiMovInsn = false;
687 
688 private:
689     MapleMap<uint32, uint32> registerBinding; /* used for inline asm only */
690     StackMap *stackMap = nullptr;
691     enum OpKind : uint32 {
692         kOpUnknown = 0,
693         kOpCondDef = 0x1,
694         kOpAccessRefField = (1ULL << 30),            /* load-from/store-into a ref flag-fieldGetMachineOpcode() */
695         kOpDassignToSaveRetValToLocal = (1ULL << 31) /* save return value to local flag */
696     };
697 
698     uint32 id = 0;
699     uint32 address = 0;
700     uint32 nopNum = 0;
701     RetType retType = kRegNull; /* if this insn is call, it represent the return register type R0/V0 */
702     uint32 retSize = 0;         /* Byte size of the return value if insn is a call. */
703     /* record the stack cleared by MCC_ClearLocalStackRef or MCC_DecRefResetPair */
704     int64 clearStackOffset[kMaxStackOffsetSize] = {-1, -1};
705     DepNode *depNode = nullptr; /* For dependence analysis, pointing to a dependence node. */
706     MapleString comment;
707     bool isThrow = false;
708     bool doNotRemove = false;          /* caller reg cross call */
709     bool isCallReturnUnsigned = false; /* for call insn only. false: signed, true: unsigned */
710     bool isSpill = false;              /* used as hint for optimization */
711     bool isReload = false;             /* used as hint for optimization */
712     bool isFrameDef = false;
713     bool asmDefCondCode = false;
714     bool asmModMem = false;
715     bool needSplit = false;
716 
717     /* for dynamic language to mark reference counting */
718     int32 refSkipIdx = -1;
719 
720     /* for multiple architecture */
721     const InsnDesc *md = nullptr;
722     SparseDataInfo *stackMapDef = nullptr;
723     SparseDataInfo *stackMapUse = nullptr;
724     SparseDataInfo *stackMapLiveIn = nullptr;
725 };
726 
727 struct VectorRegSpec {
VectorRegSpecVectorRegSpec728     VectorRegSpec() : vecLane(-1), vecLaneMax(0), vecElementSize(0), compositeOpnds(0) {}
729 
730     VectorRegSpec(PrimType type, int16 lane = -1, uint16 compositeOpnds = 0)
vecLaneVectorRegSpec731         : vecLane(lane),
732           vecLaneMax(GetVecLanes(type)),
733           vecElementSize(GetVecEleSize(type)),
734           compositeOpnds(compositeOpnds)
735     {
736     }
737 
738     VectorRegSpec(uint16 laneNum, uint16 eleSize, int16 lane = -1, uint16 compositeOpnds = 0)
vecLaneVectorRegSpec739         : vecLane(lane), vecLaneMax(laneNum), vecElementSize(eleSize), compositeOpnds(compositeOpnds)
740     {
741     }
742 
743     int16 vecLane;         /* -1 for whole reg, 0 to 15 to specify individual lane */
744     uint16 vecLaneMax;     /* Maximum number of lanes for this vregister */
745     uint16 vecElementSize; /* element size in each Lane */
746     uint16 compositeOpnds; /* Number of enclosed operands within this composite operand */
747 };
748 
749 class VectorInsn : public Insn {
750 public:
VectorInsn(MemPool & memPool,MOperator opc)751     VectorInsn(MemPool &memPool, MOperator opc) : Insn(memPool, opc), regSpecList(localAlloc.Adapter())
752     {
753         regSpecList.clear();
754     }
755 
756     ~VectorInsn() override = default;
757 
ClearRegSpecList()758     void ClearRegSpecList()
759     {
760         regSpecList.clear();
761     }
762 
763     VectorRegSpec *GetAndRemoveRegSpecFromList();
764 
GetNumOfRegSpec()765     size_t GetNumOfRegSpec() const
766     {
767         if (IsVectorOp() && !regSpecList.empty()) {
768             return regSpecList.size();
769         }
770         return 0;
771     }
772 
GetRegSpecList()773     MapleVector<VectorRegSpec *> &GetRegSpecList()
774     {
775         return regSpecList;
776     }
777 
SetRegSpecList(const MapleVector<VectorRegSpec * > & vec)778     void SetRegSpecList(const MapleVector<VectorRegSpec *> &vec)
779     {
780         regSpecList = vec;
781     }
782 
PushRegSpecEntry(VectorRegSpec * v)783     VectorInsn &PushRegSpecEntry(VectorRegSpec *v)
784     {
785         regSpecList.emplace(regSpecList.begin(), v);
786         return *this;
787     }
788 
789 private:
790     MapleVector<VectorRegSpec *> regSpecList;
791 };
792 
793 struct InsnIdCmp {
operatorInsnIdCmp794     bool operator()(const Insn *lhs, const Insn *rhs) const
795     {
796         CHECK_FATAL(lhs != nullptr, "lhs is nullptr in InsnIdCmp");
797         CHECK_FATAL(rhs != nullptr, "rhs is nullptr in InsnIdCmp");
798         return lhs->GetId() < rhs->GetId();
799     }
800 };
801 using InsnSet = std::set<Insn *, InsnIdCmp>;
802 using InsnMapleSet = MapleSet<Insn *, InsnIdCmp>;
803 } /* namespace maplebe */
804 
805 #endif /* MAPLEBE_INCLUDE_CG_INSN_H */
806