| 396 | } |
| 397 | |
| 398 | void GcnCompiler::emitControlFlowEndIf(const GcnToken& token) |
| 399 | { |
| 400 | if (m_controlFlowStack.size() == 0 || |
| 401 | m_controlFlowStack.back().type != GcnCfgBlockType::If) |
| 402 | { |
| 403 | Logger::exception("GcnCompiler: 'EndIf' without 'If' found"); |
| 404 | } |
| 405 | |
| 406 | // Remove the block from the stack, it's closed |
| 407 | GcnCfgBlock block = m_controlFlowStack.back(); |
| 408 | m_controlFlowStack.pop_back(); |
| 409 | |
| 410 | uint32_t labelMerge = m_blockTerminators.empty() |
| 411 | ? block.b_if.labelEnd |
| 412 | : m_blockTerminators.back(); |
| 413 | |
| 414 | // Write out the 'if' header |
| 415 | m_module.beginInsertion(block.b_if.headerPtr); |
| 416 | |
| 417 | m_module.opSelectionMerge( |
| 418 | labelMerge, |
| 419 | spv::SelectionControlMaskNone); |
| 420 | |
| 421 | m_module.opBranchConditional( |
| 422 | block.b_if.conditionId, |
| 423 | block.b_if.labelIf, |
| 424 | block.b_if.labelElse != 0 |
| 425 | ? block.b_if.labelElse |
| 426 | : labelMerge); |
| 427 | |
| 428 | m_module.endInsertion(); |
| 429 | |
| 430 | if (m_blockTerminators.empty()) |
| 431 | { |
| 432 | // End the active 'if' or 'else' block |
| 433 | m_module.opBranch(labelMerge); |
| 434 | m_module.opLabel(labelMerge); |
| 435 | } |
| 436 | else |
| 437 | { |
| 438 | // if the block is already closed by other terminator instruction, |
| 439 | // then don't emit branch |
| 440 | // remove the terminator |
| 441 | m_blockTerminators.pop_back(); |
| 442 | } |
| 443 | } |
| 444 | |
| 445 | void GcnCompiler::emitControlFlowLoop(const GcnToken& token) |
| 446 | { |
no test coverage detected