(initialVar, conditionNode, updateVar)
| 370 | } |
| 371 | |
| 372 | loopIsBounded(initialVar, conditionNode, updateVar) { |
| 373 | // A loop is considered "bounded" if we can determine at compile time that it will |
| 374 | // execute a known number of iterations. This happens when: |
| 375 | // 1. The condition compares the loop variable against a compile-time constant |
| 376 | // 2. At least one side of the comparison uses only literals (no variables/uniforms) |
| 377 | |
| 378 | if (!conditionNode) return false; |
| 379 | |
| 380 | // Analyze the condition node - it should be a comparison operation |
| 381 | const conditionData = DAG.getNodeDataFromID(this.strandsContext.dag, conditionNode.id); |
| 382 | |
| 383 | if (conditionData.nodeType !== NodeType.OPERATION) { |
| 384 | return false; |
| 385 | } |
| 386 | |
| 387 | // For a comparison like "i < bound", we need at least one side to use only literals |
| 388 | // The condition should have two dependencies: left and right operands |
| 389 | if (!conditionData.dependsOn || conditionData.dependsOn.length !== 2) { |
| 390 | return false; |
| 391 | } |
| 392 | |
| 393 | // Check if either operand uses only literals |
| 394 | const leftOperand = createStrandsNode(conditionData.dependsOn[0], 1, this.strandsContext); |
| 395 | const rightOperand = createStrandsNode(conditionData.dependsOn[1], 1, this.strandsContext); |
| 396 | |
| 397 | const leftUsesOnlyLiterals = this.nodeUsesOnlyLiterals(leftOperand); |
| 398 | const rightUsesOnlyLiterals = this.nodeUsesOnlyLiterals(rightOperand); |
| 399 | |
| 400 | // At least one side should use only literals for the loop to be bounded |
| 401 | return leftUsesOnlyLiterals || rightUsesOnlyLiterals; |
| 402 | } |
| 403 | |
| 404 | nodeUsesOnlyLiterals(node) { |
| 405 | // Recursively check if a node and all its dependencies use only literals |
no test coverage detected