| 2434 | _current_block_data->instructions.push_back(merge_label); |
| 2435 | } |
| 2436 | void emit_switch(const location &loc, id, id selector_block, id default_label, id default_block, const std::vector<id> &case_literal_and_labels, const std::vector<id> &case_blocks, unsigned int selection_control) override |
| 2437 | { |
| 2438 | assert(case_blocks.size() == case_literal_and_labels.size() / 2); |
| 2439 | |
| 2440 | spirv_instruction merge_label = _current_block_data->instructions.back(); |
| 2441 | assert(merge_label.op == spv::OpLabel); |
| 2442 | _current_block_data->instructions.pop_back(); |
| 2443 | |
| 2444 | // Add previous block containing the selector value first |
| 2445 | _current_block_data->append(_block_data[selector_block]); |
| 2446 | |
| 2447 | spirv_instruction switch_inst = _current_block_data->instructions.back(); |
| 2448 | assert(switch_inst.op == spv::OpSwitch); |
| 2449 | _current_block_data->instructions.pop_back(); |
| 2450 | |
| 2451 | // Add structured control flow instruction |
| 2452 | add_location(loc, *_current_block_data); |
| 2453 | add_instruction_without_result(spv::OpSelectionMerge) |
| 2454 | .add(merge_label) |
| 2455 | .add(selection_control & 0x3); // 'SelectionControl' happens to match the flags produced by the parser |
| 2456 | |
| 2457 | // Update switch instruction to contain all case labels |
| 2458 | switch_inst.operands[1] = default_label; |
| 2459 | switch_inst.add(case_literal_and_labels.begin(), case_literal_and_labels.end()); |
| 2460 | |
| 2461 | // Append all blocks belonging to the switch |
| 2462 | _current_block_data->instructions.push_back(switch_inst); |
| 2463 | |
| 2464 | std::vector<id> blocks = case_blocks; |
| 2465 | if (default_label != merge_label) |
| 2466 | blocks.push_back(default_block); |
| 2467 | // Eliminate duplicates (because of multiple case labels pointing to the same block) |
| 2468 | std::sort(blocks.begin(), blocks.end()); |
| 2469 | blocks.erase(std::unique(blocks.begin(), blocks.end()), blocks.end()); |
| 2470 | for (const id case_block : blocks) |
| 2471 | _current_block_data->append(_block_data[case_block]); |
| 2472 | |
| 2473 | _current_block_data->instructions.push_back(merge_label); |
| 2474 | } |
| 2475 | |
| 2476 | void emit_pragma(const std::string &) override |
| 2477 | { |