mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-04-08 14:37:40 +00:00
Removed Variable class (using SymbolVariable).
This commit is contained in:
parent
5b1e3ec153
commit
093898455f
@ -5,12 +5,11 @@ import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||
import dk.camelot64.kickc.model.statements.StatementSource;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.parser.CParser;
|
||||
import dk.camelot64.kickc.parser.KickCParser;
|
||||
import dk.camelot64.kickc.passes.*;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.RuleContext;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
@ -174,7 +173,7 @@ public class Compiler {
|
||||
|
||||
if(getLog().isVerbosePass1CreateSsa()) {
|
||||
getLog().append("SYMBOLS");
|
||||
getLog().append(program.getScope().toString(program, null));
|
||||
getLog().append(program.getScope().toString(program, false));
|
||||
}
|
||||
|
||||
new Pass1AddressOfVolatile(program).execute();
|
||||
@ -249,7 +248,7 @@ public class Compiler {
|
||||
getLog().append(program.getGraph().toString(program));
|
||||
|
||||
getLog().append("SYMBOL TABLE SSA");
|
||||
getLog().append(program.getScope().toString(program, null));
|
||||
getLog().append(program.getScope().toString(program, false));
|
||||
|
||||
program.endPass1();
|
||||
|
||||
@ -543,7 +542,7 @@ public class Compiler {
|
||||
|
||||
getLog().append("\nVARIABLE REGISTER WEIGHTS");
|
||||
program.getVariableRegisterWeights();
|
||||
getLog().append(program.getScope().toString(program, Variable.class));
|
||||
getLog().append(program.getScope().toString(program, true));
|
||||
|
||||
new Pass4LiveRangeEquivalenceClassesFinalize(program).allocate();
|
||||
new Pass4RegistersFinalize(program).allocate(true);
|
||||
@ -650,7 +649,7 @@ public class Compiler {
|
||||
new Pass5FixLongBranches(program).optimize();
|
||||
|
||||
getLog().append("\nFINAL SYMBOL TABLE");
|
||||
getLog().append(program.getScope().toString(program, null));
|
||||
getLog().append(program.getScope().toString(program, false));
|
||||
|
||||
getLog().append("\nFINAL ASSEMBLER");
|
||||
getLog().append("Score: " + Pass4RegisterUpliftCombinations.getAsmScore(program) + "\n");
|
||||
|
@ -16,7 +16,7 @@ public class AsmFormat {
|
||||
* Get ASM code for a constant value
|
||||
*
|
||||
* @param value The constant value
|
||||
* @param precedence The precedence of the outer expression operator. Used to generate perenthesis when needed.
|
||||
* @param precedence The precedence of the outer expression operator. Used to generate parenthesis when needed.
|
||||
* @param codeScope The scope containing the code being generated. Used for adding scope to the name when needed (eg. line.x1 when referencing x1 variable inside line scope from outside line scope).
|
||||
* @return The ASM string representing the constant value
|
||||
*/
|
||||
|
@ -8,7 +8,7 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.Registers;
|
||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.parser.KickCParser;
|
||||
@ -76,8 +76,8 @@ public class AsmFragmentInstance {
|
||||
if(boundValue == null) {
|
||||
throw new RuntimeException("Binding '" + name + "' not found in fragment " + this.name);
|
||||
}
|
||||
if(boundValue instanceof Variable) {
|
||||
Variable boundVar = (Variable) boundValue;
|
||||
if(boundValue instanceof SymbolVariable && ((SymbolVariable) boundValue).isVariable()) {
|
||||
SymbolVariable boundVar = (SymbolVariable) boundValue;
|
||||
Registers.Register register = boundVar.getAllocation();
|
||||
if(register != null && register instanceof Registers.RegisterZpMem) {
|
||||
return new AsmParameter(AsmFormat.getAsmParamName(boundVar, codeScopeRef), true);
|
||||
@ -86,9 +86,9 @@ public class AsmFragmentInstance {
|
||||
} else {
|
||||
throw new RuntimeException("Register Type not implemented " + register);
|
||||
}
|
||||
} else if(boundValue instanceof ConstantVar) {
|
||||
ConstantVar constantVar = (ConstantVar) boundValue;
|
||||
String constantValueAsm = AsmFormat.getAsmConstant(program, constantVar.getRef(), 99, codeScopeRef);
|
||||
} else if(boundValue instanceof SymbolVariable && ((SymbolVariable) boundValue).isConstant()) {
|
||||
SymbolVariable constantVar = (SymbolVariable) boundValue;
|
||||
String constantValueAsm = AsmFormat.getAsmConstant(program, constantVar.getConstantRef(), 99, codeScopeRef);
|
||||
boolean constantValueZp = SymbolType.BYTE.equals(constantVar.getType());
|
||||
if(!constantValueZp) {
|
||||
constantValueZp = isConstantValueZp(constantVar.getConstantValue());
|
||||
|
@ -8,10 +8,7 @@ import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.*;
|
||||
import dk.camelot64.kickc.model.types.*;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
@ -106,7 +103,7 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
throw new AsmFragmentInstance.AluNotApplicableException("Error! ALU register only allowed as rValue2. " + assignment);
|
||||
}
|
||||
VariableRef assignmentRValue2 = (VariableRef) assignment.getrValue2();
|
||||
Variable assignmentRValue2Var = program.getSymbolInfos().getVariable(assignmentRValue2);
|
||||
SymbolVariable assignmentRValue2Var = program.getSymbolInfos().getVariable(assignmentRValue2);
|
||||
Registers.Register rVal2Register = assignmentRValue2Var.getAllocation();
|
||||
|
||||
if(!rVal2Register.getType().equals(Registers.RegisterType.REG_ALU)) {
|
||||
@ -338,7 +335,7 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
return bindValue.toString();
|
||||
}
|
||||
} else if(value instanceof VariableRef) {
|
||||
Variable variable = program.getSymbolInfos().getVariable((VariableRef) value);
|
||||
SymbolVariable variable = program.getSymbolInfos().getVariable((VariableRef) value);
|
||||
if(castType == null) {
|
||||
castType = variable.getType();
|
||||
}
|
||||
@ -455,8 +452,9 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
String zpNameIdx = null;
|
||||
for(String boundName : bindings.keySet()) {
|
||||
Value boundValue = bindings.get(boundName);
|
||||
if(boundValue instanceof Variable) {
|
||||
Registers.Register boundRegister = ((Variable) boundValue).getAllocation();
|
||||
if(boundValue instanceof SymbolVariable && ((SymbolVariable) boundValue).isVariable()) {
|
||||
SymbolVariable boundVariable = (SymbolVariable) boundValue;
|
||||
Registers.Register boundRegister = boundVariable.getAllocation();
|
||||
if(boundRegister != null && Registers.RegisterType.ZP_MEM.equals(boundRegister.getType())) {
|
||||
Registers.RegisterZpMem boundRegisterZp = (Registers.RegisterZpMem) boundRegister;
|
||||
if(registerZp.getZp() == boundRegisterZp.getZp()) {
|
||||
@ -476,8 +474,9 @@ public class AsmFragmentInstanceSpecFactory {
|
||||
String memNameIdx = null;
|
||||
for(String boundName : bindings.keySet()) {
|
||||
Value boundValue = bindings.get(boundName);
|
||||
if(boundValue instanceof Variable) {
|
||||
Registers.Register boundRegister = ((Variable) boundValue).getAllocation();
|
||||
if(boundValue instanceof SymbolVariable && ((SymbolVariable) boundValue).isVariable()) {
|
||||
SymbolVariable boundVariable = (SymbolVariable) boundValue;
|
||||
Registers.Register boundRegister = boundVariable.getAllocation();
|
||||
if(boundRegister instanceof Registers.RegisterMainMem) {
|
||||
if(boundRegister.equals(register)) {
|
||||
memNameIdx = boundName.substring(boundName.length() - 1);
|
||||
|
@ -8,7 +8,6 @@ import dk.camelot64.kickc.model.statements.StatementSource;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
@ -80,12 +79,12 @@ public class AsmFragmentTemplate {
|
||||
ProgramScope scope = new ProgramScope();
|
||||
LinkedHashMap<String, Value> bindings = new LinkedHashMap<>();
|
||||
{
|
||||
Variable v1 = new Variable("z1", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY);
|
||||
Variable v2 = new Variable("z2", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY);
|
||||
Variable v3 = new Variable("z3", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY);
|
||||
Variable v4 = new Variable("z4", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY);
|
||||
Variable v5 = new Variable("z5", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY);
|
||||
Variable v6 = new Variable("z6", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY);
|
||||
SymbolVariable v1 = new SymbolVariable( false, "z1", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
SymbolVariable v2 = new SymbolVariable( false, "z2", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
SymbolVariable v3 = new SymbolVariable( false, "z3", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
SymbolVariable v4 = new SymbolVariable( false, "z4", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
SymbolVariable v5 = new SymbolVariable( false, "z5", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
SymbolVariable v6 = new SymbolVariable( false, "z6", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.PHI_VERSION, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, null);
|
||||
v1.setAllocation(new Registers.RegisterZpMem(2, 1));
|
||||
v2.setAllocation(new Registers.RegisterZpMem(4, 1));
|
||||
v3.setAllocation(new Registers.RegisterZpMem(6, 1));
|
||||
@ -100,18 +99,18 @@ public class AsmFragmentTemplate {
|
||||
if(signature.contains("z6")) bindings.put("z6", v6);
|
||||
}
|
||||
{
|
||||
Variable v1 = new Variable("m1", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY);
|
||||
Variable v2 = new Variable("m2", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY);
|
||||
Variable v3 = new Variable("m3", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY);
|
||||
Variable v4 = new Variable("m4", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY);
|
||||
Variable v5 = new Variable("m5", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY);
|
||||
Variable v6 = new Variable("m6", scope, SymbolType.BYTE, null, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY);
|
||||
v1.setAllocation(new Registers.RegisterMainMem(v1.getRef(), 1, null));
|
||||
v2.setAllocation(new Registers.RegisterMainMem(v2.getRef(), 1, null));
|
||||
v3.setAllocation(new Registers.RegisterMainMem(v3.getRef(), 1, null));
|
||||
v4.setAllocation(new Registers.RegisterMainMem(v4.getRef(), 1, null));
|
||||
v5.setAllocation(new Registers.RegisterMainMem(v5.getRef(), 1, null));
|
||||
v6.setAllocation(new Registers.RegisterMainMem(v6.getRef(), 1, null));
|
||||
SymbolVariable v1 = new SymbolVariable( false, "m1", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
||||
SymbolVariable v2 = new SymbolVariable( false, "m2", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
||||
SymbolVariable v3 = new SymbolVariable( false, "m3", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
||||
SymbolVariable v4 = new SymbolVariable( false, "m4", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
||||
SymbolVariable v5 = new SymbolVariable( false, "m5", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
||||
SymbolVariable v6 = new SymbolVariable( false, "m6", scope, SymbolType.BYTE, SymbolVariable.StorageStrategy.LOAD_STORE, SymbolVariable.MemoryArea.MAIN_MEMORY, null);
|
||||
v1.setAllocation(new Registers.RegisterMainMem(v1.getVariableRef(), 1, null));
|
||||
v2.setAllocation(new Registers.RegisterMainMem(v2.getVariableRef(), 1, null));
|
||||
v3.setAllocation(new Registers.RegisterMainMem(v3.getVariableRef(), 1, null));
|
||||
v4.setAllocation(new Registers.RegisterMainMem(v4.getVariableRef(), 1, null));
|
||||
v5.setAllocation(new Registers.RegisterMainMem(v5.getVariableRef(), 1, null));
|
||||
v6.setAllocation(new Registers.RegisterMainMem(v6.getVariableRef(), 1, null));
|
||||
if(signature.contains("m1")) bindings.put("m1", v1);
|
||||
if(signature.contains("m2")) bindings.put("m2", v2);
|
||||
if(signature.contains("m3")) bindings.put("m3", v3);
|
||||
|
@ -26,7 +26,7 @@ public class CallingConventionStack {
|
||||
returnOffsetConstant = new ConstantVar(returnOffsetConstantName, procedure, SymbolType.BYTE, new ConstantInteger(returnByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
||||
procedure.add(returnOffsetConstant);
|
||||
}
|
||||
return returnOffsetConstant.getRef();
|
||||
return returnOffsetConstant.getConstantRef();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,7 +45,7 @@ public class CallingConventionStack {
|
||||
paramOffsetConstant = new ConstantVar(paramOffsetConstantName, procedure, SymbolType.BYTE, new ConstantInteger(paramByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
||||
procedure.add(paramOffsetConstant);
|
||||
}
|
||||
return paramOffsetConstant.getRef();
|
||||
return paramOffsetConstant.getConstantRef();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,7 +125,7 @@ public class CallingConventionStack {
|
||||
long STACK_BASE_ADDRESS = 0x103L;
|
||||
ConstantVar stackBase = new ConstantVar("STACK_BASE", programScope, SymbolType.WORD, new ConstantInteger(STACK_BASE_ADDRESS, SymbolType.WORD), Scope.SEGMENT_DATA_DEFAULT);
|
||||
programScope.add(stackBase);
|
||||
return stackBase.getRef();
|
||||
return stackBase.getConstantRef();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,10 +6,7 @@ import dk.camelot64.kickc.model.statements.StatementLValue;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.Pass2ConstantIdentification;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -92,7 +89,7 @@ public class ControlFlowGraph implements Serializable {
|
||||
* @param variable The variable to find the assignment for
|
||||
* @return All assignments.
|
||||
*/
|
||||
public List<StatementLValue> getAssignments(VariableRef variable) {
|
||||
public List<StatementLValue> getAssignments(SymbolVariableRef variable) {
|
||||
ArrayList<StatementLValue> assignments = new ArrayList<>();
|
||||
for(ControlFlowBlock block : getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -107,7 +107,7 @@ public class LiveRangeEquivalenceClassSet {
|
||||
for(LiveRangeEquivalenceClass equivalenceClass : getEquivalenceClasses()) {
|
||||
Registers.Register register = equivalenceClass.getRegister();
|
||||
for(VariableRef variable : equivalenceClass.getVariables()) {
|
||||
Variable var = program.getSymbolInfos().getVariable(variable);
|
||||
SymbolVariable var = program.getSymbolInfos().getVariable(variable);
|
||||
var.setAllocation(register);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
@ -187,8 +187,8 @@ public class PhiTransitions {
|
||||
PhiTransition.PhiAssignment assignment = assignments.get(i);
|
||||
PhiTransition.PhiAssignment otherAssignment = otherAssignments.get(i);
|
||||
if(assignment.getVariable() != null && otherAssignment.getVariable() != null) {
|
||||
Variable var = program.getSymbolInfos().getVariable(assignment.getVariable());
|
||||
Variable otherVar = program.getSymbolInfos().getVariable(otherAssignment.getVariable());
|
||||
SymbolVariable var = program.getSymbolInfos().getVariable(assignment.getVariable());
|
||||
SymbolVariable otherVar = program.getSymbolInfos().getVariable(otherAssignment.getVariable());
|
||||
if(!var.getAllocation().equals(otherVar.getAllocation())) {
|
||||
return false;
|
||||
}
|
||||
@ -196,8 +196,8 @@ public class PhiTransitions {
|
||||
return false;
|
||||
}
|
||||
if(assignment.getrValue() instanceof VariableRef && otherAssignment.getrValue() instanceof VariableRef) {
|
||||
Variable var = program.getSymbolInfos().getVariable((VariableRef) assignment.getrValue());
|
||||
Variable otherVar = program.getSymbolInfos().getVariable((VariableRef) otherAssignment.getrValue());
|
||||
SymbolVariable var = program.getSymbolInfos().getVariable((VariableRef) assignment.getrValue());
|
||||
SymbolVariable otherVar = program.getSymbolInfos().getVariable((VariableRef) otherAssignment.getrValue());
|
||||
if(!var.getAllocation().equals(otherVar.getAllocation())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
@ -28,7 +28,7 @@ public class RegisterCombination {
|
||||
for(LiveRangeEquivalenceClass equivalenceClass : allocation.keySet()) {
|
||||
Registers.Register register = allocation.get(equivalenceClass);
|
||||
for(VariableRef variable : equivalenceClass.getVariables()) {
|
||||
Variable var = program.getSymbolInfos().getVariable(variable);
|
||||
SymbolVariable var = program.getSymbolInfos().getVariable(variable);
|
||||
var.setAllocation(register);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import java.util.Map;
|
||||
public class StructUnwinding {
|
||||
|
||||
/** Maps struct variables to unwinding of each member. */
|
||||
Map<VariableRef, VariableUnwinding> structVariables = new LinkedHashMap<>();
|
||||
Map<SymbolVariableRef, VariableUnwinding> structVariables = new LinkedHashMap<>();
|
||||
|
||||
/**
|
||||
* Get information about how a struct variable was unwound into member variables
|
||||
@ -33,7 +33,7 @@ public class StructUnwinding {
|
||||
* @param ref The variable to add information for
|
||||
* @return The new information about the unwinding.
|
||||
*/
|
||||
public VariableUnwinding createVariableUnwinding(VariableRef ref) {
|
||||
public VariableUnwinding createVariableUnwinding(SymbolVariableRef ref) {
|
||||
VariableUnwinding existing = structVariables.put(ref, new VariableUnwinding());
|
||||
if(existing != null) {
|
||||
throw new InternalError("ERROR! Struct unwinding was already created once! " + ref.toString());
|
||||
@ -46,10 +46,10 @@ public class StructUnwinding {
|
||||
public static class VariableUnwinding implements StructMemberUnwinding {
|
||||
|
||||
/** Maps member names to the unwound variables. */
|
||||
Map<String, VariableRef> memberUnwinding = new LinkedHashMap<>();
|
||||
Map<String, SymbolVariableRef> memberUnwinding = new LinkedHashMap<>();
|
||||
|
||||
/** Set how a member variable was unwound to a specific (new) variable. */
|
||||
public void setMemberUnwinding(String memberName, VariableRef memberVariableUnwound) {
|
||||
public void setMemberUnwinding(String memberName, SymbolVariableRef memberVariableUnwound) {
|
||||
this.memberUnwinding.put(memberName, memberVariableUnwound);
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ public class StructUnwinding {
|
||||
* @return The new variable
|
||||
*/
|
||||
public LValue getMemberUnwinding(String memberName) {
|
||||
return this.memberUnwinding.get(memberName);
|
||||
return (LValue) this.memberUnwinding.get(memberName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -20,8 +20,8 @@ public class SymbolInfos {
|
||||
return symbols.get(ref);
|
||||
}
|
||||
|
||||
public Variable getVariable(VariableRef ref) {
|
||||
return (Variable) getSymbol(ref);
|
||||
public SymbolVariable getVariable(VariableRef ref) {
|
||||
return (SymbolVariable) getSymbol(ref);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ public class VariableReferenceInfos {
|
||||
* @param varRef The variable to look for
|
||||
* @return Index of all statements referencing the constant
|
||||
*/
|
||||
public Collection<Integer> getVarRefStatements(VariableRef varRef) {
|
||||
public Collection<Integer> getVarRefStatements(SymbolVariableRef varRef) {
|
||||
Collection<ReferenceToSymbolVar> refs = symbolVarReferences.get(varRef);
|
||||
LinkedHashSet<Integer> stmts = new LinkedHashSet<>();
|
||||
if(refs != null) {
|
||||
|
@ -11,7 +11,6 @@ import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
@ -119,9 +118,9 @@ public interface ProgramExpressionBinary extends ProgramExpression {
|
||||
assignment.setrValue1(new ConstantCastValue(toType, (ConstantValue) assignment.getrValue1()));
|
||||
} else {
|
||||
Scope blockScope = symbols.getScope(currentScope);
|
||||
Variable tmpVar = blockScope.addVariableIntermediate();
|
||||
SymbolVariable tmpVar = blockScope.addVariableIntermediate();
|
||||
tmpVar.setTypeInferred(toType);
|
||||
StatementAssignment newAssignment = new StatementAssignment(tmpVar.getRef(), Operators.getCastUnary(toType), assignment.getrValue1(), assignment.getSource(), Comment.NO_COMMENTS);
|
||||
StatementAssignment newAssignment = new StatementAssignment((LValue) tmpVar.getRef(), Operators.getCastUnary(toType), assignment.getrValue1(), assignment.getSource(), Comment.NO_COMMENTS);
|
||||
assignment.setrValue1(tmpVar.getRef());
|
||||
stmtIt.previous();
|
||||
stmtIt.add(newAssignment);
|
||||
@ -135,9 +134,9 @@ public interface ProgramExpressionBinary extends ProgramExpression {
|
||||
assignment.setrValue2(new ConstantCastValue(toType, (ConstantValue) assignment.getrValue2()));
|
||||
} else {
|
||||
Scope blockScope = symbols.getScope(currentScope);
|
||||
Variable tmpVar = blockScope.addVariableIntermediate();
|
||||
SymbolVariable tmpVar = blockScope.addVariableIntermediate();
|
||||
tmpVar.setTypeInferred(toType);
|
||||
StatementAssignment newAssignment = new StatementAssignment(tmpVar.getRef(), Operators.getCastUnary(toType), assignment.getrValue2(), assignment.getSource(), Comment.NO_COMMENTS);
|
||||
StatementAssignment newAssignment = new StatementAssignment((LValue) tmpVar.getRef(), Operators.getCastUnary(toType), assignment.getrValue2(), assignment.getSource(), Comment.NO_COMMENTS);
|
||||
assignment.setrValue2(tmpVar.getRef());
|
||||
stmtIt.previous();
|
||||
stmtIt.add(newAssignment);
|
||||
@ -259,11 +258,11 @@ public interface ProgramExpressionBinary extends ProgramExpression {
|
||||
throw new InternalError("Cannot cast declared type!" + variable.toString());
|
||||
} else {
|
||||
Scope blockScope = symbols.getScope(currentScope);
|
||||
Variable tmpVar = blockScope.addVariableIntermediate();
|
||||
SymbolVariable tmpVar = blockScope.addVariableIntermediate();
|
||||
SymbolType rightType = SymbolTypeInference.inferType(symbols, getRight());
|
||||
tmpVar.setTypeInferred(rightType);
|
||||
StatementAssignment newAssignment = new StatementAssignment(assignment.getlValue(), Operators.getCastUnary(toType), tmpVar.getRef(), assignment.getSource(), Comment.NO_COMMENTS);
|
||||
assignment.setlValue(tmpVar.getRef());
|
||||
assignment.setlValue((LValue) tmpVar.getRef());
|
||||
stmtIt.add(newAssignment);
|
||||
}
|
||||
}
|
||||
@ -274,11 +273,11 @@ public interface ProgramExpressionBinary extends ProgramExpression {
|
||||
assignment.setOperator(Operators.getCastUnary(toType));
|
||||
} else {
|
||||
Scope blockScope = symbols.getScope(currentScope);
|
||||
Variable tmpVar = blockScope.addVariableIntermediate();
|
||||
SymbolVariable tmpVar = blockScope.addVariableIntermediate();
|
||||
SymbolType rightType = SymbolTypeInference.inferType(symbols, getRight());
|
||||
tmpVar.setTypeInferred(rightType);
|
||||
StatementAssignment newAssignment = new StatementAssignment(assignment.getlValue(), Operators.getCastUnary(toType), tmpVar.getRef(), assignment.getSource(), Comment.NO_COMMENTS);
|
||||
assignment.setlValue(tmpVar.getRef());
|
||||
assignment.setlValue((LValue) tmpVar.getRef());
|
||||
stmtIt.add(newAssignment);
|
||||
}
|
||||
}
|
||||
|
@ -481,9 +481,9 @@ public interface ProgramValue {
|
||||
/** Member of a constant struct value. */
|
||||
class ProgramValueConstantStructMember implements ProgramValue {
|
||||
private final ConstantStructValue structValue;
|
||||
private final VariableRef memberRef;
|
||||
private final SymbolVariableRef memberRef;
|
||||
|
||||
public ProgramValueConstantStructMember(ConstantStructValue structValue, VariableRef memberRef) {
|
||||
public ProgramValueConstantStructMember(ConstantStructValue structValue, SymbolVariableRef memberRef) {
|
||||
this.structValue = structValue;
|
||||
this.memberRef = memberRef;
|
||||
}
|
||||
@ -498,7 +498,7 @@ public interface ProgramValue {
|
||||
structValue.setValue(memberRef, (ConstantValue) value);
|
||||
}
|
||||
|
||||
public VariableRef getMemberRef() {
|
||||
public SymbolVariableRef getMemberRef() {
|
||||
return memberRef;
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ public class ProgramValueIterator {
|
||||
}
|
||||
} else if(value instanceof ConstantStructValue) {
|
||||
ConstantStructValue constantStructValue = (ConstantStructValue) value;
|
||||
for(VariableRef memberRef : constantStructValue.getMembers()) {
|
||||
for(SymbolVariableRef memberRef : constantStructValue.getMembers()) {
|
||||
subValues.add(new ProgramValue.ProgramValueConstantStructMember(constantStructValue, memberRef));
|
||||
}
|
||||
} else if(value instanceof CastValue) {
|
||||
@ -249,11 +249,10 @@ public class ProgramValueIterator {
|
||||
} else if(value instanceof StackIdxValue) {
|
||||
subValues.add(new ProgramValue.ProgramValueStackIdxValue((StackIdxValue) value));
|
||||
} else if(value == null ||
|
||||
value instanceof VariableRef ||
|
||||
value instanceof Variable ||
|
||||
value instanceof SymbolVariableRef ||
|
||||
value instanceof SymbolVariable ||
|
||||
value instanceof ProcedureRef ||
|
||||
value instanceof ConstantLiteral ||
|
||||
value instanceof ConstantRef ||
|
||||
value instanceof StructZero ||
|
||||
value instanceof Label ||
|
||||
value instanceof LabelRef
|
||||
|
@ -45,7 +45,7 @@ public class OperatorSizeOf extends OperatorUnary {
|
||||
typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize&0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
||||
programScope.add(typeSizeConstant);
|
||||
}
|
||||
return typeSizeConstant.getRef();
|
||||
return typeSizeConstant.getConstantRef();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,7 +47,7 @@ public class OperatorTypeId extends OperatorUnary {
|
||||
typeIdConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize), Scope.SEGMENT_DATA_DEFAULT);
|
||||
programScope.add(typeIdConstant);
|
||||
}
|
||||
return typeIdConstant.getRef();
|
||||
return typeIdConstant.getConstantRef();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,6 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -1,20 +1,14 @@
|
||||
package dk.camelot64.kickc.model.symbols;
|
||||
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantRef;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
|
||||
/** A named constant or a variable that has been inferred to be constant in the symbol table */
|
||||
public class ConstantVar extends SymbolVariable {
|
||||
|
||||
public ConstantVar(String name, Scope scope, SymbolType type, ConstantValue value, String dataSegment) {
|
||||
super(name, scope, type, StorageStrategy.CONSTANT, MemoryArea.MAIN_MEMORY, dataSegment);
|
||||
super(true, name, scope, type, StorageStrategy.CONSTANT, MemoryArea.MAIN_MEMORY, dataSegment);
|
||||
setConstantValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstantRef getRef() {
|
||||
return new ConstantRef(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -125,11 +125,11 @@ public class Procedure extends Scope {
|
||||
return super.getFullName();
|
||||
}
|
||||
|
||||
public String toString(Program program, Class symbolClass) {
|
||||
public String toString(Program program, boolean onlyVars) {
|
||||
StringBuilder res = new StringBuilder();
|
||||
res.append(toString(program));
|
||||
res.append("\n");
|
||||
res.append(super.toString(program, symbolClass));
|
||||
res.append(super.toString(program, onlyVars));
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,10 @@ public class ProgramScope extends Scope {
|
||||
|
||||
|
||||
@Override
|
||||
public String toString(Program program, Class symbolClass) {
|
||||
public String toString(Program program, boolean onlyVars) {
|
||||
LiveRangeEquivalenceClassSet liveRangeEquivalenceClassSet = program.getLiveRangeEquivalenceClassSet();
|
||||
StringBuilder out = new StringBuilder();
|
||||
out.append(super.toString(program, symbolClass));
|
||||
out.append(super.toString(program, onlyVars));
|
||||
if(liveRangeEquivalenceClassSet != null) {
|
||||
out.append("\n");
|
||||
for(LiveRangeEquivalenceClass liveRangeEquivalenceClass : liveRangeEquivalenceClassSet.getEquivalenceClasses()) {
|
||||
|
@ -99,13 +99,13 @@ public abstract class Scope implements Symbol, Serializable {
|
||||
symbols.remove(symbol.getLocalName());
|
||||
}
|
||||
|
||||
public Variable addVariablePhiMaster(String name, SymbolType type, SymbolVariable.MemoryArea memoryArea, String dataSegment) {
|
||||
return add(new Variable(name, this, type, dataSegment, SymbolVariable.StorageStrategy.PHI_MASTER, memoryArea));
|
||||
public SymbolVariable addVariablePhiMaster(String name, SymbolType type, SymbolVariable.MemoryArea memoryArea, String dataSegment) {
|
||||
return add(new SymbolVariable( false, name, this, type, SymbolVariable.StorageStrategy.PHI_MASTER, memoryArea, dataSegment));
|
||||
}
|
||||
|
||||
public Variable addVariableIntermediate() {
|
||||
public SymbolVariable addVariableIntermediate() {
|
||||
String name = allocateIntermediateVariableName();
|
||||
return add(new Variable(name, this, SymbolType.VAR, getSegmentData(), SymbolVariable.StorageStrategy.INTERMEDIATE, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY));
|
||||
return add(new SymbolVariable( false, name, this, SymbolType.VAR, SymbolVariable.StorageStrategy.INTERMEDIATE, SymbolVariable.MemoryArea.ZEROPAGE_MEMORY, getSegmentData()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -117,11 +117,10 @@ public abstract class Scope implements Symbol, Serializable {
|
||||
public Collection<SymbolVariable> getVersions(SymbolVariable unversioned) {
|
||||
LinkedHashSet<SymbolVariable> versions = new LinkedHashSet<>();
|
||||
for(Symbol symbol : symbols.values()) {
|
||||
if(symbol instanceof Variable) {
|
||||
if(((Variable) symbol).isStoragePhiVersion()) {
|
||||
if(((Variable) symbol).getVersionOf().equals(unversioned)) {
|
||||
versions.add((Variable) symbol);
|
||||
}
|
||||
if(symbol instanceof SymbolVariable) {
|
||||
SymbolVariable variable = (SymbolVariable) symbol;
|
||||
if(variable.isVariable() && variable.isStoragePhiVersion() && variable.getVersionOf().equals(unversioned)) {
|
||||
versions.add(variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,12 +192,12 @@ public abstract class Scope implements Symbol, Serializable {
|
||||
return vars;
|
||||
}
|
||||
|
||||
public Collection<Variable> getAllVariables(boolean includeSubScopes) {
|
||||
public Collection<SymbolVariable> getAllVariables(boolean includeSubScopes) {
|
||||
Collection<SymbolVariable> symbolVariables = getAllSymbolVariables(includeSubScopes);
|
||||
Collection<Variable> vars = new ArrayList<>();
|
||||
Collection<SymbolVariable> vars = new ArrayList<>();
|
||||
symbolVariables.stream().
|
||||
filter(symbolVariable -> (symbolVariable instanceof Variable)).
|
||||
forEach(symbolVariable -> vars.add((Variable) symbolVariable));
|
||||
filter(SymbolVariable::isVariable).
|
||||
forEach(vars::add);
|
||||
return vars;
|
||||
}
|
||||
|
||||
@ -253,7 +252,6 @@ public abstract class Scope implements Symbol, Serializable {
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Label addLabel(String name) {
|
||||
return add(new Label(name, this, false));
|
||||
}
|
||||
@ -296,6 +294,7 @@ public abstract class Scope implements Symbol, Serializable {
|
||||
/**
|
||||
* Add a struct definition.
|
||||
* The name can be either defined in the program or an intermediate name.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public StructDefinition addStructDefinition(String name) {
|
||||
@ -328,7 +327,7 @@ public abstract class Scope implements Symbol, Serializable {
|
||||
return (Procedure) getSymbol(ref);
|
||||
}
|
||||
|
||||
public String toString(Program program, Class symbolClass) {
|
||||
public String toString(Program program, boolean onlyVars) {
|
||||
VariableRegisterWeights registerWeights = program.getOrNullVariableRegisterWeights();
|
||||
StringBuilder res = new StringBuilder();
|
||||
Set<String> names = symbols.keySet();
|
||||
@ -337,42 +336,44 @@ public abstract class Scope implements Symbol, Serializable {
|
||||
for(String name : sortedNames) {
|
||||
Symbol symbol = symbols.get(name);
|
||||
if(symbol instanceof Scope) {
|
||||
res.append(((Scope) symbol).toString(program, symbolClass));
|
||||
} else {
|
||||
if(symbolClass == null || symbolClass.isInstance(symbol)) {
|
||||
// Always output scopes
|
||||
res.append(((Scope) symbol).toString(program, onlyVars));
|
||||
} else if(symbol instanceof SymbolVariable) {
|
||||
SymbolVariable symVar = (SymbolVariable) symbol;
|
||||
if(!onlyVars || symVar.isVariable()) {
|
||||
// Output if not instructed to only output variables - or if it is a variable
|
||||
res.append(symbol.toString(program));
|
||||
if(symbol instanceof SymbolVariable) {
|
||||
SymbolVariable symVar = (SymbolVariable) symbol;
|
||||
if(symVar.getAsmName()!=null && !symVar.getName().equals(symVar.getAsmName())) {
|
||||
res.append(" " + symVar.getAsmName());
|
||||
if(symVar.getAsmName() != null && !symVar.getName().equals(symVar.getAsmName())) {
|
||||
res.append(" " + symVar.getAsmName());
|
||||
}
|
||||
if(symVar.isStorageLoadStore()) {
|
||||
res.append(" notregister");
|
||||
}
|
||||
Registers.Register declRegister = symVar.getDeclaredRegister();
|
||||
if(declRegister != null) {
|
||||
res.append(" !" + declRegister);
|
||||
}
|
||||
if(symVar.isVariable()) {
|
||||
Registers.Register register = symVar.getAllocation();
|
||||
if(register != null && !register.equals(declRegister)) {
|
||||
res.append(" " + register);
|
||||
}
|
||||
if(symVar.isStorageLoadStore()) {
|
||||
res.append(" notregister");
|
||||
}
|
||||
Registers.Register declRegister = symVar.getDeclaredRegister();
|
||||
if(declRegister != null) {
|
||||
res.append(" !" + declRegister);
|
||||
}
|
||||
if(symbol instanceof Variable) {
|
||||
Variable var = (Variable) symVar;
|
||||
Registers.Register register = var.getAllocation();
|
||||
if(register != null && !register.equals(declRegister)) {
|
||||
res.append(" " + register);
|
||||
}
|
||||
if(registerWeights != null) {
|
||||
Double weight = registerWeights.getWeight(var.getRef());
|
||||
if(weight != null) {
|
||||
res.append(" " + weight);
|
||||
}
|
||||
if(registerWeights != null) {
|
||||
Double weight = registerWeights.getWeight(symVar.getVariableRef());
|
||||
if(weight != null) {
|
||||
res.append(" " + weight);
|
||||
}
|
||||
}
|
||||
if(symbol instanceof ConstantVar) {
|
||||
ConstantVar constVar = (ConstantVar) symbol;
|
||||
res.append(" = " + constVar.getConstantValue().toString(program));
|
||||
}
|
||||
}
|
||||
if(symVar.isConstant()) {
|
||||
res.append(" = " + symVar.getConstantValue().toString(program));
|
||||
}
|
||||
res.append("\n");
|
||||
}
|
||||
} else if(!onlyVars) {
|
||||
// Only output if not instructed to only output variables
|
||||
res.append(symbol.toString(program));
|
||||
res.append("\n");
|
||||
}
|
||||
}
|
||||
return res.toString();
|
||||
@ -384,6 +385,7 @@ public abstract class Scope implements Symbol, Serializable {
|
||||
|
||||
/**
|
||||
* Set the value of the counter used to number intermediate labels
|
||||
*
|
||||
* @param intermediateLabelCount The new counter value
|
||||
*/
|
||||
public void setIntermediateLabelCount(int intermediateLabelCount) {
|
||||
|
@ -23,8 +23,8 @@ public class StructDefinition extends Scope {
|
||||
* @param name The name of the member
|
||||
* @return The member variable
|
||||
*/
|
||||
public Variable getMember(String name) {
|
||||
for(Variable member : getAllVariables(false)) {
|
||||
public SymbolVariable getMember(String name) {
|
||||
for(SymbolVariable member : getAllVariables(false)) {
|
||||
if(member.getLocalName().equals(name)) {
|
||||
return member;
|
||||
}
|
||||
@ -37,9 +37,9 @@ public class StructDefinition extends Scope {
|
||||
* @param member The member to find offset for
|
||||
* @return The byte offset of the start of the member data
|
||||
*/
|
||||
public long getMemberByteOffset(Variable member, ProgramScope programScope) {
|
||||
public long getMemberByteOffset(SymbolVariable member, ProgramScope programScope) {
|
||||
long byteOffset=0;
|
||||
for(Variable structMember : getAllVariables(false)) {
|
||||
for(SymbolVariable structMember : getAllVariables(false)) {
|
||||
if(structMember.equals(member)) {
|
||||
break;
|
||||
} else {
|
||||
|
@ -5,14 +5,16 @@ import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.Registers;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantRef;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
import dk.camelot64.kickc.model.values.SymbolVariableRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/** Abstract Variable or a Constant Variable */
|
||||
public abstract class SymbolVariable implements Symbol {
|
||||
public class SymbolVariable implements Symbol {
|
||||
|
||||
/** The name of the variable. */
|
||||
private String name;
|
||||
@ -29,6 +31,9 @@ public abstract class SymbolVariable implements Symbol {
|
||||
/** A short name used for the variable in ASM code. If possible variable names of variables are shortened in ASM code. This is possible, when several versions of the var use the same register. */
|
||||
private String asmName;
|
||||
|
||||
/** True of the variable is a compile-time constant (previously ConstantVar*/
|
||||
private boolean isConstant;
|
||||
|
||||
/** Specifies whether the symbol is declared to be constant, never constant or maybe constant. */
|
||||
public enum ConstantDeclaration {
|
||||
CONST, NOT_CONST, MAYBE_CONST
|
||||
@ -100,7 +105,8 @@ public abstract class SymbolVariable implements Symbol {
|
||||
/** If the variable is assigned to a specific "register", this contains the register. If null the variable has no allocation (yet). Constants are never assigned to registers. */
|
||||
private Registers.Register allocation;
|
||||
|
||||
public SymbolVariable(String name, Scope scope, SymbolType type, StorageStrategy storageStrategy, MemoryArea memoryArea, String dataSegment) {
|
||||
public SymbolVariable(boolean isConstant, String name, Scope scope, SymbolType type, StorageStrategy storageStrategy, MemoryArea memoryArea, String dataSegment) {
|
||||
this.isConstant = isConstant;
|
||||
this.name = name;
|
||||
this.scope = scope;
|
||||
this.type = type;
|
||||
@ -115,7 +121,56 @@ public abstract class SymbolVariable implements Symbol {
|
||||
this.nextPhiVersionNumber = 0;
|
||||
}
|
||||
|
||||
public abstract SymbolVariableRef getRef();
|
||||
/**
|
||||
* Create a version of a PHI master variable
|
||||
*
|
||||
* @param phiMaster The PHI master variable.
|
||||
* @param version The version number
|
||||
*/
|
||||
public SymbolVariable(SymbolVariable phiMaster, int version) {
|
||||
this(false, phiMaster.getName() + "#" + version, phiMaster.getScope(), phiMaster.getType(), StorageStrategy.PHI_VERSION, phiMaster.getMemoryArea(), phiMaster.getDataSegment());
|
||||
this.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
|
||||
this.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
|
||||
this.setDeclaredNotRegister(phiMaster.isDeclaredAsNotRegister());
|
||||
this.setConstantDeclaration(phiMaster.getConstantDeclaration());
|
||||
this.setDeclaredRegister(phiMaster.getDeclaredRegister());
|
||||
this.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
|
||||
this.setDeclaredExport(phiMaster.isDeclaredExport());
|
||||
this.setInferedVolatile(phiMaster.isInferedVolatile());
|
||||
this.setInferredType(phiMaster.isInferredType());
|
||||
this.setComments(phiMaster.getComments());
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the variable is a compile time constant. (Previously this was ConstantVar)
|
||||
* @return True if the variable is a compile time constant.
|
||||
*/
|
||||
public boolean isConstant() {
|
||||
return isConstant;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the variable is a not compile time constant. (Previously this was Variable)
|
||||
* @return True if the variable is not a compile-time constant
|
||||
*/
|
||||
public boolean isVariable() {
|
||||
return !isConstant;
|
||||
}
|
||||
|
||||
public SymbolVariableRef getRef() {
|
||||
if(isConstant)
|
||||
return new ConstantRef((ConstantVar) this);
|
||||
else
|
||||
return new VariableRef(this);
|
||||
}
|
||||
|
||||
public ConstantRef getConstantRef() {
|
||||
return (ConstantRef) getRef();
|
||||
}
|
||||
|
||||
public VariableRef getVariableRef() {
|
||||
return (VariableRef) getRef();
|
||||
}
|
||||
|
||||
private void setFullName() {
|
||||
String scopeName = (scope == null) ? "" : scope.getFullName();
|
||||
@ -127,10 +182,10 @@ public abstract class SymbolVariable implements Symbol {
|
||||
*
|
||||
* @return The new version of the PHI master
|
||||
*/
|
||||
public Variable createVersion() {
|
||||
public SymbolVariable createVersion() {
|
||||
if(!isStoragePhiMaster())
|
||||
throw new InternalError("Cannot version non-PHI variable " + this.toString());
|
||||
Variable version = new Variable(this, nextPhiVersionNumber++);
|
||||
SymbolVariable version = new SymbolVariable(this, nextPhiVersionNumber++);
|
||||
getScope().add(version);
|
||||
return version;
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
package dk.camelot64.kickc.model.symbols;
|
||||
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
/**
|
||||
* A Variable in the program.
|
||||
*/
|
||||
public class Variable extends SymbolVariable {
|
||||
|
||||
public Variable(String name, Scope scope, SymbolType type, String dataSegment, StorageStrategy storageStrategy, MemoryArea memoryArea) {
|
||||
super(name, scope, type, storageStrategy, memoryArea, dataSegment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a version of a PHI master variable
|
||||
*
|
||||
* @param phiMaster The PHI master variable.
|
||||
* @param version The version number
|
||||
*/
|
||||
public Variable(SymbolVariable phiMaster, int version) {
|
||||
super(phiMaster.getName() + "#" + version, phiMaster.getScope(), phiMaster.getType(), StorageStrategy.PHI_VERSION, phiMaster.getMemoryArea(), phiMaster.getDataSegment());
|
||||
this.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
|
||||
this.setDeclaredAsRegister(phiMaster.isDeclaredAsRegister());
|
||||
this.setDeclaredNotRegister(phiMaster.isDeclaredAsNotRegister());
|
||||
this.setConstantDeclaration(phiMaster.getConstantDeclaration());
|
||||
this.setDeclaredRegister(phiMaster.getDeclaredRegister());
|
||||
this.setDeclaredVolatile(phiMaster.isDeclaredVolatile());
|
||||
this.setDeclaredExport(phiMaster.isDeclaredExport());
|
||||
this.setInferedVolatile(phiMaster.isInferedVolatile());
|
||||
this.setInferredType(phiMaster.isInferredType());
|
||||
this.setComments(phiMaster.getComments());
|
||||
}
|
||||
|
||||
public VariableRef getRef() {
|
||||
return new VariableRef(this);
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,7 @@ package dk.camelot64.kickc.model.types;
|
||||
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
@ -53,7 +53,7 @@ public class SymbolTypeStruct implements SymbolType {
|
||||
*/
|
||||
public int calculateSizeBytes(StructDefinition structDefinition, ProgramScope programScope) {
|
||||
int sizeBytes = 0;
|
||||
for(Variable member : structDefinition.getAllVariables(false)) {
|
||||
for(SymbolVariable member : structDefinition.getAllVariables(false)) {
|
||||
SymbolType memberType = member.getType();
|
||||
int memberSize = getMemberSizeBytes(memberType, programScope);
|
||||
sizeBytes += memberSize;
|
||||
|
@ -17,9 +17,9 @@ public class ConstantStructValue implements ConstantValue {
|
||||
private SymbolTypeStruct structType;
|
||||
|
||||
/** The values of the members. */
|
||||
private Map<VariableRef, ConstantValue> values;
|
||||
private Map<SymbolVariableRef, ConstantValue> values;
|
||||
|
||||
public ConstantStructValue(SymbolTypeStruct structType, Map<VariableRef, ConstantValue> values) {
|
||||
public ConstantStructValue(SymbolTypeStruct structType, Map<SymbolVariableRef, ConstantValue> values) {
|
||||
this.structType = structType;
|
||||
this.values = values;
|
||||
}
|
||||
@ -42,7 +42,7 @@ public class ConstantStructValue implements ConstantValue {
|
||||
* Get the members of the struct
|
||||
* @return list of variable refs representing the members
|
||||
*/
|
||||
public List<VariableRef> getMembers() {
|
||||
public List<SymbolVariableRef> getMembers() {
|
||||
return new ArrayList<>(values.keySet());
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ public class ConstantStructValue implements ConstantValue {
|
||||
* @param memberRef The variable ref of the member
|
||||
* @return The constant value of the member
|
||||
*/
|
||||
public ConstantValue getValue(VariableRef memberRef) {
|
||||
public ConstantValue getValue(SymbolVariableRef memberRef) {
|
||||
return values.get(memberRef);
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ public class ConstantStructValue implements ConstantValue {
|
||||
* @param memberRef The variable ref of the member
|
||||
* @param value The new constant value of the member
|
||||
*/
|
||||
public void setValue(VariableRef memberRef, ConstantValue value) {
|
||||
public void setValue(SymbolVariableRef memberRef, ConstantValue value) {
|
||||
values.put(memberRef, value);
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ public class ConstantStructValue implements ConstantValue {
|
||||
StringBuilder out = new StringBuilder();
|
||||
boolean first = true;
|
||||
out.append("{ ");
|
||||
for(VariableRef memberRef : getMembers()) {
|
||||
for(SymbolVariableRef memberRef : getMembers()) {
|
||||
if(!first) {
|
||||
out.append(", ");
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.Registers;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
|
||||
@ -39,13 +39,16 @@ public class ConstantSymbolPointer implements ConstantValue {
|
||||
public ConstantLiteral calculateLiteral(ProgramScope scope) {
|
||||
// If the symbol has been allocated we can calculate a literal value!
|
||||
Symbol symbol = scope.getSymbol(toSymbol);
|
||||
if(symbol instanceof Variable) {
|
||||
Registers.Register allocation = ((Variable) symbol).getAllocation();
|
||||
if(allocation!=null && Registers.RegisterType.ZP_MEM.equals(allocation.getType())) {
|
||||
int zp = ((Registers.RegisterZpMem) allocation).getZp();
|
||||
return new ConstantInteger((long)zp, SymbolType.BYTE);
|
||||
} else if(allocation!=null && Registers.RegisterType.MAIN_MEM.equals(allocation.getType())) {
|
||||
throw new ConstantNotLiteral("Cannot calculate literal var pointer");
|
||||
if(symbol instanceof SymbolVariable) {
|
||||
SymbolVariable variable = (SymbolVariable) symbol;
|
||||
if(variable.isVariable()) {
|
||||
Registers.Register allocation = variable.getAllocation();
|
||||
if(allocation != null && Registers.RegisterType.ZP_MEM.equals(allocation.getType())) {
|
||||
int zp = ((Registers.RegisterZpMem) allocation).getZp();
|
||||
return new ConstantInteger((long) zp, SymbolType.BYTE);
|
||||
} else if(allocation != null && Registers.RegisterType.MAIN_MEM.equals(allocation.getType())) {
|
||||
throw new ConstantNotLiteral("Cannot calculate literal var pointer");
|
||||
}
|
||||
}
|
||||
}
|
||||
// WE cannot calculate a literal value
|
||||
|
@ -1,6 +1,7 @@
|
||||
package dk.camelot64.kickc.model.values;
|
||||
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
|
||||
/** A reference to a variable from the symbol table */
|
||||
public class VariableRef extends SymbolVariableRef implements RValue, LValue {
|
||||
@ -9,8 +10,10 @@ public class VariableRef extends SymbolVariableRef implements RValue, LValue {
|
||||
super(fullName);
|
||||
}
|
||||
|
||||
public VariableRef(Variable variable) {
|
||||
public VariableRef(SymbolVariable variable) {
|
||||
this(variable.getFullName());
|
||||
if(!variable.isVariable())
|
||||
throw new InternalError("VariableRef not allowed for non-variable "+variable.toString());
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@ package dk.camelot64.kickc.model.values;
|
||||
import dk.camelot64.kickc.model.InternalError;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeIntegerFixed;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
@ -19,9 +19,9 @@ public class ZeroConstantValues {
|
||||
public static ConstantValue zeroValue(SymbolType type, ProgramScope programScope) {
|
||||
if(type instanceof SymbolTypeStruct) {
|
||||
SymbolTypeStruct typeStruct = (SymbolTypeStruct) type;
|
||||
LinkedHashMap<VariableRef, ConstantValue> zeroValues = new LinkedHashMap<>();
|
||||
LinkedHashMap<SymbolVariableRef, ConstantValue> zeroValues = new LinkedHashMap<>();
|
||||
StructDefinition structDefinition = typeStruct.getStructDefinition(programScope);
|
||||
for(Variable memberVar : structDefinition.getAllVariables(false)) {
|
||||
for(SymbolVariable memberVar : structDefinition.getAllVariables(false)) {
|
||||
zeroValues.put(memberVar.getRef(), zeroValue(memberVar.getType(), programScope));
|
||||
}
|
||||
return new ConstantStructValue(typeStruct, zeroValues);
|
||||
|
@ -205,7 +205,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
procedure.setComments(ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
scopeStack.push(procedure);
|
||||
Label procExit = procedure.addLabel(SymbolRef.PROCEXIT_BLOCK_NAME);
|
||||
Variable returnVar = null;
|
||||
SymbolVariable returnVar = null;
|
||||
if(!SymbolType.VOID.equals(type)) {
|
||||
returnVar = procedure.addVariablePhiMaster("return", type, defaultMemoryArea, procedure.getSegmentData());
|
||||
}
|
||||
@ -226,9 +226,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
}
|
||||
sequence.addStatement(new StatementLabel(procExit.getRef(), StatementSource.procedureEnd(ctx), Comment.NO_COMMENTS));
|
||||
if(Procedure.CallingConvension.PHI_CALL.equals(procedure.getCallingConvension()) && returnVar != null) {
|
||||
sequence.addStatement(new StatementAssignment(returnVar.getRef(), returnVar.getRef(), StatementSource.procedureEnd(ctx), Comment.NO_COMMENTS));
|
||||
sequence.addStatement(new StatementAssignment(returnVar.getVariableRef(), returnVar.getRef(), StatementSource.procedureEnd(ctx), Comment.NO_COMMENTS));
|
||||
}
|
||||
VariableRef returnVarRef = null;
|
||||
SymbolVariableRef returnVarRef = null;
|
||||
if(returnVar != null) {
|
||||
returnVarRef = returnVar.getRef();
|
||||
}
|
||||
@ -241,8 +241,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
|
||||
@Override
|
||||
public List<Variable> visitParameterListDecl(KickCParser.ParameterListDeclContext ctx) {
|
||||
ArrayList<Variable> parameterDecls = new ArrayList<>();
|
||||
public List<SymbolVariable> visitParameterListDecl(KickCParser.ParameterListDeclContext ctx) {
|
||||
ArrayList<SymbolVariable> parameterDecls = new ArrayList<>();
|
||||
for(KickCParser.ParameterDeclContext parameterDeclCtx : ctx.parameterDecl()) {
|
||||
Object parameterDecl = this.visit(parameterDeclCtx);
|
||||
if(parameterDecl.equals(SymbolType.VOID)) {
|
||||
@ -252,8 +252,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
} else {
|
||||
throw new CompileError("Illegal void parameter.", new StatementSource(ctx));
|
||||
}
|
||||
} else if(parameterDecl instanceof Variable) {
|
||||
parameterDecls.add((Variable) parameterDecl);
|
||||
} else if(parameterDecl instanceof SymbolVariable) {
|
||||
parameterDecls.add((SymbolVariable) parameterDecl);
|
||||
} else {
|
||||
throw new CompileError("Unknown parameter " + ctx.getText(), new StatementSource(ctx));
|
||||
}
|
||||
@ -266,7 +266,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
this.visitDeclTypes(ctx.declTypes());
|
||||
SymbolType type = declVarType;
|
||||
List<Directive> directives = declVarDirectives;
|
||||
Variable param = new Variable(ctx.NAME().getText(), getCurrentScope(), type, currentDataSegment, SymbolVariable.StorageStrategy.PHI_MASTER, defaultMemoryArea);
|
||||
SymbolVariable param = new SymbolVariable( false, ctx.NAME().getText(), getCurrentScope(), type, SymbolVariable.StorageStrategy.PHI_MASTER, defaultMemoryArea, currentDataSegment);
|
||||
// Add directives
|
||||
addDirectives(param, true, directives, new StatementSource(ctx));
|
||||
exitDeclTypes();
|
||||
@ -557,7 +557,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
@Override
|
||||
public Object visitDeclVariableInitExpr(KickCParser.DeclVariableInitExprContext ctx) {
|
||||
String varName = ctx.NAME().getText();
|
||||
Variable lValue = visitDeclVariableInit(varName, ctx);
|
||||
SymbolVariable lValue = visitDeclVariableInit(varName, ctx);
|
||||
SymbolType type = declVarType;
|
||||
List<Comment> comments = declVarComments;
|
||||
KickCParser.ExprContext initializer = ctx.expr();
|
||||
@ -571,7 +571,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
} else {
|
||||
Statement initStmt;
|
||||
StatementSource statementSource = new StatementSource(ctx);
|
||||
initStmt = createDefaultInitializationStatement(lValue.getRef(), type, statementSource, ensureUnusedComments(comments));
|
||||
initStmt = createDefaultInitializationStatement((VariableRef) lValue.getRef(), type, statementSource, ensureUnusedComments(comments));
|
||||
sequence.addStatement(initStmt);
|
||||
}
|
||||
|
||||
@ -582,7 +582,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
@Override
|
||||
public Object visitDeclVariableInitKasm(KickCParser.DeclVariableInitKasmContext ctx) {
|
||||
String varName = ctx.NAME().getText();
|
||||
Variable lValue = visitDeclVariableInit(varName, ctx);
|
||||
SymbolVariable lValue = visitDeclVariableInit(varName, ctx);
|
||||
SymbolType type = this.declVarType;
|
||||
List<Comment> comments = this.declVarComments;
|
||||
if(!(type instanceof SymbolTypeArray)) {
|
||||
@ -606,17 +606,17 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
// Remove the KickAsm statement
|
||||
sequence.getStatements().remove(sequence.getStatements().size() - 1);
|
||||
// Add an initializer statement instead
|
||||
Statement stmt = new StatementAssignment(lValue.getRef(), constantArrayKickAsm, new StatementSource(ctx), ensureUnusedComments(comments));
|
||||
Statement stmt = new StatementAssignment((LValue) lValue.getRef(), constantArrayKickAsm, new StatementSource(ctx), ensureUnusedComments(comments));
|
||||
sequence.addStatement(stmt);
|
||||
return null;
|
||||
}
|
||||
|
||||
private Variable visitDeclVariableInit(String varName, KickCParser.DeclVariableInitContext ctx) {
|
||||
private SymbolVariable visitDeclVariableInit(String varName, KickCParser.DeclVariableInitContext ctx) {
|
||||
List<Directive> directives = declVarDirectives;
|
||||
SymbolType type = declVarType;
|
||||
List<Comment> comments = declVarComments;
|
||||
|
||||
Variable lValue;
|
||||
SymbolVariable lValue;
|
||||
try {
|
||||
lValue = getCurrentScope().addVariablePhiMaster(varName, type, defaultMemoryArea, currentDataSegment);
|
||||
} catch(CompileError e) {
|
||||
@ -877,13 +877,13 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
RValue exprVal = (RValue) this.visit(ctx.commaExpr());
|
||||
if(notConsumed(exprVal)) {
|
||||
// Make a tmpVar to create the statement
|
||||
Variable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
SymbolVariable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
List<Comment> comments = ensureUnusedComments(getCommentsSymbol(ctx));
|
||||
RValue rVal = exprVal;
|
||||
if(exprVal instanceof LValue) {
|
||||
rVal = copyLValue((LValue) exprVal);
|
||||
}
|
||||
sequence.addStatement(new StatementAssignment(tmpVar.getRef(), rVal, new StatementSource(ctx), comments));
|
||||
sequence.addStatement(new StatementAssignment((LValue) tmpVar.getRef(), rVal, new StatementSource(ctx), comments));
|
||||
}
|
||||
endNotConsumedTracking();
|
||||
PrePostModifierHandler.addPostModifiers(this, ctx.commaExpr(), new StatementSource(ctx));
|
||||
@ -900,8 +900,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
|
||||
if(elseStmt == null) {
|
||||
// If without else - skip the entire section if condition not met
|
||||
VariableRef notExprVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
sequence.addStatement(new StatementAssignment(notExprVar, null, Operators.LOGIC_NOT, rValue, StatementSource.ifThen(ctx), comments));
|
||||
SymbolVariableRef notExprVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
sequence.addStatement(new StatementAssignment((LValue) notExprVar, null, Operators.LOGIC_NOT, rValue, StatementSource.ifThen(ctx), comments));
|
||||
PrePostModifierHandler.addPostModifiers(this, ctx.commaExpr(), StatementSource.ifThen(ctx));
|
||||
Label endJumpLabel = getCurrentScope().addLabelIntermediate();
|
||||
sequence.addStatement(new StatementConditionalJump(notExprVar, endJumpLabel.getRef(), StatementSource.ifThen(ctx), Comment.NO_COMMENTS));
|
||||
@ -1225,9 +1225,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
sequence.addStatement(stmtNxt);
|
||||
// Add condition i!=last+1 or i!=last-1
|
||||
RValue beyondLastVal = new RangeComparison(rangeFirstValue, rangeLastValue, lValue.getType());
|
||||
Variable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmtTmpVar = new StatementAssignment(tmpVarRef, lValue.getRef(), Operators.NEQ, beyondLastVal, statementSource, Comment.NO_COMMENTS);
|
||||
SymbolVariable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
SymbolVariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmtTmpVar = new StatementAssignment((LValue) tmpVarRef, lValue.getRef(), Operators.NEQ, beyondLastVal, statementSource, Comment.NO_COMMENTS);
|
||||
sequence.addStatement(stmtTmpVar);
|
||||
// Add jump if condition was met
|
||||
StatementConditionalJump doJmpStmt = new StatementConditionalJump(tmpVarRef, repeatLabel.getRef(), statementSource, Comment.NO_COMMENTS);
|
||||
@ -1420,10 +1420,10 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addInitialAssignment(KickCParser.ExprContext initializer, Variable lValue, List<Comment> comments, StatementSource statementSource) {
|
||||
private void addInitialAssignment(KickCParser.ExprContext initializer, SymbolVariable lValue, List<Comment> comments, StatementSource statementSource) {
|
||||
PrePostModifierHandler.addPreModifiers(this, initializer, statementSource);
|
||||
RValue rValue = (RValue) visit(initializer);
|
||||
Statement stmt = new StatementAssignment(lValue.getRef(), rValue, statementSource, ensureUnusedComments(comments));
|
||||
Statement stmt = new StatementAssignment((LValue) lValue.getRef(), rValue, statementSource, ensureUnusedComments(comments));
|
||||
sequence.addStatement(stmt);
|
||||
PrePostModifierHandler.addPostModifiers(this, initializer, statementSource);
|
||||
}
|
||||
@ -1771,9 +1771,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
RValue child = (RValue) this.visit(ctx.expr());
|
||||
SymbolType castType = (SymbolType) this.visit(ctx.typeDecl());
|
||||
Operator operator = Operators.getCastUnary(castType);
|
||||
Variable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment(tmpVarRef, operator, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
SymbolVariable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
SymbolVariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment((LValue) tmpVarRef, operator, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
sequence.addStatement(stmt);
|
||||
consumeExpr(child);
|
||||
return tmpVarRef;
|
||||
@ -1788,9 +1788,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
} else {
|
||||
// sizeof(expression) - add a unary expression to be resolved later
|
||||
RValue child = (RValue) this.visit(ctx.expr());
|
||||
Variable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment(tmpVarRef, Operators.SIZEOF, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
SymbolVariable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
SymbolVariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment((LValue) tmpVarRef, Operators.SIZEOF, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
sequence.addStatement(stmt);
|
||||
consumeExpr(child);
|
||||
return tmpVarRef;
|
||||
@ -1806,9 +1806,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
} else {
|
||||
// typeid(expression) - add a unary expression to be resolved later
|
||||
RValue child = (RValue) this.visit(ctx.expr());
|
||||
Variable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment(tmpVarRef, Operators.TYPEID, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
SymbolVariable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
SymbolVariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment((LValue) tmpVarRef, Operators.TYPEID, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
sequence.addStatement(stmt);
|
||||
consumeExpr(child);
|
||||
return tmpVarRef;
|
||||
@ -1824,16 +1824,16 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
} else {
|
||||
parameters = new ArrayList<>();
|
||||
}
|
||||
Variable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
SymbolVariable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
SymbolVariableRef tmpVarRef = tmpVar.getRef();
|
||||
|
||||
String procedureName;
|
||||
if(ctx.expr() instanceof KickCParser.ExprIdContext) {
|
||||
procedureName = ctx.expr().getText();
|
||||
sequence.addStatement(new StatementCall(tmpVarRef, procedureName, parameters, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx))));
|
||||
sequence.addStatement(new StatementCall((LValue) tmpVarRef, procedureName, parameters, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx))));
|
||||
} else {
|
||||
RValue procedurePointer = (RValue) this.visit(ctx.expr());
|
||||
sequence.addStatement(new StatementCallPointer(tmpVarRef, procedurePointer, parameters, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx))));
|
||||
sequence.addStatement(new StatementCallPointer((LValue) tmpVarRef, procedurePointer, parameters, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx))));
|
||||
consumeExpr(procedurePointer);
|
||||
}
|
||||
for(RValue parameter : parameters) {
|
||||
@ -1953,9 +1953,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
if(left instanceof ConstantValue && right instanceof ConstantValue) {
|
||||
return new ConstantBinary((ConstantValue) left, (OperatorBinary) operator, (ConstantValue) right);
|
||||
} else {
|
||||
Variable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment(tmpVarRef, left, operator, right, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
SymbolVariable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
SymbolVariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment((LValue) tmpVarRef, left, operator, right, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
sequence.addStatement(stmt);
|
||||
consumeExpr(left);
|
||||
consumeExpr(right);
|
||||
@ -1982,9 +1982,9 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
} else if(child instanceof ConstantValue) {
|
||||
return new ConstantUnary((OperatorUnary) operator, (ConstantValue) child);
|
||||
} else {
|
||||
Variable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment(tmpVarRef, operator, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
SymbolVariable tmpVar = getCurrentScope().addVariableIntermediate();
|
||||
SymbolVariableRef tmpVarRef = tmpVar.getRef();
|
||||
Statement stmt = new StatementAssignment((LValue) tmpVarRef, operator, child, new StatementSource(ctx), ensureUnusedComments(getCommentsSymbol(ctx)));
|
||||
sequence.addStatement(stmt);
|
||||
consumeExpr(child);
|
||||
return tmpVarRef;
|
||||
@ -2000,20 +2000,20 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
sequence.addStatement(new StatementConditionalJump(condValue, trueLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
sequence.addStatement(new StatementLabel(falseLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
RValue falseValue = (RValue) this.visit(ctx.expr(2));
|
||||
VariableRef falseVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
sequence.addStatement(new StatementAssignment(falseVar, null, null, falseValue, new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
SymbolVariableRef falseVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
sequence.addStatement(new StatementAssignment((LValue) falseVar, null, null, falseValue, new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
LabelRef falseExitLabel = sequence.getCurrentBlockLabel();
|
||||
sequence.addStatement(new StatementJump(endJumpLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
sequence.addStatement(new StatementLabel(trueLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
RValue trueValue = (RValue) this.visit(ctx.expr(1));
|
||||
VariableRef trueVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
sequence.addStatement(new StatementAssignment(trueVar, null, null, trueValue, new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
SymbolVariableRef trueVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
sequence.addStatement(new StatementAssignment((LValue) trueVar, null, null, trueValue, new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
LabelRef trueExitLabel = sequence.getCurrentBlockLabel();
|
||||
sequence.addStatement(new StatementLabel(endJumpLabel.getRef(), new StatementSource(ctx), Comment.NO_COMMENTS));
|
||||
StatementPhiBlock phiBlock = new StatementPhiBlock(Comment.NO_COMMENTS);
|
||||
phiBlock.setSource(new StatementSource(ctx));
|
||||
VariableRef finalVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
StatementPhiBlock.PhiVariable phiVariable = phiBlock.addPhiVariable(finalVar);
|
||||
SymbolVariableRef finalVar = getCurrentScope().addVariableIntermediate().getRef();
|
||||
StatementPhiBlock.PhiVariable phiVariable = phiBlock.addPhiVariable((VariableRef) finalVar);
|
||||
phiVariable.setrValue(trueExitLabel, trueVar);
|
||||
phiVariable.setrValue(falseExitLabel, falseVar);
|
||||
sequence.addStatement(phiBlock);
|
||||
@ -2052,14 +2052,12 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
||||
@Override
|
||||
public RValue visitExprId(KickCParser.ExprIdContext ctx) {
|
||||
Symbol symbol = getCurrentScope().getSymbol(ctx.NAME().getText());
|
||||
if(symbol instanceof Variable) {
|
||||
Variable variable = (Variable) symbol;
|
||||
if(symbol instanceof SymbolVariable) {
|
||||
SymbolVariable variable = (SymbolVariable) symbol;
|
||||
return variable.getRef();
|
||||
} else if(symbol instanceof Procedure) {
|
||||
Procedure procedure = (Procedure) symbol;
|
||||
return procedure.getRef();
|
||||
} else if(symbol instanceof ConstantVar) {
|
||||
return ((ConstantVar) symbol).getRef();
|
||||
} else if(symbol == null) {
|
||||
// Either forward reference or a non-existing variable. Create a forward reference for later resolving.
|
||||
return new ForwardVariableRef(ctx.NAME().getText());
|
||||
|
@ -9,7 +9,6 @@ import dk.camelot64.kickc.model.statements.StatementLValue;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
import dk.camelot64.kickc.model.values.SymbolVariableRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
@ -28,8 +27,8 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
|
||||
@Override
|
||||
public boolean step() {
|
||||
Collection<SymbolVariableRef> earlyConstants = new ArrayList<>();
|
||||
for(Variable variable : getProgram().getScope().getAllVariables(true)) {
|
||||
VariableRef variableRef = variable.getRef();
|
||||
for(SymbolVariable variable : getProgram().getScope().getAllVariables(true)) {
|
||||
SymbolVariableRef variableRef = variable.getRef();
|
||||
if(!variable.isDeclaredConstant() && !variable.isVolatile() && !variableRef.isIntermediate()) {
|
||||
if(variable.isDeclaredNotConstant())
|
||||
// Skip explicit non-constants
|
||||
@ -64,7 +63,7 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
|
||||
* @param variableRef The variable
|
||||
* @return true if the variable is a procedure parameter
|
||||
*/
|
||||
public boolean isParameter(VariableRef variableRef) {
|
||||
public boolean isParameter(SymbolVariableRef variableRef) {
|
||||
SymbolVariable var = getScope().getVariable(variableRef);
|
||||
Scope varScope = var.getScope();
|
||||
if(varScope instanceof Procedure) {
|
||||
@ -82,7 +81,7 @@ public class Pass1EarlyConstantIdentification extends Pass1Base {
|
||||
* @param variable The variable
|
||||
* @return all assignments
|
||||
*/
|
||||
private Collection<StatementLValue> getAssignments(Variable variable) {
|
||||
private Collection<StatementLValue> getAssignments(SymbolVariable variable) {
|
||||
Collection<StatementLValue> assignments = new ArrayList<>();
|
||||
for(ControlFlowBlock block : getGraph().getAllBlocks()) {
|
||||
for(Statement statement : block.getStatements()) {
|
||||
|
@ -1,17 +1,19 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.operators.Operator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.LvalueIntermediate;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementLValue;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.LvalueIntermediate;
|
||||
import dk.camelot64.kickc.model.values.SymbolVariableRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -76,9 +78,9 @@ public class Pass1FixLValuesLoHi extends Pass1Base {
|
||||
SymbolVariable intermediateVar = programScope.getVariable(intermediate.getVariable());
|
||||
Scope currentScope = intermediateVar.getScope();
|
||||
// Let assignment put value into a tmp Var
|
||||
Variable tmpVar = currentScope.addVariableIntermediate();
|
||||
VariableRef tmpVarRef = tmpVar.getRef();
|
||||
statementLValue.setlValue(tmpVarRef);
|
||||
SymbolVariable tmpVar = currentScope.addVariableIntermediate();
|
||||
SymbolVariableRef tmpVarRef = tmpVar.getRef();
|
||||
statementLValue.setlValue((LValue) tmpVarRef);
|
||||
PassNTypeInference.updateInferedTypeLValue(getProgram(), statementLValue);
|
||||
// Insert an extra "set low" assignment statement
|
||||
Statement setLoHiAssignment = new StatementAssignment(loHiVar, loHiVar, loHiOperator, tmpVarRef, statementLValue.getSource(), new ArrayList<>());
|
||||
|
@ -81,7 +81,7 @@ public class Pass1GenerateSingleStaticAssignmentForm extends Pass1Base {
|
||||
if(assignedVar.isStoragePhiMaster()) {
|
||||
if(assignedVar.isDeclaredConstant() || earlyIdentifiedConstants.contains(assignedVar.getRef()))
|
||||
throw new InternalError("Error! Constants can not be versioned ", source);
|
||||
Variable version = assignedVar.createVersion();
|
||||
SymbolVariable version = assignedVar.createVersion();
|
||||
programLValue.set(version.getRef());
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
@ -50,7 +49,7 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
}
|
||||
|
||||
// For each statement maps RValues used as index to the new *sizeof() variable created
|
||||
Map<Statement, Map<RValue, VariableRef>> handled = new LinkedHashMap<>();
|
||||
Map<Statement, Map<RValue, SymbolVariableRef>> handled = new LinkedHashMap<>();
|
||||
ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
if(programValue.get() instanceof PointerDereferenceIndexed) {
|
||||
PointerDereferenceIndexed deref = (PointerDereferenceIndexed) programValue.get();
|
||||
@ -59,12 +58,12 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
if(pointerType.getElementType().getSizeBytes() > 1) {
|
||||
// Array-indexing into a non-byte pointer - multiply by sizeof()
|
||||
getLog().append("Fixing pointer array-indexing " + deref.toString(getProgram()));
|
||||
VariableRef idx2VarRef = handled.getOrDefault(currentStmt, new LinkedHashMap<>()).get(deref.getIndex());
|
||||
SymbolVariableRef idx2VarRef = handled.getOrDefault(currentStmt, new LinkedHashMap<>()).get(deref.getIndex());
|
||||
if(idx2VarRef == null) {
|
||||
Variable idx2Var = getScope().getScope(currentBlock.getScope()).addVariableIntermediate();
|
||||
SymbolVariable idx2Var = getScope().getScope(currentBlock.getScope()).addVariableIntermediate();
|
||||
idx2Var.setTypeInferred(SymbolTypeInference.inferType(getScope(), deref.getIndex()));
|
||||
ConstantRef sizeOfTargetType = OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
|
||||
StatementAssignment idx2 = new StatementAssignment(idx2Var.getRef(), deref.getIndex(), Operators.MULTIPLY, sizeOfTargetType, currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
StatementAssignment idx2 = new StatementAssignment((LValue) idx2Var.getRef(), deref.getIndex(), Operators.MULTIPLY, sizeOfTargetType, currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
stmtIt.previous();
|
||||
stmtIt.add(idx2);
|
||||
stmtIt.next();
|
||||
@ -104,9 +103,9 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
isPointerPlusConst = false;
|
||||
getLog().append("Fixing pointer addition " + assignment.toString(getProgram(), false));
|
||||
LValue lValue = assignment.getlValue();
|
||||
Variable tmpVar = getScope().getScope(block.getScope()).addVariableIntermediate();
|
||||
SymbolVariable tmpVar = getScope().getScope(block.getScope()).addVariableIntermediate();
|
||||
tmpVar.setTypeInferred(SymbolTypeInference.inferType(getScope(), assignment.getlValue()));
|
||||
assignment.setlValue(tmpVar.getRef());
|
||||
assignment.setlValue((LValue) tmpVar.getRef());
|
||||
ConstantRef sizeOfTargetType = OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
|
||||
stmtIt.add(new StatementAssignment(lValue, tmpVar.getRef(), Operators.DIVIDE, sizeOfTargetType, assignment.getSource(), Comment.NO_COMMENTS));
|
||||
}
|
||||
@ -116,11 +115,11 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
// Binary operation on a non-byte pointer - sizeof()-handling is probably needed!
|
||||
// Adding to a pointer - multiply by sizeof()
|
||||
getLog().append("Fixing pointer addition " + assignment.toString(getProgram(), false));
|
||||
Variable tmpVar = getScope().getScope(block.getScope()).addVariableIntermediate();
|
||||
SymbolVariable tmpVar = getScope().getScope(block.getScope()).addVariableIntermediate();
|
||||
tmpVar.setTypeInferred(SymbolTypeInference.inferType(getScope(), assignment.getrValue2()));
|
||||
stmtIt.remove();
|
||||
ConstantRef sizeOfTargetType = OperatorSizeOf.getSizeOfConstantVar(getProgram().getScope(), pointerType.getElementType());
|
||||
stmtIt.add(new StatementAssignment(tmpVar.getRef(), assignment.getrValue2(), Operators.MULTIPLY, sizeOfTargetType, assignment.getSource(), Comment.NO_COMMENTS));
|
||||
stmtIt.add(new StatementAssignment((LValue) tmpVar.getRef(), assignment.getrValue2(), Operators.MULTIPLY, sizeOfTargetType, assignment.getSource(), Comment.NO_COMMENTS));
|
||||
stmtIt.add(assignment);
|
||||
assignment.setrValue2(tmpVar.getRef());
|
||||
}
|
||||
@ -182,7 +181,7 @@ public class Pass1PointerSizeofFix extends Pass1Base {
|
||||
SymbolType structType = SymbolTypeInference.inferType(getScope(), struct);
|
||||
if(structType instanceof SymbolTypeStruct) {
|
||||
StructDefinition structDefinition = ((SymbolTypeStruct) structType).getStructDefinition(getScope());
|
||||
Variable memberVariable = structDefinition.getMember(structMemberRef.getMemberName());
|
||||
SymbolVariable memberVariable = structDefinition.getMember(structMemberRef.getMemberName());
|
||||
SymbolType memberType = memberVariable.getType();
|
||||
if(memberType instanceof SymbolTypePointer) {
|
||||
return (SymbolTypePointer) memberType;
|
||||
|
@ -297,10 +297,10 @@ public class Pass1ProcedureInline extends Pass1Base {
|
||||
callScope.addLabel(procedure.getLocalName() + serial);
|
||||
// And copy all procedure symbols
|
||||
for(Symbol procSymbol : procedure.getAllSymbols()) {
|
||||
if(procSymbol instanceof Variable) {
|
||||
Variable procVar = (Variable) procSymbol;
|
||||
if(procSymbol instanceof SymbolVariable) {
|
||||
SymbolVariable procVar = (SymbolVariable) procSymbol;
|
||||
String inlineVarName = getInlineSymbolName(procedure, procSymbol, serial);
|
||||
Variable inlineVar = callScope.addVariablePhiMaster(inlineVarName, procSymbol.getType(), procVar.getMemoryArea(), procVar.getDataSegment());
|
||||
SymbolVariable inlineVar = callScope.addVariablePhiMaster(inlineVarName, procSymbol.getType(), procVar.getMemoryArea(), procVar.getDataSegment());
|
||||
inlineVar.setInferredType(procVar.isInferredType());
|
||||
inlineVar.setDeclaredAlignment(procVar.getDeclaredAlignment());
|
||||
inlineVar.setConstantDeclaration(procVar.getConstantDeclaration());
|
||||
|
@ -2,7 +2,7 @@ package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
@ -21,7 +21,7 @@ public class Pass1StructTypeSizeFix extends Pass2SsaOptimization {
|
||||
@Override
|
||||
public boolean step() {
|
||||
AtomicBoolean modified = new AtomicBoolean(false);
|
||||
for(Variable variable : getScope().getAllVariables(true)) {
|
||||
for(SymbolVariable variable : getScope().getAllVariables(true)) {
|
||||
modified.set(fixStructSize(variable.getType()));
|
||||
}
|
||||
return modified.get();
|
||||
|
@ -71,12 +71,12 @@ public class Pass1UnwindBlockScopes extends Pass1Base {
|
||||
Label unwound = procedure.addLabel(name);
|
||||
unwoundSymbols.put(symbol.getRef(), unwound.getRef());
|
||||
}
|
||||
} else if(symbol instanceof Variable) {
|
||||
Variable variable = (Variable) symbol;
|
||||
} else if(symbol instanceof SymbolVariable) {
|
||||
SymbolVariable variable = (SymbolVariable) symbol;
|
||||
if(variable.isStoragePhiMaster() || variable.isStorageConstant()) {
|
||||
String name = findLocalName(procedure, symbol);
|
||||
Variable var = (Variable) symbol;
|
||||
Variable unwound = procedure.addVariablePhiMaster(name, symbol.getType(), var.getMemoryArea(), var.getDataSegment());
|
||||
SymbolVariable var = (SymbolVariable) symbol;
|
||||
SymbolVariable unwound = procedure.addVariablePhiMaster(name, symbol.getType(), var.getMemoryArea(), var.getDataSegment());
|
||||
unwound.setDeclaredAlignment(var.getDeclaredAlignment());
|
||||
unwound.setConstantDeclaration(var.getConstantDeclaration());
|
||||
unwound.setDeclaredVolatile(var.isDeclaredVolatile());
|
||||
@ -87,7 +87,7 @@ public class Pass1UnwindBlockScopes extends Pass1Base {
|
||||
unwound.setStorageStrategy(var.getStorageStrategy());
|
||||
unwound.setMemoryArea(var.getMemoryArea());
|
||||
} else if(variable.isStorageIntermediate()) {
|
||||
Variable unwound = procedure.addVariableIntermediate();
|
||||
SymbolVariable unwound = procedure.addVariableIntermediate();
|
||||
unwound.setStorageStrategy(variable.getStorageStrategy());
|
||||
unwound.setMemoryArea(variable.getMemoryArea());
|
||||
unwoundSymbols.put(symbol.getRef(), unwound.getRef());
|
||||
|
@ -199,7 +199,7 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
private boolean unwindStructVariables() {
|
||||
boolean modified = false;
|
||||
// Iterate through all scopes generating member-variables for each struct
|
||||
for(Variable variable : getScope().getAllVariables(true)) {
|
||||
for(SymbolVariable variable : getScope().getAllVariables(true)) {
|
||||
if(variable.getType() instanceof SymbolTypeStruct) {
|
||||
StructUnwinding structUnwinding = getProgram().getStructUnwinding();
|
||||
if(structUnwinding.getVariableUnwinding(variable.getRef()) == null) {
|
||||
@ -209,10 +209,10 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
// Not inside another struct
|
||||
StructDefinition structDefinition = ((SymbolTypeStruct) variable.getType()).getStructDefinition(getProgram().getScope());
|
||||
StructUnwinding.VariableUnwinding variableUnwinding = structUnwinding.createVariableUnwinding(variable.getRef());
|
||||
for(Variable member : structDefinition.getAllVariables(false)) {
|
||||
Variable memberVariable;
|
||||
for(SymbolVariable member : structDefinition.getAllVariables(false)) {
|
||||
SymbolVariable memberVariable;
|
||||
if(variable.getRef().isIntermediate()) {
|
||||
memberVariable = scope.add(new Variable(variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType(), variable.getDataSegment(), SymbolVariable.StorageStrategy.INTERMEDIATE, variable.getMemoryArea()));
|
||||
memberVariable = scope.add(new SymbolVariable( false, variable.getLocalName() + "_" + member.getLocalName(), scope, member.getType(), SymbolVariable.StorageStrategy.INTERMEDIATE, variable.getMemoryArea(), variable.getDataSegment()));
|
||||
} else {
|
||||
if(member.getType() instanceof SymbolTypePointer) {
|
||||
// Always put pointers in ZP memory area
|
||||
@ -405,9 +405,9 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
|
||||
@Override
|
||||
public List<String> getMemberNames() {
|
||||
Collection<Variable> structMemberVars = structDefinition.getAllVariables(false);
|
||||
Collection<SymbolVariable> structMemberVars = structDefinition.getAllVariables(false);
|
||||
ArrayList<String> memberNames = new ArrayList<>();
|
||||
for(Variable structMemberVar : structMemberVars) {
|
||||
for(SymbolVariable structMemberVar : structMemberVars) {
|
||||
memberNames.add(structMemberVar.getLocalName());
|
||||
}
|
||||
return memberNames;
|
||||
@ -416,13 +416,13 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
@Override
|
||||
public LValue getMemberUnwinding(String memberName) {
|
||||
ConstantRef memberOffsetConstant = PassNStructPointerRewriting.getMemberOffsetConstant(getScope(), structDefinition, memberName);
|
||||
Variable member = structDefinition.getMember(memberName);
|
||||
SymbolVariable member = structDefinition.getMember(memberName);
|
||||
Scope scope = getScope().getScope(currentBlock.getScope());
|
||||
Variable memberAddress = scope.addVariableIntermediate();
|
||||
SymbolVariable memberAddress = scope.addVariableIntermediate();
|
||||
memberAddress.setType(new SymbolTypePointer(member.getType()));
|
||||
CastValue structTypedPointer = new CastValue(new SymbolTypePointer(member.getType()), pointerDeref.getPointer());
|
||||
// Add statement $1 = ptr_struct + OFFSET_STRUCT_NAME_MEMBER
|
||||
stmtIt.add(new StatementAssignment(memberAddress.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.add(new StatementAssignment((LValue) memberAddress.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
// Unwind to *(ptr_struct+OFFSET_STRUCT_NAME_MEMBER)
|
||||
return new PointerDereferenceSimple(memberAddress.getRef());
|
||||
}
|
||||
@ -446,9 +446,9 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
|
||||
@Override
|
||||
public List<String> getMemberNames() {
|
||||
Collection<Variable> structMemberVars = structDefinition.getAllVariables(false);
|
||||
Collection<SymbolVariable> structMemberVars = structDefinition.getAllVariables(false);
|
||||
ArrayList<String> memberNames = new ArrayList<>();
|
||||
for(Variable structMemberVar : structMemberVars) {
|
||||
for(SymbolVariable structMemberVar : structMemberVars) {
|
||||
memberNames.add(structMemberVar.getLocalName());
|
||||
}
|
||||
return memberNames;
|
||||
@ -457,13 +457,13 @@ public class Pass1UnwindStructValues extends Pass1Base {
|
||||
@Override
|
||||
public LValue getMemberUnwinding(String memberName) {
|
||||
ConstantRef memberOffsetConstant = PassNStructPointerRewriting.getMemberOffsetConstant(getScope(), structDefinition, memberName);
|
||||
Variable member = structDefinition.getMember(memberName);
|
||||
SymbolVariable member = structDefinition.getMember(memberName);
|
||||
Scope scope = getScope().getScope(currentBlock.getScope());
|
||||
Variable memberAddress = scope.addVariableIntermediate();
|
||||
SymbolVariable memberAddress = scope.addVariableIntermediate();
|
||||
memberAddress.setType(new SymbolTypePointer(member.getType()));
|
||||
CastValue structTypedPointer = new CastValue(new SymbolTypePointer(member.getType()), pointerDeref.getPointer());
|
||||
// Add statement $1 = ptr_struct + OFFSET_STRUCT_NAME_MEMBER
|
||||
stmtIt.add(new StatementAssignment(memberAddress.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.add(new StatementAssignment((LValue) memberAddress.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
// Unwind to *(ptr_struct+OFFSET_STRUCT_NAME_MEMBER[idx]
|
||||
return new PointerDereferenceIndexed(memberAddress.getRef(), pointerDeref.getIndex());
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import dk.camelot64.kickc.model.StructUnwinding;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.StructUnwoundPlaceholder;
|
||||
@ -38,12 +38,12 @@ public class Pass1UnwindStructVersions extends Pass1Base {
|
||||
StructUnwoundPlaceholder placeholder = (StructUnwoundPlaceholder) assignment.getrValue2();
|
||||
SymbolTypeStruct typeStruct = placeholder.getTypeStruct();
|
||||
StructDefinition structDefinition = typeStruct.getStructDefinition(getProgram().getScope());
|
||||
Collection<Variable> members = structDefinition.getAllVariables(false);
|
||||
Iterator<Variable> memberDefIt = members.iterator();
|
||||
Collection<SymbolVariable> members = structDefinition.getAllVariables(false);
|
||||
Iterator<SymbolVariable> memberDefIt = members.iterator();
|
||||
List<RValue> unwoundMembers = placeholder.getUnwoundMembers();
|
||||
Iterator<RValue> memberUnwoundIt = unwoundMembers.iterator();
|
||||
while(memberDefIt.hasNext()) {
|
||||
Variable memberVar = memberDefIt.next();
|
||||
SymbolVariable memberVar = memberDefIt.next();
|
||||
RValue memberVal = memberUnwoundIt.next();
|
||||
versionedUnwinding.setMemberUnwinding(memberVar.getLocalName(), (VariableRef) memberVal);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -5,13 +5,9 @@ import dk.camelot64.kickc.model.iterator.ProgramValue;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
||||
import dk.camelot64.kickc.model.values.ConstantRef;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
import dk.camelot64.kickc.model.values.Value;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -58,7 +54,7 @@ public class Pass2ArrayInStructInlining extends Pass2SsaOptimization {
|
||||
ProgramValueIterator.execute(getProgram(), (programValue, currentStmt, stmtIt, currentBlock) -> {
|
||||
Value value = programValue.get();
|
||||
if(programValue instanceof ProgramValue.ProgramValueConstantStructMember) {
|
||||
VariableRef memberRef = ((ProgramValue.ProgramValueConstantStructMember) programValue).getMemberRef();
|
||||
SymbolVariableRef memberRef = ((ProgramValue.ProgramValueConstantStructMember) programValue).getMemberRef();
|
||||
SymbolVariable structMemberVar = getScope().getVariable(memberRef);
|
||||
if(structMemberVar.getType() instanceof SymbolTypeArray) {
|
||||
if(((SymbolTypeArray) structMemberVar.getType()).getSize() != null) {
|
||||
|
@ -5,7 +5,6 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValue;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.ForwardVariableRef;
|
||||
import dk.camelot64.kickc.model.values.Value;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
@ -43,9 +43,9 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
|
||||
Collection<Symbol> tableSymbols = getScope().getAllSymbols(true);
|
||||
|
||||
for(Symbol tableSymbol : tableSymbols) {
|
||||
if(tableSymbol instanceof Variable && ((Variable) tableSymbol).isStoragePhiMaster()) continue;
|
||||
if(tableSymbol instanceof Variable && ((Variable) tableSymbol).isStorageConstant()) continue;
|
||||
if(tableSymbol instanceof Variable && ((Variable) tableSymbol).isStorageLoadStore()) continue;
|
||||
if(tableSymbol instanceof SymbolVariable && ((SymbolVariable) tableSymbol).isStoragePhiMaster()) continue;
|
||||
if(tableSymbol instanceof SymbolVariable && ((SymbolVariable) tableSymbol).isStorageConstant()) continue;
|
||||
if(tableSymbol instanceof SymbolVariable && ((SymbolVariable) tableSymbol).isStorageLoadStore()) continue;
|
||||
if(tableSymbol instanceof ConstantVar) continue;
|
||||
if(tableSymbol instanceof StructDefinition) continue;
|
||||
if(tableSymbol instanceof EnumDefinition) continue;
|
||||
|
@ -182,7 +182,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
}
|
||||
|
||||
// Look for constants among non-versioned variables
|
||||
for(Variable variable : getScope().getAllVariables(true)) {
|
||||
for(SymbolVariable variable : getScope().getAllVariables(true)) {
|
||||
if(variable.isVolatile() || variable.isDeclaredNotConstant() || !variable.isStorageLoadStore())
|
||||
// Do not examine volatiles, non-constants or versioned variables
|
||||
continue;
|
||||
@ -219,7 +219,7 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
||||
return (ConstantValue) rValue;
|
||||
} else if(rValue instanceof ConstantVar) {
|
||||
ConstantVar constantVar = (ConstantVar) rValue;
|
||||
return constantVar.getRef();
|
||||
return constantVar.getConstantRef();
|
||||
} else if(rValue instanceof CastValue) {
|
||||
CastValue castValue = (CastValue) rValue;
|
||||
ConstantValue castConstant = getConstant(castValue.getValue());
|
||||
|
@ -6,7 +6,7 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
|
||||
@ -86,7 +86,7 @@ public class Pass2ConstantInitializerValueLists extends Pass2SsaOptimization {
|
||||
// Check that type of constant values match the struct member types
|
||||
SymbolTypeStruct declaredStructType = (SymbolTypeStruct) declaredType;
|
||||
StructDefinition structDefinition = declaredStructType.getStructDefinition(getScope());
|
||||
Collection<Variable> memberDefs = structDefinition.getAllVariables(false);
|
||||
Collection<SymbolVariable> memberDefs = structDefinition.getAllVariables(false);
|
||||
if(memberDefs.size()!=constantValues.size()) {
|
||||
throw new CompileError(
|
||||
"Struct initializer has wrong size ("+valueList.getList().size()+"), " +
|
||||
@ -94,10 +94,10 @@ public class Pass2ConstantInitializerValueLists extends Pass2SsaOptimization {
|
||||
" Struct initializer: "+valueList.toString(getProgram()),
|
||||
currentStmt);
|
||||
}
|
||||
Iterator<Variable> memberDefIt = memberDefs.iterator();
|
||||
LinkedHashMap<VariableRef, ConstantValue> memberValues = new LinkedHashMap<>();
|
||||
Iterator<SymbolVariable> memberDefIt = memberDefs.iterator();
|
||||
LinkedHashMap<SymbolVariableRef, ConstantValue> memberValues = new LinkedHashMap<>();
|
||||
for(int i = 0; i < constantValues.size(); i++) {
|
||||
Variable memberDef = memberDefIt.next();
|
||||
SymbolVariable memberDef = memberDefIt.next();
|
||||
SymbolType declaredElementType = memberDef.getType();
|
||||
ConstantValue memberValue = constantValues.get(i);
|
||||
SymbolType elmType = memberValue.getType(getScope());
|
||||
|
@ -3,10 +3,7 @@ package dk.camelot64.kickc.passes;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValue;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.Symbol;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.*;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantArray;
|
||||
import dk.camelot64.kickc.model.values.ConstantRef;
|
||||
@ -96,7 +93,7 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
||||
for(ConstantVar constant : allConstants) {
|
||||
if(constant.getRef().isIntermediate()) {
|
||||
if(!(constant.getType().equals(SymbolType.STRING)) && !(constant.getConstantValue() instanceof ConstantArray)) {
|
||||
unnamed.put(constant.getRef(), constant.getConstantValue());
|
||||
unnamed.put(constant.getConstantRef(), constant.getConstantValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,10 +114,10 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
||||
if(constantValue instanceof ConstantRef) {
|
||||
if(((ConstantRef) constantValue).isIntermediate()) {
|
||||
// The value is an intermediate constant - replace all uses of the intermediate with uses of the referrer instead.
|
||||
aliases.put((ConstantRef) constant.getConstantValue(), constant.getRef());
|
||||
aliases.put((ConstantRef) constant.getConstantValue(), constant.getConstantRef());
|
||||
constant.setConstantValue(programScope.getConstant((ConstantRef) constantValue).getConstantValue());
|
||||
} else {
|
||||
aliases.put(constant.getRef(), constant.getConstantValue());
|
||||
aliases.put(constant.getConstantRef(), constant.getConstantValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,14 +143,14 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
||||
for(Symbol symbol : scopeSymbols) {
|
||||
if(symbol.getRef().isVersion() && symbol.getRef().getFullNameUnversioned().equals(baseName)) {
|
||||
ConstantValue value = constant.getConstantValue();
|
||||
if(symbol instanceof Variable) {
|
||||
aliases.put(constant.getRef(), value);
|
||||
if(symbol instanceof SymbolVariable && ((SymbolVariable) symbol).isVariable()) {
|
||||
aliases.put(constant.getConstantRef(), value);
|
||||
getLog().append("Inlining constant with var siblings " + constant);
|
||||
break;
|
||||
} else if(symbol instanceof ConstantVar) {
|
||||
ConstantValue otherValue = ((ConstantVar) symbol).getConstantValue();
|
||||
if(!otherValue.equals(value) && !(value instanceof ConstantString) && !(value instanceof ConstantArray) && !(otherValue instanceof ConstantRef)) {
|
||||
aliases.put(constant.getRef(), value);
|
||||
aliases.put(constant.getConstantRef(), value);
|
||||
getLog().append("Inlining constant with different constant siblings " + constant);
|
||||
break;
|
||||
}
|
||||
|
@ -6,13 +6,10 @@ import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.values.AssignmentRValue;
|
||||
import dk.camelot64.kickc.model.values.PointerDereferenceIndexed;
|
||||
import dk.camelot64.kickc.model.values.PointerDereferenceSimple;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@ -35,9 +32,9 @@ public class Pass2DeInlineWordDerefIdx extends Pass2SsaOptimization {
|
||||
// Index is multiple bytes - de-inline it
|
||||
getLog().append("De-inlining pointer[w] to *(pointer+w) "+currentStmt.toString(getProgram(), false));
|
||||
Scope currentScope = getScope().getScope(currentBlock.getScope());
|
||||
Variable tmpVar = currentScope.addVariableIntermediate();
|
||||
SymbolVariable tmpVar = currentScope.addVariableIntermediate();
|
||||
stmtIt.previous();
|
||||
StatementAssignment tmpVarAssignment = new StatementAssignment(tmpVar.getRef(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue, currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
StatementAssignment tmpVarAssignment = new StatementAssignment((LValue) tmpVar.getRef(), dereferenceIndexed.getPointer(), Operators.PLUS, indexValue, currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
stmtIt.add(tmpVarAssignment);
|
||||
stmtIt.next();
|
||||
programValue.set(new PointerDereferenceSimple(tmpVar.getRef()));
|
||||
|
@ -11,13 +11,14 @@ import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
import dk.camelot64.kickc.model.values.PointerDereference;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
|
@ -10,11 +10,12 @@ import dk.camelot64.kickc.model.operators.*;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
import dk.camelot64.kickc.model.values.CastValue;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.ValueList;
|
||||
|
||||
@ -82,12 +83,12 @@ public class Pass2FixInlineConstructors extends Pass2SsaOptimization {
|
||||
public void addLiteralWordConstructor(OperatorBinary constructOperator, SymbolType constructType, SymbolType subType, ProgramExpression programExpression, List<RValue> listValues, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
// Convert list to a word constructor in a new tmp variable
|
||||
Scope currentScope = Pass2FixInlineConstructors.this.getScope().getScope(currentBlock.getScope());
|
||||
Variable tmpVar = currentScope.addVariableIntermediate();
|
||||
SymbolVariable tmpVar = currentScope.addVariableIntermediate();
|
||||
//tmpVar.setTypeInferred(constructType);
|
||||
// Move backward - to insert before the current statement
|
||||
stmtIt.previous();
|
||||
// Add assignment of the new tmpVar
|
||||
StatementAssignment assignment = new StatementAssignment(tmpVar.getRef(), new CastValue(subType, listValues.get(0)), constructOperator, new CastValue(subType, listValues.get(1)), currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
StatementAssignment assignment = new StatementAssignment((LValue) tmpVar.getRef(), new CastValue(subType, listValues.get(0)), constructOperator, new CastValue(subType, listValues.get(1)), currentStmt.getSource(), Comment.NO_COMMENTS);
|
||||
stmtIt.add(assignment);
|
||||
// Move back before the current statement
|
||||
stmtIt.next();
|
||||
|
@ -6,8 +6,10 @@ import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.PointerDereference;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.passes.utils.Unroller;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -8,13 +8,10 @@ import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
import java.util.ListIterator;
|
||||
|
||||
@ -74,14 +71,14 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization {
|
||||
long powVal = 1L <<pow2;
|
||||
if(remains>=powVal) {
|
||||
// First add shifts
|
||||
Variable varShift = scope.addVariableIntermediate();
|
||||
SymbolVariable varShift = scope.addVariableIntermediate();
|
||||
varShift.setType(resultType);
|
||||
stmtIt.add(new StatementAssignment(varShift.getRef(), building, Operators.SHIFT_LEFT, new ConstantInteger(shiftCount, SymbolType.BYTE), assignment.getSource(), Comment.NO_COMMENTS));
|
||||
stmtIt.add(new StatementAssignment((LValue) varShift.getRef(), building, Operators.SHIFT_LEFT, new ConstantInteger(shiftCount, SymbolType.BYTE), assignment.getSource(), Comment.NO_COMMENTS));
|
||||
shiftCount = 0;
|
||||
// Then add rvalue1
|
||||
Variable varAdd = scope.addVariableIntermediate();
|
||||
SymbolVariable varAdd = scope.addVariableIntermediate();
|
||||
varAdd.setType(resultType);
|
||||
stmtIt.add(new StatementAssignment(varAdd.getRef(), varShift.getRef(), Operators.PLUS, assignment.getrValue1(), assignment.getSource(), Comment.NO_COMMENTS));
|
||||
stmtIt.add(new StatementAssignment((LValue) varAdd.getRef(), varShift.getRef(), Operators.PLUS, assignment.getrValue1(), assignment.getSource(), Comment.NO_COMMENTS));
|
||||
building = varAdd.getRef();
|
||||
remains -= powVal;
|
||||
}
|
||||
@ -93,9 +90,9 @@ public class Pass2MultiplyToShiftRewriting extends Pass2SsaOptimization {
|
||||
}
|
||||
// add remaining shifts
|
||||
if(shiftCount>0) {
|
||||
Variable varShift = scope.addVariableIntermediate();
|
||||
SymbolVariable varShift = scope.addVariableIntermediate();
|
||||
varShift.setType(resultType);
|
||||
stmtIt.add(new StatementAssignment(varShift.getRef(), building, Operators.SHIFT_LEFT, new ConstantInteger(shiftCount, SymbolType.BYTE), assignment.getSource(), Comment.NO_COMMENTS));
|
||||
stmtIt.add(new StatementAssignment((LValue) varShift.getRef(), building, Operators.SHIFT_LEFT, new ConstantInteger(shiftCount, SymbolType.BYTE), assignment.getSource(), Comment.NO_COMMENTS));
|
||||
building = varShift.getRef();
|
||||
}
|
||||
stmtIt.next();
|
||||
|
@ -5,7 +5,6 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
|
@ -7,6 +7,7 @@ import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.*;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
|
||||
import java.util.*;
|
||||
@ -46,7 +47,7 @@ public class Pass3PhiLifting {
|
||||
LabelRef predecessorRef = phiRValue.getPredecessor();
|
||||
ControlFlowBlock predecessorBlock = graph.getBlock(predecessorRef);
|
||||
//VariableRef rValVarRef = (VariableRef) phiRValue.getrValue();
|
||||
Variable newVar;
|
||||
SymbolVariable newVar;
|
||||
if(phiVariable.getVariable().isVersion()) {
|
||||
SymbolVariable lValVar = program.getScope().getVariable(phiVariable.getVariable());
|
||||
newVar = lValVar.getVersionOf().createVersion();
|
||||
@ -62,7 +63,7 @@ public class Pass3PhiLifting {
|
||||
if(predecessorStatements.size() > 0) {
|
||||
lastPredecessorStatement = predecessorStatements.get(predecessorStatements.size() - 1);
|
||||
}
|
||||
StatementAssignment newAssignment = new StatementAssignment(newVar.getRef(), phiRValue.getrValue(), phiBlock.getSource(), Comment.NO_COMMENTS);
|
||||
StatementAssignment newAssignment = new StatementAssignment((LValue) newVar.getRef(), phiRValue.getrValue(), phiBlock.getSource(), Comment.NO_COMMENTS);
|
||||
if(lastPredecessorStatement instanceof StatementConditionalJump) {
|
||||
// Use or Create a new block between the predecessor and this one - replace labels where appropriate
|
||||
ControlFlowBlock newBlock;
|
||||
|
@ -7,7 +7,6 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementPhiBlock;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.values.ConstantValue;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
@ -1,14 +1,14 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.asm.AsmChunk;
|
||||
import dk.camelot64.kickc.asm.AsmClobber;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.asm.AsmChunk;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.LabelRef;
|
||||
import dk.camelot64.kickc.model.values.RValue;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -100,7 +100,7 @@ public class Pass4AssertNoCpuClobber extends Pass2Base {
|
||||
|
||||
// Non-assigned alive variables must not be clobbered
|
||||
for(VariableRef aliveVar : aliveVars) {
|
||||
Variable variable = getProgram().getSymbolInfos().getVariable(aliveVar);
|
||||
SymbolVariable variable = getProgram().getSymbolInfos().getVariable(aliveVar);
|
||||
Registers.Register aliveVarRegister = variable.getAllocation();
|
||||
if(aliveVarRegister.isMem()) {
|
||||
// No need to check a zp-register - here we are only interested in CPU registers
|
||||
|
@ -3,7 +3,7 @@ package dk.camelot64.kickc.passes;
|
||||
import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.Registers;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@ -18,8 +18,8 @@ public class Pass4AssertZeropageAllocation extends Pass2Base {
|
||||
* Check that all variables fit onto zeropage
|
||||
*/
|
||||
public void check() {
|
||||
Collection<Variable> allVariables = getSymbols().getAllVariables(true);
|
||||
for(Variable variable : allVariables) {
|
||||
Collection<SymbolVariable> allVariables = getSymbols().getAllVariables(true);
|
||||
for(SymbolVariable variable : allVariables) {
|
||||
Registers.Register allocation = variable.getAllocation();
|
||||
if(allocation != null && Registers.RegisterType.ZP_MEM.equals(allocation.getType())) {
|
||||
int zp = ((Registers.RegisterZpMem) allocation).getZp();
|
||||
|
@ -327,7 +327,7 @@ public class Pass4CodeGeneration {
|
||||
*/
|
||||
private boolean useLabelForConst(ScopeRef scopeRef, ConstantVar constantVar) {
|
||||
boolean useLabel = false;
|
||||
Collection<Integer> constRefStatements = program.getVariableReferenceInfos().getConstRefStatements(constantVar.getRef());
|
||||
Collection<Integer> constRefStatements = program.getVariableReferenceInfos().getConstRefStatements(constantVar.getConstantRef());
|
||||
if(constRefStatements != null) {
|
||||
for(Integer constRefStmtIdx : constRefStatements) {
|
||||
Statement statement = program.getStatementInfos().getStatement(constRefStmtIdx);
|
||||
@ -365,7 +365,7 @@ public class Pass4CodeGeneration {
|
||||
}
|
||||
}
|
||||
}
|
||||
Collection<SymbolVariableRef> symbolRefConsts = program.getVariableReferenceInfos().getSymbolRefConsts(constantVar.getRef());
|
||||
Collection<SymbolVariableRef> symbolRefConsts = program.getVariableReferenceInfos().getSymbolRefConsts(constantVar.getConstantRef());
|
||||
if(symbolRefConsts != null) {
|
||||
for(SymbolVariableRef symbolRefConst : symbolRefConsts) {
|
||||
SymbolVariable symbolRefVar = (SymbolVariable) program.getScope().getSymbol(symbolRefConst);
|
||||
@ -424,8 +424,8 @@ public class Pass4CodeGeneration {
|
||||
}
|
||||
|
||||
// Add labels for memory variables without data
|
||||
Collection<Variable> scopeVars = scope.getAllVariables(false);
|
||||
for(Variable scopeVar : scopeVars) {
|
||||
Collection<SymbolVariable> scopeVars = scope.getAllVariables(false);
|
||||
for(SymbolVariable scopeVar : scopeVars) {
|
||||
Registers.Register register = scopeVar.getAllocation();
|
||||
if(register != null) {
|
||||
if(Registers.RegisterType.ZP_MEM.equals(register.getType())) {
|
||||
@ -494,8 +494,8 @@ public class Pass4CodeGeneration {
|
||||
}
|
||||
}
|
||||
// Add all memory variables
|
||||
Collection<Variable> scopeVariables = scope.getAllVariables(false);
|
||||
for(Variable variable : scopeVariables) {
|
||||
Collection<SymbolVariable> scopeVariables = scope.getAllVariables(false);
|
||||
for(SymbolVariable variable : scopeVariables) {
|
||||
if(variable.isMemoryAreaMain()) {
|
||||
// Skip PHI masters
|
||||
if(variable.isStoragePhiMaster())
|
||||
@ -573,7 +573,7 @@ public class Pass4CodeGeneration {
|
||||
if(valueType instanceof SymbolTypeStruct) {
|
||||
// Add each struct member recursively
|
||||
ConstantStructValue structValue = (ConstantStructValue) value;
|
||||
for(VariableRef memberRef : structValue.getMembers()) {
|
||||
for(SymbolVariableRef memberRef : structValue.getMembers()) {
|
||||
ConstantValue memberValue = structValue.getValue(memberRef);
|
||||
SymbolVariable memberVariable = getScope().getVariable(memberRef);
|
||||
addChunkData(dataChunk, memberValue, memberVariable.getType(), scopeRef);
|
||||
|
@ -1,11 +1,11 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||
import dk.camelot64.kickc.model.statements.StatementCallFinalize;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -32,15 +32,15 @@ public class Pass4LiveRangeEquivalenceClassesFinalize extends Pass2Base {
|
||||
|
||||
|
||||
// Add all versions of volatile variables to the same equivalence class
|
||||
for(Variable variable : getSymbols().getAllVariables(true)) {
|
||||
for(SymbolVariable variable : getSymbols().getAllVariables(true)) {
|
||||
if(variable.isStoragePhiVersion() && variable.isVolatile()) {
|
||||
// Found a volatile non-versioned variable
|
||||
for(Variable otherVariable : variable.getScope().getAllVariables(false)) {
|
||||
for(SymbolVariable otherVariable : variable.getScope().getAllVariables(false)) {
|
||||
if(otherVariable.isStoragePhiVersion()) {
|
||||
if((otherVariable).getVersionOf().equals((variable).getVersionOf())) {
|
||||
// They share the same main variable
|
||||
LiveRangeEquivalenceClass varEC = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass(variable.getRef());
|
||||
LiveRangeEquivalenceClass otherEC = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass(otherVariable.getRef());
|
||||
LiveRangeEquivalenceClass varEC = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass((VariableRef) variable.getRef());
|
||||
LiveRangeEquivalenceClass otherEC = liveRangeEquivalenceClassSet.getOrCreateEquivalenceClass((VariableRef) otherVariable.getRef());
|
||||
if(!varEC.equals(otherEC)) {
|
||||
getLog().append("Coalescing volatile variable equivalence classes " + varEC.toString() + " and " + otherEC.toString());
|
||||
liveRangeEquivalenceClassSet.consolidate(varEC, otherEC);
|
||||
@ -115,8 +115,8 @@ public class Pass4LiveRangeEquivalenceClassesFinalize extends Pass2Base {
|
||||
for(VariableRef preference : preferences) {
|
||||
LiveRangeEquivalenceClass preferenceEquivalenceClass = liveRangeEquivalenceClassSet.getEquivalenceClass(preference);
|
||||
if(preferenceEquivalenceClass != null) {
|
||||
Variable potentialVariable = getProgram().getSymbolInfos().getVariable(preference);
|
||||
Variable lValVariable = getProgram().getSymbolInfos().getVariable(lValVar);
|
||||
SymbolVariable potentialVariable = getProgram().getSymbolInfos().getVariable(preference);
|
||||
SymbolVariable lValVariable = getProgram().getSymbolInfos().getVariable(lValVar);
|
||||
if(lValVariable.getType().equals(potentialVariable.getType())) {
|
||||
if(!lValLiveRange.overlaps(preferenceEquivalenceClass.getLiveRange())) {
|
||||
chosen = preferenceEquivalenceClass;
|
||||
|
@ -3,7 +3,6 @@ package dk.camelot64.kickc.passes;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.ProcedureRef;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
import dk.camelot64.kickc.model.values.SymbolRef;
|
||||
|
@ -1,14 +1,14 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.asm.AsmChunk;
|
||||
import dk.camelot64.kickc.asm.AsmProgram;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentInstance;
|
||||
import dk.camelot64.kickc.fragment.AsmFragmentTemplateSynthesizer;
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.values.ScopeRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -204,7 +204,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
||||
Collection<VariableRef> alive = aliveCombinations.getEffectiveAliveAtStmt(callPath);
|
||||
Pass2AliasElimination.Aliases callPathAliases = aliveCombinations.getEffectiveAliasesAtStmt(callPath);
|
||||
for(VariableRef varRef : alive) {
|
||||
Variable var = program.getSymbolInfos().getVariable(varRef);
|
||||
SymbolVariable var = program.getSymbolInfos().getVariable(varRef);
|
||||
Registers.Register allocation = var.getAllocation();
|
||||
LiveRangeEquivalenceClass allocationClass = usedRegisters.get(allocation);
|
||||
if(allocationClass != null && !allocationClass.contains(varRef)) {
|
||||
|
@ -2,7 +2,6 @@ package dk.camelot64.kickc.passes;
|
||||
|
||||
import dk.camelot64.kickc.model.*;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -36,7 +36,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
}
|
||||
}
|
||||
// Add all ZP's declared hardcoded register for a live variable
|
||||
for(Variable variable : getSymbols().getAllVariables(true)) {
|
||||
for(SymbolVariable variable : getSymbols().getAllVariables(true)) {
|
||||
if(variable.getDeclaredRegister() instanceof Registers.RegisterZpMem) {
|
||||
int zp = ((Registers.RegisterZpMem) variable.getDeclaredRegister()).getZp();
|
||||
int sizeBytes = variable.getType().getSizeBytes();
|
||||
@ -95,7 +95,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
allScopes.add(getProgram().getScope());
|
||||
for(Scope scope : allScopes) {
|
||||
// Create initial short names
|
||||
for(Variable variable : scope.getAllVariables(false)) {
|
||||
for(SymbolVariable variable : scope.getAllVariables(false)) {
|
||||
if(variable.getAllocation() != null && variable.getAllocation().isMem()) {
|
||||
variable.setAsmName(variable.getLocalName());
|
||||
} else {
|
||||
@ -109,7 +109,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
// Maps short name to the allocated register.
|
||||
Map<String, Registers.Register> shortNames = new LinkedHashMap<>();
|
||||
// Shorten variable and constant names
|
||||
for(Variable variable : scope.getAllVariables(false)) {
|
||||
for(SymbolVariable variable : scope.getAllVariables(false)) {
|
||||
Registers.Register allocation = variable.getAllocation();
|
||||
if(allocation != null && allocation.isMem()) {
|
||||
shortenAsmName(shortNames, variable, allocation);
|
||||
@ -170,7 +170,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
if(reallocate) {
|
||||
String before = register == null ? null : register.toString();
|
||||
VariableRef variableRef = equivalenceClass.getVariables().get(0);
|
||||
Variable variable = getProgram().getSymbolInfos().getVariable(variableRef);
|
||||
SymbolVariable variable = getProgram().getSymbolInfos().getVariable(variableRef);
|
||||
if(variable.isMemoryAreaMain()) {
|
||||
register = new Registers.RegisterMainMem(variableRef, variable.getType().getSizeBytes(), null);
|
||||
} else {
|
||||
@ -217,7 +217,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
||||
* The register type created uses one or more zero page locations based on the variable type
|
||||
* @return The new zeropage register
|
||||
*/
|
||||
private Registers.Register allocateNewRegisterZp(Variable variable) {
|
||||
private Registers.Register allocateNewRegisterZp(SymbolVariable variable) {
|
||||
SymbolType varType = variable.getType();
|
||||
if(SymbolType.BYTE.equals(varType)) {
|
||||
return new Registers.RegisterZpMem(allocateZp(1), 1);
|
||||
|
@ -10,7 +10,7 @@ import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||
import dk.camelot64.kickc.model.statements.StatementConditionalJump;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||
@ -41,7 +41,7 @@ public class PassNAddBooleanCasts extends Pass2SsaOptimization {
|
||||
if(SymbolType.isInteger(type) || type instanceof SymbolTypePointer) {
|
||||
// Found integer condition - add boolean cast
|
||||
getLog().append("Warning! Adding boolean cast to non-boolean condition "+rValue2.toString(getProgram()));
|
||||
Variable tmpVar = addBooleanCast(rValue2, type, currentStmt, stmtIt, currentBlock);
|
||||
SymbolVariable tmpVar = addBooleanCast(rValue2, type, currentStmt, stmtIt, currentBlock);
|
||||
conditionalJump.setrValue2(tmpVar.getRef());
|
||||
}
|
||||
}
|
||||
@ -59,7 +59,7 @@ public class PassNAddBooleanCasts extends Pass2SsaOptimization {
|
||||
unaryExpression.setOperand(new ConstantBinary(new ConstantInteger(0L, SymbolType.NUMBER), Operators.NEQ, (ConstantValue) operand));
|
||||
} else {
|
||||
SymbolType type = SymbolTypeInference.inferType(getScope(), operand);
|
||||
Variable tmpVar = addBooleanCast(operand, type, currentStmt, stmtIt, currentBlock);
|
||||
SymbolVariable tmpVar = addBooleanCast(operand, type, currentStmt, stmtIt, currentBlock);
|
||||
unaryExpression.setOperand(tmpVar.getRef());
|
||||
}
|
||||
}
|
||||
@ -68,10 +68,10 @@ public class PassNAddBooleanCasts extends Pass2SsaOptimization {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Variable addBooleanCast(RValue rValue, SymbolType rValueType, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
public SymbolVariable addBooleanCast(RValue rValue, SymbolType rValueType, Statement currentStmt, ListIterator<Statement> stmtIt, ControlFlowBlock currentBlock) {
|
||||
Scope currentScope = getScope().getScope(currentBlock.getScope());
|
||||
stmtIt.previous();
|
||||
Variable tmpVar = currentScope.addVariableIntermediate();
|
||||
SymbolVariable tmpVar = currentScope.addVariableIntermediate();
|
||||
tmpVar.setTypeInferred(SymbolType.BOOLEAN);
|
||||
// Go straight to xxx!=0 instead of casting to bool
|
||||
ConstantValue nullValue;
|
||||
@ -80,7 +80,7 @@ public class PassNAddBooleanCasts extends Pass2SsaOptimization {
|
||||
} else {
|
||||
nullValue = new ConstantInteger(0L, SymbolType.NUMBER);
|
||||
}
|
||||
stmtIt.add(new StatementAssignment(tmpVar.getRef(), nullValue, Operators.NEQ, rValue, currentStmt.getSource(), Comment.NO_COMMENTS));
|
||||
stmtIt.add(new StatementAssignment((LValue) tmpVar.getRef(), nullValue, Operators.NEQ, rValue, currentStmt.getSource(), Comment.NO_COMMENTS));
|
||||
stmtIt.next();
|
||||
return tmpVar;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import dk.camelot64.kickc.model.iterator.ProgramValue;
|
||||
import dk.camelot64.kickc.model.operators.Operators;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.*;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
|
||||
@ -74,7 +74,7 @@ public class PassNAddInitializerValueListTypeCasts extends Pass2SsaOptimization
|
||||
SymbolTypeStruct declaredStructType = (SymbolTypeStruct) declaredType;
|
||||
// Recursively cast all sub-elements
|
||||
StructDefinition structDefinition = declaredStructType.getStructDefinition(getScope());
|
||||
Collection<Variable> memberDefinitions = structDefinition.getAllVariables(false);
|
||||
Collection<SymbolVariable> memberDefinitions = structDefinition.getAllVariables(false);
|
||||
int size = memberDefinitions.size();
|
||||
if(size!=valueList.getList().size()) {
|
||||
throw new CompileError(
|
||||
@ -83,9 +83,9 @@ public class PassNAddInitializerValueListTypeCasts extends Pass2SsaOptimization
|
||||
" Struct initializer: "+valueList.toString(getProgram()),
|
||||
currentStmt);
|
||||
}
|
||||
Iterator<Variable> memberDefIt = memberDefinitions.iterator();
|
||||
Iterator<SymbolVariable> memberDefIt = memberDefinitions.iterator();
|
||||
for(int i = 0; i < size; i++) {
|
||||
Variable memberDef = memberDefIt.next();
|
||||
SymbolVariable memberDef = memberDefIt.next();
|
||||
exprModified |= addValueCasts(memberDef.getType(), new ProgramValue.ProgramValueListElement(valueList, i), currentStmt);
|
||||
}
|
||||
// Add a cast to the value list itself
|
||||
|
@ -6,7 +6,6 @@ import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.statements.Statement;
|
||||
import dk.camelot64.kickc.model.statements.StatementLValue;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
import dk.camelot64.kickc.model.values.SymbolVariableRef;
|
||||
import dk.camelot64.kickc.model.values.VariableRef;
|
||||
|
@ -4,7 +4,7 @@ import dk.camelot64.kickc.model.CompileError;
|
||||
import dk.camelot64.kickc.model.Program;
|
||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||
import dk.camelot64.kickc.model.symbols.StructDefinition;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.types.SymbolType;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeInference;
|
||||
import dk.camelot64.kickc.model.types.SymbolTypeStruct;
|
||||
@ -28,7 +28,7 @@ public class PassNAssertStructMembers extends Pass2SsaOptimization {
|
||||
if(type instanceof SymbolTypeStruct) {
|
||||
SymbolTypeStruct structType = (SymbolTypeStruct) type;
|
||||
StructDefinition structDefinition = structType.getStructDefinition(getScope());
|
||||
Variable member = structDefinition.getMember(structMemberRef.getMemberName());
|
||||
SymbolVariable member = structDefinition.getMember(structMemberRef.getMemberName());
|
||||
if(member==null) {
|
||||
throw new CompileError("Unknown struct member "+structMemberRef.getMemberName()+" in struct "+structType.getTypeName(), currentStmt);
|
||||
}
|
||||
|
@ -44,11 +44,11 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
|
||||
CastValue structTypedPointer = new CastValue(memberType, structPointer);
|
||||
// Create temporary variable to hold pointer to member ($1)
|
||||
Scope scope = getScope().getScope(currentBlock.getScope());
|
||||
Variable memberAddress1 = scope.addVariableIntermediate();
|
||||
SymbolVariable memberAddress1 = scope.addVariableIntermediate();
|
||||
memberAddress1.setType(memberType);
|
||||
// Add statement $1 = ptr_struct + OFFSET_STRUCT_NAME_MEMBER
|
||||
stmtIt.previous();
|
||||
stmtIt.add(new StatementAssignment(memberAddress1.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.add(new StatementAssignment((LValue) memberAddress1.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.next();
|
||||
// Replace (*ptr_struct).x with *($1)
|
||||
programValue.set(memberAddress1.getRef());
|
||||
@ -57,11 +57,11 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
|
||||
CastValue structTypedPointer = new CastValue(new SymbolTypePointer(memberType), structPointer);
|
||||
// Create temporary variable to hold pointer to member ($1)
|
||||
Scope scope = getScope().getScope(currentBlock.getScope());
|
||||
Variable memberAddress = scope.addVariableIntermediate();
|
||||
SymbolVariable memberAddress = scope.addVariableIntermediate();
|
||||
memberAddress.setType(new SymbolTypePointer(memberType));
|
||||
// Add statement $1 = ptr_struct + OFFSET_STRUCT_NAME_MEMBER
|
||||
stmtIt.previous();
|
||||
stmtIt.add(new StatementAssignment(memberAddress.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.add(new StatementAssignment((LValue) memberAddress.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.next();
|
||||
// Replace (*ptr_struct).x with *($1)
|
||||
programValue.set(new PointerDereferenceSimple(memberAddress.getRef()));
|
||||
@ -83,14 +83,14 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
|
||||
CastValue structTypedPointer = new CastValue(memberType, structPointer);
|
||||
// Create temporary variable to hold pointer to member ($1)
|
||||
Scope scope = getScope().getScope(currentBlock.getScope());
|
||||
Variable memberAddress1 = scope.addVariableIntermediate();
|
||||
SymbolVariable memberAddress1 = scope.addVariableIntermediate();
|
||||
memberAddress1.setType(memberType);
|
||||
Variable memberAddress2 = scope.addVariableIntermediate();
|
||||
SymbolVariable memberAddress2 = scope.addVariableIntermediate();
|
||||
memberAddress2.setType(memberType);
|
||||
// Add statement $1 = ptr_struct + OFFSET_STRUCT_NAME_MEMBER
|
||||
stmtIt.previous();
|
||||
stmtIt.add(new StatementAssignment(memberAddress1.getRef(), structTypedPointer, Operators.PLUS, ((PointerDereferenceIndexed) struct).getIndex(), currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.add(new StatementAssignment(memberAddress2.getRef(), memberAddress1.getRef(), Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.add(new StatementAssignment((LValue) memberAddress1.getRef(), structTypedPointer, Operators.PLUS, ((PointerDereferenceIndexed) struct).getIndex(), currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.add(new StatementAssignment((LValue) memberAddress2.getRef(), memberAddress1.getRef(), Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.next();
|
||||
// Replace ptr_struct[idx].x with ($1)[idx]
|
||||
programValue.set(memberAddress2.getRef());
|
||||
@ -100,11 +100,11 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
|
||||
CastValue structTypedPointer = new CastValue(new SymbolTypePointer(memberType), structPointer);
|
||||
// Create temporary variable to hold pointer to member ($1)
|
||||
Scope scope = getScope().getScope(currentBlock.getScope());
|
||||
Variable memberAddress = scope.addVariableIntermediate();
|
||||
SymbolVariable memberAddress = scope.addVariableIntermediate();
|
||||
memberAddress.setType(new SymbolTypePointer(memberType));
|
||||
// Add statement $1 = ptr_struct + OFFSET_STRUCT_NAME_MEMBER
|
||||
stmtIt.previous();
|
||||
stmtIt.add(new StatementAssignment(memberAddress.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.add(new StatementAssignment((LValue) memberAddress.getRef(), structTypedPointer, Operators.PLUS, memberOffsetConstant, currentStmt.getSource(), currentStmt.getComments()));
|
||||
stmtIt.next();
|
||||
// Replace ptr_struct[idx].x with ($1)[idx]
|
||||
programValue.set(new PointerDereferenceIndexed(memberAddress.getRef(), ((PointerDereferenceIndexed) struct).getIndex()));
|
||||
@ -129,12 +129,12 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
|
||||
ConstantVar memberOffsetConstant = programScope.getConstant(typeConstName);
|
||||
if(memberOffsetConstant == null) {
|
||||
// Constant not found - create it
|
||||
Variable memberDef = structDefinition.getMember(memberName);
|
||||
SymbolVariable memberDef = structDefinition.getMember(memberName);
|
||||
long memberByteOffset = structDefinition.getMemberByteOffset(memberDef, programScope);
|
||||
memberOffsetConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
||||
programScope.add(memberOffsetConstant);
|
||||
}
|
||||
return memberOffsetConstant.getRef();
|
||||
return memberOffsetConstant.getConstantRef();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,7 +7,6 @@ import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.Procedure;
|
||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.types.*;
|
||||
import dk.camelot64.kickc.model.values.AssignmentRValue;
|
||||
import dk.camelot64.kickc.model.values.LValue;
|
||||
|
@ -7,7 +7,6 @@ import dk.camelot64.kickc.model.statements.*;
|
||||
import dk.camelot64.kickc.model.symbols.Label;
|
||||
import dk.camelot64.kickc.model.symbols.Scope;
|
||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||
import dk.camelot64.kickc.model.symbols.Variable;
|
||||
import dk.camelot64.kickc.model.values.*;
|
||||
import dk.camelot64.kickc.passes.Pass1GenerateSingleStaticAssignmentForm;
|
||||
import dk.camelot64.kickc.passes.calcs.PassNCalcVariableReferenceInfos;
|
||||
@ -43,7 +42,7 @@ public class Unroller {
|
||||
/** The strategy used for rewriting transitions into the block / inside the block. */
|
||||
private UnrollStrategy strategy;
|
||||
/** Maps variables defined in the original block to the copies of these variables defined in the new block. */
|
||||
private Map<VariableRef, VariableRef> varsOriginalToCopied;
|
||||
private Map<SymbolVariableRef, SymbolVariableRef> varsOriginalToCopied;
|
||||
/** Maps labels of blocks in the original block to the labels of the copied blocks. */
|
||||
private Map<LabelRef, LabelRef> blocksOriginalToCopied;
|
||||
|
||||
@ -76,12 +75,12 @@ public class Unroller {
|
||||
*/
|
||||
private void prepare() {
|
||||
// TODO Handle variables modified inside called functions!
|
||||
for(VariableRef origVarRef : getVarsDefinedIn(unrollBlocks, program)) {
|
||||
for(SymbolVariableRef origVarRef : getVarsDefinedIn(unrollBlocks, program)) {
|
||||
// Find out if the variable is ever referenced outside the loop
|
||||
if(isReferencedOutside(origVarRef, unrollBlocks, program)) {
|
||||
// Re-version all usages of the specific variable version
|
||||
Map<LabelRef, VariableRef> newPhis = new LinkedHashMap<>();
|
||||
Map<LabelRef, VariableRef> varVersions = new LinkedHashMap<>();
|
||||
Map<LabelRef, SymbolVariableRef> newPhis = new LinkedHashMap<>();
|
||||
Map<LabelRef, SymbolVariableRef> varVersions = new LinkedHashMap<>();
|
||||
reVersionAllUsages(origVarRef, newPhis, varVersions);
|
||||
if(program.getLog().isVerboseLoopUnroll()) {
|
||||
program.getLog().append("Created new versions for " + origVarRef + ")");
|
||||
@ -100,7 +99,7 @@ public class Unroller {
|
||||
* @param newPhis Map that will be populated with all new (empty) PHI-variables for the new versionw - these will be populated later.
|
||||
* @param varVersions Map that will be populated with the version of the origVariable at the end of each block where it has a defined version.
|
||||
*/
|
||||
private void reVersionAllUsages(VariableRef origVarRef, Map<LabelRef, VariableRef> newPhis, Map<LabelRef, VariableRef> varVersions) {
|
||||
private void reVersionAllUsages(SymbolVariableRef origVarRef, Map<LabelRef, SymbolVariableRef> newPhis, Map<LabelRef, SymbolVariableRef> varVersions) {
|
||||
|
||||
// First add the definition of origVar to varVersions
|
||||
for(ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||
@ -113,7 +112,7 @@ public class Unroller {
|
||||
}
|
||||
// Next iterate the entire graph ensuring that all usages create new versions (except usages right after the definition)
|
||||
for(ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||
AtomicReference<VariableRef> currentVersion = new AtomicReference<>();
|
||||
AtomicReference<SymbolVariableRef> currentVersion = new AtomicReference<>();
|
||||
// Set current version from map
|
||||
currentVersion.set(varVersions.get(block.getLabel()));
|
||||
for(Statement statement : block.getStatements()) {
|
||||
@ -132,7 +131,7 @@ public class Unroller {
|
||||
} else if(statement instanceof StatementPhiBlock && programValue instanceof ProgramValue.PhiValue) {
|
||||
// The reference is inside a PHI-value - we need a version in the predecessor
|
||||
LabelRef predecessor = ((ProgramValue.PhiValue) programValue).getPredecessor();
|
||||
VariableRef predecessorVersion = varVersions.get(predecessor);
|
||||
SymbolVariableRef predecessorVersion = varVersions.get(predecessor);
|
||||
if(predecessorVersion == null) {
|
||||
// Add a new PHI to the predecessor
|
||||
predecessorVersion = createNewVersion(origVarRef);
|
||||
@ -143,7 +142,7 @@ public class Unroller {
|
||||
programValue.set(predecessorVersion);
|
||||
} else if(currentVersion.get() == null) {
|
||||
// Found a reference - no definition - create a new version
|
||||
VariableRef newVarRef = createNewVersion(origVarRef);
|
||||
SymbolVariableRef newVarRef = createNewVersion(origVarRef);
|
||||
currentVersion.set(newVarRef);
|
||||
varVersions.put(block.getLabel(), newVarRef);
|
||||
newPhis.put(block.getLabel(), currentVersion.get());
|
||||
@ -159,8 +158,8 @@ public class Unroller {
|
||||
// Add the new empty PHI-blocks()
|
||||
for(LabelRef blockRef : newPhis.keySet()) {
|
||||
ControlFlowBlock block = program.getGraph().getBlock(blockRef);
|
||||
VariableRef newVersion = newPhis.get(blockRef);
|
||||
block.getPhiBlock().addPhiVariable(newVersion);
|
||||
SymbolVariableRef newVersion = newPhis.get(blockRef);
|
||||
block.getPhiBlock().addPhiVariable((VariableRef) newVersion);
|
||||
}
|
||||
|
||||
}
|
||||
@ -170,10 +169,10 @@ public class Unroller {
|
||||
* @param origVarRef The original variable
|
||||
* @return The new version
|
||||
*/
|
||||
private VariableRef createNewVersion(VariableRef origVarRef) {
|
||||
private SymbolVariableRef createNewVersion(SymbolVariableRef origVarRef) {
|
||||
SymbolVariable origVar = program.getScope().getVariable(origVarRef);
|
||||
Scope scope = origVar.getScope();
|
||||
VariableRef newVarRef;
|
||||
SymbolVariableRef newVarRef;
|
||||
if(origVarRef.isIntermediate()) {
|
||||
newVarRef = scope.addVariableIntermediate().getRef();
|
||||
} else {
|
||||
@ -189,22 +188,22 @@ public class Unroller {
|
||||
* @param newPhis New (empty) PHI-variables for the new versions that need to be populated
|
||||
* @param varVersions Map with the version of the origVariable at the end of each block where it has a defined version.
|
||||
*/
|
||||
private void completePhiFunctions(Map<LabelRef, VariableRef> newPhis, Map<LabelRef, VariableRef> varVersions) {
|
||||
Map<LabelRef, VariableRef> todo = newPhis;
|
||||
private void completePhiFunctions(Map<LabelRef, SymbolVariableRef> newPhis, Map<LabelRef, SymbolVariableRef> varVersions) {
|
||||
Map<LabelRef, SymbolVariableRef> todo = newPhis;
|
||||
while(todo.size() > 0) {
|
||||
Map<LabelRef, VariableRef> doing = todo;
|
||||
Map<LabelRef, SymbolVariableRef> doing = todo;
|
||||
todo = new LinkedHashMap<>();
|
||||
for(LabelRef blockRef : doing.keySet()) {
|
||||
VariableRef doingVarRef = doing.get(blockRef);
|
||||
SymbolVariableRef doingVarRef = doing.get(blockRef);
|
||||
ControlFlowBlock block = program.getGraph().getBlock(blockRef);
|
||||
StatementPhiBlock.PhiVariable doingPhiVariable = block.getPhiBlock().getPhiVariable(doingVarRef);
|
||||
StatementPhiBlock.PhiVariable doingPhiVariable = block.getPhiBlock().getPhiVariable((VariableRef) doingVarRef);
|
||||
List<ControlFlowBlock> predecessors = Pass1GenerateSingleStaticAssignmentForm.getPhiPredecessors(block, program);
|
||||
for(ControlFlowBlock predecessor : predecessors) {
|
||||
VariableRef predecessorVarRef = varVersions.get(predecessor.getLabel());
|
||||
SymbolVariableRef predecessorVarRef = varVersions.get(predecessor.getLabel());
|
||||
if(predecessorVarRef == null) {
|
||||
// Variable has no version in the predecessor block - add a new PHI and populate later!
|
||||
VariableRef newVarRef = createNewVersion(doingVarRef);
|
||||
predecessor.getPhiBlock().addPhiVariable(newVarRef);
|
||||
SymbolVariableRef newVarRef = createNewVersion(doingVarRef);
|
||||
predecessor.getPhiBlock().addPhiVariable((VariableRef) newVarRef);
|
||||
//program.getLog().append("Adding PHI for "+newVarRef+" to "+predecessor.getLabel());
|
||||
varVersions.put(predecessor.getLabel(), newVarRef);
|
||||
todo.put(predecessor.getLabel(), newVarRef);
|
||||
@ -224,11 +223,11 @@ public class Unroller {
|
||||
* @param unrollBlocks The blocks being unrolled
|
||||
* @return A map from variables assigned inside the unroll blocks to the new copy of the variable
|
||||
*/
|
||||
private static Map<VariableRef, VariableRef> copyDefinedVars(BlockSet unrollBlocks, Program program) {
|
||||
Map<VariableRef, VariableRef> definedToNewVar = new LinkedHashMap<>();
|
||||
private static Map<SymbolVariableRef, SymbolVariableRef> copyDefinedVars(BlockSet unrollBlocks, Program program) {
|
||||
Map<SymbolVariableRef, SymbolVariableRef> definedToNewVar = new LinkedHashMap<>();
|
||||
for(VariableRef definedVarRef : getVarsDefinedIn(unrollBlocks, program)) {
|
||||
SymbolVariable definedVar = program.getScope().getVariable(definedVarRef);
|
||||
Variable newVar;
|
||||
SymbolVariable newVar;
|
||||
if(definedVarRef.isIntermediate()) {
|
||||
newVar = definedVar.getScope().addVariableIntermediate();
|
||||
newVar.setType(definedVar.getType());
|
||||
@ -463,9 +462,9 @@ public class Unroller {
|
||||
private Statement unrollStatementPhi(StatementPhiBlock origPhiBlock, LabelRef origBlock) {
|
||||
StatementPhiBlock newPhiBlock = new StatementPhiBlock(Comment.NO_COMMENTS);
|
||||
for(StatementPhiBlock.PhiVariable origPhiVariable : origPhiBlock.getPhiVariables()) {
|
||||
VariableRef origPhiVar = origPhiVariable.getVariable();
|
||||
VariableRef newPhiVar = varsOriginalToCopied.get(origPhiVar);
|
||||
StatementPhiBlock.PhiVariable newPhiVariable = newPhiBlock.addPhiVariable(newPhiVar);
|
||||
SymbolVariableRef origPhiVar = origPhiVariable.getVariable();
|
||||
SymbolVariableRef newPhiVar = varsOriginalToCopied.get(origPhiVar);
|
||||
StatementPhiBlock.PhiVariable newPhiVariable = newPhiBlock.addPhiVariable((VariableRef) newPhiVar);
|
||||
List<StatementPhiBlock.PhiRValue> origPhiRValues = origPhiVariable.getValues();
|
||||
ListIterator<StatementPhiBlock.PhiRValue> origPhiRValuesIt = origPhiRValues.listIterator();
|
||||
while(origPhiRValuesIt.hasNext()) {
|
||||
@ -533,7 +532,7 @@ public class Unroller {
|
||||
* @param definedToNewVar Map from variables defined in the original loop to the variables in the new unrolled "rest" loop
|
||||
* @return A copy of the RValue with all relevant variable references updated
|
||||
*/
|
||||
private static RValue valueToNew(RValue rValue, Map<VariableRef, VariableRef> definedToNewVar) {
|
||||
private static RValue valueToNew(RValue rValue, Map<SymbolVariableRef, SymbolVariableRef> definedToNewVar) {
|
||||
if(rValue == null) return null;
|
||||
RValue rValueCopy = valueToOrig(rValue);
|
||||
ProgramValue.GenericValue genericValue = new ProgramValue.GenericValue(rValueCopy);
|
||||
@ -649,7 +648,7 @@ public class Unroller {
|
||||
* @param program The program
|
||||
* @return true if the variable is ever referenced outside the block set
|
||||
*/
|
||||
private static boolean isReferencedOutside(VariableRef variableRef, BlockSet blockSet, Program program) {
|
||||
private static boolean isReferencedOutside(SymbolVariableRef variableRef, BlockSet blockSet, Program program) {
|
||||
boolean referencedOutside = false;
|
||||
VariableReferenceInfos variableReferenceInfos = program.getVariableReferenceInfos();
|
||||
StatementInfos statementInfos = program.getStatementInfos();
|
||||
|
@ -3416,7 +3416,7 @@ public class TestPrograms {
|
||||
boolean success = true;
|
||||
ReferenceHelper helper = new ReferenceHelperFolder(refPath);
|
||||
success &= helper.testOutput(fileName, ".asm", program.getAsm().toString(new AsmProgram.AsmPrintState(false, false, false, false), program));
|
||||
success &= helper.testOutput(fileName, ".sym", program.getScope().toString(program, null));
|
||||
success &= helper.testOutput(fileName, ".sym", program.getScope().toString(program, false));
|
||||
success &= helper.testOutput(fileName, ".cfg", program.getGraph().toString(program));
|
||||
success &= helper.testOutput(fileName, ".log", program.getLog().toString());
|
||||
if(!success) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user