From 4597275ed22daa2c2ed2e0fe7c3cd967e071ddc7 Mon Sep 17 00:00:00 2001 From: Gary Frost <frost.gary@gmail.com> Date: Wed, 23 Jan 2013 21:30:07 +0000 Subject: [PATCH] Max Grossman discovered/reported that Aparapi did not support do{}while(??). This is an attempt to rectify that. Added a junit test and a first implementation --- .../src/java/com/amd/aparapi/BlockWriter.java | 13 +++++++ .../java/com/amd/aparapi/ExpressionList.java | 24 +++++++++++- .../java/com/amd/aparapi/InstructionSet.java | 17 ++++++++- .../java/com/amd/aparapi/test/DoWhile.java | 38 +++++++++++++++++++ 4 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 test/codegen/src/java/com/amd/aparapi/test/DoWhile.java diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/BlockWriter.java b/com.amd.aparapi/src/java/com/amd/aparapi/BlockWriter.java index e2336381..71fab3fc 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/BlockWriter.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/BlockWriter.java @@ -60,6 +60,7 @@ import com.amd.aparapi.InstructionSet.CloneInstruction; import com.amd.aparapi.InstructionSet.CompositeArbitraryScopeInstruction; import com.amd.aparapi.InstructionSet.CompositeEmptyLoopInstruction; import com.amd.aparapi.InstructionSet.CompositeForEclipseInstruction; +import com.amd.aparapi.InstructionSet.CompositeDoWhileInstruction; import com.amd.aparapi.InstructionSet.CompositeForSunInstruction; import com.amd.aparapi.InstructionSet.CompositeIfElseInstruction; import com.amd.aparapi.InstructionSet.CompositeIfInstruction; @@ -291,6 +292,18 @@ abstract class BlockWriter{ write("}"); } + } else if (instruction instanceof CompositeDoWhileInstruction) { + newLine(); + write("do"); + Instruction blockStart = instruction.getFirstChild(); + Instruction blockEnd = instruction.getLastChild(); + writeBlock(blockStart, blockEnd); + write("while("); + writeConditional(((CompositeInstruction) instruction).getBranchSet(), true); + write(");"); + newLine(); + + } } diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/ExpressionList.java b/com.amd.aparapi/src/java/com/amd/aparapi/ExpressionList.java index bceada5d..ac28e944 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/ExpressionList.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/ExpressionList.java @@ -430,7 +430,7 @@ class ExpressionList{ if (tail != null && tail.isBranch() && tail.asBranch().isReverseConditional()) { /** - * This looks like an eclipse style for/while loop + * This looks like an eclipse style for/while loop or possibly a do{}while() * <pre> * eclipse for (INIT,??,DELTA){BODY} ... * [INIT] >> [BODY] [DELTA] ?? ?< ... @@ -446,6 +446,10 @@ class ExpressionList{ * >> [BODY] ?? ?< ... * --------> * <---------- + * do {BODY} while(??) + * [BODY] ?? ?< ... + * <----------- + * * </pre> **/ BranchSet branchSet = ((ConditionalBranch) tail.asBranch()).getOrCreateBranchSet(); @@ -487,6 +491,24 @@ class ExpressionList{ handled = true; } } + if (!handled){ + // do{}while()_ do not require any previous instruction + if (loopTop.getPrevExpr() ==null){ + throw new IllegalStateException("might be a dowhile with no provious expression"); + + }else if (!(loopTop.getPrevExpr().isBranch() && loopTop.getPrevExpr().asBranch().isForwardUnconditional())){ + if (doesNotContainCompositeOrBranch(branchSet.getTarget().getRootExpr(), branchSet.getFirst().getPrevExpr())) { + loopTop = loopTop.getPrevExpr(); + branchSet.unhook(); + addAsComposites(ByteCode.COMPOSITE_DO_WHILE, loopTop, branchSet); + handled = true; + } + }else{ + throw new IllegalStateException("might be mistaken for a do while!"); + } + + + } } } if (!handled && _instruction.isForwardConditionalBranchTarget() && tail.isBranch() diff --git a/com.amd.aparapi/src/java/com/amd/aparapi/InstructionSet.java b/com.amd.aparapi/src/java/com/amd/aparapi/InstructionSet.java index 755a45db..573ee740 100644 --- a/com.amd.aparapi/src/java/com/amd/aparapi/InstructionSet.java +++ b/com.amd.aparapi/src/java/com/amd/aparapi/InstructionSet.java @@ -602,7 +602,7 @@ class InstructionSet{ COMPOSITE_IF, // COMPOSITE_IF_ELSE, // COMPOSITE_FOR_SUN, // - COMPOSITE_FOR_ECLIPSE, // + COMPOSITE_FOR_ECLIPSE,// COMPOSITE_ARBITRARY_SCOPE, // COMPOSITE_WHILE, // CLONE, // @@ -613,7 +613,8 @@ class InstructionSet{ FIELD_ARRAY_ELEMENT_INCREMENT, // FIELD_ARRAY_ELEMENT_ASSIGN, // HEAD, // - COMPOSITE_EMPTY_LOOP; + COMPOSITE_EMPTY_LOOP,// + COMPOSITE_DO_WHILE; private Class<?> clazz; @@ -835,6 +836,9 @@ class InstructionSet{ case COMPOSITE_EMPTY_LOOP: compositeInstruction = new CompositeEmptyLoopInstruction(_methodModel, _firstChild, _lastChild, _branchSet); break; + case COMPOSITE_DO_WHILE: + compositeInstruction = new CompositeDoWhileInstruction(_methodModel, _firstChild, _lastChild, _branchSet); + break; } return (compositeInstruction); @@ -886,6 +890,15 @@ class InstructionSet{ } } + + static class CompositeDoWhileInstruction extends CompositeInstruction{ + + protected CompositeDoWhileInstruction(MethodModel method, Instruction _firstChild, Instruction _lastChild, + BranchSet _branchSet) { + super(method, ByteCode.COMPOSITE_DO_WHILE, _firstChild, _lastChild, _branchSet); + + } + } static class CompositeForEclipseInstruction extends CompositeInstruction{ diff --git a/test/codegen/src/java/com/amd/aparapi/test/DoWhile.java b/test/codegen/src/java/com/amd/aparapi/test/DoWhile.java new file mode 100644 index 00000000..409efbc1 --- /dev/null +++ b/test/codegen/src/java/com/amd/aparapi/test/DoWhile.java @@ -0,0 +1,38 @@ +package com.amd.aparapi.test; + +public class DoWhile{ + public void run() { + @SuppressWarnings("unused") boolean pass = false; + int i = 0; + do{ + pass = true; + i++; + }while (i < 10); + } +} +/**{OpenCL{ +typedef struct This_s{ + + int passid; +}This; +int get_pass_id(This *this){ + return this->passid; + } + +__kernel void run( + int passid +){ + This thisStruct; + This* this=&thisStruct; + this->passid = passid; + { + char pass = 0; + int i = 0; + do{ + pass = 1; + i++; + }while (i<10); + return; + } +} +}OpenCL}**/ -- GitLab