• 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_ME_INCLUDE_SSA_MIR_NODES_H
17 #define MAPLE_ME_INCLUDE_SSA_MIR_NODES_H
18 #include <iostream>
19 #include "bb.h"
20 #include "ver_symbol.h"
21 
22 // This file define data structures to store SSA information in the IR instructions
23 namespace maple {
24 class MayDefNode {
25 public:
MayDefNode(VersionSt * sym,StmtNode * st)26     MayDefNode(VersionSt *sym, StmtNode *st) : opnd(sym), result(sym), stmt(st) {}
27 
28     ~MayDefNode() = default;
29 
GetOpnd()30     VersionSt *GetOpnd()
31     {
32         return opnd;
33     }
GetOpnd()34     const VersionSt *GetOpnd() const
35     {
36         return opnd;
37     }
38 
GetResult()39     VersionSt *GetResult()
40     {
41         return result;
42     }
GetResult()43     const VersionSt *GetResult() const
44     {
45         return result;
46     }
47 
GetStmt()48     StmtNode *GetStmt()
49     {
50         return stmt;
51     }
GetStmt()52     const StmtNode *GetStmt() const
53     {
54         return stmt;
55     }
56 
SetStmt(StmtNode * s)57     void SetStmt(StmtNode *s)
58     {
59         stmt = s;
60     }
61 
SetOpnd(VersionSt * sym)62     void SetOpnd(VersionSt *sym)
63     {
64         opnd = sym;
65     }
66 
SetResult(VersionSt * sym)67     void SetResult(VersionSt *sym)
68     {
69         result = sym;
70     }
71 
Dump()72     void Dump() const
73     {
74         result->Dump();
75         LogInfo::MapleLogger() << " = MAYD(";
76         opnd->Dump();
77         LogInfo::MapleLogger() << ")\n";
78     }
79 
80     bool operator==(const MayDefNode &other) const
81     {
82         return opnd == other.opnd && result == other.result && stmt == other.stmt;
83     }
84 
85     VersionSt *base = nullptr;  // only provided if indirectLev is 1 and attached to iassign
86 private:
87     VersionSt *opnd;
88     VersionSt *result;
89     StmtNode *stmt;
90 };
91 
92 class MayUseNode {
93 public:
MayUseNode(VersionSt * sym)94     explicit MayUseNode(VersionSt *sym) : opnd(sym) {}
95 
96     ~MayUseNode() = default;
97 
GetOpnd()98     VersionSt *GetOpnd() const
99     {
100         return opnd;
101     }
102 
SetOpnd(VersionSt * sym)103     void SetOpnd(VersionSt *sym)
104     {
105         opnd = sym;
106     }
107 
Dump()108     void Dump() const
109     {
110         LogInfo::MapleLogger() << " MAYU(";
111         opnd->Dump();
112         LogInfo::MapleLogger() << ")\n";
113     }
114 
115     bool operator==(const MayUseNode &other) const
116     {
117         return opnd == other.opnd;
118     }
119 
120 private:
121     VersionSt *opnd;
122 };
123 
124 // this is only used in the callassigned type of call statements
125 class MustDefNode {
126 public:
127     MustDefNode() = default;
128 
MustDefNode(VersionSt * sym,StmtNode * st)129     MustDefNode(VersionSt *sym, StmtNode *st) : result(sym), stmt(st) {}
130 
131     ~MustDefNode() = default;
132 
GetResult()133     VersionSt *GetResult()
134     {
135         return result;
136     }
GetResult()137     const VersionSt *GetResult() const
138     {
139         return result;
140     }
141 
SetResult(VersionSt * sym)142     void SetResult(VersionSt *sym)
143     {
144         result = sym;
145     }
146 
GetStmt()147     StmtNode *GetStmt()
148     {
149         return stmt;
150     }
GetStmt()151     const StmtNode *GetStmt() const
152     {
153         return stmt;
154     }
155 
Dump()156     void Dump() const
157     {
158         result->Dump();
159         LogInfo::MapleLogger() << " = MUSTDEF\n";
160     }
161 
162 private:
163     VersionSt *result = nullptr;
164     StmtNode *stmt = nullptr;
165 };
166 
167 using TypeOfMayUseList = MapleMap<OStIdx, MayUseNode>;
168 using TypeOfMayDefList = MapleMap<OStIdx, MayDefNode>;
169 using TypeOfMustDefList = MapleVector<MustDefNode>;
170 class AccessSSANodes {
171 public:
172     AccessSSANodes() = default;
173     virtual ~AccessSSANodes() = default;
174 
GetMayDefNodes()175     virtual const TypeOfMayDefList &GetMayDefNodes() const
176     {
177         CHECK_FATAL(false, "No mayDefNodes");
178     }
179 
GetMayDefNodes()180     virtual TypeOfMayDefList &GetMayDefNodes()
181     {
182         CHECK_FATAL(false, "No mayDefNodes");
183     }
184 
GetMayUseNodes()185     virtual const TypeOfMayUseList &GetMayUseNodes() const
186     {
187         CHECK_FATAL(false, "No mayUseNodes");
188     }
189 
GetMayUseNodes()190     virtual TypeOfMayUseList &GetMayUseNodes()
191     {
192         CHECK_FATAL(false, "No mayUseNodes");
193     }
194 
GetMustDefNodes()195     virtual const TypeOfMustDefList &GetMustDefNodes() const
196     {
197         CHECK_FATAL(false, "No mustDefNodes");
198     }
GetMustDefNodes()199     virtual TypeOfMustDefList &GetMustDefNodes()
200     {
201         CHECK_FATAL(false, "No mustDefNodes");
202     }
203 
GetSSAVar()204     virtual const VersionSt *GetSSAVar() const
205     {
206         CHECK_FATAL(false, "No ssaVar");
207     }
208 
GetSSAVar()209     virtual VersionSt *GetSSAVar()
210     {
211         CHECK_FATAL(false, "No ssaVar");
212     }
213 
SetSSAVar(VersionSt &)214     virtual void SetSSAVar(VersionSt &)
215     {
216         CHECK_FATAL(false, "No ssaVar");
217     }
218 
DumpMayDefNodes(const MIRModule &)219     virtual void DumpMayDefNodes(const MIRModule &) const
220     {
221         for (const auto &mayDefNode : GetMayDefNodes()) {
222             mayDefNode.second.Dump();
223         }
224     }
225 
DumpMayUseNodes(const MIRModule &)226     virtual void DumpMayUseNodes(const MIRModule &) const
227     {
228         for (const auto &mapItem : GetMayUseNodes()) {
229             mapItem.second.Dump();
230         }
231     }
232 
DumpMustDefNodes(const MIRModule &)233     virtual void DumpMustDefNodes(const MIRModule &) const
234     {
235         for (const auto &mustDefNode : GetMustDefNodes()) {
236             mustDefNode.Dump();
237         }
238     }
239 
InsertMayDefNode(MayDefNode mayDefNode)240     inline void InsertMayDefNode(MayDefNode mayDefNode)
241     {
242         auto &mayDefNodes = GetMayDefNodes();
243         OStIdx ostIdx = mayDefNode.GetOpnd()->GetOrigIdx();
244         (void)mayDefNodes.insert({ostIdx, mayDefNode});
245     }
246 
InsertMayUseNode(MayUseNode mayUseNode)247     inline void InsertMayUseNode(MayUseNode mayUseNode)
248     {
249         auto &mayUseNodes = GetMayUseNodes();
250         OStIdx ostIdx = mayUseNode.GetOpnd()->GetOrigIdx();
251         (void)mayUseNodes.insert({ostIdx, mayUseNode});
252     }
253 
InsertMustDefNode(VersionSt * sym,StmtNode * s)254     virtual void InsertMustDefNode(VersionSt *sym, StmtNode *s)
255     {
256         GetMustDefNodes().emplace_back(MustDefNode(sym, s));
257     }
258 };
259 
260 class MayDefPart : public AccessSSANodes {
261 public:
MayDefPart(MapleAllocator * alloc)262     explicit MayDefPart(MapleAllocator *alloc) : mayDefNodes(alloc->Adapter()) {}
263 
264     ~MayDefPart() override = default;
265 
GetMayDefNodes()266     const TypeOfMayDefList &GetMayDefNodes() const override
267     {
268         return mayDefNodes;
269     }
270 
GetMayDefNodes()271     TypeOfMayDefList &GetMayDefNodes() override
272     {
273         return mayDefNodes;
274     }
275 
276 private:
277     TypeOfMayDefList mayDefNodes;
278 };
279 
280 class MayUsePart : public AccessSSANodes {
281 public:
MayUsePart(MapleAllocator * alloc)282     explicit MayUsePart(MapleAllocator *alloc) : mayUseNodes(alloc->Adapter()) {}
283 
284     ~MayUsePart() override = default;
285 
GetMayUseNodes()286     const TypeOfMayUseList &GetMayUseNodes() const override
287     {
288         return mayUseNodes;
289     }
290 
GetMayUseNodes()291     TypeOfMayUseList &GetMayUseNodes() override
292     {
293         return mayUseNodes;
294     }
295 
296 private:
297     TypeOfMayUseList mayUseNodes;
298 };
299 
300 class MustDefPart : public AccessSSANodes {
301 public:
MustDefPart(MapleAllocator * alloc)302     explicit MustDefPart(MapleAllocator *alloc) : mustDefNodes(alloc->Adapter()) {}
303 
304     ~MustDefPart() override = default;
305 
GetMustDefNodes()306     const TypeOfMustDefList &GetMustDefNodes() const override
307     {
308         return mustDefNodes;
309     }
310 
GetMustDefNodes()311     TypeOfMustDefList &GetMustDefNodes() override
312     {
313         return mustDefNodes;
314     }
315 
316 private:
317     TypeOfMustDefList mustDefNodes;
318 };
319 
320 class MayDefPartWithVersionSt : public AccessSSANodes {
321 public:
MayDefPartWithVersionSt(MapleAllocator * alloc)322     explicit MayDefPartWithVersionSt(MapleAllocator *alloc) : mayDefNodes(alloc->Adapter()) {}
323 
324     ~MayDefPartWithVersionSt() override = default;
325 
GetMayDefNodes()326     const TypeOfMayDefList &GetMayDefNodes() const override
327     {
328         return mayDefNodes;
329     }
330 
GetMayDefNodes()331     TypeOfMayDefList &GetMayDefNodes() override
332     {
333         return mayDefNodes;
334     }
335 
GetSSAVar()336     const VersionSt *GetSSAVar() const override
337     {
338         return ssaVar;
339     }
340 
GetSSAVar()341     VersionSt *GetSSAVar() override
342     {
343         return ssaVar;
344     }
345 
SetSSAVar(VersionSt & ssaVarPara)346     void SetSSAVar(VersionSt &ssaVarPara) override
347     {
348         ssaVar = &ssaVarPara;
349     }
350 
351 private:
352     VersionSt *ssaVar = nullptr;
353     TypeOfMayDefList mayDefNodes;
354 };
355 
356 class VersionStPart : public AccessSSANodes {
357 public:
358     VersionStPart() = default;
359     ~VersionStPart() override = default;
360 
GetSSAVar()361     const VersionSt *GetSSAVar() const override
362     {
363         return ssaVar;
364     }
365 
GetSSAVar()366     VersionSt *GetSSAVar() override
367     {
368         return ssaVar;
369     }
370 
SetSSAVar(VersionSt & ssaVarPara)371     void SetSSAVar(VersionSt &ssaVarPara) override
372     {
373         ssaVar = &ssaVarPara;
374     }
375 
376 private:
377     VersionSt *ssaVar = nullptr;
378 };
379 
380 class MayDefMayUsePart : public AccessSSANodes {
381 public:
MayDefMayUsePart(MapleAllocator * alloc)382     explicit MayDefMayUsePart(MapleAllocator *alloc) : mayDefNodes(alloc->Adapter()), mayUseNodes(alloc->Adapter()) {}
383 
384     ~MayDefMayUsePart() override = default;
385 
GetMayDefNodes()386     const TypeOfMayDefList &GetMayDefNodes() const override
387     {
388         return mayDefNodes;
389     }
390 
GetMayDefNodes()391     TypeOfMayDefList &GetMayDefNodes() override
392     {
393         return mayDefNodes;
394     }
395 
GetMayUseNodes()396     const TypeOfMayUseList &GetMayUseNodes() const override
397     {
398         return mayUseNodes;
399     }
400 
GetMayUseNodes()401     TypeOfMayUseList &GetMayUseNodes() override
402     {
403         return mayUseNodes;
404     }
405 
406 private:
407     TypeOfMayDefList mayDefNodes;
408     TypeOfMayUseList mayUseNodes;
409 };
410 
411 class MayDefMayUseMustDefPart : public AccessSSANodes {
412 public:
MayDefMayUseMustDefPart(MapleAllocator * alloc)413     explicit MayDefMayUseMustDefPart(MapleAllocator *alloc)
414         : mayDefNodes(alloc->Adapter()), mayUseNodes(alloc->Adapter()), mustDefNodes(alloc->Adapter())
415     {
416     }
417 
418     ~MayDefMayUseMustDefPart() override = default;
419 
GetMayDefNodes()420     const TypeOfMayDefList &GetMayDefNodes() const override
421     {
422         return mayDefNodes;
423     }
424 
GetMayDefNodes()425     TypeOfMayDefList &GetMayDefNodes() override
426     {
427         return mayDefNodes;
428     }
429 
GetMayUseNodes()430     const TypeOfMayUseList &GetMayUseNodes() const override
431     {
432         return mayUseNodes;
433     }
434 
GetMayUseNodes()435     TypeOfMayUseList &GetMayUseNodes() override
436     {
437         return mayUseNodes;
438     }
439 
GetMustDefNodes()440     const TypeOfMustDefList &GetMustDefNodes() const override
441     {
442         return mustDefNodes;
443     }
GetMustDefNodes()444     TypeOfMustDefList &GetMustDefNodes() override
445     {
446         return mustDefNodes;
447     }
448 
449 private:
450     TypeOfMayDefList mayDefNodes;
451     TypeOfMayUseList mayUseNodes;
452     TypeOfMustDefList mustDefNodes;
453 };
454 
455 // statement nodes are covered by StmtsSSAPart
456 class StmtsSSAPart {
457 public:
458     // Key of ssaPart is stmtID
459     // Each element of ssaPart, depending on the stmt, can be pointer to one of:
460     // (1) MayDefPart
461     // (2) MayUsePart
462     // (3) MayDefMayUsePart
463     // (4) MayDefPartWithVersionSt
464     // (5) MayDefMayUseMustDefPart
465     // (6) VersionSt
StmtsSSAPart(MemPool * memPool)466     explicit StmtsSSAPart(MemPool *memPool) : ssaPartMp(memPool), ssaPartAlloc(memPool), ssaPart(ssaPartAlloc.Adapter())
467     {
468     }
469 
470     ~StmtsSSAPart() = default;
471 
SSAPartOf(const StmtNode & stmt)472     AccessSSANodes *SSAPartOf(const StmtNode &stmt)
473     {
474         return ssaPart[stmt.GetStmtID()];
475     }
SSAPartOf(const StmtNode & stmt)476     const AccessSSANodes *SSAPartOf(const StmtNode &stmt) const
477     {
478         return ssaPart.at(stmt.GetStmtID());
479     }
480 
HasMayDef(const StmtNode & stmt)481     bool HasMayDef(const StmtNode &stmt)
482     {
483         return kOpcodeInfo.HasSSADef(stmt.GetOpCode()) && !GetMayDefNodesOf(stmt).empty();
484     }
485 
GetMayDefNodesOf(const StmtNode & stmt)486     TypeOfMayDefList &GetMayDefNodesOf(const StmtNode &stmt)
487     {
488         return ssaPart[stmt.GetStmtID()]->GetMayDefNodes();
489     }
490 
GetMayUseNodesOf(const StmtNode & stmt)491     TypeOfMayUseList &GetMayUseNodesOf(const StmtNode &stmt)
492     {
493         return ssaPart[stmt.GetStmtID()]->GetMayUseNodes();
494     }
495 
GetMustDefNodesOf(const StmtNode & stmt)496     MapleVector<MustDefNode> &GetMustDefNodesOf(const StmtNode &stmt)
497     {
498         return ssaPart.at(stmt.GetStmtID())->GetMustDefNodes();
499     }
GetMustDefNodesOf(const StmtNode & stmt)500     const MapleVector<MustDefNode> &GetMustDefNodesOf(const StmtNode &stmt) const
501     {
502         return ssaPart.at(stmt.GetStmtID())->GetMustDefNodes();
503     }
504 
GetAssignedVarOf(const StmtNode & stmt)505     VersionSt *GetAssignedVarOf(const StmtNode &stmt)
506     {
507         return ssaPart.at(stmt.GetStmtID())->GetSSAVar();
508     }
GetAssignedVarOf(const StmtNode & stmt)509     const VersionSt *GetAssignedVarOf(const StmtNode &stmt) const
510     {
511         return ssaPart.at(stmt.GetStmtID())->GetSSAVar();
512     }
513 
514     template <class T>
SetSSAPartOf(const StmtNode & s,T * p)515     void SetSSAPartOf(const StmtNode &s, T *p)
516     {
517         ssaPart[s.GetStmtID()] = static_cast<AccessSSANodes *>(p);
518     }
519 
SetSSAPartOf(const StmtNode & s,VersionSt * vst)520     void SetSSAPartOf(const StmtNode &s, VersionSt *vst)
521     {
522         auto *vstSSAPart = GetSSAPartMp()->New<VersionStPart>();
523         vstSSAPart->SetSSAVar(*vst);
524         ssaPart[s.GetStmtID()] = vstSSAPart;
525     }
526 
GetSSAPartMp()527     MemPool *GetSSAPartMp()
528     {
529         return ssaPartMp;
530     }
531 
GetSSAPartAlloc()532     MapleAllocator &GetSSAPartAlloc()
533     {
534         return ssaPartAlloc;
535     }
536 
537 private:
538     MemPool *ssaPartMp;
539     MapleAllocator ssaPartAlloc;
540     MapleMap<uint32, AccessSSANodes *> ssaPart;  // key is stmtID
541 };
542 
543 class SSANode : public BaseNode {
544 public:
SSANode(Opcode op,PrimType typ,uint8 numOpr)545     SSANode(Opcode op, PrimType typ, uint8 numOpr) : BaseNode(op, typ, numOpr) {}
546 
547     ~SSANode() override = default;
548 
GetSSAVar()549     VersionSt *GetSSAVar()
550     {
551         return ssaVar;
552     }
GetSSAVar()553     const VersionSt *GetSSAVar() const
554     {
555         return ssaVar;
556     }
557 
SetSSAVar(VersionSt & ssaVarPara)558     void SetSSAVar(VersionSt &ssaVarPara)
559     {
560         ssaVar = &ssaVarPara;
561     }
562 
IsSSANode()563     bool IsSSANode() const override
564     {
565         return true;
566     }
567 
568     // MIRSymbol query
GetMIRSymbol()569     const MIRSymbol &GetMIRSymbol() const
570     {
571         return *(GetSSAVar()->GetOst()->GetMIRSymbol());
572     }
573 
574     virtual BaseNode *GetNoSSANode() = 0;
575 
576 protected:
577     virtual void SetNoSSANode(BaseNode *node) = 0;
578     VersionSt *ssaVar = nullptr;
579 };
580 
581 // The following expression nodes need extra fields to represent SSA
582 class AddrofSSANode : public SSANode {
583 public:
AddrofSSANode(AddrofNode & addrNode)584     explicit AddrofSSANode(AddrofNode &addrNode)
585         : SSANode(addrNode.GetOpCode(), addrNode.GetPrimType(), addrNode.NumOpnds()), addrofNode(&addrNode)
586     {
587     }
588 
589     ~AddrofSSANode() override = default;
590 
Dump(int32 indent)591     void Dump(int32 indent) const override
592     {
593         addrofNode->Dump(indent);
594         if (GetSSAVar() != nullptr) {
595             GetSSAVar()->Dump(true);
596         }
597     }
598 
GetStIdx()599     StIdx GetStIdx() const
600     {
601         return addrofNode->GetStIdx();
602     }
603 
GetFieldID()604     FieldID GetFieldID() const
605     {
606         return addrofNode->GetFieldID();
607     }
608 
GetNoSSANode()609     BaseNode *GetNoSSANode() override
610     {
611         return addrofNode;
612     }
613 
CloneTree(MapleAllocator & allocator)614     AddrofSSANode *CloneTree(MapleAllocator &allocator) const override
615     {
616         auto *node = allocator.New<AddrofSSANode>(*this);
617         BaseNode *newAddrof = node->GetNoSSANode()->CloneTree(allocator);
618         node->SetNoSSANode(newAddrof);
619         return node;
620     }
621 
622 protected:
SetNoSSANode(BaseNode * node)623     void SetNoSSANode(BaseNode *node) override
624     {
625         DEBUG_ASSERT(node->GetOpCode() == OP_addrof || node->GetOpCode() == OP_dread, "must be!");
626         addrofNode = static_cast<AddrofNode *>(node);
627     }
628     AddrofNode *addrofNode;
629 };
630 
631 class IreadSSANode : public SSANode {
632 public:
IreadSSANode(IreadNode & iread)633     explicit IreadSSANode(IreadNode &iread)
634         : SSANode(iread.GetOpCode(), iread.GetPrimType(), iread.NumOpnds()), ireadNode(&iread)
635     {
636     }
637 
638     ~IreadSSANode() override = default;
639 
Dump(int32 indent)640     void Dump(int32 indent) const override
641     {
642         if (GetSSAVar() != nullptr) {
643             GetSSAVar()->Dump(true);
644         }
645         ireadNode->Dump(indent);
646     }
647 
GetFieldID()648     FieldID GetFieldID() const
649     {
650         return ireadNode->GetFieldID();
651     }
652 
GetTyIdx()653     TyIdx GetTyIdx() const
654     {
655         return ireadNode->GetTyIdx();
656     }
657 
Opnd(size_t idx)658     BaseNode *Opnd(size_t idx) const override
659     {
660         return ireadNode->Opnd(idx);
661     }
662 
663     void SetOpnd(BaseNode *node, size_t i = 0) override
664     {
665         ireadNode->SetOpnd(node, i);
666     }
667 
GetNoSSANode()668     BaseNode *GetNoSSANode() override
669     {
670         return ireadNode;
671     }
672 
CloneTree(MapleAllocator & allocator)673     IreadSSANode *CloneTree(MapleAllocator &allocator) const override
674     {
675         auto *node = allocator.New<IreadSSANode>(*this);
676         BaseNode *newIread = node->GetNoSSANode()->CloneTree(allocator);
677         node->SetNoSSANode(newIread);
678         return node;
679     }
680 
681 protected:
SetNoSSANode(BaseNode * node)682     void SetNoSSANode(BaseNode *node) override
683     {
684         DEBUG_ASSERT(node->GetOpCode() == OP_iread, "must be!");
685         ireadNode = static_cast<IreadNode *>(node);
686     }
687     IreadNode *ireadNode;
688 };
689 
690 class RegreadSSANode : public SSANode {
691 public:
RegreadSSANode(RegreadNode & regRead)692     explicit RegreadSSANode(RegreadNode &regRead)
693         : SSANode(regRead.GetOpCode(), regRead.GetPrimType(), regRead.GetNumOpnds()), regreadNode(&regRead)
694     {
695     }
696 
697     ~RegreadSSANode() override = default;
698 
Dump(int32 indent)699     void Dump(int32 indent) const override
700     {
701         regreadNode->Dump(indent);
702         if (GetSSAVar() != nullptr) {
703             GetSSAVar()->Dump(true);
704         }
705     }
706 
GetRegIdx()707     PregIdx GetRegIdx() const
708     {
709         return regreadNode->GetRegIdx();
710     }
711 
GetNoSSANode()712     BaseNode *GetNoSSANode() override
713     {
714         return regreadNode;
715     }
716 
CloneTree(MapleAllocator & allocator)717     RegreadSSANode *CloneTree(MapleAllocator &allocator) const override
718     {
719         auto *node = allocator.New<RegreadSSANode>(*this);
720         BaseNode *newRegread = node->GetNoSSANode()->CloneTree(allocator);
721         node->SetNoSSANode(newRegread);
722         return node;
723     }
724 
725 protected:
SetNoSSANode(BaseNode * node)726     void SetNoSSANode(BaseNode *node) override
727     {
728         DEBUG_ASSERT(node->GetOpCode() == OP_regread, "must be!");
729         regreadNode = static_cast<RegreadNode *>(node);
730     }
731     RegreadNode *regreadNode;
732 };
733 
HasMallocOpnd(const BaseNode * x)734 inline bool HasMallocOpnd(const BaseNode *x)
735 {
736     return x->op == OP_malloc || x->op == OP_gcmalloc || x->op == OP_gcmallocjarray || x->op == OP_alloca ||
737            x->op == OP_stackmalloc || x->op == OP_stackmallocjarray;
738 }
739 
740 bool IsSameContent(const BaseNode *exprA, const BaseNode *exprB, bool isZeroVstEqual = true);
741 }  // namespace maple
742 #endif  // MAPLE_ME_INCLUDE_SSA_MIR_NODES_H
743