mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-12-20 23:30:43 +00:00
Ensured we do not coalesce across segments.
This commit is contained in:
parent
606ea29132
commit
11c86793d3
@ -583,30 +583,30 @@ public class Pass4CodeGeneration {
|
||||
if (registerMainMem.getAddress() == null) {
|
||||
// Generate into the data segment
|
||||
// Set segment
|
||||
// // We check first the bank of the variable. Only local variables can be stored in the bank.
|
||||
// // Parameters must be stored in main memory.
|
||||
// if(!variable.getDataSegment().equals(Scope.SEGMENT_DATA_DEFAULT)) {
|
||||
// if(scope instanceof Procedure) {
|
||||
// Procedure procedure = (Procedure) scope;
|
||||
// List<Variable> parameters = procedure.getParameters();
|
||||
// if (variable.isKindPhiVersion()) {
|
||||
// Variable master = variable.getPhiMaster();
|
||||
// if (master != null) {
|
||||
// if (parameters.contains(master) || master.getLocalName().equals("return")) {
|
||||
// variable.setDataSegment(Scope.SEGMENT_DATA_DEFAULT);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Intermediate variables are placed at the banked data segment, but parameters and return values are kept untouched.
|
||||
// if (variable.isKindIntermediate()) {
|
||||
// if (scope instanceof Procedure) {
|
||||
// Procedure procedure = (Procedure) scope;
|
||||
// variable.setDataSegment(procedure.getSegmentData());
|
||||
// }
|
||||
// }
|
||||
// We check first the bank of the variable. Only local variables can be stored in the bank.
|
||||
// Parameters must be stored in main memory.
|
||||
if(!variable.getDataSegment().equals(Scope.SEGMENT_DATA_DEFAULT)) {
|
||||
if(scope instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) scope;
|
||||
List<Variable> parameters = procedure.getParameters();
|
||||
if (variable.isKindPhiVersion()) {
|
||||
Variable master = variable.getPhiMaster();
|
||||
if (master != null) {
|
||||
if (parameters.contains(master) || master.getLocalName().equals("return")) {
|
||||
variable.setDataSegment(Scope.SEGMENT_DATA_DEFAULT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intermediate variables are placed at the banked data segment, but parameters and return values are kept untouched.
|
||||
if (variable.isKindIntermediate()) {
|
||||
if (scope instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) scope;
|
||||
variable.setDataSegment(procedure.getSegmentData());
|
||||
}
|
||||
}
|
||||
setCurrentSegment(variable.getDataSegment(), asm);
|
||||
// Add any comments
|
||||
generateComments(asm, variable.getComments());
|
||||
@ -925,7 +925,7 @@ public class Pass4CodeGeneration {
|
||||
if(Bank.CallingDistance.NEAR.equals(callingDistance)) {
|
||||
AsmFragmentCodeGenerator.generateAsm(asm, AsmFragmentInstanceSpecBuilder.call(call, indirectCallCount++, program), program);
|
||||
} else {
|
||||
throw new CompileError("Call procedure not supported in banked mode " + toProcedure.toString(program));
|
||||
throw new CompileError("Stack Call procedure not supported in banked mode " + toProcedure.toString(program));
|
||||
}
|
||||
RValue procedureRVal = call.getProcedureRVal();
|
||||
if (!(procedureRVal instanceof ProcedureRef)) {
|
||||
|
@ -53,6 +53,7 @@ public abstract class Pass4MemoryCoalesce extends Pass2Base {
|
||||
return
|
||||
canCoalesceNotEqual(ec1, ec2) &&
|
||||
canCoalesceCompatible(ec1, ec2, program) &&
|
||||
canCoalesceSegments(ec1, ec2, program) &&
|
||||
canCoalesceVolatile(ec1, ec2, program) &&
|
||||
canCoalesceThreads(ec1, ec2, threadHeads, program) &&
|
||||
canCoalesceClobber(ec1, ec2, unknownFragments, program);
|
||||
@ -69,6 +70,21 @@ public abstract class Pass4MemoryCoalesce extends Pass2Base {
|
||||
return !ec1.equals(ec2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if two live range equivalence classes are candidates for coalescing by ensuring they are not from different data segments.
|
||||
* @param ec1 One equivalence class
|
||||
* @param ec2 Another equivalence class
|
||||
* @param program The program
|
||||
* @return True if the two equivalence classes can be coalesced into one without problems.
|
||||
*/
|
||||
private static boolean canCoalesceSegments(LiveRangeEquivalenceClass ec1, LiveRangeEquivalenceClass ec2, Program program) {
|
||||
final VariableRef variableRef1 = ec1.getVariables().get(0);
|
||||
final String dataSegment1 = program.getScope().getVar(variableRef1).getDataSegment();
|
||||
final VariableRef variableRef2 = ec2.getVariables().get(0);
|
||||
final String dataSegment2 = program.getScope().getVar(variableRef2).getDataSegment();
|
||||
return dataSegment1.equals(dataSegment2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if two live range equivalence classes can be coalesced without cross-thread clobber.
|
||||
* This is possible if they are both only called from the same thread head.
|
||||
|
@ -1581,6 +1581,12 @@ public class TestProgramsFast extends TestPrograms {
|
||||
compileAndCompare("call-banked-phi-case-6-close-1.c");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBankedPhiMemvars() throws IOException {
|
||||
compileAndCompare("call-banked-phi-memvars.c", log());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testBankedStackCase2Close0() throws IOException {
|
||||
assertError("call-banked-stack-case-2-close-0.c", "Stack Call procedure not supported in banked mode");
|
||||
|
30
src/test/kc/call-banked-phi-memvars.c
Normal file
30
src/test/kc/call-banked-phi-memvars.c
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Test banked calls with memory variables.
|
||||
* The parameters & return should end up in the shared/common bank.
|
||||
*/
|
||||
|
||||
#pragma link("call-banked-phi.ld")
|
||||
#pragma var_model(mem)
|
||||
|
||||
int* const SCREEN = (int*)0x0400;
|
||||
|
||||
#pragma code_seg(Code)
|
||||
#pragma nobank
|
||||
void main(void) {
|
||||
for(char i=0;i<5; i++) {
|
||||
SCREEN[i] = plus(100, (int)i);
|
||||
SCREEN[10+i] = plus(200, (int)i);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma code_seg(RAM_Bank1)
|
||||
#pragma data_seg(RAM_Bank1)
|
||||
#pragma bank(cx16_ram, 1)
|
||||
int plus(int a, int b) {
|
||||
int r = 2;
|
||||
r += a;
|
||||
r += b;
|
||||
r += a;
|
||||
r += b;
|
||||
return r;
|
||||
}
|
Loading…
Reference in New Issue
Block a user