mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-22 21:29:50 +00:00
Optimized fragment generation by caching loaded fragment files.
This commit is contained in:
parent
439a70e52a
commit
0da6c7af6a
@ -10,6 +10,7 @@ import org.antlr.v4.runtime.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -344,6 +345,9 @@ public class AsmFragment {
|
||||
return bound;
|
||||
}
|
||||
|
||||
/** Cache for fragment files. Maps signature to the parsed file. */
|
||||
private static Map<String, Asm6502Parser.FileContext> fragmentFileCache = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Generate assembler code for the assembler fragment.
|
||||
*
|
||||
@ -351,48 +355,50 @@ public class AsmFragment {
|
||||
*/
|
||||
public void generate(AsmProgram asm) {
|
||||
String signature = this.getSignature();
|
||||
ClassLoader classLoader = this.getClass().getClassLoader();
|
||||
final URL fragmentResource = classLoader.getResource("dk/camelot64/kickc/asm/fragment/" + signature + ".asm");
|
||||
if (fragmentResource == null) {
|
||||
throw new UnknownFragmentException(signature);
|
||||
Asm6502Parser.FileContext fragmentFile = fragmentFileCache.get(signature);
|
||||
if(fragmentFile==null) {
|
||||
ClassLoader classLoader = this.getClass().getClassLoader();
|
||||
final URL fragmentResource = classLoader.getResource("dk/camelot64/kickc/asm/fragment/" + signature + ".asm");
|
||||
if (fragmentResource == null) {
|
||||
throw new UnknownFragmentException(signature);
|
||||
}
|
||||
|
||||
try {
|
||||
InputStream fragmentStream = fragmentResource.openStream();
|
||||
Asm6502Lexer lexer = new Asm6502Lexer(CharStreams.fromStream(fragmentStream));
|
||||
Asm6502Parser parser = new Asm6502Parser(new CommonTokenStream(lexer));
|
||||
parser.addErrorListener(new BaseErrorListener() {
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
|
||||
throw new RuntimeException("Error parsing fragment fragmentFile " + fragmentResource + "\n - Line: " + line + "\n - Message: " + msg);
|
||||
}
|
||||
});
|
||||
parser.setBuildParseTree(true);
|
||||
fragmentFile = parser.file();
|
||||
fragmentStream.close();
|
||||
fragmentFileCache.put(signature, fragmentFile);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading code fragment " + fragmentResource);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
InputStream fragmentStream = fragmentResource.openStream();
|
||||
Asm6502Lexer lexer = new Asm6502Lexer(CharStreams.fromStream(fragmentStream));
|
||||
Asm6502Parser parser = new Asm6502Parser(new CommonTokenStream(lexer));
|
||||
parser.addErrorListener(new BaseErrorListener() {
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
|
||||
throw new RuntimeException("Error parsing fragment file " + fragmentResource + "\n - Line: " + line + "\n - Message: " + msg);
|
||||
}
|
||||
});
|
||||
parser.setBuildParseTree(true);
|
||||
Asm6502Parser.FileContext file = parser.file();
|
||||
AsmSequenceGenerator asmSequenceGenerator = new AsmSequenceGenerator(fragmentResource, asm);
|
||||
asmSequenceGenerator.generate(file);
|
||||
fragmentStream.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error reading code fragment " + fragmentResource);
|
||||
}
|
||||
AsmSequenceGenerator asmSequenceGenerator = new AsmSequenceGenerator(signature, this, asm);
|
||||
asmSequenceGenerator.generate(fragmentFile);
|
||||
|
||||
}
|
||||
|
||||
private class AsmSequenceGenerator extends Asm6502BaseVisitor {
|
||||
private static class AsmSequenceGenerator extends Asm6502BaseVisitor {
|
||||
|
||||
private URL fragmentResource;
|
||||
private String signature;
|
||||
private AsmProgram program;
|
||||
private AsmFragment bindings;
|
||||
|
||||
public AsmSequenceGenerator(URL fragmentResource, AsmProgram program) {
|
||||
this.fragmentResource = fragmentResource;
|
||||
public AsmSequenceGenerator(String signature, AsmFragment bindings, AsmProgram program) {
|
||||
this.signature = signature;
|
||||
this.bindings = bindings;
|
||||
this.program = program;
|
||||
}
|
||||
|
||||
public AsmSequenceGenerator(URL fragmentResource) {
|
||||
this.fragmentResource = fragmentResource;
|
||||
this.program = new AsmProgram();
|
||||
}
|
||||
|
||||
public AsmProgram getProgram() {
|
||||
return program;
|
||||
}
|
||||
@ -427,7 +433,7 @@ public class AsmFragment {
|
||||
if (instruction != null) {
|
||||
program.addLine(instruction);
|
||||
} else {
|
||||
throw new RuntimeException("Error parsing ASM fragment line in " + fragmentResource.toString() + "\n - Line: " + ctx.getText());
|
||||
throw new RuntimeException("Error parsing ASM fragment line in dk/camelot64/kickc/asm/fragment/" + signature + ".asm\n - Line: " + ctx.getText());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -505,7 +511,7 @@ public class AsmFragment {
|
||||
@Override
|
||||
public Object visitExprReplace(Asm6502Parser.ExprReplaceContext ctx) {
|
||||
String replaceName = ctx.NAME().getSymbol().getText();
|
||||
return AsmFragment.this.getBoundValue(replaceName);
|
||||
return bindings.getBoundValue(replaceName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ public class Pass3RegisterUpliftPotentialRegisterAnalysis extends Pass2Base {
|
||||
* @return A set with registers that are clobbered by all different register assignments in the combination
|
||||
*/
|
||||
private Set<RegisterAllocation.Register> findAlwaysClobberedRegisters(ControlFlowBlock block, Statement statement, RegisterCombinationIterator combinations) {
|
||||
Set<RegisterAllocation.Register> alwaysClobbered = new HashSet<>();
|
||||
Set<RegisterAllocation.Register> alwaysClobbered = new LinkedHashSet<>();
|
||||
alwaysClobbered.add(RegisterAllocation.getRegisterA());
|
||||
alwaysClobbered.add(RegisterAllocation.getRegisterX());
|
||||
alwaysClobbered.add(RegisterAllocation.getRegisterY());
|
||||
|
@ -1171,13 +1171,13 @@ B3_from_B2:
|
||||
//SEG31 [6] phi (byte*) cursor#5 = (byte*) cursor#2 -- register_copy
|
||||
jmp B3
|
||||
|
||||
Statement [1] *((byte*) cursor#3) ← (byte) 81 [ cursor#3 x#2 e#3 y#2 ] always clobbers reg byte y reg byte a
|
||||
Removing always clobbered register reg byte y as potential for zp byte:4 [ x#2 x#1 ]
|
||||
Statement [1] *((byte*) cursor#3) ← (byte) 81 [ cursor#3 x#2 e#3 y#2 ] always clobbers reg byte a reg byte y
|
||||
Removing always clobbered register reg byte a as potential for zp byte:4 [ x#2 x#1 ]
|
||||
Removing always clobbered register reg byte y as potential for zp byte:5 [ e#3 e#5 e#1 e#2 ]
|
||||
Removing always clobbered register reg byte y as potential for zp byte:4 [ x#2 x#1 ]
|
||||
Removing always clobbered register reg byte a as potential for zp byte:5 [ e#3 e#5 e#1 e#2 ]
|
||||
Removing always clobbered register reg byte y as potential for zp byte:6 [ y#2 y#4 y#1 ]
|
||||
Removing always clobbered register reg byte y as potential for zp byte:5 [ e#3 e#5 e#1 e#2 ]
|
||||
Removing always clobbered register reg byte a as potential for zp byte:6 [ y#2 y#4 y#1 ]
|
||||
Removing always clobbered register reg byte y as potential for zp byte:6 [ y#2 y#4 y#1 ]
|
||||
Statement [4] (byte) e#1 ← (byte) e#3 + (byte) 24 [ x#1 e#1 cursor#1 y#2 ] always clobbers reg byte a
|
||||
Statement [9] (byte*) cursor#2 ← (byte*) cursor#1 + (byte) 40 [ x#1 e#1 cursor#2 y#1 ] always clobbers reg byte a
|
||||
Statement [10] (byte) e#2 ← (byte) e#1 - (byte) 39 [ x#1 cursor#2 e#2 y#1 ] always clobbers reg byte a
|
||||
|
@ -2066,9 +2066,9 @@ lvalue__B1_from_B2:
|
||||
//SEG70 [27] phi (byte) lvalue::i#2 = (byte) lvalue::i#1 -- register_copy
|
||||
jmp lvalue__B1
|
||||
|
||||
Statement [9] *((byte*) lvaluevar::screen#2) ← (byte) 4 [ lvaluevar::i#2 lvaluevar::screen#2 ] always clobbers reg byte y reg byte a
|
||||
Removing always clobbered register reg byte y as potential for zp byte:2 [ lvaluevar::i#2 lvaluevar::i#1 ]
|
||||
Statement [9] *((byte*) lvaluevar::screen#2) ← (byte) 4 [ lvaluevar::i#2 lvaluevar::screen#2 ] always clobbers reg byte a reg byte y
|
||||
Removing always clobbered register reg byte a as potential for zp byte:2 [ lvaluevar::i#2 lvaluevar::i#1 ]
|
||||
Removing always clobbered register reg byte y as potential for zp byte:2 [ lvaluevar::i#2 lvaluevar::i#1 ]
|
||||
Statement [15] (byte) rvaluevar::b#0 ← * (byte*) rvaluevar::screen#2 [ rvaluevar::i#2 rvaluevar::screen#2 ] always clobbers reg byte a reg byte y
|
||||
Removing always clobbered register reg byte a as potential for zp byte:5 [ rvaluevar::i#2 rvaluevar::i#1 ]
|
||||
Removing always clobbered register reg byte y as potential for zp byte:5 [ rvaluevar::i#2 rvaluevar::i#1 ]
|
||||
|
Loading…
Reference in New Issue
Block a user