mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-10 13:38:18 +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 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)
|
||||
|
@ -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());
|
||||
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) {
|
||||
|
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#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);
|
||||
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user