mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-20 07:30:00 +00:00
Preventing double imports. Closes #102
This commit is contained in:
parent
41fd3bc436
commit
9c39311d67
@ -19,8 +19,7 @@ public class Compiler {
|
|||||||
private Program program;
|
private Program program;
|
||||||
|
|
||||||
public Compiler() {
|
public Compiler() {
|
||||||
this.program = new Program(new ProgramScope(), new CompileLog());
|
this.program = new Program();
|
||||||
this.program.setImportPaths(new ArrayList<>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompileLog getLog() {
|
public CompileLog getLog() {
|
||||||
@ -57,7 +56,14 @@ public class Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void loadAndParseFile(String fileName, Program program, StatementSequenceGenerator statementSequenceGenerator) {
|
public static void loadAndParseFile(String fileName, Program program, StatementSequenceGenerator statementSequenceGenerator) {
|
||||||
CharStream fileStream = loadFile(fileName, program);
|
try {
|
||||||
|
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());
|
program.getLog().append(fileStream.toString());
|
||||||
KickCLexer lexer = new KickCLexer(fileStream);
|
KickCLexer lexer = new KickCLexer(fileStream);
|
||||||
KickCParser parser = new KickCParser(new CommonTokenStream(lexer));
|
KickCParser parser = new KickCParser(new CommonTokenStream(lexer));
|
||||||
@ -75,13 +81,15 @@ public class Compiler {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
statementSequenceGenerator.generate(parser.file());
|
statementSequenceGenerator.generate(parser.file());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new CompileError("Error loading file " + fileName, e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CharStream loadFile(String fileName, Program program) {
|
private static File loadFile(String fileName, Program program) {
|
||||||
if (!fileName.endsWith(".kc")) {
|
if (!fileName.endsWith(".kc")) {
|
||||||
fileName += ".kc";
|
fileName += ".kc";
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
List<String> importPaths = program.getImportPaths();
|
List<String> importPaths = program.getImportPaths();
|
||||||
for (String importPath : importPaths) {
|
for (String importPath : importPaths) {
|
||||||
if (!importPath.endsWith("/")) {
|
if (!importPath.endsWith("/")) {
|
||||||
@ -90,12 +98,9 @@ public class Compiler {
|
|||||||
String filePath = importPath + fileName;
|
String filePath = importPath + fileName;
|
||||||
File file = new File(filePath);
|
File file = new File(filePath);
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
return CharStreams.fromPath(file.toPath());
|
return file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
throw new CompileError("Error loading file " + fileName, e);
|
|
||||||
}
|
|
||||||
throw new CompileError("File not found " + fileName);
|
throw new CompileError("File not found " + fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package dk.camelot64.kickc.model;
|
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.CompileLog;
|
||||||
import dk.camelot64.kickc.asm.AsmProgram;
|
import dk.camelot64.kickc.asm.AsmProgram;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** A KickC Intermediate Compiler Language (ICL) Program */
|
/** A KickC Intermediate Compiler Language (ICL) Program */
|
||||||
@ -12,6 +11,8 @@ public class Program {
|
|||||||
|
|
||||||
/** Paths used for importing files. */
|
/** Paths used for importing files. */
|
||||||
private List<String> importPaths;
|
private List<String> importPaths;
|
||||||
|
/** Imported files. */
|
||||||
|
private List<String> imported;
|
||||||
/** The initial statement sequence generated byt the parser. */
|
/** The initial statement sequence generated byt the parser. */
|
||||||
private StatementSequence statementSequence;
|
private StatementSequence statementSequence;
|
||||||
/** The main scope. */
|
/** The main scope. */
|
||||||
@ -52,27 +53,19 @@ public class Program {
|
|||||||
/** Separation of live range equivalence classes into scopes - used for register uplift */
|
/** Separation of live range equivalence classes into scopes - used for register uplift */
|
||||||
private RegisterUpliftProgram registerUpliftProgram;
|
private RegisterUpliftProgram registerUpliftProgram;
|
||||||
|
|
||||||
@JsonCreator
|
public Program() {
|
||||||
public Program(
|
this.scope = new ProgramScope();
|
||||||
@JsonProperty("scope") ProgramScope scope,
|
this.log = new CompileLog();
|
||||||
@JsonProperty("graph") ControlFlowGraph graph,
|
this.importPaths = new ArrayList<>();
|
||||||
@JsonProperty("asm") AsmProgram asm) {
|
this.imported = new ArrayList<>();
|
||||||
this.scope = scope;
|
|
||||||
this.graph = graph;
|
|
||||||
this.asm = asm;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Program(ProgramScope programScope, CompileLog log) {
|
|
||||||
this.scope = programScope;
|
|
||||||
this.log = log;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getImportPaths() {
|
public List<String> getImportPaths() {
|
||||||
return importPaths;
|
return importPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setImportPaths(List<String> importPaths) {
|
public List<String> getImported() {
|
||||||
this.importPaths = importPaths;
|
return imported;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatementSequence getStatementSequence() {
|
public StatementSequence getStatementSequence() {
|
||||||
|
@ -24,6 +24,10 @@ public class TestPrograms extends TestCase {
|
|||||||
helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/");
|
helper = new ReferenceHelper("dk/camelot64/kickc/test/ref/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testDoubleImport() throws IOException, URISyntaxException {
|
||||||
|
compileAndCompare("double-import");
|
||||||
|
}
|
||||||
|
|
||||||
public void testImporting() throws IOException, URISyntaxException {
|
public void testImporting() throws IOException, URISyntaxException {
|
||||||
compileAndCompare("importing");
|
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