1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-11-20 02:32:36 +00:00

Added -Wfragment option that replaces error with warning when a fragment is missing.

This commit is contained in:
jespergravgaard 2019-09-06 22:32:18 +02:00
parent 01008ccb26
commit f09b1616c2
7 changed files with 38 additions and 13 deletions

View File

@ -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}

View File

@ -111,6 +111,9 @@ public class KickC implements Callable<Void> {
@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<Void> {
compiler.disableLoopHeadConstant();
}
if(warnFragmentMissing) {
compiler.setWarnFragmentMissing(true);
}
if(linkScript!=null) {
compiler.setLinkScriptFileName(linkScript);
}

View File

@ -78,5 +78,10 @@ public class LiveRangeVariables {
return liveRanges.get(variable);
}
public int size() {
return liveRanges.size();
}
}

View File

@ -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());
}
}
}
}

View File

@ -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()) {

View File

@ -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();

View File

@ -40,14 +40,11 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
/** Variables referenced inside each procedure and all it's sub-calls. */
private Map<ProcedureRef, Collection<VariableRef>> 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<Procedure> allProcedures = getScope().getAllProcedures(true);
Map<ProcedureRef, Collection<VariableRef>> procReferencedVars = new LinkedHashMap<>();
@ -55,8 +52,6 @@ public class PassNCalcLiveRangeVariables extends PassNCalcBase<LiveRangeVariable
Collection<VariableRef> 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<LiveRangeVariable
* @return true if any live ranges was modified. false if no modification was performed (and the propagation is complete)
*/
private boolean calculateLiveRanges(LiveRangeVariables liveRanges) {
VariableReferenceInfos referenceInfo = getProgram().getVariableReferenceInfos();
boolean modified = false;
for(ControlFlowBlock block : getProgram().getGraph().getAllBlocks()) {
for(Statement stmt : block.getStatements()) {