diff --git a/src/main/java/dk/camelot64/kickc/Compiler.java b/src/main/java/dk/camelot64/kickc/Compiler.java index 688115fcf..00c68057c 100644 --- a/src/main/java/dk/camelot64/kickc/Compiler.java +++ b/src/main/java/dk/camelot64/kickc/Compiler.java @@ -33,6 +33,9 @@ public class Compiler { * Currently the optimization is flaky and results in NPE's and wrong values in some programs. */ private boolean enableLoopHeadConstant = false; + /** Missing fragments produce a warning instead of an error */ + private boolean warnFragmentMissing = false; + /** File name of link script to use (from command line parameter). */ private String linkScriptFileName; @@ -40,6 +43,14 @@ public class Compiler { this.program = new Program(); } + public boolean isWarnFragmentMissing() { + return warnFragmentMissing; + } + + public void setWarnFragmentMissing(boolean warnFragmentMissing) { + this.warnFragmentMissing = warnFragmentMissing; + } + public void setLinkScriptFileName(String linkScript) { linkScriptFileName = linkScript; } @@ -475,7 +486,7 @@ public class Compiler { new Pass4RegistersFinalize(program).allocate(true); // Initial Code generation - new Pass4CodeGeneration(program, false).generate(); + new Pass4CodeGeneration(program, false, warnFragmentMissing).generate(); new Pass4AssertNoCpuClobber(program).check(); getLog().append("\nINITIAL ASM"); getLog().append("Target platform is " + program.getTargetPlatform().getName()); @@ -521,7 +532,7 @@ public class Compiler { // Final ASM code generation before optimization program.clearPhiTransitions(); - new Pass4CodeGeneration(program, false).generate(); + new Pass4CodeGeneration(program, false, warnFragmentMissing).generate(); new Pass4AssertNoCpuClobber(program).check(); // Remove unnecessary register savings from interrupts {@link InterruptType#HARDWARE_NOCLOBBER} diff --git a/src/main/java/dk/camelot64/kickc/KickC.java b/src/main/java/dk/camelot64/kickc/KickC.java index 294bd757b..375b6ea01 100644 --- a/src/main/java/dk/camelot64/kickc/KickC.java +++ b/src/main/java/dk/camelot64/kickc/KickC.java @@ -111,6 +111,9 @@ public class KickC implements Callable { @CommandLine.Option(names = {"-vasmoptimize"}, description = "Verbosity Option. Assembler optimization.") private boolean verboseAsmOptimize = false; + @CommandLine.Option(names = {"-Wfragment"}, description = "Warning Option. Missing fragments produces a warning instead of an error.") + private boolean warnFragmentMissing = false; + @CommandLine.Option(names = {"-fragment"}, description = "Print the ASM code for a named fragment. The fragment is loaded/synthesized and the ASM variations are written to the output.") private String fragment = null; @@ -227,6 +230,10 @@ public class KickC implements Callable { compiler.disableLoopHeadConstant(); } + if(warnFragmentMissing) { + compiler.setWarnFragmentMissing(true); + } + if(linkScript!=null) { compiler.setLinkScriptFileName(linkScript); } diff --git a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java index a5092a3a8..8e0f0134d 100644 --- a/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java +++ b/src/main/java/dk/camelot64/kickc/model/LiveRangeVariables.java @@ -78,5 +78,10 @@ public class LiveRangeVariables { return liveRanges.get(variable); } + public int size() { + return liveRanges.size(); + + } + } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java index 7482d5d03..15bb92551 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4CodeGeneration.java @@ -25,6 +25,9 @@ public class Pass4CodeGeneration { /** Should the generated ASM contain verbose alive info for the statements (costs a bit more to generate). */ boolean verboseAliveInfo; + /** Missing fragments produce a warning instead of an error. */ + boolean warnFragmentMissing; + /** The program being generated. */ private Program program; @@ -57,9 +60,10 @@ public class Pass4CodeGeneration { transitionsGenerated.put(transition, Boolean.TRUE); } - public Pass4CodeGeneration(Program program, boolean verboseAliveInfo) { + public Pass4CodeGeneration(Program program, boolean verboseAliveInfo, boolean warnFragmentMissing) { this.program = program; this.verboseAliveInfo = verboseAliveInfo; + this.warnFragmentMissing = warnFragmentMissing; } ControlFlowGraph getGraph() { @@ -644,7 +648,12 @@ public class Pass4CodeGeneration { try { generateStatementAsm(asm, block, statement, aluState, true); } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { - throw new CompileError("Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature(), statement.getSource()); + if(warnFragmentMissing) { + program.getLog().append("Warning! Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature()+"\n"+statement.getSource().toString()); + asm.addLine(new AsmInlineKickAsm(".assert \"Missing ASM fragment "+ e.getFragmentSignature()+"\", 0, 1", 0L, 0L)); + } else { + throw new CompileError("Unknown fragment for statement " + statement.toString(program, false) + "\nMissing ASM fragment " + e.getFragmentSignature(), statement.getSource()); + } } } } diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java index 4684cb337..b2c62e678 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftCombinations.java @@ -110,7 +110,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base { // Generate ASM try { program.clearPhiTransitions(); - new Pass4CodeGeneration(program, false).generate(); + new Pass4CodeGeneration(program, false, false).generate(); } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { unknownFragments.add(e.getFragmentSignature()); if(program.getLog().isVerboseUplift()) { diff --git a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java index d13d54c9e..c5a6be49a 100644 --- a/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java +++ b/src/main/java/dk/camelot64/kickc/passes/Pass4RegisterUpliftPotentialRegisterAnalysis.java @@ -163,7 +163,7 @@ public class Pass4RegisterUpliftPotentialRegisterAnalysis extends Pass2Base { asm.startChunk(block.getScope(), statement.getIndex(), statement.toString(getProgram(), false)); Pass4CodeGeneration.AsmCodegenAluState aluState = new Pass4CodeGeneration.AsmCodegenAluState(); try { - (new Pass4CodeGeneration(getProgram(), false)).generateStatementAsm(asm, block, statement, aluState, false); + (new Pass4CodeGeneration(getProgram(), false, false)).generateStatementAsm(asm, block, statement, aluState, false); } catch(AsmFragmentTemplateSynthesizer.UnknownFragmentException e) { unknownFragments.add(e.getFragmentSignature()); StringBuilder msg = new StringBuilder(); diff --git a/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcLiveRangeVariables.java b/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcLiveRangeVariables.java index 3a987986c..901fc228b 100644 --- a/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcLiveRangeVariables.java +++ b/src/main/java/dk/camelot64/kickc/passes/calcs/PassNCalcLiveRangeVariables.java @@ -40,14 +40,11 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase> procedureReferencedVars; - - static int callCount = 0; /** * Calculate the variables referenced inside each procedure and all it's sub-calls. */ private void calculateProcedureReferencedVars() { - //getLog().append("calculateLiveRanges starting "+callCount); VariableReferenceInfos referenceInfo = getProgram().getVariableReferenceInfos(); Collection allProcedures = getScope().getAllProcedures(true); Map> procReferencedVars = new LinkedHashMap<>(); @@ -55,8 +52,6 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase referencedVars = referenceInfo.getReferencedVars(procedure.getRef().getLabelRef()); procReferencedVars.put(procedure.getRef(), referencedVars); } - //getLog().append("calculateLiveRanges done "+callCount); - callCount++; this.procedureReferencedVars = procReferencedVars; } @@ -83,9 +78,7 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase