1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Added missing fragments for rolling unsigned words. Added test demonstrating Unroller problem.

This commit is contained in:
jespergravgaard 2019-08-15 08:34:50 +02:00
parent 8d7b0385cb
commit ea9054a562
7 changed files with 62 additions and 13 deletions

View File

@ -0,0 +1,10 @@
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1

View File

@ -0,0 +1,14 @@
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1
asl {z1}
rol {z1}+1

View File

@ -344,19 +344,10 @@ public class Compiler {
optimizations.add(new Pass2EliminateUnusedBlocks(program));
if(!disableLoopHeadConstant) {
optimizations.add(new PassNStatementIndices(program));
optimizations.add(() -> {
program.clearDominators();
return false;
});
optimizations.add(() -> {
program.clearLoopSet();
return false;
});
optimizations.add(() -> { program.clearDominators(); return false; });
optimizations.add(() -> { program.clearLoopSet(); return false; });
optimizations.add(new Pass2LoopHeadConstantIdentification(program));
optimizations.add(() -> {
program.clearStatementIndices();
return false;
});
optimizations.add(() -> { program.clearStatementIndices(); return false; });
}
return optimizations;
}

View File

@ -104,6 +104,8 @@ public class Pass2LoopHeadConstantIdentification extends Pass2SsaOptimization {
return blocks;
};
//getLog().append("Unrolling Constant Loop Head " +loopHeadBlock.getLabel());
// Copy the block and all statements - enter through the copy - finish through the original
Unroller.UnrollStrategy unrollStrategy = new Unroller.UnrollStrategy() {
@Override

View File

@ -75,6 +75,7 @@ public class Unroller {
* Ensure that variables defined inside and used outside the blocks to be copied has different versions in different successors blocks.
*/
private void prepare() {
// TODO Handle variables modified inside called functions!
for(VariableRef origVarRef : getVarsDefinedIn(unrollBlocks, program)) {
// Find out if the variable is ever referenced outside the loop
if(isReferencedOutside(origVarRef, unrollBlocks, program)) {
@ -204,6 +205,7 @@ public class Unroller {
// Variable has no version in the predecessor block - add a new PHI and populate later!
VariableRef newVarRef = createNewVersion(doingVarRef);
predecessor.getPhiBlock().addPhiVariable(newVarRef);
//program.getLog().append("Adding PHI for "+newVarRef+" to "+predecessor.getLabel());
varVersions.put(predecessor.getLabel(), newVarRef);
todo.put(predecessor.getLabel(), newVarRef);
predecessorVarRef = newVarRef;
@ -211,6 +213,8 @@ public class Unroller {
doingPhiVariable.setrValue(predecessor.getLabel(), predecessorVarRef);
}
}
//program.getLog().append("Completing PHI-functions...");
//program.getLog().append(program.getGraph().toString(program));
}
}

View File

@ -36,6 +36,11 @@ public class TestPrograms {
public TestPrograms() {
}
//@Test
//public void testLoopheadProblem() throws IOException, URISyntaxException {
// compileAndCompare("loophead-problem");
//}
@Test
public void testSwitch0() throws IOException, URISyntaxException {
compileAndCompare("switch-0");
@ -1638,7 +1643,7 @@ public class TestPrograms {
//@Test
//public void testRobozzle64() throws IOException, URISyntaxException {
// compileAndCompare("complex/robozzle_c64/robozzle64", log());
// compileAndCompare("complex/robozzle_c64/robozzle64", log().verboseSSAOptimize().verboseLoopUnroll());
//}
//@Test

23
src/test/kc/loophead-problem.kc Executable file
View File

@ -0,0 +1,23 @@
// Demonstrates a problem where constant loophead unrolling results in an error
// The result is a NullPointerException
// The cause is that the Unroller does not handle the variable opcode correctly.
// The Unroller gets the verwions for opcode wrong because it misses the fact that it is modified inside call to popup_selector()
const byte* screen = $0400;
byte opcode = 'a'; // Offending unroll variable
void main() {
screen[40] = opcode;
popup_selector();
screen[41] = opcode;
}
void popup_selector() {
for (byte k = 0; k <= 2; k++) {
opcode = 'b';
screen[k] = opcode;
}
}