From 91ed1223bd57256f278608ed84a7edeffbbd9fe2 Mon Sep 17 00:00:00 2001 From: Hunter Bastian <81837742+hunterbastian@users.noreply.github.com> Date: Tue, 12 May 2026 01:15:14 -0400 Subject: [PATCH] Handle unused locals without scope metadata --- .../aparapi/internal/writer/BlockWriter.java | 48 ++++---- .../codegen/test/ArbitraryScopeTest.java | 106 +++++++++--------- .../aparapi/runtime/ArbitraryScopeTest.java | 6 - 3 files changed, 74 insertions(+), 86 deletions(-) diff --git a/src/main/java/com/aparapi/internal/writer/BlockWriter.java b/src/main/java/com/aparapi/internal/writer/BlockWriter.java index 013239d0..15900fe1 100644 --- a/src/main/java/com/aparapi/internal/writer/BlockWriter.java +++ b/src/main/java/com/aparapi/internal/writer/BlockWriter.java @@ -411,32 +411,32 @@ public void writeInstruction(Instruction _instruction) throws CodeGenException { final LocalVariableInfo localVariableInfo = assignToLocalVariable.getLocalVariableInfo(); - if ((_instruction.getFirstChild() instanceof I_NEWARRAY)) { - if (localVariableInfo == null) { - throw new CodeGenException("outOfScope" + _instruction.getThisPC() + " = "); - } else { - final String descriptor = localVariableInfo.getVariableDescriptor(); - write(convertType(descriptor, true, true)); - write(localVariableInfo.getVariableName()); - } + if (localVariableInfo == null) { + // A javac local variable table can omit unused locals. Preserve any + // RHS side effects without inventing a name or scope for the local. + for (Instruction operand = _instruction.getFirstChild(); operand != null; operand = operand.getNextExpr()) { + writeInstruction(operand); + } } else { - if (assignToLocalVariable.isDeclaration()) { - final String descriptor = localVariableInfo.getVariableDescriptor(); - // Arrays always map to __global arrays - if (descriptor.startsWith("[")) { + if ((_instruction.getFirstChild() instanceof I_NEWARRAY)) { + final String descriptor = localVariableInfo.getVariableDescriptor(); + write(convertType(descriptor, true, true)); + write(localVariableInfo.getVariableName()); + } else { + if (assignToLocalVariable.isDeclaration()) { + final String descriptor = localVariableInfo.getVariableDescriptor(); + // Arrays always map to __global arrays + if (descriptor.startsWith("[")) { write(" __global "); - } - write(convertType(descriptor, true, false)); - } - if (localVariableInfo == null) { - throw new CodeGenException("outOfScope" + _instruction.getThisPC() + " = "); - } else { - write(localVariableInfo.getVariableName() + " = "); - } - } - - for (Instruction operand = _instruction.getFirstChild(); operand != null; operand = operand.getNextExpr()) { - writeInstruction(operand); + } + write(convertType(descriptor, true, false)); + } + write(localVariableInfo.getVariableName() + " = "); + } + + for (Instruction operand = _instruction.getFirstChild(); operand != null; operand = operand.getNextExpr()) { + writeInstruction(operand); + } } } else if (_instruction instanceof AssignToArrayElement) { diff --git a/src/test/java/com/aparapi/codegen/test/ArbitraryScopeTest.java b/src/test/java/com/aparapi/codegen/test/ArbitraryScopeTest.java index bbc299b8..525faa7b 100644 --- a/src/test/java/com/aparapi/codegen/test/ArbitraryScopeTest.java +++ b/src/test/java/com/aparapi/codegen/test/ArbitraryScopeTest.java @@ -15,75 +15,69 @@ */ package com.aparapi.codegen.test; -import org.junit.Ignore; import org.junit.Test; public class ArbitraryScopeTest extends com.aparapi.codegen.CodeGenJUnitBase { private static final String[] expectedOpenCL = { "typedef struct This_s{\n" - + " int width;\n" - + " float scale;\n" - + " int maxIterations;\n" - + "\n" - + " int passid;\n" - + " }This;\n" - + " int get_pass_id(This *this){\n" - + " return this->passid;\n" - + " }\n" - + "\n" - + " __kernel void run(\n" - + " int width,\n" - + " float scale,\n" - + " int maxIterations,\n" - + " int passid\n" - + " ){\n" - + " This thisStruct;\n" - + " This* this=&thisStruct;\n" - + " this->width = width;\n" - + " this->scale = scale;\n" - + " this->maxIterations = maxIterations;\n" - + " this->passid = passid;\n" - + " {\n" - + " int tid = 0;\n" - + " int i = tid % this->width;\n" - + " int j = tid / this->width;\n" - + " float x0 = (((float)i * this->scale) - ((this->scale / 2.0f) * (float)this->width)) / (float)this->width;\n" - + " float y0 = (((float)j * this->scale) - ((this->scale / 2.0f) * (float)this->width)) / (float)this->width;\n" - + " float x = x0;\n" - + " float y = y0;\n" - + " float x2 = x * x;\n" - + " float y2 = y * y;\n" - + " {\n" - + " float scaleSquare = this->scale * this->scale;\n" - + " int count = 0;\n" - + " for (int iter = 0; itermaxIterations; iter++){\n" - + " if ((x2 + y2)<=scaleSquare){\n" - + " y = ((2.0f * x) * y) + y0;\n" - + " x = (x2 - y2) + x0;\n" - + " x2 = x * x;\n" - + " y2 = y * y;\n" - + " count++;\n" - + " } else {\n" - + " count--;\n" - + " }\n" - + " }\n" - + " int value = (256 * count) / this->maxIterations;\n" - + " }\n" - + " float scaleSquare = 1.0f;\n" - + " return;\n" - + " }\n" - + " }\n" - + " "}; + + " int width;\n" + + " float scale;\n" + + " int maxIterations;\n" + + " int passid;\n" + + "}This;\n" + + "int get_pass_id(This *this){\n" + + " return this->passid;\n" + + "}\n" + + "__kernel void run(\n" + + " int width, \n" + + " float scale, \n" + + " int maxIterations, \n" + + " int passid\n" + + "){\n" + + " This thisStruct;\n" + + " This* this=&thisStruct;\n" + + " this->width = width;\n" + + " this->scale = scale;\n" + + " this->maxIterations = maxIterations;\n" + + " this->passid = passid;\n" + + " {\n" + + " int tid = 0;\n" + + " int i = tid % this->width;\n" + + " int j = tid / this->width;\n" + + " float x0 = (((float)i * this->scale) - ((this->scale / 2.0f) * (float)this->width)) / (float)this->width;\n" + + " float y0 = (((float)j * this->scale) - ((this->scale / 2.0f) * (float)this->width)) / (float)this->width;\n" + + " float x = x0;\n" + + " float y = y0;\n" + + " float x2 = x * x;\n" + + " float y2 = y * y;\n" + + " {\n" + + " float scaleSquare = this->scale * this->scale;\n" + + " int count = 0;\n" + + " for (int iter = 0; itermaxIterations; iter++){\n" + + " if ((x2 + y2)<=scaleSquare){\n" + + " y = ((2.0f * x) * y) + y0;\n" + + " x = (x2 - y2) + x0;\n" + + " x2 = x * x;\n" + + " y2 = y * y;\n" + + " count++;\n" + + " } else {\n" + + " count--;\n" + + " }\n" + + " }\n" + + " (256 * count) / this->maxIterations;\n" + + " }\n" + + " float scaleSquare = 1.0f;\n" + + " return;\n" + + " }\n" + + "}\n"}; private static final Class expectedException = null; - @Ignore @Test public void ArbitraryScopeTest() { test(com.aparapi.codegen.test.ArbitraryScope.class, expectedException, expectedOpenCL); } - @Ignore @Test public void ArbitraryScopeTestWorksWithCaching() { test(com.aparapi.codegen.test.ArbitraryScope.class, expectedException, expectedOpenCL); diff --git a/src/test/java/com/aparapi/runtime/ArbitraryScopeTest.java b/src/test/java/com/aparapi/runtime/ArbitraryScopeTest.java index bb186621..32fc5baa 100644 --- a/src/test/java/com/aparapi/runtime/ArbitraryScopeTest.java +++ b/src/test/java/com/aparapi/runtime/ArbitraryScopeTest.java @@ -16,15 +16,10 @@ package com.aparapi.runtime; import com.aparapi.Kernel; -import com.aparapi.Range; -import org.junit.Ignore; import org.junit.Test; -import static org.junit.Assert.assertEquals; - public class ArbitraryScopeTest { - @Ignore("Known bug, ignoring test") @Test public void UnusedInArbitraryScopeTest() { @@ -40,7 +35,6 @@ public void run() { kernel.execute(1); } - @Ignore("Known bug, ignoring test") @Test public void UnusedInNormalScopeTest() {