mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-08 17:54:40 +00:00
Added a phase 2 block assertion checking that the program always contains all referenced blocks.
This commit is contained in:
parent
56cf4c80ef
commit
de8e5139cc
@ -13,6 +13,7 @@ Features
|
|||||||
- Add ability to call ASM code from KC.
|
- 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 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?)
|
- Add inline ASM (maybe?)
|
||||||
|
- Handle long branches
|
||||||
|
|
||||||
Process/Code Structure Improvement
|
Process/Code Structure Improvement
|
||||||
- Make each phase return a separate object graph (allowing for keeeping the history in memory & performing rollbacks)
|
- Make each phase return a separate object graph (allowing for keeeping the history in memory & performing rollbacks)
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
lda {zpby2}
|
||||||
|
ldy {zpby1}
|
||||||
|
sta {cowo1},y
|
@ -0,0 +1,3 @@
|
|||||||
|
lda {zpby1}
|
||||||
|
cmp #{coby1}
|
||||||
|
bne {la1}
|
@ -40,7 +40,7 @@ public class Pass1ProcedureCallParameters extends ControlFlowGraphCopyVisitor {
|
|||||||
splitCurrentBlock(scope.addLabelIntermediate());
|
splitCurrentBlock(scope.addLabelIntermediate());
|
||||||
if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) {
|
if(!SymbolTypeBasic.VOID.equals(procedure.getReturnType())) {
|
||||||
addStatementToCurrentBlock(new StatementAssignment(origCall.getLValue(), procReturnVar));
|
addStatementToCurrentBlock(new StatementAssignment(origCall.getLValue(), procReturnVar));
|
||||||
} {
|
} else {
|
||||||
// No return type. Remove variable receiving the result.
|
// No return type. Remove variable receiving the result.
|
||||||
LValue lValue = origCall.getLValue();
|
LValue lValue = origCall.getLValue();
|
||||||
if(lValue instanceof Variable) {
|
if(lValue instanceof Variable) {
|
||||||
|
73
src/dk/camelot64/kickc/icl/Pass2AssertBlocks.java
Normal file
73
src/dk/camelot64/kickc/icl/Pass2AssertBlocks.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -72,6 +72,7 @@ public class Pass3RegisterAllocation {
|
|||||||
//allocation.allocate(symbols.getVariable("a#1"), new RegisterAllocation.RegisterAByte());
|
//allocation.allocate(symbols.getVariable("a#1"), new RegisterAllocation.RegisterAByte());
|
||||||
//allocation.allocate(symbols.getVariable("a#0"), 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#0"), RegisterAllocation.getRegisterX());
|
||||||
allocation.allocate(symbols.getVariable("plot::i#1"), RegisterAllocation.getRegisterX());
|
allocation.allocate(symbols.getVariable("plot::i#1"), RegisterAllocation.getRegisterX());
|
||||||
allocation.allocate(symbols.getVariable("plot::i#2"), 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#2"), RegisterAllocation.getRegisterX());
|
||||||
allocation.allocate(symbols.getVariable("c#3"), RegisterAllocation.getRegisterX());
|
allocation.allocate(symbols.getVariable("c#3"), RegisterAllocation.getRegisterX());
|
||||||
allocation.allocate(symbols.getVariable("c#4"), RegisterAllocation.getRegisterX());
|
allocation.allocate(symbols.getVariable("c#4"), RegisterAllocation.getRegisterX());
|
||||||
|
|
||||||
symbols.setAllocation(allocation);
|
symbols.setAllocation(allocation);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ public class Main {
|
|||||||
|
|
||||||
List<Pass2SsaAssertion> assertions = new ArrayList<>();
|
List<Pass2SsaAssertion> assertions = new ArrayList<>();
|
||||||
assertions.add(new Pass2AssertSymbols(controlFlowGraph, programScope));
|
assertions.add(new Pass2AssertSymbols(controlFlowGraph, programScope));
|
||||||
|
assertions.add(new Pass2AssertBlocks(controlFlowGraph, programScope));
|
||||||
|
|
||||||
boolean ssaOptimized = true;
|
boolean ssaOptimized = true;
|
||||||
while (ssaOptimized) {
|
while (ssaOptimized) {
|
||||||
|
Loading…
Reference in New Issue
Block a user