1 /*
2  * Copyright (c) 2022 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 #include "graph.h"
17 
18 namespace panda::defect_scan_aux {
19 using Opcode = compiler::Opcode;
20 using IntrinsicId = compiler::RuntimeInterface::IntrinsicId;
21 
22 static std::unordered_map<Opcode, InstType> OPCODE_INSTTYPE_MAP_TABLE = {
23     OPCODE_INSTTYPE_MAP_TABLE(BUILD_OPCODE_MAP_TABLE)};
24 
25 static std::unordered_map<IntrinsicId, InstType> INTRINSIC_INSTTYPE_MAP_TABLE = {
26     INTRINSIC_INSTTYPE_MAP_TABLE(BUILD_INTRINSIC_MAP_TABLE)};
27 
operator ==(const Inst &inst) const28 bool Inst::operator==(const Inst &inst) const
29 {
30     return inst_ == inst.inst_;
31 }
32 
operator !=(const Inst &inst) const33 bool Inst::operator!=(const Inst &inst) const
34 {
35     return inst_ != inst.inst_;
36 }
37 
GetType() const38 InstType Inst::GetType() const
39 {
40     return type_;
41 }
42 
IsInstStLexVar() const43 bool Inst::IsInstStLexVar() const
44 {
45     return type_ == InstType::STLEXVAR_IMM4_IMM4 || type_ == InstType::STLEXVAR_IMM8_IMM8 ||
46            type_ == InstType::WIDE_STLEXVAR_PREF_IMM16_IMM16;
47 }
48 
IsInstLdLexVar() const49 bool Inst::IsInstLdLexVar() const
50 {
51     return type_ == InstType::LDLEXVAR_IMM4_IMM4 || type_ == InstType::LDLEXVAR_IMM8_IMM8 ||
52            type_ == InstType::WIDE_LDLEXVAR_PREF_IMM16_IMM16;
53 }
54 
IsInstStGlobal() const55 bool Inst::IsInstStGlobal() const
56 {
57     return type_ == InstType::TRYSTGLOBALBYNAME_IMM8_ID16 || type_ == InstType::TRYSTGLOBALBYNAME_IMM16_ID16 ||
58            type_ == InstType::STGLOBALVAR_IMM16_ID16 || type_ == InstType::STCONSTTOGLOBALRECORD_IMM16_ID16 ||
59            type_ == InstType::STTOGLOBALRECORD_IMM16_ID16;
60 }
61 
IsInstLdGlobal() const62 bool Inst::IsInstLdGlobal() const
63 {
64     return type_ == InstType::LDGLOBALVAR_IMM16_ID16 || type_ == InstType::TRYLDGLOBALBYNAME_IMM8_ID16 ||
65            type_ == InstType::TRYLDGLOBALBYNAME_IMM16_ID16;
66 }
67 
GetArgIndex() const68 uint16_t Inst::GetArgIndex() const
69 {
70     ASSERT(inst_->IsParameter());
71     return inst_->CastToParameter()->GetArgNumber();
72 }
73 
GetPc() const74 uint32_t Inst::GetPc() const
75 {
76     return inst_->GetPc();
77 }
78 
GetInstId() const79 uint32_t Inst::GetInstId() const
80 {
81     return inst_->GetId();
82 }
83 
GetBasicBlock() const84 BasicBlock Inst::GetBasicBlock() const
85 {
86     return BasicBlock(inst_->GetBasicBlock());
87 }
88 
GetGraph() const89 Graph Inst::GetGraph() const
90 {
91     return Graph(GetBasicBlock().GetGraph());
92 }
93 
GetInputInsts() const94 std::vector<Inst> Inst::GetInputInsts() const
95 {
96     std::vector<Inst> inputs;
97     for (auto &input : inst_->GetInputs()) {
98         if (!input.GetInst()->IsSaveState()) {
99             inputs.emplace_back(input.GetInst());
100         }
101     }
102     return inputs;
103 }
104 
GetUserInsts() const105 std::vector<Inst> Inst::GetUserInsts() const
106 {
107     std::vector<Inst> users;
108     auto user_list = inst_->GetUsers();
109     for (auto &user : user_list) {
110         if (!user.GetInst()->IsSaveState()) {
111             users.emplace_back(user.GetInst());
112         }
113     }
114     return users;
115 }
116 
GetImms() const117 std::vector<uint32_t> Inst::GetImms() const
118 {
119     ASSERT(inst_->IsIntrinsic());
120     std::vector<uint32_t> imms;
121     auto &intrinsic_imms = inst_->CastToIntrinsic()->GetImms();
122     for (auto imm : intrinsic_imms) {
123         imms.push_back(imm);
124     }
125     return imms;
126 }
127 
GetInstType(const compiler::Inst *inst)128 InstType Inst::GetInstType(const compiler::Inst *inst)
129 {
130     if (inst->IsIntrinsic()) {
131         return INTRINSIC_INSTTYPE_MAP_TABLE[inst->CastToIntrinsic()->GetIntrinsicId()];
132     }
133     return OPCODE_INSTTYPE_MAP_TABLE[inst->GetOpcode()];
134 }
135 
operator ==(const BasicBlock &bb) const136 bool BasicBlock::operator==(const BasicBlock &bb) const
137 {
138     return bb_ == bb.bb_;
139 }
140 
operator !=(const BasicBlock &bb) const141 bool BasicBlock::operator!=(const BasicBlock &bb) const
142 {
143     return bb_ != bb.bb_;
144 }
145 
GetGraph() const146 Graph BasicBlock::GetGraph() const
147 {
148     return Graph(bb_->GetGraph());
149 }
150 
GetPredBlocks() const151 std::vector<BasicBlock> BasicBlock::GetPredBlocks() const
152 {
153     std::vector<BasicBlock> pred_blocks;
154     for (auto &bb : bb_->GetPredsBlocks()) {
155         pred_blocks.emplace_back(bb);
156     }
157     return pred_blocks;
158 }
159 
GetSuccBlocks() const160 std::vector<BasicBlock> BasicBlock::GetSuccBlocks() const
161 {
162     std::vector<BasicBlock> succ_blocks;
163     for (auto &bb : bb_->GetSuccsBlocks()) {
164         succ_blocks.emplace_back(bb);
165     }
166     return succ_blocks;
167 }
168 
GetInstList() const169 std::vector<Inst> BasicBlock::GetInstList() const
170 {
171     std::vector<Inst> inst_list;
172     for (auto inst : bb_->AllInsts()) {
173         if (!inst->IsSaveState()) {
174             inst_list.emplace_back(inst);
175         }
176     }
177     return inst_list;
178 }
179 
GetStartBasicBlock() const180 BasicBlock Graph::GetStartBasicBlock() const
181 {
182     return BasicBlock(graph_->GetStartBlock());
183 }
184 
GetEndBasicBlock() const185 BasicBlock Graph::GetEndBasicBlock() const
186 {
187     return BasicBlock(graph_->GetEndBlock());
188 }
189 
GetBasicBlockList() const190 std::vector<BasicBlock> Graph::GetBasicBlockList() const
191 {
192     std::vector<BasicBlock> bb_list;
193     auto &blocks = graph_->GetBlocksRPO();
194     for (auto &bb : blocks) {
195         bb_list.emplace_back(bb);
196     }
197     return bb_list;
198 }
199 
VisitAllInstructions(const InstVisitor visitor) const200 void Graph::VisitAllInstructions(const InstVisitor visitor) const
201 {
202     for (auto &bb : graph_->GetBlocksRPO()) {
203         std::vector<Inst> inst_list = BasicBlock(bb).GetInstList();
204         for (auto &inst : inst_list) {
205             visitor(inst);
206         }
207     }
208 }
209 }  // namespace panda::defect_scan_aux