mirror of
https://gitlab.com/camelot/kickc.git
synced 2025-02-20 00:29:10 +00:00
Removed ConstantVar class (using SymbolVariable instead).
This commit is contained in:
parent
093898455f
commit
fd307776ae
@ -22,7 +22,7 @@ public class AsmFormat {
|
|||||||
*/
|
*/
|
||||||
public static String getAsmConstant(Program program, ConstantValue value, int precedence, ScopeRef codeScope) {
|
public static String getAsmConstant(Program program, ConstantValue value, int precedence, ScopeRef codeScope) {
|
||||||
if(value instanceof ConstantRef) {
|
if(value instanceof ConstantRef) {
|
||||||
ConstantVar constantVar = program.getScope().getConstant((ConstantRef) value);
|
SymbolVariable constantVar = program.getScope().getConstant((ConstantRef) value);
|
||||||
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
||||||
return getAsmParamName(constantVar.getScope().getRef(), asmName, codeScope);
|
return getAsmParamName(constantVar.getScope().getRef(), asmName, codeScope);
|
||||||
} else if(value instanceof ConstantInteger) {
|
} else if(value instanceof ConstantInteger) {
|
||||||
|
@ -6,7 +6,6 @@ import dk.camelot64.kickc.model.ConstantNotLiteral;
|
|||||||
import dk.camelot64.kickc.model.InternalError;
|
import dk.camelot64.kickc.model.InternalError;
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import dk.camelot64.kickc.model.Registers;
|
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.Label;
|
||||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
@ -127,7 +126,7 @@ public class AsmFragmentInstance {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
if(boundConst instanceof ConstantRef) {
|
if(boundConst instanceof ConstantRef) {
|
||||||
ConstantVar reffedConstant = program.getScope().getConstant((ConstantRef) boundConst);
|
SymbolVariable reffedConstant = program.getScope().getConstant((ConstantRef) boundConst);
|
||||||
return isConstantValueZp(reffedConstant.getConstantValue());
|
return isConstantValueZp(reffedConstant.getConstantValue());
|
||||||
}
|
}
|
||||||
if(boundConst instanceof ConstantCastValue) {
|
if(boundConst instanceof ConstantCastValue) {
|
||||||
|
@ -506,7 +506,7 @@ public class AsmFragmentInstanceSpecFactory {
|
|||||||
// If the constant is already bound - reuse the index
|
// If the constant is already bound - reuse the index
|
||||||
for(String boundName : bindings.keySet()) {
|
for(String boundName : bindings.keySet()) {
|
||||||
Value boundValue = bindings.get(boundName);
|
Value boundValue = bindings.get(boundName);
|
||||||
if(boundValue instanceof ConstantValue || boundValue instanceof ConstantVar) {
|
if(boundValue instanceof ConstantValue || (boundValue instanceof SymbolVariable && ((SymbolVariable) boundValue).isConstant())) {
|
||||||
if(boundValue.equals(constant)) {
|
if(boundValue.equals(constant)) {
|
||||||
return "c" + boundName.substring(boundName.length() - 1);
|
return "c" + boundName.substring(boundName.length() - 1);
|
||||||
}
|
}
|
||||||
|
@ -19,11 +19,11 @@ public class CallingConventionStack {
|
|||||||
*/
|
*/
|
||||||
public static ConstantRef getReturnOffsetConstant(Procedure procedure) {
|
public static ConstantRef getReturnOffsetConstant(Procedure procedure) {
|
||||||
String returnOffsetConstantName = "OFFSET_STACK_RETURN";
|
String returnOffsetConstantName = "OFFSET_STACK_RETURN";
|
||||||
ConstantVar returnOffsetConstant = procedure.getConstant(returnOffsetConstantName);
|
SymbolVariable returnOffsetConstant = procedure.getConstant(returnOffsetConstantName);
|
||||||
if(returnOffsetConstant == null) {
|
if(returnOffsetConstant == null) {
|
||||||
// Constant not found - create it
|
// Constant not found - create it
|
||||||
long returnByteOffset = getReturnByteOffset(procedure);
|
long returnByteOffset = getReturnByteOffset(procedure);
|
||||||
returnOffsetConstant = new ConstantVar(returnOffsetConstantName, procedure, SymbolType.BYTE, new ConstantInteger(returnByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
returnOffsetConstant = new SymbolVariable(returnOffsetConstantName, procedure, SymbolType.BYTE, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(returnByteOffset & 0xff, SymbolType.BYTE));
|
||||||
procedure.add(returnOffsetConstant);
|
procedure.add(returnOffsetConstant);
|
||||||
}
|
}
|
||||||
return returnOffsetConstant.getConstantRef();
|
return returnOffsetConstant.getConstantRef();
|
||||||
@ -38,11 +38,11 @@ public class CallingConventionStack {
|
|||||||
*/
|
*/
|
||||||
public static ConstantRef getParameterOffsetConstant(Procedure procedure, SymbolVariable parameter) {
|
public static ConstantRef getParameterOffsetConstant(Procedure procedure, SymbolVariable parameter) {
|
||||||
String paramOffsetConstantName = getParameterOffsetConstantName(parameter.getName());
|
String paramOffsetConstantName = getParameterOffsetConstantName(parameter.getName());
|
||||||
ConstantVar paramOffsetConstant = procedure.getConstant(paramOffsetConstantName);
|
SymbolVariable paramOffsetConstant = procedure.getConstant(paramOffsetConstantName);
|
||||||
if(paramOffsetConstant == null) {
|
if(paramOffsetConstant == null) {
|
||||||
// Constant not found - create it
|
// Constant not found - create it
|
||||||
long paramByteOffset = getParameterByteOffset(procedure, parameter);
|
long paramByteOffset = getParameterByteOffset(procedure, parameter);
|
||||||
paramOffsetConstant = new ConstantVar(paramOffsetConstantName, procedure, SymbolType.BYTE, new ConstantInteger(paramByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
paramOffsetConstant = new SymbolVariable(paramOffsetConstantName, procedure, SymbolType.BYTE, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(paramByteOffset & 0xff, SymbolType.BYTE));
|
||||||
procedure.add(paramOffsetConstant);
|
procedure.add(paramOffsetConstant);
|
||||||
}
|
}
|
||||||
return paramOffsetConstant.getConstantRef();
|
return paramOffsetConstant.getConstantRef();
|
||||||
@ -123,7 +123,7 @@ public class CallingConventionStack {
|
|||||||
*/
|
*/
|
||||||
public static ConstantRef getStackBaseConstant(ProgramScope programScope) {
|
public static ConstantRef getStackBaseConstant(ProgramScope programScope) {
|
||||||
long STACK_BASE_ADDRESS = 0x103L;
|
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);
|
SymbolVariable stackBase = new SymbolVariable("STACK_BASE", programScope, SymbolType.WORD, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(STACK_BASE_ADDRESS, SymbolType.WORD));
|
||||||
programScope.add(stackBase);
|
programScope.add(stackBase);
|
||||||
return stackBase.getConstantRef();
|
return stackBase.getConstantRef();
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package dk.camelot64.kickc.model.iterator;
|
|||||||
|
|
||||||
import dk.camelot64.kickc.model.ControlFlowBlock;
|
import dk.camelot64.kickc.model.ControlFlowBlock;
|
||||||
import dk.camelot64.kickc.model.statements.*;
|
import dk.camelot64.kickc.model.statements.*;
|
||||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
||||||
import dk.camelot64.kickc.model.values.*;
|
import dk.camelot64.kickc.model.values.*;
|
||||||
|
|
||||||
@ -630,9 +630,9 @@ public interface ProgramValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ProgramValueConstantVar implements ProgramValue {
|
class ProgramValueConstantVar implements ProgramValue {
|
||||||
private final ConstantVar constantVar;
|
private final SymbolVariable constantVar;
|
||||||
|
|
||||||
ProgramValueConstantVar(ConstantVar constantVar) {
|
ProgramValueConstantVar(SymbolVariable constantVar) {
|
||||||
this.constantVar = constantVar;
|
this.constantVar = constantVar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,8 +50,8 @@ public class ProgramValueIterator {
|
|||||||
if(symbolVariable.getType() instanceof SymbolTypeArray) {
|
if(symbolVariable.getType() instanceof SymbolTypeArray) {
|
||||||
execute(new ProgramValue.ProgramValueTypeArraySize((SymbolTypeArray) symbolVariable.getType()), programValueHandler, null, null, null);
|
execute(new ProgramValue.ProgramValueTypeArraySize((SymbolTypeArray) symbolVariable.getType()), programValueHandler, null, null, null);
|
||||||
}
|
}
|
||||||
if(symbolVariable instanceof ConstantVar) {
|
if(symbolVariable.isConstant()) {
|
||||||
execute(new ProgramValue.ProgramValueConstantVar((ConstantVar) symbolVariable), programValueHandler, null, null, null);
|
execute(new ProgramValue.ProgramValueConstantVar(symbolVariable), programValueHandler, null, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package dk.camelot64.kickc.model.operators;
|
|||||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
||||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||||
import dk.camelot64.kickc.model.symbols.Scope;
|
import dk.camelot64.kickc.model.symbols.Scope;
|
||||||
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||||
@ -38,11 +39,11 @@ public class OperatorSizeOf extends OperatorUnary {
|
|||||||
*/
|
*/
|
||||||
public static ConstantRef getSizeOfConstantVar(ProgramScope programScope, SymbolType type) {
|
public static ConstantRef getSizeOfConstantVar(ProgramScope programScope, SymbolType type) {
|
||||||
String typeConstName = getSizeofConstantName(type);
|
String typeConstName = getSizeofConstantName(type);
|
||||||
ConstantVar typeSizeConstant = programScope.getConstant(typeConstName);
|
SymbolVariable typeSizeConstant = programScope.getConstant(typeConstName);
|
||||||
if(typeSizeConstant == null) {
|
if(typeSizeConstant == null) {
|
||||||
// Constant not found - create it
|
// Constant not found - create it
|
||||||
long typeSize = type.getSizeBytes();
|
long typeSize = type.getSizeBytes();
|
||||||
typeSizeConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize&0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
typeSizeConstant = new SymbolVariable(typeConstName, programScope, SymbolType.BYTE, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(typeSize&0xff, SymbolType.BYTE));
|
||||||
programScope.add(typeSizeConstant);
|
programScope.add(typeSizeConstant);
|
||||||
}
|
}
|
||||||
return typeSizeConstant.getConstantRef();
|
return typeSizeConstant.getConstantRef();
|
||||||
|
@ -3,6 +3,7 @@ package dk.camelot64.kickc.model.operators;
|
|||||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
||||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||||
import dk.camelot64.kickc.model.symbols.Scope;
|
import dk.camelot64.kickc.model.symbols.Scope;
|
||||||
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.*;
|
import dk.camelot64.kickc.model.types.*;
|
||||||
import dk.camelot64.kickc.model.values.ConstantInteger;
|
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||||
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||||
@ -40,11 +41,11 @@ public class OperatorTypeId extends OperatorUnary {
|
|||||||
*/
|
*/
|
||||||
public static ConstantRef getTypeIdConstantVar(ProgramScope programScope, SymbolType type) {
|
public static ConstantRef getTypeIdConstantVar(ProgramScope programScope, SymbolType type) {
|
||||||
String typeConstName = "TYPEID_" + getTypeIdConstantName(type);
|
String typeConstName = "TYPEID_" + getTypeIdConstantName(type);
|
||||||
ConstantVar typeIdConstant = programScope.getConstant(typeConstName);
|
SymbolVariable typeIdConstant = programScope.getConstant(typeConstName);
|
||||||
if(typeIdConstant == null) {
|
if(typeIdConstant == null) {
|
||||||
// Constant not found - create it
|
// Constant not found - create it
|
||||||
long typeSize = getTypeId(type);
|
long typeSize = getTypeId(type);
|
||||||
typeIdConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(typeSize), Scope.SEGMENT_DATA_DEFAULT);
|
typeIdConstant = new SymbolVariable(typeConstName, programScope, SymbolType.BYTE, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(typeSize));
|
||||||
programScope.add(typeIdConstant);
|
programScope.add(typeIdConstant);
|
||||||
}
|
}
|
||||||
return typeIdConstant.getConstantRef();
|
return typeIdConstant.getConstantRef();
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
package dk.camelot64.kickc.model.symbols;
|
|
||||||
|
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
|
||||||
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(true, name, scope, type, StorageStrategy.CONSTANT, MemoryArea.MAIN_MEMORY, dataSegment);
|
|
||||||
setConstantValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
package dk.camelot64.kickc.model.symbols;
|
package dk.camelot64.kickc.model.symbols;
|
||||||
|
|
||||||
import dk.camelot64.kickc.model.CompileError;
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
|
import dk.camelot64.kickc.model.InternalError;
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import dk.camelot64.kickc.model.Registers;
|
import dk.camelot64.kickc.model.Registers;
|
||||||
import dk.camelot64.kickc.model.VariableRegisterWeights;
|
import dk.camelot64.kickc.model.VariableRegisterWeights;
|
||||||
@ -163,18 +164,22 @@ public abstract class Scope implements Symbol, Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SymbolVariable getVariable(String name) {
|
public SymbolVariable getVariable(String name) {
|
||||||
return (SymbolVariable) getSymbol(name);
|
SymbolVariable symbol = (SymbolVariable) getSymbol(name);
|
||||||
|
if(symbol!=null && !symbol.isVariable()) throw new InternalError("Symbol is not a variable! "+symbol.toString());
|
||||||
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SymbolVariable getVariable(SymbolVariableRef variableRef) {
|
public SymbolVariable getVariable(SymbolVariableRef variableRef) {
|
||||||
return getVariable(variableRef.getFullName());
|
return getVariable(variableRef.getFullName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstantVar getConstant(String name) {
|
public SymbolVariable getConstant(String name) {
|
||||||
return (ConstantVar) getSymbol(name);
|
SymbolVariable symbol = (SymbolVariable) getSymbol(name);
|
||||||
|
if(symbol!=null && !symbol.isConstant()) throw new InternalError("Symbol is not a constant! "+symbol.toString());
|
||||||
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstantVar getConstant(ConstantRef constantRef) {
|
public SymbolVariable getConstant(ConstantRef constantRef) {
|
||||||
return getConstant(constantRef.getFullName());
|
return getConstant(constantRef.getFullName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,12 +206,12 @@ public abstract class Scope implements Symbol, Serializable {
|
|||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<ConstantVar> getAllConstants(boolean includeSubScopes) {
|
public Collection<SymbolVariable> getAllConstants(boolean includeSubScopes) {
|
||||||
Collection<SymbolVariable> symbolVariables = getAllSymbolVariables(includeSubScopes);
|
Collection<SymbolVariable> symbolVariables = getAllSymbolVariables(includeSubScopes);
|
||||||
Collection<ConstantVar> vars = new ArrayList<>();
|
Collection<SymbolVariable> vars = new ArrayList<>();
|
||||||
symbolVariables.stream().
|
symbolVariables.stream().
|
||||||
filter(symbolVariable -> (symbolVariable instanceof ConstantVar)).
|
filter(SymbolVariable::isConstant).
|
||||||
forEach(symbolVariable -> vars.add((ConstantVar) symbolVariable));
|
forEach(vars::add);
|
||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,12 +121,17 @@ public class SymbolVariable implements Symbol {
|
|||||||
this.nextPhiVersionNumber = 0;
|
this.nextPhiVersionNumber = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public SymbolVariable(String name, Scope scope, SymbolType type, String dataSegment, ConstantValue value) {
|
||||||
* Create a version of a PHI master variable
|
this(true, name, scope, type, StorageStrategy.CONSTANT, MemoryArea.MAIN_MEMORY, dataSegment);
|
||||||
*
|
setConstantValue(value);
|
||||||
* @param phiMaster The PHI master variable.
|
}
|
||||||
* @param version The version number
|
|
||||||
*/
|
/**
|
||||||
|
* 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) {
|
public SymbolVariable(SymbolVariable phiMaster, int version) {
|
||||||
this(false, phiMaster.getName() + "#" + version, phiMaster.getScope(), phiMaster.getType(), StorageStrategy.PHI_VERSION, phiMaster.getMemoryArea(), phiMaster.getDataSegment());
|
this(false, phiMaster.getName() + "#" + version, phiMaster.getScope(), phiMaster.getType(), StorageStrategy.PHI_VERSION, phiMaster.getMemoryArea(), phiMaster.getDataSegment());
|
||||||
this.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
|
this.setDeclaredAlignment(phiMaster.getDeclaredAlignment());
|
||||||
@ -159,7 +164,7 @@ public class SymbolVariable implements Symbol {
|
|||||||
|
|
||||||
public SymbolVariableRef getRef() {
|
public SymbolVariableRef getRef() {
|
||||||
if(isConstant)
|
if(isConstant)
|
||||||
return new ConstantRef((ConstantVar) this);
|
return new ConstantRef(this);
|
||||||
else
|
else
|
||||||
return new VariableRef(this);
|
return new VariableRef(this);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ public class SymbolTypeInference {
|
|||||||
SymbolVariable variable = symbols.getVariable((VariableRef) rValue);
|
SymbolVariable variable = symbols.getVariable((VariableRef) rValue);
|
||||||
type = variable.getType();
|
type = variable.getType();
|
||||||
} else if(rValue instanceof ConstantRef) {
|
} else if(rValue instanceof ConstantRef) {
|
||||||
ConstantVar constVar = symbols.getConstant((ConstantRef) rValue);
|
SymbolVariable constVar = symbols.getConstant((ConstantRef) rValue);
|
||||||
type = constVar.getType();
|
type = constVar.getType();
|
||||||
} else if(rValue instanceof Symbol) {
|
} else if(rValue instanceof Symbol) {
|
||||||
Symbol rSymbol = (Symbol) rValue;
|
Symbol rSymbol = (Symbol) rValue;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package dk.camelot64.kickc.model.values;
|
package dk.camelot64.kickc.model.values;
|
||||||
|
|
||||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
import dk.camelot64.kickc.model.InternalError;
|
||||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
@ -8,19 +8,21 @@ import dk.camelot64.kickc.model.types.SymbolType;
|
|||||||
/** A reference to a named Constant (in the symbol table) */
|
/** A reference to a named Constant (in the symbol table) */
|
||||||
public class ConstantRef extends SymbolVariableRef implements ConstantValue {
|
public class ConstantRef extends SymbolVariableRef implements ConstantValue {
|
||||||
|
|
||||||
public ConstantRef(ConstantVar constantVar) {
|
public ConstantRef(SymbolVariable constantVar) {
|
||||||
super(constantVar.getFullName());
|
super(constantVar.getFullName());
|
||||||
|
if(!constantVar.isConstant())
|
||||||
|
throw new InternalError("VariableRef not allowed for non-constant "+constantVar.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SymbolType getType(ProgramScope scope) {
|
public SymbolType getType(ProgramScope scope) {
|
||||||
SymbolVariable constant = scope.getVariable(this);
|
SymbolVariable constant = scope.getConstant(this);
|
||||||
return constant.getType();
|
return constant.getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConstantLiteral calculateLiteral(ProgramScope scope) {
|
public ConstantLiteral calculateLiteral(ProgramScope scope) {
|
||||||
ConstantVar constantVar = scope.getConstant(this);
|
SymbolVariable constantVar = scope.getConstant(this);
|
||||||
ConstantValue constantVarValue = constantVar.getConstantValue();
|
ConstantValue constantVarValue = constantVar.getConstantValue();
|
||||||
return constantVarValue.calculateLiteral(scope);
|
return constantVarValue.calculateLiteral(scope);
|
||||||
}
|
}
|
||||||
|
@ -1499,8 +1499,8 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
// Copy all members to upper-level scope
|
// Copy all members to upper-level scope
|
||||||
Scope parentScope = getCurrentScope();
|
Scope parentScope = getCurrentScope();
|
||||||
while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope();
|
while(parentScope instanceof StructDefinition) parentScope = parentScope.getScope();
|
||||||
for(ConstantVar member : enumDefinition.getAllConstants(false)) {
|
for(SymbolVariable member : enumDefinition.getAllConstants(false)) {
|
||||||
parentScope.add(new ConstantVar(member.getLocalName(), parentScope, SymbolType.BYTE, member.getConstantValue(), currentDataSegment));
|
parentScope.add(new SymbolVariable(member.getLocalName(), parentScope, SymbolType.BYTE, currentDataSegment, member.getConstantValue()));
|
||||||
}
|
}
|
||||||
return SymbolType.BYTE;
|
return SymbolType.BYTE;
|
||||||
} catch(CompileError e) {
|
} catch(CompileError e) {
|
||||||
@ -1520,11 +1520,11 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
enumValue = (ConstantValue) exprVal;
|
enumValue = (ConstantValue) exprVal;
|
||||||
} else {
|
} else {
|
||||||
// No specific value - find previous value
|
// No specific value - find previous value
|
||||||
List<ConstantVar> values = new ArrayList<>(currentEnum.getAllConstants(false));
|
List<SymbolVariable> values = new ArrayList<>(currentEnum.getAllConstants(false));
|
||||||
if(values.isEmpty()) {
|
if(values.isEmpty()) {
|
||||||
enumValue = new ConstantInteger(0L, SymbolType.BYTE);
|
enumValue = new ConstantInteger(0L, SymbolType.BYTE);
|
||||||
} else {
|
} else {
|
||||||
ConstantVar prevEnumMember = values.get(values.size() - 1);
|
SymbolVariable prevEnumMember = values.get(values.size() - 1);
|
||||||
ConstantValue prevValue = prevEnumMember.getConstantValue();
|
ConstantValue prevValue = prevEnumMember.getConstantValue();
|
||||||
if(prevValue instanceof ConstantInteger) {
|
if(prevValue instanceof ConstantInteger) {
|
||||||
enumValue = new ConstantInteger(((ConstantInteger) prevValue).getInteger() + 1, SymbolType.BYTE);
|
enumValue = new ConstantInteger(((ConstantInteger) prevValue).getInteger() + 1, SymbolType.BYTE);
|
||||||
@ -1534,7 +1534,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentEnum.add(new ConstantVar(memberName, getCurrentScope(), SymbolType.BYTE, enumValue, currentDataSegment));
|
currentEnum.add(new SymbolVariable(memberName, getCurrentScope(), SymbolType.BYTE, currentDataSegment, enumValue));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package dk.camelot64.kickc.passes;
|
|||||||
import dk.camelot64.kickc.model.*;
|
import dk.camelot64.kickc.model.*;
|
||||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
||||||
import dk.camelot64.kickc.model.statements.StatementCallPrepare;
|
import dk.camelot64.kickc.model.statements.StatementCallPrepare;
|
||||||
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.values.ConstantString;
|
import dk.camelot64.kickc.model.values.ConstantString;
|
||||||
import dk.camelot64.kickc.model.values.RValue;
|
import dk.camelot64.kickc.model.values.RValue;
|
||||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||||
@ -55,14 +56,14 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
|
|||||||
Scope blockScope = Pass1ExtractInlineStrings.this.getProgram().getScope().getScope(currentBlock.getScope());
|
Scope blockScope = Pass1ExtractInlineStrings.this.getProgram().getScope().getScope(currentBlock.getScope());
|
||||||
Value value = programValue.get();
|
Value value = programValue.get();
|
||||||
if(value instanceof ConstantString) {
|
if(value instanceof ConstantString) {
|
||||||
ConstantVar strConst = Pass1ExtractInlineStrings.this.createStringConstantVar(blockScope, (ConstantString) programValue.get(), nameHint);
|
SymbolVariable strConst = Pass1ExtractInlineStrings.this.createStringConstantVar(blockScope, (ConstantString) programValue.get(), nameHint);
|
||||||
programValue.set(strConst.getRef());
|
programValue.set(strConst.getRef());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConstantVar createStringConstantVar(Scope blockScope, ConstantString constantString, String nameHint) {
|
private SymbolVariable createStringConstantVar(Scope blockScope, ConstantString constantString, String nameHint) {
|
||||||
String name;
|
String name;
|
||||||
if(nameHint == null) {
|
if(nameHint == null) {
|
||||||
name = blockScope.allocateIntermediateVariableName();
|
name = blockScope.allocateIntermediateVariableName();
|
||||||
@ -73,7 +74,7 @@ public class Pass1ExtractInlineStrings extends Pass1Base {
|
|||||||
name = nameHint + nameHintIdx++;
|
name = nameHint + nameHintIdx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConstantVar strConst = new ConstantVar(name, blockScope, SymbolType.STRING, constantString, blockScope.getSegmentData());
|
SymbolVariable strConst = new SymbolVariable(name, blockScope, SymbolType.STRING, blockScope.getSegmentData(), constantString);
|
||||||
blockScope.add(strConst);
|
blockScope.add(strConst);
|
||||||
if(getLog().isVerbosePass1CreateSsa()) {
|
if(getLog().isVerbosePass1CreateSsa()) {
|
||||||
getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\"");
|
getLog().append("Creating constant string variable for inline " + strConst.toString(getProgram()) + " \"" + constantString.getValue() + "\"");
|
||||||
|
@ -3,11 +3,13 @@ package dk.camelot64.kickc.passes;
|
|||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import dk.camelot64.kickc.model.iterator.ProgramValue;
|
import dk.camelot64.kickc.model.iterator.ProgramValue;
|
||||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
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.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
||||||
import dk.camelot64.kickc.model.values.*;
|
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.Value;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -62,7 +64,7 @@ public class Pass2ArrayInStructInlining extends Pass2SsaOptimization {
|
|||||||
ConstantValue constantValue = (ConstantValue) value;
|
ConstantValue constantValue = (ConstantValue) value;
|
||||||
if(constantValue.getType(getProgram().getScope()).equals(SymbolType.STRING)) {
|
if(constantValue.getType(getProgram().getScope()).equals(SymbolType.STRING)) {
|
||||||
if(constantValue instanceof ConstantRef) {
|
if(constantValue instanceof ConstantRef) {
|
||||||
ConstantVar constantStringVar = getScope().getConstant((ConstantRef) constantValue);
|
SymbolVariable constantStringVar = getScope().getConstant((ConstantRef) constantValue);
|
||||||
inline.put((ConstantRef) constantValue, constantStringVar.getConstantValue());
|
inline.put((ConstantRef) constantValue, constantStringVar.getConstantValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ public class Pass2AssertSymbols extends Pass2SsaAssertion {
|
|||||||
if(tableSymbol instanceof SymbolVariable && ((SymbolVariable) tableSymbol).isStoragePhiMaster()) continue;
|
if(tableSymbol instanceof SymbolVariable && ((SymbolVariable) tableSymbol).isStoragePhiMaster()) continue;
|
||||||
if(tableSymbol instanceof SymbolVariable && ((SymbolVariable) tableSymbol).isStorageConstant()) continue;
|
if(tableSymbol instanceof SymbolVariable && ((SymbolVariable) tableSymbol).isStorageConstant()) continue;
|
||||||
if(tableSymbol instanceof SymbolVariable && ((SymbolVariable) tableSymbol).isStorageLoadStore()) continue;
|
if(tableSymbol instanceof SymbolVariable && ((SymbolVariable) tableSymbol).isStorageLoadStore()) continue;
|
||||||
if(tableSymbol instanceof ConstantVar) continue;
|
if(tableSymbol instanceof SymbolVariable && (((SymbolVariable) tableSymbol).isConstant()) ) continue;
|
||||||
if(tableSymbol instanceof StructDefinition) continue;
|
if(tableSymbol instanceof StructDefinition) continue;
|
||||||
if(tableSymbol instanceof EnumDefinition) continue;
|
if(tableSymbol instanceof EnumDefinition) continue;
|
||||||
if(tableSymbol instanceof TypeDefsScope) continue;
|
if(tableSymbol instanceof TypeDefsScope) continue;
|
||||||
|
@ -5,7 +5,7 @@ import dk.camelot64.kickc.model.Program;
|
|||||||
import dk.camelot64.kickc.model.statements.Statement;
|
import dk.camelot64.kickc.model.statements.Statement;
|
||||||
import dk.camelot64.kickc.model.statements.StatementCall;
|
import dk.camelot64.kickc.model.statements.StatementCall;
|
||||||
import dk.camelot64.kickc.model.statements.StatementCallPointer;
|
import dk.camelot64.kickc.model.statements.StatementCallPointer;
|
||||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
import dk.camelot64.kickc.model.types.SymbolTypePointer;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypeProcedure;
|
import dk.camelot64.kickc.model.types.SymbolTypeProcedure;
|
||||||
@ -38,7 +38,7 @@ public class Pass2ConstantCallPointerIdentification extends Pass2SsaOptimization
|
|||||||
optimized = true;
|
optimized = true;
|
||||||
}
|
}
|
||||||
} else if(procedure instanceof ConstantRef) {
|
} else if(procedure instanceof ConstantRef) {
|
||||||
ConstantVar procedureVariable = getScope().getConstant((ConstantRef) procedure);
|
SymbolVariable procedureVariable = getScope().getConstant((ConstantRef) procedure);
|
||||||
SymbolType procedureVariableType = procedureVariable.getType();
|
SymbolType procedureVariableType = procedureVariable.getType();
|
||||||
if(procedureVariableType instanceof SymbolTypePointer) {
|
if(procedureVariableType instanceof SymbolTypePointer) {
|
||||||
if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) {
|
if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) {
|
||||||
@ -82,7 +82,7 @@ public class Pass2ConstantCallPointerIdentification extends Pass2SsaOptimization
|
|||||||
*/
|
*/
|
||||||
private ProcedureRef findConstProcedure(RValue procedurePointer) {
|
private ProcedureRef findConstProcedure(RValue procedurePointer) {
|
||||||
if(procedurePointer instanceof ConstantRef) {
|
if(procedurePointer instanceof ConstantRef) {
|
||||||
ConstantVar constant = getScope().getConstant((ConstantRef) procedurePointer);
|
SymbolVariable constant = getScope().getConstant((ConstantRef) procedurePointer);
|
||||||
return findConstProcedure(constant.getConstantValue());
|
return findConstProcedure(constant.getConstantValue());
|
||||||
} else if(procedurePointer instanceof ConstantSymbolPointer) {
|
} else if(procedurePointer instanceof ConstantSymbolPointer) {
|
||||||
ConstantSymbolPointer pointer = (ConstantSymbolPointer) procedurePointer;
|
ConstantSymbolPointer pointer = (ConstantSymbolPointer) procedurePointer;
|
||||||
|
@ -69,12 +69,11 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantVar constantVar = new ConstantVar(
|
SymbolVariable constantVar = new SymbolVariable(
|
||||||
variable.getName(),
|
variable.getName(),
|
||||||
constScope,
|
constScope,
|
||||||
variableType,
|
variableType,
|
||||||
constVal,
|
variable.getDataSegment(), constVal
|
||||||
variable.getDataSegment()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
constantVar.setInferredType(variable.isInferredType());
|
constantVar.setInferredType(variable.isInferredType());
|
||||||
@ -217,8 +216,8 @@ public class Pass2ConstantIdentification extends Pass2SsaOptimization {
|
|||||||
public static ConstantValue getConstant(RValue rValue) {
|
public static ConstantValue getConstant(RValue rValue) {
|
||||||
if(rValue instanceof ConstantValue) {
|
if(rValue instanceof ConstantValue) {
|
||||||
return (ConstantValue) rValue;
|
return (ConstantValue) rValue;
|
||||||
} else if(rValue instanceof ConstantVar) {
|
} else if(rValue instanceof SymbolVariable && ((SymbolVariable) rValue).isConstant()) {
|
||||||
ConstantVar constantVar = (ConstantVar) rValue;
|
SymbolVariable constantVar = (SymbolVariable) rValue;
|
||||||
return constantVar.getConstantRef();
|
return constantVar.getConstantRef();
|
||||||
} else if(rValue instanceof CastValue) {
|
} else if(rValue instanceof CastValue) {
|
||||||
CastValue castValue = (CastValue) rValue;
|
CastValue castValue = (CastValue) rValue;
|
||||||
|
@ -89,8 +89,8 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
|||||||
*/
|
*/
|
||||||
private Map<ConstantRef, ConstantValue> findUnnamedConstants() {
|
private Map<ConstantRef, ConstantValue> findUnnamedConstants() {
|
||||||
Map<ConstantRef, ConstantValue> unnamed = new HashMap<>();
|
Map<ConstantRef, ConstantValue> unnamed = new HashMap<>();
|
||||||
Collection<ConstantVar> allConstants = getProgram().getScope().getAllConstants(true);
|
Collection<SymbolVariable> allConstants = getProgram().getScope().getAllConstants(true);
|
||||||
for(ConstantVar constant : allConstants) {
|
for(SymbolVariable constant : allConstants) {
|
||||||
if(constant.getRef().isIntermediate()) {
|
if(constant.getRef().isIntermediate()) {
|
||||||
if(!(constant.getType().equals(SymbolType.STRING)) && !(constant.getConstantValue() instanceof ConstantArray)) {
|
if(!(constant.getType().equals(SymbolType.STRING)) && !(constant.getConstantValue() instanceof ConstantArray)) {
|
||||||
unnamed.put(constant.getConstantRef(), constant.getConstantValue());
|
unnamed.put(constant.getConstantRef(), constant.getConstantValue());
|
||||||
@ -108,8 +108,8 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
|||||||
private Map<ConstantRef, ConstantValue> findAliasConstants() {
|
private Map<ConstantRef, ConstantValue> findAliasConstants() {
|
||||||
Map<ConstantRef, ConstantValue> aliases = new HashMap<>();
|
Map<ConstantRef, ConstantValue> aliases = new HashMap<>();
|
||||||
ProgramScope programScope = getProgram().getScope();
|
ProgramScope programScope = getProgram().getScope();
|
||||||
Collection<ConstantVar> allConstants = programScope.getAllConstants(true);
|
Collection<SymbolVariable> allConstants = programScope.getAllConstants(true);
|
||||||
for(ConstantVar constant : allConstants) {
|
for(SymbolVariable constant : allConstants) {
|
||||||
ConstantValue constantValue = constant.getConstantValue();
|
ConstantValue constantValue = constant.getConstantValue();
|
||||||
if(constantValue instanceof ConstantRef) {
|
if(constantValue instanceof ConstantRef) {
|
||||||
if(((ConstantRef) constantValue).isIntermediate()) {
|
if(((ConstantRef) constantValue).isIntermediate()) {
|
||||||
@ -134,8 +134,8 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
|||||||
private Map<ConstantRef, ConstantValue> findConstVarVersions() {
|
private Map<ConstantRef, ConstantValue> findConstVarVersions() {
|
||||||
Map<ConstantRef, ConstantValue> aliases = new HashMap<>();
|
Map<ConstantRef, ConstantValue> aliases = new HashMap<>();
|
||||||
|
|
||||||
Collection<ConstantVar> allConstants = getProgram().getScope().getAllConstants(true);
|
Collection<SymbolVariable> allConstants = getProgram().getScope().getAllConstants(true);
|
||||||
for(ConstantVar constant : allConstants) {
|
for(SymbolVariable constant : allConstants) {
|
||||||
if(constant.getRef().isVersion()) {
|
if(constant.getRef().isVersion()) {
|
||||||
// Constant is a version - find the other versions
|
// Constant is a version - find the other versions
|
||||||
String baseName = constant.getRef().getFullNameUnversioned();
|
String baseName = constant.getRef().getFullNameUnversioned();
|
||||||
@ -147,8 +147,8 @@ public class Pass2ConstantInlining extends Pass2SsaOptimization {
|
|||||||
aliases.put(constant.getConstantRef(), value);
|
aliases.put(constant.getConstantRef(), value);
|
||||||
getLog().append("Inlining constant with var siblings " + constant);
|
getLog().append("Inlining constant with var siblings " + constant);
|
||||||
break;
|
break;
|
||||||
} else if(symbol instanceof ConstantVar) {
|
} else if(symbol instanceof SymbolVariable && ((SymbolVariable) symbol).isConstant()) {
|
||||||
ConstantValue otherValue = ((ConstantVar) symbol).getConstantValue();
|
ConstantValue otherValue = ((SymbolVariable) symbol).getConstantValue();
|
||||||
if(!otherValue.equals(value) && !(value instanceof ConstantString) && !(value instanceof ConstantArray) && !(otherValue instanceof ConstantRef)) {
|
if(!otherValue.equals(value) && !(value instanceof ConstantString) && !(value instanceof ConstantArray) && !(otherValue instanceof ConstantRef)) {
|
||||||
aliases.put(constant.getConstantRef(), value);
|
aliases.put(constant.getConstantRef(), value);
|
||||||
getLog().append("Inlining constant with different constant siblings " + constant);
|
getLog().append("Inlining constant with different constant siblings " + constant);
|
||||||
|
@ -3,6 +3,7 @@ package dk.camelot64.kickc.passes;
|
|||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
||||||
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
import dk.camelot64.kickc.model.symbols.ProgramScope;
|
||||||
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
import dk.camelot64.kickc.model.values.ConstantRef;
|
import dk.camelot64.kickc.model.values.ConstantRef;
|
||||||
import dk.camelot64.kickc.model.values.ConstantString;
|
import dk.camelot64.kickc.model.values.ConstantString;
|
||||||
@ -30,18 +31,18 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
|
|||||||
public boolean step() {
|
public boolean step() {
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
// Build a map with all constant strings
|
// Build a map with all constant strings
|
||||||
Map<ConstantString, List<ConstantVar>> constantStringMap = new LinkedHashMap<>();
|
Map<ConstantString, List<SymbolVariable>> constantStringMap = new LinkedHashMap<>();
|
||||||
for(ConstantVar constVar : getScope().getAllConstants(true)) {
|
for(SymbolVariable constVar : getScope().getAllConstants(true)) {
|
||||||
ConstantValue constVal = constVar.getConstantValue();
|
ConstantValue constVal = constVar.getConstantValue();
|
||||||
if(constVal instanceof ConstantString) {
|
if(constVal instanceof ConstantString) {
|
||||||
ConstantString constString = (ConstantString) constVal;
|
ConstantString constString = (ConstantString) constVal;
|
||||||
List<ConstantVar> constantVars = constantStringMap.computeIfAbsent(constString, k -> new ArrayList<>());
|
List<SymbolVariable> constantVars = constantStringMap.computeIfAbsent(constString, k -> new ArrayList<>());
|
||||||
constantVars.add(constVar);
|
constantVars.add(constVar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle all constant strings with duplicate definitions
|
// Handle all constant strings with duplicate definitions
|
||||||
for(ConstantString constantString : constantStringMap.keySet()) {
|
for(ConstantString constantString : constantStringMap.keySet()) {
|
||||||
List<ConstantVar> constantVars = constantStringMap.get(constantString);
|
List<SymbolVariable> constantVars = constantStringMap.get(constantString);
|
||||||
if(constantVars.size() > 1) {
|
if(constantVars.size() > 1) {
|
||||||
// Found duplicate constant strings
|
// Found duplicate constant strings
|
||||||
modified |= handleDuplicateConstantString(constantVars, constantString);
|
modified |= handleDuplicateConstantString(constantVars, constantString);
|
||||||
@ -57,14 +58,14 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
|
|||||||
* @param constantVars The constant strings with identical values
|
* @param constantVars The constant strings with identical values
|
||||||
* @return true if any optimization was performed
|
* @return true if any optimization was performed
|
||||||
*/
|
*/
|
||||||
private boolean handleDuplicateConstantString(List<ConstantVar> constantVars, ConstantString constString) {
|
private boolean handleDuplicateConstantString(List<SymbolVariable> constantVars, ConstantString constString) {
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
// Look for a constant in the root scope - or check if they are all in the same scope
|
// Look for a constant in the root scope - or check if they are all in the same scope
|
||||||
ConstantVar rootConstant = null;
|
SymbolVariable rootConstant = null;
|
||||||
boolean isCommonScope = true;
|
boolean isCommonScope = true;
|
||||||
ScopeRef commonScope = null;
|
ScopeRef commonScope = null;
|
||||||
String segmentData = null;
|
String segmentData = null;
|
||||||
for(ConstantVar constantVar : constantVars) {
|
for(SymbolVariable constantVar : constantVars) {
|
||||||
ScopeRef constScope = constantVar.getScope().getRef();
|
ScopeRef constScope = constantVar.getScope().getRef();
|
||||||
segmentData = constantVar.getDataSegment();
|
segmentData = constantVar.getDataSegment();
|
||||||
if(constScope.equals(ScopeRef.ROOT)) {
|
if(constScope.equals(ScopeRef.ROOT)) {
|
||||||
@ -89,13 +90,13 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
|
|||||||
// Create a new root - and roll around again
|
// Create a new root - and roll around again
|
||||||
ProgramScope rootScope = getScope();
|
ProgramScope rootScope = getScope();
|
||||||
String localName = getRootName(constantVars);
|
String localName = getRootName(constantVars);
|
||||||
ConstantVar newRootConstant = new ConstantVar(localName, rootScope, SymbolType.STRING, constString, segmentData);
|
SymbolVariable newRootConstant = new SymbolVariable(localName, rootScope, SymbolType.STRING, segmentData, constString);
|
||||||
rootScope.add(newRootConstant);
|
rootScope.add(newRootConstant);
|
||||||
rootConstant = newRootConstant;
|
rootConstant = newRootConstant;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Modify all other constants to be references to the root constant
|
// Modify all other constants to be references to the root constant
|
||||||
for(ConstantVar constantVar : constantVars) {
|
for(SymbolVariable constantVar : constantVars) {
|
||||||
if(!constantVar.equals(rootConstant)) {
|
if(!constantVar.equals(rootConstant)) {
|
||||||
constantVar.setConstantValue(new ConstantRef(rootConstant));
|
constantVar.setConstantValue(new ConstantRef(rootConstant));
|
||||||
modified = true;
|
modified = true;
|
||||||
@ -108,10 +109,10 @@ public class Pass2ConstantStringConsolidation extends Pass2SsaOptimization {
|
|||||||
return modified;
|
return modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getRootName(List<ConstantVar> constantVars) {
|
private String getRootName(List<SymbolVariable> constantVars) {
|
||||||
String constName = null;
|
String constName = null;
|
||||||
// Try all variables with non-intermediate names
|
// Try all variables with non-intermediate names
|
||||||
for(ConstantVar constantVar : constantVars) {
|
for(SymbolVariable constantVar : constantVars) {
|
||||||
if(!constantVar.getRef().isIntermediate()) {
|
if(!constantVar.getRef().isIntermediate()) {
|
||||||
String candidateName = constantVar.getLocalName();
|
String candidateName = constantVar.getLocalName();
|
||||||
if(getScope().getSymbol(candidateName) == null) {
|
if(getScope().getSymbol(candidateName) == null) {
|
||||||
|
@ -2,7 +2,7 @@ package dk.camelot64.kickc.passes;
|
|||||||
|
|
||||||
import dk.camelot64.kickc.model.CompileError;
|
import dk.camelot64.kickc.model.CompileError;
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
||||||
import dk.camelot64.kickc.model.values.*;
|
import dk.camelot64.kickc.model.values.*;
|
||||||
@ -20,8 +20,8 @@ public class Pass3AssertArrayLengths extends Pass2SsaAssertion {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void check() throws AssertionFailed {
|
public void check() throws AssertionFailed {
|
||||||
Collection<ConstantVar> allConstants = getScope().getAllConstants(true);
|
Collection<SymbolVariable> allConstants = getScope().getAllConstants(true);
|
||||||
for(ConstantVar constantVar : allConstants) {
|
for(SymbolVariable constantVar : allConstants) {
|
||||||
SymbolType constantType = constantVar.getType();
|
SymbolType constantType = constantVar.getType();
|
||||||
if(constantType instanceof SymbolTypeArray) {
|
if(constantType instanceof SymbolTypeArray) {
|
||||||
RValue declaredSize = ((SymbolTypeArray) constantType).getSize();
|
RValue declaredSize = ((SymbolTypeArray) constantType).getSize();
|
||||||
|
@ -299,7 +299,7 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasData(ConstantVar constantVar) {
|
private boolean hasData(SymbolVariable constantVar) {
|
||||||
ConstantValue constantValue = constantVar.getConstantValue();
|
ConstantValue constantValue = constantVar.getConstantValue();
|
||||||
if(constantValue instanceof ConstantArray) {
|
if(constantValue instanceof ConstantArray) {
|
||||||
return true;
|
return true;
|
||||||
@ -325,7 +325,7 @@ public class Pass4CodeGeneration {
|
|||||||
* @param constantVar The constant to examine
|
* @param constantVar The constant to examine
|
||||||
* @return true if a .label should be used in the generated ASM
|
* @return true if a .label should be used in the generated ASM
|
||||||
*/
|
*/
|
||||||
private boolean useLabelForConst(ScopeRef scopeRef, ConstantVar constantVar) {
|
private boolean useLabelForConst(ScopeRef scopeRef, SymbolVariable constantVar) {
|
||||||
boolean useLabel = false;
|
boolean useLabel = false;
|
||||||
Collection<Integer> constRefStatements = program.getVariableReferenceInfos().getConstRefStatements(constantVar.getConstantRef());
|
Collection<Integer> constRefStatements = program.getVariableReferenceInfos().getConstRefStatements(constantVar.getConstantRef());
|
||||||
if(constRefStatements != null) {
|
if(constRefStatements != null) {
|
||||||
@ -389,10 +389,10 @@ public class Pass4CodeGeneration {
|
|||||||
private void addConstantsAndLabels(AsmProgram asm, ScopeRef scopeRef) {
|
private void addConstantsAndLabels(AsmProgram asm, ScopeRef scopeRef) {
|
||||||
Scope scope = program.getScope().getScope(scopeRef);
|
Scope scope = program.getScope().getScope(scopeRef);
|
||||||
Set<String> added = new LinkedHashSet<>();
|
Set<String> added = new LinkedHashSet<>();
|
||||||
Collection<ConstantVar> scopeConstants = scope.getAllConstants(false);
|
Collection<SymbolVariable> scopeConstants = scope.getAllConstants(false);
|
||||||
|
|
||||||
// Add all constants without data
|
// Add all constants without data
|
||||||
for(ConstantVar constantVar : scopeConstants) {
|
for(SymbolVariable constantVar : scopeConstants) {
|
||||||
if(!hasData(constantVar)) {
|
if(!hasData(constantVar)) {
|
||||||
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
||||||
if(asmName != null && !added.contains(asmName)) {
|
if(asmName != null && !added.contains(asmName)) {
|
||||||
@ -462,10 +462,10 @@ public class Pass4CodeGeneration {
|
|||||||
*/
|
*/
|
||||||
private void addData(AsmProgram asm, ScopeRef scopeRef) {
|
private void addData(AsmProgram asm, ScopeRef scopeRef) {
|
||||||
Scope scope = program.getScope().getScope(scopeRef);
|
Scope scope = program.getScope().getScope(scopeRef);
|
||||||
Collection<ConstantVar> scopeConstants = scope.getAllConstants(false);
|
Collection<SymbolVariable> scopeConstants = scope.getAllConstants(false);
|
||||||
Set<String> added = new LinkedHashSet<>();
|
Set<String> added = new LinkedHashSet<>();
|
||||||
// Add all constants arrays incl. strings with data
|
// Add all constants arrays incl. strings with data
|
||||||
for(ConstantVar constantVar : scopeConstants) {
|
for(SymbolVariable constantVar : scopeConstants) {
|
||||||
if(hasData(constantVar)) {
|
if(hasData(constantVar)) {
|
||||||
// Skip if already added
|
// Skip if already added
|
||||||
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
String asmName = constantVar.getAsmName() == null ? constantVar.getLocalName() : constantVar.getAsmName();
|
||||||
@ -946,7 +946,7 @@ public class Pass4CodeGeneration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if(procedure instanceof ConstantRef) {
|
} else if(procedure instanceof ConstantRef) {
|
||||||
ConstantVar procedureVariable = getScope().getConstant((ConstantRef) procedure);
|
SymbolVariable procedureVariable = getScope().getConstant((ConstantRef) procedure);
|
||||||
SymbolType procedureVariableType = procedureVariable.getType();
|
SymbolType procedureVariableType = procedureVariable.getType();
|
||||||
if(procedureVariableType instanceof SymbolTypePointer) {
|
if(procedureVariableType instanceof SymbolTypePointer) {
|
||||||
if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) {
|
if(((SymbolTypePointer) procedureVariableType).getElementType() instanceof SymbolTypeProcedure) {
|
||||||
|
@ -102,7 +102,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
|||||||
variable.setAsmName(null);
|
variable.setAsmName(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(ConstantVar constantVar : scope.getAllConstants(false)) {
|
for(SymbolVariable constantVar : scope.getAllConstants(false)) {
|
||||||
constantVar.setAsmName(constantVar.getLocalName());
|
constantVar.setAsmName(constantVar.getLocalName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ public class Pass4RegistersFinalize extends Pass2Base {
|
|||||||
shortenAsmName(shortNames, variable, allocation);
|
shortenAsmName(shortNames, variable, allocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(ConstantVar constantVar : scope.getAllConstants(false)) {
|
for(SymbolVariable constantVar : scope.getAllConstants(false)) {
|
||||||
Registers.Register allocation = new Registers.RegisterConstant(constantVar.getConstantValue());
|
Registers.Register allocation = new Registers.RegisterConstant(constantVar.getConstantValue());
|
||||||
shortenAsmName(shortNames, constantVar, allocation);
|
shortenAsmName(shortNames, constantVar, allocation);
|
||||||
}
|
}
|
||||||
|
@ -139,8 +139,8 @@ public class PassNEliminateUnusedVars extends Pass2SsaOptimization {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<ConstantVar> allConstants = getScope().getAllConstants(true);
|
Collection<SymbolVariable> allConstants = getScope().getAllConstants(true);
|
||||||
for(ConstantVar constant : allConstants) {
|
for(SymbolVariable constant : allConstants) {
|
||||||
if(!(constant.getScope() instanceof EnumDefinition)) {
|
if(!(constant.getScope() instanceof EnumDefinition)) {
|
||||||
if(referenceInfos.isUnused(constant.getRef())) {
|
if(referenceInfos.isUnused(constant.getRef())) {
|
||||||
if(constant.isDeclaredExport()) {
|
if(constant.isDeclaredExport()) {
|
||||||
|
@ -3,10 +3,13 @@ package dk.camelot64.kickc.passes;
|
|||||||
import dk.camelot64.kickc.model.InternalError;
|
import dk.camelot64.kickc.model.InternalError;
|
||||||
import dk.camelot64.kickc.model.Program;
|
import dk.camelot64.kickc.model.Program;
|
||||||
import dk.camelot64.kickc.model.iterator.ProgramValueIterator;
|
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.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
|
import dk.camelot64.kickc.model.types.SymbolTypeConversion;
|
||||||
import dk.camelot64.kickc.model.values.*;
|
import dk.camelot64.kickc.model.values.ConstantCastValue;
|
||||||
|
import dk.camelot64.kickc.model.values.ConstantInteger;
|
||||||
|
import dk.camelot64.kickc.model.values.ConstantLiteral;
|
||||||
|
import dk.camelot64.kickc.model.values.ConstantRef;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
@ -42,7 +45,7 @@ public class PassNFinalizeNumberTypeConversions extends Pass2SsaOptimization {
|
|||||||
if(SymbolType.UNUMBER.equals(toType)) {
|
if(SymbolType.UNUMBER.equals(toType)) {
|
||||||
if(constantCastValue.getValue() instanceof ConstantRef) {
|
if(constantCastValue.getValue() instanceof ConstantRef) {
|
||||||
ConstantRef constRef = (ConstantRef) constantCastValue.getValue();
|
ConstantRef constRef = (ConstantRef) constantCastValue.getValue();
|
||||||
ConstantVar constant = getScope().getConstant(constRef);
|
SymbolVariable constant = getScope().getConstant(constRef);
|
||||||
if(constant.isInferredType())
|
if(constant.isInferredType())
|
||||||
constant.setTypeInferred(toType);
|
constant.setTypeInferred(toType);
|
||||||
else
|
else
|
||||||
@ -57,7 +60,7 @@ public class PassNFinalizeNumberTypeConversions extends Pass2SsaOptimization {
|
|||||||
} else if(SymbolType.SNUMBER.equals(toType)) {
|
} else if(SymbolType.SNUMBER.equals(toType)) {
|
||||||
if(constantCastValue.getValue() instanceof ConstantRef) {
|
if(constantCastValue.getValue() instanceof ConstantRef) {
|
||||||
ConstantRef constRef = (ConstantRef) constantCastValue.getValue();
|
ConstantRef constRef = (ConstantRef) constantCastValue.getValue();
|
||||||
ConstantVar constant = getScope().getConstant(constRef);
|
SymbolVariable constant = getScope().getConstant(constRef);
|
||||||
if(constant.isInferredType())
|
if(constant.isInferredType())
|
||||||
constant.setTypeInferred(toType);
|
constant.setTypeInferred(toType);
|
||||||
else
|
else
|
||||||
|
@ -10,7 +10,6 @@ import dk.camelot64.kickc.model.operators.OperatorSizeOf;
|
|||||||
import dk.camelot64.kickc.model.operators.Operators;
|
import dk.camelot64.kickc.model.operators.Operators;
|
||||||
import dk.camelot64.kickc.model.statements.Statement;
|
import dk.camelot64.kickc.model.statements.Statement;
|
||||||
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
||||||
import dk.camelot64.kickc.model.symbols.ConstantVar;
|
|
||||||
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
import dk.camelot64.kickc.model.symbols.SymbolVariable;
|
||||||
import dk.camelot64.kickc.model.types.SymbolType;
|
import dk.camelot64.kickc.model.types.SymbolType;
|
||||||
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
import dk.camelot64.kickc.model.types.SymbolTypeArray;
|
||||||
@ -70,7 +69,7 @@ public class PassNSizeOfSimplification extends Pass2SsaOptimization {
|
|||||||
|
|
||||||
public void resolveConstantSizeOf(AtomicBoolean modified, ProgramValue programValue, ConstantUnary unary, ConstantValue operand) {
|
public void resolveConstantSizeOf(AtomicBoolean modified, ProgramValue programValue, ConstantUnary unary, ConstantValue operand) {
|
||||||
if(operand instanceof ConstantRef) {
|
if(operand instanceof ConstantRef) {
|
||||||
ConstantVar constant = getScope().getConstant((ConstantRef) operand);
|
SymbolVariable constant = getScope().getConstant((ConstantRef) operand);
|
||||||
SymbolType symbolType = constant.getType();
|
SymbolType symbolType = constant.getType();
|
||||||
if(symbolType instanceof SymbolTypeArray) {
|
if(symbolType instanceof SymbolTypeArray) {
|
||||||
SymbolTypeArray arrayType = (SymbolTypeArray) symbolType;
|
SymbolTypeArray arrayType = (SymbolTypeArray) symbolType;
|
||||||
|
@ -126,12 +126,12 @@ public class PassNStructPointerRewriting extends Pass2SsaOptimization {
|
|||||||
*/
|
*/
|
||||||
public static ConstantRef getMemberOffsetConstant(ProgramScope programScope, StructDefinition structDefinition, String memberName) {
|
public static ConstantRef getMemberOffsetConstant(ProgramScope programScope, StructDefinition structDefinition, String memberName) {
|
||||||
String typeConstName = getMemberOffsetConstantName(structDefinition, memberName);
|
String typeConstName = getMemberOffsetConstantName(structDefinition, memberName);
|
||||||
ConstantVar memberOffsetConstant = programScope.getConstant(typeConstName);
|
SymbolVariable memberOffsetConstant = programScope.getConstant(typeConstName);
|
||||||
if(memberOffsetConstant == null) {
|
if(memberOffsetConstant == null) {
|
||||||
// Constant not found - create it
|
// Constant not found - create it
|
||||||
SymbolVariable memberDef = structDefinition.getMember(memberName);
|
SymbolVariable memberDef = structDefinition.getMember(memberName);
|
||||||
long memberByteOffset = structDefinition.getMemberByteOffset(memberDef, programScope);
|
long memberByteOffset = structDefinition.getMemberByteOffset(memberDef, programScope);
|
||||||
memberOffsetConstant = new ConstantVar(typeConstName, programScope, SymbolType.BYTE, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE), Scope.SEGMENT_DATA_DEFAULT);
|
memberOffsetConstant = new SymbolVariable(typeConstName, programScope, SymbolType.BYTE, Scope.SEGMENT_DATA_DEFAULT, new ConstantInteger(memberByteOffset & 0xff, SymbolType.BYTE));
|
||||||
programScope.add(memberOffsetConstant);
|
programScope.add(memberOffsetConstant);
|
||||||
}
|
}
|
||||||
return memberOffsetConstant.getConstantRef();
|
return memberOffsetConstant.getConstantRef();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user