| 276 | } |
| 277 | |
| 278 | bool MemPass::IsTargetVar(uint32_t varId) { |
| 279 | if (varId == 0) { |
| 280 | return false; |
| 281 | } |
| 282 | |
| 283 | if (seen_non_target_vars_.find(varId) != seen_non_target_vars_.end()) |
| 284 | return false; |
| 285 | if (seen_target_vars_.find(varId) != seen_target_vars_.end()) return true; |
| 286 | const Instruction* varInst = get_def_use_mgr()->GetDef(varId); |
| 287 | if (varInst->opcode() != spv::Op::OpVariable) return false; |
| 288 | const uint32_t varTypeId = varInst->type_id(); |
| 289 | const Instruction* varTypeInst = get_def_use_mgr()->GetDef(varTypeId); |
| 290 | if (spv::StorageClass(varTypeInst->GetSingleWordInOperand( |
| 291 | kTypePointerStorageClassInIdx)) != spv::StorageClass::Function) { |
| 292 | seen_non_target_vars_.insert(varId); |
| 293 | return false; |
| 294 | } |
| 295 | const uint32_t varPteTypeId = |
| 296 | varTypeInst->GetSingleWordInOperand(kTypePointerTypeIdInIdx); |
| 297 | Instruction* varPteTypeInst = get_def_use_mgr()->GetDef(varPteTypeId); |
| 298 | if (!IsTargetType(varPteTypeInst)) { |
| 299 | seen_non_target_vars_.insert(varId); |
| 300 | return false; |
| 301 | } |
| 302 | seen_target_vars_.insert(varId); |
| 303 | return true; |
| 304 | } |
| 305 | |
| 306 | // Remove all |phi| operands coming from unreachable blocks (i.e., blocks not in |
| 307 | // |reachable_blocks|). There are two types of removal that this function can |