1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-12-27 09:31:18 +00:00

Now using VariableBuilderConfig for SSA/MA.

This commit is contained in:
Jesper Gravgaard 2020-02-09 11:48:17 +01:00
parent df9bde2ee8
commit eed8d58d74
3 changed files with 72 additions and 26 deletions

View File

@ -38,7 +38,10 @@ public class VariableBuilder {
/** The data segment. */
private String dataSegment;
public VariableBuilder(String varName, Scope scope, boolean isParameter, SymbolType type, ArraySpec arraySpec, List<Directive> directives, String dataSegment) {
/** Configuration of how to setup optimization/memory area for variables. */
private VariableBuilderConfig config;
public VariableBuilder(String varName, Scope scope, boolean isParameter, SymbolType type, ArraySpec arraySpec, List<Directive> directives, String dataSegment, VariableBuilderConfig config) {
this.varName = varName;
this.scope = scope;
this.isParameter = isParameter;
@ -46,14 +49,13 @@ public class VariableBuilder {
this.arraySpec = arraySpec;
this.directives = directives;
this.dataSegment = dataSegment;
this.config = config;
}
public static VariableBuilderConfig getDefaultConfig(CompileLog log) {
VariableBuilderConfig config = new VariableBuilderConfig();
config.addSetting("ssa_zp", log, null);
config.addSetting("array_ma_mem", log, null);
config.addSetting("global_ma_mem", log, null);
config.addSetting("local_struct_ssa_zp", log, null);
config.addSetting("global_struct_ma_mem", log, null);
return config;
}
@ -247,12 +249,15 @@ public class VariableBuilder {
else if(isVolatile())
// volatile variables must be load/store
return false;
else if(isTypeStruct() && isScopeGlobal())
// global struct variables must be load/store
return false;
else
// All others are single-static-assignment (by default)
return true;
else {
VariableBuilderConfig.Scope scope = VariableBuilderConfig.getScope(isScopeGlobal(), isScopeLocal(), isScopeParameter(), isScopeMember());
VariableBuilderConfig.Type type = VariableBuilderConfig.getType(isTypeInteger(), isArray(), isTypePointer(), isTypeStruct());
VariableBuilderConfig.Setting setting = config.getSetting(scope, type);
if(setting!=null && VariableBuilderConfig.Optimization.MA.equals(setting.optimization))
return false;
else
return true;
}
}
/**

View File

@ -4,9 +4,7 @@ import dk.camelot64.kickc.CompileLog;
import dk.camelot64.kickc.model.operators.Operator;
import dk.camelot64.kickc.model.statements.StatementSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
/**
* Configuration for the {@link VariableBuilder} specifying how different variables should be compiled.
@ -62,13 +60,38 @@ public class VariableBuilderConfig {
}
}
/** Key of the settings map containing scope & type. */
public static class ScopeType {
public Scope scope;
public Type type;
public ScopeType(Scope scope, Type type) {
this.scope = scope;
this.type = type;
}
@Override
public boolean equals(Object o) {
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
ScopeType scopeType = (ScopeType) o;
return scope == scopeType.scope &&
type == scopeType.type;
}
@Override
public int hashCode() {
return Objects.hash(scope, type);
}
}
/**
* The settings
*/
private List<Setting> settings;
private Map<ScopeType, Setting> settings;
VariableBuilderConfig() {
this.settings = new ArrayList<>();
this.settings = new HashMap<>();
}
public void addSetting(String pragmaParam, CompileLog log, StatementSource statementSource) {
@ -81,7 +104,7 @@ public class VariableBuilderConfig {
throw new CompileError("Warning: Malformed var_model parameter "+pragmaParam, statementSource);
for(Scope scope : scopes) {
for(Type type : types) {
settings.add(new Setting(scope, type, memoryArea, optimization));
settings.put(new ScopeType(scope, type), new Setting(scope, type, memoryArea, optimization));
}
}
}
@ -182,13 +205,31 @@ public class VariableBuilderConfig {
* @return The memory area to use
*/
public Setting getSetting(Scope scope, Type type) {
for(Setting setting : settings) {
if(setting.scope.equals(scope) && setting.type.equals(type)) {
// Found perfect match - return it
return setting;
}
}
return null;
return settings.get(new ScopeType(scope, type));
}
public static Scope getScope(boolean isScopeGlobal, boolean isScopeLocal, boolean isScopeParameter, boolean isScopeMember) {
if(isScopeGlobal)
return Scope.GLOBAL;
if(isScopeLocal)
return Scope.LOCAL;
if(isScopeParameter)
return Scope.PARAMETER;
if(isScopeMember)
return Scope.MEMBER;
throw new InternalError("Unknown scope!");
}
public static Type getType(boolean isTypeInteger, boolean isTypeArray, boolean isTypePointer, boolean isTypeStruct) {
if(isTypeInteger)
return Type.INTEGER;
if(isTypeArray)
return Type.ARRAY;
if(isTypePointer)
return Type.POINTER;
if(isTypeStruct)
return Type.STRUCT;
throw new InternalError("Unknown type!");
}

View File

@ -276,7 +276,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
public Object visitParameterDeclType(KickCParser.ParameterDeclTypeContext ctx) {
this.visitDeclTypes(ctx.declTypes());
String varName = ctx.NAME().getText();
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), true, declVarType, null, declVarDirectives, currentDataSegment);
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), true, declVarType, null, declVarDirectives, currentDataSegment, variableBuilderConfig);
Variable param = varBuilder.build();
exitDeclTypes();
return param;
@ -579,7 +579,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
PrePostModifierHandler.addPreModifiers(this, initializer, statementSource);
RValue initValue = (initializer == null) ? null : (RValue) visit(initializer);
initValue = Initializers.constantify(initValue, new Initializers.ValueTypeSpec(declVarType, declArraySpec), program, statementSource);
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, declVarType, declArraySpec, declVarDirectives, currentDataSegment);
VariableBuilder varBuilder = new VariableBuilder(varName, getCurrentScope(), false, declVarType, declArraySpec, declVarDirectives, currentDataSegment, variableBuilderConfig);
Variable variable = varBuilder.build();
if(variable.isKindConstant() || (variable.isKindLoadStore() && Variable.MemoryArea.MAIN_MEMORY.equals(variable.getMemoryArea()) && initValue instanceof ConstantValue && !declVarStructMember && variable.getRegister()==null)) {
// Set constant value
@ -645,7 +645,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
sequence.getStatements().remove(sequence.getStatements().size() - 1);
// Add a constant variable
Scope scope = getCurrentScope();
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, declVarType, declArraySpec, declVarDirectives, currentDataSegment);
VariableBuilder varBuilder = new VariableBuilder(varName, scope, false, declVarType, declArraySpec, declVarDirectives, currentDataSegment, variableBuilderConfig);
Variable variable = varBuilder.build();
// Set constant value
variable.setInitValue(getConstInitValue(constantArrayKickAsm, null, statementSource));
@ -1139,7 +1139,7 @@ public class Pass0GenerateStatementSequence extends KickCParserBaseVisitor<Objec
String varName = ctx.NAME().getText();
Variable lValue;
if(varType != null) {
VariableBuilder varBuilder = new VariableBuilder(varName, blockScope, false, varType, null, declVarDirectives, currentDataSegment);
VariableBuilder varBuilder = new VariableBuilder(varName, blockScope, false, varType, null, declVarDirectives, currentDataSegment, variableBuilderConfig);
lValue = varBuilder.build();
} else {
lValue = getCurrentScope().getVariable(varName);