| 443 | } |
| 444 | |
| 445 | void GcnCompiler::emitControlFlowLoop(const GcnToken& token) |
| 446 | { |
| 447 | // Declare the 'loop' block |
| 448 | GcnCfgBlock block; |
| 449 | block.type = GcnCfgBlockType::Loop; |
| 450 | block.b_loop.labelHeader = m_module.allocateId(); |
| 451 | block.b_loop.labelBegin = m_module.allocateId(); |
| 452 | block.b_loop.labelContinue = m_module.allocateId(); |
| 453 | block.b_loop.labelBreak = m_module.allocateId(); |
| 454 | m_controlFlowStack.push_back(block); |
| 455 | |
| 456 | m_module.opBranch(block.b_loop.labelHeader); |
| 457 | m_module.opLabel(block.b_loop.labelHeader); |
| 458 | |
| 459 | m_module.opLoopMerge( |
| 460 | block.b_loop.labelBreak, |
| 461 | block.b_loop.labelContinue, |
| 462 | spv::LoopControlMaskNone); |
| 463 | |
| 464 | m_module.opBranch(block.b_loop.labelBegin); |
| 465 | m_module.opLabel(block.b_loop.labelBegin); |
| 466 | |
| 467 | // This will make for(;;) becomes while(true) |
| 468 | uint32_t labelTrue = m_module.allocateId(); |
| 469 | m_module.opBranchConditional(m_module.constBool(true), |
| 470 | labelTrue, |
| 471 | block.b_loop.labelBreak); |
| 472 | m_module.opLabel(labelTrue); |
| 473 | } |
| 474 | |
| 475 | void GcnCompiler::emitControlFlowEndLoop(const GcnToken& token) |
| 476 | { |
no test coverage detected