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) const28bool Inst::operator==(const Inst &inst) const 29 { 30 return inst_ == inst.inst_; 31 } 32 operator !=(const Inst & inst) const33bool Inst::operator!=(const Inst &inst) const 34 { 35 return inst_ != inst.inst_; 36 } 37 GetType() const38InstType Inst::GetType() const 39 { 40 return type_; 41 } 42 IsInstStLexVar() const43bool 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() const49bool 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() const55bool 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() const62bool 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() const68uint16_t Inst::GetArgIndex() const 69 { 70 ASSERT(inst_->IsParameter()); 71 return inst_->CastToParameter()->GetArgNumber(); 72 } 73 GetPc() const74uint32_t Inst::GetPc() const 75 { 76 return inst_->GetPc(); 77 } 78 GetBasicBlock() const79BasicBlock Inst::GetBasicBlock() const 80 { 81 return BasicBlock(inst_->GetBasicBlock()); 82 } 83 GetGraph() const84Graph Inst::GetGraph() const 85 { 86 return Graph(GetBasicBlock().GetGraph()); 87 } 88 GetInputInsts() const89std::vector<Inst> Inst::GetInputInsts() const 90 { 91 std::vector<Inst> inputs; 92 for (auto &input : inst_->GetInputs()) { 93 if (!input.GetInst()->IsSaveState()) { 94 inputs.emplace_back(input.GetInst()); 95 } 96 } 97 return inputs; 98 } 99 GetUserInsts() const100std::vector<Inst> Inst::GetUserInsts() const 101 { 102 std::vector<Inst> users; 103 auto user_list = inst_->GetUsers(); 104 for (auto &user : user_list) { 105 if (!user.GetInst()->IsSaveState()) { 106 users.emplace_back(user.GetInst()); 107 } 108 } 109 return users; 110 } 111 GetImms() const112std::vector<uint32_t> Inst::GetImms() const 113 { 114 ASSERT(inst_->IsIntrinsic()); 115 std::vector<uint32_t> imms; 116 auto &intrinsic_imms = inst_->CastToIntrinsic()->GetImms(); 117 for (auto imm : intrinsic_imms) { 118 imms.push_back(imm); 119 } 120 return imms; 121 } 122 GetInstType(const compiler::Inst * inst)123InstType Inst::GetInstType(const compiler::Inst *inst) 124 { 125 if (inst->IsIntrinsic()) { 126 return INTRINSIC_INSTTYPE_MAP_TABLE[inst->CastToIntrinsic()->GetIntrinsicId()]; 127 } 128 return OPCODE_INSTTYPE_MAP_TABLE[inst->GetOpcode()]; 129 } 130 operator ==(const BasicBlock & bb) const131bool BasicBlock::operator==(const BasicBlock &bb) const 132 { 133 return bb_ == bb.bb_; 134 } 135 operator !=(const BasicBlock & bb) const136bool BasicBlock::operator!=(const BasicBlock &bb) const 137 { 138 return bb_ != bb.bb_; 139 } 140 GetGraph() const141Graph BasicBlock::GetGraph() const 142 { 143 return Graph(bb_->GetGraph()); 144 } 145 GetPredBlocks() const146std::vector<BasicBlock> BasicBlock::GetPredBlocks() const 147 { 148 std::vector<BasicBlock> pred_blocks; 149 for (auto &bb : bb_->GetPredsBlocks()) { 150 pred_blocks.emplace_back(bb); 151 } 152 return pred_blocks; 153 } 154 GetSuccBlocks() const155std::vector<BasicBlock> BasicBlock::GetSuccBlocks() const 156 { 157 std::vector<BasicBlock> succ_blocks; 158 for (auto &bb : bb_->GetSuccsBlocks()) { 159 succ_blocks.emplace_back(bb); 160 } 161 return succ_blocks; 162 } 163 GetInstList() const164std::vector<Inst> BasicBlock::GetInstList() const 165 { 166 std::vector<Inst> inst_list; 167 for (auto inst : bb_->AllInsts()) { 168 if (!inst->IsSaveState()) { 169 inst_list.emplace_back(inst); 170 } 171 } 172 return inst_list; 173 } 174 GetStartBasicBlock() const175BasicBlock Graph::GetStartBasicBlock() const 176 { 177 return BasicBlock(graph_->GetStartBlock()); 178 } 179 GetEndBasicBlock() const180BasicBlock Graph::GetEndBasicBlock() const 181 { 182 return BasicBlock(graph_->GetEndBlock()); 183 } 184 GetBasicBlockList() const185std::vector<BasicBlock> Graph::GetBasicBlockList() const 186 { 187 std::vector<BasicBlock> bb_list; 188 auto &blocks = graph_->GetBlocksRPO(); 189 for (auto &bb : blocks) { 190 bb_list.emplace_back(bb); 191 } 192 return bb_list; 193 } 194 VisitAllInstructions(const InstVisitor visitor) const195void Graph::VisitAllInstructions(const InstVisitor visitor) const 196 { 197 for (auto &bb : graph_->GetBlocksRPO()) { 198 std::vector<Inst> inst_list = BasicBlock(bb).GetInstList(); 199 for (auto &inst : inst_list) { 200 visitor(inst); 201 } 202 } 203 } 204 } // namespace panda::defect_scan_aux