1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +00:00

- Ensure that for exported procedure parameters, there are no constant values calculated.

- Optimization of function to calculate exported procedure parameters.
This commit is contained in:
Sven Van de Velde 2023-11-18 17:24:13 +01:00
parent bcd7a49f6a
commit 818da3f995
10 changed files with 497 additions and 440 deletions

View File

@ -730,6 +730,7 @@ public class Program {
procedure.setAsmLibrary(asmLibrary.getFullName());
procedure.setDeclaredExtern(false);
procedure.setDeclaredInline(false);
procedure.setAsmExported(true);
}
}

View File

@ -58,6 +58,17 @@ public class Procedure extends Scope {
this.asmLibrary = asmLibrary;
}
private boolean asmExported;
public boolean isAsmExported() {
return asmExported;
}
public void setAsmExported(boolean asmExported) {
this.asmExported = asmExported;
}
/**
* The bank that the procedure code is placed in.
* Used to decide whether to produce near, close or far call code when generating calls.

View File

@ -298,6 +298,14 @@ public class Variable implements Symbol {
return Kind.LOAD_STORE.equals(getKind());
}
public boolean isAsmExportParameter() {
Procedure procedure = this.getContainingProcedure();
if(procedure != null)
return procedure.isAsmExported() && procedure.getParameters().contains(this);
else
return false;
}
public boolean isKindIntermediate() {
return Kind.INTERMEDIATE.equals(getKind());
}

View File

@ -144,7 +144,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
LValue lValue = assignment.getlValue();
if(lValue instanceof VariableRef varRef) {
Variable var = getProgramScope().getVariable(varRef);
if(var.isVolatile() || var.isKindLoadStore())
if(var.isVolatile() || var.isKindLoadStore() || var.isAsmExportParameter())
// Do not examine volatiles and non-versioned variables
continue;
if(var.getRegister() != null && var.getRegister().isMem())
@ -175,7 +175,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
// Look for constants among non-versioned variables
for(Variable variable : getProgramScope().getAllVariables(true)) {
if(variable.isVolatile() || !variable.isKindLoadStore())
if(variable.isVolatile() || !variable.isKindLoadStore() || variable.isAsmExportParameter()) // #828 - Added
// Do not examine volatiles, non-constants or versioned variables
continue;
if(variable.getRegister() != null && variable.getRegister().isMem())

View File

@ -112,24 +112,16 @@ public abstract class Pass4MemoryCoalesce extends Pass2Base {
Procedure proc1 = program.getScope().getProcedure((ProcedureRef)threads1.toArray()[0]);
Procedure proc2 = program.getScope().getProcedure((ProcedureRef)threads2.toArray()[0]);
if(program.isProcedureAsmExport(proc1.getFullName()) || program.isProcedureAsmExport(proc2.getFullName()) ) {
if(proc1.isAsmExported() || proc2.isAsmExported()) {
return true;
} else {
return threads1.equals(threads2);
}
}
private static boolean isExportParameter(VariableRef varRef, Program program) {
private static boolean isAsmExportParameter(VariableRef varRef, Program program) {
Variable variable = program.getScope().getVariable(varRef);
ScopeRef scopeRef = variable.getScope().getRef();
if (scopeRef instanceof ProcedureRef) {
if (program.isProcedureAsmExport(scopeRef.getFullName())) {
Procedure procedure = program.getScope().getProcedure((ProcedureRef)scopeRef);
if(procedure.getParameters().contains(variable))
return true;
}
}
return false;
return variable.isAsmExportParameter();
}
/**
@ -144,9 +136,9 @@ public abstract class Pass4MemoryCoalesce extends Pass2Base {
*/
private static boolean canCoalesceExports(LiveRangeEquivalenceClass ec1, LiveRangeEquivalenceClass ec2, Program program) {
for(VariableRef varRef : ec1.getVariables()) {
if(isExportParameter(varRef, program)) {
if(isAsmExportParameter(varRef, program)) {
for(VariableRef varRef2 : ec2.getVariables()) {
if(isExportParameter(varRef2, program))
if(isAsmExportParameter(varRef2, program))
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
#pragma link("conio.ld")
#pragma encoding(petscii_mixed)
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_library("conio_var")
#pragma asm_export("conio_var", __varcall, __conio_var_start, conio_x16_init)

View File

@ -0,0 +1,6 @@
#if __asm_import__
#else
.segmentdef Code [start=%P]
.segmentdef Data [startAfter="Code"]
#endif

View File

@ -0,0 +1,26 @@
/** this test validates that constant candidates are considered as normal variables for exported procedure parameters */
#pragma link("test.ld")
#pragma encoding(petscii_mixed)
#pragma var_model(zp)
#pragma asm_library("test_implicit_const_var")
#pragma asm_export("test_implicit_const_var", __varcall, test, color)
//void main() {
//test();
//}
#pragma zp_reserve(0x80..0xFF)
const char BLUE = 6;
__export char testcolor = 0;
void __varcall test() {
color(BLUE);
}
void __varcall color(char c) {
testcolor = c;
}

View File

@ -10,6 +10,9 @@
// In the ideal world, these functions should not be provided but
// linked by a "linker".
#pragma encoding(screencode_mixed)
#pragma var_model(zp)
#pragma asm_import("conio_var", __varcall, __conio_var_start, conio_x16_init, clrscr, gotoxy)
#pragma asm_import("conio_var", __varcall, wherex, wherey)
@ -24,26 +27,25 @@
extern void __conio_var_start();
extern void conio_x16_init();
extern void clrscr();
extern void gotoxy(__zp($d) char x, __zp(2) char y);
extern __zp(4) char wherex();
extern __zp(3) char wherey();
extern void screensize(__zp(8) char *x, __zp($10) char *y);
extern __zp($d) char screensizex();
extern void gotoxy(__zp(2) char x, __zp(5) char y);
extern __zp($b) char wherex();
extern __zp(8) char wherey();
extern void screensize(__zp(6) char *x, __zp($e) char *y);
extern __zp(5) char screensizex();
extern __zp(2) char screensizey();
extern void cputln();
extern void cputc(__zp($a) char c);
extern void cputcxy(__zp($d) char x, __zp(2) char y, __zp(7) char c);
extern void cputs(__zp($e) const char *s);
extern void cputsxy(__zp($d) char x, __zp(2) char y, __zp($10) const char *s);
extern __zp(2) char textcolor(__zp(6) char color);
extern __zp(2) char bgcolor(__zp(3) char color);
extern __zp(4) char bordercolor(__zp(3) char color);
extern void cputc(__zp(8) char c);
extern void cputcxy(__zp(2) char x, __zp(5) char y, __zp(3) char c);
extern void cputs(__zp($c) const char *s);
extern void cputsxy(__zp(2) char x, __zp(5) char y, __zp($e) const char *s);
extern __zp(8) char textcolor(__zp(2) char color);
extern __zp(8) char bgcolor(__zp(2) char color);
extern __zp(8) char bordercolor(__zp(3) char color);
extern char kbhit();
extern __zp(4) char cursor(__zp(5) char onoff);
extern __zp($d) char scroll(__zp(5) char onoff);
extern __zp(8) char cursor(__zp(2) char onoff);
extern __zp(5) char scroll(__zp(3) char onoff);
extern void screenlayer1();
// Linkage
#pragma link("printf-library.ld")