| 67 | } |
| 68 | |
| 69 | bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function, |
| 70 | spv::ExecutionModel model) { |
| 71 | bool modified = false; |
| 72 | Instruction* last_line_dbg_inst = nullptr; |
| 73 | function->ForEachInst( |
| 74 | [model, &modified, &last_line_dbg_inst, this](Instruction* inst) { |
| 75 | // Track the debug information so we can have a meaningful message. |
| 76 | if (inst->opcode() == spv::Op::OpLabel || inst->IsNoLine()) { |
| 77 | last_line_dbg_inst = nullptr; |
| 78 | return; |
| 79 | } else if (inst->IsLine()) { |
| 80 | last_line_dbg_inst = inst; |
| 81 | return; |
| 82 | } |
| 83 | |
| 84 | bool replace = false; |
| 85 | if (model != spv::ExecutionModel::Fragment && |
| 86 | IsFragmentShaderOnlyInstruction(inst)) { |
| 87 | replace = true; |
| 88 | } |
| 89 | |
| 90 | if (model != spv::ExecutionModel::TessellationControl && |
| 91 | model != spv::ExecutionModel::GLCompute && |
| 92 | !context()->IsTargetEnvAtLeast(SPV_ENV_UNIVERSAL_1_3)) { |
| 93 | if (inst->opcode() == spv::Op::OpControlBarrier) { |
| 94 | assert(model != spv::ExecutionModel::Kernel && |
| 95 | "Expecting to be working on a shader module."); |
| 96 | replace = true; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | if (replace) { |
| 101 | modified = true; |
| 102 | if (last_line_dbg_inst == nullptr) { |
| 103 | ReplaceInstruction(inst, nullptr, 0, 0); |
| 104 | } else { |
| 105 | // Get the name of the source file. |
| 106 | uint32_t file_name_id = 0; |
| 107 | if (last_line_dbg_inst->opcode() == spv::Op::OpLine) { |
| 108 | file_name_id = last_line_dbg_inst->GetSingleWordInOperand(0); |
| 109 | } else { // NSDI::DebugLine |
| 110 | uint32_t debug_source_id = |
| 111 | last_line_dbg_inst->GetSingleWordInOperand(2); |
| 112 | Instruction* debug_source_inst = |
| 113 | context()->get_def_use_mgr()->GetDef(debug_source_id); |
| 114 | file_name_id = debug_source_inst->GetSingleWordInOperand(2); |
| 115 | } |
| 116 | Instruction* file_name = |
| 117 | context()->get_def_use_mgr()->GetDef(file_name_id); |
| 118 | const std::string source = file_name->GetInOperand(0).AsString(); |
| 119 | |
| 120 | // Get the line number and column number. |
| 121 | uint32_t line_number = |
| 122 | last_line_dbg_inst->GetSingleWordInOperand(1); |
| 123 | uint32_t col_number = last_line_dbg_inst->GetSingleWordInOperand(2); |
| 124 | |
| 125 | // Replace the instruction. |
| 126 | ReplaceInstruction(inst, source.c_str(), line_number, col_number); |
nothing calls this directly
no test coverage detected