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 ®Read)
693 : SSANode(regRead.GetOpCode(), regRead.GetPrimType(), regRead.GetNumOpnds()), regreadNode(®Read)
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