1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-08-02 09:29:35 +00:00

Added a phase 2 block assertion checking that the program always contains all referenced blocks.

This commit is contained in:
Jesper Gravgaard 2017-07-13 22:03:52 +02:00
parent 56cf4c80ef
commit de8e5139cc
7 changed files with 83 additions and 2 deletions

View File

@ -13,6 +13,7 @@ Features
- Add ability to call ASM code from KC.
- Add ability to call KC code from ASM. (maybe declare some functions external to ensure their interface is well defined. Maybe generate ASM call stubs.)
- Add inline ASM (maybe?)
- Handle long branches
Process/Code Structure Improvement
- Make each phase return a separate object graph (allowing for keeeping the history in memory & performing rollbacks)

View File

@ -0,0 +1,3 @@
lda {zpby2}
ldy {zpby1}
sta {cowo1},y

View File

@ -0,0 +1,3 @@
lda {zpby1}
cmp #{coby1}
bne {la1}

View File

@ -40,7 +40,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
splitCurrentBlock(scope.addLabelIntermediate());
if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) {
addStatementToCurrentBlock(new StatementAssignment(origCall.getLValue(), procReturnVar));
} {
} else {
// No return type. Remove variable receiving the result.
LValue lValue = origCall.getLValue();
if(lValue instanceof Variable) {

View File

@ -0,0 +1,73 @@
package dk.camelot64.kickc.icl;
/** Assert that all referenced blocks exist in the program */
public class Pass2AssertBlocks extends Pass2SsaAssertion {
public Pass2AssertBlocks(ControlFlowGraph graph, Scope scope) {
super(graph, scope);
}
@Override
public void check() throws AssertionFailed {
ControlFlowGraphBaseVisitor<Void> blockReferenceFinder = new BlockReferenceChecker(getGraph());
blockReferenceFinder.visitGraph(getGraph());
}
private static class BlockReferenceChecker extends ControlFlowGraphBaseVisitor<Void> {
private ControlFlowGraph graph;
public BlockReferenceChecker(ControlFlowGraph graph) {
this.graph = graph;
}
private void assertBlock(Label blockLabel) throws AssertionFailed {
if (blockLabel == null) {
return;
}
if (blockLabel.getFullName().equals("@RETURN")) {
return;
}
ControlFlowBlock block = graph.getBlock(blockLabel);
if (block == null) {
throw new AssertionFailed("Compilation Process Error! Block referenced, but not found in program. " + blockLabel);
}
}
@Override
public Void visitBlock(ControlFlowBlock block) {
assertBlock(block.getDefaultSuccessor());
assertBlock(block.getCallSuccessor());
assertBlock(block.getConditionalSuccessor());
return super.visitBlock(block);
}
@Override
public Void visitConditionalJump(StatementConditionalJump conditionalJump) {
assertBlock(conditionalJump.getDestination());
return super.visitConditionalJump(conditionalJump);
}
@Override
public Void visitCall(StatementCall callLValue) {
assertBlock(callLValue.getProcedure().getLabel());
return super.visitCall(callLValue);
}
@Override
public Void visitPhi(StatementPhi phi) {
for (StatementPhi.PreviousSymbol previousSymbol : phi.getPreviousVersions()) {
assertBlock(previousSymbol.getBlock());
}
return super.visitPhi(phi);
}
@Override
public Void visitJump(StatementJump jump) {
assertBlock(jump.getDestination());
return super.visitJump(jump);
}
}
}

View File

@ -72,6 +72,7 @@ public class Pass3RegisterAllocation {
//allocation.allocate(symbols.getVariable("a#1"), new RegisterAllocation.RegisterAByte());
//allocation.allocate(symbols.getVariable("a#0"), new RegisterAllocation.RegisterAByte());
// Optimal Registers for flipper-rex2.kc
allocation.allocate(symbols.getVariable("plot::i#0"), RegisterAllocation.getRegisterX());
allocation.allocate(symbols.getVariable("plot::i#1"), RegisterAllocation.getRegisterX());
allocation.allocate(symbols.getVariable("plot::i#2"), RegisterAllocation.getRegisterX());
@ -126,7 +127,6 @@ public class Pass3RegisterAllocation {
allocation.allocate(symbols.getVariable("c#2"), RegisterAllocation.getRegisterX());
allocation.allocate(symbols.getVariable("c#3"), RegisterAllocation.getRegisterX());
allocation.allocate(symbols.getVariable("c#4"), RegisterAllocation.getRegisterX());
symbols.setAllocation(allocation);
}

View File

@ -73,6 +73,7 @@ public class Main {
List<Pass2SsaAssertion> assertions = new ArrayList<>();
assertions.add(new Pass2AssertSymbols(controlFlowGraph, programScope));
assertions.add(new Pass2AssertBlocks(controlFlowGraph, programScope));
boolean ssaOptimized = true;
while (ssaOptimized) {