Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/main/java/com/aparapi/internal/instruction/ExpressionList.java
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,26 @@ public boolean foldComposite(final Instruction _instruction) throws ClassParseEx

}
}
if (!handled && tail.isBranch() && tail.asBranch().isForwardUnconditional()
&& _instruction.isForwardConditionalBranchTarget()) {
final Branch forwardGoto = tail.asBranch();
final Instruction forwardTarget = forwardGoto.getTarget();
final Instruction beforeForwardTarget = forwardTarget.getPrevPC();
if (forwardTarget.isAfter(_instruction) && forwardTarget.isForwardConditionalBranchTarget()) {
if (beforeForwardTarget != null && beforeForwardTarget.isBranch()
&& beforeForwardTarget.asBranch().isReverseUnconditional()) {
final ConditionalBranch lastForwardConditional = _instruction.getForwardConditionalBranches().getLast();
final BranchSet branchSet = lastForwardConditional.getOrCreateBranchSet();
if (doesNotContainCompositeOrBranch(branchSet.getLast().getNextExpr(), forwardGoto)) {
forwardGoto.setBreakOrContinue(true);
branchSet.unhook();
forwardGoto.unhook();
addAsComposites(ByteCode.COMPOSITE_IF, branchSet.getFirst().getPrevExpr(), branchSet);
handled = true;
}
}
}
}
if (!handled && !tail.isForwardBranch() && _instruction.isForwardConditionalBranchTarget()) {
/**
* This an if(exp)
Expand Down
60 changes: 51 additions & 9 deletions src/main/java/com/aparapi/internal/writer/BlockWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public abstract class BlockWriter{

public final static String arrayDimMangleSuffix = "__javaArrayDimension";

private final Stack<Instruction> breakTargets = new Stack<Instruction>();

public abstract void write(String _string);

public void writeln(String _string) {
Expand Down Expand Up @@ -207,11 +209,11 @@ public void writeComposite(CompositeInstruction instruction) throws CodeGenExcep
if (!(delta instanceof CompositeInstruction)) {
writeInstruction(delta);
write(")");
writeBlock(blockStart, delta);
writeBreakableBlock(blockStart, delta, branchSet.getTarget());
} else {
write("){");
in();
writeSequence(blockStart, delta);
writeBreakableSequence(blockStart, delta, branchSet.getTarget());

newLine();
writeSequence(delta, delta.getNextExpr());
Expand All @@ -229,7 +231,7 @@ public void writeComposite(CompositeInstruction instruction) throws CodeGenExcep
final Instruction blockStart = writeConditional(branchSet);
write(")");
final Instruction lastGoto = instruction.getLastChild();
writeBlock(blockStart, lastGoto);
writeBreakableBlock(blockStart, lastGoto, branchSet.getTarget());

} else if (instruction instanceof CompositeEmptyLoopInstruction) {
newLine();
Expand All @@ -256,17 +258,18 @@ public void writeComposite(CompositeInstruction instruction) throws CodeGenExcep
while (last.getPrevExpr().isBranch()) {
last = last.getPrevExpr();
}
writeConditional(instruction.getBranchSet(), true);
final BranchSet branchSet = instruction.getBranchSet();
writeConditional(branchSet, true);
write("; ");
final Instruction delta = last.getPrevExpr();
if (!(delta instanceof CompositeInstruction)) {
writeInstruction(delta);
write(")");
writeBlock(topGoto.getNextExpr(), delta);
writeBreakableBlock(topGoto.getNextExpr(), delta, branchSet.getFallThrough());
} else {
write("){");
in();
writeSequence(topGoto.getNextExpr(), delta);
writeBreakableSequence(topGoto.getNextExpr(), delta, branchSet.getFallThrough());

newLine();
writeSequence(delta, delta.getNextExpr());
Expand All @@ -281,7 +284,7 @@ public void writeComposite(CompositeInstruction instruction) throws CodeGenExcep
write("do");
Instruction blockStart = instruction.getFirstChild();
Instruction blockEnd = instruction.getLastChild();
writeBlock(blockStart, blockEnd);
writeBreakableBlock(blockStart, blockEnd, ((CompositeInstruction) instruction).getBranchSet().getFallThrough());
write("while(");
writeConditional(((CompositeInstruction) instruction).getBranchSet(), true);
write(");");
Expand Down Expand Up @@ -327,6 +330,42 @@ public void writeBlock(Instruction _first, Instruction _last) throws CodeGenExce
write("}");
}

private void writeBreakableBlock(Instruction first, Instruction last, Instruction breakTarget) throws CodeGenException {
pushBreakTarget(breakTarget);
try {
writeBlock(first, last);
} finally {
popBreakTarget();
}
}

private void writeBreakableSequence(Instruction first, Instruction last, Instruction breakTarget) throws CodeGenException {
pushBreakTarget(breakTarget);
try {
writeSequence(first, last);
} finally {
popBreakTarget();
}
}

private void pushBreakTarget(Instruction breakTarget) {
breakTargets.push(breakTarget);
}

private void popBreakTarget() {
breakTargets.pop();
}

private boolean isCurrentBreakTarget(Branch branch) {
if (breakTargets.isEmpty()) {
return false;
}

final Instruction breakTarget = breakTargets.peek();
final Instruction branchTarget = branch.getTarget();
return branchTarget == breakTarget || branchTarget.getStartPC() == breakTarget.getStartPC();
}

public Instruction writeConditional(BranchSet _branchSet) throws CodeGenException {
return (writeConditional(_branchSet, false));
}
Expand Down Expand Up @@ -745,10 +784,13 @@ public void writeInstruction(Instruction _instruction) throws CodeGenException {
} else if (_instruction.getByteCode().equals(ByteCode.NONE)) {
// we are done
} else if (_instruction instanceof Branch) {
if(_instruction instanceof ConditionalBranch16)
final Branch branch = (Branch) _instruction;
if (isCurrentBreakTarget(branch)) {
write("break");
} else if(_instruction instanceof ConditionalBranch16)
writeConditionalBranch16((ConditionalBranch16) _instruction, true);
else
throw new CodeGenException(String.format("%s -> %04d", _instruction.getByteCode().toString().toLowerCase(), ((Branch) _instruction).getTarget().getThisPC()));
throw new CodeGenException(String.format("%s -> %04d", _instruction.getByteCode().toString().toLowerCase(), branch.getTarget().getThisPC()));
} else if (_instruction instanceof I_POP) {
//POP discarded void call return?
writeInstruction(_instruction.getFirstChild());
Expand Down
1 change: 0 additions & 1 deletion src/test/java/com/aparapi/codegen/test/Break.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,3 @@ public void run() {
}
}
}
/**{Throws{ClassParseException}Throws}**/
31 changes: 28 additions & 3 deletions src/test/java/com/aparapi/codegen/test/BreakTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,37 @@
*/
package com.aparapi.codegen.test;

import com.aparapi.internal.exception.ClassParseException;
import org.junit.Test;

public class BreakTest extends com.aparapi.codegen.CodeGenJUnitBase {
private static final String[] expectedOpenCL = null;
private static final Class<? extends com.aparapi.internal.exception.AparapiException> expectedException = ClassParseException.class;
private static final String[] expectedOpenCL = {
"typedef struct This_s{\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 passid\n" +
" ){\n" +
" This thisStruct;\n" +
" This* this=&thisStruct;\n" +
" this->passid = passid;\n" +
" {\n" +
" char pass = 0;\n" +
" for (int i = 0; i<10; i++){\n" +
" if (i==5){\n" +
" break;\n" +
" }\n" +
" pass = 1;\n" +
" }\n" +
" return;\n" +
" }\n" +
" }\n" +
" "};
private static final Class<? extends com.aparapi.internal.exception.AparapiException> expectedException = null;

@Test
public void BreakTest() {
Expand Down
1 change: 0 additions & 1 deletion src/test/java/com/aparapi/codegen/test/ForBreak.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,3 @@ public void run() {

}
}
/**{Throws{ClassParseException}Throws}**/
32 changes: 29 additions & 3 deletions src/test/java/com/aparapi/codegen/test/ForBreakTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,38 @@
*/
package com.aparapi.codegen.test;

import com.aparapi.internal.exception.ClassParseException;
import org.junit.Test;

public class ForBreakTest extends com.aparapi.codegen.CodeGenJUnitBase {
private static final String[] expectedOpenCL = null;
private static final Class<? extends com.aparapi.internal.exception.AparapiException> expectedException = ClassParseException.class;
private static final String[] expectedOpenCL = {
"typedef struct This_s{\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 passid\n" +
" ){\n" +
" This thisStruct;\n" +
" This* this=&thisStruct;\n" +
" this->passid = passid;\n" +
" {\n" +
" char pass = 0;\n" +
" for (int i = 0; i>2 && i<10; i++){\n" +
" pass = 0;\n" +
" if ((i==5 || i==6) && i==5){\n" +
" pass = 1;\n" +
" break;\n" +
" }\n" +
" }\n" +
" return;\n" +
" }\n" +
" }\n" +
" "};
private static final Class<? extends com.aparapi.internal.exception.AparapiException> expectedException = null;

@Test
public void ForBreakTest() {
Expand Down