mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-19 00:29:29 +00:00
Preventing double imports. Closes #102
This commit is contained in:
parent
41fd3bc436
commit
9c39311d67
@ -19,10 +19,9 @@ public class Compiler {
|
||||
private Program program;
|
||||
|
||||
public Compiler() {
|
||||
this.program = new Program(new ProgramScope(), new CompileLog());
|
||||
this.program.setImportPaths(new ArrayList<>());
|
||||
this.program = new Program();
|
||||
}
|
||||
|
||||
|
||||
public CompileLog getLog() {
|
||||
return program.getLog();
|
||||
}
|
||||
@ -57,45 +56,51 @@ public class Compiler {
|
||||
}
|
||||
|
||||
public static void loadAndParseFile(String fileName, Program program, StatementSequenceGenerator statementSequenceGenerator) {
|
||||
CharStream fileStream = loadFile(fileName, program);
|
||||
program.getLog().append(fileStream.toString());
|
||||
KickCLexer lexer = new KickCLexer(fileStream);
|
||||
KickCParser parser = new KickCParser(new CommonTokenStream(lexer));
|
||||
parser.setBuildParseTree(true);
|
||||
parser.addErrorListener(new BaseErrorListener() {
|
||||
@Override
|
||||
public void syntaxError(
|
||||
Recognizer<?, ?> recognizer,
|
||||
Object offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e) {
|
||||
throw new CompileError("Error parsing file " + fileStream.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg);
|
||||
}
|
||||
});
|
||||
statementSequenceGenerator.generate(parser.file());
|
||||
}
|
||||
|
||||
private static CharStream loadFile(String fileName, Program program) {
|
||||
if(!fileName.endsWith(".kc")) {
|
||||
fileName += ".kc";
|
||||
}
|
||||
try {
|
||||
List<String> importPaths = program.getImportPaths();
|
||||
for (String importPath : importPaths) {
|
||||
if(!importPath.endsWith("/")) {
|
||||
importPath += "/";
|
||||
}
|
||||
String filePath = importPath + fileName;
|
||||
File file = new File(filePath);
|
||||
if(file.exists()) {
|
||||
return CharStreams.fromPath(file.toPath());
|
||||
}
|
||||
File file = loadFile(fileName, program);
|
||||
List<String> imported = program.getImported();
|
||||
if (imported.contains(file.getAbsolutePath())) {
|
||||
return;
|
||||
}
|
||||
final CharStream fileStream = CharStreams.fromPath(file.toPath());
|
||||
imported.add(file.getAbsolutePath());
|
||||
program.getLog().append(fileStream.toString());
|
||||
KickCLexer lexer = new KickCLexer(fileStream);
|
||||
KickCParser parser = new KickCParser(new CommonTokenStream(lexer));
|
||||
parser.setBuildParseTree(true);
|
||||
parser.addErrorListener(new BaseErrorListener() {
|
||||
@Override
|
||||
public void syntaxError(
|
||||
Recognizer<?, ?> recognizer,
|
||||
Object offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e) {
|
||||
throw new CompileError("Error parsing file " + fileStream.getSourceName() + "\n - Line: " + line + "\n - Message: " + msg);
|
||||
}
|
||||
});
|
||||
statementSequenceGenerator.generate(parser.file());
|
||||
} catch (IOException e) {
|
||||
throw new CompileError("Error loading file " + fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static File loadFile(String fileName, Program program) {
|
||||
if (!fileName.endsWith(".kc")) {
|
||||
fileName += ".kc";
|
||||
}
|
||||
List<String> importPaths = program.getImportPaths();
|
||||
for (String importPath : importPaths) {
|
||||
if (!importPath.endsWith("/")) {
|
||||
importPath += "/";
|
||||
}
|
||||
String filePath = importPath + fileName;
|
||||
File file = new File(filePath);
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
throw new CompileError("File not found " + fileName);
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import dk.camelot64.kickc.CompileLog;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** A KickC Intermediate Compiler Language (ICL) Program */
|
||||
@ -12,6 +11,8 @@ public class Program {
|
||||
|
||||
/** Paths used for importing files. */
|
||||
private List<String> importPaths;
|
||||
/** Imported files. */
|
||||
private List<String> imported;
|
||||
/** The initial statement sequence generated byt the parser. */
|
||||
private StatementSequence statementSequence;
|
||||
/** The main scope. */
|
||||
@ -52,27 +53,19 @@ public class Program {
|
||||
/** Separation of live range equivalence classes into scopes - used for register uplift */
|
||||
private RegisterUpliftProgram registerUpliftProgram;
|
||||
|
||||
@JsonCreator
|
||||
public Program(
|
||||
@JsonProperty("scope") ProgramScope scope,
|
||||
@JsonProperty("graph") ControlFlowGraph graph,
|
||||
@JsonProperty("asm") AsmProgram asm) {
|
||||
this.scope = scope;
|
||||
this.graph = graph;
|
||||
this.asm = asm;
|
||||
}
|
||||
|
||||
public Program(ProgramScope programScope, CompileLog log) {
|
||||
this.scope = programScope;
|
||||
this.log = log;
|
||||
public Program() {
|
||||
this.scope = new ProgramScope();
|
||||
this.log = new CompileLog();
|
||||
this.importPaths = new ArrayList<>();
|
||||
this.imported = new ArrayList<>();
|
||||
}
|
||||
|
||||
public List<String> getImportPaths() {
|
||||
return importPaths;
|
||||
}
|
||||
|
||||
public void setImportPaths(List<String> importPaths) {
|
||||
this.importPaths = importPaths;
|
||||
public List<String> getImported() {
|
||||
return imported;
|
||||
}
|
||||
|
||||
public StatementSequence getStatementSequence() {
|
||||
|
@ -24,6 +24,10 @@ public class TestPrograms extends TestCase {
|
||||
helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/");
|
||||
}
|
||||
|
||||
public void testDoubleImport() throws IOException, URISyntaxException {
|
||||
compileAndCompare("double-import");
|
||||
}
|
||||
|
||||
public void testImporting() throws IOException, URISyntaxException {
|
||||
compileAndCompare("importing");
|
||||
}
|
||||
|
6
src/main/java/dk/camelot64/kickc/test/double-import.kc
Normal file
6
src/main/java/dk/camelot64/kickc/test/double-import.kc
Normal file
@ -0,0 +1,6 @@
|
||||
import "imported"
|
||||
import "imported"
|
||||
|
||||
void main() {
|
||||
*BGCOL = RED;
|
||||
}
|
11
src/main/java/dk/camelot64/kickc/test/ref/double-import.asm
Normal file
11
src/main/java/dk/camelot64/kickc/test/ref/double-import.asm
Normal file
@ -0,0 +1,11 @@
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
.const BGCOL = $d021
|
||||
.const RED = 2
|
||||
jsr main
|
||||
main: {
|
||||
lda #RED
|
||||
sta BGCOL
|
||||
rts
|
||||
}
|
15
src/main/java/dk/camelot64/kickc/test/ref/double-import.cfg
Normal file
15
src/main/java/dk/camelot64/kickc/test/ref/double-import.cfg
Normal file
@ -0,0 +1,15 @@
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main param-assignment [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] )
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return [ ] ( main:2 [ ] )
|
||||
to:@return
|
514
src/main/java/dk/camelot64/kickc/test/ref/double-import.log
Normal file
514
src/main/java/dk/camelot64/kickc/test/ref/double-import.log
Normal file
@ -0,0 +1,514 @@
|
||||
import "imported"
|
||||
import "imported"
|
||||
|
||||
void main() {
|
||||
*BGCOL = RED;
|
||||
}
|
||||
Importing imported
|
||||
const byte *BGCOL = $d021;
|
||||
const byte RED = 2;
|
||||
|
||||
Importing imported
|
||||
PROGRAM
|
||||
(byte*) BGCOL ← (word) 53281
|
||||
(byte) RED ← (byte/signed byte/word/signed word) 2
|
||||
proc (void()) main()
|
||||
*((byte*) BGCOL) ← (byte) RED
|
||||
main::@return:
|
||||
return
|
||||
endproc // main()
|
||||
call main
|
||||
|
||||
SYMBOLS
|
||||
(byte*) BGCOL
|
||||
(byte) RED
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
Promoting word to byte* in BGCOL ← ((byte*)) 53281
|
||||
INITIAL CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL ← ((byte*)) (word) 53281
|
||||
(byte) RED ← (byte/signed byte/word/signed word) 2
|
||||
to:@1
|
||||
main: scope:[main] from
|
||||
*((byte*) BGCOL) ← (byte) RED
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL ← ((byte*)) (word) 53281
|
||||
(byte) RED ← (byte/signed byte/word/signed word) 2
|
||||
to:@1
|
||||
main: scope:[main] from
|
||||
*((byte*) BGCOL) ← (byte) RED
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
PROCEDURE MODIFY VARIABLE ANALYSIS
|
||||
|
||||
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL ← ((byte*)) (word) 53281
|
||||
(byte) RED ← (byte/signed byte/word/signed word) 2
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
*((byte*) BGCOL) ← (byte) RED
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main param-assignment
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
Completing Phi functions...
|
||||
Completing Phi functions...
|
||||
CONTROL FLOW GRAPH SSA
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL#0 ← ((byte*)) (word) 53281
|
||||
(byte) RED#0 ← (byte/signed byte/word/signed word) 2
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) BGCOL#1 ← phi( @1/(byte*) BGCOL#2 )
|
||||
(byte) RED#1 ← phi( @1/(byte) RED#2 )
|
||||
*((byte*) BGCOL#1) ← (byte) RED#1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
(byte*) BGCOL#2 ← phi( @begin/(byte*) BGCOL#0 )
|
||||
(byte) RED#2 ← phi( @begin/(byte) RED#0 )
|
||||
call main param-assignment
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
CONTROL FLOW GRAPH WITH ASSIGNMENT CALL & RETURN
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL#0 ← ((byte*)) (word) 53281
|
||||
(byte) RED#0 ← (byte/signed byte/word/signed word) 2
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) BGCOL#1 ← phi( @1/(byte*) BGCOL#2 )
|
||||
(byte) RED#1 ← phi( @1/(byte) RED#2 )
|
||||
*((byte*) BGCOL#1) ← (byte) RED#1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
(byte*) BGCOL#2 ← phi( @begin/(byte*) BGCOL#0 )
|
||||
(byte) RED#2 ← phi( @begin/(byte) RED#0 )
|
||||
call main param-assignment
|
||||
to:@2
|
||||
@2: scope:[] from @1
|
||||
to:@end
|
||||
@end: scope:[] from @2
|
||||
|
||||
INITIAL SSA SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @2
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(byte*) BGCOL#0
|
||||
(byte*) BGCOL#1
|
||||
(byte*) BGCOL#2
|
||||
(byte) RED
|
||||
(byte) RED#0
|
||||
(byte) RED#1
|
||||
(byte) RED#2
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
Culled Empty Block (label) @2
|
||||
Succesful SSA optimization Pass2CullEmptyBlocks
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL#0 ← ((byte*)) (word) 53281
|
||||
(byte) RED#0 ← (byte/signed byte/word/signed word) 2
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) BGCOL#1 ← phi( @1/(byte*) BGCOL#2 )
|
||||
(byte) RED#1 ← phi( @1/(byte) RED#2 )
|
||||
*((byte*) BGCOL#1) ← (byte) RED#1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
(byte*) BGCOL#2 ← phi( @begin/(byte*) BGCOL#0 )
|
||||
(byte) RED#2 ← phi( @begin/(byte) RED#0 )
|
||||
call main param-assignment
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Not aliassing across scopes: RED#1 RED#2
|
||||
Not aliassing across scopes: BGCOL#1 BGCOL#2
|
||||
Alias (byte) RED#0 = (byte) RED#2
|
||||
Alias (byte*) BGCOL#0 = (byte*) BGCOL#2
|
||||
Succesful SSA optimization Pass2AliasElimination
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL#0 ← ((byte*)) (word) 53281
|
||||
(byte) RED#0 ← (byte/signed byte/word/signed word) 2
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
(byte*) BGCOL#1 ← phi( @1/(byte*) BGCOL#0 )
|
||||
(byte) RED#1 ← phi( @1/(byte) RED#0 )
|
||||
*((byte*) BGCOL#1) ← (byte) RED#1
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main param-assignment
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Not aliassing across scopes: RED#1 RED#0
|
||||
Not aliassing across scopes: BGCOL#1 BGCOL#0
|
||||
Redundant Phi (byte) RED#1 (byte) RED#0
|
||||
Redundant Phi (byte*) BGCOL#1 (byte*) BGCOL#0
|
||||
Succesful SSA optimization Pass2RedundantPhiElimination
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
(byte*) BGCOL#0 ← ((byte*)) (word) 53281
|
||||
(byte) RED#0 ← (byte/signed byte/word/signed word) 2
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
*((byte*) BGCOL#0) ← (byte) RED#0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main param-assignment
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
Constant (const byte*) BGCOL#0 = ((byte*))53281
|
||||
Constant (const byte) RED#0 = 2
|
||||
Succesful SSA optimization Pass2ConstantIdentification
|
||||
CONTROL FLOW GRAPH
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
main: scope:[main] from @1
|
||||
*((const byte*) BGCOL#0) ← (const byte) RED#0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
@1: scope:[] from @begin
|
||||
call main param-assignment
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(const byte*) BGCOL#0 = ((byte*))(word) 53281
|
||||
(byte) RED
|
||||
(const byte) RED#0 = (byte/signed byte/word/signed word) 2
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
Block Sequence Planned @begin @1 @end main main::@return
|
||||
Block Sequence Planned @begin @1 @end main main::@return
|
||||
CONTROL FLOW GRAPH - PHI LIFTED
|
||||
@begin: scope:[] from
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
call main param-assignment
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
main: scope:[main] from @1
|
||||
*((const byte*) BGCOL#0) ← (const byte) RED#0
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
return
|
||||
to:@return
|
||||
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
CALL GRAPH
|
||||
Calls in [] to main:2
|
||||
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - LIVE RANGES FOUND
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ]
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ]
|
||||
[2] call main param-assignment [ ]
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ]
|
||||
main: scope:[main] from @1
|
||||
[4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ]
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return [ ]
|
||||
to:@return
|
||||
|
||||
Created 0 initial phi equivalence classes
|
||||
Coalesced down to 0 phi equivalence classes
|
||||
Block Sequence Planned @begin @1 @end main main::@return
|
||||
Adding NOP phi() at start of @begin
|
||||
Adding NOP phi() at start of @1
|
||||
Adding NOP phi() at start of @end
|
||||
Propagating live ranges...
|
||||
CONTROL FLOW GRAPH - BEFORE EFFECTIVE LIVE RANGES
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ]
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ]
|
||||
[2] call main param-assignment [ ]
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ]
|
||||
main: scope:[main] from @1
|
||||
[4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ]
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return [ ]
|
||||
to:@return
|
||||
|
||||
CONTROL FLOW GRAPH - PHI MEM COALESCED
|
||||
@begin: scope:[] from
|
||||
[0] phi() [ ] ( )
|
||||
to:@1
|
||||
@1: scope:[] from @begin
|
||||
[1] phi() [ ] ( )
|
||||
[2] call main param-assignment [ ] ( )
|
||||
to:@end
|
||||
@end: scope:[] from @1
|
||||
[3] phi() [ ] ( )
|
||||
main: scope:[main] from @1
|
||||
[4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] )
|
||||
to:main::@return
|
||||
main::@return: scope:[main] from main
|
||||
[5] return [ ] ( main:2 [ ] )
|
||||
to:@return
|
||||
|
||||
DOMINATORS
|
||||
@begin dominated by @begin
|
||||
@1 dominated by @1 @begin
|
||||
@end dominated by @1 @begin @end
|
||||
main dominated by @1 @begin main
|
||||
main::@return dominated by main::@return @1 @begin main
|
||||
|
||||
NATURAL LOOPS
|
||||
|
||||
Found 0 loops in scope []
|
||||
Found 0 loops in scope [main]
|
||||
NATURAL LOOPS WITH DEPTH
|
||||
|
||||
|
||||
VARIABLE REGISTER WEIGHTS
|
||||
(byte*) BGCOL
|
||||
(byte) RED
|
||||
(void()) main()
|
||||
|
||||
Initial phi equivalence classes
|
||||
Complete equivalence classes
|
||||
INITIAL ASM
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
.const BGCOL = $d021
|
||||
.const RED = 2
|
||||
//SEG2 @begin
|
||||
bbegin:
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
jmp b1
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 [2] call main param-assignment [ ] ( )
|
||||
jsr main
|
||||
//SEG6 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
jmp bend
|
||||
//SEG7 @end
|
||||
bend:
|
||||
//SEG8 main
|
||||
main: {
|
||||
//SEG9 [4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2
|
||||
lda #RED
|
||||
sta BGCOL
|
||||
jmp breturn
|
||||
//SEG10 main::@return
|
||||
breturn:
|
||||
//SEG11 [5] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
||||
REGISTER UPLIFT POTENTIAL REGISTERS
|
||||
Statement [4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) always clobbers reg byte a
|
||||
|
||||
REGISTER UPLIFT SCOPES
|
||||
Uplift Scope [main]
|
||||
Uplift Scope []
|
||||
|
||||
Uplifting [main] best 27 combination
|
||||
Uplifting [] best 27 combination
|
||||
Removing instruction jmp b1
|
||||
Removing instruction jmp bend
|
||||
Removing instruction jmp breturn
|
||||
Succesful ASM optimization Pass5NextJumpElimination
|
||||
ASSEMBLER
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
.const BGCOL = $d021
|
||||
.const RED = 2
|
||||
//SEG2 @begin
|
||||
bbegin:
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
b1_from_bbegin:
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 [2] call main param-assignment [ ] ( )
|
||||
jsr main
|
||||
//SEG6 [3] phi from @1 to @end [phi:@1->@end]
|
||||
bend_from_b1:
|
||||
//SEG7 @end
|
||||
bend:
|
||||
//SEG8 main
|
||||
main: {
|
||||
//SEG9 [4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2
|
||||
lda #RED
|
||||
sta BGCOL
|
||||
//SEG10 main::@return
|
||||
breturn:
|
||||
//SEG11 [5] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
||||
Removing instruction bbegin:
|
||||
Removing instruction b1_from_bbegin:
|
||||
Removing instruction bend_from_b1:
|
||||
Succesful ASM optimization Pass5RedundantLabelElimination
|
||||
ASSEMBLER
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
.const BGCOL = $d021
|
||||
.const RED = 2
|
||||
//SEG2 @begin
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG4 @1
|
||||
b1:
|
||||
//SEG5 [2] call main param-assignment [ ] ( )
|
||||
jsr main
|
||||
//SEG6 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG7 @end
|
||||
bend:
|
||||
//SEG8 main
|
||||
main: {
|
||||
//SEG9 [4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2
|
||||
lda #RED
|
||||
sta BGCOL
|
||||
//SEG10 main::@return
|
||||
breturn:
|
||||
//SEG11 [5] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
||||
Removing instruction b1:
|
||||
Removing instruction bend:
|
||||
Removing instruction breturn:
|
||||
Succesful ASM optimization Pass5UnusedLabelElimination
|
||||
ASSEMBLER
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
.const BGCOL = $d021
|
||||
.const RED = 2
|
||||
//SEG2 @begin
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG4 @1
|
||||
//SEG5 [2] call main param-assignment [ ] ( )
|
||||
jsr main
|
||||
//SEG6 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG7 @end
|
||||
//SEG8 main
|
||||
main: {
|
||||
//SEG9 [4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2
|
||||
lda #RED
|
||||
sta BGCOL
|
||||
//SEG10 main::@return
|
||||
//SEG11 [5] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
||||
FINAL SYMBOL TABLE
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(const byte*) BGCOL#0 BGCOL = ((byte*))(word) 53281
|
||||
(byte) RED
|
||||
(const byte) RED#0 RED = (byte/signed byte/word/signed word) 2
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
||||
|
||||
FINAL CODE
|
||||
//SEG0 Basic Upstart
|
||||
.pc = $801 "Basic"
|
||||
:BasicUpstart(main)
|
||||
.pc = $80d "Program"
|
||||
//SEG1 Global Constants & labels
|
||||
.const BGCOL = $d021
|
||||
.const RED = 2
|
||||
//SEG2 @begin
|
||||
//SEG3 [1] phi from @begin to @1 [phi:@begin->@1]
|
||||
//SEG4 @1
|
||||
//SEG5 [2] call main param-assignment [ ] ( )
|
||||
jsr main
|
||||
//SEG6 [3] phi from @1 to @end [phi:@1->@end]
|
||||
//SEG7 @end
|
||||
//SEG8 main
|
||||
main: {
|
||||
//SEG9 [4] *((const byte*) BGCOL#0) ← (const byte) RED#0 [ ] ( main:2 [ ] ) -- _deref_cowo1=coby2
|
||||
lda #RED
|
||||
sta BGCOL
|
||||
//SEG10 main::@return
|
||||
//SEG11 [5] return [ ] ( main:2 [ ] )
|
||||
rts
|
||||
}
|
||||
|
10
src/main/java/dk/camelot64/kickc/test/ref/double-import.sym
Normal file
10
src/main/java/dk/camelot64/kickc/test/ref/double-import.sym
Normal file
@ -0,0 +1,10 @@
|
||||
(label) @1
|
||||
(label) @begin
|
||||
(label) @end
|
||||
(byte*) BGCOL
|
||||
(const byte*) BGCOL#0 BGCOL = ((byte*))(word) 53281
|
||||
(byte) RED
|
||||
(const byte) RED#0 RED = (byte/signed byte/word/signed word) 2
|
||||
(void()) main()
|
||||
(label) main::@return
|
||||
|
Loading…
Reference in New Issue
Block a user