| 20 | namespace opt { |
| 21 | |
| 22 | Pass::Status WrapOpKill::Process() { |
| 23 | bool modified = false; |
| 24 | |
| 25 | auto func_to_process = |
| 26 | context()->GetStructuredCFGAnalysis()->FindFuncsCalledFromContinue(); |
| 27 | for (uint32_t func_id : func_to_process) { |
| 28 | Function* func = context()->GetFunction(func_id); |
| 29 | bool successful = func->WhileEachInst([this, &modified](Instruction* inst) { |
| 30 | const auto opcode = inst->opcode(); |
| 31 | if ((opcode == spv::Op::OpKill) || |
| 32 | (opcode == spv::Op::OpTerminateInvocation)) { |
| 33 | modified = true; |
| 34 | if (!ReplaceWithFunctionCall(inst)) { |
| 35 | return false; |
| 36 | } |
| 37 | } |
| 38 | return true; |
| 39 | }); |
| 40 | |
| 41 | if (!successful) { |
| 42 | return Status::Failure; |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | if (opkill_function_ != nullptr) { |
| 47 | assert(modified && |
| 48 | "The function should only be generated if something was modified."); |
| 49 | context()->AddFunction(std::move(opkill_function_)); |
| 50 | } |
| 51 | if (opterminateinvocation_function_ != nullptr) { |
| 52 | assert(modified && |
| 53 | "The function should only be generated if something was modified."); |
| 54 | context()->AddFunction(std::move(opterminateinvocation_function_)); |
| 55 | } |
| 56 | return (modified ? Status::SuccessWithChange : Status::SuccessWithoutChange); |
| 57 | } |
| 58 | |
| 59 | bool WrapOpKill::ReplaceWithFunctionCall(Instruction* inst) { |
| 60 | assert((inst->opcode() == spv::Op::OpKill || |
nothing calls this directly
no test coverage detected